Skip to content

Commit cb585d7

Browse files
authored
Merge pull request #318 from java-operator-sdk/fixes
Fixes
2 parents 03b6517 + 7608163 commit cb585d7

File tree

23 files changed

+369
-181
lines changed

23 files changed

+369
-181
lines changed

operator-framework-core/pom.xml

Lines changed: 87 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -2,72 +2,97 @@
22
<project xmlns="http://maven.apache.org/POM/4.0.0"
33
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
44
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5-
<modelVersion>4.0.0</modelVersion>
6-
<parent>
7-
<groupId>io.javaoperatorsdk</groupId>
8-
<artifactId>java-operator-sdk</artifactId>
9-
<version>1.7.1-SNAPSHOT</version>
10-
<relativePath>../pom.xml</relativePath>
11-
</parent>
5+
<modelVersion>4.0.0</modelVersion>
6+
<parent>
7+
<groupId>io.javaoperatorsdk</groupId>
8+
<artifactId>java-operator-sdk</artifactId>
9+
<version>1.7.1-SNAPSHOT</version>
10+
<relativePath>../pom.xml</relativePath>
11+
</parent>
1212

13-
<artifactId>operator-framework-core</artifactId>
14-
<name>Operator SDK - Framework - Core</name>
15-
<description>Core framework for implementing Kubernetes operators</description>
16-
<packaging>jar</packaging>
13+
<artifactId>operator-framework-core</artifactId>
14+
<name>Operator SDK - Framework - Core</name>
15+
<description>Core framework for implementing Kubernetes operators</description>
16+
<packaging>jar</packaging>
1717

18-
<properties>
19-
<java.version>11</java.version>
20-
<maven.compiler.source>11</maven.compiler.source>
21-
<maven.compiler.target>11</maven.compiler.target>
22-
</properties>
18+
<properties>
19+
<java.version>11</java.version>
20+
<maven.compiler.source>11</maven.compiler.source>
21+
<maven.compiler.target>11</maven.compiler.target>
22+
</properties>
2323

24-
<build>
25-
<plugins>
26-
<plugin>
27-
<groupId>org.apache.maven.plugins</groupId>
28-
<artifactId>maven-surefire-plugin</artifactId>
29-
<version>${surefire.version}</version>
30-
</plugin>
31-
</plugins>
32-
</build>
24+
<build>
25+
<plugins>
26+
<plugin>
27+
<groupId>org.apache.maven.plugins</groupId>
28+
<artifactId>maven-surefire-plugin</artifactId>
29+
<version>${surefire.version}</version>
30+
</plugin>
31+
<plugin>
32+
<!-- Used to generate the version / commit information -->
33+
<groupId>pl.project13.maven</groupId>
34+
<artifactId>git-commit-id-plugin</artifactId>
35+
<version>4.0.3</version>
36+
<executions>
37+
<execution>
38+
<id>get-the-git-infos</id>
39+
<goals>
40+
<goal>revision</goal>
41+
</goals>
42+
<phase>initialize</phase>
43+
</execution>
44+
</executions>
45+
<configuration>
46+
<generateGitPropertiesFile>true</generateGitPropertiesFile>
47+
<generateGitPropertiesFilename>${project.build.outputDirectory}/version.properties
48+
</generateGitPropertiesFilename>
49+
<includeOnlyProperties>
50+
<includeOnlyProperty>^git.build.(time|version)$</includeOnlyProperty>
51+
<includeOnlyProperty>^git.commit.id.(abbrev|full)$</includeOnlyProperty>
52+
</includeOnlyProperties>
53+
<commitIdGenerationMode>full</commitIdGenerationMode>
54+
</configuration>
55+
</plugin>
56+
</plugins>
57+
</build>
3358

3459

35-
<dependencies>
36-
<dependency>
37-
<groupId>io.fabric8</groupId>
38-
<artifactId>openshift-client</artifactId>
39-
</dependency>
40-
<dependency>
41-
<groupId>org.slf4j</groupId>
42-
<artifactId>slf4j-api</artifactId>
43-
</dependency>
60+
<dependencies>
61+
<dependency>
62+
<groupId>io.fabric8</groupId>
63+
<artifactId>openshift-client</artifactId>
64+
</dependency>
65+
<dependency>
66+
<groupId>org.slf4j</groupId>
67+
<artifactId>slf4j-api</artifactId>
68+
</dependency>
4469

