What is the bug?
When configuring the OpenSearch Operator with http TLS enabled, generate: true, and a specific caSecret, the operator incorrectly configures the plugins.security.ssl.http.pemtrustedcas_filepath to point to a non-existent directory tls-http-ca/ca.crt.
When generate is set to true, the operator generates a certificate signed by the provided CA and stores it in a new secret (e.g., cluster-name-http-cert). This generated secret contains ca.crt, tls.crt, and tls.key and is mounted at /usr/share/opensearch/config/tls-http.
generated secret:
volumeMounts:
But, it looks like an operator skips mounting CA cert as a separate folder, because of generate: true
https://github.com/opensearch-project/opensearch-k8s-operator/blob/main/opensearch-operator/pkg/reconcilers/tls.go#L619
if tlsConfig.Generate {
...
}
else {
...
// Implement new mounting logic based on CaSecret.Name configuration
switch name := tlsConfig.CaSecret.Name; name {
case "":
// If CaSecret.Name is empty, mount Secret.Name as a directory
mountFolder("http", "certs", tlsConfig.Secret.Name, r.reconcilerContext)
case tlsConfig.Secret.Name:
// If CaSecret.Name is same as Secret.Name, mount only Secret.Name as a directory
mountFolder("http", "certs", tlsConfig.Secret.Name, r.reconcilerContext)
default:
// If CaSecret.Name is different from Secret.Name, mount both secrets as directories
// Mount Secret.Name as tls-http/
mountFolder("http", "certs", tlsConfig.Secret.Name, r.reconcilerContext)
// Mount CaSecret.Name as tls-http-ca/
mountFolder("http", "ca", tlsConfig.CaSecret.Name, r.reconcilerContext)
}
and then where it uses it as tls-http-ca/ca.crt:
https://github.com/opensearch-project/opensearch-k8s-operator/blob/main/opensearch-operator/pkg/reconcilers/tls.go#L724
if tlsConfig.CaSecret.Name == "" || tlsConfig.CaSecret.Name == tlsConfig.Secret.Name {
// Single secret mounted as directory
r.reconcilerContext.AddConfig("plugins.security.ssl.http.pemcert_filepath", fmt.Sprintf("tls-http/%s", corev1.TLSCertKey))
r.reconcilerContext.AddConfig("plugins.security.ssl.http.pemkey_filepath", fmt.Sprintf("tls-http/%s", corev1.TLSPrivateKeyKey))
r.reconcilerContext.AddConfig("plugins.security.ssl.http.pemtrustedcas_filepath", fmt.Sprintf("tls-http/%s", CaCertKey))
} else {
// Separate secrets mounted as directories
r.reconcilerContext.AddConfig("plugins.security.ssl.http.pemcert_filepath", fmt.Sprintf("tls-http/%s", corev1.TLSCertKey))
r.reconcilerContext.AddConfig("plugins.security.ssl.http.pemkey_filepath", fmt.Sprintf("tls-http/%s", corev1.TLSPrivateKeyKey))
r.reconcilerContext.AddConfig("plugins.security.ssl.http.pemtrustedcas_filepath", fmt.Sprintf("tls-http-ca/%s", CaCertKey))
}
How can one reproduce the bug?
Deploy an OpenSearchCluster with the following TLS configuration:
tls:
http:
enabled: true
generate: true
caSecret:
name: opensearch-ca # Specify custom CA
The OpenSearch Pods fail to start with the following error:
java.lang.IllegalStateException: failed to load plugin class [org.opensearch.security.OpenSearchSecurityPlugin]
Likely root cause: OpenSearchException[Unable to read the file tls-http-ca/ca.crt. Please make sure this files exists and is readable regarding to permissions]
What is the expected behavior?
probably it makes sense to mount and use ca.crt from the generated secret in case genanrate:true and caSecret is not null. In this case line https://github.com/opensearch-project/opensearch-k8s-operator/blob/main/opensearch-operator/pkg/reconcilers/tls.go#L715 just needs to be changed to:
if tlsConfig.Generate || tlsConfig.CaSecret.Name == "" || tlsConfig.CaSecret.Name == tlsConfig.Secret.Name {
What is the bug?
When configuring the OpenSearch Operator with http TLS enabled,
generate: true, and a specificcaSecret, the operator incorrectly configures the plugins.security.ssl.http.pemtrustedcas_filepath to point to a non-existent directory tls-http-ca/ca.crt.When generate is set to true, the operator generates a certificate signed by the provided CA and stores it in a new secret (e.g., cluster-name-http-cert). This generated secret contains ca.crt, tls.crt, and tls.key and is mounted at /usr/share/opensearch/config/tls-http.
generated secret:
volumeMounts:
But, it looks like an operator skips mounting CA cert as a separate folder, because of
generate: truehttps://github.com/opensearch-project/opensearch-k8s-operator/blob/main/opensearch-operator/pkg/reconcilers/tls.go#L619
and then where it uses it as tls-http-ca/ca.crt:
https://github.com/opensearch-project/opensearch-k8s-operator/blob/main/opensearch-operator/pkg/reconcilers/tls.go#L724
How can one reproduce the bug?
Deploy an OpenSearchCluster with the following TLS configuration:
The OpenSearch Pods fail to start with the following error:
What is the expected behavior?
probably it makes sense to mount and use ca.crt from the generated secret in case
genanrate:trueandcaSecretis not null. In this case line https://github.com/opensearch-project/opensearch-k8s-operator/blob/main/opensearch-operator/pkg/reconcilers/tls.go#L715 just needs to be changed to: