This is an automated email from the ASF dual-hosted git repository.

davsclaus 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 19e52982123f CAMEL-26934: camel-jbang-plugin-kubernetes - env, mounts, 
labels and annotations apply to a CronJob and a Knative Service (#29932)
19e52982123f is described below

commit 19e52982123fbc04219a7b8bdfbec10f3df7b4b5
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Nov 14 19:28:01 2026 +0100

    CAMEL-26934: camel-jbang-plugin-kubernetes - env, mounts, labels and 
annotations apply to a CronJob and a Knative Service (#29932)
    
    A kubernetes export with the CronJob trait dropped --env, --config, 
--volume and
    --annotation, and a Knative Service lost the env and the labels: EnvTrait 
was not used
    without a Deployment and, like MountTrait, applied to the Deployment only; 
LabelTrait
    skipped the Knative Service and AnnotationTrait the CronJob. Each applies 
to the
    workload there is now.
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 .../kubernetes/traits/AnnotationTrait.java         |  5 ++
 .../core/commands/kubernetes/traits/EnvTrait.java  | 56 ++++++++++++++++------
 .../commands/kubernetes/traits/LabelTrait.java     |  6 +++
 .../commands/kubernetes/traits/MountTrait.java     | 28 +++++++++++
 .../kubernetes/KubernetesExportKnativeTest.java    | 26 +++++++++-
 .../commands/kubernetes/KubernetesExportTest.java  | 23 +++++++++
 6 files changed, 128 insertions(+), 16 deletions(-)

diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/AnnotationTrait.java
 
b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/AnnotationTrait.java
index be6d7fd367af..c9827410bffb 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/AnnotationTrait.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/AnnotationTrait.java
@@ -44,5 +44,10 @@ public class AnnotationTrait extends BaseTrait {
                 s -> s.editOrNewMetadata()
                         .addToAnnotations(context.getAnnotations())
                         .endMetadata());
+        // a CronJob had none (CAMEL-26934)
+        context.doWithCronJobs(
+                j -> j.editOrNewMetadata()
+                        .addToAnnotations(context.getAnnotations())
+                        .endMetadata());
     }
 }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/EnvTrait.java
 
b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/EnvTrait.java
index f7556cc88b68..4d03c0567fde 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/EnvTrait.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/EnvTrait.java
@@ -17,11 +17,12 @@
 
 package org.apache.camel.dsl.jbang.core.commands.kubernetes.traits;
 
+import java.util.List;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
+import io.fabric8.kubernetes.api.model.EnvVar;
 import io.fabric8.kubernetes.api.model.EnvVarBuilder;
-import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder;
 import org.apache.camel.RuntimeCamelException;
 import 
org.apache.camel.dsl.jbang.core.commands.kubernetes.traits.model.Environment;
 import org.apache.camel.dsl.jbang.core.commands.kubernetes.traits.model.Traits;