45-
<dependency>
46-
<groupId>org.junit.jupiter</groupId>
47-
<artifactId>junit-jupiter-api</artifactId>
48-
<scope>test</scope>
49-
</dependency>
50-
<dependency>
51-
<groupId>org.junit.jupiter</groupId>
52-
<artifactId>junit-jupiter-engine</artifactId>
53-
<scope>test</scope>
54-
</dependency>
55-
<dependency>
56-
<groupId>org.mockito</groupId>
57-
<artifactId>mockito-core</artifactId>
58-
<scope>test</scope>
59-
</dependency>
60-
<dependency>
61-
<groupId>org.apache.logging.log4j</groupId>
62-
<artifactId>log4j-slf4j-impl</artifactId>
63-
<version>2.13.3</version>
64-
<scope>test</scope>
65-
</dependency>
66-
<dependency>
67-
<groupId>org.assertj</groupId>
68-
<artifactId>assertj-core</artifactId>
69-
<version>3.18.0</version>
70-
<scope>test</scope>
71-
</dependency>
72-
</dependencies>
70+
<dependency>
71+
<groupId>org.junit.jupiter</groupId>
72+
<artifactId>junit-jupiter-api</artifactId>
73+
<scope>test</scope>
74+
</dependency>
75+
<dependency>
76+
<groupId>org.junit.jupiter</groupId>
77+
<artifactId>junit-jupiter-engine</artifactId>
78+
<scope>test</scope>
79+
</dependency>
80+
<dependency>
81+
<groupId>org.mockito</groupId>
82+
<artifactId>mockito-core</artifactId>
83+
<scope>test</scope>
84+
</dependency>
85+
<dependency>
86+
<groupId>org.apache.logging.log4j</groupId>
87+
<artifactId>log4j-slf4j-impl</artifactId>
88+
<version>2.13.3</version>
89+
<scope>test</scope>
90+
</dependency>
91+
<dependency>
92+
<groupId>org.assertj</groupId>
93+
<artifactId>assertj-core</artifactId>
94+
<version>3.18.0</version>
95+
<scope>test</scope>
96+
</dependency>
97+
</dependencies>
7398
</project>

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package io.javaoperatorsdk.operator;
22

3-
import io.fabric8.kubernetes.client.CustomResource;
43
import io.javaoperatorsdk.operator.api.Controller;
54
import io.javaoperatorsdk.operator.api.ResourceController;
65
import java.util.Locale;
@@ -13,11 +12,6 @@ public static String getDefaultFinalizerName(String crdName) {
1312
return crdName + FINALIZER_NAME_SUFFIX;
1413
}
1514

