This is an automated email from the ASF dual-hosted git repository. gfournier pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push: new ecb137f7f08 CAMEL-21369: camel-jbang kubernetes - add quarkus openshift extensions configuration for Route traits ecb137f7f08 is described below commit ecb137f7f084369a9b7fe21475aee0f089196151 Author: Gaelle Fournier <gaelle.fournier.w...@gmail.com> AuthorDate: Fri Oct 25 14:29:30 2024 +0200 CAMEL-21369: camel-jbang kubernetes - add quarkus openshift extensions configuration for Route traits --- .../dsl/jbang/core/commands/k/IntegrationRun.java | 3 +- .../core/commands/kubernetes/KubernetesExport.java | 2 +- .../core/commands/kubernetes/KubernetesHelper.java | 13 ++--- .../core/commands/kubernetes/traits/BaseTrait.java | 6 +++ .../commands/kubernetes/traits/RouteTrait.java | 55 ++++++++++++++++++++++ .../core/commands/kubernetes/traits/Trait.java | 34 +++++++++++++ .../commands/kubernetes/traits/TraitCatalog.java | 7 ++- .../commands/kubernetes/traits/TraitContext.java | 5 ++ .../commands/kubernetes/KubernetesExportTest.java | 23 ++++++--- 9 files changed, 132 insertions(+), 16 deletions(-) diff --git a/dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationRun.java b/dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationRun.java index 127e9ee7cbe..ee064cb306b 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationRun.java +++ b/dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationRun.java @@ -37,6 +37,7 @@ import org.apache.camel.dsl.jbang.core.commands.kubernetes.traits.TraitCatalog; import org.apache.camel.dsl.jbang.core.commands.kubernetes.traits.TraitContext; import org.apache.camel.dsl.jbang.core.common.JSonHelper; import org.apache.camel.dsl.jbang.core.common.Printer; +import org.apache.camel.dsl.jbang.core.common.RuntimeType; import org.apache.camel.dsl.jbang.core.common.Source; import org.apache.camel.dsl.jbang.core.common.SourceHelper; import org.apache.camel.dsl.jbang.core.common.SourceScheme; @@ -319,7 +320,7 @@ public class IntegrationRun extends KubernetesBaseCommand { = KubernetesHelper.yaml(this.getClass().getClassLoader()) .loadAs(KubernetesHelper.dumpYaml(traits), org.apache.camel.dsl.jbang.core.commands.kubernetes.traits.model.Traits.class); - new TraitCatalog().apply(kubernetesTraits, context, traitProfile); + new TraitCatalog().apply(kubernetesTraits, context, traitProfile, RuntimeType.quarkus); printer().println( context.buildItems().stream().map(KubernetesHelper::dumpYaml).collect(Collectors.joining("---"))); diff --git a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExport.java b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExport.java index 5833f6787b6..d2c9b2bc0e5 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExport.java +++ b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExport.java @@ -352,7 +352,7 @@ public class KubernetesExport extends Export { printer().println("Building Kubernetes manifest ..."); } - new TraitCatalog().apply(traitsSpec, context, clusterType); + new TraitCatalog().apply(traitsSpec, context, clusterType, runtime); var kubeFragments = context.buildItems().stream().map(KubernetesHelper::toJsonMap).toList(); diff --git a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesHelper.java b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesHelper.java index 976de6a4ae3..31966980e53 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesHelper.java +++ b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesHelper.java @@ -199,12 +199,13 @@ public final class KubernetesHelper { } public static File getKubernetesManifest(String clusterType, File workingDir, String extension) { - String manifestFile; - if (ClusterType.KIND.isEqualTo(clusterType) || ClusterType.MINIKUBE.isEqualTo(clusterType)) { - manifestFile = "kubernetes"; - } else { - manifestFile = Optional.ofNullable(clusterType).map(String::toLowerCase).orElse("kubernetes"); - } + ClusterType cs = ClusterType + .valueOf(Optional.ofNullable(clusterType).map(String::toUpperCase).orElse(ClusterType.KUBERNETES.name())); + String manifestFile = switch (cs) { + case KIND, MINIKUBE -> "kubernetes"; + case OPENSHIFT -> "_openshift"; + default -> cs.name().toLowerCase(); + }; return new File(workingDir, "%s.%s".formatted(manifestFile, extension)); } } diff --git a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/BaseTrait.java b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/BaseTrait.java index 7738408bbc0..88d32ae726d 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/BaseTrait.java +++ b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/BaseTrait.java @@ -18,6 +18,8 @@ package org.apache.camel.dsl.jbang.core.commands.kubernetes.traits; import org.apache.camel.dsl.jbang.core.commands.kubernetes.ClusterType; +import org.apache.camel.dsl.jbang.core.commands.kubernetes.traits.model.Traits; +import org.apache.camel.dsl.jbang.core.common.RuntimeType; public abstract class BaseTrait implements Trait { @@ -48,4 +50,8 @@ public abstract class BaseTrait implements Trait { public boolean accept(ClusterType clusterType) { return true; } + + @Override + public void applyRuntimeSpecificProperties(Traits traitConfig, TraitContext context, RuntimeType runtimeType) { + } } diff --git a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/RouteTrait.java b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/RouteTrait.java index 49eb2021d2b..b44df6ce087 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/RouteTrait.java +++ b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/RouteTrait.java @@ -20,7 +20,10 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; import io.fabric8.kubernetes.api.model.IntOrString; import io.fabric8.kubernetes.api.model.IntOrStringBuilder; @@ -30,6 +33,7 @@ import org.apache.camel.dsl.jbang.core.commands.kubernetes.ClusterType; import org.apache.camel.dsl.jbang.core.commands.kubernetes.traits.model.Container; import org.apache.camel.dsl.jbang.core.commands.kubernetes.traits.model.Route; import org.apache.camel.dsl.jbang.core.commands.kubernetes.traits.model.Traits; +import org.apache.camel.dsl.jbang.core.common.RuntimeType; import org.apache.camel.util.IOHelper; import org.apache.camel.util.StringHelper; @@ -115,6 +119,56 @@ public class RouteTrait extends BaseTrait { } + @Override + public void applyRuntimeSpecificProperties(Traits traitConfig, TraitContext context, RuntimeType runtimeType) { + List<String> routeProperties = new ArrayList<>(); + if (runtimeType == RuntimeType.quarkus) { + Route routeTrait = Optional.ofNullable(traitConfig.getRoute()).orElseGet(Route::new); + Container containerTrait = Optional.ofNullable(traitConfig.getContainer()).orElseGet(Container::new); + + routeProperties.add("quarkus.openshift.route.expose=true"); + if (routeTrait.getAnnotations() != null) { + routeTrait.getAnnotations().forEach((name, value) -> routeProperties + .add("quarkus.openshift.route.annotations.\"%s\"=%s".formatted(name, value))); + } + + if (routeTrait.getHost() != null) { + routeProperties.add("quarkus.openshift.route.host=%s".formatted(routeTrait.getHost())); + } + routeProperties.add("quarkus.openshift.route.target-port=%s" + .formatted(Optional.ofNullable(containerTrait.getServicePortName()).orElse(DEFAULT_CONTAINER_PORT_NAME))); + + if (routeTrait.getTlsTermination() != null) { + routeProperties + .add("quarkus.openshift.route.tls.termination=%s".formatted(routeTrait.getTlsTermination().getValue())); + } + if (routeTrait.getTlsCertificate() != null) { + routeProperties.add( + "quarkus.openshift.route.tls.certificate=%s" + .formatted(getContent(routeTrait.getTlsCertificate()).replaceAll("\n", "\\\\n"))); + } + if (routeTrait.getTlsKey() != null) { + routeProperties.add("quarkus.openshift.route.tls.key=%s" + .formatted(getContent(routeTrait.getTlsKey()).replaceAll("\n", "\\\\n"))); + } + if (routeTrait.getTlsCACertificate() != null) { + routeProperties + .add("quarkus.openshift.route.tls.ca-certificate=%s" + .formatted(getContent(routeTrait.getTlsCACertificate()).replaceAll("\n", "\\\\n"))); + } + if (routeTrait.getTlsDestinationCACertificate() != null) { + routeProperties.add("quarkus.openshift.route.tls.destination-ca-certificate=%s" + .formatted(getContent(routeTrait.getTlsDestinationCACertificate()).replaceAll("\n", "\\\\n"))); + } + if (routeTrait.getTlsInsecureEdgeTerminationPolicy() != null) { + routeProperties.add("quarkus.openshift.route.tls.insecure-edge-termination-policy=%s" + .formatted(routeTrait.getTlsInsecureEdgeTerminationPolicy())); + } + } + context.addOrAppendConfigurationResource("application.properties", + routeProperties.stream().collect(Collectors.joining(System.lineSeparator()))); + } + @Override public boolean accept(ClusterType clusterType) { return ClusterType.OPENSHIFT == clusterType; @@ -139,4 +193,5 @@ public class RouteTrait extends BaseTrait { return value; } } + } diff --git a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/Trait.java b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/Trait.java index dafe68a4847..559c0bcadee 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/Trait.java +++ b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/Trait.java @@ -19,17 +19,51 @@ package org.apache.camel.dsl.jbang.core.commands.kubernetes.traits; import org.apache.camel.dsl.jbang.core.commands.kubernetes.ClusterType; import org.apache.camel.dsl.jbang.core.commands.kubernetes.traits.model.Traits; +import org.apache.camel.dsl.jbang.core.common.RuntimeType; public interface Trait extends Comparable<Trait> { + /** + * Evaluate if Trait configuration is ready to be applyed + * + * @param traitConfig trait configuration + * @param context command traits context + * @return true if the trait configuration can be applied to context + */ boolean configure(Traits traitConfig, TraitContext context); + /** + * Apply trait configuration to context + * + * @param traitConfig trait configuration + * @param context command traits context + */ void apply(Traits traitConfig, TraitContext context); + /** + * Priority order for trait application. + * + * @return order + */ int order(); + /** + * Evaluate if trait can be applied to cluster type + * + * @param clusterType cluster type + * @return true if applicable + */ boolean accept(ClusterType clusterType); + /** + * Add runtime properties to command trait context to be added to generated project properties + * + * @param traitConfig trait configuration + * @param context command traits context + * @param runtimeType + */ + void applyRuntimeSpecificProperties(Traits traitConfig, TraitContext context, RuntimeType runtimeType); + @Override default int compareTo(Trait o) { return Integer.compare(order(), o.order()); diff --git a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/TraitCatalog.java b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/TraitCatalog.java index d90f2ec376d..d6205b5686a 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/TraitCatalog.java +++ b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/TraitCatalog.java @@ -26,6 +26,7 @@ import org.apache.camel.dsl.jbang.core.commands.kubernetes.ClusterType; import org.apache.camel.dsl.jbang.core.commands.kubernetes.traits.knative.KnativeServiceTrait; import org.apache.camel.dsl.jbang.core.commands.kubernetes.traits.knative.KnativeTrait; import org.apache.camel.dsl.jbang.core.commands.kubernetes.traits.model.Traits; +import org.apache.camel.dsl.jbang.core.common.RuntimeType; /** * Catalog of traits that get applied to a trait context in order to generate a set of Kubernetes resources as a @@ -70,21 +71,25 @@ public class TraitCatalog { * @param traitsSpec the trait configuration spec. * @param context the trait context. * @param clusterType the optional trait profile to select traits. + * @param runtimeType the runtime. */ - public void apply(Traits traitsSpec, TraitContext context, String clusterType) { + public void apply(Traits traitsSpec, TraitContext context, String clusterType, RuntimeType runtimeType) { if (clusterType != null) { new TraitCatalog().traitsForProfile(ClusterType.valueOf(clusterType.toUpperCase(Locale.US))) .forEach(t -> { if (t.configure(traitsSpec, context)) { t.apply(traitsSpec, context); + t.applyRuntimeSpecificProperties(traitsSpec, context, runtimeType); } }); } else { new TraitCatalog().allTraits().forEach(t -> { if (t.configure(traitsSpec, context)) { t.apply(traitsSpec, context); + t.applyRuntimeSpecificProperties(traitsSpec, context, runtimeType); } }); } } + } diff --git a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/TraitContext.java b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/TraitContext.java index a2e1b3238bb..6f54691f026 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/TraitContext.java +++ b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/TraitContext.java @@ -276,7 +276,12 @@ public class TraitContext { this.configurationResources.put(name, content); } + public void addOrAppendConfigurationResource(String name, String content) { + this.configurationResources.merge(name, content, (content1, content2) -> content1 + System.lineSeparator() + content2); + } + public void doWithConfigurationResources(BiConsumer<String, String> consumer) { configurationResources.forEach(consumer); } + } diff --git a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExportTest.java b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExportTest.java index 49e69f869c0..71ce46d19f4 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExportTest.java +++ b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExportTest.java @@ -51,12 +51,6 @@ class KubernetesExportTest extends KubernetesExportBaseTest { Arguments.of(RuntimeType.quarkus)); } - private static Stream<Arguments> runtimeProviderOpenshift() { - return Stream.of( - Arguments.of(RuntimeType.main), - Arguments.of(RuntimeType.springBoot)); - } - @ParameterizedTest @MethodSource("runtimeProvider") public void shouldGenerateProject(RuntimeType rt) throws Exception { @@ -228,10 +222,11 @@ class KubernetesExportTest extends KubernetesExportBaseTest { Assertions.assertEquals("/$2", ingress.getMetadata().getAnnotations().get("nginx.ingress.kubernetes.io/rewrite-target")); Assertions.assertEquals("true", ingress.getMetadata().getAnnotations().get("nginx.ingress.kubernetes.io/use-regex")); + } @ParameterizedTest - @MethodSource("runtimeProviderOpenshift") + @MethodSource("runtimeProvider") public void shouldAddRouteSpec(RuntimeType rt) throws Exception { String certificate = IOHelper.loadText(new FileInputStream("src/test/resources/route/tls.pem")); String key = IOHelper.loadText(new FileInputStream("src/test/resources/route/tls.key")); @@ -266,6 +261,20 @@ class KubernetesExportTest extends KubernetesExportBaseTest { Assertions.assertEquals("route-service", route.getSpec().getTo().getName()); Assertions.assertTrue(certificate.startsWith(route.getSpec().getTls().getCertificate())); Assertions.assertTrue(key.startsWith(route.getSpec().getTls().getKey())); + + if (RuntimeType.quarkus.equals(rt)) { + Properties applicationProperties = getApplicationProperties(workingDir); + Assertions.assertEquals("true", applicationProperties.get("quarkus.openshift.route.expose")); + Assertions.assertEquals("example.com", + applicationProperties.get("quarkus.openshift.route.host")); + Assertions.assertEquals("http", + applicationProperties.get("quarkus.openshift.route.target-port")); + Assertions.assertEquals("edge", + applicationProperties.get("quarkus.openshift.route.tls.termination")); + Assertions.assertTrue(certificate.startsWith( + applicationProperties.get("quarkus.openshift.route.tls.certificate").toString())); + Assertions.assertTrue(key.startsWith(applicationProperties.get("quarkus.openshift.route.tls.key").toString())); + } } @ParameterizedTest