diff --git a/controllers/solrcloud_controller_tls_test.go b/controllers/solrcloud_controller_tls_test.go index 6dff3d70..374f28f7 100644 --- a/controllers/solrcloud_controller_tls_test.go +++ b/controllers/solrcloud_controller_tls_test.go @@ -22,6 +22,8 @@ import ( "crypto/md5" b64 "encoding/base64" "fmt" + "strings" + solrv1beta1 "github.com/apache/solr-operator/api/v1beta1" "github.com/apache/solr-operator/controllers/util" . "github.com/onsi/ginkgo/v2" @@ -31,7 +33,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/client" - "strings" ) var _ = FDescribe("SolrCloud controller - TLS", func() { @@ -522,7 +523,7 @@ func expectTLSConfigOnPodTemplateWithGomega(g Gomega, solrCloud *solrv1beta1.Sol break } } - expCmd := "openssl pkcs12 -export -in /var/solr/tls/tls.crt -in /var/solr/tls/ca.crt -inkey /var/solr/tls/tls.key -out /var/solr/tls/pkcs12/keystore.p12 -passout pass:${SOLR_SSL_KEY_STORE_PASSWORD}" + expCmd := "OPTIONAL_CACRT=\"$(test -e /var/solr/tls/ca.crt && echo ' -certfile /var/solr/tls/ca.crt')\"; openssl pkcs12 -export -in /var/solr/tls/tls.crt $OPTIONAL_CACRT -inkey /var/solr/tls/tls.key -out /var/solr/tls/pkcs12/keystore.p12 -passout pass:${SOLR_SSL_KEY_STORE_PASSWORD}" g.Expect(expInitContainer).To(Not(BeNil()), "Didn't find the gen-pkcs12-keystore InitContainer in the sts!") g.Expect(expInitContainer.Command[2]).To(Equal(expCmd), "Wrong TLS initContainer command") } diff --git a/controllers/util/solr_tls_util.go b/controllers/util/solr_tls_util.go index 676311b1..85287577 100644 --- a/controllers/util/solr_tls_util.go +++ b/controllers/util/solr_tls_util.go @@ -21,13 +21,14 @@ import ( "context" "crypto/md5" "fmt" + "strconv" + "strings" + solr "github.com/apache/solr-operator/api/v1beta1" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - "strconv" - "strings" ) const ( @@ -707,8 +708,11 @@ func (tls *TLSConfig) generatePkcs12InitContainer(imageName string, imagePullPol }, } - cmd := "openssl pkcs12 -export -in " + DefaultKeyStorePath + "/" + TLSCertKey + " -in " + DefaultKeyStorePath + - "/ca.crt -inkey " + DefaultKeyStorePath + "/tls.key -out " + DefaultKeyStorePath + + caCrtFileName := DefaultKeyStorePath + "/ca.crt" + + cmd := "OPTIONAL_CACRT=\"$(test -e " + caCrtFileName + " && echo ' -certfile " + caCrtFileName + "')\"; " + + "openssl pkcs12 -export -in " + DefaultKeyStorePath + "/" + TLSCertKey + " $OPTIONAL_CACRT " + + "-inkey " + DefaultKeyStorePath + "/tls.key -out " + DefaultKeyStorePath + "/pkcs12/" + DefaultPkcs12KeystoreFile + " -passout pass:${SOLR_SSL_KEY_STORE_PASSWORD}" return corev1.Container{ diff --git a/helm/solr-operator/Chart.yaml b/helm/solr-operator/Chart.yaml index 5a954c28..4f274146 100644 --- a/helm/solr-operator/Chart.yaml +++ b/helm/solr-operator/Chart.yaml @@ -54,6 +54,13 @@ annotations: # Add change log for a single release here. # Allowed syntax is described at: https://artifacthub.io/docs/topics/annotations/helm/#example artifacthub.io/changes: | + - kind: fixed + description: gen-pkcs12-keystore init container fails if the tls secret contains no ca.crt + links: + - name: Github Issue + url: https://github.com/apache/solr-operator/issues/684 + - name: Github PR + url: https://github.com/apache/solr-operator/pull/685 - kind: changed description: SolrClouds now support auto-readOnlyRootFilesystem setting. links: @@ -61,6 +68,7 @@ annotations: url: https://github.com/apache/solr-operator/issues/624 - name: Github PR url: https://github.com/apache/solr-operator/pull/648 + - kind: fixed description: Avoid reset of security.json if get request fails links: - name: Github Issue diff --git a/tests/e2e/prometheus_exporter_tls_test.go b/tests/e2e/prometheus_exporter_tls_test.go index a027ffbb..f6fa2299 100644 --- a/tests/e2e/prometheus_exporter_tls_test.go +++ b/tests/e2e/prometheus_exporter_tls_test.go @@ -19,6 +19,7 @@ package e2e import ( "context" + solrv1beta1 "github.com/apache/solr-operator/api/v1beta1" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -44,7 +45,7 @@ var _ = FDescribe("E2E - Prometheus Exporter - TLS ", Ordered, func() { */ BeforeAll(func(ctx context.Context) { installSolrIssuer(ctx, testNamespace()) - solrCloud = generateBaseSolrCloudWithSecretTLS(ctx, 2, true) + solrCloud = generateBaseSolrCloudWithSecretTLS(ctx, 2, true, true) solrCloud.Spec.SolrTLS.CheckPeerName = true diff --git a/tests/e2e/solrcloud_tls_test.go b/tests/e2e/solrcloud_tls_test.go index 30b05f2e..d1622255 100644 --- a/tests/e2e/solrcloud_tls_test.go +++ b/tests/e2e/solrcloud_tls_test.go @@ -19,6 +19,7 @@ package e2e import ( "context" + solrv1beta1 "github.com/apache/solr-operator/api/v1beta1" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -59,7 +60,7 @@ var _ = FDescribe("E2E - SolrCloud - TLS - Secrets", func() { FContext("No Client TLS", func() { BeforeEach(func(ctx context.Context) { - solrCloud = generateBaseSolrCloudWithSecretTLS(ctx, 2, false) + solrCloud = generateBaseSolrCloudWithSecretTLS(ctx, 2, false, true) //solrCloud.Spec.SolrOpts = "-Djavax.net.debug=SSL,keymanager,trustmanager,ssl:handshake" }) @@ -70,7 +71,21 @@ var _ = FDescribe("E2E - SolrCloud - TLS - Secrets", func() { FContext("No Client TLS - Just a Keystore", func() { BeforeEach(func(ctx context.Context) { - solrCloud = generateBaseSolrCloudWithSecretTLS(ctx, 2, false) + solrCloud = generateBaseSolrCloudWithSecretTLS(ctx, 2, false, true) + + solrCloud.Spec.SolrTLS.TrustStoreSecret = nil + solrCloud.Spec.SolrTLS.TrustStorePasswordSecret = nil + + //solrCloud.Spec.SolrOpts = "-Djavax.net.debug=SSL,keymanager,trustmanager,ssl:handshake" + }) + + FIt("Can run", func() {}) + }) + + FContext("No Client TLS - gen-pkcs12-keystore", func() { + + BeforeEach(func(ctx context.Context) { + solrCloud = generateBaseSolrCloudWithSecretTLS(ctx, 2, false, false) solrCloud.Spec.SolrTLS.TrustStoreSecret = nil solrCloud.Spec.SolrTLS.TrustStorePasswordSecret = nil @@ -84,7 +99,7 @@ var _ = FDescribe("E2E - SolrCloud - TLS - Secrets", func() { FContext("No Client TLS - CheckPeerName", func() { BeforeEach(func(ctx context.Context) { - solrCloud = generateBaseSolrCloudWithSecretTLS(ctx, 2, false) + solrCloud = generateBaseSolrCloudWithSecretTLS(ctx, 2, false, true) solrCloud.Spec.SolrTLS.CheckPeerName = true @@ -115,7 +130,7 @@ var _ = FDescribe("E2E - SolrCloud - TLS - Secrets", func() { FContext("With Client TLS - VerifyClientHostname", func() { BeforeEach(func(ctx context.Context) { - solrCloud = generateBaseSolrCloudWithSecretTLS(ctx, 2, true) + solrCloud = generateBaseSolrCloudWithSecretTLS(ctx, 2, true, true) solrCloud.Spec.SolrTLS.VerifyClientHostname = true @@ -139,7 +154,7 @@ var _ = FDescribe("E2E - SolrCloud - TLS - Secrets", func() { FContext("With Client TLS - CheckPeerName", func() { BeforeEach(func(ctx context.Context) { - solrCloud = generateBaseSolrCloudWithSecretTLS(ctx, 2, true) + solrCloud = generateBaseSolrCloudWithSecretTLS(ctx, 2, true, true) solrCloud.Spec.SolrTLS.CheckPeerName = true @@ -164,7 +179,7 @@ var _ = FDescribe("E2E - SolrCloud - TLS - Secrets", func() { FContext("With Client TLS - Client Auth Need", func() { BeforeEach(func(ctx context.Context) { - solrCloud = generateBaseSolrCloudWithSecretTLS(ctx, 2, true) + solrCloud = generateBaseSolrCloudWithSecretTLS(ctx, 2, true, true) solrCloud.Spec.SolrTLS.ClientAuth = solrv1beta1.Need @@ -177,7 +192,7 @@ var _ = FDescribe("E2E - SolrCloud - TLS - Secrets", func() { FContext("With Client TLS - Client Auth Want", func() { BeforeEach(func(ctx context.Context) { - solrCloud = generateBaseSolrCloudWithSecretTLS(ctx, 2, true) + solrCloud = generateBaseSolrCloudWithSecretTLS(ctx, 2, true, true) solrCloud.Spec.SolrTLS.ClientAuth = solrv1beta1.Want diff --git a/tests/e2e/test_utils_test.go b/tests/e2e/test_utils_test.go index c3e693cf..f287250c 100644 --- a/tests/e2e/test_utils_test.go +++ b/tests/e2e/test_utils_test.go @@ -23,6 +23,12 @@ import ( "encoding/json" "errors" "fmt" + "io" + "os" + "strconv" + "strings" + "time" + solrv1beta1 "github.com/apache/solr-operator/api/v1beta1" "github.com/apache/solr-operator/controllers/util" "github.com/apache/solr-operator/controllers/util/solr_api" @@ -34,7 +40,6 @@ import ( "helm.sh/helm/v3/pkg/cli" "helm.sh/helm/v3/pkg/release" "helm.sh/helm/v3/pkg/storage/driver" - "io" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -43,11 +48,7 @@ import ( "k8s.io/apimachinery/pkg/util/rand" "k8s.io/client-go/tools/remotecommand" "k8s.io/utils/pointer" - "os" "sigs.k8s.io/controller-runtime/pkg/client" - "strconv" - "strings" - "time" ) const ( diff --git a/tests/e2e/utils_tls_test.go b/tests/e2e/utils_tls_test.go index b8efcfad..5089bdf6 100644 --- a/tests/e2e/utils_tls_test.go +++ b/tests/e2e/utils_tls_test.go @@ -19,6 +19,7 @@ package e2e import ( "context" + solrv1beta1 "github.com/apache/solr-operator/api/v1beta1" certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" certmanagermetav1 "github.com/cert-manager/cert-manager/pkg/apis/meta/v1" @@ -39,10 +40,10 @@ const ( clientAuthSecret = "client-auth" ) -func generateBaseSolrCloudWithSecretTLS(ctx context.Context, replicas int, includeClientTLS bool) (solrCloud *solrv1beta1.SolrCloud) { +func generateBaseSolrCloudWithSecretTLS(ctx context.Context, replicas int, includeClientTLS bool, createKeyStore bool) (solrCloud *solrv1beta1.SolrCloud) { solrCloud = generateBaseSolrCloud(replicas) - solrCertSecret, tlsPasswordSecret, clientCertSecret, clientTlsPasswordSecret := generateSolrCert(ctx, solrCloud, includeClientTLS) + solrCertSecret, tlsPasswordSecret, clientCertSecret, clientTlsPasswordSecret := generateSolrCert(ctx, solrCloud, includeClientTLS, createKeyStore) solrCloud.Spec.SolrTLS = &solrv1beta1.SolrTLSOptions{ PKCS12Secret: &corev1.SecretKeySelector{ @@ -303,7 +304,7 @@ func installSolrIssuer(ctx context.Context, namespace string) { expectSecret(ctx, clusterCA, secretName) } -func generateSolrCert(ctx context.Context, solrCloud *solrv1beta1.SolrCloud, includeClientTLS bool) (certSecretName string, tlsPasswordSecretName string, clientTLSCertSecretName string, clientTLSPasswordSecretName string) { +func generateSolrCert(ctx context.Context, solrCloud *solrv1beta1.SolrCloud, includeClientTLS bool, createKeyStore bool) (certSecretName string, tlsPasswordSecretName string, clientTLSCertSecretName string, clientTLSPasswordSecretName string) { // First create a secret to use as a password for the keystore/truststore tlsPasswordSecret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -338,7 +339,7 @@ func generateSolrCert(ctx context.Context, solrCloud *solrv1beta1.SolrCloud, inc SecretName: certSecretName, Keystores: &certmanagerv1.CertificateKeystores{ PKCS12: &certmanagerv1.PKCS12Keystore{ - Create: true, + Create: createKeyStore, PasswordSecretRef: certmanagermetav1.SecretKeySelector{ LocalObjectReference: certmanagermetav1.LocalObjectReference{ Name: tlsPasswordSecret.Name,