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..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 @@ -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 @@ -505,6 +504,18 @@ default boolean useSSAToPatchPrimaryResource() { return true; } + /** + * 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#withUseSSAToAddFinalizer(boolean) + * @since 5.1.2 + */ + default boolean useSSAToAddFinalizer() { + 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..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,6 +39,7 @@ public class ConfigurationServiceOverrider { private Boolean previousAnnotationForDependentResources; private Boolean parseResourceVersions; private Boolean useSSAToPatchPrimaryResource; + private Boolean useSSAToAddFinalizer; private Boolean cloneSecondaryResourcesWhenGettingFromCache; private Set> previousAnnotationUsageBlocklist; @@ -183,6 +184,11 @@ public ConfigurationServiceOverrider withUseSSAToPatchPrimaryResource(boolean va return this; } + public ConfigurationServiceOverrider withUseSSAToAddFinalizer(boolean value) { + this.useSSAToAddFinalizer = value; + return this; + } + public ConfigurationServiceOverrider withCloneSecondaryResourcesWhenGettingFromCache( boolean value) { this.cloneSecondaryResourcesWhenGettingFromCache = value; @@ -336,6 +342,12 @@ public boolean useSSAToPatchPrimaryResource() { useSSAToPatchPrimaryResource, ConfigurationService::useSSAToPatchPrimaryResource); } + @Override + public boolean useSSAToAddFinalizer() { + return overriddenValueOrDefault( + useSSAToAddFinalizer, 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..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,6 +42,7 @@ class ReconciliationDispatcher

{ private final boolean retryConfigurationHasZeroAttempts; private final Cloner cloner; private final boolean useSSA; + private final boolean useSSAToAddFinalizer; 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(); + useSSAToAddFinalizer = configuration.getConfigurationService().useSSAToAddFinalizer(); } public ReconciliationDispatcher(Controller

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

handleReconcile( * finalizer. */ P updatedResource; - if (useSSA) { + 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 89f3655356..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 @@ -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) + .withUseSSAToAddFinalizer(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);