diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java index 382ac7525c..8a74690f1e 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java @@ -37,10 +37,15 @@ public abstract class KubernetesDependentResource> { private static final Logger log = LoggerFactory.getLogger(KubernetesDependentResource.class); + private final boolean garbageCollected = this instanceof GarbageCollected; private KubernetesDependentResourceConfig kubernetesDependentResourceConfig; private volatile Boolean useSSA; + private SSABasedGenericKubernetesResourceMatcher matcher = + SSABasedGenericKubernetesResourceMatcher.getInstance(); + private volatile boolean matcherSet = false; + public KubernetesDependentResource(Class resourceType) { this(resourceType, null); } @@ -49,11 +54,26 @@ public KubernetesDependentResource(Class resourceType, String name) { super(resourceType, name); } + public KubernetesDependentResource( + Class resourceType, String name, SSABasedGenericKubernetesResourceMatcher matcher) { + this(resourceType, name); + this.matcher = matcher; + matcherSet = true; + } + @Override public void configureWith(KubernetesDependentResourceConfig config) { this.kubernetesDependentResourceConfig = config; } + public void setMatcher(SSABasedGenericKubernetesResourceMatcher matcher) { + if (matcherSet) { + throw new IllegalStateException("Can only set a matcher once."); + } + this.matcher = matcher; + matcherSet = true; + } + @SuppressWarnings("unused") public R create(R desired, P primary, Context

context) { if (useSSA(context)) { @@ -111,9 +131,7 @@ public Result match(R actualResource, R desired, P primary, Context

contex final boolean matches; addMetadata(true, actualResource, desired, primary, context); if (useSSA(context)) { - matches = - SSABasedGenericKubernetesResourceMatcher.getInstance() - .matches(actualResource, desired, context); + matches = matcher.matches(actualResource, desired, context); } else { matches = GenericKubernetesResourceMatcher.match(desired, actualResource, false, false, context) diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/SSABasedGenericKubernetesResourceMatcherTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/SSABasedGenericKubernetesResourceMatcherTest.java index 176531344c..64b91225e8 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/SSABasedGenericKubernetesResourceMatcherTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/SSABasedGenericKubernetesResourceMatcherTest.java @@ -22,6 +22,7 @@ import io.javaoperatorsdk.operator.api.reconciler.Context; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -39,6 +40,7 @@ void setup() { when(mockedContext.getClient()).thenReturn(client); final var configurationService = mock(ConfigurationService.class); + when(configurationService.shouldUseSSA(any(), any(), any())).thenReturn(true); final var controllerConfiguration = mock(ControllerConfiguration.class); when(controllerConfiguration.getConfigurationService()).thenReturn(configurationService); when(controllerConfiguration.fieldManager()).thenReturn("controller"); @@ -239,17 +241,30 @@ void testSanitizeState_daemonSetWithResources_withMismatch() { @ParameterizedTest @ValueSource(booleans = {true, false}) void testCustomMatcher_returnsExpectedMatchBasedOnReadOnlyLabel(boolean readOnly) { + var dr = new ConfigMapDR(); var desiredConfigMap = loadResource("configmap.empty-owner-reference-desired.yaml", ConfigMap.class); desiredConfigMap.getData().put("key1", "another value"); var actualConfigMap = loadResource("configmap.empty-owner-reference.yaml", ConfigMap.class); actualConfigMap.getMetadata().getLabels().put("readonly", Boolean.toString(readOnly)); - var matcher = new ReadOnlyAwareMatcher(); - assertThat(matcher.matches(actualConfigMap, desiredConfigMap, mockedContext)) + ConfigMap ignoredPrimary = null; + assertThat( + dr.match( + actualConfigMap, + desiredConfigMap, + ignoredPrimary, + (Context) mockedContext) + .matched()) .isEqualTo(readOnly); } + private static class ConfigMapDR extends KubernetesDependentResource { + public ConfigMapDR() { + super(ConfigMap.class, "foo", new ReadOnlyAwareMatcher<>()); + } + } + private static class ReadOnlyAwareMatcher extends SSABasedGenericKubernetesResourceMatcher { @Override