@@ -35,8 +36,8 @@ public class EnvTrait extends BaseTrait {
 
     @Override
     public boolean configure(Traits traitConfig, TraitContext context) {
-        Optional<DeploymentBuilder> deployment = context.getDeployment();
-        if (deployment.isEmpty()) {
+        // a workload: a Deployment, a CronJob or a Knative Service 
(CAMEL-26934: only a Deployment had the variables)
+        if (context.getDeployment().isEmpty() && 
context.getCronJob().isEmpty() && context.getKnativeService().isEmpty()) {
             return false;
         }
 
@@ -49,23 +50,48 @@ public class EnvTrait extends BaseTrait {
         Environment envTrait = traitConfig.getEnvironment();
 
         if (ObjectHelper.isNotEmpty(envTrait.getVars())) {
+            List<EnvVar> vars = envTrait.getVars().stream().map(envvar -> {
+                String[] parts = envvar.split("=", 2);
+                if (parts.length != 2) {
+                    throw new RuntimeCamelException(
+                            "Invalid environment variable '%s', must be in 
NAME=value format".formatted(envvar));
+                }
+                return new EnvVarBuilder()
+                        .withName(parts[0])
+                        .withValue(parts[1])
+                        .build();
+            }).collect(Collectors.toList());
             context.doWithDeployments(
                     d -> d.editSpec()
                             .editTemplate()
                             .editSpec()
                             .editFirstContainer()
-                            
.addAllToEnv(envTrait.getVars().stream().map(envvar -> {
-                                String[] parts = envvar.split("=", 2);
-                                if (parts.length != 2) {
-                                    throw new RuntimeCamelException(
-                                            "Invalid environment variable 
'%s', must be in NAME=value format"
-                                                    .formatted(envvar));
-                                }
-                                return new EnvVarBuilder()
-                                        .withName(parts[0])
-                                        .withValue(parts[1])
-                                        .build();
-                            }).collect(Collectors.toList()))
+                            .addAllToEnv(vars)
+                            .endContainer()
+                            .endSpec()
+                            .endTemplate()
+                            .endSpec());
+            // and the other workloads: a CronJob and a Knative Service had no 
variables (CAMEL-26934)
+            context.doWithCronJobs(
+                    j -> j.editOrNewSpec()
+                            .editOrNewJobTemplate()
+                            .editOrNewSpec()
+                            .editOrNewTemplate()
+                            .editOrNewSpec()
+                            .editFirstContainer()
+                            .addAllToEnv(vars)
+                            .endContainer()
+                            .endSpec()
+                            .endTemplate()
+                            .endSpec()
+                            .endJobTemplate()
+                            .endSpec());
+            context.doWithKnativeServices(
+                    k -> k.editOrNewSpec()
+                            .editOrNewTemplate()
+                            .editOrNewSpec()
+                            .editFirstContainer()
+                            .addAllToEnv(vars)
                             .endContainer()
                             .endSpec()
                             .endTemplate()
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/LabelTrait.java
 
b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/LabelTrait.java
index 590b14d0d50a..22143f6d054a 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/LabelTrait.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/LabelTrait.java
@@ -55,5 +55,11 @@ public class LabelTrait extends BaseTrait {
                         .endMetadata()
                         .endJobTemplate()
                         .endSpec());
+        // a Knative Service had none, also not app.kubernetes.io/runtime 
(CAMEL-26934)
+        context.doWithKnativeServices(
+                k -> k.editOrNewMetadata()
+                        .addToLabels(KUBERNETES_LABEL_NAME, context.getName())
+                        .addToLabels(context.getLabels())
+                        .endMetadata());
     }
 }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/MountTrait.java
 
b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/MountTrait.java
index 7738a1e649b5..f76b8cacfdc9 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/MountTrait.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/traits/MountTrait.java
@@ -102,6 +102,34 @@ public class MountTrait extends BaseTrait {
                 .endSpec()
                 .endTemplate()
                 .endSpec());
+        if (volumes.isEmpty()) {
+            return;
+        }
+        // and the other workloads: a CronJob and a Knative Service had no 
volumes (CAMEL-26934)
+        context.doWithCronJobs(j -> j.editOrNewSpec()
+                .editOrNewJobTemplate()
+                .editOrNewSpec()
+                .editOrNewTemplate()
+                .editOrNewSpec()
+                .addAllToVolumes(volumes)
+                .editFirstContainer()
+                .addAllToVolumeMounts(volumeMounts)
+                .endContainer()
+                .endSpec()
+                .endTemplate()
+                .endSpec()
+                .endJobTemplate()
+                .endSpec());
+        context.doWithKnativeServices(k -> k.editOrNewSpec()
+                .editOrNewTemplate()
+                .editOrNewSpec()
+                .addAllToVolumes(volumes)
+                .editFirstContainer()
+                .addAllToVolumeMounts(volumeMounts)
+                .endContainer()
+                .endSpec()
+                .endTemplate()
+                .endSpec());
     }
 
     private void configureVolumesAndMounts(Mount mountTrait, List<Volume> 
volumes, List<VolumeMount> volumeMounts) {
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExportKnativeTest.java
 
b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExportKnativeTest.java
index 2e7557595429..0db69b22519b 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExportKnativeTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExportKnativeTest.java
@@ -76,7 +76,9 @@ public class KubernetesExportKnativeTest extends 
KubernetesExportBaseTestSupport
         var labelsB = 
service.getSpec().getTemplate().getMetadata().getLabels();
         Map<String, String> annotations = 
service.getSpec().getTemplate().getMetadata().getAnnotations();
         Assertions.assertEquals("route-service", 
service.getMetadata().getName());
-        Assertions.assertEquals(8, labelsA.size());
+        // and app.kubernetes.io/runtime, which the Knative Service did not 
have (CAMEL-26934)
+        Assertions.assertEquals(9, labelsA.size());
+        Assertions.assertEquals("camel", 
labelsA.get("app.kubernetes.io/runtime"));
         Assertions.assertEquals("route-service", 
labelsA.get(BaseTrait.KUBERNETES_LABEL_NAME));
         Assertions.assertEquals("true", 
labelsA.get("bindings.knative.dev/include"));
         Assertions.assertEquals("cluster-local", 
labelsA.get("networking.knative.dev/visibility"));
@@ -93,6 +95,28 @@ public class KubernetesExportKnativeTest extends 
KubernetesExportBaseTestSupport
         Assertions.assertEquals(300, 
service.getSpec().getTemplate().getSpec().getTimeoutSeconds());
     }
 
+    @ParameterizedTest
+    @MethodSource("runtimeProvider")
+    public void theOptionsOfTheWorkloadApplyToAKnativeService(RuntimeType rt) 
throws Exception {
+        // the env, the volumes and the labels were not in the Knative Service 
(CAMEL-26934)
+        KubernetesExport command = createCommand(new String[] { 
"classpath:route-service.yaml" },
+                "--image-group=camel-test", "--runtime=" + rt.runtime(), 
"--env=MY_VAR=hello",
+                "--config=configmap:my-cm", "--label=tier=web");
+        command.traits = new String[] { "knative-service.enabled=true" };
+        Assertions.assertEquals(0, command.doCall());
+
+        Service service = getResource(rt, Service.class)
+                .orElseThrow(() -> new RuntimeCamelException("Missing Knative 
service in Kubernetes manifest"));
+        var pod = service.getSpec().getTemplate().getSpec();
+        var container = pod.getContainers().get(0);
+        Assertions.assertTrue(container.getEnv().stream()
+                .anyMatch(e -> "MY_VAR".equals(e.getName()) && 
"hello".equals(e.getValue())), container.getEnv().toString());
+        Assertions.assertTrue(pod.getVolumes().stream()
+                .anyMatch(v -> v.getConfigMap() != null && 
"my-cm".equals(v.getConfigMap().getName())),
+                pod.getVolumes().toString());
+        Assertions.assertEquals("web", 
service.getMetadata().getLabels().get("tier"));
+    }
+
     @ParameterizedTest
     @MethodSource("runtimeProvider")
     public void shouldAddKnativeTrigger(RuntimeType rt) throws Exception {
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 fefb0123af96..332561c3eb4b 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
@@ -224,6 +224,29 @@ class KubernetesExportTest extends 
KubernetesExportBaseTestSupport {
         Assertions.assertFalse(hasKnativeService(rt));
     }
 
+    @ParameterizedTest
+    @MethodSource("runtimeProvider")
+    public void theOptionsOfTheWorkloadApplyToACronjob(RuntimeType rt) throws 
Exception {
+        // --env, --config and --annotation were not in cronjob.yml 
(CAMEL-26934)
+        KubernetesExport command = createCommand(new String[] { 
"classpath:route.yaml" },
+                "--image-group=camel-test", "--runtime=" + rt.runtime(), 
"--env=MY_VAR=hello",
+                "--config=configmap:my-cm", "--annotation=team=ops");
+        command.traits = new String[] { "cronjob.enabled=true", 
"cronjob.schedule=\"0 22 * * 1-5\"" };
+        Assertions.assertEquals(0, command.doCall());
+
+        CronJob cronjob = getResource(rt, CronJob.class)
+                .orElseThrow(() -> new RuntimeCamelException("Cannot find 
cronjob for: %s".formatted(rt.runtime())));
+        var pod = 
cronjob.getSpec().getJobTemplate().getSpec().getTemplate().getSpec();
+        var container = pod.getContainers().get(0);
+        Assertions.assertTrue(container.getEnv().stream()
+                .anyMatch(e -> "MY_VAR".equals(e.getName()) && 
"hello".equals(e.getValue())), container.getEnv().toString());
+        Assertions.assertTrue(pod.getVolumes().stream()
+                .anyMatch(v -> v.getConfigMap() != null && 
"my-cm".equals(v.getConfigMap().getName())),
+                pod.getVolumes().toString());
+        Assertions.assertFalse(container.getVolumeMounts().isEmpty());
+        Assertions.assertEquals("ops", 
cronjob.getMetadata().getAnnotations().get("team"));
+    }
+
     @ParameterizedTest
     @MethodSource("runtimeProvider")
     public void shouldGenerateCronjobKubernetesManifest(RuntimeType rt) throws 
Exception {

Reply via email to