Skip to content

Commit 825a6c1

Browse files
committed
fix: rebase on merge
1 parent 276e7e6 commit 825a6c1

13 files changed

+79
-41
lines changed

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/LeaderElectionManager.java

+27-27
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
package io.javaoperatorsdk.operator;
22

3-
import java.util.Arrays;
43
import java.util.Arrays;
54
import java.util.UUID;
65
import java.util.concurrent.CompletableFuture;
76

8-
import io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectRulesReview;
9-
import io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectRulesReviewSpecBuilder;
10-
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
117
import org.slf4j.Logger;
128
import org.slf4j.LoggerFactory;
139

14-
import io.fabric8.kubernetes.api.model.authorization.v1.*;
10+
import io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectRulesReview;
11+
import io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectRulesReviewSpecBuilder;
1512
import io.fabric8.kubernetes.client.KubernetesClient;
1613
import io.fabric8.kubernetes.client.extended.leaderelection.LeaderCallbacks;
1714
import io.fabric8.kubernetes.client.extended.leaderelection.LeaderElectionConfig;
@@ -27,12 +24,15 @@ public class LeaderElectionManager {
2724

2825
public static final String NO_PERMISSION_TO_LEASE_RESOURCE_MESSAGE =
2926
"No permission to lease resource.";
27+
public static final String UNIVERSAL_VERB = "*";
28+
public static final String COORDINATION_GROUP = "coordination.k8s.io";
29+
public static final String LEASES_RESOURCE = "leases";
3030

3131
private LeaderElector leaderElector = null;
3232
private final ControllerManager controllerManager;
3333
private String identity;
3434
private CompletableFuture<?> leaderElectionFuture;
35-
private KubernetesClient client;
35+
private KubernetesClient kubernetesClient;
3636
private final ConfigurationService configurationService;
3737
private String leaseNamespace;
3838

@@ -48,31 +48,31 @@ public boolean isLeaderElectionEnabled() {
4848
return configurationService.getLeaderElectionConfiguration().isPresent();
4949
}
5050

51-
public void init(LeaderElectionConfiguration config) {
51+
private void init(LeaderElectionConfiguration config) {
5252
this.identity = identity(config);
5353
leaseNamespace =
54-
config.getLeaseNamespace().orElseGet(
55-
() -> configurationService.getClientConfiguration().getNamespace());
54+
config.getLeaseNamespace().orElseGet(
55+
() -> configurationService.getClientConfiguration().getNamespace());
5656
if (leaseNamespace == null) {
5757
final var message =
58-
"Lease namespace is not set and cannot be inferred. Leader election cannot continue.";
58+
"Lease namespace is not set and cannot be inferred. Leader election cannot continue.";
5959
log.error(message);
6060
throw new IllegalArgumentException(message);
6161
}
6262
final var lock = new LeaseLock(leaseNamespace, config.getLeaseName(), identity);
6363
// releaseOnCancel is not used in the underlying implementation
6464
leaderElector = new LeaderElectorBuilder(
65-
kubernetesClient, configurationService.getExecutorServiceManager().cachingExecutorService())
66-
.withConfig(
67-
new LeaderElectionConfig(
68-
lock,
69-
config.getLeaseDuration(),
70-
config.getRenewDeadline(),
71-
config.getRetryPeriod(),
72-
leaderCallbacks(),
73-
true,
74-
config.getLeaseName()))
75-
.build();
65+
kubernetesClient, configurationService.getExecutorServiceManager().cachingExecutorService())
66+
.withConfig(
67+
new LeaderElectionConfig(
68+
lock,
69+
config.getLeaseDuration(),
70+
config.getRenewDeadline(),
71+
config.getRetryPeriod(),
72+
leaderCallbacks(),
73+
true,
74+
config.getLeaseName()))
75+
.build();
7676
}
7777

7878

@@ -122,16 +122,16 @@ private void checkLeaseAccess() {
122122
var verbs = Arrays.asList("create", "update", "get");
123123
SelfSubjectRulesReview review = new SelfSubjectRulesReview();
124124
review.setSpec(new SelfSubjectRulesReviewSpecBuilder().withNamespace(leaseNamespace).build());
125-
var reviewResult = client.resource(review).create();
125+
var reviewResult = kubernetesClient.resource(review).create();
126126
log.debug("SelfSubjectRulesReview result: {}", reviewResult);
127127
var foundRule = reviewResult.getStatus().getResourceRules().stream()
128-
.filter(rule -> rule.getApiGroups().contains("coordination.k8s.io")
129-
&& rule.getResources().contains("leases")
130-
&& (rule.getVerbs().containsAll(verbs)) || rule.getVerbs().contains("*"))
131-
.findAny();
128+
.filter(rule -> rule.getApiGroups().contains(COORDINATION_GROUP)
129+
&& rule.getResources().contains(LEASES_RESOURCE)
130+
&& (rule.getVerbs().containsAll(verbs)) || rule.getVerbs().contains(UNIVERSAL_VERB))
131+
.findAny();
132132
if (foundRule.isEmpty()) {
133133
throw new OperatorException(NO_PERMISSION_TO_LEASE_RESOURCE_MESSAGE +
134-
" in namespace: " + leaseNamespace);
134+
" in namespace: " + leaseNamespace);
135135
}
136136
}
137137
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericKubernetesResourceMatcher.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import java.util.*;
44

