This is an automated email from the ASF dual-hosted git repository. pcongiusti pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit e07d0da4fe3167f27f7f5871b3ad0c80bd2dbf7f Author: Pranjul Kalsi <[email protected]> AuthorDate: Thu Dec 18 13:21:48 2025 +0530 fix(jvm): change caCert params from secret refs to file paths --- docs/modules/ROOT/partials/apis/camel-k-crds.adoc | 13 +-- docs/modules/traits/pages/jvm.adoc | 43 +++++---- e2e/common/traits/jvm_test.go | 6 +- helm/camel-k/crds/camel-k-crds.yaml | 104 +++++++++++---------- pkg/apis/camel/v1/trait/jvm.go | 13 +-- .../camel.apache.org_integrationplatforms.yaml | 26 +++--- .../camel.apache.org_integrationprofiles.yaml | 26 +++--- .../crd/bases/camel.apache.org_integrations.yaml | 26 +++--- .../config/crd/bases/camel.apache.org_pipes.yaml | 26 +++--- pkg/trait/init_containers.go | 18 +--- pkg/trait/init_containers_test.go | 4 +- pkg/trait/jvm.go | 23 +---- pkg/trait/jvm_cacert.go | 76 ++++----------- pkg/trait/jvm_test.go | 73 ++++----------- pkg/trait/mount.go | 26 +----- pkg/trait/mount_test.go | 22 +---- 16 files changed, 210 insertions(+), 315 deletions(-) diff --git a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc index 6c3dd80db..2013fbab5 100644 --- a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc +++ b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc @@ -7801,15 +7801,16 @@ string | -The secret should contain PEM-encoded certificates. -Example: "secret:my-ca-certs" or "secret:my-ca-certs/custom-ca.crt" +Path to a PEM-encoded CA certificate file. The file must be mounted +by the user using the mount trait (e.g., mount.configs or mount.secrets). +Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt" |`caCertMountPath` + string | -The path where the generated truststore will be mounted +The path where the generated truststore will be mounted. Default: "/etc/camel/conf.d/_truststore" |`caCertPassword` + @@ -7817,9 +7818,9 @@ string | -Required when caCert is set. A secret reference containing the truststore password. -If the secret key is not specified, "password" is used as the default key. -Example: "secret:my-truststore-password" or "secret:my-truststore-password/mykey" +Required when caCert is set. Path to a file containing the truststore password. +The file must be mounted by the user using the mount trait. +Example: "/etc/camel/conf.d/_secrets/truststore-pass/password" |=== diff --git a/docs/modules/traits/pages/jvm.adoc b/docs/modules/traits/pages/jvm.adoc index baca4f6f9..a7079b61b 100755 --- a/docs/modules/traits/pages/jvm.adoc +++ b/docs/modules/traits/pages/jvm.adoc @@ -64,19 +64,20 @@ Deprecated: no longer in use. | jvm.ca-cert | string -| The secret should contain PEM-encoded certificates. -Example: "secret:my-ca-certs" or "secret:my-ca-certs/custom-ca.crt" +| Path to a PEM-encoded CA certificate file. The file must be mounted +by the user using the mount trait (e.g., mount.configs or mount.secrets). +Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt" | jvm.ca-cert-mount-path | string -| The path where the generated truststore will be mounted +| The path where the generated truststore will be mounted. Default: "/etc/camel/conf.d/_truststore" | jvm.ca-cert-password | string -| Required when caCert is set. A secret reference containing the truststore password. -If the secret key is not specified, "password" is used as the default key. -Example: "secret:my-truststore-password" or "secret:my-truststore-password/mykey" +| Required when caCert is set. Path to a file containing the truststore password. +The file must be mounted by the user using the mount trait. +Example: "/etc/camel/conf.d/_secrets/truststore-pass/password" |=== @@ -115,39 +116,41 @@ $ kamel run --resource configmap:my-dep -t jvm.classpath=/etc/camel/resources/my When connecting to services that use TLS with certificates signed by a private CA (e.g., internal Elasticsearch, Kafka, or databases), you can use the `ca-cert` option to add the CA certificate to the JVM's truststore. -First, create a Kubernetes Secret containing the CA certificate: +First, create Kubernetes Secrets containing the CA certificate and truststore password: [source,console] ---- kubectl create secret generic my-private-ca --from-file=ca.crt=/path/to/ca-certificate.pem ----- - -Next, create a Secret containing the truststore password: - -[source,console] ----- kubectl create secret generic my-truststore-pwd --from-literal=password=mysecurepassword ---- -Then reference both secrets when running the integration: +Then mount the secrets using the mount trait and reference the file paths: [source,console] ---- -$ kamel run MyRoute.java -t jvm.ca-cert=secret:my-private-ca -t jvm.ca-cert-password=secret:my-truststore-pwd +$ kamel run MyRoute.java \ + -t mount.configs=secret:my-private-ca \ + -t mount.configs=secret:my-truststore-pwd \ + -t jvm.ca-cert=/etc/camel/conf.d/_secrets/my-private-ca/ca.crt \ + -t jvm.ca-cert-password=/etc/camel/conf.d/_secrets/my-truststore-pwd/password ---- -If your certificate is stored under a different key in the secret: +If your secret uses a different key name for the certificate: [source,console] ---- -$ kamel run MyRoute.java -t jvm.ca-cert=secret:my-private-ca/custom-ca.pem -t jvm.ca-cert-password=secret:my-truststore-pwd +$ kamel run MyRoute.java \ + -t mount.configs=secret:my-private-ca \ + -t mount.configs=secret:my-truststore-pwd \ + -t jvm.ca-cert=/etc/camel/conf.d/_secrets/my-private-ca/custom-ca.pem \ + -t jvm.ca-cert-password=/etc/camel/conf.d/_secrets/my-truststore-pwd/password ---- This will automatically: -1. Mount the CA certificate secret +1. Mount the secrets to the integration container (via mount trait) 2. Generate a JVM truststore using an init container 3. Configure the JVM to use the generated truststore via `-Djavax.net.ssl.trustStore` -4. Inject the truststore password securely as an environment variable from your secret -NOTE: The `ca-cert-password` option is **required** when using `ca-cert`. The password is never exposed in command-line arguments - it is injected as an environment variable from the secret. +NOTE: The `ca-cert-password` option is **required** when using `ca-cert`. Both values must be file paths to the mounted secrets. + diff --git a/e2e/common/traits/jvm_test.go b/e2e/common/traits/jvm_test.go index ea07ae3f6..6e143b98b 100644 --- a/e2e/common/traits/jvm_test.go +++ b/e2e/common/traits/jvm_test.go @@ -111,8 +111,10 @@ func TestJVMTrait(t *testing.T) { g.Expect(KamelRun(t, ctx, ns, "./files/Java.java", "--name", name, - "-t", "jvm.ca-cert=secret:test-ca-cert", - "-t", "jvm.ca-cert-password=secret:test-ca-password", + "-t", "mount.configs=secret:test-ca-cert", + "-t", "mount.configs=secret:test-ca-password", + "-t", "jvm.ca-cert=/etc/camel/conf.d/_secrets/test-ca-cert/ca.crt", + "-t", "jvm.ca-cert-password=/etc/camel/conf.d/_secrets/test-ca-password/password", ).Execute()).To(Succeed()) g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) diff --git a/helm/camel-k/crds/camel-k-crds.yaml b/helm/camel-k/crds/camel-k-crds.yaml index 4b324ed8c..9b6662390 100644 --- a/helm/camel-k/crds/camel-k-crds.yaml +++ b/helm/camel-k/crds/camel-k-crds.yaml @@ -4723,19 +4723,20 @@ spec: type: array caCert: description: |- - The secret should contain PEM-encoded certificates. - Example: "secret:my-ca-certs" or "secret:my-ca-certs/custom-ca.crt" + Path to a PEM-encoded CA certificate file. The file must be mounted + by the user using the mount trait (e.g., mount.configs or mount.secrets). + Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt" type: string caCertMountPath: description: |- - The path where the generated truststore will be mounted + The path where the generated truststore will be mounted. Default: "/etc/camel/conf.d/_truststore" type: string caCertPassword: description: |- - Required when caCert is set. A secret reference containing the truststore password. - If the secret key is not specified, "password" is used as the default key. - Example: "secret:my-truststore-password" or "secret:my-truststore-password/mykey" + Required when caCert is set. Path to a file containing the truststore password. + The file must be mounted by the user using the mount trait. + Example: "/etc/camel/conf.d/_secrets/truststore-pass/password" type: string classpath: description: Additional JVM classpath (use `Linux` classpath @@ -7145,19 +7146,20 @@ spec: type: array caCert: description: |- - The secret should contain PEM-encoded certificates. - Example: "secret:my-ca-certs" or "secret:my-ca-certs/custom-ca.crt" + Path to a PEM-encoded CA certificate file. The file must be mounted + by the user using the mount trait (e.g., mount.configs or mount.secrets). + Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt" type: string caCertMountPath: description: |- - The path where the generated truststore will be mounted + The path where the generated truststore will be mounted. Default: "/etc/camel/conf.d/_truststore" type: string caCertPassword: description: |- - Required when caCert is set. A secret reference containing the truststore password. - If the secret key is not specified, "password" is used as the default key. - Example: "secret:my-truststore-password" or "secret:my-truststore-password/mykey" + Required when caCert is set. Path to a file containing the truststore password. + The file must be mounted by the user using the mount trait. + Example: "/etc/camel/conf.d/_secrets/truststore-pass/password" type: string classpath: description: Additional JVM classpath (use `Linux` classpath @@ -9469,19 +9471,20 @@ spec: type: array caCert: description: |- - The secret should contain PEM-encoded certificates. - Example: "secret:my-ca-certs" or "secret:my-ca-certs/custom-ca.crt" + Path to a PEM-encoded CA certificate file. The file must be mounted + by the user using the mount trait (e.g., mount.configs or mount.secrets). + Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt" type: string caCertMountPath: description: |- - The path where the generated truststore will be mounted + The path where the generated truststore will be mounted. Default: "/etc/camel/conf.d/_truststore" type: string caCertPassword: description: |- - Required when caCert is set. A secret reference containing the truststore password. - If the secret key is not specified, "password" is used as the default key. - Example: "secret:my-truststore-password" or "secret:my-truststore-password/mykey" + Required when caCert is set. Path to a file containing the truststore password. + The file must be mounted by the user using the mount trait. + Example: "/etc/camel/conf.d/_secrets/truststore-pass/password" type: string classpath: description: Additional JVM classpath (use `Linux` classpath @@ -11770,19 +11773,20 @@ spec: type: array caCert: description: |- - The secret should contain PEM-encoded certificates. - Example: "secret:my-ca-certs" or "secret:my-ca-certs/custom-ca.crt" + Path to a PEM-encoded CA certificate file. The file must be mounted + by the user using the mount trait (e.g., mount.configs or mount.secrets). + Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt" type: string caCertMountPath: description: |- - The path where the generated truststore will be mounted + The path where the generated truststore will be mounted. Default: "/etc/camel/conf.d/_truststore" type: string caCertPassword: description: |- - Required when caCert is set. A secret reference containing the truststore password. - If the secret key is not specified, "password" is used as the default key. - Example: "secret:my-truststore-password" or "secret:my-truststore-password/mykey" + Required when caCert is set. Path to a file containing the truststore password. + The file must be mounted by the user using the mount trait. + Example: "/etc/camel/conf.d/_secrets/truststore-pass/password" type: string classpath: description: Additional JVM classpath (use `Linux` classpath @@ -20905,19 +20909,20 @@ spec: type: array caCert: description: |- - The secret should contain PEM-encoded certificates. - Example: "secret:my-ca-certs" or "secret:my-ca-certs/custom-ca.crt" + Path to a PEM-encoded CA certificate file. The file must be mounted + by the user using the mount trait (e.g., mount.configs or mount.secrets). + Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt" type: string caCertMountPath: description: |- - The path where the generated truststore will be mounted + The path where the generated truststore will be mounted. Default: "/etc/camel/conf.d/_truststore" type: string caCertPassword: description: |- - Required when caCert is set. A secret reference containing the truststore password. - If the secret key is not specified, "password" is used as the default key. - Example: "secret:my-truststore-password" or "secret:my-truststore-password/mykey" + Required when caCert is set. Path to a file containing the truststore password. + The file must be mounted by the user using the mount trait. + Example: "/etc/camel/conf.d/_secrets/truststore-pass/password" type: string classpath: description: Additional JVM classpath (use `Linux` classpath @@ -23160,19 +23165,20 @@ spec: type: array caCert: description: |- - The secret should contain PEM-encoded certificates. - Example: "secret:my-ca-certs" or "secret:my-ca-certs/custom-ca.crt" + Path to a PEM-encoded CA certificate file. The file must be mounted + by the user using the mount trait (e.g., mount.configs or mount.secrets). + Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt" type: string caCertMountPath: description: |- - The path where the generated truststore will be mounted + The path where the generated truststore will be mounted. Default: "/etc/camel/conf.d/_truststore" type: string caCertPassword: description: |- - Required when caCert is set. A secret reference containing the truststore password. - If the secret key is not specified, "password" is used as the default key. - Example: "secret:my-truststore-password" or "secret:my-truststore-password/mykey" + Required when caCert is set. Path to a file containing the truststore password. + The file must be mounted by the user using the mount trait. + Example: "/etc/camel/conf.d/_secrets/truststore-pass/password" type: string classpath: description: Additional JVM classpath (use `Linux` classpath @@ -33657,19 +33663,20 @@ spec: type: array caCert: description: |- - The secret should contain PEM-encoded certificates. - Example: "secret:my-ca-certs" or "secret:my-ca-certs/custom-ca.crt" + Path to a PEM-encoded CA certificate file. The file must be mounted + by the user using the mount trait (e.g., mount.configs or mount.secrets). + Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt" type: string caCertMountPath: description: |- - The path where the generated truststore will be mounted + The path where the generated truststore will be mounted. Default: "/etc/camel/conf.d/_truststore" type: string caCertPassword: description: |- - Required when caCert is set. A secret reference containing the truststore password. - If the secret key is not specified, "password" is used as the default key. - Example: "secret:my-truststore-password" or "secret:my-truststore-password/mykey" + Required when caCert is set. Path to a file containing the truststore password. + The file must be mounted by the user using the mount trait. + Example: "/etc/camel/conf.d/_secrets/truststore-pass/password" type: string classpath: description: Additional JVM classpath (use `Linux` classpath @@ -35844,19 +35851,20 @@ spec: type: array caCert: description: |- - The secret should contain PEM-encoded certificates. - Example: "secret:my-ca-certs" or "secret:my-ca-certs/custom-ca.crt" + Path to a PEM-encoded CA certificate file. The file must be mounted + by the user using the mount trait (e.g., mount.configs or mount.secrets). + Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt" type: string caCertMountPath: description: |- - The path where the generated truststore will be mounted + The path where the generated truststore will be mounted. Default: "/etc/camel/conf.d/_truststore" type: string caCertPassword: description: |- - Required when caCert is set. A secret reference containing the truststore password. - If the secret key is not specified, "password" is used as the default key. - Example: "secret:my-truststore-password" or "secret:my-truststore-password/mykey" + Required when caCert is set. Path to a file containing the truststore password. + The file must be mounted by the user using the mount trait. + Example: "/etc/camel/conf.d/_secrets/truststore-pass/password" type: string classpath: description: Additional JVM classpath (use `Linux` classpath diff --git a/pkg/apis/camel/v1/trait/jvm.go b/pkg/apis/camel/v1/trait/jvm.go index b00c7c6a8..a1f855fe0 100644 --- a/pkg/apis/camel/v1/trait/jvm.go +++ b/pkg/apis/camel/v1/trait/jvm.go @@ -42,14 +42,15 @@ type JVMTrait struct { Jar string `json:"jar,omitempty" property:"jar"` // A list of JVM agents to download and execute with format `<agent-name>;<agent-url>[;<jvm-agent-options>]`. Agents []string `json:"agents,omitempty" property:"agents"` - // The secret should contain PEM-encoded certificates. - // Example: "secret:my-ca-certs" or "secret:my-ca-certs/custom-ca.crt" + // Path to a PEM-encoded CA certificate file. The file must be mounted + // by the user using the mount trait (e.g., mount.configs or mount.secrets). + // Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt" CACert string `json:"caCert,omitempty" property:"ca-cert"` - // The path where the generated truststore will be mounted + // The path where the generated truststore will be mounted. // Default: "/etc/camel/conf.d/_truststore" CACertMountPath string `json:"caCertMountPath,omitempty" property:"ca-cert-mount-path"` - // Required when caCert is set. A secret reference containing the truststore password. - // If the secret key is not specified, "password" is used as the default key. - // Example: "secret:my-truststore-password" or "secret:my-truststore-password/mykey" + // Required when caCert is set. Path to a file containing the truststore password. + // The file must be mounted by the user using the mount trait. + // Example: "/etc/camel/conf.d/_secrets/truststore-pass/password" CACertPassword string `json:"caCertPassword,omitempty" property:"ca-cert-password"` } diff --git a/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml b/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml index 27cebea39..972725282 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml @@ -1474,19 +1474,20 @@ spec: type: array caCert: description: |- - The secret should contain PEM-encoded certificates. - Example: "secret:my-ca-certs" or "secret:my-ca-certs/custom-ca.crt" + Path to a PEM-encoded CA certificate file. The file must be mounted + by the user using the mount trait (e.g., mount.configs or mount.secrets). + Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt" type: string caCertMountPath: description: |- - The path where the generated truststore will be mounted + The path where the generated truststore will be mounted. Default: "/etc/camel/conf.d/_truststore" type: string caCertPassword: description: |- - Required when caCert is set. A secret reference containing the truststore password. - If the secret key is not specified, "password" is used as the default key. - Example: "secret:my-truststore-password" or "secret:my-truststore-password/mykey" + Required when caCert is set. Path to a file containing the truststore password. + The file must be mounted by the user using the mount trait. + Example: "/etc/camel/conf.d/_secrets/truststore-pass/password" type: string classpath: description: Additional JVM classpath (use `Linux` classpath @@ -3896,19 +3897,20 @@ spec: type: array caCert: description: |- - The secret should contain PEM-encoded certificates. - Example: "secret:my-ca-certs" or "secret:my-ca-certs/custom-ca.crt" + Path to a PEM-encoded CA certificate file. The file must be mounted + by the user using the mount trait (e.g., mount.configs or mount.secrets). + Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt" type: string caCertMountPath: description: |- - The path where the generated truststore will be mounted + The path where the generated truststore will be mounted. Default: "/etc/camel/conf.d/_truststore" type: string caCertPassword: description: |- - Required when caCert is set. A secret reference containing the truststore password. - If the secret key is not specified, "password" is used as the default key. - Example: "secret:my-truststore-password" or "secret:my-truststore-password/mykey" + Required when caCert is set. Path to a file containing the truststore password. + The file must be mounted by the user using the mount trait. + Example: "/etc/camel/conf.d/_secrets/truststore-pass/password" type: string classpath: description: Additional JVM classpath (use `Linux` classpath diff --git a/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml b/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml index 61fda2ec5..d51140633 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml @@ -1342,19 +1342,20 @@ spec: type: array caCert: description: |- - The secret should contain PEM-encoded certificates. - Example: "secret:my-ca-certs" or "secret:my-ca-certs/custom-ca.crt" + Path to a PEM-encoded CA certificate file. The file must be mounted + by the user using the mount trait (e.g., mount.configs or mount.secrets). + Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt" type: string caCertMountPath: description: |- - The path where the generated truststore will be mounted + The path where the generated truststore will be mounted. Default: "/etc/camel/conf.d/_truststore" type: string caCertPassword: description: |- - Required when caCert is set. A secret reference containing the truststore password. - If the secret key is not specified, "password" is used as the default key. - Example: "secret:my-truststore-password" or "secret:my-truststore-password/mykey" + Required when caCert is set. Path to a file containing the truststore password. + The file must be mounted by the user using the mount trait. + Example: "/etc/camel/conf.d/_secrets/truststore-pass/password" type: string classpath: description: Additional JVM classpath (use `Linux` classpath @@ -3643,19 +3644,20 @@ spec: type: array caCert: description: |- - The secret should contain PEM-encoded certificates. - Example: "secret:my-ca-certs" or "secret:my-ca-certs/custom-ca.crt" + Path to a PEM-encoded CA certificate file. The file must be mounted + by the user using the mount trait (e.g., mount.configs or mount.secrets). + Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt" type: string caCertMountPath: description: |- - The path where the generated truststore will be mounted + The path where the generated truststore will be mounted. Default: "/etc/camel/conf.d/_truststore" type: string caCertPassword: description: |- - Required when caCert is set. A secret reference containing the truststore password. - If the secret key is not specified, "password" is used as the default key. - Example: "secret:my-truststore-password" or "secret:my-truststore-password/mykey" + Required when caCert is set. Path to a file containing the truststore password. + The file must be mounted by the user using the mount trait. + Example: "/etc/camel/conf.d/_secrets/truststore-pass/password" type: string classpath: description: Additional JVM classpath (use `Linux` classpath diff --git a/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml b/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml index 2ec617d6c..901483d1c 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml @@ -8156,19 +8156,20 @@ spec: type: array caCert: description: |- - The secret should contain PEM-encoded certificates. - Example: "secret:my-ca-certs" or "secret:my-ca-certs/custom-ca.crt" + Path to a PEM-encoded CA certificate file. The file must be mounted + by the user using the mount trait (e.g., mount.configs or mount.secrets). + Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt" type: string caCertMountPath: description: |- - The path where the generated truststore will be mounted + The path where the generated truststore will be mounted. Default: "/etc/camel/conf.d/_truststore" type: string caCertPassword: description: |- - Required when caCert is set. A secret reference containing the truststore password. - If the secret key is not specified, "password" is used as the default key. - Example: "secret:my-truststore-password" or "secret:my-truststore-password/mykey" + Required when caCert is set. Path to a file containing the truststore password. + The file must be mounted by the user using the mount trait. + Example: "/etc/camel/conf.d/_secrets/truststore-pass/password" type: string classpath: description: Additional JVM classpath (use `Linux` classpath @@ -10411,19 +10412,20 @@ spec: type: array caCert: description: |- - The secret should contain PEM-encoded certificates. - Example: "secret:my-ca-certs" or "secret:my-ca-certs/custom-ca.crt" + Path to a PEM-encoded CA certificate file. The file must be mounted + by the user using the mount trait (e.g., mount.configs or mount.secrets). + Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt" type: string caCertMountPath: description: |- - The path where the generated truststore will be mounted + The path where the generated truststore will be mounted. Default: "/etc/camel/conf.d/_truststore" type: string caCertPassword: description: |- - Required when caCert is set. A secret reference containing the truststore password. - If the secret key is not specified, "password" is used as the default key. - Example: "secret:my-truststore-password" or "secret:my-truststore-password/mykey" + Required when caCert is set. Path to a file containing the truststore password. + The file must be mounted by the user using the mount trait. + Example: "/etc/camel/conf.d/_secrets/truststore-pass/password" type: string classpath: description: Additional JVM classpath (use `Linux` classpath diff --git a/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml b/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml index c4d821277..f7e2979db 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml @@ -8212,19 +8212,20 @@ spec: type: array caCert: description: |- - The secret should contain PEM-encoded certificates. - Example: "secret:my-ca-certs" or "secret:my-ca-certs/custom-ca.crt" + Path to a PEM-encoded CA certificate file. The file must be mounted + by the user using the mount trait (e.g., mount.configs or mount.secrets). + Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt" type: string caCertMountPath: description: |- - The path where the generated truststore will be mounted + The path where the generated truststore will be mounted. Default: "/etc/camel/conf.d/_truststore" type: string caCertPassword: description: |- - Required when caCert is set. A secret reference containing the truststore password. - If the secret key is not specified, "password" is used as the default key. - Example: "secret:my-truststore-password" or "secret:my-truststore-password/mykey" + Required when caCert is set. Path to a file containing the truststore password. + The file must be mounted by the user using the mount trait. + Example: "/etc/camel/conf.d/_secrets/truststore-pass/password" type: string classpath: description: Additional JVM classpath (use `Linux` classpath @@ -10399,19 +10400,20 @@ spec: type: array caCert: description: |- - The secret should contain PEM-encoded certificates. - Example: "secret:my-ca-certs" or "secret:my-ca-certs/custom-ca.crt" + Path to a PEM-encoded CA certificate file. The file must be mounted + by the user using the mount trait (e.g., mount.configs or mount.secrets). + Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt" type: string caCertMountPath: description: |- - The path where the generated truststore will be mounted + The path where the generated truststore will be mounted. Default: "/etc/camel/conf.d/_truststore" type: string caCertPassword: description: |- - Required when caCert is set. A secret reference containing the truststore password. - If the secret key is not specified, "password" is used as the default key. - Example: "secret:my-truststore-password" or "secret:my-truststore-password/mykey" + Required when caCert is set. Path to a file containing the truststore password. + The file must be mounted by the user using the mount trait. + Example: "/etc/camel/conf.d/_secrets/truststore-pass/password" type: string classpath: description: Additional JVM classpath (use `Linux` classpath diff --git a/pkg/trait/init_containers.go b/pkg/trait/init_containers.go index ec423ef64..574a1da18 100644 --- a/pkg/trait/init_containers.go +++ b/pkg/trait/init_containers.go @@ -93,28 +93,18 @@ func (t *initContainersTrait) Configure(e *Environment) (bool, *TraitCondition, } // Set the CA cert truststore init container if configured if ok && jvm.hasCACert() { - _, secretKey, err := parseSecretRef(jvm.CACert) - if err != nil { + if err := jvm.validateCACertConfig(); err != nil { return false, nil, err } - if secretKey == "" { - secretKey = "ca.crt" - } - - secretName, secretKey2, err := jvm.getTrustStorePasswordSecretRef() - if err != nil { - return false, nil, err - } - + // keytool reads password from file using -storepass:file keytoolCmd := fmt.Sprintf( - "keytool -importcert -noprompt -alias custom-ca -storepass:env %s -keystore %s -file /etc/secrets/cacert/%s", - truststorePasswordEnvVar, jvm.getTrustStorePath(), secretKey, + "keytool -importcert -noprompt -alias custom-ca -storepass:file %s -keystore %s -file %s", + jvm.getCACertPasswordPath(), jvm.getTrustStorePath(), jvm.getCACertPath(), ) caCertTask := containerTask{ name: "generate-truststore", image: defaults.BaseImage(), command: keytoolCmd, - env: []corev1.EnvVar{getTrustStorePasswordEnvVar(secretName, secretKey2)}, } t.tasks = append(t.tasks, caCertTask) } diff --git a/pkg/trait/init_containers_test.go b/pkg/trait/init_containers_test.go index 9f562b8f5..afad65841 100644 --- a/pkg/trait/init_containers_test.go +++ b/pkg/trait/init_containers_test.go @@ -393,8 +393,8 @@ func TestApplyInitContainerWithCACert(t *testing.T) { Spec: v1.IntegrationSpec{ Traits: v1.Traits{ JVM: &trait.JVMTrait{ - CACert: "secret:my-ca-secret", - CACertPassword: "secret:my-ca-password", + CACert: "/etc/camel/conf.d/_secrets/my-ca/ca.crt", + CACertPassword: "/etc/camel/conf.d/_secrets/truststore-pass/password", }, }, }, diff --git a/pkg/trait/jvm.go b/pkg/trait/jvm.go index 484d7d4eb..8c1a5c541 100644 --- a/pkg/trait/jvm.go +++ b/pkg/trait/jvm.go @@ -158,7 +158,7 @@ func (t *jvmTrait) Apply(e *Environment) error { args = append(args, httpProxyArgs...) } - caCertArgs, err := t.configureCaCert(e) + caCertArgs, err := t.configureCaCert() if err != nil { return err } @@ -379,26 +379,13 @@ func getLegacyCamelQuarkusDependenciesPaths() *sets.Set { } // configureCACert configures the CA certificate truststore and returns the JVM arguments. -func (t *jvmTrait) configureCaCert(e *Environment) ([]string, error) { - if t.CACert == "" { - return nil, nil - } - - _, _, err := parseSecretRef(t.CACert) - if err != nil { +func (t *jvmTrait) configureCaCert() ([]string, error) { + if err := t.validateCACertConfig(); err != nil { return nil, err } - secretName, secretKey, err := t.getTrustStorePasswordSecretRef() - if err != nil { - return nil, fmt.Errorf("failed to configure truststore password: %w", err) - } - - // Inject password - container := e.GetIntegrationContainer() - if container != nil { - envVar := getTrustStorePasswordEnvVar(secretName, secretKey) - container.Env = append(container.Env, envVar) + if t.CACert == "" { + return nil, nil } return []string{ diff --git a/pkg/trait/jvm_cacert.go b/pkg/trait/jvm_cacert.go index 6220a5e0e..7d11f678e 100644 --- a/pkg/trait/jvm_cacert.go +++ b/pkg/trait/jvm_cacert.go @@ -17,21 +17,13 @@ limitations under the License. package trait -import ( - "errors" - "fmt" - "strings" - - corev1 "k8s.io/api/core/v1" -) +import "errors" const ( - defaultCACertMountPath = "/etc/camel/conf.d/_truststore" - caCertVolumeName = "jvm-truststore" - caCertSecretVolumeName = "ca-cert-secret" //nolint:gosec // G101: not a credential, just a volume name - trustStoreName = "truststore.jks" - truststorePasswordEnvVar = "TRUSTSTORE_PASSWORD" - truststorePasswordSecretKey = "password" + defaultCACertMountPath = "/etc/camel/conf.d/_truststore" + caCertVolumeName = "jvm-truststore" + trustStoreName = "truststore.jks" + truststorePasswordEnvVar = "TRUSTSTORE_PASSWORD" ) func (t *jvmTrait) hasCACert() bool { @@ -46,58 +38,28 @@ func (t *jvmTrait) getCACertMountPath() string { return defaultCACertMountPath } -// parseSecretRef parses a secret reference in the format "secret:name" or "secret:name/key". -func parseSecretRef(ref string) (string, string, error) { - if !strings.HasPrefix(ref, "secret:") { - return "", "", fmt.Errorf("invalid CA cert reference %q: must start with 'secret:'", ref) - } - - ref = strings.TrimPrefix(ref, "secret:") - parts := strings.SplitN(ref, "/", 2) - secretName, secretKey := parts[0], "" - - if len(parts) > 1 { - secretKey = parts[1] - } - if secretName == "" { - return "", "", errors.New("invalid CA cert reference: secret name is empty") - } - - return secretName, secretKey, nil -} - func (t *jvmTrait) getTrustStorePath() string { return t.getCACertMountPath() + "/" + trustStoreName } -// getTrustStorePasswordSecretRef parses and returns the user-provided password secret reference. -func (t *jvmTrait) getTrustStorePasswordSecretRef() (string, string, error) { +// validateCACertConfig validates that the required file paths are provided. +func (t *jvmTrait) validateCACertConfig() error { + if t.CACert == "" { + return nil + } if t.CACertPassword == "" { - return "", "", errors.New("ca-cert-password is required when ca-cert is set") + return errors.New("ca-cert-password is required when ca-cert is set") } - secretName, secretKey, err := parseSecretRef(t.CACertPassword) - if err != nil { - return "", "", fmt.Errorf("invalid ca-cert-password reference: %w", err) - } - if secretKey == "" { - secretKey = truststorePasswordSecretKey - } + return nil +} - return secretName, secretKey, nil +// getCACertPath returns the user-provided CA certificate file path. +func (t *jvmTrait) getCACertPath() string { + return t.CACert } -// getTrustStorePasswordEnvVar returns the environment variable for truststore password injection. -func getTrustStorePasswordEnvVar(secretName, secretKey string) corev1.EnvVar { - return corev1.EnvVar{ - Name: truststorePasswordEnvVar, - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: secretName, - }, - Key: secretKey, - }, - }, - } +// getCACertPasswordPath returns the user-provided password file path. +func (t *jvmTrait) getCACertPasswordPath() string { + return t.CACertPassword } diff --git a/pkg/trait/jvm_test.go b/pkg/trait/jvm_test.go index 62883cfad..c458c0154 100644 --- a/pkg/trait/jvm_test.go +++ b/pkg/trait/jvm_test.go @@ -722,7 +722,7 @@ func TestApplyJvmTraitAgentFail(t *testing.T) { func TestApplyJvmTraitWithCACertMissingPassword(t *testing.T) { trait, environment := createNominalJvmTest(v1.IntegrationKitTypePlatform) - trait.CACert = "secret:my-ca-secret" + trait.CACert = "/etc/camel/conf.d/_secrets/my-ca/ca.crt" d := appsv1.Deployment{ Spec: appsv1.DeploymentSpec{ @@ -751,8 +751,8 @@ func TestApplyJvmTraitWithCACertMissingPassword(t *testing.T) { func TestApplyJvmTraitWithCACert(t *testing.T) { trait, environment := createNominalJvmTest(v1.IntegrationKitTypePlatform) - trait.CACert = "secret:my-ca-secret" - trait.CACertPassword = "secret:my-truststore-password" + trait.CACert = "/etc/camel/conf.d/_secrets/my-ca/ca.crt" + trait.CACertPassword = "/etc/camel/conf.d/_secrets/truststore-pass/password" d := appsv1.Deployment{ Spec: appsv1.DeploymentSpec{ @@ -779,46 +779,31 @@ func TestApplyJvmTraitWithCACert(t *testing.T) { assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, "-Djavax.net.ssl.trustStore=/etc/camel/conf.d/_truststore/truststore.jks") assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, "-Djavax.net.ssl.trustStorePassword=$(TRUSTSTORE_PASSWORD)") - - // Verify TRUSTSTORE_PASSWORD env var is injected from user-provided secret - var foundEnvVar bool - for _, env := range d.Spec.Template.Spec.Containers[0].Env { - if env.Name == "TRUSTSTORE_PASSWORD" { - foundEnvVar = true - assert.NotNil(t, env.ValueFrom) - assert.NotNil(t, env.ValueFrom.SecretKeyRef) - assert.Equal(t, "my-truststore-password", env.ValueFrom.SecretKeyRef.Name) - assert.Equal(t, "password", env.ValueFrom.SecretKeyRef.Key) - break - } - } - assert.True(t, foundEnvVar, "TRUSTSTORE_PASSWORD env var should be injected") } -func TestParseSecretRef(t *testing.T) { - name, key, err := parseSecretRef("secret:my-secret") - require.NoError(t, err) - assert.Equal(t, "my-secret", name) - assert.Equal(t, "", key) +func TestValidateCACertConfig(t *testing.T) { + trait, _ := createNominalJvmTest(v1.IntegrationKitTypePlatform) - name, key, err = parseSecretRef("secret:my-secret/ca.crt") + trait.CACert = "" + err := trait.validateCACertConfig() require.NoError(t, err) - assert.Equal(t, "my-secret", name) - assert.Equal(t, "ca.crt", key) - _, _, err = parseSecretRef("configmap:my-cm") + trait.CACert = "/etc/camel/conf.d/_secrets/my-ca/ca.crt" + trait.CACertPassword = "" + err = trait.validateCACertConfig() require.Error(t, err) - assert.Contains(t, err.Error(), "must start with 'secret:'") + assert.Contains(t, err.Error(), "ca-cert-password is required") - _, _, err = parseSecretRef("secret:") - require.Error(t, err) - assert.Contains(t, err.Error(), "secret name is empty") + trait.CACertPassword = "/etc/camel/conf.d/_secrets/truststore-pass/password" + err = trait.validateCACertConfig() + require.NoError(t, err) } -func TestApplyJvmTraitWithCACertUserProvidedPassword(t *testing.T) { +func TestApplyJvmTraitWithCustomCACertMountPath(t *testing.T) { trait, environment := createNominalJvmTest(v1.IntegrationKitTypePlatform) - trait.CACert = "secret:my-ca-secret" - trait.CACertPassword = "secret:my-custom-password/mykey" + trait.CACert = "/etc/camel/conf.d/_secrets/my-ca/ca.crt" + trait.CACertPassword = "/etc/camel/conf.d/_secrets/truststore-pass/password" + trait.CACertMountPath = "/custom/truststore/path" d := appsv1.Deployment{ Spec: appsv1.DeploymentSpec{ @@ -843,26 +828,6 @@ func TestApplyJvmTraitWithCACertUserProvidedPassword(t *testing.T) { err = trait.Apply(environment) require.NoError(t, err) + assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, "-Djavax.net.ssl.trustStore=/custom/truststore/path/truststore.jks") assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, "-Djavax.net.ssl.trustStorePassword=$(TRUSTSTORE_PASSWORD)") - - var foundEnvVar bool - for _, env := range d.Spec.Template.Spec.Containers[0].Env { - if env.Name == "TRUSTSTORE_PASSWORD" { - foundEnvVar = true - assert.NotNil(t, env.ValueFrom) - assert.NotNil(t, env.ValueFrom.SecretKeyRef) - assert.Equal(t, "my-custom-password", env.ValueFrom.SecretKeyRef.Name) - assert.Equal(t, "mykey", env.ValueFrom.SecretKeyRef.Key) - break - } - } - assert.True(t, foundEnvVar, "TRUSTSTORE_PASSWORD env var should be injected") - - var foundAutoSecret bool - environment.Resources.VisitSecret(func(secret *corev1.Secret) { - if secret.Name == "my-it-truststore-password" { - foundAutoSecret = true - } - }) - assert.False(t, foundAutoSecret, "Auto-generated password secret should NOT be created when user provides one") } diff --git a/pkg/trait/mount.go b/pkg/trait/mount.go index 56403cbf1..3e25bad0f 100644 --- a/pkg/trait/mount.go +++ b/pkg/trait/mount.go @@ -190,7 +190,6 @@ func (t *mountTrait) configureVolumesAndMounts( } // Mount the agent volume if any agent exists trait := e.Catalog.GetTrait(jvmTraitID) - //nolint:nestif if trait != nil { jvm, ok := trait.(*jvmTrait) if ok && jvm.hasJavaAgents() { @@ -204,25 +203,11 @@ func (t *mountTrait) configureVolumesAndMounts( (*icnts)[i].VolumeMounts = append((*icnts)[i].VolumeMounts, *volumeMount) } } - // Mount CA cert volumes if configured + + // Mount CA cert truststore volume if configured if ok && jvm.hasCACert() { - secretName, _, err := parseSecretRef(jvm.CACert) - if err != nil { - return err - } mountPath := jvm.getCACertMountPath() - // Secret volume for CA cert - secretVolume := corev1.Volume{ - Name: caCertSecretVolumeName, - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: secretName, - }, - }, - } - *vols = append(*vols, secretVolume) - // EmptyDir volume for truststore output trustStoreVolume := corev1.Volume{ Name: caCertVolumeName, @@ -239,14 +224,9 @@ func (t *mountTrait) configureVolumesAndMounts( ReadOnly: true, }) - // Mount volumes to init containers for truststore generation + // Mount truststore volume to init containers for i := range *icnts { (*icnts)[i].VolumeMounts = append((*icnts)[i].VolumeMounts, - corev1.VolumeMount{ - Name: caCertSecretVolumeName, - MountPath: "/etc/secrets/cacert", - ReadOnly: true, - }, corev1.VolumeMount{ Name: caCertVolumeName, MountPath: mountPath, diff --git a/pkg/trait/mount_test.go b/pkg/trait/mount_test.go index afd675b36..9817fce3b 100644 --- a/pkg/trait/mount_test.go +++ b/pkg/trait/mount_test.go @@ -729,8 +729,8 @@ func TestCACertVolume(t *testing.T) { environment.Integration.Spec.Traits.Mount = &traitv1.MountTrait{} environment.Integration.Spec.Traits.JVM = &traitv1.JVMTrait{ - CACert: "secret:my-ca-secret", - CACertPassword: "secret:my-ca-password", + CACert: "/etc/camel/conf.d/_secrets/my-ca/ca.crt", + CACertPassword: "/etc/camel/conf.d/_secrets/truststore-pass/password", } environment.Platform.ResyncStatusFullConfig() conditions, traits, err := traitCatalog.apply(environment) @@ -747,22 +747,10 @@ func TestCACertVolume(t *testing.T) { assert.NotNil(t, deployment) spec := deployment.Spec.Template.Spec - // Should have: 2 base volumes + secret volume + emptyDir volume = 4 - assert.Len(t, spec.Volumes, 4) - - // Check secret volume exists - var secretVolume *corev1.Volume - for _, v := range spec.Volumes { - if v.Name == caCertSecretVolumeName { - secretVolume = &v - break - } - } - assert.NotNil(t, secretVolume, "Expected secret volume for CA cert") - assert.NotNil(t, secretVolume.Secret) - assert.Equal(t, "my-ca-secret", secretVolume.Secret.SecretName) + // Should have: 2 base volumes + emptyDir volume for truststore = 3 + assert.Len(t, spec.Volumes, 3) - // Check emptyDir volume exists + // Check emptyDir volume exists for truststore var emptyDirVolume *corev1.Volume for _, v := range spec.Volumes { if v.Name == caCertVolumeName {
