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
29
28
public Operator (KubernetesClient k8sClient , ConfigurationService configurationService ) {
30
29
this .k8sClient = k8sClient ;
31
30
this .configurationService = configurationService ;
32
- this .closeables = new ArrayList <>();
33
31
this .lock = new Object ();
34
32
this .controllers = new ArrayList <>();
35
33
this .started = false ;
@@ -82,9 +80,7 @@ public void start() {
82
80
throw new OperatorException ("Error retrieving the server version" , e );
83
81
}
84
82
85
- for (ControllerRef ref : controllers ) {
86
- startController (ref .controller , ref .configuration );
87
- }
83
+ controllers .forEach (ConfiguredController ::start );
88
84
89
85
started = true ;
90
86
}
@@ -101,7 +97,7 @@ public void close() {
101
97
log .info (
102
98
"Operator SDK {} is shutting down..." , configurationService .getVersion ().getSdkVersion ());
103
99
104
- for (Closeable closeable : this .closeables ) {
100
+ for (Closeable closeable : this .controllers ) {
105
101
try {
106
102
log .debug ("closing {}" , closeable );
107
103
closeable .close ();
@@ -143,32 +139,6 @@ public <R extends CustomResource> void register(ResourceController<R> controller
143
139
public <R extends CustomResource > void register (
144
140
ResourceController <R > controller , ControllerConfiguration <R > configuration )
145
141
throws OperatorException {
146
- synchronized (lock ) {
147
- if (!started ) {
148
- this .controllers .add (new ControllerRef (controller , configuration ));
149
- } else {
150
- this .controllers .add (new ControllerRef (controller , configuration ));
151
- startController (controller , configuration );
152
- }
153
- }
154
- }
155
-
156
- /**
157
- * Registers the specified controller with this operator, overriding its default configuration by
158
- * the specified one (usually created via
159
- * {@link io.javaoperatorsdk.operator.api.config.ControllerConfigurationOverrider#override(ControllerConfiguration)},
160
- * passing it the controller's original configuration.
161
- *
162
- * @param controller the controller to register
163
- * @param configuration the configuration with which we want to register the controller, if {@code
164
- * null}, the controller's original configuration is used
165
- * @param <R> the {@code CustomResource} type associated with the controller
166
- * @throws OperatorException if a problem occurred during the registration process
167
- */
168
- private <R extends CustomResource > void startController (
169
- ResourceController <R > controller , ControllerConfiguration <R > configuration )
170
- throws OperatorException {
171
-
172
142
final var existing = configurationService .getConfigurationFor (controller );
173
143
if (existing == null ) {
174
144
log .warn (
@@ -181,39 +151,13 @@ private <R extends CustomResource> void startController(
181
151
if (configuration == null ) {
182
152
configuration = existing ;
183
153
}
184
-
185
- final Class <R > resClass = configuration .getCustomResourceClass ();
186
- final String controllerName = configuration .getName ();
187
- final var crdName = configuration .getCRDName ();
188
- final var specVersion = "v1" ;
189
-
190
- // check that the custom resource is known by the cluster if configured that way
191
- final CustomResourceDefinition crd ; // todo: check proper CRD spec version based on config
192
- if (configurationService .checkCRDAndValidateLocalModel ()) {
193
- crd = k8sClient .apiextensions ().v1 ().customResourceDefinitions ().withName (crdName ).get ();
194
- if (crd == null ) {
195
- throwMissingCRDException (crdName , specVersion , controllerName );
154
+ synchronized (lock ) {
155
+ final var configuredController =
156
+ new ConfiguredController (controller , configuration , k8sClient );
157
+ this .controllers .add (configuredController );
158
+ if (started ) {
159
+ configuredController .start ();
196
160
}
197
-
198
- // Apply validations that are not handled by fabric8
199
- CustomResourceUtils .assertCustomResource (resClass , crd );
200
- }
201
-
202
- try {
203
- DefaultEventSourceManager eventSourceManager =
204
- new DefaultEventSourceManager (
205
- controller , configuration , k8sClient .customResources (resClass ));
206
- controller .init (eventSourceManager );
207
- closeables .add (eventSourceManager );
208
- } catch (MissingCRDException e ) {
209
- throwMissingCRDException (crdName , specVersion , controllerName );
210
- }
211
-
212
- if (failOnMissingCurrentNS (configuration )) {
213
- throw new OperatorException (
214
- "Controller '"
215
- + controllerName
216
- + "' is configured to watch the current namespace but it couldn't be inferred from the current configuration." );
217
161
}
218
162
219
163
final var watchedNS =
@@ -222,49 +166,9 @@ private <R extends CustomResource> void startController(
222
166
: configuration .getEffectiveNamespaces ();
223
167
log .info (
224
168
"Registered Controller: '{}' for CRD: '{}' for namespace(s): {}" ,
225
- controllerName ,
226
- resClass ,
169
+ configuration . getName () ,
170
+ configuration . getCustomResourceClass () ,
227
171
watchedNS );
228
172
}
229
173
}
230
-
231
- private void throwMissingCRDException (String crdName , String specVersion , String controllerName ) {
232
- throw new MissingCRDException (
233
- crdName ,
234
- specVersion ,
235
- "'"
236
- + crdName
237
- + "' "
238
- + specVersion
239
- + " CRD was not found on the cluster, controller '"
240
- + controllerName
241
- + "' cannot be registered" );
242
- }
243
-
244
- /**
245
- * Determines whether we should fail because the current namespace is request as target namespace
246
- * but is missing
247
- *
248
- * @return {@code true} if the current namespace is requested but is missing, {@code false}
249
- * otherwise
250
- */
251
- private static <R extends CustomResource > boolean failOnMissingCurrentNS (
252
- ControllerConfiguration <R > configuration ) {
253
- if (configuration .watchCurrentNamespace ()) {
254
- final var effectiveNamespaces = configuration .getEffectiveNamespaces ();
255
- return effectiveNamespaces .size () == 1
256
- && effectiveNamespaces .stream ().allMatch (Objects ::isNull );
257
- }
258
- return false ;
259
- }
260
-
261
- private static class ControllerRef {
262
- public final ResourceController controller ;
263
- public final ControllerConfiguration configuration ;
264
-
265
- public ControllerRef (ResourceController controller , ControllerConfiguration configuration ) {
266
- this .controller = controller ;
267
- this .configuration = configuration ;
268
- }
269
- }
270
174
}
0 commit comments