5-
import com.fasterxml.jackson.databind.ObjectMapper;
65
import io.fabric8.kubernetes.api.model.ConfigMap;
76
import io.fabric8.kubernetes.api.model.HasMetadata;
87
import io.fabric8.kubernetes.api.model.Secret;
@@ -12,7 +11,6 @@
1211
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.processors.GenericResourceUpdatePreProcessor;
1312

1413
import com.fasterxml.jackson.databind.JsonNode;
15-
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.processors.GenericResourceUpdatePreProcessor;
1614
import com.fasterxml.jackson.databind.ObjectMapper;
1715

1816
public class GenericKubernetesResourceMatcher<R extends HasMetadata, P extends HasMetadata>
@@ -186,15 +184,16 @@ public static <R extends HasMetadata> Result<R> match(R desired, R actualResourc
186184

187185
if (considerMetadata) {
188186
Optional<Result<R>> res =
189-
matchMetadata(desired, actualResource, labelsAndAnnotationsEquality, objectMapper);
187+
matchMetadata(desired, actualResource, labelsAndAnnotationsEquality, objectMapper);
190188
if (res.isPresent()) {
191189
return res.orElseThrow();
192190
}
193191
}
194192

195193
final ResourceUpdatePreProcessor<R> processor =
196-
GenericResourceUpdatePreProcessor.processorFor((Class<R>) desired.getClass());
197-
final var matched = processor.matches(actualResource, desired, specEquality, ignoredPaths);
194+
GenericResourceUpdatePreProcessor.processorFor((Class<R>) desired.getClass());
195+
final var matched =
196+
processor.matches(actualResource, desired, specEquality, objectMapper, ignoredPaths);
198197
return Result.computed(matched, desired);
199198
}
200199

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/ResourceUpdatePreProcessor.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66

77
import io.fabric8.kubernetes.api.model.HasMetadata;
88
import io.fabric8.zjsonpatch.JsonDiff;
9-
import io.javaoperatorsdk.operator.api.config.ConfigurationServiceProvider;
109
import io.javaoperatorsdk.operator.api.reconciler.Context;
1110

1211
import com.fasterxml.jackson.databind.JsonNode;
12+
import com.fasterxml.jackson.databind.ObjectMapper;
1313

1414
import static io.javaoperatorsdk.operator.processing.dependent.kubernetes.GenericKubernetesResourceMatcher.*;
1515

