Skip to content

Commit adf42d3

Browse files
committed
fix: improve missing CRD detection
If starting the event source throws a 404 error, this means that there is no API endpoint to handle the resource on the server. This is indicative of the associated CRD not being deployed yet. We therefore need to handle this case to throw a MissingCRDException. Since we don't have the needed CRD information at the point of the exception, we let the exception trickle up and provide the information (crd name and version) where we know about it. Fixes #460
1 parent 5eab911 commit adf42d3

File tree

2 files changed

+32
-16
lines changed

2 files changed

+32
-16
lines changed

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

+24-16
Original file line numberDiff line numberDiff line change
@@ -122,35 +122,30 @@ public <R extends CustomResource> void register(
122122

123123
Class<R> resClass = configuration.getCustomResourceClass();
124124
final String controllerName = configuration.getName();
125+
final var crdName = configuration.getCRDName();
126+
final var specVersion = "v1";
125127

126128
// check that the custom resource is known by the cluster if configured that way
127129
final CustomResourceDefinition crd; // todo: check proper CRD spec version based on config
128130
if (configurationService.checkCRDAndValidateLocalModel()) {
129-
final var crdName = configuration.getCRDName();
130-
final var specVersion = "v1";
131131
crd = k8sClient.apiextensions().v1().customResourceDefinitions().withName(crdName).get();
132132
if (crd == null) {
133-
throw new MissingCRDException(
134-
crdName,
135-
specVersion,
136-
"'"
137-
+ crdName
138-
+ "' "
139-
+ specVersion
140-
+ " CRD was not found on the cluster, controller '"
141-
+ controllerName
142-
+ "' cannot be registered");
133+
throwMissingCRDException(crdName, specVersion, controllerName);
143134
}
144135

145136
// Apply validations that are not handled by fabric8
146137
CustomResourceUtils.assertCustomResource(resClass, crd);
147138
}
148139

149140
final var client = k8sClient.customResources(resClass);
150-
DefaultEventSourceManager eventSourceManager =
151-
new DefaultEventSourceManager(controller, configuration, client);
152-
controller.init(eventSourceManager);
153-
closeables.add(eventSourceManager);
141+
try {
142+
DefaultEventSourceManager eventSourceManager =
143+
new DefaultEventSourceManager(controller, configuration, client);
144+
controller.init(eventSourceManager);
145+
closeables.add(eventSourceManager);
146+
} catch (MissingCRDException e) {
147+
throwMissingCRDException(crdName, specVersion, controllerName);
148+
}
154149

155150
if (failOnMissingCurrentNS(configuration)) {
156151
throw new OperatorException(
@@ -171,6 +166,19 @@ public <R extends CustomResource> void register(
171166
}
172167
}
173168

169+
private void throwMissingCRDException(String crdName, String specVersion, String controllerName) {
170+
throw new MissingCRDException(
171+
crdName,
172+
specVersion,
173+
"'"
174+
+ crdName
175+
+ "' "
176+
+ specVersion
177+
+ " CRD was not found on the cluster, controller '"
178+
+ controllerName
179+
+ "' cannot be registered");
180+
}
181+
174182
/**
175183
* Determines whether we should fail because the current namespace is request as target namespace
176184
* but is missing

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/DefaultEventSourceManager.java

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

33
import io.fabric8.kubernetes.api.model.KubernetesResourceList;
44
import io.fabric8.kubernetes.client.CustomResource;
5+
import io.fabric8.kubernetes.client.KubernetesClientException;
56
import io.fabric8.kubernetes.client.dsl.MixedOperation;
67
import io.fabric8.kubernetes.client.dsl.Resource;
8+
import io.javaoperatorsdk.operator.MissingCRDException;
79
import io.javaoperatorsdk.operator.OperatorException;
810
import io.javaoperatorsdk.operator.api.ResourceController;
911
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
@@ -90,6 +92,12 @@ public final void registerEventSource(String name, EventSource eventSource)
9092
// leave untouched
9193
throw e;
9294
}
95+
if (e instanceof KubernetesClientException) {
96+
KubernetesClientException ke = (KubernetesClientException) e;
97+
if (404 == ke.getCode()) {
98+
throw new MissingCRDException(null, null);
99+
}
100+
}
93101
throw new OperatorException("Couldn't register event source named '" + name + "'", e);
94102
} finally {
95103
lock.unlock();

0 commit comments

Comments
 (0)