Skip to content

Commit 3464d0a

Browse files
committed
migration test
1 parent 905a30f commit 3464d0a

File tree

15 files changed

+202
-66
lines changed

15 files changed

+202
-66
lines changed

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/BaseConfigurationService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ protected <P extends HasMetadata> ControllerConfiguration<P> configFor(Reconcile
138138

139139
final var dependentFieldManager = valueOrDefault(
140140
annotation,
141-
io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::dependentFieldManager,
141+
io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::fieldManager,
142142
DEFAULT_FIELD_MANAGER);
143143

144144
final var config = new ResolvedControllerConfiguration<P>(

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ default Set<String> getEffectiveNamespaces() {
127127
}
128128

129129
// todo javadoc
130-
default String dependentFieldManager() {
130+
default String fieldManager() {
131131
return DEFAULT_FIELD_MANAGER;
132132
}
133133

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverrider.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public class ControllerConfigurationOverrider<R extends HasMetadata> {
3939
private Map<DependentResourceSpec, Object> configurations;
4040
private ItemStore<R> itemStore;
4141
private String name;
42-
private String dependentFieldManager;
42+
private String fieldManager;
4343

4444
private ControllerConfigurationOverrider(ControllerConfiguration<R> original) {
4545
this.finalizer = original.getFinalizerName();
@@ -55,7 +55,7 @@ private ControllerConfigurationOverrider(ControllerConfiguration<R> original) {
5555
this.original = original;
5656
this.rateLimiter = original.getRateLimiter();
5757
this.name = original.getName();
58-
this.dependentFieldManager = original.dependentFieldManager();
58+
this.fieldManager = original.fieldManager();
5959
}
6060

6161
public ControllerConfigurationOverrider<R> withFinalizer(String finalizer) {
@@ -170,9 +170,9 @@ public ControllerConfigurationOverrider<R> withName(String name) {
170170
return this;
171171
}
172172

173-
public ControllerConfigurationOverrider<R> withDependentFieldManager(
173+
public ControllerConfigurationOverrider<R> withFieldManager(
174174
String dependentFieldManager) {
175-
this.dependentFieldManager = dependentFieldManager;
175+
this.fieldManager = dependentFieldManager;
176176
return this;
177177
}
178178

@@ -198,7 +198,7 @@ public ControllerConfiguration<R> build() {
198198
generationAware, original.getAssociatedReconcilerClassName(), retry, rateLimiter,
199199
reconciliationMaxInterval, onAddFilter, onUpdateFilter, genericFilter,
200200
original.getDependentResources(),
201-
namespaces, finalizer, labelSelector, configurations, itemStore, dependentFieldManager,
201+
namespaces, finalizer, labelSelector, configurations, itemStore, fieldManager,
202202
original.getConfigurationService());
203203
overridden.setEventFilter(customResourcePredicate);
204204
return overridden;

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResolvedControllerConfiguration.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public class ResolvedControllerConfiguration<P extends HasMetadata>
3232
private final Map<DependentResourceSpec, Object> configurations;
3333
private final ItemStore<P> itemStore;
3434
private final ConfigurationService configurationService;
35-
private final String dependentFieldManager;
35+
private final String fieldManager;
3636

3737
private ResourceEventFilter<P> eventFilter;
3838
private List<DependentResourceSpec> dependentResources;
@@ -45,7 +45,7 @@ public ResolvedControllerConfiguration(Class<P> resourceClass, ControllerConfigu
4545
other.genericFilter().orElse(null),
4646
other.getDependentResources(), other.getNamespaces(),
4747
other.getFinalizerName(), other.getLabelSelector(), Collections.emptyMap(),
48-
other.getItemStore().orElse(null), other.dependentFieldManager(),
48+
other.getItemStore().orElse(null), other.fieldManager(),
4949
other.getConfigurationService());
5050
}
5151

@@ -74,11 +74,11 @@ public ResolvedControllerConfiguration(Class<P> resourceClass, String name,
7474
List<DependentResourceSpec> dependentResources,
7575
Set<String> namespaces, String finalizer, String labelSelector,
7676
Map<DependentResourceSpec, Object> configurations, ItemStore<P> itemStore,
77-
String dependentFieldManager,
77+
String fieldManager,
7878
ConfigurationService configurationService) {
7979
this(resourceClass, name, generationAware, associatedReconcilerClassName, retry, rateLimiter,
8080
maxReconciliationInterval, onAddFilter, onUpdateFilter, genericFilter,
81-
namespaces, finalizer, labelSelector, configurations, itemStore, dependentFieldManager,
81+
namespaces, finalizer, labelSelector, configurations, itemStore, fieldManager,
8282
configurationService);
8383
setDependentResources(dependentResources);
8484
}
@@ -89,7 +89,7 @@ protected ResolvedControllerConfiguration(Class<P> resourceClass, String name,
8989
OnAddFilter<P> onAddFilter, OnUpdateFilter<P> onUpdateFilter, GenericFilter<P> genericFilter,
9090
Set<String> namespaces, String finalizer, String labelSelector,
9191
Map<DependentResourceSpec, Object> configurations, ItemStore<P> itemStore,
92-
String dependentFieldManager,
92+
String fieldManager,
9393
ConfigurationService configurationService) {
9494
super(resourceClass, namespaces, labelSelector, onAddFilter, onUpdateFilter, genericFilter,
9595
itemStore);
@@ -104,7 +104,7 @@ protected ResolvedControllerConfiguration(Class<P> resourceClass, String name,
104104
this.itemStore = itemStore;
105105
this.finalizer =
106106
ControllerConfiguration.ensureValidFinalizerName(finalizer, getResourceTypeName());
107-
this.dependentFieldManager = dependentFieldManager;
107+
this.fieldManager = fieldManager;
108108
}
109109

110110
protected ResolvedControllerConfiguration(Class<P> resourceClass, String name,
@@ -190,7 +190,7 @@ public Optional<ItemStore<P>> getItemStore() {
190190
}
191191

192192
@Override
193-
public String dependentFieldManager() {
194-
return dependentFieldManager;
193+
public String fieldManager() {
194+
return fieldManager;
195195
}
196196
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ControllerConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,5 +133,5 @@ MaxReconciliationInterval maxReconciliationInterval() default @MaxReconciliation
133133
Class<? extends ItemStore> itemStore() default ItemStore.class;
134134

135135
// todo javadoc
136-
String dependentFieldManager() default DEFAULT_FIELD_MANAGER;
136+
String fieldManager() default DEFAULT_FIELD_MANAGER;
137137
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ private PatchContext getSSAPatchContext(Context<P> context) {
294294
return new PatchContext.Builder()
295295
.withPatchType(PatchType.SERVER_SIDE_APPLY)
296296
.withForce(true)
297-
.withFieldManager(context.getControllerConfiguration().dependentFieldManager())
297+
.withFieldManager(context.getControllerConfiguration().fieldManager())
298298
.build();
299299
}
300300

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public boolean matches(R actual, R desired, Context<?> context) {
4343

4444
var optionalManagedFieldsEntry =
4545
checkIfFieldManagerExists(actual,
46-
context.getControllerConfiguration().dependentFieldManager());
46+
context.getControllerConfiguration().fieldManager());
4747
// the update will add the field manager
4848
if (optionalManagedFieldsEntry.isEmpty()) {
4949
return false;

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/SSABasedGenericKubernetesResourceMatcherTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class SSABasedGenericKubernetesResourceMatcherTest {
2424
@SuppressWarnings("unchecked")
2525
void setup() {
2626
var controllerConfiguration = mock(ControllerConfiguration.class);
27-
when(controllerConfiguration.dependentFieldManager()).thenCallRealMethod();
27+
when(controllerConfiguration.fieldManager()).thenCallRealMethod();
2828
var configurationService = mock(ConfigurationService.class);
2929
when(configurationService.getObjectMapper()).thenCallRealMethod();
3030
when(controllerConfiguration.getConfigurationService()).thenReturn(configurationService);

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

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
import io.fabric8.kubernetes.client.dsl.base.PatchContext;
1313
import io.fabric8.kubernetes.client.dsl.base.PatchType;
1414
import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension;
15-
import io.javaoperatorsdk.operator.sample.dependentssamatching.DependentSSAMatchingReconciler;
16-
import io.javaoperatorsdk.operator.sample.dependentssamatching.DependentSSAMatchingSpec;
17-
import io.javaoperatorsdk.operator.sample.dependentssamatching.DependnetSSAMatchingCustomResource;
18-
import io.javaoperatorsdk.operator.sample.dependentssamatching.SSAMatchingConfigMapDependent;
15+
import io.javaoperatorsdk.operator.sample.dependentssa.DependentSSAReconciler;
16+
import io.javaoperatorsdk.operator.sample.dependentssa.DependentSSASpec;
17+
import io.javaoperatorsdk.operator.sample.dependentssa.DependnetSSACustomResource;
18+
import io.javaoperatorsdk.operator.sample.dependentssa.SSAConfigMapDependent;
1919

2020
import static org.assertj.core.api.Assertions.assertThat;
2121
import static org.awaitility.Awaitility.await;
@@ -35,8 +35,8 @@ public class DependentSSAMatchingIT {
3535
@RegisterExtension
3636
LocallyRunOperatorExtension extension =
3737
LocallyRunOperatorExtension.builder()
38-
.withReconciler(new DependentSSAMatchingReconciler(),
39-
o -> o.withDependentFieldManager(CUSTOM_FIELD_MANAGER_NAME))
38+
.withReconciler(new DependentSSAReconciler(),
39+
o -> o.withFieldManager(CUSTOM_FIELD_MANAGER_NAME))
4040
.build();
4141

4242

@@ -47,10 +47,10 @@ void testMatchingAndUpdate() {
4747
await().untilAsserted(() -> {
4848
var cm = extension.get(ConfigMap.class, TEST_RESOURCE_NAME);
4949
assertThat(cm).isNotNull();
50-
assertThat(cm.getData()).containsEntry(SSAMatchingConfigMapDependent.DATA_KEY, INITIAL_VALUE);
50+
assertThat(cm.getData()).containsEntry(SSAConfigMapDependent.DATA_KEY, INITIAL_VALUE);
5151
assertThat(cm.getMetadata().getManagedFields().stream()
5252
.filter(fm -> fm.getManager().equals(CUSTOM_FIELD_MANAGER_NAME))).isNotEmpty();
53-
assertThat(SSAMatchingConfigMapDependent.NUMBER_OF_UPDATES.get()).isZero();
53+
assertThat(SSAConfigMapDependent.NUMBER_OF_UPDATES.get()).isZero();
5454
});
5555

5656
ConfigMap cmPatch = new ConfigMapBuilder()
@@ -70,7 +70,7 @@ void testMatchingAndUpdate() {
7070
await().pollDelay(Duration.ofMillis(300)).untilAsserted(() -> {
7171
var cm = extension.get(ConfigMap.class, TEST_RESOURCE_NAME);
7272
assertThat(cm.getData()).hasSize(2);
73-
assertThat(SSAMatchingConfigMapDependent.NUMBER_OF_UPDATES.get()).isZero();
73+
assertThat(SSAConfigMapDependent.NUMBER_OF_UPDATES.get()).isZero();
7474
assertThat(cm.getMetadata().getManagedFields()).hasSize(2);
7575
});
7676

@@ -80,19 +80,19 @@ void testMatchingAndUpdate() {
8080
await().untilAsserted(() -> {
8181
var cm = extension.get(ConfigMap.class, TEST_RESOURCE_NAME);
8282
assertThat(cm.getData()).hasSize(2);
83-
assertThat(cm.getData()).containsEntry(SSAMatchingConfigMapDependent.DATA_KEY, CHANGED_VALUE);
83+
assertThat(cm.getData()).containsEntry(SSAConfigMapDependent.DATA_KEY, CHANGED_VALUE);
8484
assertThat(cm.getData()).containsEntry(ADDITIONAL_KEY, ADDITIONAL_VALUE);
8585
assertThat(cm.getMetadata().getManagedFields()).hasSize(2);
86-
assertThat(SSAMatchingConfigMapDependent.NUMBER_OF_UPDATES.get()).isEqualTo(1);
86+
assertThat(SSAConfigMapDependent.NUMBER_OF_UPDATES.get()).isEqualTo(1);
8787
});
8888
}
8989

90-
public DependnetSSAMatchingCustomResource testResource() {
91-
DependnetSSAMatchingCustomResource resource = new DependnetSSAMatchingCustomResource();
90+
public DependnetSSACustomResource testResource() {
91+
DependnetSSACustomResource resource = new DependnetSSACustomResource();
9292
resource.setMetadata(new ObjectMetaBuilder()
9393
.withName(TEST_RESOURCE_NAME)
9494
.build());
95-
resource.setSpec(new DependentSSAMatchingSpec());
95+
resource.setSpec(new DependentSSASpec());
9696
resource.getSpec().setValue(INITIAL_VALUE);
9797
return resource;
9898
}
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
package io.javaoperatorsdk.operator;
2+
3+
import org.junit.jupiter.api.AfterEach;
4+
import org.junit.jupiter.api.BeforeEach;
5+
import org.junit.jupiter.api.Test;
6+
import org.junit.jupiter.api.TestInfo;
7+
8+
import io.fabric8.kubernetes.api.model.NamespaceBuilder;
9+
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
10+
import io.fabric8.kubernetes.client.KubernetesClient;
11+
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
12+
import io.fabric8.kubernetes.client.utils.KubernetesResourceUtil;
13+
import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension;
14+
import io.javaoperatorsdk.operator.sample.dependentssa.DependentSSAReconciler;
15+
import io.javaoperatorsdk.operator.sample.dependentssa.DependentSSASpec;
16+
import io.javaoperatorsdk.operator.sample.dependentssa.DependnetSSACustomResource;
17+
import io.javaoperatorsdk.operator.sample.dependentssa.SSAConfigMapDependent;
18+
19+
import static org.assertj.core.api.Assertions.assertThat;
20+
import static org.awaitility.Awaitility.await;
21+
22+
class DependentSSAMigrationIT {
23+
24+
public static final String TEST_RESOURCE_NAME = "test1";
25+
public static final String INITIAL_VALUE = "INITIAL_VALUE";
26+
public static final String CHANGED_VALUE = "CHANGED_VALUE";
27+
28+
private String namespace;
29+
private final KubernetesClient client = new KubernetesClientBuilder().build();
30+
31+
@BeforeEach
32+
void setup(TestInfo testInfo) {
33+
LocallyRunOperatorExtension.applyCrd(DependnetSSACustomResource.class, client);
34+
testInfo.getTestMethod().ifPresent(method -> {
35+
namespace = KubernetesResourceUtil.sanitizeName(method.getName());
36+
client.namespaces().resource(new NamespaceBuilder().withMetadata(new ObjectMetaBuilder()
37+
.withName(namespace)
38+
.build()).build()).create();
39+
});
40+
}
41+
42+
@AfterEach
43+
void cleanup() {
44+
client.namespaces().resource(new NamespaceBuilder().withMetadata(new ObjectMetaBuilder()
45+
.withName(namespace)
46+
.build()).build()).delete();
47+
}
48+
49+
@Test
50+
void migratesFromLegacyToWorksAndBack() {
51+
var legacyOperator = createOperator(client, true);
52+
DependnetSSACustomResource testResource = reconcileWithLegacyOpetor(legacyOperator);
53+
54+
var operator = createOperator(client, false);
55+
testResource = reconcileWithNewApproach(testResource, operator);
56+
57+
reconcileAgainWithLegacy(legacyOperator, testResource);
58+
}
59+
60+
private void reconcileAgainWithLegacy(Operator legacyOperator,
61+
DependnetSSACustomResource testResource) {
62+
legacyOperator.start();
63+
64+
testResource.getSpec().setValue(INITIAL_VALUE);
65+
testResource.getMetadata().setResourceVersion(null);
66+
client.resource(testResource).update();
67+
68+
await().untilAsserted(() -> {
69+
var cm = client.configMaps().inNamespace(namespace).withName(TEST_RESOURCE_NAME).get();
70+
assertThat(cm.getData()).containsEntry(SSAConfigMapDependent.DATA_KEY, INITIAL_VALUE);
71+
});
72+
73+
legacyOperator.stop();
74+
}
75+
76+
private DependnetSSACustomResource reconcileWithNewApproach(
77+
DependnetSSACustomResource testResource, Operator operator) {
78+
operator.start();
79+
80+
await().untilAsserted(() -> {
81+
var cm = client.configMaps().inNamespace(namespace).withName(TEST_RESOURCE_NAME).get();
82+
assertThat(cm).isNotNull();
83+
// todo there will be a second manager? both managing
84+
assertThat(cm.getMetadata().getManagedFields()).hasSize(2);
85+
assertThat(cm.getData()).hasSize(1);
86+
});
87+
88+
testResource.getSpec().setValue(CHANGED_VALUE);
89+
testResource.getMetadata().setResourceVersion(null);
90+
testResource = client.resource(testResource).update();
91+
92+
await().untilAsserted(() -> {
93+
var cm = client.configMaps().inNamespace(namespace).withName(TEST_RESOURCE_NAME).get();
94+
assertThat(cm.getData()).containsEntry(SSAConfigMapDependent.DATA_KEY, CHANGED_VALUE);
95+
});
96+
operator.stop();
97+
return testResource;
98+
}
99+
100+
private DependnetSSACustomResource reconcileWithLegacyOpetor(Operator legacyOperator) {
101+
legacyOperator.start();
102+
103+
var testResource = client.resource(testResource()).create();
104+
105+
await().untilAsserted(() -> {
106+
var cm = client.configMaps().inNamespace(namespace).withName(TEST_RESOURCE_NAME).get();
107+
assertThat(cm).isNotNull();
108+
assertThat(cm.getMetadata().getManagedFields()).hasSize(1);
109+
assertThat(cm.getData()).hasSize(1);
110+
});
111+
112+
legacyOperator.stop();
113+
return testResource;
114+
}
115+
116+
private Operator createOperator(KubernetesClient client, boolean legacyDependentHandling) {
117+
Operator operator = new Operator(client,
118+
o -> o.withLegacyCreateUpdateAndMatchingForDependentResources(legacyDependentHandling)
119+
.withCloseClientOnStop(false));
120+
operator.register(new DependentSSAReconciler(), o -> o.settingNamespace(namespace));
121+
return operator;
122+
}
123+
124+
125+
public DependnetSSACustomResource testResource() {
126+
DependnetSSACustomResource resource = new DependnetSSACustomResource();
127+
resource.setMetadata(new ObjectMetaBuilder()
128+
.withNamespace(namespace)
129+
.withName(TEST_RESOURCE_NAME)
130+
.build());
131+
resource.setSpec(new DependentSSASpec());
132+
resource.getSpec().setValue(INITIAL_VALUE);
133+
return resource;
134+
}
135+
136+
}
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
1-
package io.javaoperatorsdk.operator.sample.dependentssamatching;
1+
package io.javaoperatorsdk.operator.sample.dependentssa;
22

33
import java.util.concurrent.atomic.AtomicInteger;
44

55
import io.javaoperatorsdk.operator.api.reconciler.*;
66
import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent;
77
import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider;
88

9-
@ControllerConfiguration(dependents = {@Dependent(type = SSAMatchingConfigMapDependent.class)})
10-
public class DependentSSAMatchingReconciler
11-
implements Reconciler<DependnetSSAMatchingCustomResource>, TestExecutionInfoProvider {
9+
@ControllerConfiguration(dependents = {@Dependent(type = SSAConfigMapDependent.class)})
10+
public class DependentSSAReconciler
11+
implements Reconciler<DependnetSSACustomResource>, TestExecutionInfoProvider {
1212

1313
private final AtomicInteger numberOfExecutions = new AtomicInteger(0);
1414

1515
@Override
16-
public UpdateControl<DependnetSSAMatchingCustomResource> reconcile(
17-
DependnetSSAMatchingCustomResource resource,
18-
Context<DependnetSSAMatchingCustomResource> context) {
16+
public UpdateControl<DependnetSSACustomResource> reconcile(
17+
DependnetSSACustomResource resource,
18+
Context<DependnetSSACustomResource> context) {
1919
numberOfExecutions.addAndGet(1);
2020
return UpdateControl.noUpdate();
2121
}

0 commit comments

Comments
 (0)