diff --git a/core/deployment/pom.xml b/core/deployment/pom.xml
index c318a8b6b..ec3472580 100644
--- a/core/deployment/pom.xml
+++ b/core/deployment/pom.xml
@@ -50,6 +50,10 @@
io.fabric8
crd-generator-api-v2
+
+ io.fabric8
+ crd-generator-api
+
org.semver4j
semver4j
diff --git a/core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/CRDGeneration.java b/core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/CRDGeneration.java
index 59c48251c..280d68979 100644
--- a/core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/CRDGeneration.java
+++ b/core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/CRDGeneration.java
@@ -11,8 +11,6 @@
import org.jboss.logging.Logger;
-import io.fabric8.crdv2.generator.CRDGenerator;
-import io.fabric8.crdv2.generator.CustomResourceInfo;
import io.fabric8.kubernetes.client.CustomResource;
import io.quarkiverse.operatorsdk.common.CustomResourceAugmentedClassInfo;
import io.quarkiverse.operatorsdk.common.FileUtils;
@@ -79,21 +77,7 @@ CRDGenerationInfo generate(OutputTargetBuildItem outputTarget,
FileUtils.ensureDirectoryExists(outputDir);
// generate CRDs with detailed information
- final var info = generator.forCRDVersions(crdConfiguration.versions()).inOutputDir(outputDir).detailedGenerate();
- final var crdDetailsPerNameAndVersion = info.getCRDDetailsPerNameAndVersion();
-
- crdDetailsPerNameAndVersion.forEach((crdName, initialVersionToCRDInfoMap) -> {
- log.infov("Generated {0} CRD:", crdName);
- generated.add(crdName);
-
- initialVersionToCRDInfoMap
- .forEach((crdSpecVersion, crdInfo) -> {
- final var filePath = crdInfo.getFilePath();
- log.infov(" - {0} -> {1}", crdSpecVersion, filePath);
- converted.addCRDInfo(new CRDInfo(crdName,
- crdSpecVersion, filePath, crdInfo.getDependentClassNames()));
- });
- });
+ generator.generate(crdConfiguration.versions(), outputDir, generated, converted);
}
return new CRDGenerationInfo(shouldApply(), validateCustomResources, converted, generated);
}
@@ -145,10 +129,10 @@ void withCustomResource(Class extends CustomResource, ?>> crClass, String as
// generator MUST be initialized before we start processing classes as initializing it
// will reset the types information held by the generator
if (generator == null) {
- generator = new CRDGenerator().withParallelGenerationEnabled(crdConfiguration.generateInParallel());
+ generator = crdConfiguration.useV1CRDGenerator() ? new CRDGeneratorV1(crdConfiguration.generateInParallel())
+ : new CRDGeneratorV2(crdConfiguration.generateInParallel());
}
- final var info = CustomResourceInfo.fromClass(crClass);
- generator.customResources(info);
+ generator.scheduleForGeneration(crClass);
needGeneration = true;
} catch (Exception e) {
throw new IllegalArgumentException("Cannot process " + crClass.getName() + " custom resource"
diff --git a/core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/CRDGenerator.java b/core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/CRDGenerator.java
new file mode 100644
index 000000000..659307a5e
--- /dev/null
+++ b/core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/CRDGenerator.java
@@ -0,0 +1,14 @@
+package io.quarkiverse.operatorsdk.deployment;
+
+import java.io.File;
+import java.util.List;
+import java.util.Set;
+
+import io.fabric8.kubernetes.client.CustomResource;
+import io.quarkiverse.operatorsdk.runtime.CRDInfos;
+
+interface CRDGenerator {
+ void generate(List crdSpecVersions, File outputDir, Set generated, CRDInfos converted);
+
+ void scheduleForGeneration(Class extends CustomResource, ?>> crClass);
+}
diff --git a/core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/CRDGeneratorV1.java b/core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/CRDGeneratorV1.java
new file mode 100644
index 000000000..f183c6884
--- /dev/null
+++ b/core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/CRDGeneratorV1.java
@@ -0,0 +1,46 @@
+package io.quarkiverse.operatorsdk.deployment;
+
+import java.io.File;
+import java.util.List;
+import java.util.Set;
+
+import org.jboss.logging.Logger;
+
+import io.fabric8.crd.generator.CustomResourceInfo;
+import io.fabric8.kubernetes.client.CustomResource;
+import io.quarkiverse.operatorsdk.runtime.CRDInfo;
+import io.quarkiverse.operatorsdk.runtime.CRDInfos;
+
+class CRDGeneratorV1 implements CRDGenerator {
+ private static final Logger log = Logger.getLogger(CRDGeneratorV1.class.getName());
+ private final io.fabric8.crd.generator.CRDGenerator generator;
+
+ public CRDGeneratorV1(boolean parallelGeneration) {
+ this.generator = new io.fabric8.crd.generator.CRDGenerator().withParallelGenerationEnabled(parallelGeneration);
+ }
+
+ @Override
+ public void generate(List crdSpecVersions, File outputDir, Set generated, CRDInfos converted) {
+ final var info = generator.forCRDVersions(crdSpecVersions).inOutputDir(outputDir).detailedGenerate();
+ final var crdDetailsPerNameAndVersion = info.getCRDDetailsPerNameAndVersion();
+
+ crdDetailsPerNameAndVersion.forEach((crdName, initialVersionToCRDInfoMap) -> {
+ log.infov("Generated {0} CRD:", crdName);
+ generated.add(crdName);
+
+ initialVersionToCRDInfoMap
+ .forEach((crdSpecVersion, crdInfo) -> {
+ final var filePath = crdInfo.getFilePath();
+ log.infov(" - {0} -> {1}", crdSpecVersion, filePath);
+ converted.addCRDInfo(new CRDInfo(crdName,
+ crdSpecVersion, filePath, crdInfo.getDependentClassNames()));
+ });
+ });
+ }
+
+ @Override
+ public void scheduleForGeneration(Class extends CustomResource, ?>> crClass) {
+ final var info = CustomResourceInfo.fromClass(crClass);
+ generator.customResources(info);
+ }
+}
diff --git a/core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/CRDGeneratorV2.java b/core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/CRDGeneratorV2.java
new file mode 100644
index 000000000..bdee1e4e7
--- /dev/null
+++ b/core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/CRDGeneratorV2.java
@@ -0,0 +1,46 @@
+package io.quarkiverse.operatorsdk.deployment;
+
+import java.io.File;
+import java.util.List;
+import java.util.Set;
+
+import org.jboss.logging.Logger;
+
+import io.fabric8.crdv2.generator.CustomResourceInfo;
+import io.fabric8.kubernetes.client.CustomResource;
+import io.quarkiverse.operatorsdk.runtime.CRDInfo;
+import io.quarkiverse.operatorsdk.runtime.CRDInfos;
+
+class CRDGeneratorV2 implements CRDGenerator {
+ private static final Logger log = Logger.getLogger(CRDGeneratorV2.class.getName());
+ private final io.fabric8.crdv2.generator.CRDGenerator generator;
+
+ public CRDGeneratorV2(boolean parallelGeneration) {
+ this.generator = new io.fabric8.crdv2.generator.CRDGenerator().withParallelGenerationEnabled(parallelGeneration);
+ }
+
+ @Override
+ public void generate(List crdSpecVersions, File outputDir, Set generated, CRDInfos converted) {
+ final var info = generator.forCRDVersions(crdSpecVersions).inOutputDir(outputDir).detailedGenerate();
+ final var crdDetailsPerNameAndVersion = info.getCRDDetailsPerNameAndVersion();
+
+ crdDetailsPerNameAndVersion.forEach((crdName, initialVersionToCRDInfoMap) -> {
+ log.infov("Generated {0} CRD:", crdName);
+ generated.add(crdName);
+
+ initialVersionToCRDInfoMap
+ .forEach((crdSpecVersion, crdInfo) -> {
+ final var filePath = crdInfo.getFilePath();
+ log.infov(" - {0} -> {1}", crdSpecVersion, filePath);
+ converted.addCRDInfo(new CRDInfo(crdName,
+ crdSpecVersion, filePath, crdInfo.getDependentClassNames()));
+ });
+ });
+ }
+
+ @Override
+ public void scheduleForGeneration(Class extends CustomResource, ?>> crClass) {
+ final var info = CustomResourceInfo.fromClass(crClass);
+ generator.customResources(info);
+ }
+}
diff --git a/core/runtime/src/main/java/io/quarkiverse/operatorsdk/runtime/CRDConfiguration.java b/core/runtime/src/main/java/io/quarkiverse/operatorsdk/runtime/CRDConfiguration.java
index bd0ca5e9c..313169dcc 100644
--- a/core/runtime/src/main/java/io/quarkiverse/operatorsdk/runtime/CRDConfiguration.java
+++ b/core/runtime/src/main/java/io/quarkiverse/operatorsdk/runtime/CRDConfiguration.java
@@ -6,6 +6,7 @@
import io.fabric8.kubernetes.client.CustomResource;
import io.quarkus.runtime.annotations.ConfigGroup;
import io.smallrye.config.WithDefault;
+import io.smallrye.config.WithName;
@ConfigGroup
public interface CRDConfiguration {
@@ -13,6 +14,7 @@ public interface CRDConfiguration {
String DEFAULT_OUTPUT_DIRECTORY = "kubernetes";
String DEFAULT_VALIDATE = "true";
String DEFAULT_VERSIONS = "v1";
+ String DEFAULT_USE_V1_CRD_GENERATOR = "false";
/**
* Whether the operator should check that the CRD is properly deployed and that the associated
@@ -78,4 +80,18 @@ public interface CRDConfiguration {
* @since 6.8.4
*/
Optional> externalCRDLocations();
+
+ /**
+ * Whether or not to use the v1 version of the CRD generator. Note that this should only be used if a compatibility issue is
+ * found with the v2 generator, which is the default one and the one that is actively maintained.
+ *
+ * @return {@code true} if the v1 version of the CRD generator should be used
+ * @since 6.9.1
+ * @deprecated using this method should be reserved for blocking situations, please open an issue reporting the problem
+ * you're facing with the v2 generator before reverting to use the v1 version
+ */
+ @Deprecated(forRemoval = true)
+ @WithDefault(DEFAULT_USE_V1_CRD_GENERATOR)
+ @WithName("use-deprecated-v1-crd-generator")
+ Boolean useV1CRDGenerator();
}