diff --git a/controllers/barbican_controller.go b/controllers/barbican_controller.go index 3f341c8..8bdeca8 100644 --- a/controllers/barbican_controller.go +++ b/controllers/barbican_controller.go @@ -674,7 +674,6 @@ func (r *BarbicanReconciler) workerDeploymentCreateOrUpdate(ctx context.Context, } func (r *BarbicanReconciler) keystoneListenerDeploymentCreateOrUpdate(ctx context.Context, instance *barbicanv1beta1.Barbican, helper *helper.Helper) (*barbicanv1beta1.BarbicanKeystoneListener, controllerutil.OperationResult, error) { - Log := r.GetLogger(ctx) Log.Info(fmt.Sprintf("Creating barbican KeystoneListener spec. transporturlsecret: '%s'", instance.Status.TransportURLSecret)) Log.Info(fmt.Sprintf("database hostname: '%s'", instance.Status.DatabaseHostname)) diff --git a/controllers/barbicanapi_controller.go b/controllers/barbicanapi_controller.go index 064a297..e0889ba 100644 --- a/controllers/barbicanapi_controller.go +++ b/controllers/barbicanapi_controller.go @@ -303,7 +303,7 @@ func (r *BarbicanAPIReconciler) generateServiceConfigs( httpdVhostConfig := map[string]interface{}{} for _, endpt := range []service.Endpoint{service.EndpointInternal, service.EndpointPublic} { endptConfig := map[string]interface{}{} - endptConfig["ServerName"] = fmt.Sprintf("barbican-%s.%s.svc", endpt.String(), instance.Namespace) + endptConfig["ServerName"] = fmt.Sprintf("%s-%s.%s.svc", barbican.ServiceName, endpt.String(), instance.Namespace) endptConfig["TLS"] = false // default TLS to false, and set it bellow to true if enabled if instance.Spec.TLS.API.Enabled(endpt) { endptConfig["TLS"] = true @@ -785,7 +785,6 @@ func (r *BarbicanAPIReconciler) reconcileNormal(ctx context.Context, instance *b // SetupWithManager sets up the controller with the Manager. func (r *BarbicanAPIReconciler) SetupWithManager(mgr ctrl.Manager) error { - // index passwordSecretField if err := mgr.GetFieldIndexer().IndexField(context.Background(), &barbicanv1beta1.BarbicanAPI{}, passwordSecretField, func(rawObj client.Object) []string { // Extract the secret name from the spec, if one is provided diff --git a/go.mod b/go.mod index 2be1ea2..9b3db5d 100644 --- a/go.mod +++ b/go.mod @@ -19,6 +19,7 @@ require ( k8s.io/api v0.26.13 k8s.io/apimachinery v0.27.1 k8s.io/client-go v0.26.13 + k8s.io/utils v0.0.0-20240102154912-e7106e64919e sigs.k8s.io/controller-runtime v0.14.7 ) diff --git a/templates/barbican/config/barbican-api-config.json b/templates/barbican/config/barbican-api-config.json index 13b6fc1..f545011 100644 --- a/templates/barbican/config/barbican-api-config.json +++ b/templates/barbican/config/barbican-api-config.json @@ -1,73 +1,89 @@ { - "command": "/usr/sbin/httpd -DFOREGROUND", - "config_files": [ - { - "source": "/var/lib/config-data/default/00-default.conf", - "dest": "/etc/barbican/barbican.conf.d/00-default.conf", - "owner": "barbican", - "perm": "0600" - }, - { - "source": "/var/lib/config-data/default/02-service.conf", - "dest": "/etc/barbican/barbican.conf.d/02-service.conf", - "owner": "barbican", - "perm": "0600", - "optional": true - }, - { - "source": "/var/lib/config-data/default/03-secrets.conf", - "dest": "/etc/barbican/barbican.conf.d/03-secrets.conf", - "owner": "barbican", - "perm": "0640", - "optional": true - }, - { - "source": "/var/lib/config-data/default/10-barbican_wsgi_main.conf", - "dest": "/etc/httpd/conf.d/10-barbican_wsgi_main.conf", - "owner": "root", - "perm": "0640", - "optional": true - }, - { - "source": "/var/lib/config-data/default/httpd.conf", - "dest": "/etc/httpd/conf/httpd.conf", - "owner": "root", - "perm": "0640", - "optional": true - }, - { - "source": "/var/lib/config-data/default/main", - "dest": "/var/www/cgi-bin/barbican/main", - "owner": "barbican", - "perm": "0640", - "optional": true - }, - { - "source": "/var/lib/config-data/default/mime.conf", - "dest": "/etc/httpd/conf.modules.d/mime.conf", - "owner": "root", - "perm": "0640", - "optional": true - }, - { - "source": "/var/lib/config-data/default/kolla_extend_start", - "dest": "/usr/local/bin/kolla_extend_start", - "owner": "root", - "perm": "0755", - "optional": true - }, - { - "source": "/var/lib/config-data/default/ssl.conf", - "dest": "/etc/httpd/conf.d/ssl.conf", - "owner": "root", - "perm": "0644" - } - ], - "permissions": [ - { - "path": "/var/log/barbican", - "owner": "barbican:barbican", - "recurse": true - } - ] + "command": "/usr/sbin/httpd -DFOREGROUND", + "config_files": [ + { + "source": "/var/lib/config-data/default/00-default.conf", + "dest": "/etc/barbican/barbican.conf.d/00-default.conf", + "owner": "barbican", + "perm": "0600" + }, + { + "source": "/var/lib/config-data/default/02-service.conf", + "dest": "/etc/barbican/barbican.conf.d/02-service.conf", + "owner": "barbican", + "perm": "0600", + "optional": true + }, + { + "source": "/var/lib/config-data/default/03-secrets.conf", + "dest": "/etc/barbican/barbican.conf.d/03-secrets.conf", + "owner": "barbican", + "perm": "0640", + "optional": true + }, + { + "source": "/var/lib/config-data/default/10-barbican_wsgi_main.conf", + "dest": "/etc/httpd/conf.d/10-barbican_wsgi_main.conf", + "owner": "root", + "perm": "0640", + "optional": true + }, + { + "source": "/var/lib/config-data/default/httpd.conf", + "dest": "/etc/httpd/conf/httpd.conf", + "owner": "root", + "perm": "0640", + "optional": true + }, + { + "source": "/var/lib/config-data/default/main", + "dest": "/var/www/cgi-bin/barbican/main", + "owner": "barbican", + "perm": "0640", + "optional": true + }, + { + "source": "/var/lib/config-data/default/mime.conf", + "dest": "/etc/httpd/conf.modules.d/mime.conf", + "owner": "root", + "perm": "0640", + "optional": true + }, + { + "source": "/var/lib/config-data/default/kolla_extend_start", + "dest": "/usr/local/bin/kolla_extend_start", + "owner": "root", + "perm": "0755", + "optional": true + }, + { + "source": "/var/lib/config-data/default/ssl.conf", + "dest": "/etc/httpd/conf.d/ssl.conf", + "owner": "root", + "perm": "0644" + }, + { + "source": "/var/lib/config-data/tls/certs/*", + "dest": "/etc/pki/tls/certs/", + "owner": "root", + "perm": "0640", + "optional": true, + "merge": true + }, + { + "source": "/var/lib/config-data/tls/private/*", + "dest": "/etc/pki/tls/private/", + "owner": "root", + "perm": "0600", + "optional": true, + "merge": true + } + ], + "permissions": [ + { + "path": "/var/log/barbican", + "owner": "barbican:barbican", + "recurse": true + } + ] } diff --git a/tests/functional/barbican_controller_test.go b/tests/functional/barbican_controller_test.go index 62518a3..93bdd0d 100644 --- a/tests/functional/barbican_controller_test.go +++ b/tests/functional/barbican_controller_test.go @@ -1,62 +1,30 @@ -package functional_test +package functional import ( - "os" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + . "github.com/openstack-k8s-operators/lib-common/modules/common/test/helpers" + barbicanv1beta1 "github.com/openstack-k8s-operators/barbican-operator/api/v1beta1" condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition" - . "github.com/openstack-k8s-operators/lib-common/modules/common/test/helpers" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" ) var _ = Describe("Barbican controller", func() { - - var barbicanName types.NamespacedName - var barbicanTransportURL types.NamespacedName - var dbSyncJobName types.NamespacedName - var barbicanConfigMapData types.NamespacedName - - BeforeEach(func() { - - barbicanName = types.NamespacedName{ - Name: "barbican", - Namespace: namespace, - } - barbicanTransportURL = types.NamespacedName{ - Name: "barbican-barbican-transport", - Namespace: namespace, - } - dbSyncJobName = types.NamespacedName{ - Name: "barbican-db-sync", - Namespace: namespace, - } - barbicanConfigMapData = types.NamespacedName{ - Name: "barbican-config-data", - Namespace: namespace, - } - - err := os.Setenv("OPERATOR_TEMPLATES", "../../templates") - Expect(err).NotTo(HaveOccurred()) - - }) - When("A Barbican instance is created", func() { BeforeEach(func() { - DeferCleanup(th.DeleteInstance, CreateBarbican(barbicanName, GetDefaultBarbicanSpec())) + DeferCleanup(th.DeleteInstance, CreateBarbican(barbicanTest.Instance, GetDefaultBarbicanSpec())) }) It("should have the Spec fields defaulted", func() { - Barbican := GetBarbican(barbicanName) + Barbican := GetBarbican(barbicanTest.Instance) Expect(Barbican.Spec.ServiceUser).Should(Equal("barbican")) Expect(Barbican.Spec.DatabaseInstance).Should(Equal("openstack")) Expect(Barbican.Spec.DatabaseUser).Should(Equal("barbican")) }) It("should have the Status fields initialized", func() { - Barbican := GetBarbican(barbicanName) + Barbican := GetBarbican(barbicanTest.Instance) Expect(Barbican.Status.Hash).To(BeEmpty()) Expect(Barbican.Status.BarbicanAPIReadyCount).To(Equal(int32(0))) Expect(Barbican.Status.BarbicanWorkerReadyCount).To(Equal(int32(0))) @@ -67,14 +35,14 @@ var _ = Describe("Barbican controller", func() { It("should have input not ready and unknown Conditions initialized", func() { th.ExpectCondition( - barbicanName, + barbicanTest.Instance, ConditionGetterFunc(BarbicanConditionGetter), condition.ReadyCondition, corev1.ConditionFalse, ) th.ExpectCondition( - barbicanName, + barbicanTest.Instance, ConditionGetterFunc(BarbicanConditionGetter), condition.InputReadyCondition, corev1.ConditionUnknown, @@ -87,7 +55,7 @@ var _ = Describe("Barbican controller", func() { condition.NetworkAttachmentsReadyCondition, } { th.ExpectCondition( - barbicanName, + barbicanTest.Instance, ConditionGetterFunc(BarbicanConditionGetter), cond, corev1.ConditionUnknown, @@ -98,126 +66,179 @@ var _ = Describe("Barbican controller", func() { // the reconciler loop adds the finalizer so we have to wait for // it to run Eventually(func() []string { - return GetBarbican(barbicanName).Finalizers + return GetBarbican(barbicanTest.Instance).Finalizers }, timeout, interval).Should(ContainElement("Barbican")) }) It("should not create a config map", func() { Eventually(func() []corev1.ConfigMap { - return th.ListConfigMaps(barbicanConfigMapData.Name).Items + return th.ListConfigMaps(barbicanTest.BarbicanConfigMapData.Name).Items }, timeout, interval).Should(BeEmpty()) }) }) When("Barbican DB is created", func() { BeforeEach(func() { - DeferCleanup(k8sClient.Delete, ctx, CreateBarbicanMessageBusSecret(barbicanName.Namespace, "rabbitmq-secret")) - DeferCleanup(th.DeleteInstance, CreateBarbican(barbicanName, GetDefaultBarbicanSpec())) - DeferCleanup(k8sClient.Delete, ctx, CreateKeystoneAPISecret(namespace, SecretName)) + DeferCleanup(k8sClient.Delete, ctx, CreateBarbicanMessageBusSecret(barbicanTest.Instance.Namespace, "rabbitmq-secret")) + DeferCleanup(th.DeleteInstance, CreateBarbican(barbicanTest.Instance, GetDefaultBarbicanSpec())) + DeferCleanup(k8sClient.Delete, ctx, CreateKeystoneAPISecret(barbicanTest.Instance.Namespace, SecretName)) DeferCleanup( mariadb.DeleteDBService, mariadb.CreateDBService( - namespace, - GetBarbican(barbicanName).Spec.DatabaseInstance, + barbicanTest.Instance.Namespace, + GetBarbican(barbicanTest.Instance).Spec.DatabaseInstance, corev1.ServiceSpec{ Ports: []corev1.ServicePort{{Port: 3306}}, }, ), ) - infra.SimulateTransportURLReady(barbicanTransportURL) - DeferCleanup(keystone.DeleteKeystoneAPI, keystone.CreateKeystoneAPI(barbicanName.Namespace)) - //DeferCleanup(infra.DeleteMemcached, infra.CreateMemcached(namespace, "memcached", memcachedSpec)) + infra.SimulateTransportURLReady(barbicanTest.BarbicanTransportURL) + DeferCleanup(keystone.DeleteKeystoneAPI, keystone.CreateKeystoneAPI(barbicanTest.Instance.Namespace)) }) It("Should set DBReady Condition and set DatabaseHostname Status when DB is Created", func() { - mariadb.SimulateMariaDBDatabaseCompleted(barbicanName) - th.SimulateJobSuccess(dbSyncJobName) - Barbican := GetBarbican(barbicanName) + mariadb.SimulateMariaDBDatabaseCompleted(barbicanTest.Instance) + th.SimulateJobSuccess(barbicanTest.BarbicanDBSync) + Barbican := GetBarbican(barbicanTest.Instance) Expect(Barbican.Status.DatabaseHostname).To(Equal("hostname-for-openstack")) th.ExpectCondition( - barbicanName, + barbicanTest.Instance, ConditionGetterFunc(BarbicanConditionGetter), - condition.InputReadyCondition, + condition.DBReadyCondition, corev1.ConditionTrue, ) th.ExpectCondition( - barbicanName, + barbicanTest.Instance, ConditionGetterFunc(BarbicanConditionGetter), condition.DBSyncReadyCondition, corev1.ConditionFalse, ) }) It("Should fail if db-sync job fails when DB is Created", func() { - mariadb.SimulateMariaDBDatabaseCompleted(barbicanName) - th.SimulateJobFailure(dbSyncJobName) + mariadb.SimulateMariaDBDatabaseCompleted(barbicanTest.Instance) + th.SimulateJobFailure(barbicanTest.BarbicanDBSync) th.ExpectCondition( - barbicanName, + barbicanTest.Instance, ConditionGetterFunc(BarbicanConditionGetter), condition.DBReadyCondition, corev1.ConditionTrue, ) th.ExpectCondition( - barbicanName, + barbicanTest.Instance, ConditionGetterFunc(BarbicanConditionGetter), condition.DBSyncReadyCondition, corev1.ConditionFalse, ) }) It("Does not create BarbicanAPI", func() { - BarbicanAPINotExists(barbicanName) + BarbicanAPINotExists(barbicanTest.Instance) }) It("Does not create BarbicanWorker", func() { - BarbicanWorkerNotExists(barbicanName) + BarbicanWorkerNotExists(barbicanTest.Instance) }) It("Does not create BarbicanKeystoneListener", func() { - BarbicanKeystoneListenerNotExists(barbicanName) + BarbicanKeystoneListenerNotExists(barbicanTest.Instance) }) }) When("DB sync is completed", func() { BeforeEach(func() { - DeferCleanup(k8sClient.Delete, ctx, CreateBarbicanMessageBusSecret(barbicanName.Namespace, "rabbitmq-secret")) - DeferCleanup(th.DeleteInstance, CreateBarbican(barbicanName, GetDefaultBarbicanSpec())) - DeferCleanup(k8sClient.Delete, ctx, CreateKeystoneAPISecret(namespace, SecretName)) + DeferCleanup(k8sClient.Delete, ctx, CreateBarbicanMessageBusSecret(barbicanTest.Instance.Namespace, "rabbitmq-secret")) + DeferCleanup(th.DeleteInstance, CreateBarbican(barbicanTest.Instance, GetDefaultBarbicanSpec())) + DeferCleanup(k8sClient.Delete, ctx, CreateKeystoneAPISecret(barbicanTest.Instance.Namespace, SecretName)) DeferCleanup( - k8sClient.Delete, ctx, CreateBarbicanSecret(barbicanName.Namespace, "test-osp-secret-berbican")) + k8sClient.Delete, ctx, CreateBarbicanSecret(barbicanTest.Instance.Namespace, "test-osp-secret-barbican")) DeferCleanup( mariadb.DeleteDBService, mariadb.CreateDBService( - namespace, - GetBarbican(barbicanName).Spec.DatabaseInstance, + barbicanTest.Instance.Namespace, + GetBarbican(barbicanTest.Instance).Spec.DatabaseInstance, corev1.ServiceSpec{ Ports: []corev1.ServicePort{{Port: 3306}}, }, ), ) - infra.SimulateTransportURLReady(barbicanTransportURL) - DeferCleanup(keystone.DeleteKeystoneAPI, keystone.CreateKeystoneAPI(barbicanName.Namespace)) - mariadb.SimulateMariaDBDatabaseCompleted(barbicanName) - th.SimulateJobSuccess(dbSyncJobName) + infra.SimulateTransportURLReady(barbicanTest.BarbicanTransportURL) + DeferCleanup(keystone.DeleteKeystoneAPI, keystone.CreateKeystoneAPI(barbicanTest.Instance.Namespace)) + mariadb.SimulateMariaDBDatabaseCompleted(barbicanTest.Instance) + th.SimulateJobSuccess(barbicanTest.BarbicanDBSync) }) It("should have db sync ready condition", func() { th.ExpectCondition( - barbicanName, + barbicanTest.Instance, ConditionGetterFunc(BarbicanConditionGetter), condition.ReadyCondition, corev1.ConditionFalse, ) th.ExpectCondition( - barbicanName, + barbicanTest.Instance, ConditionGetterFunc(BarbicanConditionGetter), barbicanv1beta1.BarbicanRabbitMQTransportURLReadyCondition, corev1.ConditionTrue, ) th.ExpectCondition( - barbicanName, + barbicanTest.Instance, ConditionGetterFunc(BarbicanConditionGetter), condition.DBSyncReadyCondition, corev1.ConditionTrue, ) }) }) + When("A Barbican with TLS is created", func() { + BeforeEach(func() { + DeferCleanup(th.DeleteInstance, CreateBarbican(barbicanTest.Instance, GetTLSBarbicanSpec())) + DeferCleanup(k8sClient.Delete, ctx, CreateBarbicanMessageBusSecret(barbicanTest.Instance.Namespace, barbicanTest.RabbitmqSecretName)) + DeferCleanup(th.DeleteInstance, CreateBarbicanAPI(barbicanTest.Instance, GetTLSBarbicanAPISpec())) + DeferCleanup(k8sClient.Delete, ctx, CreateKeystoneAPISecret(barbicanTest.Instance.Namespace, SecretName)) + DeferCleanup( + mariadb.DeleteDBService, + mariadb.CreateDBService( + barbicanTest.Instance.Namespace, + GetBarbican(barbicanTest.Instance).Spec.DatabaseInstance, + corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{Port: 3306}}, + }, + ), + ) + infra.SimulateTransportURLReady(barbicanTest.BarbicanTransportURL) + DeferCleanup(keystone.DeleteKeystoneAPI, keystone.CreateKeystoneAPI(barbicanTest.Instance.Namespace)) + mariadb.SimulateMariaDBDatabaseCompleted(barbicanTest.Instance) + th.SimulateJobSuccess(barbicanTest.BarbicanDBSync) + }) + + It("Creates BarbicanAPI", func() { + DeferCleanup(k8sClient.Delete, ctx, th.CreateCABundleSecret(barbicanTest.CABundleSecret)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(barbicanTest.InternalCertSecret)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(barbicanTest.PublicCertSecret)) + keystone.SimulateKeystoneEndpointReady(barbicanTest.BarbicanKeystoneEndpoint) + + BarbicanAPIExists(barbicanTest.Instance) + + d := th.GetStatefulSet(barbicanTest.BarbicanAPI) + // Check the resulting deployment fields + Expect(int(*d.Spec.Replicas)).To(Equal(1)) + + Expect(d.Spec.Template.Spec.Volumes).To(HaveLen(9)) + Expect(d.Spec.Template.Spec.Containers).To(HaveLen(2)) + + // cert deployment volumes + th.AssertVolumeExists(barbicanTest.CABundleSecret.Name, d.Spec.Template.Spec.Volumes) + th.AssertVolumeExists(barbicanTest.InternalCertSecret.Name, d.Spec.Template.Spec.Volumes) + th.AssertVolumeExists(barbicanTest.PublicCertSecret.Name, d.Spec.Template.Spec.Volumes) + + // cert volumeMounts + container := d.Spec.Template.Spec.Containers[1] + th.AssertVolumeMountExists(barbicanTest.InternalCertSecret.Name, "tls.key", container.VolumeMounts) + th.AssertVolumeMountExists(barbicanTest.InternalCertSecret.Name, "tls.crt", container.VolumeMounts) + th.AssertVolumeMountExists(barbicanTest.PublicCertSecret.Name, "tls.key", container.VolumeMounts) + th.AssertVolumeMountExists(barbicanTest.PublicCertSecret.Name, "tls.crt", container.VolumeMounts) + th.AssertVolumeMountExists(barbicanTest.CABundleSecret.Name, "tls-ca-bundle.pem", container.VolumeMounts) + + Expect(container.ReadinessProbe.HTTPGet.Scheme).To(Equal(corev1.URISchemeHTTPS)) + Expect(container.LivenessProbe.HTTPGet.Scheme).To(Equal(corev1.URISchemeHTTPS)) + }) + }) }) diff --git a/tests/functional/barbican_test_data.go b/tests/functional/barbican_test_data.go new file mode 100644 index 0000000..e355f0e --- /dev/null +++ b/tests/functional/barbican_test_data.go @@ -0,0 +1,167 @@ +/* +Copyright 2023. + +Licensed 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 functional implements the envTest coverage for barbican-operator +package functional + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/types" +) + +type APIType string + +const ( + // BarbicanAPIInternal - + BarbicanAPITypeInternal APIType = "internal" + // BarbicanAPITypeExternal + BarbicanAPITypePublic APIType = "public" + // PublicCertSecretName - + PublicCertSecretName = "public-tls-certs" + // InternalCertSecretName - + InternalCertSecretName = "internal-tls-certs" + // CABundleSecretName - + CABundleSecretName = "combined-ca-bundle" +) + +// BarbicanTestData is the data structure used to provide input data to envTest +type BarbicanTestData struct { + BarbicanDatabaseUser string + BarbicanPassword string + BarbicanServiceUser string + ContainerImage string + DatabaseHostname string + DatabaseInstance string + RabbitmqClusterName string + RabbitmqSecretName string + Instance types.NamespacedName + Barbican types.NamespacedName + BarbicanDBSync types.NamespacedName + BarbicanAPI types.NamespacedName + BarbicanRole types.NamespacedName + BarbicanRoleBinding types.NamespacedName + BarbicanTransportURL types.NamespacedName + BarbicanSA types.NamespacedName + BarbicanKeystoneService types.NamespacedName + BarbicanKeystoneEndpoint types.NamespacedName + BarbicanServicePublic types.NamespacedName + BarbicanServiceInternal types.NamespacedName + BarbicanConfigSecret types.NamespacedName + BarbicanConfigScripts types.NamespacedName + BarbicanConfigMapData types.NamespacedName + BarbicanScheduler types.NamespacedName + InternalAPINAD types.NamespacedName + CABundleSecret types.NamespacedName + InternalCertSecret types.NamespacedName + PublicCertSecret types.NamespacedName +} + +// GetBarbicanTestData is a function that initialize the BarbicanTestData +// used in the test +func GetBarbicanTestData(barbicanName types.NamespacedName) BarbicanTestData { + m := barbicanName + return BarbicanTestData{ + Instance: m, + + Barbican: types.NamespacedName{ + Namespace: barbicanName.Namespace, + Name: barbicanName.Name, + }, + BarbicanDBSync: types.NamespacedName{ + Namespace: barbicanName.Namespace, + Name: fmt.Sprintf("%s-db-sync", barbicanName.Name), + }, + BarbicanAPI: types.NamespacedName{ + Namespace: barbicanName.Namespace, + Name: fmt.Sprintf("%s-api", barbicanName.Name), + }, + BarbicanRole: types.NamespacedName{ + Namespace: barbicanName.Namespace, + Name: fmt.Sprintf("barbican-%s-role", barbicanName.Name), + }, + BarbicanRoleBinding: types.NamespacedName{ + Namespace: barbicanName.Namespace, + Name: fmt.Sprintf("barbican-%s-rolebinding", barbicanName.Name), + }, + BarbicanTransportURL: types.NamespacedName{ + Namespace: barbicanName.Namespace, + Name: fmt.Sprintf("barbican-%s-transport", barbicanName.Name), + }, + BarbicanSA: types.NamespacedName{ + Namespace: barbicanName.Namespace, + Name: fmt.Sprintf("barbican-%s", barbicanName.Name), + }, + BarbicanKeystoneService: types.NamespacedName{ + Namespace: barbicanName.Namespace, + Name: barbicanName.Name, + }, + BarbicanKeystoneEndpoint: types.NamespacedName{ + Namespace: barbicanName.Namespace, + Name: barbicanName.Name, + }, + // Also used to identify BarbicanRoutePublic + BarbicanServicePublic: types.NamespacedName{ + Namespace: barbicanName.Namespace, + Name: fmt.Sprintf("%s-public", barbicanName.Name), + }, + BarbicanServiceInternal: types.NamespacedName{ + Namespace: barbicanName.Namespace, + Name: fmt.Sprintf("%s-internal", barbicanName.Name), + }, + BarbicanConfigSecret: types.NamespacedName{ + Namespace: barbicanName.Namespace, + Name: fmt.Sprintf("%s-%s", barbicanName.Name, "config-data"), + }, + BarbicanConfigScripts: types.NamespacedName{ + Namespace: barbicanName.Namespace, + Name: fmt.Sprintf("%s-%s", barbicanName.Name, "scripts"), + }, + BarbicanConfigMapData: types.NamespacedName{ + Namespace: barbicanName.Namespace, + Name: fmt.Sprintf("%s-%s", barbicanName.Name, "config-data"), + }, + BarbicanScheduler: types.NamespacedName{ + Namespace: barbicanName.Namespace, + Name: fmt.Sprintf("%s-scheduler", barbicanName.Name), + }, + InternalAPINAD: types.NamespacedName{ + Namespace: barbicanName.Namespace, + Name: "internalapi", + }, + CABundleSecret: types.NamespacedName{ + Namespace: barbicanName.Namespace, + Name: CABundleSecretName, + }, + InternalCertSecret: types.NamespacedName{ + Namespace: barbicanName.Namespace, + Name: InternalCertSecretName, + }, + PublicCertSecret: types.NamespacedName{ + Namespace: barbicanName.Namespace, + Name: PublicCertSecretName, + }, + RabbitmqClusterName: "rabbitmq", + RabbitmqSecretName: "rabbitmq-secret", + BarbicanDatabaseUser: "barbican", + DatabaseInstance: "openstack", + // Password used for both db and service + BarbicanPassword: "12345678", + BarbicanServiceUser: "barbican", + ContainerImage: "test://barbican", + DatabaseHostname: "database-hostname", + } +} diff --git a/tests/functional/base_test.go b/tests/functional/base_test.go index b9309fe..cb64aaf 100644 --- a/tests/functional/base_test.go +++ b/tests/functional/base_test.go @@ -14,10 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -package functional_test +package functional import ( "fmt" + "maps" + . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" @@ -47,7 +49,6 @@ func GetDefaultBarbicanSpec() map[string]interface{} { } func CreateBarbican(name types.NamespacedName, spec map[string]interface{}) client.Object { - raw := map[string]interface{}{ "apiVersion": "barbican.openstack.org/v1beta1", "kind": "Barbican", @@ -117,3 +118,81 @@ func BarbicanKeystoneListenerNotExists(name types.NamespacedName) { g.Expect(k8s_errors.IsNotFound(err)).To(BeTrue()) }, timeout, interval).Should(Succeed()) } + +// ========== TLS Stuff ============== +func BarbicanAPIConditionGetter(name types.NamespacedName) condition.Conditions { + instance := GetBarbicanAPI(name) + return instance.Status.Conditions +} + +func BarbicanAPIExists(name types.NamespacedName) { + Consistently(func(g Gomega) { + instance := &barbicanv1.BarbicanAPI{} + err := k8sClient.Get(ctx, name, instance) + g.Expect(k8s_errors.IsNotFound(err)).To(BeFalse()) + }, timeout, interval).Should(Succeed()) +} + +func GetBarbicanAPI(name types.NamespacedName) *barbicanv1.BarbicanAPI { + instance := &barbicanv1.BarbicanAPI{} + Eventually(func(g Gomega) { + g.Expect(k8sClient.Get(ctx, name, instance)).Should(Succeed()) + }, timeout, interval).Should(Succeed()) + return instance +} + +func GetTLSBarbicanSpec() map[string]interface{} { + return map[string]interface{}{ + "databaseInstance": "openstack", + "secret": SecretName, + "barbicanAPI": GetTLSBarbicanAPISpec(), + } +} + +func GetTLSBarbicanAPISpec() map[string]interface{} { + spec := GetDefaultBarbicanAPISpec() + maps.Copy(spec, map[string]interface{}{ + "tls": map[string]interface{}{ + "api": map[string]interface{}{ + "internal": map[string]interface{}{ + "secretName": InternalCertSecretName, + }, + "public": map[string]interface{}{ + "secretName": PublicCertSecretName, + }, + }, + "caBundleSecretName": CABundleSecretName, + }, + }) + return spec +} + +func GetDefaultBarbicanAPISpec() map[string]interface{} { + return map[string]interface{}{ + "secret": SecretName, + "replicas": 1, + "databaseHostname": barbicanTest.DatabaseHostname, + "databaseInstance": barbicanTest.DatabaseInstance, + "containerImage": barbicanTest.ContainerImage, + "serviceAccount": barbicanTest.BarbicanSA.Name, + "transportURLSecret": barbicanTest.RabbitmqSecretName, + } +} + +func CreateBarbicanAPI(name types.NamespacedName, spec map[string]interface{}) client.Object { + // we get the parent CR and set ownership to the barbicanAPI CR + raw := map[string]interface{}{ + "apiVersion": "barbican.openstack.org/v1beta1", + "kind": "BarbicanAPI", + "metadata": map[string]interface{}{ + "annotations": map[string]interface{}{ + "keystoneEndpoint": "true", + }, + "name": name.Name, + "namespace": name.Namespace, + }, + "spec": spec, + } + + return th.CreateUnstructured(raw) +} diff --git a/tests/functional/suite_test.go b/tests/functional/suite_test.go index a65d955..5638b5a 100644 --- a/tests/functional/suite_test.go +++ b/tests/functional/suite_test.go @@ -1,4 +1,4 @@ -package functional_test +package functional import ( "context" @@ -15,6 +15,7 @@ import ( . "github.com/onsi/gomega" "go.uber.org/zap/zapcore" + "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" @@ -44,17 +45,19 @@ import ( // http://onsi.github.io/ginkgo/ to learn more about Ginkgo. var ( - cfg *rest.Config - k8sClient client.Client - testEnv *envtest.Environment - ctx context.Context - cancel context.CancelFunc - logger logr.Logger - th *common_test.TestHelper - keystone *keystone_test.TestHelper - mariadb *mariadb_test.TestHelper - infra *infra_test.TestHelper - namespace string + cfg *rest.Config + k8sClient client.Client + testEnv *envtest.Environment + ctx context.Context + cancel context.CancelFunc + logger logr.Logger + th *common_test.TestHelper + keystone *keystone_test.TestHelper + mariadb *mariadb_test.TestHelper + infra *infra_test.TestHelper + namespace string + barbicanName types.NamespacedName + barbicanTest BarbicanTestData ) const ( @@ -138,6 +141,7 @@ var _ = BeforeSuite(func() { err = appsv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) + logger = ctrl.Log.WithName("---Test---") //+kubebuilder:scaffold:scheme k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) @@ -170,11 +174,6 @@ var _ = BeforeSuite(func() { kclient, err := kubernetes.NewForConfig(cfg) Expect(err).ToNot(HaveOccurred(), "failed to create kclient") - err = (&barbicanv1.Barbican{}).SetupWebhookWithManager(k8sManager) - Expect(err).NotTo(HaveOccurred()) - - barbicanv1.SetupDefaults() - err = (&controllers.BarbicanReconciler{ Client: k8sManager.GetClient(), Scheme: k8sManager.GetScheme(), @@ -182,6 +181,18 @@ var _ = BeforeSuite(func() { }).SetupWithManager(k8sManager) Expect(err).ToNot(HaveOccurred()) + err = (&controllers.BarbicanAPIReconciler{ + Client: k8sManager.GetClient(), + Scheme: k8sManager.GetScheme(), + Kclient: kclient, + }).SetupWithManager(k8sManager) + Expect(err).ToNot(HaveOccurred()) + + barbicanv1.SetupDefaults() + + err = (&barbicanv1.Barbican{}).SetupWebhookWithManager(k8sManager) + Expect(err).NotTo(HaveOccurred()) + go func() { defer GinkgoRecover() err = k8sManager.Start(ctx) @@ -216,5 +227,12 @@ var _ = BeforeEach(func() { th.CreateNamespace(namespace) // We still request the delete of the Namespace to properly cleanup if // we run the test in an existing cluster. + barbicanName = types.NamespacedName{ + Namespace: namespace, + Name: "barbican", + } + + barbicanTest = GetBarbicanTestData(barbicanName) + DeferCleanup(th.DeleteNamespace, namespace) })