diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericResourceUpdatePreProcessor.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericResourceUpdatePreProcessor.java deleted file mode 100644 index e35913af68..0000000000 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericResourceUpdatePreProcessor.java +++ /dev/null @@ -1,53 +0,0 @@ -package io.javaoperatorsdk.operator.processing.dependent.kubernetes; - -import io.fabric8.kubernetes.api.model.ConfigMap; -import io.fabric8.kubernetes.api.model.HasMetadata; -import io.fabric8.kubernetes.api.model.Secret; -import io.javaoperatorsdk.operator.ReconcilerUtils; -import io.javaoperatorsdk.operator.api.config.ConfigurationServiceProvider; -import io.javaoperatorsdk.operator.api.reconciler.Context; - -public abstract class GenericResourceUpdatePreProcessor<R extends HasMetadata> implements - ResourceUpdatePreProcessor<R> { - - private GenericResourceUpdatePreProcessor() {} - - @SuppressWarnings("unchecked") - public static <R extends HasMetadata> ResourceUpdatePreProcessor<R> processorFor( - Class<R> resourceType) { - if (Secret.class.isAssignableFrom(resourceType)) { - return (ResourceUpdatePreProcessor<R>) new GenericResourceUpdatePreProcessor<Secret>() { - @Override - protected void updateClonedActual(Secret actual, Secret desired) { - actual.setData(desired.getData()); - actual.setStringData(desired.getStringData()); - } - }; - } else if (ConfigMap.class.isAssignableFrom(resourceType)) { - return (ResourceUpdatePreProcessor<R>) new GenericResourceUpdatePreProcessor<ConfigMap>() { - - @Override - protected void updateClonedActual(ConfigMap actual, ConfigMap desired) { - actual.setData(desired.getData()); - actual.setBinaryData((desired.getBinaryData())); - } - }; - } else { - return new GenericResourceUpdatePreProcessor<>() { - @Override - protected void updateClonedActual(R actual, R desired) { - var desiredSpec = ReconcilerUtils.getSpec(desired); - ReconcilerUtils.setSpec(actual, desiredSpec); - } - }; - } - } - - public R replaceSpecOnActual(R actual, R desired, Context<?> context) { - var clonedActual = ConfigurationServiceProvider.instance().getResourceCloner().clone(actual); - updateClonedActual(clonedActual, desired); - return clonedActual; - } - - protected abstract void updateClonedActual(R actual, R desired); -} 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 5e2b209a71..6a978ff429 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 @@ -24,6 +24,7 @@ import io.javaoperatorsdk.operator.processing.dependent.AbstractEventSourceHolderDependentResource; import io.javaoperatorsdk.operator.processing.dependent.Matcher; import io.javaoperatorsdk.operator.processing.dependent.Matcher.Result; +import io.javaoperatorsdk.operator.processing.dependent.kubernetes.processors.GenericResourceUpdatePreProcessor; import io.javaoperatorsdk.operator.processing.event.ResourceID; import io.javaoperatorsdk.operator.processing.event.source.SecondaryToPrimaryMapper; import io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/ClusterRoleBindingResourceUpdatePreProcessor.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/ClusterRoleBindingResourceUpdatePreProcessor.java new file mode 100644 index 0000000000..70ad11470a --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/ClusterRoleBindingResourceUpdatePreProcessor.java @@ -0,0 +1,13 @@ +package io.javaoperatorsdk.operator.processing.dependent.kubernetes.processors; + +import io.fabric8.kubernetes.api.model.rbac.ClusterRoleBinding; + +public class ClusterRoleBindingResourceUpdatePreProcessor + extends GenericResourceUpdatePreProcessor<ClusterRoleBinding> { + + @Override + protected void updateClonedActual(ClusterRoleBinding actual, ClusterRoleBinding desired) { + actual.setRoleRef(desired.getRoleRef()); + actual.setSubjects(desired.getSubjects()); + } +} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/ClusterRoleResourceUpdatePreProcessor.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/ClusterRoleResourceUpdatePreProcessor.java new file mode 100644 index 0000000000..05408a3ef7 --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/ClusterRoleResourceUpdatePreProcessor.java @@ -0,0 +1,13 @@ +package io.javaoperatorsdk.operator.processing.dependent.kubernetes.processors; + +import io.fabric8.kubernetes.api.model.rbac.ClusterRole; + +public class ClusterRoleResourceUpdatePreProcessor + extends GenericResourceUpdatePreProcessor<ClusterRole> { + + @Override + protected void updateClonedActual(ClusterRole actual, ClusterRole desired) { + actual.setAggregationRule(desired.getAggregationRule()); + actual.setRules(desired.getRules()); + } +} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/ConfigMapResourceUpdatePreProcessor.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/ConfigMapResourceUpdatePreProcessor.java new file mode 100644 index 0000000000..12087eac8e --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/ConfigMapResourceUpdatePreProcessor.java @@ -0,0 +1,14 @@ +package io.javaoperatorsdk.operator.processing.dependent.kubernetes.processors; + +import io.fabric8.kubernetes.api.model.ConfigMap; + +public class ConfigMapResourceUpdatePreProcessor + extends GenericResourceUpdatePreProcessor<ConfigMap> { + + @Override + protected void updateClonedActual(ConfigMap actual, ConfigMap desired) { + actual.setData(desired.getData()); + actual.setBinaryData((desired.getBinaryData())); + actual.setImmutable(desired.getImmutable()); + } +} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/GenericResourceUpdatePreProcessor.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/GenericResourceUpdatePreProcessor.java new file mode 100644 index 0000000000..8153166a5f --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/GenericResourceUpdatePreProcessor.java @@ -0,0 +1,53 @@ +package io.javaoperatorsdk.operator.processing.dependent.kubernetes.processors; + +import java.util.Map; + +import javax.management.relation.Role; + +import io.fabric8.kubernetes.api.model.ConfigMap; +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.fabric8.kubernetes.api.model.Secret; +import io.fabric8.kubernetes.api.model.ServiceAccount; +import io.fabric8.kubernetes.api.model.rbac.ClusterRole; +import io.fabric8.kubernetes.api.model.rbac.ClusterRoleBinding; +import io.fabric8.kubernetes.api.model.rbac.RoleBinding; +import io.javaoperatorsdk.operator.ReconcilerUtils; +import io.javaoperatorsdk.operator.api.config.ConfigurationServiceProvider; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.processing.dependent.kubernetes.ResourceUpdatePreProcessor; + +public class GenericResourceUpdatePreProcessor<R extends HasMetadata> implements + ResourceUpdatePreProcessor<R> { + private static final ResourceUpdatePreProcessor<?> INSTANCE = + new GenericResourceUpdatePreProcessor<>(); + + @SuppressWarnings("rawtypes") + private static final Map<Class, ResourceUpdatePreProcessor> processors = Map.of( + Secret.class, new SecretResourceUpdatePreProcessor(), + ConfigMap.class, new ConfigMapResourceUpdatePreProcessor(), + ServiceAccount.class, new ServiceAccountResourceUpdateProcessor(), + Role.class, new RoleResourceUpdatePreProcessor(), + ClusterRole.class, new ClusterRoleResourceUpdatePreProcessor(), + RoleBinding.class, new RoleBindingResourceUpdatePreProcessor(), + ClusterRoleBinding.class, new ClusterRoleBindingResourceUpdatePreProcessor()); + + protected GenericResourceUpdatePreProcessor() {} + + @SuppressWarnings("unchecked") + public static <R extends HasMetadata> ResourceUpdatePreProcessor<R> processorFor( + Class<R> resourceType) { + final var processor = processors.get(resourceType); + return processor != null ? processor : (ResourceUpdatePreProcessor<R>) INSTANCE; + } + + public R replaceSpecOnActual(R actual, R desired, Context<?> context) { + var clonedActual = ConfigurationServiceProvider.instance().getResourceCloner().clone(actual); + updateClonedActual(clonedActual, desired); + return clonedActual; + } + + protected void updateClonedActual(R actual, R desired) { + var desiredSpec = ReconcilerUtils.getSpec(desired); + ReconcilerUtils.setSpec(actual, desiredSpec); + } +} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/RoleBindingResourceUpdatePreProcessor.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/RoleBindingResourceUpdatePreProcessor.java new file mode 100644 index 0000000000..cdd1c9458e --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/RoleBindingResourceUpdatePreProcessor.java @@ -0,0 +1,13 @@ +package io.javaoperatorsdk.operator.processing.dependent.kubernetes.processors; + +import io.fabric8.kubernetes.api.model.rbac.RoleBinding; + +public class RoleBindingResourceUpdatePreProcessor + extends GenericResourceUpdatePreProcessor<RoleBinding> { + + @Override + protected void updateClonedActual(RoleBinding actual, RoleBinding desired) { + actual.setRoleRef(desired.getRoleRef()); + actual.setSubjects(desired.getSubjects()); + } +} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/RoleResourceUpdatePreProcessor.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/RoleResourceUpdatePreProcessor.java new file mode 100644 index 0000000000..786cb9f098 --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/RoleResourceUpdatePreProcessor.java @@ -0,0 +1,11 @@ +package io.javaoperatorsdk.operator.processing.dependent.kubernetes.processors; + +import io.fabric8.kubernetes.api.model.rbac.Role; + +public class RoleResourceUpdatePreProcessor extends GenericResourceUpdatePreProcessor<Role> { + + @Override + protected void updateClonedActual(Role actual, Role desired) { + actual.setRules(desired.getRules()); + } +} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/SecretResourceUpdatePreProcessor.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/SecretResourceUpdatePreProcessor.java new file mode 100644 index 0000000000..68bf012c65 --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/SecretResourceUpdatePreProcessor.java @@ -0,0 +1,14 @@ +package io.javaoperatorsdk.operator.processing.dependent.kubernetes.processors; + +import io.fabric8.kubernetes.api.model.Secret; + +public class SecretResourceUpdatePreProcessor extends GenericResourceUpdatePreProcessor<Secret> { + + @Override + protected void updateClonedActual(Secret actual, Secret desired) { + actual.setData(desired.getData()); + actual.setStringData(desired.getStringData()); + actual.setImmutable(desired.getImmutable()); + actual.setType(desired.getType()); + } +} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/ServiceAccountResourceUpdateProcessor.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/ServiceAccountResourceUpdateProcessor.java new file mode 100644 index 0000000000..b4d4582ace --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/processors/ServiceAccountResourceUpdateProcessor.java @@ -0,0 +1,14 @@ +package io.javaoperatorsdk.operator.processing.dependent.kubernetes.processors; + +import io.fabric8.kubernetes.api.model.ServiceAccount; + +public class ServiceAccountResourceUpdateProcessor + extends GenericResourceUpdatePreProcessor<ServiceAccount> { + + @Override + protected void updateClonedActual(ServiceAccount actual, ServiceAccount desired) { + actual.setAutomountServiceAccountToken(desired.getAutomountServiceAccountToken()); + actual.setImagePullSecrets(desired.getImagePullSecrets()); + actual.setSecrets(desired.getSecrets()); + } +} diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericResourceUpdatePreProcessorTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericResourceUpdatePreProcessorTest.java index 9f1856edbc..4be7e07b25 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericResourceUpdatePreProcessorTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericResourceUpdatePreProcessorTest.java @@ -9,10 +9,13 @@ import io.fabric8.kubernetes.api.model.Namespace; import io.fabric8.kubernetes.api.model.NamespaceBuilder; import io.fabric8.kubernetes.api.model.NamespaceSpec; +import io.fabric8.kubernetes.api.model.Secret; +import io.fabric8.kubernetes.api.model.SecretBuilder; import io.fabric8.kubernetes.api.model.apps.Deployment; import io.javaoperatorsdk.operator.ReconcilerUtils; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.processing.dependent.kubernetes.processors.GenericResourceUpdatePreProcessor; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -74,6 +77,19 @@ void checkNamespaces() { assertThat(result.getSpec()).isNull(); } + @Test + void checkSecret() { + var processor = GenericResourceUpdatePreProcessor.processorFor(Secret.class); + var desired = + new SecretBuilder().withImmutable().withType("Opaque").addToData("foo", "bar").build(); + var actual = new SecretBuilder().build(); + + final var secret = processor.replaceSpecOnActual(actual, desired, context); + assertThat(secret.getImmutable()).isTrue(); + assertThat(secret.getType()).isEqualTo("Opaque"); + assertThat(secret.getData()).containsOnlyKeys("foo"); + } + Deployment createDeployment() { return ReconcilerUtils.loadYaml( Deployment.class, GenericResourceUpdatePreProcessorTest.class, "nginx-deployment.yaml");