16-
public static boolean hasGivenFinalizer(CustomResource resource, String finalizer) {
17-
return resource.getMetadata().getFinalizers() != null
18-
&& resource.getMetadata().getFinalizers().contains(finalizer);
19-
}
20-
2115
public static String getNameFor(Class<? extends ResourceController> controllerClass) {
2216
// if the controller annotation has a name attribute, use it
2317
final var annotation = controllerClass.getAnnotation(Controller.class);

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

Lines changed: 78 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import io.javaoperatorsdk.operator.processing.event.DefaultEventSourceManager;
1313
import io.javaoperatorsdk.operator.processing.event.internal.CustomResourceEventSource;
1414
import io.javaoperatorsdk.operator.processing.retry.GenericRetry;
15-
import io.javaoperatorsdk.operator.processing.retry.Retry;
1615
import java.util.Arrays;
1716
import org.slf4j.Logger;
1817
import org.slf4j.LoggerFactory;
@@ -29,11 +28,44 @@ public Operator(KubernetesClient k8sClient, ConfigurationService configurationSe
2928
this.configurationService = configurationService;
3029
}
3130

31+
/**
32+
* Finishes the operator startup process. This is mostly used in injection-aware applications
33+
* where there is no obvious entrypoint to the application which can trigger the injection process
34+
* and start the cluster monitoring processes.
35+
*/
36+
public void start() {
37+
final var version = configurationService.getVersion();
38+
log.info(
39+
"Operator {} (commit: {}) built on {} starting...",
40+
version.getSdkVersion(),
41+
version.getCommit(),
42+
version.getBuiltTime());
43+
}
44+
45+
/**
46+
* Registers the specified controller with this operator.
47+
*
48+
* @param controller the controller to register
49+
* @param <R> the {@code CustomResource} type associated with the controller
50+
* @throws OperatorException if a problem occurred during the registration process
51+
*/
3252
public <R extends CustomResource> void register(ResourceController<R> controller)
3353
throws OperatorException {
3454
register(controller, null);
3555
}
3656

57+
/**
58+
* Registers the specified controller with this operator, overriding its default configuration by
59+
* the specified one (usually created via {@link
60+
* io.javaoperatorsdk.operator.api.config.ControllerConfigurationOverrider#override(ControllerConfiguration)},
61+
* passing it the controller's original configuration.
62+
*
63+
* @param controller the controller to register
64+
* @param configuration the configuration with which we want to register the controller, if {@code
65+
* null}, the controller's orginal configuration is used
66+
* @param <R> the {@code CustomResource} type associated with the controller
67+
* @throws OperatorException if a problem occurred during the registration process
68+
*/
3769
public <R extends CustomResource> void register(
3870
ResourceController<R> controller, ControllerConfiguration<R> configuration)
3971
throws OperatorException {
@@ -49,55 +81,57 @@ public <R extends CustomResource> void register(
4981
if (configuration == null) {
5082
configuration = existing;
5183
}
84+
5285
final var retry = GenericRetry.fromConfiguration(configuration.getRetryConfiguration());
5386
final var targetNamespaces = configuration.getNamespaces().toArray(new String[] {});
54-
registerController(controller, configuration.watchAllNamespaces(), retry, targetNamespaces);
55-
}
56-
}
87+
Class<R> resClass = configuration.getCustomResourceClass();
88+
String finalizer = configuration.getFinalizer();
89+
final var client = k8sClient.customResources(resClass);
90+
EventDispatcher dispatcher =
91+
new EventDispatcher(
92+
controller, finalizer, new EventDispatcher.CustomResourceFacade(client));
5793

58-
@SuppressWarnings("rawtypes")
59-
private <R extends CustomResource> void registerController(
60-
ResourceController<R> controller,
61-
boolean watchAllNamespaces,
62-
Retry retry,
63-
String... targetNamespaces)
64-
throws OperatorException {
65-
final var configuration = configurationService.getConfigurationFor(controller);
66-
Class<R> resClass = configuration.getCustomResourceClass();
67-
String finalizer = configuration.getFinalizer();
68-
MixedOperation client = k8sClient.customResources(resClass);
69-
EventDispatcher eventDispatcher =
70-
new EventDispatcher(
71-
controller, finalizer, new EventDispatcher.CustomResourceFacade(client));
94+
// check that the custom resource is known by the cluster
95+
final var crdName = configuration.getCRDName();
96+
final var crd =
97+
k8sClient.apiextensions().v1().customResourceDefinitions().withName(crdName).get();
98+
final var controllerName = configuration.getName();
99+
if (crd == null) {
100+
throw new OperatorException(
101+
"'"
102+
+ crdName
103+
+ "' CRD was not found on the cluster, controller "
104+
+ controllerName
105+
+ " cannot be registered");
106+
}
72107

73-
CustomResourceCache customResourceCache = new CustomResourceCache();
74-
DefaultEventHandler defaultEventHandler =
75-
new DefaultEventHandler(
76-
customResourceCache, eventDispatcher, controller.getClass().getName(), retry);
77-
DefaultEventSourceManager eventSourceManager =
78-
new DefaultEventSourceManager(defaultEventHandler, retry != null);
79-
defaultEventHandler.setEventSourceManager(eventSourceManager);
80-
eventDispatcher.setEventSourceManager(eventSourceManager);
108+
CustomResourceCache customResourceCache = new CustomResourceCache();
109+
DefaultEventHandler defaultEventHandler =
110+
new DefaultEventHandler(customResourceCache, dispatcher, controllerName, retry);
111+
DefaultEventSourceManager eventSourceManager =
112+
new DefaultEventSourceManager(defaultEventHandler, retry != null);
113+
defaultEventHandler.setEventSourceManager(eventSourceManager);
114+
dispatcher.setEventSourceManager(eventSourceManager);
81115

82-
controller.init(eventSourceManager);
83-
CustomResourceEventSource customResourceEventSource =
84-
createCustomResourceEventSource(
85-
client,
86-
customResourceCache,
87-
watchAllNamespaces,
88-
targetNamespaces,
89-
defaultEventHandler,
90-
configuration.isGenerationAware(),
91-
finalizer);
92-
eventSourceManager.registerCustomResourceEventSource(customResourceEventSource);
116+
controller.init(eventSourceManager);
117+
final boolean watchAllNamespaces = configuration.watchAllNamespaces();
118+
CustomResourceEventSource customResourceEventSource =
119+
createCustomResourceEventSource(
120+
client,
121+
customResourceCache,
122+
watchAllNamespaces,
123+
targetNamespaces,
124+
defaultEventHandler,
125+
configuration.isGenerationAware(),
126+
finalizer);
127+
eventSourceManager.registerCustomResourceEventSource(customResourceEventSource);
93128

94-
log.info(
95-
"Registered Controller: '{}' for CRD: '{}' for namespaces: {}",
96-
controller.getClass().getSimpleName(),
97-
resClass,
98-
targetNamespaces.length == 0
99-
? "[all/client namespace]"
100-
: Arrays.toString(targetNamespaces));
129+
log.info(
130+
"Registered Controller: '{}' for CRD: '{}' for namespaces: {}",
131+
controller.getClass().getSimpleName(),
132+
resClass,
133+
watchAllNamespaces ? "[all namespaces]" : Arrays.toString(targetNamespaces));
134+
}
101135
}
102136

