thelabdude commented on a change in pull request #312:
URL: https://github.com/apache/solr-operator/pull/312#discussion_r699689067



##########
File path: controllers/solrcloud_controller.go
##########
@@ -960,80 +950,160 @@ func (r *SolrCloudReconciler) 
indexAndWatchForTLSSecret(mgr ctrl.Manager, ctrlBu
 
        return ctrlBuilder.Watches(
                &source.Kind{Type: &corev1.Secret{}},
-               &handler.EnqueueRequestsFromMapFunc{
-                       ToRequests: handler.ToRequestsFunc(func(a 
handler.MapObject) []reconcile.Request {
-                               foundClouds := &solr.SolrCloudList{}
-                               listOps := &client.ListOptions{
-                                       FieldSelector: 
fields.OneTermEqualSelector(".spec.solrTLS.pkcs12Secret", a.Meta.GetName()),
-                                       Namespace:     a.Meta.GetNamespace(),
-                               }
-                               err := r.List(context.TODO(), foundClouds, 
listOps)
-                               if err != nil {
-                                       return []reconcile.Request{}
-                               }
+               r.findSolrCloudByFieldValueFunc(field),
+               
builder.WithPredicates(predicate.ResourceVersionChangedPredicate{})), nil
+}
 
-                               requests := make([]reconcile.Request, 
len(foundClouds.Items))
-                               for i, item := range foundClouds.Items {
-                                       requests[i] = reconcile.Request{
-                                               NamespacedName: 
types.NamespacedName{
-                                                       Name:      
item.GetName(),
-                                                       Namespace: 
item.GetNamespace(),
-                                               },
-                                       }
-                               }
-                               return requests
-                       }),
-               },
+func (r *SolrCloudReconciler) indexAndWatchForClientTLSSecret(mgr 
ctrl.Manager, ctrlBuilder *builder.Builder) (*builder.Builder, error) {
+       field := ".spec.solrClientTLS.pkcs12Secret"
+       if err := mgr.GetFieldIndexer().IndexField(context.TODO(), 
&solr.SolrCloud{}, field, func(rawObj runtime.Object) []string {
+               // grab the SolrCloud object, extract the used configMap...
+               solrCloud := rawObj.(*solr.SolrCloud)
+               if solrCloud.Spec.SolrClientTLS == nil || 
solrCloud.Spec.SolrClientTLS.PKCS12Secret == nil {
+                       return nil
+               }
+               // ...and if so, return it
+               return []string{solrCloud.Spec.SolrClientTLS.PKCS12Secret.Name}
+       }); err != nil {
+               return ctrlBuilder, err
+       }
+
+       return ctrlBuilder.Watches(
+               &source.Kind{Type: &corev1.Secret{}},
+               r.findSolrCloudByFieldValueFunc(field),
                
builder.WithPredicates(predicate.ResourceVersionChangedPredicate{})), nil
 }
 
+func (r *SolrCloudReconciler) findSolrCloudByFieldValueFunc(field string) 
*handler.EnqueueRequestsFromMapFunc {
+       return &handler.EnqueueRequestsFromMapFunc{
+               ToRequests: handler.ToRequestsFunc(func(a handler.MapObject) 
[]reconcile.Request {
+                       foundClouds := &solr.SolrCloudList{}
+                       listOps := &client.ListOptions{
+                               FieldSelector: 
fields.OneTermEqualSelector(field, a.Meta.GetName()),
+                               Namespace:     a.Meta.GetNamespace(),
+                       }
+                       err := r.List(context.TODO(), foundClouds, listOps)
+                       if err != nil {
+                               return []reconcile.Request{}
+                       }
+
+                       requests := make([]reconcile.Request, 
len(foundClouds.Items))
+                       for i, item := range foundClouds.Items {
+                               requests[i] = reconcile.Request{
+                                       NamespacedName: types.NamespacedName{
+                                               Name:      item.GetName(),
+                                               Namespace: item.GetNamespace(),
+                                       },
+                               }
+                       }
+                       return requests
+               }),
+       }
+}
+
 // 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
