From 2ad39b6322b8d8c3d8172f4982f66f723964dc26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Fri, 4 Jul 2025 14:34:24 +0200 Subject: [PATCH 1/2] improve: add sample when updating the spec with SSA it removes the finalizer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit if the finalizer is not explicitly added to the fresh resource Signed-off-by: Attila Mészáros --- .../SSASpecUpdateCustomResource.java | 14 ++++++ .../SSASpecUpdateCustomResourceSpec.java | 14 ++++++ .../SSASpecUpdateCustomResourceStatus.java | 15 +++++++ .../ssaissue/specupdate/SSASpecUpdateIT.java | 39 ++++++++++++++++ .../specupdate/SSASpecUpdateReconciler.java | 45 +++++++++++++++++++ 5 files changed, 127 insertions(+) create mode 100644 operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateCustomResource.java create mode 100644 operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateCustomResourceSpec.java create mode 100644 operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateCustomResourceStatus.java create mode 100644 operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateIT.java create mode 100644 operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateReconciler.java diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateCustomResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateCustomResource.java new file mode 100644 index 0000000000..c4ee2dd1a5 --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateCustomResource.java @@ -0,0 +1,14 @@ +package io.javaoperatorsdk.operator.baseapi.ssaissue.specupdate; + +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("ssul") +public class SSASpecUpdateCustomResource + extends CustomResource + implements Namespaced {} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateCustomResourceSpec.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateCustomResourceSpec.java new file mode 100644 index 0000000000..47953ccce0 --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateCustomResourceSpec.java @@ -0,0 +1,14 @@ +package io.javaoperatorsdk.operator.baseapi.ssaissue.specupdate; + +public class SSASpecUpdateCustomResourceSpec { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateCustomResourceStatus.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateCustomResourceStatus.java new file mode 100644 index 0000000000..e5f103dc69 --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateCustomResourceStatus.java @@ -0,0 +1,15 @@ +package io.javaoperatorsdk.operator.baseapi.ssaissue.specupdate; + +public class SSASpecUpdateCustomResourceStatus { + + private Integer value = 0; + + public Integer getValue() { + return value; + } + + public SSASpecUpdateCustomResourceStatus setValue(Integer value) { + this.value = value; + return this; + } +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateIT.java new file mode 100644 index 0000000000..96a2485ebc --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateIT.java @@ -0,0 +1,39 @@ +package io.javaoperatorsdk.operator.baseapi.ssaissue.specupdate; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; +import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; + +class SSASpecUpdateIT { + + public static final String TEST_RESOURCE_NAME = "test"; + + @RegisterExtension + LocallyRunOperatorExtension operator = + LocallyRunOperatorExtension.builder().withReconciler(SSASpecUpdateReconciler.class).build(); + + @Test + void showFinalizerRemovalWhenSpecUpdated() { + SSASpecUpdateCustomResource res = createResource(); + operator.create(res); + + await() + .untilAsserted( + () -> { + var actual = operator.get(SSASpecUpdateCustomResource.class, TEST_RESOURCE_NAME); + assertThat(actual.getSpec()).isNotNull(); + assertThat(actual.getFinalizers()).isEmpty(); + }); + } + + SSASpecUpdateCustomResource createResource() { + SSASpecUpdateCustomResource res = new SSASpecUpdateCustomResource(); + res.setMetadata(new ObjectMetaBuilder().withName(TEST_RESOURCE_NAME).build()); + return res; + } +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateReconciler.java new file mode 100644 index 0000000000..afbdad752d --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateReconciler.java @@ -0,0 +1,45 @@ +package io.javaoperatorsdk.operator.baseapi.ssaissue.specupdate; + +import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; +import io.javaoperatorsdk.operator.api.reconciler.Cleaner; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.DeleteControl; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; + +@ControllerConfiguration +public class SSASpecUpdateReconciler + implements Reconciler, Cleaner { + + @Override + public UpdateControl reconcile( + SSASpecUpdateCustomResource resource, Context context) { + + var copy = createFreshCopy(resource); + copy.getSpec().setValue("value"); + context.getClient().resource(copy).fieldManager(context.getControllerConfiguration() + .fieldManager()) + .serverSideApply(); + + return UpdateControl.noUpdate(); + } + + SSASpecUpdateCustomResource createFreshCopy(SSASpecUpdateCustomResource resource) { + var res = new SSASpecUpdateCustomResource(); + res.setMetadata( + new ObjectMetaBuilder() + .withName(resource.getMetadata().getName()) + .withNamespace(resource.getMetadata().getNamespace()) + .build()); + res.setSpec(new SSASpecUpdateCustomResourceSpec()); + return res; + } + + @Override + public DeleteControl cleanup( + SSASpecUpdateCustomResource resource, Context context) { + + return DeleteControl.defaultDelete(); + } +} From 6ad00a49fb8dea0dbdc91b560ae4cfe223188636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Fri, 4 Jul 2025 14:36:32 +0200 Subject: [PATCH 2/2] format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Attila Mészáros --- .../baseapi/ssaissue/specupdate/SSASpecUpdateIT.java | 2 ++ .../ssaissue/specupdate/SSASpecUpdateReconciler.java | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateIT.java index 96a2485ebc..5f1b992259 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateIT.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateIT.java @@ -17,6 +17,8 @@ class SSASpecUpdateIT { LocallyRunOperatorExtension operator = LocallyRunOperatorExtension.builder().withReconciler(SSASpecUpdateReconciler.class).build(); + // showcases that is the spec of the resources is updated with SSA, but the finalizer + // is not explicitly added to the fresh resource it removes the finalizer @Test void showFinalizerRemovalWhenSpecUpdated() { SSASpecUpdateCustomResource res = createResource(); diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateReconciler.java index afbdad752d..483060ad59 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ssaissue/specupdate/SSASpecUpdateReconciler.java @@ -18,9 +18,11 @@ public UpdateControl reconcile( var copy = createFreshCopy(resource); copy.getSpec().setValue("value"); - context.getClient().resource(copy).fieldManager(context.getControllerConfiguration() - .fieldManager()) - .serverSideApply(); + context + .getClient() + .resource(copy) + .fieldManager(context.getControllerConfiguration().fieldManager()) + .serverSideApply(); return UpdateControl.noUpdate(); }