Skip to content

Commit c2ef248

Browse files
pkalsi97squakez
authored andcommitted
fix(jvm): simplify CA certificate add process by removing per-cert PasswordPath and cleanup tests
1 parent df0d06d commit c2ef248

File tree

14 files changed

+571
-219
lines changed

14 files changed

+571
-219
lines changed

docs/modules/ROOT/partials/apis/camel-k-crds.adoc

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6666,7 +6666,7 @@ The list of manifest platforms to use to build a container image (default `linux
66666666
66676667
* <<#_camel_apache_org_v1_trait_JVMTrait, JVMTrait>>
66686668
6669-
CACertConfig associates a CA certificate with its password file.
6669+
CACertConfig specifies a CA certificate to import into the truststore.
66706670
66716671
[cols="2,2a",options="header"]
66726672
|===
@@ -6680,13 +6680,6 @@ string
66806680
66816681
Path to the PEM-encoded CA certificate file to import.
66826682
6683-
|`passwordPath` +
6684-
string
6685-
|
6686-
6687-
6688-
Path to a file containing the password for importing this certificate.
6689-
66906683
66916684
|===
66926685
@@ -7912,6 +7905,13 @@ A list of CA certificates to import into the truststore. Certificates must be mo
79127905
79137906
Optional base truststore to use as the starting point for adding certificates.
79147907
7908+
|`truststorePasswordPath` +
7909+
string
7910+
|
7911+
7912+
7913+
Path to a file containing the password for the generated truststore. Required when using ca-certificates without base-truststore.
7914+
79157915
|`caCertMountPath` +
79167916
string
79177917
|

docs/modules/traits/pages/jvm.adoc

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ Deprecated: no longer in use.
7171
| github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait.BaseTruststore
7272
| Optional base truststore to use as the starting point for adding certificates.
7373

74+
| jvm.truststore-password-path
75+
| string
76+
| Path to a file containing the password for the generated truststore. Required when using ca-certificates without base-truststore.
77+
7478
| jvm.ca-cert-mount-path
7579
| string
7680
| The path where the generated truststore will be mounted (default `/etc/camel/conf.d/_truststore`).
@@ -118,7 +122,9 @@ $ kamel run --resource configmap:my-dep -t jvm.classpath=/etc/camel/resources/my
118122

119123
== Trusting Custom CA Certificates
120124

121-
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.
125+
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-certificates` option to add CA certificates to the JVM's truststore.
126+
127+
=== Single Certificate
122128

123129
First, create Kubernetes Secrets containing the CA certificate and truststore password:
124130

@@ -135,25 +141,66 @@ Then mount the secrets using the mount trait and reference the file paths:
135141
$ kamel run MyRoute.java \
136142
-t mount.configs=secret:my-private-ca \
137143
-t mount.configs=secret:my-truststore-pwd \
138-
-t jvm.ca-cert=/etc/camel/conf.d/_secrets/my-private-ca/ca.crt \
139-
-t jvm.ca-cert-password=/etc/camel/conf.d/_secrets/my-truststore-pwd/password
144+
-t jvm.ca-certificates[0].cert-path=/etc/camel/conf.d/_secrets/my-private-ca/ca.crt \
145+
-t jvm.truststore-password-path=/etc/camel/conf.d/_secrets/my-truststore-pwd/password
140146
----
141147

142-
If your secret uses a different key name for the certificate:
148+
=== Multiple Certificates
149+
150+
You can add multiple CA certificates to the truststore:
151+
152+
[source,console]
153+
----
154+
$ kamel run MyRoute.java \
155+
-t mount.configs=secret:ca1 \
156+
-t mount.configs=secret:ca2 \
157+
-t mount.configs=secret:truststore-pwd \
158+
-t jvm.ca-certificates[0].cert-path=/etc/camel/conf.d/_secrets/ca1/ca.crt \
159+
-t jvm.ca-certificates[1].cert-path=/etc/camel/conf.d/_secrets/ca2/ca.crt \
160+
-t jvm.truststore-password-path=/etc/camel/conf.d/_secrets/truststore-pwd/password
161+
----
162+
163+
=== Using a Base Truststore (Preserving JDK Public CAs)
164+
165+
To preserve the JDK's default public CA certificates while adding your custom certificates, use the `base-truststore` option:
143166

144167
[source,console]
145168
----
146169
$ kamel run MyRoute.java \
147170
-t mount.configs=secret:my-private-ca \
148-
-t mount.configs=secret:my-truststore-pwd \
149-
-t jvm.ca-cert=/etc/camel/conf.d/_secrets/my-private-ca/custom-ca.pem \
150-
-t jvm.ca-cert-password=/etc/camel/conf.d/_secrets/my-truststore-pwd/password
171+
-t mount.configs=secret:cacerts-pwd \
172+
-t jvm.base-truststore.truststore-path=/opt/java/openjdk/lib/security/cacerts \
173+
-t jvm.base-truststore.password-path=/etc/camel/conf.d/_secrets/cacerts-pwd/password \
174+
-t jvm.ca-certificates[0].cert-path=/etc/camel/conf.d/_secrets/my-private-ca/ca.crt
151175
----
152176

177+
NOTE: When using `base-truststore`, you can optionally provide `truststore-password-path` to set a different password for the output truststore. If not provided, the base truststore password is used.
178+
179+
=== Truststore Password Resolution
180+
181+
The truststore password is determined using this priority:
182+
183+
1. `truststore-password-path` (if explicitly provided)
184+
2. `base-truststore.password-path` (if base-truststore is configured)
185+
3. Validation error (password is required when using `ca-certificates`)
186+
153187
This will automatically:
154188

155189
1. Mount the secrets to the integration container (via mount trait)
156190
2. Generate a JVM truststore using an init container
157191
3. Configure the JVM to use the generated truststore via `-Djavax.net.ssl.trustStore`
158192

159-
NOTE: The `ca-cert-password` option is **required** when using `ca-cert`. Both values must be file paths to the mounted secrets.
193+
=== Deprecated Syntax (Backward Compatible)
194+
195+
The legacy `ca-cert` and `ca-cert-password` options are still supported but deprecated:
196+
197+
[source,console]
198+
----
199+
$ kamel run MyRoute.java \
200+
-t mount.configs=secret:my-private-ca \
201+
-t mount.configs=secret:my-truststore-pwd \
202+
-t jvm.ca-cert=/etc/camel/conf.d/_secrets/my-private-ca/ca.crt \
203+
-t jvm.ca-cert-password=/etc/camel/conf.d/_secrets/my-truststore-pwd/password
204+
----
205+
206+
NOTE: We recommend migrating to the new `ca-certificates` syntax for better multi-certificate support and explicit truststore password configuration.

e2e/common/traits/jvm_test.go

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -92,36 +92,38 @@ func TestJVMTrait(t *testing.T) {
9292
})
9393