+func (r *SolrCloudReconciler) reconcileTLSConfig(instance *solr.SolrCloud) 
(*util.TLSCerts, error) {
+       tls := util.TLSCertsForSolrCloud(instance)
 
        // 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 {
+       serverCert := tls.ServerConfig.Options
+       if serverCert.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")
+               if serverCert.MountedTLSDir != nil {
+                       return nil, fmt.Errorf("invalid TLS config, either 
supply `solrTLS.pkcs12Secret` or `solrTLS.mountedTLSDir` but not both")
                }
 
-               foundTLSSecret, err := 
r.verifyTLSSecretConfig(instance.Spec.SolrTLS.PKCS12Secret.Name, 
instance.Namespace, instance.Spec.SolrTLS.KeyStorePasswordSecret)
+               foundTLSSecret, err := 
r.verifyTLSSecretConfig(serverCert.PKCS12Secret.Name, instance.Namespace, 
serverCert.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 serverCert.RestartOnTLSSecretUpdate {
+                               tls.ServerConfig.CertMd5, err = 
r.computeCertMd5(foundTLSSecret)
+                               if err != nil {
+                                       return nil, err
                                }
+                               tls.ServerConfig.CertMd5Annotation = 
util.SolrTlsCertMd5Annotation
                        }
 
-                       if _, ok := 
foundTLSSecret.Data[instance.Spec.SolrTLS.PKCS12Secret.Key]; !ok {
+                       if _, ok := 
foundTLSSecret.Data[serverCert.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
+                               tls.ServerConfig.NeedsPkcs12InitContainer = true
                        }
                }
 
-               if instance.Spec.SolrTLS.TrustStoreSecret != nil {
+               if serverCert.TrustStoreSecret != nil {
                        // verify the TrustStore secret is configured correctly
-                       passwordSecret := 
instance.Spec.SolrTLS.TrustStorePasswordSecret
-                       if passwordSecret == nil {
-                               passwordSecret = 
instance.Spec.SolrTLS.KeyStorePasswordSecret
+                       err = r.verifyTruststoreConfig(serverCert, 
instance.Namespace)
+                       if err != nil {
+                               return nil, err
+                       }
+               } else {
+                       // does the supplied keystore secret also contain the 
truststore?
+                       if _, ok := 
foundTLSSecret.Data[util.DefaultPkcs12TruststoreFile]; ok {
+                               // there's a truststore in the supplied TLS 
secret
+                               serverCert.TrustStoreSecret = 
&corev1.SecretKeySelector{
+                                       LocalObjectReference: 
corev1.LocalObjectReference{Name: foundTLSSecret.Name},
+                                       Key:                  
util.DefaultPkcs12TruststoreFile,
+                               }
+                               serverCert.TrustStorePasswordSecret = 
serverCert.KeyStorePasswordSecret
                        }
-                       _, err := 
r.verifyTLSSecretConfig(instance.Spec.SolrTLS.TrustStoreSecret.Name, 
instance.Namespace, passwordSecret)
+               }
+
+               // is there a client TLS config too?
+               if tls.ClientConfig != nil {
+                       if tls.ClientConfig.Options.PKCS12Secret == nil {
+                               // cannot mix options with the client cert, if 
the server cert comes from a secret, so too must the client, not a mountedTLSDir
+                               return nil, fmt.Errorf("invalid TLS config, the 
'solrClientTLS.pkcs12Secret' option is required when using a secret for server 
cert")
+                       }
+
+                       clientOpts := tls.ClientConfig.Options
+                       // shouldn't configure a client cert if it's the same 
as the server cert
+                       if clientOpts.PKCS12Secret == 
tls.ServerConfig.Options.PKCS12Secret {
+                               return nil, fmt.Errorf("invalid TLS config, the 
'solrClientTLS.pkcs12Secret' option should not be the same as the 
'solrTLS.pkcs12Secret'")

Review comment:
       Probably not an issue for Solr but seemed like that would be a 
mis-configuration / accident by the user since it wouldn't be sensible to use 
the same cert for the client & server (you don't need a separate client in that 
case) so I felt raising an error would help draw attention to a mistake.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscr...@solr.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscr...@solr.apache.org
For additional commands, e-mail: issues-h...@solr.apache.org

Reply via email to