diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/DependentDifferentNamespaceIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/DependentDifferentNamespaceIT.java new file mode 100644 index 0000000000..452de53930 --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/DependentDifferentNamespaceIT.java @@ -0,0 +1,71 @@ +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.dependentdifferentnamespace.ConfigMapDependentResource; +import io.javaoperatorsdk.operator.sample.dependentdifferentnamespace.DependentDifferentNamespaceCustomResource; +import io.javaoperatorsdk.operator.sample.dependentdifferentnamespace.DependentDifferentNamespaceReconciler; +import io.javaoperatorsdk.operator.sample.dependentdifferentnamespace.DependentDifferentNamespaceSpec; + +import static io.javaoperatorsdk.operator.sample.dependentdifferentnamespace.ConfigMapDependentResource.KEY; +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; + +class DependentDifferentNamespaceIT { + + public static final String TEST_1 = "different-ns-test1"; + public static final String INITIAL_VALUE = "initial_value"; + public static final String CHANGED_VALUE = "changed_value"; + + @RegisterExtension + LocallyRunOperatorExtension extension = + LocallyRunOperatorExtension.builder() + .withReconciler(DependentDifferentNamespaceReconciler.class) + .build(); + + @Test + void managesCRUDOperationsForDependentInDifferentNamespace() { + var resource = extension.create(testResource()); + + await().untilAsserted(() -> { + var cm = getDependentConfigMap(); + assertThat(cm).isNotNull(); + assertThat(cm.getData()).containsEntry(KEY, INITIAL_VALUE); + }); + + resource.getSpec().setValue(CHANGED_VALUE); + resource = extension.replace(resource); + + await().untilAsserted(() -> { + var cm = getDependentConfigMap(); + assertThat(cm.getData()).containsEntry(KEY, CHANGED_VALUE); + }); + + extension.delete(resource); + await().untilAsserted(() -> { + var cm = getDependentConfigMap(); + assertThat(cm).isNull(); + }); + } + + private ConfigMap getDependentConfigMap() { + return extension.getKubernetesClient().configMaps() + .inNamespace(ConfigMapDependentResource.NAMESPACE) + .withName(TEST_1).get(); + } + + DependentDifferentNamespaceCustomResource testResource() { + var res = new DependentDifferentNamespaceCustomResource(); + res.setMetadata(new ObjectMetaBuilder() + .withName(TEST_1) + .build()); + res.setSpec(new DependentDifferentNamespaceSpec()); + res.getSpec().setValue(INITIAL_VALUE); + return res; + } + +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/dependentdifferentnamespace/ConfigMapDependentResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/dependentdifferentnamespace/ConfigMapDependentResource.java new file mode 100644 index 0000000000..ca0d28e934 --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/dependentdifferentnamespace/ConfigMapDependentResource.java @@ -0,0 +1,34 @@ +package io.javaoperatorsdk.operator.sample.dependentdifferentnamespace; + +import java.util.HashMap; + +import io.fabric8.kubernetes.api.model.ConfigMap; +import io.fabric8.kubernetes.api.model.ObjectMeta; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDNoGCKubernetesDependentResource; + +public class ConfigMapDependentResource extends + CRUDNoGCKubernetesDependentResource { + + public static final String KEY = "key"; + + public static final String NAMESPACE = "default"; + + public ConfigMapDependentResource() { + super(ConfigMap.class); + } + + @Override + protected ConfigMap desired(DependentDifferentNamespaceCustomResource primary, + Context context) { + + ConfigMap configMap = new ConfigMap(); + configMap.setMetadata(new ObjectMeta()); + configMap.getMetadata().setName(primary.getMetadata().getName()); + configMap.getMetadata().setNamespace(NAMESPACE); + HashMap data = new HashMap<>(); + data.put(KEY, primary.getSpec().getValue()); + configMap.setData(data); + return configMap; + } +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/dependentdifferentnamespace/DependentDifferentNamespaceCustomResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/dependentdifferentnamespace/DependentDifferentNamespaceCustomResource.java new file mode 100644 index 0000000000..629fdca1f1 --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/dependentdifferentnamespace/DependentDifferentNamespaceCustomResource.java @@ -0,0 +1,15 @@ +package io.javaoperatorsdk.operator.sample.dependentdifferentnamespace; + +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("ddn") +public class DependentDifferentNamespaceCustomResource + extends CustomResource + implements Namespaced { +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/dependentdifferentnamespace/DependentDifferentNamespaceReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/dependentdifferentnamespace/DependentDifferentNamespaceReconciler.java new file mode 100644 index 0000000000..de9ea20f4a --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/dependentdifferentnamespace/DependentDifferentNamespaceReconciler.java @@ -0,0 +1,31 @@ +package io.javaoperatorsdk.operator.sample.dependentdifferentnamespace; + +import java.util.concurrent.atomic.AtomicInteger; + +import io.javaoperatorsdk.operator.api.reconciler.*; +import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent; +import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; + +@ControllerConfiguration( + dependents = { + @Dependent(type = ConfigMapDependentResource.class), + }) +public class DependentDifferentNamespaceReconciler + implements Reconciler, + TestExecutionInfoProvider { + + private final AtomicInteger numberOfExecutions = new AtomicInteger(0); + + @Override + public UpdateControl reconcile( + DependentDifferentNamespaceCustomResource resource, + Context context) { + numberOfExecutions.addAndGet(1); + return UpdateControl.noUpdate(); + } + + public int getNumberOfExecutions() { + return numberOfExecutions.get(); + } + +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/dependentdifferentnamespace/DependentDifferentNamespaceSpec.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/dependentdifferentnamespace/DependentDifferentNamespaceSpec.java new file mode 100644 index 0000000000..a568ca4885 --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/dependentdifferentnamespace/DependentDifferentNamespaceSpec.java @@ -0,0 +1,15 @@ +package io.javaoperatorsdk.operator.sample.dependentdifferentnamespace; + +public class DependentDifferentNamespaceSpec { + + private String value; + + public String getValue() { + return value; + } + + public DependentDifferentNamespaceSpec setValue(String value) { + this.value = value; + return this; + } +}