Skip to content

feat: add support for additional Kubernetes resource pre processors #1909

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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());
}
}
Original file line number Diff line number Diff line change
@@ -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());
}
}
Original file line number Diff line number Diff line change
@@ -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());
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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());
}
}
Original file line number Diff line number Diff line change
@@ -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());
}
}
Original file line number Diff line number Diff line change
@@ -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());
}
}
Original file line number Diff line number Diff line change
@@ -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());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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");
Expand Down