This is an automated email from the ASF dual-hosted git repository.
thelabdude pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr-operator.git
The following commit(s) were added to refs/heads/main by this push:
new 4649654 Refactor TLS setup code into a separate file and consolidate
logic between the StatefulSet and exporter Deployment (#309)
4649654 is described below
commit 46496541fb04bc11dd6db3eb3adbe6119cc64e11
Author: Timothy Potter <[email protected]>
AuthorDate: Wed Aug 18 14:53:36 2021 -0600
Refactor TLS setup code into a separate file and consolidate logic between
the StatefulSet and exporter Deployment (#309)
---
controllers/controller_utils_test.go | 10 +-
controllers/solrcloud_controller.go | 97 +++--
controllers/solrcloud_controller_tls_test.go | 2 -
controllers/solrprometheusexporter_controller.go | 100 +++--
controllers/util/prometheus_exporter_util.go | 101 +----
controllers/util/solr_tls_util.go | 525 +++++++++++++++++++++++
controllers/util/solr_util.go | 345 +--------------
7 files changed, 657 insertions(+), 523 deletions(-)
diff --git a/controllers/controller_utils_test.go
b/controllers/controller_utils_test.go
index c32a5a2..8a85aa5 100644
--- a/controllers/controller_utils_test.go
+++ b/controllers/controller_utils_test.go
@@ -190,14 +190,6 @@ func verifyUserSuppliedTLSConfig(t *testing.T, tls
*solr.SolrTLSOptions, expecte
assert.Equal(t, expectedKeystorePasswordSecretKey,
tls.KeyStorePasswordSecret.Key)
assert.Equal(t, expectedTlsSecretName, tls.PKCS12Secret.Name)
assert.Equal(t, "keystore.p12", tls.PKCS12Secret.Key)
-
- // is there a separate truststore?
- expectedTrustStorePath := ""
- if tls.TrustStoreSecret != nil {
- expectedTrustStorePath = util.DefaultTrustStorePath + "/" +
tls.TrustStoreSecret.Key
- }
-
- expectTLSEnvVars(t, util.TLSEnvVars(tls, needsPkcs12InitContainer),
expectedKeystorePasswordSecretName, expectedKeystorePasswordSecretKey,
needsPkcs12InitContainer, expectedTrustStorePath)
}
func createTLSOptions(tlsSecretName string, keystorePassKey string,
restartOnTLSSecretUpdate bool) *solr.SolrTLSOptions {
@@ -376,7 +368,7 @@ func expectMountedTLSDirEnvVars(t *testing.T, envVars
[]corev1.EnvVar) {
envVars = filterVarsByName(envVars, func(n string) bool {
return strings.HasPrefix(n, "SOLR_SSL_")
})
- assert.True(t, len(envVars) == 7)
+ assert.Equal(t, 7, len(envVars), "expected SOLR_SSL related env vars
not found")
expectedKeystorePath := "/mounted-tls-dir/keystore.p12"
expectedTruststorePath := "/mounted-tls-dir/truststore.p12"
diff --git a/controllers/solrcloud_controller.go
b/controllers/solrcloud_controller.go
index bfd3c3a..4025330 100644
--- a/controllers/solrcloud_controller.go
+++ b/controllers/solrcloud_controller.go
@@ -215,7 +215,7 @@ func (r *SolrCloudReconciler) Reconcile(req ctrl.Request)
(ctrl.Result, error) {
// if there's a user-provided config, it must have one
of the expected keys
if !hasLogXml && !hasSolrXml {
// TODO: Create event for the CRD.
- return requeueOrNot, fmt.Errorf("User provided
ConfigMap %s must have one of 'solr.xml' and/or 'log4j2.xml'",
+ return requeueOrNot, fmt.Errorf("user provided
ConfigMap %s must have one of 'solr.xml' and/or 'log4j2.xml'",
providedConfigMapName)
}
@@ -223,7 +223,7 @@ func (r *SolrCloudReconciler) Reconcile(req ctrl.Request)
(ctrl.Result, error) {
// make sure the user-provided solr.xml is valid
if !strings.Contains(solrXml, "${hostPort:") {
return requeueOrNot,
- fmt.Errorf("Custom solr.xml in
ConfigMap %s must contain a placeholder for the 'hostPort' variable, such as
<int name=\"hostPort\">${hostPort:80}</int>",
+ fmt.Errorf("custom solr.xml in
ConfigMap %s must contain a placeholder for the 'hostPort' variable, such as
<int name=\"hostPort\">${hostPort:80}</int>",
providedConfigMapName)
}
// stored in the pod spec annotations on the
statefulset so that we get a restart when solr.xml changes
@@ -240,7 +240,7 @@ func (r *SolrCloudReconciler) Reconcile(req ctrl.Request)
(ctrl.Result, error) {
}
} else {
- return requeueOrNot, fmt.Errorf("Provided ConfigMap %s
has no data", providedConfigMapName)
+ return requeueOrNot, fmt.Errorf("provided ConfigMap %s
has no data", providedConfigMapName)
}
}
@@ -281,7 +281,7 @@ func (r *SolrCloudReconciler) Reconcile(req ctrl.Request)
(ctrl.Result, error) {
sec := instance.Spec.SolrSecurity
if sec.AuthenticationType != solr.Basic {
- return requeueOrNot, fmt.Errorf("%s not supported! Only
'Basic' authentication is supported by the Solr operator.",
+ return requeueOrNot, fmt.Errorf("%s not supported! Only
'Basic' authentication is supported by the Solr operator",
instance.Spec.SolrSecurity.AuthenticationType)
}
@@ -364,42 +364,12 @@ func (r *SolrCloudReconciler) Reconcile(req ctrl.Request)
(ctrl.Result, error) {
blockReconciliationOfStatefulSet = true
}
- tlsCertMd5 := ""
- needsPkcs12InitContainer := false // flag if the StatefulSet needs an
additional initCont to create PKCS12 keystore
// don't start reconciling TLS until we have ZK connectivity, avoids
TLS code having to check for ZK
- if !blockReconciliationOfStatefulSet && instance.Spec.SolrTLS != nil &&
instance.Spec.SolrTLS.PKCS12Secret != nil {
- foundTLSSecret, err :=
r.verifyTLSSecretConfig(instance.Spec.SolrTLS.PKCS12Secret.Name,
instance.Namespace, instance.Spec.SolrTLS.KeyStorePasswordSecret)
+ var tls *util.TLSConfig = nil
+ if !blockReconciliationOfStatefulSet && instance.Spec.SolrTLS != nil {
+ tls, err = r.reconcileTLSConfig(instance)
if err != nil {
return requeueOrNot, err
- } else {
- // We have a watch on secrets, so will get notified
when the secret changes (such as after cert renewal)
- // capture the hash of the secret and stash in an
annotation so that pods get restarted if the cert changes
- if instance.Spec.SolrTLS.RestartOnTLSSecretUpdate {
- if tlsCertBytes, ok :=
foundTLSSecret.Data[util.TLSCertKey]; ok {
- tlsCertMd5 = fmt.Sprintf("%x",
md5.Sum(tlsCertBytes))
- } else {
- return requeueOrNot, fmt.Errorf("%s key
not found in TLS secret %s, cannot watch for updates to"+
- " the cert without this data
but 'solrTLS.restartOnTLSSecretUpdate' is enabled!",
- util.TLSCertKey,
foundTLSSecret.Name)
- }
- }
-
- if _, ok :=
foundTLSSecret.Data[instance.Spec.SolrTLS.PKCS12Secret.Key]; !ok {
- // the keystore.p12 key is not in the TLS
secret, indicating we need to create it using an initContainer
- needsPkcs12InitContainer = true
- }
- }
-
- if instance.Spec.SolrTLS.TrustStoreSecret != nil {
- // verify the TrustStore secret is configured correctly
- passwordSecret :=
instance.Spec.SolrTLS.TrustStorePasswordSecret
- if passwordSecret == nil {
- passwordSecret =
instance.Spec.SolrTLS.KeyStorePasswordSecret
- }
- _, err :=
r.verifyTLSSecretConfig(instance.Spec.SolrTLS.TrustStoreSecret.Name,
instance.Namespace, passwordSecret)
- if err != nil {
- return requeueOrNot, err
- }
}
}
@@ -408,7 +378,7 @@ func (r *SolrCloudReconciler) Reconcile(req ctrl.Request)
(ctrl.Result, error) {
if !blockReconciliationOfStatefulSet {
// Generate StatefulSet
- statefulSet := util.GenerateStatefulSet(instance, &newStatus,
hostNameIpMap, reconcileConfigInfo, needsPkcs12InitContainer, tlsCertMd5)
+ statefulSet := util.GenerateStatefulSet(instance, &newStatus,
hostNameIpMap, reconcileConfigInfo, tls)
// Check if the StatefulSet already exists
statefulSetLogger := logger.WithValues("statefulSet",
statefulSet.Name)
@@ -1017,6 +987,57 @@ func (r *SolrCloudReconciler)
indexAndWatchForTLSSecret(mgr ctrl.Manager, ctrlBu
builder.WithPredicates(predicate.ResourceVersionChangedPredicate{})), nil
}
+// Ensure the TLS config is ready, such as verifying the TLS secret exists, to
enable TLS on SolrCloud pods
+func (r *SolrCloudReconciler) reconcileTLSConfig(instance *solr.SolrCloud)
(*util.TLSConfig, error) {
+ tls := &util.TLSConfig{}
+ tls.InitContainerImage = instance.Spec.BusyBoxImage
+ tls.Options = instance.Spec.SolrTLS
+
+ // Has the user configured a secret containing the TLS cert files that
we need to mount into the Solr pods?
+ if instance.Spec.SolrTLS.PKCS12Secret != nil {
+ // Ensure one or the other have been configured, but not both
+ if instance.Spec.SolrTLS.MountedServerTLSDir != nil {
+ return nil, fmt.Errorf("invalid TLS config, either
supply `solrTLS.pkcs12Secret` or `solrTLS.mountedServerTLSDir` but not both")
+ }
+
+ foundTLSSecret, err :=
r.verifyTLSSecretConfig(instance.Spec.SolrTLS.PKCS12Secret.Name,
instance.Namespace, instance.Spec.SolrTLS.KeyStorePasswordSecret)
+ if err != nil {
+ return nil, err
+ } else {
+ // We have a watch on secrets, so will get notified
when the secret changes (such as after cert renewal)
+ // capture the hash of the secret and stash in an
annotation so that pods get restarted if the cert changes
+ if instance.Spec.SolrTLS.RestartOnTLSSecretUpdate {
+ if tlsCertBytes, ok :=
foundTLSSecret.Data[util.TLSCertKey]; ok {
+ tls.CertMd5 = fmt.Sprintf("%x",
md5.Sum(tlsCertBytes))
+ } else {
+ return nil, fmt.Errorf("%s key not
found in TLS secret %s, cannot watch for updates to"+
+ " the cert without this data
but 'solrTLS.restartOnTLSSecretUpdate' is enabled",
+ util.TLSCertKey,
foundTLSSecret.Name)
+ }
+ }
+
+ if _, ok :=
foundTLSSecret.Data[instance.Spec.SolrTLS.PKCS12Secret.Key]; !ok {
+ // the keystore.p12 key is not in the TLS
secret, indicating we need to create it using an initContainer
+ tls.NeedsPkcs12InitContainer = true
+ }
+ }
+
+ if instance.Spec.SolrTLS.TrustStoreSecret != nil {
+ // verify the TrustStore secret is configured correctly
+ passwordSecret :=
instance.Spec.SolrTLS.TrustStorePasswordSecret
+ if passwordSecret == nil {
+ passwordSecret =
instance.Spec.SolrTLS.KeyStorePasswordSecret
+ }
+ _, err :=
r.verifyTLSSecretConfig(instance.Spec.SolrTLS.TrustStoreSecret.Name,
instance.Namespace, passwordSecret)
+ if err != nil {
+ return nil, err
+ }
+ }
+ } // else per-pod TLS files get mounted into a dir on the pod
dynamically using some external agent / CSI driver type mechanism
+
+ return tls, nil
+}
+
func (r *SolrCloudReconciler) verifyTLSSecretConfig(secretName string,
secretNamespace string, passwordSecret *corev1.SecretKeySelector)
(*corev1.Secret, error) {
ctx := context.TODO()
diff --git a/controllers/solrcloud_controller_tls_test.go
b/controllers/solrcloud_controller_tls_test.go
index 27fd378..a0deb25 100644
--- a/controllers/solrcloud_controller_tls_test.go
+++ b/controllers/solrcloud_controller_tls_test.go
@@ -126,7 +126,6 @@ func TestMountedTLSDir(t *testing.T) {
mountedDir := &solr.MountedTLSDirectory{}
mountedDir.Path = "/mounted-tls-dir"
instance.Spec.SolrTLS = &solr.SolrTLSOptions{MountedServerTLSDir:
mountedDir, CheckPeerName: true, ClientAuth: "Need", VerifyClientHostname: true}
- expectMountedTLSDirEnvVars(t, util.TLSEnvVars(instance.Spec.SolrTLS,
false))
verifyReconcileMountedTLSDir(t, instance)
}
@@ -136,7 +135,6 @@ func TestMountedTLSDirWithBasicAuth(t *testing.T) {
mountedDir.Path = "/mounted-tls-dir"
instance.Spec.SolrTLS = &solr.SolrTLSOptions{MountedServerTLSDir:
mountedDir, CheckPeerName: true, ClientAuth: "Need", VerifyClientHostname: true}
instance.Spec.SolrSecurity =
&solr.SolrSecurityOptions{AuthenticationType: solr.Basic} // with basic-auth too
- expectMountedTLSDirEnvVars(t, util.TLSEnvVars(instance.Spec.SolrTLS,
false))
verifyReconcileMountedTLSDir(t, instance)
}
diff --git a/controllers/solrprometheusexporter_controller.go
b/controllers/solrprometheusexporter_controller.go
index c3f4477..bf9cf07 100644
--- a/controllers/solrprometheusexporter_controller.go
+++ b/controllers/solrprometheusexporter_controller.go
@@ -176,49 +176,12 @@ func (r *SolrPrometheusExporterReconciler) Reconcile(req
ctrl.Request) (ctrl.Res
}
// Make sure the TLS config is in order
- var tlsClientOptions *util.TLSClientOptions = nil
- if prometheusExporter.Spec.SolrReference.SolrTLS != nil &&
prometheusExporter.Spec.SolrReference.SolrTLS.PKCS12Secret != nil {
- requeueOrNot := reconcile.Result{}
- ctx := context.TODO()
- foundTLSSecret := &corev1.Secret{}
- lookupErr := r.Get(ctx, types.NamespacedName{Name:
prometheusExporter.Spec.SolrReference.SolrTLS.PKCS12Secret.Name, Namespace:
prometheusExporter.Namespace}, foundTLSSecret)
- if lookupErr != nil {
- return requeueOrNot, lookupErr
- } else {
- // Make sure the secret containing the keystore
password exists as well
- keyStorePasswordSecret := &corev1.Secret{}
- err := r.Get(ctx, types.NamespacedName{Name:
prometheusExporter.Spec.SolrReference.SolrTLS.KeyStorePasswordSecret.Name,
Namespace: foundTLSSecret.Namespace}, keyStorePasswordSecret)
- if err != nil {
- return requeueOrNot, lookupErr
- }
- // we found the keystore secret, but does it have the
key we expect?
- if _, ok :=
keyStorePasswordSecret.Data[prometheusExporter.Spec.SolrReference.SolrTLS.KeyStorePasswordSecret.Key];
!ok {
- return requeueOrNot, fmt.Errorf("%s key not
found in keystore password secret %s",
-
prometheusExporter.Spec.SolrReference.SolrTLS.KeyStorePasswordSecret.Key,
keyStorePasswordSecret.Name)
- }
-
- tlsClientOptions = &util.TLSClientOptions{}
- tlsClientOptions.TLSOptions =
prometheusExporter.Spec.SolrReference.SolrTLS
-
- if _, ok :=
foundTLSSecret.Data[prometheusExporter.Spec.SolrReference.SolrTLS.PKCS12Secret.Key];
!ok {
- // the keystore.p12 key is not in the TLS
secret, indicating we need to create it using an initContainer
- tlsClientOptions.NeedsPkcs12InitContainer = true
- }
-
- // We have a watch on secrets, so will get notified
when the secret changes (such as after cert renewal)
- // capture the hash of the secret and stash in an
annotation so that pods get restarted if the cert changes
- if
prometheusExporter.Spec.SolrReference.SolrTLS.RestartOnTLSSecretUpdate {
- if tlsCertBytes, ok :=
foundTLSSecret.Data[util.TLSCertKey]; ok {
- tlsClientOptions.TLSCertMd5 =
fmt.Sprintf("%x", md5.Sum(tlsCertBytes))
- } else {
- return requeueOrNot, fmt.Errorf("%s key
not found in TLS secret %s, cannot watch for updates to the cert without this
data but 'solrTLS.restartOnTLSSecretUpdate' is enabled",
- util.TLSCertKey,
foundTLSSecret.Name)
- }
- }
+ var tls *util.TLSConfig = nil
+ if prometheusExporter.Spec.SolrReference.SolrTLS != nil {
+ tls, err = r.reconcileTLSConfig(prometheusExporter)
+ if err != nil {
+ return ctrl.Result{}, err
}
- } else if prometheusExporter.Spec.SolrReference.SolrTLS != nil &&
prometheusExporter.Spec.SolrReference.SolrTLS.MountedServerTLSDir != nil {
- tlsClientOptions = &util.TLSClientOptions{}
- tlsClientOptions.TLSOptions =
prometheusExporter.Spec.SolrReference.SolrTLS
}
basicAuthMd5 := ""
@@ -237,7 +200,7 @@ func (r *SolrPrometheusExporterReconciler) Reconcile(req
ctrl.Request) (ctrl.Res
basicAuthMd5 = fmt.Sprintf("%x", md5.Sum([]byte(creds)))
}
- deploy :=
util.GenerateSolrPrometheusExporterDeployment(prometheusExporter,
solrConnectionInfo, configXmlMd5, tlsClientOptions, basicAuthMd5)
+ deploy :=
util.GenerateSolrPrometheusExporterDeployment(prometheusExporter,
solrConnectionInfo, configXmlMd5, tls, basicAuthMd5)
ready := false
// Check if the Metrics Deployment already exists
@@ -443,3 +406,54 @@ func (r *SolrPrometheusExporterReconciler)
buildSecretWatch(secretField string,
},
builder.WithPredicates(predicate.ResourceVersionChangedPredicate{})), nil
}
+
+func (r *SolrPrometheusExporterReconciler)
reconcileTLSConfig(prometheusExporter *solrv1beta1.SolrPrometheusExporter)
(*util.TLSConfig, error) {
+ opts := prometheusExporter.Spec.SolrReference.SolrTLS
+
+ tls := &util.TLSConfig{}
+ tls.InitContainerImage = prometheusExporter.Spec.BusyBoxImage
+ tls.Options = opts
+
+ if opts.PKCS12Secret != nil {
+ // Ensure one or the other have been configured, but not both
+ if opts.MountedServerTLSDir != nil {
+ return nil, fmt.Errorf("invalid TLS config, either
supply `solrTLS.pkcs12Secret` or `solrTLS.mountedServerTLSDir` but not both")
+ }
+
+ ctx := context.TODO()
+ foundTLSSecret := &corev1.Secret{}
+ lookupErr := r.Get(ctx, types.NamespacedName{Name:
opts.PKCS12Secret.Name, Namespace: prometheusExporter.Namespace},
foundTLSSecret)
+ if lookupErr != nil {
+ return nil, lookupErr
+ } else {
+ // Make sure the secret containing the keystore
password exists as well
+ keyStorePasswordSecret := &corev1.Secret{}
+ err := r.Get(ctx, types.NamespacedName{Name:
opts.KeyStorePasswordSecret.Name, Namespace: foundTLSSecret.Namespace},
keyStorePasswordSecret)
+ if err != nil {
+ return nil, lookupErr
+ }
+ // we found the keystore secret, but does it have the
key we expect?
+ if _, ok :=
keyStorePasswordSecret.Data[opts.KeyStorePasswordSecret.Key]; !ok {
+ return nil, fmt.Errorf("%s key not found in
keystore password secret %s",
+ opts.KeyStorePasswordSecret.Key,
keyStorePasswordSecret.Name)
+ }
+
+ if _, ok := foundTLSSecret.Data[opts.PKCS12Secret.Key];
!ok {
+ // the keystore.p12 key is not in the TLS
secret, indicating we need to create it using an initContainer
+ tls.NeedsPkcs12InitContainer = true
+ }
+
+ // We have a watch on secrets, so will get notified
when the secret changes (such as after cert renewal)
+ // capture the hash of the secret and stash in an
annotation so that pods get restarted if the cert changes
+ if opts.RestartOnTLSSecretUpdate {
+ if tlsCertBytes, ok :=
foundTLSSecret.Data[util.TLSCertKey]; ok {
+ tls.CertMd5 = fmt.Sprintf("%x",
md5.Sum(tlsCertBytes))
+ } else {
+ return nil, fmt.Errorf("%s key not
found in TLS secret %s, cannot watch for updates to the cert without this data
but 'solrTLS.restartOnTLSSecretUpdate' is enabled",
+ util.TLSCertKey,
foundTLSSecret.Name)
+ }
+ }
+ }
+ }
+ return tls, nil
+}
diff --git a/controllers/util/prometheus_exporter_util.go
b/controllers/util/prometheus_exporter_util.go
index b6249f6..0b6f36a 100644
--- a/controllers/util/prometheus_exporter_util.go
+++ b/controllers/util/prometheus_exporter_util.go
@@ -18,7 +18,6 @@
package util
import (
- "fmt"
solr "github.com/apache/solr-operator/api/v1beta1"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
@@ -46,17 +45,9 @@ type SolrConnectionInfo struct {
StandaloneAddress string
}
-// Used internally to capture config needed to provided Solr client apps like
the exporter
-// with config needed to call TLS enabled Solr pods
-type TLSClientOptions struct {
- TLSOptions *solr.SolrTLSOptions
- NeedsPkcs12InitContainer bool
- TLSCertMd5 string
-}
-
// GenerateSolrPrometheusExporterDeployment returns a new appsv1.Deployment
pointer generated for the SolrCloud Prometheus Exporter instance
// solrPrometheusExporter: SolrPrometheusExporter instance
-func GenerateSolrPrometheusExporterDeployment(solrPrometheusExporter
*solr.SolrPrometheusExporter, solrConnectionInfo SolrConnectionInfo,
configXmlMd5 string, tls *TLSClientOptions, basicAuthMd5 string)
*appsv1.Deployment {
+func GenerateSolrPrometheusExporterDeployment(solrPrometheusExporter
*solr.SolrPrometheusExporter, solrConnectionInfo SolrConnectionInfo,
configXmlMd5 string, tls *TLSConfig, basicAuthMd5 string) *appsv1.Deployment {
gracePeriodTerm := int64(10)
singleReplica := int32(1)
fsGroup := int64(SolrMetricsPort)
@@ -170,51 +161,6 @@ func
GenerateSolrPrometheusExporterDeployment(solrPrometheusExporter *solr.SolrP
}
}
- var createTLSWrapperScriptInitContainer *corev1.Container
- if tls != nil {
- envVars = append(envVars, TLSEnvVars(tls.TLSOptions,
tls.NeedsPkcs12InitContainer)...)
- allJavaOpts = append(allJavaOpts,
tlsJavaOpts(tls.TLSOptions)...)
- if tls.TLSOptions.PKCS12Secret != nil {
- volumeMounts = append(volumeMounts,
tlsVolumeMounts(tls.TLSOptions, tls.NeedsPkcs12InitContainer)...)
- solrVolumes = append(solrVolumes,
tlsVolumes(tls.TLSOptions, tls.NeedsPkcs12InitContainer)...)
- } else if tls.TLSOptions.MountedServerTLSDir != nil {
- volName := "tls-wrapper-script"
- mountPath := "/usr/local/solr-exporter-tls"
- wrapperScript := mountPath +
"/launch-exporter-with-tls.sh"
-
- // the Prom exporter needs the keystore & truststore
passwords in a Java system property, but the password
- // is stored in a file when using the mounted TLS dir
approach, so we use a wrapper script around the main
- // container entry point to add these properties to
JAVA_OPTS at runtime
- solrVolumes = append(solrVolumes, corev1.Volume{Name:
volName, VolumeSource: corev1.VolumeSource{EmptyDir:
&corev1.EmptyDirVolumeSource{}}})
- volumeMounts = append(volumeMounts,
corev1.VolumeMount{Name: volName, MountPath: mountPath})
-
- /*
- Create a wrapper script like:
-
- #!/bin/bash
- ksp=$(cat
$MOUNTED_TLS_DIR/keystore-password)
- tsp=$(cat
$MOUNTED_TLS_DIR/keystore-password)
- JAVA_OPTS="${JAVA_OPTS}
-Djavax.net.ssl.keyStorePassword=${ksp}
-Djavax.net.ssl.trustStorePassword=${tsp}"
-
/opt/solr/contrib/prometheus-exporter/bin/solr-exporter $@
-
- */
- writeWrapperScript := fmt.Sprintf("cat << EOF >
%s\n#!/bin/bash\nksp=\\$(cat %s)\ntsp=\\$(cat %s)\nJAVA_OPTS=\"\\${JAVA_OPTS}
-Djavax.net.ssl.keyStorePassword=\\${ksp}
-Djavax.net.ssl.trustStorePassword=\\${tsp}\"\n%s \\$@\nEOF\nchmod +x %s",
- wrapperScript,
MountedTLSKeystorePasswordPath(tls.TLSOptions),
MountedTLSTruststorePasswordPath(tls.TLSOptions), entrypoint, wrapperScript)
-
- c := solrPrometheusExporter.BusyBoxImage()
- createTLSWrapperScriptInitContainer = &corev1.Container{
- Name: "create-tls-wrapper-script",
- Image: c.ToImageName(),
- ImagePullPolicy: c.PullPolicy,
- Command: []string{"sh", "-c",
writeWrapperScript},
- VolumeMounts: []corev1.VolumeMount{{Name:
volName, MountPath: mountPath}},
- }
-
- // update the main container entrypoint for the main
container to be our tls wrapper script
- entrypoint = wrapperScript
- }
- }
-
// basic auth enabled?
if solrPrometheusExporter.Spec.SolrReference.BasicAuthSecret != "" {
lor := corev1.LocalObjectReference{Name:
solrPrometheusExporter.Spec.SolrReference.BasicAuthSecret}
@@ -271,17 +217,6 @@ func
GenerateSolrPrometheusExporterDeployment(solrPrometheusExporter *solr.SolrP
}
}
- // if the supplied TLS secret does not have the pkcs12 keystore, use an
initContainer to create its
- if tls != nil && tls.NeedsPkcs12InitContainer {
- pkcs12InitContainer :=
generatePkcs12InitContainer(tls.TLSOptions,
- solrPrometheusExporter.Spec.Image.ToImageName(),
solrPrometheusExporter.Spec.Image.PullPolicy)
- initContainers = append(initContainers, pkcs12InitContainer)
- }
-
- if createTLSWrapperScriptInitContainer != nil {
- initContainers = append(initContainers,
*createTLSWrapperScriptInitContainer)
- }
-
// track the MD5 of the custom exporter config in the pod spec
annotations,
// so we get a rolling restart when the configMap changes
if configXmlMd5 != "" {
@@ -291,13 +226,6 @@ func
GenerateSolrPrometheusExporterDeployment(solrPrometheusExporter *solr.SolrP
podAnnotations[PrometheusExporterConfigXmlMd5Annotation] =
configXmlMd5
}
- if tls != nil && tls.TLSCertMd5 != "" {
- if podAnnotations == nil {
- podAnnotations = make(map[string]string, 1)
- }
- podAnnotations[SolrTlsCertMd5Annotation] = tls.TLSCertMd5
- }
-
// if the basic-auth secret changes, we want to restart the deployment
pods
if basicAuthMd5 != "" {
if podAnnotations == nil {
@@ -396,6 +324,11 @@ func
GenerateSolrPrometheusExporterDeployment(solrPrometheusExporter *solr.SolrP
}
}
+ // Enrich the deployment definition to allow the exporter to make
requests to TLS enabled Solr pods
+ if tls != nil {
+ tls.enableTLSOnExporterDeployment(deployment)
+ }
+
return deployment
}
@@ -493,25 +426,3 @@ func CreateMetricsIngressRule(solrPrometheusExporter
*solr.SolrPrometheusExporte
},
}
}
-
-func tlsJavaOpts(tlsOptions *solr.SolrTLSOptions) []string {
- javaOpts := []string{
- "-Djavax.net.ssl.keyStore=$(SOLR_SSL_KEY_STORE)",
- "-Djavax.net.ssl.trustStore=$(SOLR_SSL_TRUST_STORE)",
- "-Djavax.net.ssl.keyStoreType=PKCS12",
- "-Djavax.net.ssl.trustStoreType=PKCS12",
- "-Dsolr.ssl.checkPeerName=$(SOLR_SSL_CHECK_PEER_NAME)",
- }
-
- if tlsOptions.PKCS12Secret != nil {
- // the password is available from env vars set from a secret
- javaOpts = append(javaOpts,
"-Djavax.net.ssl.keyStorePassword=$(SOLR_SSL_KEY_STORE_PASSWORD)")
- javaOpts = append(javaOpts,
"-Djavax.net.ssl.trustStorePassword=$(SOLR_SSL_TRUST_STORE_PASSWORD)")
- } // else if mountedServerTLSDir != nil, the password is in a file and
needs to be passed differently
-
- if tlsOptions.VerifyClientHostname {
- javaOpts = append(javaOpts,
"-Dsolr.jetty.ssl.verifyClientHostName=HTTPS")
- }
-
- return javaOpts
-}
diff --git a/controllers/util/solr_tls_util.go
b/controllers/util/solr_tls_util.go
new file mode 100644
index 0000000..6f19014
--- /dev/null
+++ b/controllers/util/solr_tls_util.go
@@ -0,0 +1,525 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package util
+
+import (
+ "fmt"
+ solr "github.com/apache/solr-operator/api/v1beta1"
+ appsv1 "k8s.io/api/apps/v1"
+ corev1 "k8s.io/api/core/v1"
+ "strconv"
+ "strings"
+)
+
+const (
+ SolrTlsCertMd5Annotation = "solr.apache.org/tlsCertMd5"
+ DefaultKeyStorePath = "/var/solr/tls"
+ DefaultWritableKeyStorePath = "/var/solr/tls/pkcs12"
+ TLSCertKey = "tls.crt"
+ DefaultTrustStorePath = "/var/solr/tls-truststore"
+ InitdbPath = "/docker-entrypoint-initdb.d"
+ DefaultPkcs12KeystoreFile = "keystore.p12"
+ DefaultPkcs12TruststoreFile = "truststore.p12"
+ DefaultKeystorePasswordFile = "keystore-password"
+)
+
+// Holds Options from the user config as well as other config properties
determined during reconciliation
+// This struct is intended for internal use only and is only exposed outside
the package so that the controllers can access
+type TLSConfig struct {
+ // TLS options provided by the user in the CRD definition
+ Options *solr.SolrTLSOptions
+ // Flag to indicate if we need to convert the provided keystore into
the p12 format needed by Java
+ NeedsPkcs12InitContainer bool
+ // The MD5 hash of the TLS cert, used for restarting Solr pods after
the cert updates if so desired
+ CertMd5 string
+ // Image used for initContainers that help configure the TLS settings
+ InitContainerImage *solr.ContainerImage
+}
+
+// Enrich the config for a SolrCloud StatefulSet to enable TLS, either loaded
from a secret or
+// a directory on the main pod containing per-pod specific TLS files. In the
latter case, the "mounted dir"
+// typically comes from an external agent (such as a cert-manager extension)
or CSI driver that injects the
+// pod-specific TLS files using mutating web hooks
+func (tls *TLSConfig) enableTLSOnSolrCloudStatefulSet(stateful
*appsv1.StatefulSet) {
+ // Add the SOLR_SSL_* vars to the main container's environment
+ tls.enableTLSOnPodTemplate(&stateful.Spec.Template)
+
+ // volumes and mounts for TLS when using the mounted dir option
+ if tls.Options.MountedServerTLSDir != nil {
+ // the TLS files come from some auto-mounted directory on the
main container
+ tls.mountInitDbIfNeeded(stateful)
+ // use an initContainer to create the wrapper script in the
initdb
+ stateful.Spec.Template.Spec.InitContainers =
append(stateful.Spec.Template.Spec.InitContainers,
tls.generateTLSInitdbScriptInitContainer())
+ }
+}
+
+// Enrich the config for a Prometheus Exporter Deployment to allow the
exporter to make requests to TLS enabled Solr pods
+func (tls *TLSConfig) enableTLSOnExporterDeployment(deployment
*appsv1.Deployment) {
+ // Add the SOLR_SSL_* vars to the main container's environment
+ mainContainer := tls.enableTLSOnPodTemplate(&deployment.Spec.Template)
+
+ // the exporter process doesn't read the SOLR_SSL_* env vars, so we
need to pass them via JAVA_OPTS
+ tls.appendTLSJavaOptsToEnv(mainContainer)
+
+ // volumes and mounts for TLS when using the mounted dir option
+ if tls.Options.MountedServerTLSDir != nil {
+ tls.mountTLSWrapperScriptAndInitContainer(deployment)
+ }
+}
+
+// Configures the TLS env vars, pod annotations, volumes, and pkcs12
initContainer on a Pod template spec
+// for enabling TLS on either StatefulSet or Deployment
+func (tls *TLSConfig) enableTLSOnPodTemplate(template *corev1.PodTemplateSpec)
*corev1.Container {
+ // Add the SOLR_SSL_* vars to the main container's environment
+ mainContainer := &template.Spec.Containers[0]
+ mainContainer.Env = append(mainContainer.Env, tls.envVars()...)
+
+ if tls.Options.PKCS12Secret != nil {
+ // the TLS files are mounted from a secret, setup the volumes
and mounts
+ template.Spec.Volumes = append(template.Spec.Volumes,
tls.volumes()...)
+ mainContainer.VolumeMounts = append(mainContainer.VolumeMounts,
tls.volumeMounts()...)
+
+ // track the MD5 of the TLS cert (from secret) to trigger
restarts if the cert changes
+ if tls.Options.RestartOnTLSSecretUpdate && tls.CertMd5 != "" {
+ if template.Annotations == nil {
+ template.Annotations = make(map[string]string,
1)
+ }
+ template.Annotations[SolrTlsCertMd5Annotation] =
tls.CertMd5
+ }
+
+ // use an initContainer to convert the keystore to p12 format
if needed
+ if tls.NeedsPkcs12InitContainer {
+ pkcs12InitContainer :=
tls.generatePkcs12InitContainer(mainContainer.Image,
mainContainer.ImagePullPolicy)
+ template.Spec.InitContainers =
append(template.Spec.InitContainers, pkcs12InitContainer)
+ }
+ }
+
+ return mainContainer
+}
+
+// Get a list of volumes for the keystore and optionally a truststore loaded
from a TLS secret
+func (tls *TLSConfig) volumes() []corev1.Volume {
+ optional := false
+ defaultMode := int32(0664)
+ vols := []corev1.Volume{
+ {
+ Name: "keystore",
+ VolumeSource: corev1.VolumeSource{
+ Secret: &corev1.SecretVolumeSource{
+ SecretName:
tls.Options.PKCS12Secret.Name,
+ DefaultMode: &defaultMode,
+ Optional: &optional,
+ },
+ },
+ },
+ }
+
+ // if they're using a different truststore other than the keystore, but
don't mount an additional volume
+ // if it's just pointing at the same secret
+ if tls.Options.TrustStoreSecret != nil &&
tls.Options.TrustStoreSecret.Name != tls.Options.PKCS12Secret.Name {
+ vols = append(vols, corev1.Volume{
+ Name: "truststore",
+ VolumeSource: corev1.VolumeSource{
+ Secret: &corev1.SecretVolumeSource{
+ SecretName:
tls.Options.TrustStoreSecret.Name,
+ DefaultMode: &defaultMode,
+ Optional: &optional,
+ },
+ },
+ })
+ }
+
+ if tls.NeedsPkcs12InitContainer {
+ vols = append(vols, corev1.Volume{
+ Name: "pkcs12",
+ VolumeSource: corev1.VolumeSource{
+ EmptyDir: &corev1.EmptyDirVolumeSource{},
+ },
+ })
+ }
+
+ return vols
+}
+
+// Get the volume mounts for the keystore and truststore
+func (tls *TLSConfig) volumeMounts() []corev1.VolumeMount {
+ opts := tls.Options
+
+ mounts := []corev1.VolumeMount{
+ {
+ Name: "keystore",
+ ReadOnly: true,
+ MountPath: DefaultKeyStorePath,
+ },
+ }
+
+ if opts.TrustStoreSecret != nil && opts.TrustStoreSecret.Name !=
opts.PKCS12Secret.Name {
+ mounts = append(mounts, corev1.VolumeMount{
+ Name: "truststore",
+ ReadOnly: true,
+ MountPath: DefaultTrustStorePath,
+ })
+ }
+
+ // We need an initContainer to convert a TLS cert into the pkcs12
format Java wants (using openssl)
+ // but openssl cannot write to the /var/solr/tls directory because of
the way secret mounts work
+ // so we need to mount an empty directory to write pkcs12 keystore into
+ if tls.NeedsPkcs12InitContainer {
+ mounts = append(mounts, corev1.VolumeMount{
+ Name: "pkcs12",
+ ReadOnly: false,
+ MountPath: DefaultWritableKeyStorePath,
+ })
+ }
+
+ return mounts
+}
+
+// Get the SOLR_SSL_* env vars for enabling TLS on Solr
+func (tls *TLSConfig) envVars() []corev1.EnvVar {
+ opts := tls.Options
+
+ // Determine the correct values for the SOLR_SSL_WANT_CLIENT_AUTH and
SOLR_SSL_NEED_CLIENT_AUTH vars
+ wantClientAuth := "false"
+ needClientAuth := "false"
+ if opts.ClientAuth == solr.Need {
+ needClientAuth = "true"
+ } else if opts.ClientAuth == solr.Want {
+ wantClientAuth = "true"
+ }
+
+ var keystoreFile string
+ var passwordValueFrom *corev1.EnvVarSource
+ var truststoreFile string
+ var truststorePassFrom *corev1.EnvVarSource
+ if opts.MountedServerTLSDir != nil {
+ // TLS files are mounted by some external agent
+ keystoreFile = mountedTLSKeystorePath(opts)
+ truststoreFile = mountedTLSTruststorePath(opts)
+ } else {
+ // the keystore path depends on whether we're just loading it
from the secret or whether
+ // our initContainer has to generate it from the TLS secret
using openssl
+ // this complexity is due to the secret mount directory not
being writable
+ var keystorePath string
+ if tls.NeedsPkcs12InitContainer {
+ keystorePath = DefaultWritableKeyStorePath
+ } else {
+ keystorePath = DefaultKeyStorePath
+ }
+
+ keystoreFile = keystorePath + "/" + DefaultPkcs12KeystoreFile
+ passwordValueFrom = &corev1.EnvVarSource{SecretKeyRef:
opts.KeyStorePasswordSecret}
+
+ // If using a truststore that is different from the keystore
+ truststoreFile = keystoreFile
+ truststorePassFrom = passwordValueFrom
+ if opts.TrustStoreSecret != nil {
+ if opts.TrustStoreSecret.Name != opts.PKCS12Secret.Name
{
+ // trust store is in a different secret, so
will be mounted in a different dir
+ truststoreFile = DefaultTrustStorePath
+ } else {
+ // trust store is a different key in the same
secret as the keystore
+ truststoreFile = DefaultKeyStorePath
+ }
+ truststoreFile += "/" + opts.TrustStoreSecret.Key
+ if opts.TrustStorePasswordSecret != nil {
+ truststorePassFrom =
&corev1.EnvVarSource{SecretKeyRef: opts.TrustStorePasswordSecret}
+ }
+ }
+ }
+
+ envVars := []corev1.EnvVar{
+ {
+ Name: "SOLR_SSL_ENABLED",
+ Value: "true",
+ },
+ {
+ Name: "SOLR_SSL_KEY_STORE",
+ Value: keystoreFile,
+ },
+ {
+ Name: "SOLR_SSL_TRUST_STORE",
+ Value: truststoreFile,
+ },
+ {
+ Name: "SOLR_SSL_WANT_CLIENT_AUTH",
+ Value: wantClientAuth,
+ },
+ {
+ Name: "SOLR_SSL_NEED_CLIENT_AUTH",
+ Value: needClientAuth,
+ },
+ {
+ Name: "SOLR_SSL_CLIENT_HOSTNAME_VERIFICATION",
+ Value: strconv.FormatBool(opts.VerifyClientHostname),
+ },
+ {
+ Name: "SOLR_SSL_CHECK_PEER_NAME",
+ Value: strconv.FormatBool(opts.CheckPeerName),
+ },
+ }
+
+ if passwordValueFrom != nil {
+ envVars = append(envVars, corev1.EnvVar{Name:
"SOLR_SSL_KEY_STORE_PASSWORD", ValueFrom: passwordValueFrom})
+ }
+
+ if truststorePassFrom != nil {
+ envVars = append(envVars, corev1.EnvVar{Name:
"SOLR_SSL_TRUST_STORE_PASSWORD", ValueFrom: truststorePassFrom})
+ }
+
+ return envVars
+}
+
+// For the mounted dir approach, we need to customize the Prometheus
exporter's entry point with a wrapper script
+// that reads the keystore / truststore passwords from a file and passes them
via JAVA_OPTS
+func (tls *TLSConfig) mountTLSWrapperScriptAndInitContainer(deployment
*appsv1.Deployment) {
+ mainContainer := &deployment.Spec.Template.Spec.Containers[0]
+
+ volName := "tls-wrapper-script"
+ mountPath := "/usr/local/solr-exporter-tls"
+ wrapperScript := mountPath + "/launch-exporter-with-tls.sh"
+
+ // the Prom exporter needs the keystore & truststore passwords in a
Java system property, but the password
+ // is stored in a file when using the mounted TLS dir approach, so we
use a wrapper script around the main
+ // container entry point to add these properties to JAVA_OPTS at runtime
+ vol, mount := tls.createEmptyVolumeAndMount(volName, mountPath)
+ deployment.Spec.Template.Spec.Volumes =
append(deployment.Spec.Template.Spec.Volumes, *vol)
+ mainContainer.VolumeMounts = append(mainContainer.VolumeMounts, *mount)
+
+ /*
+ Create a wrapper script like:
+
+ #!/bin/bash
+ ksp=$(cat $MOUNTED_TLS_DIR/keystore-password)
+ tsp=$(cat $MOUNTED_TLS_DIR/keystore-password)
+ JAVA_OPTS="${JAVA_OPTS}
-Djavax.net.ssl.keyStorePassword=${ksp}
-Djavax.net.ssl.trustStorePassword=${tsp}"
+ /opt/solr/contrib/prometheus-exporter/bin/solr-exporter
$@
+
+ */
+ entrypoint := mainContainer.Command[0]
+ writeWrapperScript := fmt.Sprintf("cat << EOF >
%s\n#!/bin/bash\nksp=\\$(cat %s)\ntsp=\\$(cat %s)\n"+
+ "JAVA_OPTS=\"\\${JAVA_OPTS}
-Djavax.net.ssl.keyStorePassword=\\${ksp}
-Djavax.net.ssl.trustStorePassword=\\${tsp}\"\n%s \\$@\nEOF\nchmod +x %s",
+ wrapperScript, mountedTLSKeystorePasswordPath(tls.Options),
mountedTLSTruststorePasswordPath(tls.Options), entrypoint, wrapperScript)
+
+ createTLSWrapperScriptInitContainer := corev1.Container{
+ Name: "create-tls-wrapper-script",
+ Image: tls.InitContainerImage.ToImageName(),
+ ImagePullPolicy: tls.InitContainerImage.PullPolicy,
+ Command: []string{"sh", "-c", writeWrapperScript},
+ VolumeMounts: []corev1.VolumeMount{{Name: volName,
MountPath: mountPath}},
+ }
+ deployment.Spec.Template.Spec.InitContainers =
append(deployment.Spec.Template.Spec.InitContainers,
createTLSWrapperScriptInitContainer)
+
+ // Call the wrapper script to start the exporter process
+ mainContainer.Command = []string{wrapperScript}
+}
+
+// The Docker Solr framework allows us to run scripts from an initdb directory
before the main Solr process is started
+// Mount the initdb directory if it has not already been mounted by the user
via custom pod options
+func (tls *TLSConfig) mountInitDbIfNeeded(stateful *appsv1.StatefulSet) {
+ // Auto-TLS uses an initContainer to create a script in the initdb, so
mount that if it has not already been mounted
+ mainContainer := &stateful.Spec.Template.Spec.Containers[0]
+ var initdbMount *corev1.VolumeMount
+ for _, mount := range mainContainer.VolumeMounts {
+ if mount.MountPath == InitdbPath {
+ initdbMount = &mount
+ break
+ }
+ }
+ if initdbMount == nil {
+ vol, mount := tls.createEmptyVolumeAndMount("initdb",
InitdbPath)
+ stateful.Spec.Template.Spec.Volumes =
append(stateful.Spec.Template.Spec.Volumes, *vol)
+ mainContainer.VolumeMounts = append(mainContainer.VolumeMounts,
*mount)
+ }
+}
+
+// Utility func to create an empty dir and corresponding mount
+func (tls *TLSConfig) createEmptyVolumeAndMount(name string, mountPath string)
(*corev1.Volume, *corev1.VolumeMount) {
+ return &corev1.Volume{Name: name, VolumeSource:
corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}},
+ &corev1.VolumeMount{Name: name, MountPath: mountPath}
+}
+
+// Create an initContainer that generates the initdb script that exports the
keystore / truststore passwords stored in
+// a directory to the environment; this is only needed when using the
mountedServerTLSDir approach
+func (tls *TLSConfig) generateTLSInitdbScriptInitContainer() corev1.Container {
+ // run an initContainer that creates a script in the initdb that
exports the
+ // keystore secret from a file to the env before Solr is started
+ shCmd := fmt.Sprintf("echo -e \"#!/bin/bash\\nexport
SOLR_SSL_KEY_STORE_PASSWORD=\\`cat %s\\`\\nexport
SOLR_SSL_TRUST_STORE_PASSWORD=\\`cat %s\\`\" >
/docker-entrypoint-initdb.d/export-tls-vars.sh",
+ mountedTLSKeystorePasswordPath(tls.Options),
mountedTLSTruststorePasswordPath(tls.Options))
+
+ /*
+ Init container creates a script like:
+
+ #!/bin/bash
+ export SOLR_SSL_KEY_STORE_PASSWORD=`cat
$MOUNTED_TLS_DIR/keystore-password`
+ export SOLR_SSL_TRUST_STORE_PASSWORD=`cat
$MOUNTED_TLS_DIR/keystore-password`
+
+ */
+
+ return corev1.Container{
+ Name: "export-tls-password",
+ Image: tls.InitContainerImage.ToImageName(),
+ ImagePullPolicy: tls.InitContainerImage.PullPolicy,
+ Command: []string{"sh", "-c", shCmd},
+ VolumeMounts: []corev1.VolumeMount{{Name: "initdb",
MountPath: InitdbPath}},
+ }
+}
+
+// Returns an array of Java system properties to configure the TLS certificate
used by client applications to call mTLS enabled Solr pods
+func (tls *TLSConfig) clientJavaOpts() []string {
+ javaOpts := []string{
+ "-Djavax.net.ssl.keyStore=$(SOLR_SSL_KEY_STORE)",
+ "-Djavax.net.ssl.trustStore=$(SOLR_SSL_TRUST_STORE)",
+ "-Djavax.net.ssl.keyStoreType=PKCS12",
+ "-Djavax.net.ssl.trustStoreType=PKCS12",
+ "-Dsolr.ssl.checkPeerName=$(SOLR_SSL_CHECK_PEER_NAME)",
+ }
+
+ if tls.Options.PKCS12Secret != nil {
+ // the password is available from env vars set from a secret
+ javaOpts = append(javaOpts,
"-Djavax.net.ssl.keyStorePassword=$(SOLR_SSL_KEY_STORE_PASSWORD)")
+ javaOpts = append(javaOpts,
"-Djavax.net.ssl.trustStorePassword=$(SOLR_SSL_TRUST_STORE_PASSWORD)")
+ } // else if mountedServerTLSDir != nil, the password is in a file and
needs to be passed differently
+
+ if tls.Options.VerifyClientHostname {
+ javaOpts = append(javaOpts,
"-Dsolr.jetty.ssl.verifyClientHostName=HTTPS")
+ }
+
+ return javaOpts
+}
+
+// Append TLS related Java system properties to the JAVA_OPTS environment
variable of the main container
+func (tls *TLSConfig) appendTLSJavaOptsToEnv(mainContainer *corev1.Container) {
+ tlsJavaOpts := tls.clientJavaOpts()
+ javaOptsValue := ""
+ javaOptsAt := -1
+ for i, v := range mainContainer.Env {
+ if v.Name == "JAVA_OPTS" {
+ javaOptsValue = v.Value
+ javaOptsAt = i
+ break
+ }
+ }
+ javaOptsVar := corev1.EnvVar{Name: "JAVA_OPTS", Value:
strings.TrimSpace(javaOptsValue + " " + strings.Join(tlsJavaOpts, " "))}
+ if javaOptsAt == -1 {
+ // no JAVA_OPTS, add it on the end
+ mainContainer.Env = append(mainContainer.Env, javaOptsVar)
+ } else {
+ // need to move the JAVA_OPTS var to end of array, slice it out
...
+ envVars := mainContainer.Env[0:javaOptsAt]
+ if javaOptsAt < len(mainContainer.Env)-1 {
+ envVars = append(envVars,
mainContainer.Env[javaOptsAt+1:]...)
+ }
+ mainContainer.Env = append(envVars, javaOptsVar)
+ }
+}
+
+func (tls *TLSConfig) generatePkcs12InitContainer(imageName string,
imagePullPolicy corev1.PullPolicy) corev1.Container {
+ // get the keystore password from the env for generating the keystore
using openssl
+ passwordValueFrom := &corev1.EnvVarSource{SecretKeyRef:
tls.Options.KeyStorePasswordSecret}
+ envVars := []corev1.EnvVar{
+ {
+ Name: "SOLR_SSL_KEY_STORE_PASSWORD",
+ ValueFrom: passwordValueFrom,
+ },
+ }
+
+ cmd := "openssl pkcs12 -export -in " + DefaultKeyStorePath + "/" +
TLSCertKey + " -in " + DefaultKeyStorePath +
+ "/ca.crt -inkey " + DefaultKeyStorePath + "/tls.key -out " +
DefaultKeyStorePath +
+ "/pkcs12/" + DefaultPkcs12KeystoreFile + " -passout
pass:${SOLR_SSL_KEY_STORE_PASSWORD}"
+ return corev1.Container{
+ Name: "gen-pkcs12-keystore",
+ Image: imageName,
+ ImagePullPolicy: imagePullPolicy,
+ TerminationMessagePath: "/dev/termination-log",
+ TerminationMessagePolicy: "File",
+ Command: []string{"sh", "-c", cmd},
+ VolumeMounts: tls.volumeMounts(),
+ Env: envVars,
+ }
+}
+
+// Get TLS properties for JAVA_TOOL_OPTIONS and Java system props for
configuring the secured probe command; used when
+// we call a local command on the Solr pod for the probes instead of using
HTTP/HTTPS
+func secureProbeTLSJavaToolOpts(tls *solr.SolrTLSOptions) (string, string) {
+ tlsJavaToolOpts := ""
+ tlsJavaSysProps := ""
+ if tls != nil {
+ tlsJavaSysProps = "-Djavax.net.ssl.keyStore=$SOLR_SSL_KEY_STORE
-Djavax.net.ssl.trustStore=$SOLR_SSL_TRUST_STORE"
+
+ // If the keystore passwords are in a file, then we need to cat
the file(s) into JAVA_TOOL_OPTIONS
+ if tls.MountedServerTLSDir != nil {
+ tlsJavaToolOpts += "
-Djavax.net.ssl.keyStorePassword=$(cat " + mountedTLSKeystorePasswordPath(tls)
+ ")"
+ tlsJavaToolOpts += "
-Djavax.net.ssl.trustStorePassword=$(cat " +
mountedTLSTruststorePasswordPath(tls) + ")"
+ } else {
+ tlsJavaSysProps += "
-Djavax.net.ssl.keyStorePassword=$SOLR_SSL_KEY_STORE_PASSWORD"
+ tlsJavaSysProps += "
-Djavax.net.ssl.trustStorePassword=$SOLR_SSL_TRUST_STORE_PASSWORD"
+ }
+ }
+ return tlsJavaToolOpts, tlsJavaSysProps
+}
+
+func mountedTLSKeystorePath(tls *solr.SolrTLSOptions) string {
+ path := ""
+ if tls.MountedServerTLSDir != nil {
+ path = mountedTLSPath(tls.MountedServerTLSDir,
tls.MountedServerTLSDir.KeystoreFile, DefaultPkcs12KeystoreFile)
+ }
+ return path
+}
+
+func mountedTLSKeystorePasswordPath(tls *solr.SolrTLSOptions) string {
+ path := ""
+ if tls.MountedServerTLSDir != nil {
+ path = mountedTLSPath(tls.MountedServerTLSDir,
tls.MountedServerTLSDir.KeystorePasswordFile, DefaultKeystorePasswordFile)
+ }
+ return path
+}
+
+func mountedTLSTruststorePath(tls *solr.SolrTLSOptions) string {
+ path := ""
+ if tls.MountedServerTLSDir != nil {
+ path = mountedTLSPath(tls.MountedServerTLSDir,
tls.MountedServerTLSDir.TruststoreFile, DefaultPkcs12TruststoreFile)
+ }
+ return path
+}
+
+func mountedTLSTruststorePasswordPath(tls *solr.SolrTLSOptions) string {
+ path := ""
+ if tls.MountedServerTLSDir != nil {
+ if tls.MountedServerTLSDir.TruststorePasswordFile != "" {
+ path = mountedTLSPath(tls.MountedServerTLSDir,
tls.MountedServerTLSDir.TruststorePasswordFile, "")
+ } else {
+ path = mountedTLSKeystorePasswordPath(tls)
+ }
+ }
+ return path
+}
+
+func mountedTLSPath(dir *solr.MountedTLSDirectory, fileName string,
defaultName string) string {
+ if fileName == "" {
+ fileName = defaultName
+ }
+ return fmt.Sprintf("%s/%s", dir.Path, fileName)
+}
+
+// Command to set the urlScheme cluster prop to "https"
+func setUrlSchemeClusterPropCmd() string {
+ return "solr zk ls ${ZK_CHROOT} -z ${ZK_SERVER} || solr zk mkroot
${ZK_CHROOT} -z ${ZK_SERVER}" +
+ "; /opt/solr/server/scripts/cloud-scripts/zkcli.sh -zkhost
${ZK_HOST} -cmd clusterprop -name urlScheme -val https" +
+ "; /opt/solr/server/scripts/cloud-scripts/zkcli.sh -zkhost
${ZK_HOST} -cmd get /clusterprops.json;"
+}
diff --git a/controllers/util/solr_util.go b/controllers/util/solr_util.go
index e34aa98..17c64d5 100644
--- a/controllers/util/solr_util.go
+++ b/controllers/util/solr_util.go
@@ -53,7 +53,6 @@ const (
SolrCloudPVCDataStorage = "data"
SolrPVCInstanceLabel = "solr.apache.org/instance"
SolrXmlMd5Annotation = "solr.apache.org/solrXmlMd5"
- SolrTlsCertMd5Annotation = "solr.apache.org/tlsCertMd5"
SolrXmlFile = "solr.xml"
LogXmlMd5Annotation = "solr.apache.org/logXmlMd5"
LogXmlFile = "log4j2.xml"
@@ -62,15 +61,6 @@ const (
DefaultProbePath = "/admin/info/system"
DefaultStatefulSetPodManagementPolicy = appsv1.ParallelPodManagement
-
- DefaultKeyStorePath = "/var/solr/tls"
- DefaultWritableKeyStorePath = "/var/solr/tls/pkcs12"
- TLSCertKey = "tls.crt"
- DefaultTrustStorePath = "/var/solr/tls-truststore"
- InitdbPath = "/docker-entrypoint-initdb.d"
- DefaultPkcs12KeystoreFile = "keystore.p12"
- DefaultPkcs12TruststoreFile = "truststore.p12"
- DefaultKeystorePasswordFile = "keystore-password"
)
// GenerateStatefulSet returns a new appsv1.StatefulSet pointer generated for
the SolrCloud instance
@@ -78,14 +68,14 @@ const (
// replicas: the number of replicas for the SolrCloud instance
// storage: the size of the storage for the SolrCloud instance (e.g. 100Gi)
// zkConnectionString: the connectionString of the ZK instance to connect to
-func GenerateStatefulSet(solrCloud *solr.SolrCloud, solrCloudStatus
*solr.SolrCloudStatus, hostNameIPs map[string]string, reconcileConfigInfo
map[string]string, createPkcs12InitContainer bool, tlsCertMd5 string)
*appsv1.StatefulSet {
+func GenerateStatefulSet(solrCloud *solr.SolrCloud, solrCloudStatus
*solr.SolrCloudStatus, hostNameIPs map[string]string, reconcileConfigInfo
map[string]string, tls *TLSConfig) *appsv1.StatefulSet {
terminationGracePeriod := int64(60)
solrPodPort := solrCloud.Spec.SolrAddressability.PodPort
fsGroup := int64(DefaultSolrGroup)
defaultMode := int32(420)
probeScheme := corev1.URISchemeHTTP
- if solrCloud.Spec.SolrTLS != nil {
+ if tls != nil {
probeScheme = corev1.URISchemeHTTPS
}
@@ -155,11 +145,6 @@ func GenerateStatefulSet(solrCloud *solr.SolrCloud,
solrCloudStatus *solr.SolrCl
solrDataVolumeName := "data"
volumeMounts := []corev1.VolumeMount{{Name: solrDataVolumeName,
MountPath: "/var/solr/data"}}
- if solrCloud.Spec.SolrTLS != nil &&
solrCloud.Spec.SolrTLS.MountedServerTLSDir == nil {
- solrVolumes = append(solrVolumes,
tlsVolumes(solrCloud.Spec.SolrTLS, createPkcs12InitContainer)...)
- volumeMounts = append(volumeMounts,
tlsVolumeMounts(solrCloud.Spec.SolrTLS, createPkcs12InitContainer)...)
- }
-
var pvcs []corev1.PersistentVolumeClaim
if solrCloud.UsesPersistentStorage() {
pvc :=
solrCloud.Spec.StorageOptions.PersistentStorage.PersistentVolumeClaimTemplate.DeepCopy()
@@ -246,21 +231,6 @@ func GenerateStatefulSet(solrCloud *solr.SolrCloud,
solrCloudStatus *solr.SolrCl
}
}
- // Auto-TLS uses an initContainer to create a script in the initdb, so
mount that if it has not already been mounted
- if solrCloud.Spec.SolrTLS != nil &&
solrCloud.Spec.SolrTLS.MountedServerTLSDir != nil {
- var initdbMount *corev1.VolumeMount
- for _, mount := range volumeMounts {
- if mount.MountPath == InitdbPath {
- initdbMount = &mount
- break
- }
- }
- if initdbMount == nil {
- solrVolumes = append(solrVolumes, corev1.Volume{Name:
"initdb", VolumeSource: corev1.VolumeSource{EmptyDir:
&corev1.EmptyDirVolumeSource{}}})
- volumeMounts = append(volumeMounts,
corev1.VolumeMount{Name: "initdb", MountPath: InitdbPath})
- }
- }
-
// Host Aliases
hostAliases := make([]corev1.HostAlias, len(hostNameIPs))
if len(hostAliases) == 0 {
@@ -357,11 +327,6 @@ func GenerateStatefulSet(solrCloud *solr.SolrCloud,
solrCloudStatus *solr.SolrCl
}
}
- // Append TLS related env vars if enabled
- if solrCloud.Spec.SolrTLS != nil {
- envVars = append(envVars, TLSEnvVars(solrCloud.Spec.SolrTLS,
createPkcs12InitContainer)...)
- }
-
// Add Custom EnvironmentVariables to the solr container
if nil != customPodOptions {
envVars = append(envVars, customPodOptions.EnvVariables...)
@@ -386,7 +351,7 @@ func GenerateStatefulSet(solrCloud *solr.SolrCloud,
solrCloudStatus *solr.SolrCl
}
}
- if (solrCloud.Spec.SolrTLS != nil && solrCloud.Spec.SolrTLS.ClientAuth
!= solr.None) || (solrCloud.Spec.SolrSecurity != nil &&
solrCloud.Spec.SolrSecurity.ProbesRequireAuth) {
+ if (tls != nil && tls.Options.ClientAuth != solr.None) ||
(solrCloud.Spec.SolrSecurity != nil &&
solrCloud.Spec.SolrSecurity.ProbesRequireAuth) {
probeCommand, vol, volMount :=
configureSecureProbeCommand(solrCloud, defaultHandler.HTTPGet)
if vol != nil {
solrVolumes = append(solrVolumes, *vol)
@@ -408,14 +373,6 @@ func GenerateStatefulSet(solrCloud *solr.SolrCloud,
solrCloudStatus *solr.SolrCl
podAnnotations[SolrXmlMd5Annotation] =
reconcileConfigInfo[SolrXmlMd5Annotation]
}
- // track the MD5 of the TLS cert (from secret) to trigger restarts if
the cert changes
- if solrCloud.Spec.SolrTLS != nil &&
solrCloud.Spec.SolrTLS.RestartOnTLSSecretUpdate && tlsCertMd5 != "" {
- if podAnnotations == nil {
- podAnnotations = make(map[string]string, 1)
- }
- podAnnotations[SolrTlsCertMd5Annotation] = tlsCertMd5
- }
-
if solrCloud.Spec.SolrOpts != "" {
allSolrOpts = append(allSolrOpts, solrCloud.Spec.SolrOpts)
}
@@ -492,12 +449,6 @@ func GenerateStatefulSet(solrCloud *solr.SolrCloud,
solrCloudStatus *solr.SolrCl
podManagementPolicy =
solrCloud.Spec.CustomSolrKubeOptions.StatefulSetOptions.PodManagementPolicy
}
- if createPkcs12InitContainer {
- pkcs12InitContainer :=
generatePkcs12InitContainer(solrCloud.Spec.SolrTLS,
- solrCloud.Spec.SolrImage.ToImageName(),
solrCloud.Spec.SolrImage.PullPolicy)
- initContainers = append(initContainers, pkcs12InitContainer)
- }
-
// Create the Stateful Set
stateful := &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{
@@ -601,6 +552,11 @@ func GenerateStatefulSet(solrCloud *solr.SolrCloud,
solrCloudStatus *solr.SolrCl
}
}
+ // Enrich the StatefulSet config to enable TLS on Solr pods if needed
+ if tls != nil {
+ tls.enableTLSOnSolrCloudStatefulSet(stateful)
+ }
+
return stateful
}
@@ -645,10 +601,6 @@ func generateSolrSetupInitContainers(solrCloud
*solr.SolrCloud, solrCloudStatus
containers = append(containers, zkSetupContainer)
}
- if solrCloud.Spec.SolrTLS != nil &&
solrCloud.Spec.SolrTLS.MountedServerTLSDir != nil {
- containers = append(containers,
generateTLSInitdbScriptInitContainer(solrCloud))
- }
-
return containers
}
@@ -977,30 +929,6 @@ func CreateNodeIngressRule(solrCloud *solr.SolrCloud,
nodeName string, domainNam
return ingressRule
}
-func generateTLSInitdbScriptInitContainer(solrCloud *solr.SolrCloud)
corev1.Container {
- // run an initContainer that creates a script in the initdb that
exports the
- // keystore secret from a file to the env before Solr is started
- shCmd := fmt.Sprintf("echo -e \"#!/bin/bash\\nexport
SOLR_SSL_KEY_STORE_PASSWORD=\\`cat %s\\`\\nexport
SOLR_SSL_TRUST_STORE_PASSWORD=\\`cat %s\\`\" >
/docker-entrypoint-initdb.d/export-tls-vars.sh",
- MountedTLSKeystorePasswordPath(solrCloud.Spec.SolrTLS),
MountedTLSTruststorePasswordPath(solrCloud.Spec.SolrTLS))
-
- /*
- Init container creates a script like:
-
- #!/bin/bash
- export SOLR_SSL_KEY_STORE_PASSWORD=`cat
$MOUNTED_TLS_DIR/keystore-password`
- export SOLR_SSL_TRUST_STORE_PASSWORD=`cat
$MOUNTED_TLS_DIR/keystore-password`
-
- */
-
- return corev1.Container{
- Name: "export-tls-password",
- Image: solrCloud.Spec.BusyBoxImage.ToImageName(),
- ImagePullPolicy: solrCloud.Spec.BusyBoxImage.PullPolicy,
- Command: []string{"sh", "-c", shCmd},
- VolumeMounts: []corev1.VolumeMount{{Name: "initdb",
MountPath: InitdbPath}},
- }
-}
-
// TODO: Have this replace the postStart hook for creating the chroot
func generateZKInteractionInitContainer(solrCloud *solr.SolrCloud,
solrCloudStatus *solr.SolrCloudStatus, reconcileConfigInfo map[string]string)
(bool, corev1.Container) {
allSolrOpts := make([]string, 0)
@@ -1026,9 +954,7 @@ func generateZKInteractionInitContainer(solrCloud
*solr.SolrCloud, solrCloudStat
cmd := ""
if solrCloud.Spec.SolrTLS != nil {
- cmd = "solr zk ls ${ZK_CHROOT} -z ${ZK_SERVER} || solr zk
mkroot ${ZK_CHROOT} -z ${ZK_SERVER}" +
- "; /opt/solr/server/scripts/cloud-scripts/zkcli.sh
-zkhost ${ZK_HOST} -cmd clusterprop -name urlScheme -val https" +
- "; /opt/solr/server/scripts/cloud-scripts/zkcli.sh
-zkhost ${ZK_HOST} -cmd get /clusterprops.json;"
+ cmd = setUrlSchemeClusterPropCmd()
}
if reconcileConfigInfo[SecurityJsonFile] != "" {
@@ -1059,198 +985,6 @@ func generateZKInteractionInitContainer(solrCloud
*solr.SolrCloud, solrCloudStat
return false, corev1.Container{}
}
-func TLSEnvVars(opts *solr.SolrTLSOptions, createPkcs12InitContainer bool)
[]corev1.EnvVar {
-
- // Determine the correct values for the SOLR_SSL_WANT_CLIENT_AUTH and
SOLR_SSL_NEED_CLIENT_AUTH vars
- wantClientAuth := "false"
- needClientAuth := "false"
- if opts.ClientAuth == solr.Need {
- needClientAuth = "true"
- } else if opts.ClientAuth == solr.Want {
- wantClientAuth = "true"
- }
-
- var keystoreFile string
- var passwordValueFrom *corev1.EnvVarSource
- var truststoreFile string
- var truststorePassFrom *corev1.EnvVarSource
- if opts.MountedServerTLSDir != nil {
- // TLS files are mounted by some external agent
- keystoreFile = mountedTLSKeystorePath(opts)
- truststoreFile = mountedTLSTruststorePath(opts)
- } else {
- // the keystore path depends on whether we're just loading it
from the secret or whether
- // our initContainer has to generate it from the TLS secret
using openssl
- // this complexity is due to the secret mount directory not
being writable
- var keystorePath string
- if createPkcs12InitContainer {
- keystorePath = DefaultWritableKeyStorePath
- } else {
- keystorePath = DefaultKeyStorePath
- }
-
- keystoreFile = keystorePath + "/" + DefaultPkcs12KeystoreFile
- passwordValueFrom = &corev1.EnvVarSource{SecretKeyRef:
opts.KeyStorePasswordSecret}
-
- // If using a truststore that is different from the keystore
- truststoreFile = keystoreFile
- truststorePassFrom = passwordValueFrom
- if opts.TrustStoreSecret != nil {
- if opts.TrustStoreSecret.Name != opts.PKCS12Secret.Name
{
- // trust store is in a different secret, so
will be mounted in a different dir
- truststoreFile = DefaultTrustStorePath
- } else {
- // trust store is a different key in the same
secret as the keystore
- truststoreFile = DefaultKeyStorePath
- }
- truststoreFile += "/" + opts.TrustStoreSecret.Key
- if opts.TrustStorePasswordSecret != nil {
- truststorePassFrom =
&corev1.EnvVarSource{SecretKeyRef: opts.TrustStorePasswordSecret}
- }
- }
- }
-
- envVars := []corev1.EnvVar{
- {
- Name: "SOLR_SSL_ENABLED",
- Value: "true",
- },
- {
- Name: "SOLR_SSL_KEY_STORE",
- Value: keystoreFile,
- },
- {
- Name: "SOLR_SSL_TRUST_STORE",
- Value: truststoreFile,
- },
- {
- Name: "SOLR_SSL_WANT_CLIENT_AUTH",
- Value: wantClientAuth,
- },
- {
- Name: "SOLR_SSL_NEED_CLIENT_AUTH",
- Value: needClientAuth,
- },
- {
- Name: "SOLR_SSL_CLIENT_HOSTNAME_VERIFICATION",
- Value: strconv.FormatBool(opts.VerifyClientHostname),
- },
- {
- Name: "SOLR_SSL_CHECK_PEER_NAME",
- Value: strconv.FormatBool(opts.CheckPeerName),
- },
- }
-
- if passwordValueFrom != nil {
- envVars = append(envVars, corev1.EnvVar{Name:
"SOLR_SSL_KEY_STORE_PASSWORD", ValueFrom: passwordValueFrom})
- }
-
- if truststorePassFrom != nil {
- envVars = append(envVars, corev1.EnvVar{Name:
"SOLR_SSL_TRUST_STORE_PASSWORD", ValueFrom: truststorePassFrom})
- }
-
- return envVars
-}
-
-func tlsVolumeMounts(opts *solr.SolrTLSOptions, createPkcs12InitContainer
bool) []corev1.VolumeMount {
- mounts := []corev1.VolumeMount{
- {
- Name: "keystore",
- ReadOnly: true,
- MountPath: DefaultKeyStorePath,
- },
- }
-
- if opts.TrustStoreSecret != nil && opts.TrustStoreSecret.Name !=
opts.PKCS12Secret.Name {
- mounts = append(mounts, corev1.VolumeMount{
- Name: "truststore",
- ReadOnly: true,
- MountPath: DefaultTrustStorePath,
- })
- }
-
- // We need an initContainer to convert a TLS cert into the pkcs12
format Java wants (using openssl)
- // but openssl cannot write to the /var/solr/tls directory because of
the way secret mounts work
- // so we need to mount an empty directory to write pkcs12 keystore into
- if createPkcs12InitContainer {
- mounts = append(mounts, corev1.VolumeMount{
- Name: "pkcs12",
- ReadOnly: false,
- MountPath: DefaultWritableKeyStorePath,
- })
- }
-
- return mounts
-}
-
-func tlsVolumes(opts *solr.SolrTLSOptions, createPkcs12InitContainer bool)
[]corev1.Volume {
- optional := false
- defaultMode := int32(0664)
- vols := []corev1.Volume{
- {
- Name: "keystore",
- VolumeSource: corev1.VolumeSource{
- Secret: &corev1.SecretVolumeSource{
- SecretName: opts.PKCS12Secret.Name,
- DefaultMode: &defaultMode,
- Optional: &optional,
- },
- },
- },
- }
-
- // if they're using a different truststore other than the keystore, but
don't mount an additional volume
- // if it's just pointing at the same secret
- if opts.TrustStoreSecret != nil && opts.TrustStoreSecret.Name !=
opts.PKCS12Secret.Name {
- vols = append(vols, corev1.Volume{
- Name: "truststore",
- VolumeSource: corev1.VolumeSource{
- Secret: &corev1.SecretVolumeSource{
- SecretName: opts.TrustStoreSecret.Name,
- DefaultMode: &defaultMode,
- Optional: &optional,
- },
- },
- })
- }
-
- if createPkcs12InitContainer {
- vols = append(vols, corev1.Volume{
- Name: "pkcs12",
- VolumeSource: corev1.VolumeSource{
- EmptyDir: &corev1.EmptyDirVolumeSource{},
- },
- })
- }
-
- return vols
-}
-
-func generatePkcs12InitContainer(opts *solr.SolrTLSOptions, imageName string,
imagePullPolicy corev1.PullPolicy) corev1.Container {
- // get the keystore password from the env for generating the keystore
using openssl
- passwordValueFrom := &corev1.EnvVarSource{SecretKeyRef:
opts.KeyStorePasswordSecret}
- envVars := []corev1.EnvVar{
- {
- Name: "SOLR_SSL_KEY_STORE_PASSWORD",
- ValueFrom: passwordValueFrom,
- },
- }
-
- cmd := "openssl pkcs12 -export -in " + DefaultKeyStorePath + "/" +
TLSCertKey + " -in " + DefaultKeyStorePath +
- "/ca.crt -inkey " + DefaultKeyStorePath + "/tls.key -out " +
DefaultKeyStorePath +
- "/pkcs12/" + DefaultPkcs12KeystoreFile + " -passout
pass:${SOLR_SSL_KEY_STORE_PASSWORD}"
- return corev1.Container{
- Name: "gen-pkcs12-keystore",
- Image: imageName,
- ImagePullPolicy: imagePullPolicy,
- TerminationMessagePath: "/dev/termination-log",
- TerminationMessagePolicy: "File",
- Command: []string{"sh", "-c", cmd},
- VolumeMounts: tlsVolumeMounts(opts, true),
- Env: envVars,
- }
-}
-
func createZkConnectionEnvVars(solrCloud *solr.SolrCloud, solrCloudStatus
*solr.SolrCloudStatus) (envVars []corev1.EnvVar, solrOpt string, hasChroot
bool) {
zkConnectionStr, zkServer, zkChroot := solrCloudStatus.DissectZkInfo()
envVars = []corev1.EnvVar{
@@ -1572,64 +1306,3 @@ func configureSecureProbeCommand(solrCloud
*solr.SolrCloud, defaultProbeGetActio
return probeCommand, vol, volMount
}
-
-func secureProbeTLSJavaToolOpts(tls *solr.SolrTLSOptions) (string, string) {
- tlsJavaToolOpts := ""
- tlsJavaSysProps := ""
- if tls != nil {
- tlsJavaSysProps = "-Djavax.net.ssl.keyStore=$SOLR_SSL_KEY_STORE
-Djavax.net.ssl.trustStore=$SOLR_SSL_TRUST_STORE"
-
- // If the keystore passwords are in a file, then we need to cat
the file(s) into JAVA_TOOL_OPTIONS
- if tls.MountedServerTLSDir != nil {
- tlsJavaToolOpts += "
-Djavax.net.ssl.keyStorePassword=$(cat " + MountedTLSKeystorePasswordPath(tls)
+ ")"
- tlsJavaToolOpts += "
-Djavax.net.ssl.trustStorePassword=$(cat " +
MountedTLSTruststorePasswordPath(tls) + ")"
- } else {
- tlsJavaSysProps += "
-Djavax.net.ssl.keyStorePassword=$SOLR_SSL_KEY_STORE_PASSWORD"
- tlsJavaSysProps += "
-Djavax.net.ssl.trustStorePassword=$SOLR_SSL_TRUST_STORE_PASSWORD"
- }
- }
- return tlsJavaToolOpts, tlsJavaSysProps
-}
-
-func mountedTLSKeystorePath(tls *solr.SolrTLSOptions) string {
- path := ""
- if tls.MountedServerTLSDir != nil {
- path = mountedTLSPath(tls.MountedServerTLSDir,
tls.MountedServerTLSDir.KeystoreFile, DefaultPkcs12KeystoreFile)
- }
- return path
-}
-
-func MountedTLSKeystorePasswordPath(tls *solr.SolrTLSOptions) string {
- path := ""
- if tls.MountedServerTLSDir != nil {
- path = mountedTLSPath(tls.MountedServerTLSDir,
tls.MountedServerTLSDir.KeystorePasswordFile, DefaultKeystorePasswordFile)
- }
- return path
-}
-
-func mountedTLSTruststorePath(tls *solr.SolrTLSOptions) string {
- path := ""
- if tls.MountedServerTLSDir != nil {
- path = mountedTLSPath(tls.MountedServerTLSDir,
tls.MountedServerTLSDir.TruststoreFile, DefaultPkcs12TruststoreFile)
- }
- return path
-}
-
-func MountedTLSTruststorePasswordPath(tls *solr.SolrTLSOptions) string {
- path := ""
- if tls.MountedServerTLSDir != nil {
- if tls.MountedServerTLSDir.TruststorePasswordFile != "" {
- path = mountedTLSPath(tls.MountedServerTLSDir,
tls.MountedServerTLSDir.TruststorePasswordFile, "")
- } else {
- path = MountedTLSKeystorePasswordPath(tls)
- }
- }
- return path
-}
-
-func mountedTLSPath(dir *solr.MountedTLSDirectory, fileName string,
defaultName string) string {
- if fileName == "" {
- fileName = defaultName
- }
- return fmt.Sprintf("%s/%s", dir.Path, fileName)
-}