103137
private CustomResourceEventSource createCustomResourceEventSource(

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
public abstract class AbstractConfigurationService implements ConfigurationService {
1111

1212
private final Map<String, ControllerConfiguration> configurations = new ConcurrentHashMap<>();
13+
private final Version version;
14+
15+
public AbstractConfigurationService(Version version) {
16+
this.version = version;
17+
}
1318

1419
protected <R extends CustomResource> void register(ControllerConfiguration<R> config) {
1520
final var name = config.getName();
@@ -41,4 +46,9 @@ public <R extends CustomResource> ControllerConfiguration<R> getConfigurationFor
4146
public Set<String> getKnownControllerNames() {
4247
return configurations.keySet();
4348
}
49+
50+
@Override
51+
public Version getVersion() {
52+
return version;
53+
}
4454
}

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,41 @@
55
import io.javaoperatorsdk.operator.api.ResourceController;
66
import java.util.Set;
77

8+
/** An interface from which to retrieve configuration information. */
89
public interface ConfigurationService {
910

11+
/**
12+
* Retrieves the configuration associated with the specified controller
13+
*
14+
* @param controller the controller we want the configuration of
15+
* @param <R> the {@code CustomResource} type associated with the specified controller
16+
* @return the {@link ControllerConfiguration} associated with the specified controller or {@code
17+
* null} if no configuration exists for the controller
18+
*/
1019
<R extends CustomResource> ControllerConfiguration<R> getConfigurationFor(
1120
ResourceController<R> controller);
1221

22+
/**
23+
* Retrieves the Kubernetes client configuration
24+
*
25+
* @return the configuration of the Kubernetes client, defaulting to the provided
26+
* auto-configuration
27+
*/
1328
default Config getClientConfiguration() {
1429
return Config.autoConfigure(null);
1530
}
1631

32+
/**
33+
* Retrieves the set of the names of controllers for which a configuration exists
34+
*
35+
* @return the set of known controller names
36+
*/
1737
Set<String> getKnownControllerNames();
38+
39+
/**
40+
* Retrieves the {@link Version} information associated with this particular instance of the SDK
41+
*
42+
* @return the version information
43+
*/
44+
Version getVersion();
1845
}

0 commit comments

Comments
 (0)