9494
t.Run("JVM trait multiple CA certs", func(t *testing.T) {
95-
// Test the new ca-certificates field with multiple certificates, each with its own password
95+
// Test the new ca-certificates field with multiple certificates
9696
cert1Pem, err := generateSelfSignedCert()
9797
require.NoError(t, err)
9898
cert2Pem, err := generateSelfSignedCert()
9999
require.NoError(t, err)
100100

101-
// Create secrets with both cert and password together
101+
// Create secrets with certificates
102102
caCert1Data := make(map[string]string)
103103
caCert1Data["ca.crt"] = string(cert1Pem)
104-
caCert1Data["password"] = "test-password-1"
105104
err = CreatePlainTextSecret(t, ctx, ns, "test-ca-cert-1", caCert1Data)
106105
require.NoError(t, err)
107106

108107
caCert2Data := make(map[string]string)
109108
caCert2Data["ca.crt"] = string(cert2Pem)
110-
caCert2Data["password"] = "test-password-2"
111109
err = CreatePlainTextSecret(t, ctx, ns, "test-ca-cert-2", caCert2Data)
112110
require.NoError(t, err)
113111

112+
truststorePassData := make(map[string]string)
113+
truststorePassData["password"] = "truststore-password"
114+
err = CreatePlainTextSecret(t, ctx, ns, "truststore-pass-multi", truststorePassData)
115+
require.NoError(t, err)
116+
114117
name := RandomizedSuffixName("multicacert")
115118
g.Expect(KamelRun(t, ctx, ns,
116119
"./files/Java.java",
117120
"--name", name,
118121
"-t", "mount.configs=secret:test-ca-cert-1",
119122
"-t", "mount.configs=secret:test-ca-cert-2",
120-
// Using new ca-certificates field: each certificate with its own password path
123+
"-t", "mount.configs=secret:truststore-pass-multi",
121124
"-t", "jvm.ca-certificates[0].cert-path=/etc/camel/conf.d/_secrets/test-ca-cert-1/ca.crt",
122-
"-t", "jvm.ca-certificates[0].password-path=/etc/camel/conf.d/_secrets/test-ca-cert-1/password",
123125
"-t", "jvm.ca-certificates[1].cert-path=/etc/camel/conf.d/_secrets/test-ca-cert-2/ca.crt",
124-
"-t", "jvm.ca-certificates[1].password-path=/etc/camel/conf.d/_secrets/test-ca-cert-2/password",
126+
"-t", "jvm.truststore-password-path=/etc/camel/conf.d/_secrets/truststore-pass-multi/password",
125127
).Execute()).To(Succeed())
126128

127129
g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong*2).Should(Equal(corev1.PodRunning))
@@ -141,10 +143,9 @@ func TestJVMTrait(t *testing.T) {
141143
certPem, err := generateSelfSignedCert()
142144
require.NoError(t, err)
143145

144-
// Create secret with cert and password
146+
// Create secret with certificate
145147
caCertData := make(map[string]string)
146148
caCertData["ca.crt"] = string(certPem)
147-
caCertData["password"] = "test-password-456"
148149
err = CreatePlainTextSecret(t, ctx, ns, "test-ca-sys", caCertData)
149150
require.NoError(t, err)
150151

@@ -160,11 +161,9 @@ func TestJVMTrait(t *testing.T) {
160161
"--name", name,
161162
"-t", "mount.configs=secret:test-ca-sys",
162163
"-t", "mount.configs=secret:base-ts-password",
163-
// Using new base-truststore field with JDK cacerts as base
164164
"-t", "jvm.base-truststore.truststore-path=/opt/java/openjdk/lib/security/cacerts",
165165
"-t", "jvm.base-truststore.password-path=/etc/camel/conf.d/_secrets/base-ts-password/password",
166166
"-t", "jvm.ca-certificates[0].cert-path=/etc/camel/conf.d/_secrets/test-ca-sys/ca.crt",
167-
"-t", "jvm.ca-certificates[0].password-path=/etc/camel/conf.d/_secrets/test-ca-sys/password",
168167
).Execute()).To(Succeed())
169168

170169
g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
@@ -184,21 +183,25 @@ func TestJVMTrait(t *testing.T) {
184183
certPem, err := generateSelfSignedCert()
185184
require.NoError(t, err)
186185

187-
// Create secret with both cert and password
186+
// Create secret with certificate
188187
caCertData := make(map[string]string)
189188
caCertData["ca.crt"] = string(certPem)
190-
caCertData["password"] = "changeit"
191189
err = CreatePlainTextSecret(t, ctx, ns, "test-ca-single", caCertData)
192190
require.NoError(t, err)
193191

192+
truststorePassData := make(map[string]string)
193+
truststorePassData["password"] = "truststore-password"
194+
err = CreatePlainTextSecret(t, ctx, ns, "truststore-pass-single", truststorePassData)
195+
require.NoError(t, err)
196+
194197
name := RandomizedSuffixName("singlecert")
195198
g.Expect(KamelRun(t, ctx, ns,
196199
"./files/Java.java",
197200
"--name", name,
198201
"-t", "mount.configs=secret:test-ca-single",
199-
// Using new ca-certificates field with explicit password
202+
"-t", "mount.configs=secret:truststore-pass-single",
200203
"-t", "jvm.ca-certificates[0].cert-path=/etc/camel/conf.d/_secrets/test-ca-single/ca.crt",
201-
"-t", "jvm.ca-certificates[0].password-path=/etc/camel/conf.d/_secrets/test-ca-single/password",
204+
"-t", "jvm.truststore-password-path=/etc/camel/conf.d/_secrets/truststore-pass-single/password",
202205
).Execute()).To(Succeed())
203206

204207
g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))

0 commit comments

Comments
 (0)