diff --git a/modules/certmanager/go.mod b/modules/certmanager/go.mod index b0340cfd..da869569 100644 --- a/modules/certmanager/go.mod +++ b/modules/certmanager/go.mod @@ -6,10 +6,10 @@ require ( github.com/cert-manager/cert-manager v1.11.5 github.com/go-logr/logr v1.2.4 github.com/google/uuid v1.3.1 - github.com/onsi/ginkgo/v2 v2.12.1 + github.com/onsi/ginkgo/v2 v2.13.0 github.com/onsi/gomega v1.28.0 - github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230919113507-d74c2f31d216 - github.com/openstack-k8s-operators/lib-common/modules/test v0.1.2-0.20230919113507-d74c2f31d216 + github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20231009135225-e0907a2df5d8 + github.com/openstack-k8s-operators/lib-common/modules/test v0.3.1-0.20231009135225-e0907a2df5d8 go.uber.org/zap v1.26.0 k8s.io/api v0.26.9 k8s.io/apimachinery v0.26.9 diff --git a/modules/certmanager/go.sum b/modules/certmanager/go.sum index eef4e7f2..ea71ac58 100644 --- a/modules/certmanager/go.sum +++ b/modules/certmanager/go.sum @@ -228,8 +228,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/onsi/ginkgo/v2 v2.12.1 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA= -github.com/onsi/ginkgo/v2 v2.12.1/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.28.0 h1:i2rg/p9n/UqIDAMFUJ6qIUUMcsqOuUHgbpbu235Vr1c= github.com/onsi/gomega v1.28.0/go.mod h1:A1H2JE76sI14WIP57LMKj7FVfCHx3g3BcZVjJG8bjX8= github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7 h1:rncLxJBpFGqBztyxCMwNRnMjhhIDOWHJowi6q8G6koI= diff --git a/modules/common/go.mod b/modules/common/go.mod index e7183771..e5a4e79b 100644 --- a/modules/common/go.mod +++ b/modules/common/go.mod @@ -6,10 +6,11 @@ require ( github.com/go-logr/logr v1.2.4 github.com/google/uuid v1.3.1 github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.4.0 - github.com/onsi/ginkgo/v2 v2.12.1 + github.com/onsi/ginkgo/v2 v2.13.0 github.com/onsi/gomega v1.28.0 github.com/openshift/api v3.9.0+incompatible github.com/pkg/errors v0.9.1 + github.com/stretchr/testify v1.8.1 go.uber.org/zap v1.26.0 k8s.io/api v0.26.9 k8s.io/apimachinery v0.26.9 @@ -76,6 +77,7 @@ require ( require ( github.com/kr/pretty v0.3.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect ) diff --git a/modules/common/go.sum b/modules/common/go.sum index 2f3d80be..c6e27789 100644 --- a/modules/common/go.sum +++ b/modules/common/go.sum @@ -228,8 +228,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/onsi/ginkgo/v2 v2.12.1 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA= -github.com/onsi/ginkgo/v2 v2.12.1/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.28.0 h1:i2rg/p9n/UqIDAMFUJ6qIUUMcsqOuUHgbpbu235Vr1c= github.com/onsi/gomega v1.28.0/go.mod h1:A1H2JE76sI14WIP57LMKj7FVfCHx3g3BcZVjJG8bjX8= github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7 h1:rncLxJBpFGqBztyxCMwNRnMjhhIDOWHJowi6q8G6koI= diff --git a/modules/common/job/job.go b/modules/common/job/job.go index f8e52db6..ff94a15b 100644 --- a/modules/common/job/job.go +++ b/modules/common/job/job.go @@ -145,12 +145,13 @@ func (j *Job) DoJob( // Check if this job already exists // j.actualJob, err = GetJobWithName(ctx, h, j.expectedJob.Name, j.expectedJob.Namespace) - if err != nil && !k8s_errors.IsNotFound(err) { - return ctrl.Result{}, err - } exists := !k8s_errors.IsNotFound(err) + if err != nil && exists { + return ctrl.Result{}, fmt.Errorf("error getting existing job %s : %w", j.jobType, err) + } + // If the hash of the job not changed then we don't need to create or wait // for any jobs if !j.changed { @@ -290,10 +291,7 @@ func GetJobWithName( job := &batchv1.Job{} err := h.GetClient().Get(ctx, types.NamespacedName{Name: name, Namespace: namespace}, job) if err != nil { - if k8s_errors.IsNotFound(err) { - return job, err - } - h.GetLogger().Info("GetJobWithName err") + h.GetLogger().Info("GetJobWithName %s err: %w", name, err) return job, err } diff --git a/modules/common/tls/tls.go b/modules/common/tls/tls.go index 57be6da7..b8cfab79 100644 --- a/modules/common/tls/tls.go +++ b/modules/common/tls/tls.go @@ -21,7 +21,9 @@ package tls import ( "context" "fmt" + "strings" + "github.com/openstack-k8s-operators/lib-common/modules/common/deployment" "github.com/openstack-k8s-operators/lib-common/modules/common/helper" "github.com/openstack-k8s-operators/lib-common/modules/common/secret" corev1 "k8s.io/api/core/v1" @@ -77,6 +79,7 @@ func (t *TLS) CreateVolumeMounts() []corev1.VolumeMount { var volumeMounts []corev1.VolumeMount if t.Service != nil && t.Service.SecretName != "" { + fmt.Println("Creating tls-certs volume for:", t.Service.SecretName) volumeMounts = append(volumeMounts, corev1.VolumeMount{ Name: "tls-crt", MountPath: "/etc/pki/tls/certs/tls.crt", @@ -92,6 +95,7 @@ func (t *TLS) CreateVolumeMounts() []corev1.VolumeMount { } if t.Ca != nil && t.Ca.CaSecretName != "" { + fmt.Println("Creating ca-certs volume for:", t.Ca.CaSecretName) volumeMounts = append(volumeMounts, corev1.VolumeMount{ Name: "ca-certs", MountPath: "/etc/pki/ca-trust/extracted/pem", @@ -107,6 +111,7 @@ func (t *TLS) CreateVolumes() []corev1.Volume { var volumes []corev1.Volume if t.Service != nil && t.Service.SecretName != "" { + fmt.Println("Creating tls-certs volume mount for:", t.Service.SecretName) volumes = append(volumes, corev1.Volume{ Name: "tls-certs", VolumeSource: corev1.VolumeSource{ @@ -119,6 +124,8 @@ func (t *TLS) CreateVolumes() []corev1.Volume { } if t.Ca != nil && t.Ca.CaSecretName != "" { + fmt.Println("Creating ca-certs volume mount for:", t.Ca.CaSecretName) + volumes = append(volumes, corev1.Volume{ Name: "ca-certs", VolumeSource: corev1.VolumeSource{ @@ -132,3 +139,52 @@ func (t *TLS) CreateVolumes() []corev1.Volume { return volumes } + +// CreateDatabaseClientConfig - connection flags for the MySQL client +// Configures TLS connections for clients that use TLS certificates +// returns a string of mysql config statements +func (t *TLS) CreateDatabaseClientConfig() string { + conn := []string{} + // This assumes certificates are always injected in + // a common directory for all services + if t.Service.SecretName != "" { + conn = append(conn, + "ssl-cert=/etc/pki/tls/certs/tls.crt", + "ssl-key=/etc/pki/tls/private/tls.key") + } + // Client uses a CA certificate that gets merged + // into the pod's CA bundle by kolla_start + if t.Ca.CaSecretName != "" { + conn = append(conn, + "ssl-ca=/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem") + } + if len(conn) > 0 { + conn = append([]string{"ssl=1"}, conn...) + } + return strings.Join(conn, "\n") +} + +// UpdateDeploymentWithTLS updates a given deployment with the necessary volumes and volume mounts to support TLS configurations. +func (t *TLS) UpdateDeploymentWithTLS(ctx context.Context, d *deployment.Deployment, h *helper.Helper) error { + // Debug + if t.Service != nil { + fmt.Println("Service SecretName:", t.Service.SecretName) + } else { + fmt.Println("Service is nil") + } + + tlsVolumes := t.CreateVolumes() + fmt.Println("Generated TLS Volumes:", tlsVolumes) // Debug + + tlsVolumeMounts := t.CreateVolumeMounts() + fmt.Println("Generated TLS VolumeMounts:", tlsVolumeMounts) // Debug + + currentDeployment := d.GetDeployment() + currentDeployment.Spec.Template.Spec.Volumes = append(currentDeployment.Spec.Template.Spec.Volumes, tlsVolumes...) + for idx := range currentDeployment.Spec.Template.Spec.Containers { + currentDeployment.Spec.Template.Spec.Containers[idx].VolumeMounts = append(currentDeployment.Spec.Template.Spec.Containers[idx].VolumeMounts, tlsVolumeMounts...) + } + + _, err := d.CreateOrPatch(ctx, h) + return err +} diff --git a/modules/common/tls/tls_test.go b/modules/common/tls/tls_test.go index 79308bfb..10a57949 100644 --- a/modules/common/tls/tls_test.go +++ b/modules/common/tls/tls_test.go @@ -17,9 +17,46 @@ limitations under the License. package tls import ( + "context" + "os" + "strings" "testing" + "time" + + "github.com/openstack-k8s-operators/lib-common/modules/common/deployment" + "github.com/openstack-k8s-operators/lib-common/modules/common/helper" + "github.com/stretchr/testify/assert" + appsv1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + "sigs.k8s.io/controller-runtime/pkg/log" +) + +var ( + k8sClient client.Client ) +func TestMain(m *testing.M) { + t := &envtest.Environment{} + + cfg, err := t.Start() + if err != nil { + panic(err) + } + + k8sClient, err = client.New(cfg, client.Options{}) + if err != nil { + panic(err) + } + + code := m.Run() + + t.Stop() + + os.Exit(code) +} + func TestCreateVolumeMounts(t *testing.T) { tests := []struct { name string @@ -107,3 +144,104 @@ func TestCreateVolumes(t *testing.T) { }) } } + +func TestGenerateTLSConnectionConfig(t *testing.T) { + tests := []struct { + name string + service *Service + ca *Ca + wantStmts []string + excludeStmts []string + }{ + { + name: "No Secrets", + service: &Service{}, + ca: &Ca{}, + wantStmts: []string{}, + excludeStmts: []string{"ssl=1", "ssl-cert=", "ssl-key=", "ssl-ca="}, + }, + { + name: "Only TLS Secret", + service: &Service{SecretName: "test-tls-secret"}, + ca: &Ca{}, + wantStmts: []string{"ssl=1", "ssl-cert=", "ssl-key="}, + excludeStmts: []string{"ssl-ca="}, + }, + { + name: "Only CA Secret", + service: &Service{}, + ca: &Ca{CaSecretName: "test-ca1"}, + wantStmts: []string{"ssl=1", "ssl-ca="}, + excludeStmts: []string{"ssl-cert=", "ssl-key="}, + }, + { + name: "TLS and CA Secrets", + service: &Service{SecretName: "test-tls-secret"}, + ca: &Ca{CaSecretName: "test-ca1"}, + wantStmts: []string{"ssl=1", "ssl-cert=", "ssl-key=", "ssl-ca="}, + excludeStmts: []string{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tlsInstance := &TLS{Service: tt.service, Ca: tt.ca} + configStr := tlsInstance.CreateDatabaseClientConfig() + var missingStmts []string + for _, stmt := range tt.wantStmts { + if !strings.Contains(configStr, stmt) { + missingStmts = append(missingStmts, stmt) + } + } + var unexpectedStmts []string + for _, stmt := range tt.excludeStmts { + if strings.Contains(configStr, stmt) { + unexpectedStmts = append(unexpectedStmts, stmt) + } + } + if len(missingStmts) != 0 || len(unexpectedStmts) != 0 { + t.Errorf("CreateDatabaseClientConfig() "+ + "missing statements: %v, unexpected statements: %v", + missingStmts, unexpectedStmts) + } + }) + } +} + +func TestUpdateDeploymentWithTLS(t *testing.T) { + assert := assert.New(t) + + dep := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-deployment", + Namespace: "default", + }, + } + + customDeployment := deployment.NewDeployment(dep, time.Second*30) + + tlsObj := &TLS{ + Service: &Service{ + SecretName: "tls-secret-name", + }, + Ca: &Ca{ + CaSecretName: "ca-secret-name", + }, + } + + logger := log.Log.WithName("test-logger") + + helperObj, err := helper.NewHelper(dep, k8sClient, nil, k8sClient.Scheme(), logger) + if err != nil { + t.Fatalf("failed to create helper: %v", err) + } + + err = tlsObj.UpdateDeploymentWithTLS(context.Background(), customDeployment, helperObj) + assert.Nil(err, "failed to update deployment with TLS") + + updatedDep := &appsv1.Deployment{} + err = k8sClient.Get(context.Background(), client.ObjectKey{Name: "test-deployment", Namespace: "default"}, updatedDep) + assert.Nil(err, "failed to get updated deployment") + + assert.NotZero(len(updatedDep.Spec.Template.Spec.Volumes), "expected TLS volumes to be added but found none") +} diff --git a/modules/openstack/go.mod b/modules/openstack/go.mod index ce7cd2ba..7828c71c 100644 --- a/modules/openstack/go.mod +++ b/modules/openstack/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/go-logr/logr v1.2.4 github.com/gophercloud/gophercloud v1.7.0 - github.com/openstack-k8s-operators/lib-common/modules/common v0.1.1-0.20230919113507-d74c2f31d216 + github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20231009135225-e0907a2df5d8 ) require ( diff --git a/modules/openstack/go.sum b/modules/openstack/go.sum index aeeeaae4..7a36fe5f 100644 --- a/modules/openstack/go.sum +++ b/modules/openstack/go.sum @@ -220,7 +220,7 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/onsi/ginkgo/v2 v2.12.1 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= github.com/onsi/gomega v1.28.0 h1:i2rg/p9n/UqIDAMFUJ6qIUUMcsqOuUHgbpbu235Vr1c= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/modules/storage/go.mod b/modules/storage/go.mod index 9bf65af6..f44bb8e5 100644 --- a/modules/storage/go.mod +++ b/modules/storage/go.mod @@ -8,7 +8,7 @@ require ( ) require ( - github.com/onsi/ginkgo/v2 v2.12.1 // indirect + github.com/onsi/ginkgo/v2 v2.13.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect golang.org/x/tools v0.13.0 // indirect ) diff --git a/modules/storage/go.sum b/modules/storage/go.sum index 2f4fcbb4..906e69f9 100644 --- a/modules/storage/go.sum +++ b/modules/storage/go.sum @@ -35,8 +35,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/onsi/ginkgo/v2 v2.12.1 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA= -github.com/onsi/ginkgo/v2 v2.12.1/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.28.0 h1:i2rg/p9n/UqIDAMFUJ6qIUUMcsqOuUHgbpbu235Vr1c= github.com/onsi/gomega v1.28.0/go.mod h1:A1H2JE76sI14WIP57LMKj7FVfCHx3g3BcZVjJG8bjX8= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= diff --git a/modules/test/go.sum b/modules/test/go.sum index 219599f4..9612558b 100644 --- a/modules/test/go.sum +++ b/modules/test/go.sum @@ -110,7 +110,7 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.12.1 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= github.com/onsi/gomega v1.28.0 h1:i2rg/p9n/UqIDAMFUJ6qIUUMcsqOuUHgbpbu235Vr1c= github.com/onsi/gomega v1.28.0/go.mod h1:A1H2JE76sI14WIP57LMKj7FVfCHx3g3BcZVjJG8bjX8= github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7 h1:rncLxJBpFGqBztyxCMwNRnMjhhIDOWHJowi6q8G6koI=