@@ -19,9 +19,9 @@ public interface ResourceUpdatePreProcessor<R extends HasMetadata> {
1919

2020
R replaceSpecOnActual(R actual, R desired, Context<?> context);
2121

22-
default boolean matches(R actual, R desired, boolean equality, String[] ignoredPaths) {
22+
default boolean matches(R actual, R desired, boolean equality, ObjectMapper objectMapper,
23+
String[] ignoredPaths) {
2324

24-
var objectMapper = ConfigurationServiceProvider.instance().getObjectMapper();
2525
var desiredNode = objectMapper.valueToTree(desired);
2626
var actualNode = objectMapper.valueToTree(actual);
2727
var wholeDiffJsonPatch = JsonDiff.asJson(desiredNode, actualNode);

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/ClusterRoleBindingResourceUpdatePreProcessor.java

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
import io.fabric8.kubernetes.api.model.rbac.ClusterRoleBinding;
66

7+
import com.fasterxml.jackson.databind.ObjectMapper;
8+
79
public class ClusterRoleBindingResourceUpdatePreProcessor
810
extends GenericResourceUpdatePreProcessor<ClusterRoleBinding> {
911

@@ -15,6 +17,7 @@ protected void updateClonedActual(ClusterRoleBinding actual, ClusterRoleBinding
1517

1618
@Override
1719
public boolean matches(ClusterRoleBinding actual, ClusterRoleBinding desired, boolean equality,
20+
ObjectMapper objectMapper,
1821
String[] ignoredPaths) {
1922
return Objects.equals(actual.getRoleRef(), desired.getRoleRef()) &&
2023
Objects.equals(actual.getSubjects(), desired.getSubjects());

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/ClusterRoleResourceUpdatePreProcessor.java

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
import io.fabric8.kubernetes.api.model.rbac.ClusterRole;
66

7+
import com.fasterxml.jackson.databind.ObjectMapper;
8+
79
public class ClusterRoleResourceUpdatePreProcessor
810
extends GenericResourceUpdatePreProcessor<ClusterRole> {
911

@@ -15,6 +17,7 @@ protected void updateClonedActual(ClusterRole actual, ClusterRole desired) {
1517

1618
@Override
1719
public boolean matches(ClusterRole actual, ClusterRole desired, boolean equality,
20+
ObjectMapper objectMapper,
1821
String[] ignoredPaths) {
1922
return Objects.equals(actual.getRules(), desired.getRules()) &&
2023
Objects.equals(actual.getAggregationRule(), desired.getAggregationRule());

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/ConfigMapResourceUpdatePreProcessor.java

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
import io.fabric8.kubernetes.api.model.ConfigMap;
66

7+
import com.fasterxml.jackson.databind.ObjectMapper;
8+
79
public class ConfigMapResourceUpdatePreProcessor
810
extends GenericResourceUpdatePreProcessor<ConfigMap> {
911

@@ -16,6 +18,7 @@ protected void updateClonedActual(ConfigMap actual, ConfigMap desired) {
1618

1719
@Override
1820
public boolean matches(ConfigMap actual, ConfigMap desired, boolean equality,
21+
ObjectMapper objectMapper,
1922
String[] ignoredPaths) {
2023
return Objects.equals(actual.getImmutable(), desired.getImmutable()) &&
2124
Objects.equals(actual.getData(), desired.getData()) &&

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/RoleBindingResourceUpdatePreProcessor.java

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
import io.fabric8.kubernetes.api.model.rbac.RoleBinding;
66

7+
import com.fasterxml.jackson.databind.ObjectMapper;
8+
79
public class RoleBindingResourceUpdatePreProcessor
810
extends GenericResourceUpdatePreProcessor<RoleBinding> {
911

@@ -15,6 +17,7 @@ protected void updateClonedActual(RoleBinding actual, RoleBinding desired) {
1517

1618
@Override
1719
public boolean matches(RoleBinding actual, RoleBinding desired, boolean equality,
20+
ObjectMapper objectMapper,
1821
String[] ignoredPaths) {
1922
return Objects.equals(actual.getRoleRef(), desired.getRoleRef()) &&
2023
Objects.equals(actual.getSubjects(), desired.getSubjects());

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/RoleResourceUpdatePreProcessor.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
import io.fabric8.kubernetes.api.model.rbac.Role;
66

7+
import com.fasterxml.jackson.databind.ObjectMapper;
8+
79
public class RoleResourceUpdatePreProcessor extends GenericResourceUpdatePreProcessor<Role> {
810

911
@Override
@@ -12,7 +14,8 @@ protected void updateClonedActual(Role actual, Role desired) {
1214
}
1315

1416
@Override
15-
public boolean matches(Role actual, Role desired, boolean equality, String[] ignoredPaths) {
17+
public boolean matches(Role actual, Role desired, boolean equality, ObjectMapper objectMapper,
18+
String[] ignoredPaths) {
1619
return Objects.equals(actual.getRules(), desired.getRules());
1720
}
1821
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/SecretResourceUpdatePreProcessor.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
import io.fabric8.kubernetes.api.model.Secret;
66

7+
import com.fasterxml.jackson.databind.ObjectMapper;
8+
79
public class SecretResourceUpdatePreProcessor extends GenericResourceUpdatePreProcessor<Secret> {
810

911
@Override
@@ -15,7 +17,8 @@ protected void updateClonedActual(Secret actual, Secret desired) {
1517
}
1618

1719
@Override
18-
public boolean matches(Secret actual, Secret desired, boolean equality, String[] ignoredPaths) {
20+
public boolean matches(Secret actual, Secret desired, boolean equality, ObjectMapper objectMapper,
21+
String[] ignoredPaths) {
1922
return Objects.equals(actual.getImmutable(), desired.getImmutable()) &&
2023
Objects.equals(actual.getType(), desired.getType()) &&
2124
Objects.equals(actual.getData(), desired.getData()) &&

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/ServiceAccountResourceUpdateProcessor.java

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
import io.fabric8.kubernetes.api.model.ServiceAccount;
66

7+
import com.fasterxml.jackson.databind.ObjectMapper;
8+
79
public class ServiceAccountResourceUpdateProcessor
810
extends GenericResourceUpdatePreProcessor<ServiceAccount> {
911

@@ -16,6 +18,7 @@ protected void updateClonedActual(ServiceAccount actual, ServiceAccount desired)
1618

1719
@Override
1820
public boolean matches(ServiceAccount actual, ServiceAccount desired, boolean equality,
21+
ObjectMapper objectMapper,
1922
String[] ignoredPaths) {
2023
return Objects.equals(actual.getAutomountServiceAccountToken(),
2124
desired.getAutomountServiceAccountToken()) &&

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/LeaderElectionManagerTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import org.junit.jupiter.api.Test;
1010
import org.junit.jupiter.api.io.TempDir;
1111

12-
import io.fabric8.kubernetes.client.KubernetesClient;
12+
import io.fabric8.kubernetes.api.model.coordination.v1.Lease;
1313
import io.javaoperatorsdk.operator.api.config.BaseConfigurationService;
1414
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
1515
import io.javaoperatorsdk.operator.api.config.LeaderElectionConfiguration;
@@ -27,7 +27,7 @@ class LeaderElectionManagerTest {
2727
@BeforeEach
2828
void setUp() {
2929
ControllerManager controllerManager = mock(ControllerManager.class);
30-
final var kubernetesClient = mock(KubernetesClient.class);
30+
final var kubernetesClient = MockKubernetesClient.client(Lease.class);
3131
var configurationService =
3232
ConfigurationService.newOverriddenConfigurationService(new BaseConfigurationService(),
3333
o -> o.withLeaderElectionConfiguration(new LeaderElectionConfiguration("test")));

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/MockKubernetesClient.java

+20
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
package io.javaoperatorsdk.operator;
22

3+
import java.util.Arrays;
34
import java.util.concurrent.CompletableFuture;
45
import java.util.concurrent.Executors;
56
import java.util.function.Consumer;
67

78
import io.fabric8.kubernetes.api.model.HasMetadata;
89
import io.fabric8.kubernetes.api.model.KubernetesResourceList;
10+
import io.fabric8.kubernetes.api.model.authorization.v1.ResourceRule;
11+
import io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectRulesReview;
12+
import io.fabric8.kubernetes.api.model.authorization.v1.SubjectRulesReviewStatus;
913
import io.fabric8.kubernetes.client.KubernetesClient;
1014
import io.fabric8.kubernetes.client.V1ApiextensionAPIGroupDSL;
1115
import io.fabric8.kubernetes.client.dsl.*;
1216
import io.fabric8.kubernetes.client.extended.leaderelection.LeaderElectorBuilder;
1317
import io.fabric8.kubernetes.client.informers.SharedIndexInformer;
1418
import io.fabric8.kubernetes.client.informers.cache.Indexer;
1519

20+
import static io.javaoperatorsdk.operator.LeaderElectionManager.*;
1621
import static org.mockito.Mockito.*;
1722

1823
public class MockKubernetesClient {
@@ -61,6 +66,10 @@ public static <T extends HasMetadata> KubernetesClient client(Class<T> clazz,
6166
when(client.resources(clazz)).thenReturn(resources);
6267
when(client.leaderElector())
6368
.thenReturn(new LeaderElectorBuilder(client, Executors.newSingleThreadExecutor()));
69+
var selfSubjectResourceResourceMock = mock(NamespaceableResource.class);
70+
when(client.resource(any(SelfSubjectRulesReview.class)))
71+
.thenReturn(selfSubjectResourceResourceMock);
72+
when(selfSubjectResourceResourceMock.create()).thenReturn(allowSelfSubjectReview());
6473

6574
final var apiGroupDSL = mock(ApiextensionsAPIGroupDSL.class);
6675
when(client.apiextensions()).thenReturn(apiGroupDSL);
@@ -72,4 +81,15 @@ public static <T extends HasMetadata> KubernetesClient client(Class<T> clazz,
7281

7382
return client;
7483
}
84+
85+
private static Object allowSelfSubjectReview() {
86+
SelfSubjectRulesReview review = new SelfSubjectRulesReview();
87+
review.setStatus(new SubjectRulesReviewStatus());
88+
var resourceRule = new ResourceRule();
89+
resourceRule.setApiGroups(Arrays.asList(COORDINATION_GROUP));
90+
resourceRule.setResources(Arrays.asList(LEASES_RESOURCE));
91+
resourceRule.setVerbs(Arrays.asList(UNIVERSAL_VERB));
92+
review.getStatus().setResourceRules(Arrays.asList(resourceRule));
93+
return review;
94+
}
7595
}

operator-framework/src/test/java/io/javaoperatorsdk/operator/LeaderElectionPermissionIT.java

-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import io.fabric8.kubernetes.client.ConfigBuilder;
1010
import io.fabric8.kubernetes.client.KubernetesClient;
1111
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
12-
import io.javaoperatorsdk.operator.api.config.ConfigurationServiceProvider;
1312
import io.javaoperatorsdk.operator.api.config.LeaderElectionConfiguration;
1413
import io.javaoperatorsdk.operator.api.reconciler.Context;
1514
import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration;
@@ -46,7 +45,6 @@ void operatorStopsIfNoLeaderElectionPermission() {
4645

4746
assertThat(exception.getCause().getMessage())
4847
.contains(NO_PERMISSION_TO_LEASE_RESOURCE_MESSAGE);
49-
ConfigurationServiceProvider.reset();
5048
}
5149

5250

0 commit comments

Comments
 (0)