diff --git a/go.mod b/go.mod index 03229d564..23738839f 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( k8s.io/api v0.26.9 k8s.io/apimachinery v0.26.9 k8s.io/client-go v0.26.9 + k8s.io/utils v0.0.0-20230726121419-3b25d923346b sigs.k8s.io/controller-runtime v0.14.6 ) @@ -78,7 +79,6 @@ require ( k8s.io/component-base v0.26.9 //indirect k8s.io/klog/v2 v2.100.1 // indirect k8s.io/kube-openapi v0.0.0-20230327201221-f5883ff37f0c //indirect - k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect diff --git a/test/functional/base_test.go b/test/functional/base_test.go index b19e7e084..f4f87ec18 100644 --- a/test/functional/base_test.go +++ b/test/functional/base_test.go @@ -77,28 +77,34 @@ func GetDefaultCinderSpec() map[string]interface{} { func GetDefaultCinderAPISpec() map[string]interface{} { return map[string]interface{}{ - "secret": SecretName, - "replicas": 1, - "containerImage": cinderTest.ContainerImage, - "serviceAccount": cinderTest.CinderSA.Name, + "secret": SecretName, + "replicas": 1, + "containerImage": cinderTest.ContainerImage, + "serviceAccount": cinderTest.CinderSA.Name, + "databaseHostname": cinderTest.DatabaseHostname, + "transportURLSecret": cinderTest.RabbitmqSecretName, } } func GetDefaultCinderSchedulerSpec() map[string]interface{} { return map[string]interface{}{ - "secret": SecretName, - "replicas": 1, - "containerImage": cinderTest.ContainerImage, - "serviceAccount": cinderTest.CinderSA.Name, + "secret": SecretName, + "replicas": 1, + "containerImage": cinderTest.ContainerImage, + "serviceAccount": cinderTest.CinderSA.Name, + "databaseHostname": cinderTest.DatabaseHostname, + "transportURLSecret": cinderTest.RabbitmqSecretName, } } func GetDefaultCinderVolumeSpec() map[string]interface{} { return map[string]interface{}{ - "secret": SecretName, - "replicas": 1, - "containerImage": cinderTest.ContainerImage, - "serviceAccount": cinderTest.CinderSA.Name, + "secret": SecretName, + "replicas": 1, + "containerImage": cinderTest.ContainerImage, + "serviceAccount": cinderTest.CinderSA.Name, + "databaseHostname": cinderTest.DatabaseHostname, + "transportURLSecret": cinderTest.RabbitmqSecretName, } } diff --git a/test/functional/cinder_controller_test.go b/test/functional/cinder_controller_test.go new file mode 100644 index 000000000..c9c5b95f4 --- /dev/null +++ b/test/functional/cinder_controller_test.go @@ -0,0 +1,434 @@ +/* +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 + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + . "github.com/openstack-k8s-operators/lib-common/modules/common/test/helpers" + corev1 "k8s.io/api/core/v1" + "k8s.io/utils/ptr" + + cinderv1 "github.com/openstack-k8s-operators/cinder-operator/api/v1beta1" + memcachedv1 "github.com/openstack-k8s-operators/infra-operator/apis/memcached/v1beta1" + condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition" + util "github.com/openstack-k8s-operators/lib-common/modules/common/util" +) + +var _ = Describe("Cinder controller", func() { + var memcachedSpec memcachedv1.MemcachedSpec + + BeforeEach(func() { + memcachedSpec = memcachedv1.MemcachedSpec{ + Replicas: ptr.To(int32(3)), + } + }) + + When("Cinder CR instance is created", func() { + BeforeEach(func() { + DeferCleanup(th.DeleteInstance, CreateCinder(cinderTest.Instance, GetDefaultCinderSpec())) + }) + It("initializes the status fields", func() { + Eventually(func(g Gomega) { + cinder := GetCinder(cinderName) + g.Expect(cinder.Status.Conditions).To(HaveLen(16)) + + g.Expect(cinder.Status.DatabaseHostname).To(Equal("")) + }, timeout*2, interval).Should(Succeed()) + }) + It("is not Ready", func() { + th.ExpectCondition( + cinderTest.Instance, + ConditionGetterFunc(CinderConditionGetter), + condition.ReadyCondition, + corev1.ConditionUnknown, + ) + }) + It("should have the Spec fields initialized", func() { + Cinder := GetCinder(cinderTest.Instance) + Expect(Cinder.Spec.DatabaseInstance).Should(Equal("openstack")) + Expect(Cinder.Spec.DatabaseUser).Should(Equal(cinderTest.CinderDataBaseUser)) + Expect(Cinder.Spec.MemcachedInstance).Should(Equal(cinderTest.MemcachedInstance)) + Expect(Cinder.Spec.RabbitMqClusterName).Should(Equal(cinderTest.RabbitmqClusterName)) + Expect(Cinder.Spec.ServiceUser).Should(Equal(cinderTest.CinderServiceUser)) + }) + It("should have the Status fields initialized", func() { + Cinder := GetCinder(cinderTest.Instance) + Expect(Cinder.Status.Hash).To(BeEmpty()) + Expect(Cinder.Status.DatabaseHostname).To(Equal("")) + Expect(Cinder.Status.TransportURLSecret).To(Equal("")) + Expect(Cinder.Status.CinderAPIReadyCount).To(Equal(int32(0))) + Expect(Cinder.Status.CinderBackupReadyCount).To(Equal(int32(0))) + Expect(Cinder.Status.CinderSchedulerReadyCount).To(Equal(int32(0))) + Expect(Cinder.Status.CinderVolumesReadyCounts["volume1"]).To(Equal(int32(0))) + Expect(Cinder.Status.CinderVolumesReadyCounts["volume2"]).To(Equal(int32(0))) + }) + It("should have Unknown Conditions initialized", func() { + for _, cond := range []condition.Type{ + condition.DBReadyCondition, + condition.DBSyncReadyCondition, + condition.InputReadyCondition, + condition.MemcachedReadyCondition, + cinderv1.CinderAPIReadyCondition, + cinderv1.CinderBackupReadyCondition, + cinderv1.CinderSchedulerReadyCondition, + cinderv1.CinderVolumeReadyCondition, + } { + th.ExpectCondition( + cinderTest.Cinder, + ConditionGetterFunc(CinderConditionGetter), + cond, + corev1.ConditionUnknown, + ) + } + }) + It("should have a finalizer", func() { + // the reconciler loop adds the finalizer so we have to wait for + // it to run + Eventually(func() []string { + return GetCinder(cinderTest.Instance).Finalizers + }, timeout, interval).Should(ContainElement("Cinder")) + }) + It("creates service account, role and rolebinding", func() { + th.ExpectCondition( + cinderName, + ConditionGetterFunc(CinderConditionGetter), + condition.ServiceAccountReadyCondition, + corev1.ConditionTrue, + ) + th.ExpectCondition( + cinderName, + ConditionGetterFunc(CinderConditionGetter), + condition.RoleReadyCondition, + corev1.ConditionTrue, + ) + role := th.GetRole(cinderTest.CinderRole) + Expect(role.Rules).To(HaveLen(2)) + Expect(role.Rules[0].Resources).To(Equal([]string{"securitycontextconstraints"})) + Expect(role.Rules[1].Resources).To(Equal([]string{"pods"})) + + th.ExpectCondition( + cinderName, + ConditionGetterFunc(CinderConditionGetter), + condition.RoleBindingReadyCondition, + corev1.ConditionTrue, + ) + + sa := th.GetServiceAccount(cinderTest.CinderSA) + + binding := th.GetRoleBinding(cinderTest.CinderRoleBinding) + Expect(binding.Subjects).To(HaveLen(1)) + Expect(binding.RoleRef.Name).To(Equal(role.Name)) + Expect(binding.Subjects[0].Name).To(Equal(sa.Name)) + }) + }) + When("Cinder DB is created", func() { + BeforeEach(func() { + DeferCleanup(k8sClient.Delete, ctx, CreateCinderMessageBusSecret(cinderTest.Instance.Namespace, cinderTest.RabbitmqSecretName)) + DeferCleanup(th.DeleteInstance, CreateCinder(cinderTest.Instance, GetDefaultCinderSpec())) + DeferCleanup( + mariadb.DeleteDBService, + mariadb.CreateDBService( + namespace, + GetCinder(cinderTest.Instance).Spec.DatabaseInstance, + corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{Port: 3306}}, + }, + ), + ) + infra.SimulateTransportURLReady(cinderTest.CinderTransportURL) + DeferCleanup(infra.DeleteMemcached, infra.CreateMemcached(namespace, cinderTest.MemcachedInstance, memcachedSpec)) + infra.SimulateMemcachedReady(cinderTest.CinderMemcached) + DeferCleanup(keystone.DeleteKeystoneAPI, keystone.CreateKeystoneAPI(namespace)) + }) + It("Should set DBReady Condition and set DatabaseHostname Status when DB is Created", func() { + mariadb.SimulateMariaDBDatabaseCompleted(cinderTest.Instance) + th.SimulateJobSuccess(cinderTest.CinderDBSync) + Cinder := GetCinder(cinderTest.Instance) + Expect(Cinder.Status.DatabaseHostname).To(Equal("hostname-for-openstack")) + th.ExpectCondition( + cinderName, + ConditionGetterFunc(CinderConditionGetter), + condition.DBReadyCondition, + corev1.ConditionTrue, + ) + th.ExpectCondition( + cinderName, + ConditionGetterFunc(CinderConditionGetter), + condition.DBSyncReadyCondition, + corev1.ConditionFalse, + ) + }) + It("Should fail if db-sync job fails when DB is Created", func() { + mariadb.SimulateMariaDBDatabaseCompleted(cinderTest.Instance) + th.SimulateJobFailure(cinderTest.CinderDBSync) + th.ExpectCondition( + cinderTest.Instance, + ConditionGetterFunc(CinderConditionGetter), + condition.DBReadyCondition, + corev1.ConditionTrue, + ) + th.ExpectCondition( + cinderTest.Instance, + ConditionGetterFunc(CinderConditionGetter), + condition.DBSyncReadyCondition, + corev1.ConditionFalse, + ) + }) + It("Does not create CinderAPI", func() { + CinderAPINotExists(cinderTest.Instance) + }) + It("Does not create CinderScheduler", func() { + CinderSchedulerNotExists(cinderTest.Instance) + }) + It("Does not create CinderVolume", func() { + CinderVolumeNotExists(cinderTest.Instance) + }) + }) + When("Both TransportURL secret and osp-secret are available", func() { + BeforeEach(func() { + DeferCleanup(th.DeleteInstance, CreateCinder(cinderTest.Instance, GetDefaultCinderSpec())) + DeferCleanup(k8sClient.Delete, ctx, CreateCinderMessageBusSecret(cinderTest.Instance.Namespace, cinderTest.RabbitmqSecretName)) + DeferCleanup(mariadb.DeleteDBService, mariadb.CreateDBService( + cinderTest.Instance.Namespace, + GetCinder(cinderName).Spec.DatabaseInstance, + corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{Port: 3306}}, + }, + ), + ) + infra.SimulateTransportURLReady(cinderTest.CinderTransportURL) + DeferCleanup(infra.DeleteMemcached, infra.CreateMemcached(namespace, "memcached", memcachedSpec)) + infra.SimulateMemcachedReady(cinderTest.CinderMemcached) + }) + It("should create config-data and scripts ConfigMaps", func() { + keystoneAPI := keystone.CreateKeystoneAPI(cinderTest.Instance.Namespace) + DeferCleanup(keystone.DeleteKeystoneAPI, keystoneAPI) + Eventually(func() corev1.Secret { + return th.GetSecret(cinderTest.CinderConfigSecret) + }, timeout, interval).ShouldNot(BeNil()) + Eventually(func() corev1.Secret { + return th.GetSecret(cinderTest.CinderConfigScripts) + }, timeout, interval).ShouldNot(BeNil()) + }) + }) + When("Cinder CR is created without container images defined", func() { + BeforeEach(func() { + // CinderEmptySpec is used to provide a standard Cinder CR where no + // field is customized + DeferCleanup(th.DeleteInstance, CreateCinder(cinderTest.Instance, GetCinderEmptySpec())) + }) + It("has the expected container image defaults", func() { + cinderDefault := GetCinder(cinderTest.Instance) + Expect(cinderDefault.Spec.CinderAPI.CinderServiceTemplate.ContainerImage).To(Equal(util.GetEnvVar("RELATED_IMAGE_CINDER_API_IMAGE_URL_DEFAULT", cinderv1.CinderAPIContainerImage))) + Expect(cinderDefault.Spec.CinderScheduler.CinderServiceTemplate.ContainerImage).To(Equal(util.GetEnvVar("RELATED_IMAGE_CINDER_SCHEDULER_IMAGE_URL_DEFAULT", cinderv1.CinderSchedulerContainerImage))) + for _, volume := range cinderDefault.Spec.CinderVolumes { + Expect(volume.ContainerImage).To(Equal(util.GetEnvVar("RELATED_IMAGE_CINDER_VOLUME_IMAGE_URL_DEFAULT", cinderv1.CinderVolumeContainerImage))) + } + }) + }) + When("All the Resources are ready", func() { + BeforeEach(func() { + DeferCleanup(th.DeleteInstance, CreateCinder(cinderTest.Instance, GetDefaultCinderSpec())) + DeferCleanup(k8sClient.Delete, ctx, CreateCinderMessageBusSecret(cinderTest.Instance.Namespace, cinderTest.RabbitmqSecretName)) + DeferCleanup(th.DeleteInstance, CreateCinderAPI(cinderTest.Instance, GetDefaultCinderAPISpec())) + DeferCleanup(th.DeleteInstance, CreateCinderScheduler(cinderTest.Instance, GetDefaultCinderSchedulerSpec())) + DeferCleanup(th.DeleteInstance, CreateCinderVolume(cinderTest.Instance, GetDefaultCinderVolumeSpec())) + DeferCleanup( + mariadb.DeleteDBService, + mariadb.CreateDBService( + cinderTest.Instance.Namespace, + GetCinder(cinderName).Spec.DatabaseInstance, + corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{Port: 3306}}, + }, + ), + ) + infra.SimulateTransportURLReady(cinderTest.CinderTransportURL) + DeferCleanup(infra.DeleteMemcached, infra.CreateMemcached(namespace, cinderTest.MemcachedInstance, memcachedSpec)) + infra.SimulateMemcachedReady(cinderTest.CinderMemcached) + DeferCleanup(keystone.DeleteKeystoneAPI, keystone.CreateKeystoneAPI(cinderTest.Instance.Namespace)) + mariadb.SimulateMariaDBDatabaseCompleted(cinderTest.Instance) + th.SimulateJobSuccess(cinderTest.CinderDBSync) + keystone.SimulateKeystoneServiceReady(cinderTest.CinderKeystoneService) + keystone.SimulateKeystoneEndpointReady(cinderTest.CinderKeystoneEndpoint) + }) + It("Creates CinderAPI", func() { + CinderAPIExists(cinderTest.Instance) + }) + It("Creates CinderScheduler", func() { + CinderSchedulerExists(cinderTest.Instance) + }) + It("Creates CinderVolume", func() { + CinderVolumeExists(cinderTest.Instance) + }) + It("Assert Services are created", func() { + th.AssertServiceExists(cinderTest.CinderServicePublic) + th.AssertServiceExists(cinderTest.CinderServiceInternal) + }) + }) + When("Cinder CR instance is deleted", func() { + BeforeEach(func() { + DeferCleanup(th.DeleteInstance, CreateCinder(cinderTest.Instance, GetDefaultCinderSpec())) + DeferCleanup(k8sClient.Delete, ctx, CreateCinderMessageBusSecret(cinderTest.Instance.Namespace, cinderTest.RabbitmqSecretName)) + DeferCleanup( + mariadb.DeleteDBService, + mariadb.CreateDBService( + cinderTest.Instance.Namespace, + GetCinder(cinderTest.Instance).Spec.DatabaseInstance, + corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{Port: 3306}}, + }, + ), + ) + infra.SimulateTransportURLReady(cinderTest.CinderTransportURL) + DeferCleanup(infra.DeleteMemcached, infra.CreateMemcached(namespace, cinderTest.MemcachedInstance, memcachedSpec)) + infra.SimulateMemcachedReady(cinderTest.CinderMemcached) + DeferCleanup(keystone.DeleteKeystoneAPI, keystone.CreateKeystoneAPI(cinderTest.Instance.Namespace)) + mariadb.SimulateMariaDBDatabaseCompleted(cinderTest.Instance) + th.SimulateJobSuccess(cinderTest.CinderDBSync) + }) + It("removes the finalizers from the Cinder DB", func() { + keystone.SimulateKeystoneServiceReady(cinderTest.CinderKeystoneService) + + mDB := mariadb.GetMariaDBDatabase(cinderTest.Instance) + Expect(mDB.Finalizers).To(ContainElement("Cinder")) + + th.DeleteInstance(GetCinder(cinderTest.Instance)) + + mDB = mariadb.GetMariaDBDatabase(cinderTest.Instance) + Expect(mDB.Finalizers).NotTo(ContainElement("Cinder")) + }) + }) + When("Cinder CR instance is built with NAD", func() { + BeforeEach(func() { + nad := th.CreateNetworkAttachmentDefinition(cinderTest.InternalAPINAD) + DeferCleanup(th.DeleteInstance, nad) + serviceOverride := map[string]interface{}{} + serviceOverride["internal"] = map[string]interface{}{ + "metadata": map[string]map[string]string{ + "annotations": { + "metallb.universe.tf/address-pool": "osp-internalapi", + "metallb.universe.tf/allow-volumed-ip": "osp-internalapi", + "metallb.universe.tf/loadBalancerIPs": "internal-lb-ip-1,internal-lb-ip-2", + }, + "labels": { + "internal": "true", + "service": "nova", + }, + }, + "spec": map[string]interface{}{ + "type": "LoadBalancer", + }, + } + + rawSpec := map[string]interface{}{ + "secret": SecretName, + "databaseInstance": "openstack", + "rabbitMqClusterName": "rabbitmq", + "cinderAPI": map[string]interface{}{ + "containerImage": cinderv1.CinderAPIContainerImage, + "networkAttachments": []string{"internalapi"}, + "override": map[string]interface{}{ + "service": serviceOverride, + }, + }, + "cinderScheduler": map[string]interface{}{ + "containerImage": cinderv1.CinderSchedulerContainerImage, + "networkAttachments": []string{"internalapi"}, + }, + "cinderVolumes": map[string]interface{}{ + "volume1": map[string]interface{}{ + "containerImage": cinderv1.CinderVolumeContainerImage, + "networkAttachments": []string{"internalapi"}, + }, + }, + } + DeferCleanup(th.DeleteInstance, CreateCinder(cinderTest.Instance, rawSpec)) + DeferCleanup(k8sClient.Delete, ctx, CreateCinderMessageBusSecret(cinderTest.Instance.Namespace, cinderTest.RabbitmqSecretName)) + DeferCleanup( + mariadb.DeleteDBService, + mariadb.CreateDBService( + cinderTest.Instance.Namespace, + GetCinder(cinderTest.Instance).Spec.DatabaseInstance, + corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{Port: 3306}}, + }, + ), + ) + infra.SimulateTransportURLReady(cinderTest.CinderTransportURL) + DeferCleanup(infra.DeleteMemcached, infra.CreateMemcached(namespace, cinderTest.MemcachedInstance, memcachedSpec)) + infra.SimulateMemcachedReady(cinderTest.CinderMemcached) + keystoneAPIName := keystone.CreateKeystoneAPI(cinderTest.Instance.Namespace) + DeferCleanup(keystone.DeleteKeystoneAPI, keystoneAPIName) + keystoneAPI := keystone.GetKeystoneAPI(keystoneAPIName) + keystoneAPI.Status.APIEndpoints["internal"] = "http://keystone-internal-openstack.testing" + Eventually(func(g Gomega) { + g.Expect(k8sClient.Status().Update(ctx, keystoneAPI.DeepCopy())).Should(Succeed()) + }, timeout, interval).Should(Succeed()) + mariadb.SimulateMariaDBDatabaseCompleted(cinderTest.Instance) + th.SimulateJobSuccess(cinderTest.CinderDBSync) + keystone.SimulateKeystoneServiceReady(cinderTest.CinderKeystoneService) + }) + It("Check the resulting endpoints of the generated sub-CRs", func() { + th.SimulateDeploymentReadyWithPods( + cinderTest.CinderAPI, + map[string][]string{cinderName.Namespace + "/internalapi": {"10.0.0.1"}}, + ) + th.SimulateStatefulSetReplicaReadyWithPods( + cinderTest.CinderScheduler, + map[string][]string{cinderName.Namespace + "/internalapi": {"10.0.0.1"}}, + ) + th.SimulateStatefulSetReplicaReadyWithPods( + cinderTest.CinderVolumes[0], + map[string][]string{cinderName.Namespace + "/internalapi": {"10.0.0.1"}}, + ) + keystone.SimulateKeystoneEndpointReady(cinderTest.CinderKeystoneEndpoint) + // Retrieve the generated resources + cinder := GetCinder(cinderTest.Instance) + api := GetCinderAPI(cinderTest.CinderAPI) + sched := GetCinderScheduler(cinderTest.CinderScheduler) + volume := GetCinderVolume(cinderTest.CinderVolumes[0]) + // Check CinderAPI NADs + Expect(api.Spec.NetworkAttachments).To(Equal(cinder.Spec.CinderAPI.CinderServiceTemplate.NetworkAttachments)) + // Check CinderScheduler NADs + Expect(sched.Spec.NetworkAttachments).To(Equal(cinder.Spec.CinderScheduler.CinderServiceTemplate.NetworkAttachments)) + // Check CinderVolume exists + CinderVolumeExists(cinderTest.CinderVolumes[0]) + // Check CinderVolume NADs + Expect(volume.Spec.NetworkAttachments).To(Equal(volume.Spec.CinderServiceTemplate.NetworkAttachments)) + + // As the internal endpoint has service override configured it + // gets a LoadBalancer Service with MetalLB annotations + service := th.GetService(cinderTest.CinderServiceInternal) + Expect(service.Spec.Type).To(Equal(corev1.ServiceTypeLoadBalancer)) + Expect(service.Annotations).To( + HaveKeyWithValue("dnsmasq.network.openstack.org/hostname", "cinder-internal."+cinder.Namespace+".svc")) + Expect(service.Annotations).To( + HaveKeyWithValue("metallb.universe.tf/address-pool", "osp-internalapi")) + Expect(service.Annotations).To( + HaveKeyWithValue("metallb.universe.tf/allow-volumed-ip", "osp-internalapi")) + Expect(service.Annotations).To( + HaveKeyWithValue("metallb.universe.tf/loadBalancerIPs", "internal-lb-ip-1,internal-lb-ip-2")) + + // check keystone endpoints + keystoneEndpoint := keystone.GetKeystoneEndpoint(cinderTest.CinderKeystoneEndpoint) + endpoints := keystoneEndpoint.Spec.Endpoints + Expect(endpoints).To(HaveKeyWithValue("public", "http://cinder-public."+cinder.Namespace+".svc:8776/v3")) + Expect(endpoints).To(HaveKeyWithValue("internal", "http://cinder-internal."+cinder.Namespace+".svc:8776/v3")) + }) + }) +}) diff --git a/test/functional/cinder_test_data.go b/test/functional/cinder_test_data.go index 04cac945e..10c1f1c0d 100644 --- a/test/functional/cinder_test_data.go +++ b/test/functional/cinder_test_data.go @@ -22,24 +22,34 @@ import ( "k8s.io/apimachinery/pkg/types" ) +const ( + // MemcachedInstance - name of the memcached instance + MemcachedInstance = "memcached" +) + // CinderTestData is the data structure used to provide input data to envTest type CinderTestData struct { RabbitmqClusterName string RabbitmqSecretName string + MemcachedInstance string CinderDataBaseUser string CinderPassword string CinderServiceUser string + DatabaseHostname string Instance types.NamespacedName CinderRole types.NamespacedName CinderRoleBinding types.NamespacedName CinderTransportURL types.NamespacedName + CinderMemcached types.NamespacedName CinderSA types.NamespacedName CinderDBSync types.NamespacedName + CinderKeystoneService types.NamespacedName CinderKeystoneEndpoint types.NamespacedName CinderServicePublic types.NamespacedName CinderServiceInternal types.NamespacedName CinderConfigSecret types.NamespacedName CinderConfigScripts types.NamespacedName + Cinder types.NamespacedName CinderAPI types.NamespacedName CinderScheduler types.NamespacedName CinderVolumes []types.NamespacedName @@ -55,6 +65,10 @@ func GetCinderTestData(cinderName types.NamespacedName) CinderTestData { return CinderTestData{ Instance: m, + Cinder: types.NamespacedName{ + Namespace: cinderName.Namespace, + Name: cinderName.Name, + }, CinderDBSync: types.NamespacedName{ Namespace: cinderName.Namespace, Name: fmt.Sprintf("%s-db-sync", cinderName.Name), @@ -93,6 +107,10 @@ func GetCinderTestData(cinderName types.NamespacedName) CinderTestData { Namespace: cinderName.Namespace, Name: fmt.Sprintf("cinder-%s-transport", cinderName.Name), }, + CinderMemcached: types.NamespacedName{ + Namespace: cinderName.Namespace, + Name: MemcachedInstance, + }, CinderConfigSecret: types.NamespacedName{ Namespace: cinderName.Namespace, Name: fmt.Sprintf("%s-%s", cinderName.Name, "config-data"), @@ -106,11 +124,14 @@ func GetCinderTestData(cinderName types.NamespacedName) CinderTestData { Namespace: cinderName.Namespace, Name: fmt.Sprintf("%s-public", cinderName.Name), }, - // Also used to identify CinderKeystoneService CinderServiceInternal: types.NamespacedName{ Namespace: cinderName.Namespace, Name: fmt.Sprintf("%s-internal", cinderName.Name), }, + CinderKeystoneService: types.NamespacedName{ + Namespace: cinderName.Namespace, + Name: fmt.Sprintf("%sv3", cinderName.Name), + }, CinderKeystoneEndpoint: types.NamespacedName{ Namespace: cinderName.Namespace, Name: fmt.Sprintf("%sv3", cinderName.Name), @@ -121,10 +142,12 @@ func GetCinderTestData(cinderName types.NamespacedName) CinderTestData { }, RabbitmqClusterName: "rabbitmq", RabbitmqSecretName: "rabbitmq-secret", + MemcachedInstance: MemcachedInstance, CinderDataBaseUser: "cinder", // Password used for both db and service CinderPassword: "12345678", CinderServiceUser: "cinder", ContainerImage: "test://cinder", + DatabaseHostname: "database-hostname", } } diff --git a/test/functional/suite_test.go b/test/functional/suite_test.go index f179947d2..c9680a8e4 100644 --- a/test/functional/suite_test.go +++ b/test/functional/suite_test.go @@ -45,6 +45,7 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + memcachedv1 "github.com/openstack-k8s-operators/infra-operator/apis/memcached/v1beta1" rabbitmqv1 "github.com/openstack-k8s-operators/infra-operator/apis/rabbitmq/v1beta1" infra_test "github.com/openstack-k8s-operators/infra-operator/apis/test/helpers" keystone_test "github.com/openstack-k8s-operators/keystone-operator/api/test/helpers" @@ -140,6 +141,8 @@ var _ = BeforeSuite(func() { Expect(err).NotTo(HaveOccurred()) err = mariadbv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) + err = memcachedv1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) err = rabbitmqv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) err = corev1.AddToScheme(scheme.Scheme)