Skip to content

Commit 63b8cd9

Browse files
authored
Support Standard Kuberentes Resources not just CustomResource (#678)
1 parent 3d1f4a0 commit 63b8cd9

File tree

66 files changed

+624
-474
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+624
-474
lines changed

Diff for: docs/documentation/features.md

+7
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,13 @@ mostly for the cases when there is a long waiting period after a delete operatio
110110
you might want to either schedule a timed event to make sure the
111111
`deleteResource` is executed again or use event sources get notified about the state changes of a deleted resource.
112112

113+
## Automatic Observed Generation Handling
114+
115+
## Support for Well Known (non-custom) Kubernetes Resources
116+
117+
A Controller can be registered for a non-custom resource, so well known Kubernetes resources like (
118+
Ingress,Deployment,...). Note that automatic observed generation handling is not supported for these resources.
119+
113120
## Automatic Retries on Error
114121

115122
When an exception is thrown from a controller, the framework will schedule an automatic retry of the reconciliation. The

Diff for: micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetrics.java

+9-9
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88
import io.javaoperatorsdk.operator.api.monitoring.Metrics;
99
import io.javaoperatorsdk.operator.api.reconciler.RetryInfo;
10-
import io.javaoperatorsdk.operator.processing.event.CustomResourceID;
1110
import io.javaoperatorsdk.operator.processing.event.Event;
11+
import io.javaoperatorsdk.operator.processing.event.ResourceID;
1212
import io.micrometer.core.instrument.MeterRegistry;
1313
import io.micrometer.core.instrument.Timer;
1414

@@ -53,38 +53,38 @@ public void receivedEvent(Event event) {
5353
}
5454

5555
@Override
56-
public void cleanupDoneFor(CustomResourceID customResourceUid) {
56+
public void cleanupDoneFor(ResourceID customResourceUid) {
5757
incrementCounter(customResourceUid, "events.delete");
5858
}
5959

60-
public void reconcileCustomResource(CustomResourceID customResourceID,
60+
public void reconcileCustomResource(ResourceID resourceID,
6161
RetryInfo retryInfo) {
62-
incrementCounter(customResourceID, RECONCILIATIONS + "started",
62+
incrementCounter(resourceID, RECONCILIATIONS + "started",
6363
RECONCILIATIONS + "retries.number", "" + retryInfo.getAttemptCount(),
6464
RECONCILIATIONS + "retries.last", "" + retryInfo.isLastAttempt());
6565
}
6666

6767
@Override
68-
public void finishedReconciliation(CustomResourceID customResourceID) {
69-
incrementCounter(customResourceID, RECONCILIATIONS + "success");
68+
public void finishedReconciliation(ResourceID resourceID) {
69+
incrementCounter(resourceID, RECONCILIATIONS + "success");
7070
}
7171

72-
public void failedReconciliation(CustomResourceID customResourceID, RuntimeException exception) {
72+
public void failedReconciliation(ResourceID resourceID, RuntimeException exception) {
7373
var cause = exception.getCause();
7474
if (cause == null) {
7575
cause = exception;
7676
} else if (cause instanceof RuntimeException) {
7777
cause = cause.getCause() != null ? cause.getCause() : cause;
7878
}
79-
incrementCounter(customResourceID, RECONCILIATIONS + "failed", "exception",
79+
incrementCounter(resourceID, RECONCILIATIONS + "failed", "exception",
8080
cause.getClass().getSimpleName());
8181
}
8282

8383
public <T extends Map<?, ?>> T monitorSizeOf(T map, String name) {
8484
return registry.gaugeMapSize(PREFIX + name + ".size", Collections.emptyList(), map);
8585
}
8686

87-
private void incrementCounter(CustomResourceID id, String counterName, String... additionalTags) {
87+
private void incrementCounter(ResourceID id, String counterName, String... additionalTags) {
8888
var tags = List.of(
8989
"name", id.getName(),
9090
"name", id.getName(), "namespace", id.getNamespace().orElse(""),

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import org.slf4j.Logger;
1010
import org.slf4j.LoggerFactory;
1111

12-
import io.fabric8.kubernetes.client.CustomResource;
12+
import io.fabric8.kubernetes.api.model.HasMetadata;
1313
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
1414
import io.fabric8.kubernetes.client.KubernetesClient;
1515
import io.fabric8.kubernetes.client.Version;
@@ -114,7 +114,7 @@ public void close() {
114114
* @param <R> the {@code CustomResource} type associated with the controller
115115
* @throws OperatorException if a problem occurred during the registration process
116116
*/
117-
public <R extends CustomResource<?, ?>> void register(Reconciler<R> controller)
117+
public <R extends HasMetadata> void register(Reconciler<R> controller)
118118
throws OperatorException {
119119
register(controller, null);
120120
}
@@ -132,7 +132,7 @@ public void close() {
132132
* @param <R> the {@code CustomResource} type associated with the controller
133133
* @throws OperatorException if a problem occurred during the registration process
134134
*/
135-
public <R extends CustomResource<?, ?>> void register(
135+
public <R extends HasMetadata> void register(
136136
Reconciler<R> reconciler, ControllerConfiguration<R> configuration)
137137
throws OperatorException {
138138
final var existing = configurationService.getConfigurationFor(reconciler);
@@ -157,7 +157,7 @@ public void close() {
157157
log.info(
158158
"Registered Controller: '{}' for CRD: '{}' for namespace(s): {}",
159159
configuration.getName(),
160-
configuration.getCustomResourceClass(),
160+
configuration.getResourceClass(),
161161
watchedNS);
162162
}
163163
}
@@ -195,7 +195,7 @@ public synchronized void stop() {
195195

196196
public synchronized void add(Controller controller) {
197197
final var configuration = controller.getConfiguration();
198-
final var crdName = configuration.getCRDName();
198+
final var crdName = configuration.getResourceTypeName();
199199
final var existing = controllers.get(crdName);
200200
if (existing != null) {
201201
throw new OperatorException("Cannot register controller '" + configuration.getName()

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import java.util.concurrent.ConcurrentHashMap;
66
import java.util.stream.Stream;
77

8-
import io.fabric8.kubernetes.client.CustomResource;
8+
import io.fabric8.kubernetes.api.model.HasMetadata;
99
import io.javaoperatorsdk.operator.ControllerUtils;
1010
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
1111

@@ -18,15 +18,15 @@ public AbstractConfigurationService(Version version) {
1818
this.version = version;
1919
}
2020

21-
protected <R extends CustomResource<?, ?>> void register(ControllerConfiguration<R> config) {
21+
protected <R extends HasMetadata> void register(ControllerConfiguration<R> config) {
2222
put(config, true);
2323
}
2424

25-
protected <R extends CustomResource<?, ?>> void replace(ControllerConfiguration<R> config) {
25+
protected <R extends HasMetadata> void replace(ControllerConfiguration<R> config) {
2626
put(config, false);
2727
}
2828

29-
private <R extends CustomResource<?, ?>> void put(
29+
private <R extends HasMetadata> void put(
3030
ControllerConfiguration<R> config, boolean failIfExisting) {
3131
final var name = config.getName();
3232
if (failIfExisting) {
@@ -39,7 +39,7 @@ public AbstractConfigurationService(Version version) {
3939
config.setConfigurationService(this);
4040
}
4141

42-
protected <R extends CustomResource<?, ?>> void throwExceptionOnNameCollision(
42+
protected <R extends HasMetadata> void throwExceptionOnNameCollision(
4343
String newControllerClassName, ControllerConfiguration<R> existing) {
4444
throw new IllegalArgumentException(
4545
"Controller name '"
@@ -51,7 +51,7 @@ public AbstractConfigurationService(Version version) {
5151
}
5252

5353
@Override
54-
public <R extends CustomResource<?, ?>> ControllerConfiguration<R> getConfigurationFor(
54+
public <R extends HasMetadata> ControllerConfiguration<R> getConfigurationFor(
5555
Reconciler<R> controller) {
5656
final var key = keyFor(controller);
5757
final var configuration = configurations.get(key);
@@ -73,7 +73,7 @@ private String getControllersNameMessage() {
7373
+ ".";
7474
}
7575

76-
protected <R extends CustomResource<?, ?>> String keyFor(Reconciler<R> controller) {
76+
protected <R extends HasMetadata> String keyFor(Reconciler<R> controller) {
7777
return ControllerUtils.getNameFor(controller);
7878
}
7979

Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package io.javaoperatorsdk.operator.api.config;
22

3-
import io.fabric8.kubernetes.client.CustomResource;
3+
import io.fabric8.kubernetes.api.model.HasMetadata;
44

55
public interface Cloner {
66

7-
<T extends CustomResource<?, ?>> T clone(T object);
7+
<R extends HasMetadata> R clone(R object);
88

99
}

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.util.concurrent.ExecutorService;
55
import java.util.concurrent.Executors;
66

7+
import io.fabric8.kubernetes.api.model.HasMetadata;
78
import io.fabric8.kubernetes.client.Config;
89
import io.fabric8.kubernetes.client.CustomResource;
910
import io.javaoperatorsdk.operator.api.monitoring.Metrics;
@@ -19,10 +20,9 @@ public interface ConfigurationService {
1920
private final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
2021

2122
@Override
22-
public <T extends CustomResource<?, ?>> T clone(T object) {
23+
public HasMetadata clone(HasMetadata object) {
2324
try {
24-
return OBJECT_MAPPER.readValue(OBJECT_MAPPER.writeValueAsString(object),
25-
(Class<T>) object.getClass());
25+
return OBJECT_MAPPER.readValue(OBJECT_MAPPER.writeValueAsString(object), object.getClass());
2626
} catch (JsonProcessingException e) {
2727
throw new IllegalStateException(e);
2828
}
@@ -37,7 +37,7 @@ public interface ConfigurationService {
3737
* @return the {@link ControllerConfiguration} associated with the specified controller or {@code
3838
* null} if no configuration exists for the controller
3939
*/
40-
<R extends CustomResource<?, ?>> ControllerConfiguration<R> getConfigurationFor(
40+
<R extends HasMetadata> ControllerConfiguration<R> getConfigurationFor(
4141
Reconciler<R> controller);
4242

4343
/**

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
import java.util.Set;
44

5+
import io.fabric8.kubernetes.api.model.HasMetadata;
56
import io.fabric8.kubernetes.client.Config;
6-
import io.fabric8.kubernetes.client.CustomResource;
77
import io.javaoperatorsdk.operator.api.monitoring.Metrics;
88
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
99

@@ -61,7 +61,7 @@ public ConfigurationServiceOverrider withMetrics(Metrics metrics) {
6161
public ConfigurationService build() {
6262
return new ConfigurationService() {
6363
@Override
64-
public <R extends CustomResource<?, ?>> ControllerConfiguration<R> getConfigurationFor(
64+
public <R extends HasMetadata> ControllerConfiguration<R> getConfigurationFor(
6565
Reconciler<R> controller) {
6666
return original.getConfigurationFor(controller);
6767
}

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java

+10-9
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,24 @@
44
import java.util.Collections;
55
import java.util.Set;
66

7+
import io.fabric8.kubernetes.api.model.HasMetadata;
78
import io.fabric8.kubernetes.client.CustomResource;
89
import io.javaoperatorsdk.operator.ControllerUtils;
9-
import io.javaoperatorsdk.operator.processing.event.internal.CustomResourceEventFilter;
10-
import io.javaoperatorsdk.operator.processing.event.internal.CustomResourceEventFilters;
10+
import io.javaoperatorsdk.operator.processing.event.internal.ResourceEventFilter;
11+
import io.javaoperatorsdk.operator.processing.event.internal.ResourceEventFilters;
1112

12-
public interface ControllerConfiguration<R extends CustomResource<?, ?>> {
13+
public interface ControllerConfiguration<R extends HasMetadata> {
1314

1415
default String getName() {
1516
return ControllerUtils.getDefaultReconcilerName(getAssociatedReconcilerClassName());
1617
}
1718

18-
default String getCRDName() {
19-
return CustomResource.getCRDName(getCustomResourceClass());
19+
default String getResourceTypeName() {
20+
return CustomResource.getCRDName(getResourceClass());
2021
}
2122

2223
default String getFinalizer() {
23-
return ControllerUtils.getDefaultFinalizerName(getCRDName());
24+
return ControllerUtils.getDefaultFinalizerName(getResourceTypeName());
2425
}
2526

2627
/**
@@ -39,7 +40,7 @@ default boolean isGenerationAware() {
3940
return true;
4041
}
4142

42-
default Class<R> getCustomResourceClass() {
43+
default Class<R> getResourceClass() {
4344
ParameterizedType type = (ParameterizedType) getClass().getGenericInterfaces()[0];
4445
return (Class<R>) type.getActualTypeArguments()[0];
4546
}
@@ -110,7 +111,7 @@ default boolean useFinalizer() {
110111
*
111112
* @return filter
112113
*/
113-
default CustomResourceEventFilter<R> getEventFilter() {
114-
return CustomResourceEventFilters.passthrough();
114+
default ResourceEventFilter<R> getEventFilter() {
115+
return ResourceEventFilters.passthrough();
115116
}
116117
}

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverrider.java

+8-8
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
44
import java.util.List;
55
import java.util.Set;
66

7-
import io.fabric8.kubernetes.client.CustomResource;
8-
import io.javaoperatorsdk.operator.processing.event.internal.CustomResourceEventFilter;
7+
import io.fabric8.kubernetes.api.model.HasMetadata;
8+
import io.javaoperatorsdk.operator.processing.event.internal.ResourceEventFilter;
99

10-
public class ControllerConfigurationOverrider<R extends CustomResource<?, ?>> {
10+
public class ControllerConfigurationOverrider<R extends HasMetadata> {
1111

1212
private String finalizer;
1313
private boolean generationAware;
1414
private final Set<String> namespaces;
1515
private RetryConfiguration retry;
1616
private String labelSelector;
17-
private CustomResourceEventFilter<R> customResourcePredicate;
17+
private ResourceEventFilter<R> customResourcePredicate;
1818
private final ControllerConfiguration<R> original;
1919

2020
private ControllerConfigurationOverrider(ControllerConfiguration<R> original) {
@@ -69,7 +69,7 @@ public ControllerConfigurationOverrider<R> withLabelSelector(String labelSelecto
6969
}
7070

7171
public ControllerConfigurationOverrider<R> withCustomResourcePredicate(
72-
CustomResourceEventFilter<R> customResourcePredicate) {
72+
ResourceEventFilter<R> customResourcePredicate) {
7373
this.customResourcePredicate = customResourcePredicate;
7474
return this;
7575
}
@@ -78,18 +78,18 @@ public ControllerConfiguration<R> build() {
7878
return new DefaultControllerConfiguration<>(
7979
original.getAssociatedReconcilerClassName(),
8080
original.getName(),
81-
original.getCRDName(),
81+
original.getResourceTypeName(),
8282
finalizer,
8383
generationAware,
8484
namespaces,
8585
retry,
8686
labelSelector,
8787
customResourcePredicate,
88-
original.getCustomResourceClass(),
88+
original.getResourceClass(),
8989
original.getConfigurationService());
9090
}
9191

92-
public static <R extends CustomResource<?, ?>> ControllerConfigurationOverrider<R> override(
92+
public static <R extends HasMetadata> ControllerConfigurationOverrider<R> override(
9393
ControllerConfiguration<R> original) {
9494
return new ControllerConfigurationOverrider<>(original);
9595
}

0 commit comments

Comments
 (0)