From 5b411e537bb49aabf7ba7af3b0c52e742ab3142a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Mon, 30 Jun 2025 15:14:43 +0200 Subject: [PATCH 1/4] feat: add feature switch to use SSA for managing finalizer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Attila Mészáros --- .../operator/api/config/ConfigurationService.java | 15 +++++++++++++++ .../api/config/ConfigurationServiceOverrider.java | 12 ++++++++++++ .../event/ReconciliationDispatcher.java | 4 +++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java index 864b65c3f7..34b07064ce 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java @@ -505,6 +505,21 @@ default boolean useSSAToPatchPrimaryResource() { return true; } + /** + * {@link io.javaoperatorsdk.operator.api.reconciler.UpdateControl} patch resource or status can + * either use simple patches or SSA. Setting this to {@code true}, controllers will use SSA for + * adding finalizers, patching resources and status. + * + * @return {@code true} if Server-Side Apply (SSA) should be used when managing finalizers, + * {@code false} otherwise + * @see ConfigurationServiceOverrider#withUseSSAToManageFinalizer(boolean) + * @since 5.1.2 + */ + default boolean useSSAToManageFinalizer() { + return true; + } + + /** * Determines whether resources retrieved from caches such as via calls to {@link * Context#getSecondaryResource(Class)} should be defensively cloned first. diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java index be86cbe312..bf2d41f53f 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java @@ -39,6 +39,7 @@ public class ConfigurationServiceOverrider { private Boolean previousAnnotationForDependentResources; private Boolean parseResourceVersions; private Boolean useSSAToPatchPrimaryResource; + private Boolean useSSAToManageFinalizer; private Boolean cloneSecondaryResourcesWhenGettingFromCache; private Set> previousAnnotationUsageBlocklist; @@ -183,6 +184,11 @@ public ConfigurationServiceOverrider withUseSSAToPatchPrimaryResource(boolean va return this; } + public ConfigurationServiceOverrider withUseSSAToManageFinalizer(boolean value) { + this.useSSAToManageFinalizer = value; + return this; + } + public ConfigurationServiceOverrider withCloneSecondaryResourcesWhenGettingFromCache( boolean value) { this.cloneSecondaryResourcesWhenGettingFromCache = value; @@ -336,6 +342,12 @@ public boolean useSSAToPatchPrimaryResource() { useSSAToPatchPrimaryResource, ConfigurationService::useSSAToPatchPrimaryResource); } + @Override + public boolean useSSAToManageFinalizer() { + return overriddenValueOrDefault( + useSSAToManageFinalizer, ConfigurationService::useSSAToPatchPrimaryResource); + } + @Override public boolean cloneSecondaryResourcesWhenGettingFromCache() { return overriddenValueOrDefault( diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcher.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcher.java index c4b161ef27..d3290b5edb 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcher.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcher.java @@ -42,6 +42,7 @@ class ReconciliationDispatcher

{ private final boolean retryConfigurationHasZeroAttempts; private final Cloner cloner; private final boolean useSSA; + private final boolean useSSAForFinalizer; ReconciliationDispatcher(Controller

controller, CustomResourceFacade

customResourceFacade) { this.controller = controller; @@ -52,6 +53,7 @@ class ReconciliationDispatcher

{ var retry = configuration.getRetry(); retryConfigurationHasZeroAttempts = retry == null || retry.initExecution().isLastAttempt(); useSSA = configuration.getConfigurationService().useSSAToPatchPrimaryResource(); + useSSAForFinalizer = configuration.getConfigurationService().useSSAToManageFinalizer(); } public ReconciliationDispatcher(Controller

controller) { @@ -119,7 +121,7 @@ private PostExecutionControl

handleReconcile( * finalizer. */ P updatedResource; - if (useSSA) { + if (useSSAForFinalizer) { updatedResource = addFinalizerWithSSA(originalResource); } else { updatedResource = updateCustomResourceWithFinalizer(resourceForExecution, originalResource); From bcf6227b5a2f111b177ef212ed04eabd188f41cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Mon, 30 Jun 2025 15:29:16 +0200 Subject: [PATCH 2/4] test fix: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Attila Mészáros --- .../api/config/ConfigurationService.java | 5 ++--- .../config/ConfigurationServiceOverrider.java | 2 +- .../event/ReconciliationDispatcherTest.java | 17 +++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java index 34b07064ce..2efd516a3c 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java @@ -510,8 +510,8 @@ default boolean useSSAToPatchPrimaryResource() { * either use simple patches or SSA. Setting this to {@code true}, controllers will use SSA for * adding finalizers, patching resources and status. * - * @return {@code true} if Server-Side Apply (SSA) should be used when managing finalizers, - * {@code false} otherwise + * @return {@code true} if Server-Side Apply (SSA) should be used when managing finalizers, {@code + * false} otherwise * @see ConfigurationServiceOverrider#withUseSSAToManageFinalizer(boolean) * @since 5.1.2 */ @@ -519,7 +519,6 @@ default boolean useSSAToManageFinalizer() { return true; } - /** * Determines whether resources retrieved from caches such as via calls to {@link * Context#getSecondaryResource(Class)} should be defensively cloned first. diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java index bf2d41f53f..ae78f04f11 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java @@ -345,7 +345,7 @@ public boolean useSSAToPatchPrimaryResource() { @Override public boolean useSSAToManageFinalizer() { return overriddenValueOrDefault( - useSSAToManageFinalizer, ConfigurationService::useSSAToPatchPrimaryResource); + useSSAToManageFinalizer, ConfigurationService::useSSAToPatchPrimaryResource); } @Override diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcherTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcherTest.java index 89f3655356..fd29154b91 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcherTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcherTest.java @@ -62,18 +62,18 @@ class ReconciliationDispatcherTest { @BeforeEach void setup() { - initConfigService(true); + initConfigService(true, true); testCustomResource = TestUtils.testCustomResource(); reconciler = spy(new TestReconciler()); reconciliationDispatcher = init(testCustomResource, reconciler, null, customResourceFacade, true); } - static void initConfigService(boolean useSSA) { - initConfigService(useSSA, true); + static void initConfigService(boolean useSSA, boolean useSSAForFinalizer) { + initConfigService(useSSA, useSSAForFinalizer, true); } - static void initConfigService(boolean useSSA, boolean noCloning) { + static void initConfigService(boolean useSSA, boolean useSSAForFinalizer, boolean noCloning) { /* * We need this for mock reconcilers to properly generate the expected UpdateControl: without * this, calls such as `when(reconciler.reconcile(eq(testCustomResource), @@ -98,7 +98,8 @@ public R clone(R object) { } } }) - .withUseSSAToPatchPrimaryResource(useSSA)); + .withUseSSAToPatchPrimaryResource(useSSA) + .withUseSSAToManageFinalizer(useSSAForFinalizer)); } private ReconciliationDispatcher init( @@ -149,7 +150,7 @@ void addFinalizerOnNewResource() { @Test void addFinalizerOnNewResourceWithoutSSA() { - initConfigService(false); + initConfigService(false, false); final ReconciliationDispatcher dispatcher = init(testCustomResource, reconciler, null, customResourceFacade, true); @@ -640,7 +641,7 @@ void canSkipSchedulingMaxDelayIf() { @Test void retriesAddingFinalizerWithoutSSA() { - initConfigService(false); + initConfigService(true, false); reconciliationDispatcher = init(testCustomResource, reconciler, null, customResourceFacade, true); @@ -683,7 +684,7 @@ void reSchedulesFromErrorHandler() { @Test void reconcilerContextUsesTheSameInstanceOfResourceAsParam() { - initConfigService(false, false); + initConfigService(false, false, false); final ReconciliationDispatcher dispatcher = init(testCustomResource, reconciler, null, customResourceFacade, true); From 784df22cbd2dc81b77f9177ebd43605530277482 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Mon, 30 Jun 2025 15:37:03 +0200 Subject: [PATCH 3/4] javadoc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Attila Mészáros --- .../operator/api/config/ConfigurationService.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java index 2efd516a3c..e610c215f7 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java @@ -493,8 +493,7 @@ default boolean parseResourceVersionsForEventFilteringAndCaching() { /** * {@link io.javaoperatorsdk.operator.api.reconciler.UpdateControl} patch resource or status can - * either use simple patches or SSA. Setting this to {@code true}, controllers will use SSA for - * adding finalizers, patching resources and status. + * either use simple patches or SSA. Setting this to {@code true}, patching resources and status. * * @return {@code true} if Server-Side Apply (SSA) should be used when patching the primary * resources, {@code false} otherwise @@ -508,7 +507,7 @@ default boolean useSSAToPatchPrimaryResource() { /** * {@link io.javaoperatorsdk.operator.api.reconciler.UpdateControl} patch resource or status can * either use simple patches or SSA. Setting this to {@code true}, controllers will use SSA for - * adding finalizers, patching resources and status. + * adding finalizers. * * @return {@code true} if Server-Side Apply (SSA) should be used when managing finalizers, {@code * false} otherwise From 70e89100944d1f918ece206a78a18a5789817039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Mon, 30 Jun 2025 15:41:54 +0200 Subject: [PATCH 4/4] refine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Attila Mészáros --- .../operator/api/config/ConfigurationService.java | 8 +++----- .../api/config/ConfigurationServiceOverrider.java | 10 +++++----- .../processing/event/ReconciliationDispatcher.java | 6 +++--- .../processing/event/ReconciliationDispatcherTest.java | 2 +- 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java index e610c215f7..3a2e00c2a8 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java @@ -505,16 +505,14 @@ default boolean useSSAToPatchPrimaryResource() { } /** - * {@link io.javaoperatorsdk.operator.api.reconciler.UpdateControl} patch resource or status can - * either use simple patches or SSA. Setting this to {@code true}, controllers will use SSA for - * adding finalizers. + * Setting this to {@code true}, controllers will use SSA for adding finalizers. * * @return {@code true} if Server-Side Apply (SSA) should be used when managing finalizers, {@code * false} otherwise - * @see ConfigurationServiceOverrider#withUseSSAToManageFinalizer(boolean) + * @see ConfigurationServiceOverrider#withUseSSAToAddFinalizer(boolean) * @since 5.1.2 */ - default boolean useSSAToManageFinalizer() { + default boolean useSSAToAddFinalizer() { return true; } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java index ae78f04f11..47da97ee85 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java @@ -39,7 +39,7 @@ public class ConfigurationServiceOverrider { private Boolean previousAnnotationForDependentResources; private Boolean parseResourceVersions; private Boolean useSSAToPatchPrimaryResource; - private Boolean useSSAToManageFinalizer; + private Boolean useSSAToAddFinalizer; private Boolean cloneSecondaryResourcesWhenGettingFromCache; private Set> previousAnnotationUsageBlocklist; @@ -184,8 +184,8 @@ public ConfigurationServiceOverrider withUseSSAToPatchPrimaryResource(boolean va return this; } - public ConfigurationServiceOverrider withUseSSAToManageFinalizer(boolean value) { - this.useSSAToManageFinalizer = value; + public ConfigurationServiceOverrider withUseSSAToAddFinalizer(boolean value) { + this.useSSAToAddFinalizer = value; return this; } @@ -343,9 +343,9 @@ public boolean useSSAToPatchPrimaryResource() { } @Override - public boolean useSSAToManageFinalizer() { + public boolean useSSAToAddFinalizer() { return overriddenValueOrDefault( - useSSAToManageFinalizer, ConfigurationService::useSSAToPatchPrimaryResource); + useSSAToAddFinalizer, ConfigurationService::useSSAToPatchPrimaryResource); } @Override diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcher.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcher.java index d3290b5edb..93ebf77211 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcher.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcher.java @@ -42,7 +42,7 @@ class ReconciliationDispatcher

{ private final boolean retryConfigurationHasZeroAttempts; private final Cloner cloner; private final boolean useSSA; - private final boolean useSSAForFinalizer; + private final boolean useSSAToAddFinalizer; ReconciliationDispatcher(Controller

controller, CustomResourceFacade

customResourceFacade) { this.controller = controller; @@ -53,7 +53,7 @@ class ReconciliationDispatcher

{ var retry = configuration.getRetry(); retryConfigurationHasZeroAttempts = retry == null || retry.initExecution().isLastAttempt(); useSSA = configuration.getConfigurationService().useSSAToPatchPrimaryResource(); - useSSAForFinalizer = configuration.getConfigurationService().useSSAToManageFinalizer(); + useSSAToAddFinalizer = configuration.getConfigurationService().useSSAToAddFinalizer(); } public ReconciliationDispatcher(Controller

controller) { @@ -121,7 +121,7 @@ private PostExecutionControl

handleReconcile( * finalizer. */ P updatedResource; - if (useSSAForFinalizer) { + if (useSSAToAddFinalizer) { updatedResource = addFinalizerWithSSA(originalResource); } else { updatedResource = updateCustomResourceWithFinalizer(resourceForExecution, originalResource); diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcherTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcherTest.java index fd29154b91..6d5c309e83 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcherTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcherTest.java @@ -99,7 +99,7 @@ public R clone(R object) { } }) .withUseSSAToPatchPrimaryResource(useSSA) - .withUseSSAToManageFinalizer(useSSAForFinalizer)); + .withUseSSAToAddFinalizer(useSSAForFinalizer)); } private ReconciliationDispatcher init(