1
1
package io .javaoperatorsdk .operator ;
2
2
3
- import io .fabric8 .kubernetes .api .model .apiextensions .v1 .CustomResourceDefinition ;
4
- import io .fabric8 .kubernetes .client .CustomResource ;
5
- import io .fabric8 .kubernetes .client .KubernetesClient ;
6
- import io .fabric8 .kubernetes .client .Version ;
7
- import io .javaoperatorsdk .operator .api .ResourceController ;
8
- import io .javaoperatorsdk .operator .api .config .ConfigurationService ;
9
- import io .javaoperatorsdk .operator .api .config .ControllerConfiguration ;
10
- import io .javaoperatorsdk .operator .processing .event .DefaultEventSourceManager ;
11
3
import java .io .Closeable ;
12
4
import java .io .IOException ;
13
5
import java .util .ArrayList ;
14
6
import java .util .List ;
15
- import java . util . Objects ;
7
+
16
8
import org .slf4j .Logger ;
17
9
import org .slf4j .LoggerFactory ;
18
10
11
+ import io .fabric8 .kubernetes .client .CustomResource ;
12
+ import io .fabric8 .kubernetes .client .KubernetesClient ;
13
+ import io .fabric8 .kubernetes .client .Version ;
14
+ import io .javaoperatorsdk .operator .api .ResourceController ;
15
+ import io .javaoperatorsdk .operator .api .config .ConfigurationService ;
16
+ import io .javaoperatorsdk .operator .api .config .ControllerConfiguration ;
17
+ import io .javaoperatorsdk .operator .processing .ConfiguredController ;
18
+
19
19
@ SuppressWarnings ("rawtypes" )
20
20
public class Operator implements AutoCloseable {
21
21
private static final Logger log = LoggerFactory .getLogger (Operator .class );
22
22
private final KubernetesClient k8sClient ;
23
23
private final ConfigurationService configurationService ;
24
- private final List <Closeable > closeables ;
25
24
private final Object lock ;
26
- private final List <ControllerRef > controllers ;
25
+ private final List <ConfiguredController > controllers ;
27
26
private volatile boolean started ;
28
27
private final Metrics metrics ;
29
28
30
29
public Operator (
31
30
KubernetesClient k8sClient , ConfigurationService configurationService , Metrics metrics ) {
32
31
this .k8sClient = k8sClient ;
33
32
this .configurationService = configurationService ;
34
- this .closeables = new ArrayList <>();
35
33
this .lock = new Object ();
36
34
this .controllers = new ArrayList <>();
37
35
this .started = false ;
@@ -89,9 +87,7 @@ public void start() {
89
87
throw new OperatorException ("Error retrieving the server version" , e );
90
88
}
91
89
92
- for (ControllerRef ref : controllers ) {
93
- startController (ref .controller , ref .configuration );
94
- }
90
+ controllers .forEach (ConfiguredController ::start );
95
91
96
92
started = true ;
97
93
}
@@ -108,7 +104,7 @@ public void close() {
108
104
log .info (
109
105
"Operator SDK {} is shutting down..." , configurationService .getVersion ().getSdkVersion ());
110
106
111
- for (Closeable closeable : this .closeables ) {
107
+ for (Closeable closeable : this .controllers ) {
112
108
try {
113
109
log .debug ("closing {}" , closeable );
114
110
closeable .close ();
@@ -150,32 +146,6 @@ public <R extends CustomResource> void register(ResourceController<R> controller
150
146
public <R extends CustomResource > void register (
151
147
ResourceController <R > controller , ControllerConfiguration <R > configuration )
152
148
throws OperatorException {
153
- synchronized (lock ) {
154
- if (!started ) {
155
- this .controllers .add (new ControllerRef (controller , configuration ));
156
- } else {
157
- this .controllers .add (new ControllerRef (controller , configuration ));
158
- startController (controller , configuration );
159
- }
160
- }
161
- }
162
-
163
- /**
164
- * Registers the specified controller with this operator, overriding its default configuration by
165
- * the specified one (usually created via
166
- * {@link io.javaoperatorsdk.operator.api.config.ControllerConfigurationOverrider#override(ControllerConfiguration)},
167
- * passing it the controller's original configuration.
168
- *
169
- * @param controller the controller to register
170
- * @param configuration the configuration with which we want to register the controller, if {@code
171
- * null}, the controller's original configuration is used
172
- * @param <R> the {@code CustomResource} type associated with the controller
173
- * @throws OperatorException if a problem occurred during the registration process
174
- */
175
- private <R extends CustomResource > void startController (
176
- ResourceController <R > controller , ControllerConfiguration <R > configuration )
177
- throws OperatorException {
178
-
179
149
final var existing = configurationService .getConfigurationFor (controller );
180
150
if (existing == null ) {
181
151
log .warn (
@@ -188,39 +158,13 @@ private <R extends CustomResource> void startController(
188
158
if (configuration == null ) {
189
159
configuration = existing ;
190
160
}
191
-
192
- final Class <R > resClass = configuration .getCustomResourceClass ();
193
- final String controllerName = configuration .getName ();
194
- final var crdName = configuration .getCRDName ();
195
- final var specVersion = "v1" ;
196
-
197
- // check that the custom resource is known by the cluster if configured that way
198
- final CustomResourceDefinition crd ; // todo: check proper CRD spec version based on config
199
- if (configurationService .checkCRDAndValidateLocalModel ()) {
200
- crd = k8sClient .apiextensions ().v1 ().customResourceDefinitions ().withName (crdName ).get ();
201
- if (crd == null ) {
202
- throwMissingCRDException (crdName , specVersion , controllerName );
161
+ synchronized (lock ) {
162
+ final var configuredController =
163
+ new ConfiguredController (controller , configuration , k8sClient );
164
+ this .controllers .add (configuredController );
165
+ if (started ) {
166
+ configuredController .start ();
203
167
}
204
-
205
- // Apply validations that are not handled by fabric8
206
- CustomResourceUtils .assertCustomResource (resClass , crd );
207
- }
208
-
209
- try {
210
- DefaultEventSourceManager eventSourceManager =
211
- new DefaultEventSourceManager (
212
- controller , configuration , k8sClient .customResources (resClass ));
213
- controller .init (eventSourceManager );
214
- closeables .add (eventSourceManager );
215
- } catch (MissingCRDException e ) {
216
- throwMissingCRDException (crdName , specVersion , controllerName );
217
- }
218
-
219
- if (failOnMissingCurrentNS (configuration )) {
220
- throw new OperatorException (
221
- "Controller '"
222
- + controllerName
223
- + "' is configured to watch the current namespace but it couldn't be inferred from the current configuration." );
224
168
}
225
169
226
170
final var watchedNS =
@@ -229,49 +173,9 @@ private <R extends CustomResource> void startController(
229
173
: configuration .getEffectiveNamespaces ();
230
174
log .info (
231
175
"Registered Controller: '{}' for CRD: '{}' for namespace(s): {}" ,
232
- controllerName ,
233
- resClass ,
176
+ configuration . getName () ,
177
+ configuration . getCustomResourceClass () ,
234
178
watchedNS );
235
179
}
236
180
}
237
-
238
- private void throwMissingCRDException (String crdName , String specVersion , String controllerName ) {
239
- throw new MissingCRDException (
240
- crdName ,
241
- specVersion ,
242
- "'"
243
- + crdName
244
- + "' "
245
- + specVersion
246
- + " CRD was not found on the cluster, controller '"
247
- + controllerName
248
- + "' cannot be registered" );
249
- }
250
-
251
- /**
252
- * Determines whether we should fail because the current namespace is request as target namespace
253
- * but is missing
254
- *
255
- * @return {@code true} if the current namespace is requested but is missing, {@code false}
256
- * otherwise
257
- */
258
- private static <R extends CustomResource > boolean failOnMissingCurrentNS (
259
- ControllerConfiguration <R > configuration ) {
260
- if (configuration .watchCurrentNamespace ()) {
261
- final var effectiveNamespaces = configuration .getEffectiveNamespaces ();
262
- return effectiveNamespaces .size () == 1
263
- && effectiveNamespaces .stream ().allMatch (Objects ::isNull );
264
- }
265
- return false ;
266
- }
267
-
268
- private static class ControllerRef {
269
- public final ResourceController controller ;
270
- public final ControllerConfiguration configuration ;
271
-
272
- public ControllerRef (ResourceController controller , ControllerConfiguration configuration ) {
273
- this .controller = controller ;
274
- this .configuration = configuration ;
275
- }
276
- }
277
181
}
0 commit comments