From 3b9c4629c195375d0cdf32dfd51e48f6cacd1335 Mon Sep 17 00:00:00 2001 From: csviri <csviri@gmail.com> Date: Tue, 31 Jan 2023 13:07:37 +0100 Subject: [PATCH 1/2] feat: sample of how to do unmodifiable part --- .../operator/UnmodifiableDependentPartIT.java | 63 +++++++++++++++++++ ...modifiableDependentPartCustomResource.java | 16 +++++ .../UnmodifiableDependentPartReconciler.java | 30 +++++++++ .../UnmodifiableDependentPartSpec.java | 15 +++++ .../UnmodifiablePartConfigMapDependent.java | 38 +++++++++++ 5 files changed, 162 insertions(+) create mode 100644 operator-framework/src/test/java/io/javaoperatorsdk/operator/UnmodifiableDependentPartIT.java create mode 100644 operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/unmodifiabledependentpart/UnmodifiableDependentPartCustomResource.java create mode 100644 operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/unmodifiabledependentpart/UnmodifiableDependentPartReconciler.java create mode 100644 operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/unmodifiabledependentpart/UnmodifiableDependentPartSpec.java create mode 100644 operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/unmodifiabledependentpart/UnmodifiablePartConfigMapDependent.java diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/UnmodifiableDependentPartIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/UnmodifiableDependentPartIT.java new file mode 100644 index 0000000000..dc4a2ade9b --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/UnmodifiableDependentPartIT.java @@ -0,0 +1,63 @@ +package io.javaoperatorsdk.operator; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.fabric8.kubernetes.api.model.ConfigMap; +import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; +import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension; +import io.javaoperatorsdk.operator.sample.unmodifiabledependentpart.UnmodifiableDependentPartCustomResource; +import io.javaoperatorsdk.operator.sample.unmodifiabledependentpart.UnmodifiableDependentPartReconciler; +import io.javaoperatorsdk.operator.sample.unmodifiabledependentpart.UnmodifiableDependentPartSpec; + +import static io.javaoperatorsdk.operator.sample.unmodifiabledependentpart.UnmodifiablePartConfigMapDependent.ACTUAL_DATA_KEY; +import static io.javaoperatorsdk.operator.sample.unmodifiabledependentpart.UnmodifiablePartConfigMapDependent.UNMODIFIABLE_INITIAL_DATA_KEY; +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; + +public class UnmodifiableDependentPartIT { + + public static final String TEST_RESOURCE_NAME = "test1"; + public static final String INITIAL_DATA = "initialData"; + public static final String UPDATED_DATA = "updatedData"; + + @RegisterExtension + LocallyRunOperatorExtension operator = + LocallyRunOperatorExtension.builder() + .withReconciler(UnmodifiableDependentPartReconciler.class) + .build(); + + @Test + void partConfigMapDataUnmodifiable() { + var resource = operator.create(testResource()); + + await().untilAsserted(() -> { + var cm = operator.get(ConfigMap.class, TEST_RESOURCE_NAME); + assertThat(cm).isNotNull(); + assertThat(cm.getData().get(UNMODIFIABLE_INITIAL_DATA_KEY)).isEqualTo(INITIAL_DATA); + assertThat(cm.getData().get(ACTUAL_DATA_KEY)).isEqualTo(INITIAL_DATA); + }); + + resource.getSpec().setData(UPDATED_DATA); + operator.replace(resource); + + await().untilAsserted(() -> { + var cm = operator.get(ConfigMap.class, TEST_RESOURCE_NAME); + assertThat(cm).isNotNull(); + assertThat(cm.getData().get(UNMODIFIABLE_INITIAL_DATA_KEY)).isEqualTo(INITIAL_DATA); + assertThat(cm.getData().get(ACTUAL_DATA_KEY)).isEqualTo(UPDATED_DATA); + }); + } + + + UnmodifiableDependentPartCustomResource testResource() { + var res = new UnmodifiableDependentPartCustomResource(); + res.setMetadata(new ObjectMetaBuilder() + .withName(TEST_RESOURCE_NAME) + .build()); + res.setSpec(new UnmodifiableDependentPartSpec()); + res.getSpec().setData(INITIAL_DATA); + return res; + } + +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/unmodifiabledependentpart/UnmodifiableDependentPartCustomResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/unmodifiabledependentpart/UnmodifiableDependentPartCustomResource.java new file mode 100644 index 0000000000..013fd62503 --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/unmodifiabledependentpart/UnmodifiableDependentPartCustomResource.java @@ -0,0 +1,16 @@ +package io.javaoperatorsdk.operator.sample.unmodifiabledependentpart; + +import io.fabric8.kubernetes.api.model.Namespaced; +import io.fabric8.kubernetes.client.CustomResource; +import io.fabric8.kubernetes.model.annotation.Group; +import io.fabric8.kubernetes.model.annotation.ShortNames; +import io.fabric8.kubernetes.model.annotation.Version; + +@Group("sample.javaoperatorsdk") +@Version("v1") +@ShortNames("udp") +public class UnmodifiableDependentPartCustomResource + extends CustomResource<UnmodifiableDependentPartSpec, Void> + implements Namespaced { + +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/unmodifiabledependentpart/UnmodifiableDependentPartReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/unmodifiabledependentpart/UnmodifiableDependentPartReconciler.java new file mode 100644 index 0000000000..fd63a2cb12 --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/unmodifiabledependentpart/UnmodifiableDependentPartReconciler.java @@ -0,0 +1,30 @@ +package io.javaoperatorsdk.operator.sample.unmodifiabledependentpart; + +import java.util.concurrent.atomic.AtomicInteger; + +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; +import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent; + +@ControllerConfiguration(dependents = {@Dependent(type = UnmodifiablePartConfigMapDependent.class)}) +public class UnmodifiableDependentPartReconciler + implements Reconciler<UnmodifiableDependentPartCustomResource> { + + private final AtomicInteger numberOfExecutions = new AtomicInteger(0); + + @Override + public UpdateControl<UnmodifiableDependentPartCustomResource> reconcile( + UnmodifiableDependentPartCustomResource resource, + Context<UnmodifiableDependentPartCustomResource> context) + throws InterruptedException { + numberOfExecutions.addAndGet(1); + return UpdateControl.noUpdate(); + } + + public int getNumberOfExecutions() { + return numberOfExecutions.get(); + } + +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/unmodifiabledependentpart/UnmodifiableDependentPartSpec.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/unmodifiabledependentpart/UnmodifiableDependentPartSpec.java new file mode 100644 index 0000000000..3f9c9b3460 --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/unmodifiabledependentpart/UnmodifiableDependentPartSpec.java @@ -0,0 +1,15 @@ +package io.javaoperatorsdk.operator.sample.unmodifiabledependentpart; + +public class UnmodifiableDependentPartSpec { + + private String data; + + public String getData() { + return data; + } + + public UnmodifiableDependentPartSpec setData(String data) { + this.data = data; + return this; + } +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/unmodifiabledependentpart/UnmodifiablePartConfigMapDependent.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/unmodifiabledependentpart/UnmodifiablePartConfigMapDependent.java new file mode 100644 index 0000000000..a103e53162 --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/unmodifiabledependentpart/UnmodifiablePartConfigMapDependent.java @@ -0,0 +1,38 @@ +package io.javaoperatorsdk.operator.sample.unmodifiabledependentpart; + +import java.util.Map; + +import io.fabric8.kubernetes.api.model.ConfigMap; +import io.fabric8.kubernetes.api.model.ConfigMapBuilder; +import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource; + +public class UnmodifiablePartConfigMapDependent + extends CRUDKubernetesDependentResource<ConfigMap, UnmodifiableDependentPartCustomResource> { + + public static final String UNMODIFIABLE_INITIAL_DATA_KEY = "initialDataKey"; + public static final String ACTUAL_DATA_KEY = "actualDataKey"; + + public UnmodifiablePartConfigMapDependent() { + super(ConfigMap.class); + } + + @Override + protected ConfigMap desired(UnmodifiableDependentPartCustomResource primary, + Context<UnmodifiableDependentPartCustomResource> context) { + var actual = getSecondaryResource(primary, context); + ConfigMap res = new ConfigMapBuilder() + .withMetadata(new ObjectMetaBuilder() + .withName(primary.getMetadata().getName()) + .withNamespace(primary.getMetadata().getNamespace()) + .build()) + .build(); + res.setData(Map.of(ACTUAL_DATA_KEY, primary.getSpec().getData(), + // setting the old data if available + UNMODIFIABLE_INITIAL_DATA_KEY, + actual.map(cm -> cm.getData().get(UNMODIFIABLE_INITIAL_DATA_KEY)) + .orElse(primary.getSpec().getData()))); + return res; + } +} From c870680162050cafd22d5c3b094879e60752592a Mon Sep 17 00:00:00 2001 From: csviri <csviri@gmail.com> Date: Tue, 31 Jan 2023 13:34:46 +0100 Subject: [PATCH 2/2] test improvements --- .../operator/UnmodifiableDependentPartIT.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/UnmodifiableDependentPartIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/UnmodifiableDependentPartIT.java index dc4a2ade9b..bc0e951d8a 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/UnmodifiableDependentPartIT.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/UnmodifiableDependentPartIT.java @@ -34,8 +34,8 @@ void partConfigMapDataUnmodifiable() { await().untilAsserted(() -> { var cm = operator.get(ConfigMap.class, TEST_RESOURCE_NAME); assertThat(cm).isNotNull(); - assertThat(cm.getData().get(UNMODIFIABLE_INITIAL_DATA_KEY)).isEqualTo(INITIAL_DATA); - assertThat(cm.getData().get(ACTUAL_DATA_KEY)).isEqualTo(INITIAL_DATA); + assertThat(cm.getData()).containsEntry(UNMODIFIABLE_INITIAL_DATA_KEY, INITIAL_DATA); + assertThat(cm.getData()).containsEntry(ACTUAL_DATA_KEY, INITIAL_DATA); }); resource.getSpec().setData(UPDATED_DATA); @@ -44,8 +44,8 @@ void partConfigMapDataUnmodifiable() { await().untilAsserted(() -> { var cm = operator.get(ConfigMap.class, TEST_RESOURCE_NAME); assertThat(cm).isNotNull(); - assertThat(cm.getData().get(UNMODIFIABLE_INITIAL_DATA_KEY)).isEqualTo(INITIAL_DATA); - assertThat(cm.getData().get(ACTUAL_DATA_KEY)).isEqualTo(UPDATED_DATA); + assertThat(cm.getData()).containsEntry(UNMODIFIABLE_INITIAL_DATA_KEY, INITIAL_DATA); + assertThat(cm.getData()).containsEntry(ACTUAL_DATA_KEY, UPDATED_DATA); }); }