Skip to content

Commit 4fe7cfd

Browse files
authored
feat: allow for exclusion of some classes when generating CRDs (#687)
A new configuration property quarkus.operator-sdk.crd.exclude-resources has been introduced to provide fully-qualified class names of resource classes to be excluded from CRD generation. Fixes #674
1 parent f78ab7f commit 4fe7cfd

File tree

8 files changed

+129
-3
lines changed

8 files changed

+129
-3
lines changed

core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/CRDGeneration.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,14 @@ boolean scheduleForGenerationIfNeeded(CustomResourceAugmentedClassInfo crInfo,
149149

150150
@SuppressWarnings("rawtypes")
151151
public void withCustomResource(Class<? extends CustomResource> crClass, String crdName, String associatedControllerName) {
152+
// first check if the CR is not filtered out
153+
if (crdConfiguration.excludeResources.map(excluded -> excluded.contains(crClass.getName())).orElse(false)) {
154+
log.infov(
155+
"CRD generation was skipped for ''{1}'' because it was excluded from generation",
156+
crClass.getName());
157+
return;
158+
}
159+
152160
try {
153161
// generator MUST be initialized before we start processing classes as initializing it
154162
// will reset the types information held by the generator

core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/CRDGenerationBuildStep.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,14 @@
1919
import io.quarkus.deployment.builditem.LiveReloadBuildItem;
2020
import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem;
2121

22-
public class CRDGenerationBuildStep {
22+
class CRDGenerationBuildStep {
2323
static final Logger log = Logger.getLogger(CRDGenerationBuildStep.class.getName());
2424

25+
private BuildTimeOperatorConfiguration buildTimeConfiguration;
26+
2527
@BuildStep
2628
GeneratedCRDInfoBuildItem generateCRDs(
2729
ReconcilerInfosBuildItem reconcilers,
28-
BuildTimeOperatorConfiguration buildTimeConfiguration,
2930
LaunchModeBuildItem launchModeBuildItem,
3031
LiveReloadBuildItem liveReload,
3132
OutputTargetBuildItem outputTarget,
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package io.quarkiverse.operatorsdk.test;
2+
3+
import java.io.IOException;
4+
import java.nio.file.Files;
5+
6+
import org.junit.jupiter.api.Assertions;
7+
import org.junit.jupiter.api.Test;
8+
import org.junit.jupiter.api.extension.RegisterExtension;
9+
10+
import io.fabric8.kubernetes.client.CustomResource;
11+
import io.quarkiverse.operatorsdk.test.sources.*;
12+
import io.quarkus.test.ProdBuildResults;
13+
import io.quarkus.test.ProdModeTestResults;
14+
import io.quarkus.test.QuarkusProdModeTest;
15+
16+
public class AllCRDGenerationTest {
17+
18+
// Start unit test with your extension loaded
19+
@RegisterExtension
20+
static final QuarkusProdModeTest config = new QuarkusProdModeTest()
21+
.setApplicationName("test")
22+
.withApplicationRoot(
23+
(jar) -> jar.addClasses(SimpleReconciler.class, SimpleCR.class, SimpleSpec.class, SimpleStatus.class,
24+
External.class))
25+
.overrideConfigKey("quarkus.operator-sdk.crd.generate-all", "true");
26+
27+
@ProdBuildResults
28+
private ProdModeTestResults prodModeTestResults;
29+
30+
@Test
31+
public void shouldGenerateAllCRDs() throws IOException {
32+
final var kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes");
33+
final var kubeManifest = kubernetesDir.resolve("kubernetes.yml");
34+
Assertions.assertTrue(Files.exists(kubeManifest));
35+
36+
// checks that CRDs are all generated
37+
Assertions.assertTrue(Files.exists(kubernetesDir.resolve(CustomResource.getCRDName(SimpleCR.class) + "-v1.yml")));
38+
Assertions.assertTrue(Files.exists(kubernetesDir.resolve(CustomResource.getCRDName(External.class) + "-v1.yml")));
39+
}
40+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package io.quarkiverse.operatorsdk.test;
2+
3+
import java.io.IOException;
4+
import java.nio.file.Files;
5+
6+
import org.junit.jupiter.api.Assertions;
7+
import org.junit.jupiter.api.Test;
8+
import org.junit.jupiter.api.extension.RegisterExtension;
9+
10+
import io.fabric8.kubernetes.client.CustomResource;
11+
import io.quarkiverse.operatorsdk.test.sources.*;
12+
import io.quarkus.test.ProdBuildResults;
13+
import io.quarkus.test.ProdModeTestResults;
14+
import io.quarkus.test.QuarkusProdModeTest;
15+
16+
public class ExcludedCRDGenerationTest {
17+
18+
// Start unit test with your extension loaded
19+
@RegisterExtension
20+
static final QuarkusProdModeTest config = new QuarkusProdModeTest()
21+
.setApplicationName("test")
22+
.withApplicationRoot(
23+
(jar) -> jar.addClasses(SimpleReconciler.class, SimpleCR.class, SimpleSpec.class, SimpleStatus.class,
24+
External.class))
25+
.overrideConfigKey("quarkus.operator-sdk.crd.generate-all", "true")
26+
.overrideConfigKey("quarkus.operator-sdk.crd.exclude-resources", SimpleCR.class.getName());
27+
28+
@ProdBuildResults
29+
private ProdModeTestResults prodModeTestResults;
30+
31+
@Test
32+
public void shouldOnlyGenerateNonExcludedCRDs() throws IOException {
33+
final var kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes");
34+
final var kubeManifest = kubernetesDir.resolve("kubernetes.yml");
35+
Assertions.assertTrue(Files.exists(kubeManifest));
36+
37+
// checks that only External CRD is generated
38+
Assertions.assertFalse(Files.exists(kubernetesDir.resolve(CustomResource.getCRDName(SimpleCR.class) + "-v1.yml")));
39+
Assertions.assertTrue(Files.exists(kubernetesDir.resolve(CustomResource.getCRDName(External.class) + "-v1.yml")));
40+
}
41+
}

core/deployment/src/test/java/io/quarkiverse/operatorsdk/test/NoCRDGenerationTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class NoCRDGenerationTest {
2727
private ProdModeTestResults prodModeTestResults;
2828

2929
@Test
30-
public void shouldCreateRolesAndRoleBindings() throws IOException {
30+
public void shouldNotGenerateCRDs() throws IOException {
3131
final var kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes");
3232
final var kubeManifest = kubernetesDir.resolve("kubernetes.yml");
3333
Assertions.assertTrue(Files.exists(kubeManifest));
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package io.quarkiverse.operatorsdk.test.sources;
2+
3+
import io.fabric8.kubernetes.client.CustomResource;
4+
import io.fabric8.kubernetes.model.annotation.Group;
5+
import io.fabric8.kubernetes.model.annotation.Version;
6+
7+
@Group("halkyon.io")
8+
@Version("v1alpha1")
9+
public class External extends CustomResource<Void, Void> {
10+
11+
public static final String DISPLAY_NAME = "External display name";
12+
public static final String DESCRIPTION = "External description";
13+
}

core/runtime/src/main/java/io/quarkiverse/operatorsdk/runtime/CRDConfiguration.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,10 @@ public class CRDConfiguration {
6161
@ConfigItem(defaultValue = "false")
6262
public Boolean generateInParallel;
6363

64+
/**
65+
* A comma-separated list of fully-qualified class names implementing custom resources to exclude from the CRD generation
66+
* process.
67+
*/
68+
@ConfigItem
69+
public Optional<List<String>> excludeResources;
6470
}

docs/modules/ROOT/pages/includes/quarkus-operator-sdk.adoc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,23 @@ endif::add-copy-button-to-env-var[]
129129
|`false`
130130

131131

132+
a|icon:lock[title=Fixed at build time] [[quarkus-operator-sdk_quarkus.operator-sdk.crd.exclude-resources]]`link:#quarkus-operator-sdk_quarkus.operator-sdk.crd.exclude-resources[quarkus.operator-sdk.crd.exclude-resources]`
133+
134+
135+
[.description]
136+
--
137+
A comma-separated list of fully-qualified class names implementing custom resources to exclude from the CRD generation process.
138+
139+
ifdef::add-copy-button-to-env-var[]
140+
Environment variable: env_var_with_copy_button:+++QUARKUS_OPERATOR_SDK_CRD_EXCLUDE_RESOURCES+++[]
141+
endif::add-copy-button-to-env-var[]
142+
ifndef::add-copy-button-to-env-var[]
143+
Environment variable: `+++QUARKUS_OPERATOR_SDK_CRD_EXCLUDE_RESOURCES+++`
144+
endif::add-copy-button-to-env-var[]
145+
--|list of string
146+
|
147+
148+
132149
a|icon:lock[title=Fixed at build time] [[quarkus-operator-sdk_quarkus.operator-sdk.generation-aware]]`link:#quarkus-operator-sdk_quarkus.operator-sdk.generation-aware[quarkus.operator-sdk.generation-aware]`
133150

134151

0 commit comments

Comments
 (0)