From 6b64d94155566d40fcafaa4f91083aebecd9c412 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Wed, 30 Apr 2025 12:27:56 +0200 Subject: [PATCH 1/2] feat: allow reconcilers to override their own configuration Signed-off-by: Chris Laprun --- .../config/AbstractConfigurationService.java | 10 ++++++- .../api/config/ConfigurableReconciler.java | 7 +++++ .../config/BaseConfigurationServiceTest.java | 30 +++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurableReconciler.java diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java index 5abe6a7d03..57cd80a1ec 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java @@ -112,10 +112,18 @@ protected void throwExceptionOnNameCollision( public ControllerConfiguration getConfigurationFor( Reconciler reconciler) { final var key = keyFor(reconciler); - final var configuration = configurations.get(key); + var configuration = configurations.get(key); if (configuration == null) { logMissingReconcilerWarning(key, getReconcilersNameMessage()); + } else { + if (reconciler instanceof ConfigurableReconciler configurableReconciler) { + final var overrider = ControllerConfigurationOverrider.override(configuration); + configurableReconciler.updateConfigurationFrom(overrider); + configuration = overrider.build(); + configurations.put(key, configuration); + } } + return configuration; } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurableReconciler.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurableReconciler.java new file mode 100644 index 0000000000..7485fff40c --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurableReconciler.java @@ -0,0 +1,7 @@ +package io.javaoperatorsdk.operator.api.config; + +import io.fabric8.kubernetes.api.model.HasMetadata; + +public interface ConfigurableReconciler

{ + void updateConfigurationFrom(ControllerConfigurationOverrider

configOverrider); +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/BaseConfigurationServiceTest.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/BaseConfigurationServiceTest.java index 2f202436ff..4fbe037519 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/BaseConfigurationServiceTest.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/BaseConfigurationServiceTest.java @@ -17,6 +17,8 @@ import io.javaoperatorsdk.operator.ReconcilerUtils; import io.javaoperatorsdk.operator.api.config.AnnotationConfigurable; import io.javaoperatorsdk.operator.api.config.BaseConfigurationService; +import io.javaoperatorsdk.operator.api.config.ConfigurableReconciler; +import io.javaoperatorsdk.operator.api.config.ControllerConfigurationOverrider; import io.javaoperatorsdk.operator.api.config.dependent.ConfigurationConverter; import io.javaoperatorsdk.operator.api.config.dependent.Configured; import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec; @@ -311,6 +313,34 @@ void shouldUseSSAShouldAlsoWorkWithManualConfiguration() { configurationService.shouldUseSSA(reconciler.getSsaConfigMapDependent())); } + @Test + void shouldOverrideConfigurationForConfigurableReconciler() { + final var reconciler = new TestConfigurableReconciler(); + var config = configurationService.getConfigurationFor(reconciler); + assertThat(config.getInformerConfig().getLabelSelector()).isNull(); + + config = configurationService.getConfigurationFor(reconciler); + assertThat(config.getInformerConfig().getLabelSelector()) + .isEqualTo(TestConfigurableReconciler.selector); + } + + private static class TestConfigurableReconciler + implements Reconciler, ConfigurableReconciler { + private static final String selector = "foo=bar"; + + @Override + public UpdateControl reconcile(ConfigMap resource, Context context) + throws Exception { + return null; + } + + @Override + public void updateConfigurationFrom( + ControllerConfigurationOverrider configOverrider) { + configOverrider.withLabelSelector(selector); + } + } + @SuppressWarnings("unchecked") private static int getValue( io.javaoperatorsdk.operator.api.config.ControllerConfiguration configuration, int index) { From fa231918f3dbee3719e452e61912d0091723e919 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Sat, 3 May 2025 20:15:50 +0200 Subject: [PATCH 2/2] docs: add javadoc Signed-off-by: Chris Laprun --- .../config/AbstractConfigurationService.java | 1 + .../api/config/ConfigurableReconciler.java | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java index 57cd80a1ec..196b3f601a 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java @@ -116,6 +116,7 @@ public ControllerConfiguration getConfigurationFor( if (configuration == null) { logMissingReconcilerWarning(key, getReconcilersNameMessage()); } else { + // if a reconciler is also a ConfigurableReconciler, update and replace its configuration if (reconciler instanceof ConfigurableReconciler configurableReconciler) { final var overrider = ControllerConfigurationOverrider.override(configuration); configurableReconciler.updateConfigurationFrom(overrider); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurableReconciler.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurableReconciler.java index 7485fff40c..cd13b39bd7 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurableReconciler.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurableReconciler.java @@ -1,7 +1,25 @@ package io.javaoperatorsdk.operator.api.config; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +/** + * Implement to change a {@link io.javaoperatorsdk.operator.api.reconciler.Reconciler}'s + * configuration at runtime + * + * @param

the primary resource type of the reconciler + * @since 5.1 + */ public interface ConfigurableReconciler

{ + /** + * Updates the reconciler's configuration by applying the modifications specified by the provided + * {@link ControllerConfigurationOverrider} and then replacing the existing configuration in the + * {@link ConfigurationService} for this reconciler. Note that this method will not be applied if + * there is no configuration (as determined by {@link + * ConfigurationService#getConfigurationFor(Reconciler)} for the reconciler. + * + * @param configOverrider provides the modifications to apply to the existing reconciler's + * configuration + */ void updateConfigurationFrom(ControllerConfigurationOverrider

configOverrider); }