diff --git a/api/go.mod b/api/go.mod index 97d609de..73d0a4bb 100644 --- a/api/go.mod +++ b/api/go.mod @@ -71,3 +71,5 @@ require ( // mschuppert: map to latest commit from release-4.18 tag // must consistent within modules and service operators replace github.com/openshift/api => github.com/openshift/api v0.0.0-20250711200046-c86d80652a9e //allow-merging + +replace github.com/openstack-k8s-operators/lib-common/modules/common => github.com/fmount/lib-common/modules/common v0.0.0-20250924115659-e582f0463eb1 diff --git a/api/go.sum b/api/go.sum index d328697c..66e72435 100644 --- a/api/go.sum +++ b/api/go.sum @@ -12,6 +12,8 @@ github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/fmount/lib-common/modules/common v0.0.0-20250924115659-e582f0463eb1 h1:KP/STzbdVe18nbnklg3LVxyNe7PXrdAnJhmXp3UqJtw= +github.com/fmount/lib-common/modules/common v0.0.0-20250924115659-e582f0463eb1/go.mod h1:SmKRclrynSSRCXSLOoWlETalJPvt62ObHsfW8iPvtDA= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= @@ -75,8 +77,6 @@ github.com/openshift/api v0.0.0-20250711200046-c86d80652a9e h1:E1OdwSpqWuDPCedyU github.com/openshift/api v0.0.0-20250711200046-c86d80652a9e/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo= github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20250922155301-057562fb7182 h1:Ea+FZQOW0Eha1jorgSECFeqI9UrKz8TZlGnSM7X8Yf4= github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20250922155301-057562fb7182/go.mod h1:3Im8PFiRKPaOZpOuqYShJRN2O2pfjUuhDTUpW4KMHZw= -github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20250922082314-c83d83092a04 h1:JqJd39rF8rD9KIHmOEFbHP8UyYgttfuouj+kAFNtymU= -github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20250922082314-c83d83092a04/go.mod h1:SmKRclrynSSRCXSLOoWlETalJPvt62ObHsfW8iPvtDA= github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20250922082314-c83d83092a04 h1:j5P/ehO4bQ+VqNvqNiX7N/R8wnBweFy7MX685nh4mmY= github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20250922082314-c83d83092a04/go.mod h1:WbDAhyvX2UTyK9LzYZKjRvEGdn2fsQJHUo5l2J5q/vg= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= diff --git a/controllers/glanceapi_controller.go b/controllers/glanceapi_controller.go index 2ec65f2c..789ece04 100644 --- a/controllers/glanceapi_controller.go +++ b/controllers/glanceapi_controller.go @@ -687,6 +687,7 @@ func (r *GlanceAPIReconciler) reconcileNormal( configVars := make(map[string]env.Setter) privileged := false imageConv := false + extConfigOptions := []util.IniOption{} // // check for required OpenStack secret holding passwords for service/admin user and add hash to the vars map @@ -758,7 +759,7 @@ func (r *GlanceAPIReconciler) reconcileNormal( } } // iterate over availableBackends for backend specific cases - for i := 0; i < len(availableBackends); i++ { + for i := range availableBackends { backendToken := strings.SplitN(availableBackends[i], ":", 2) switch backendToken[1] { case "cinder": @@ -797,6 +798,16 @@ func (r *GlanceAPIReconciler) reconcileNormal( // enable image conversion by default Log.Info("Ceph config detected: enable image conversion by default") imageConv = true + case "s3": + Log.Info(fmt.Sprintf( + "s3 config detected: inject s3_store_cacert parameter to backend %s\n", backendToken[0])) + if instance.Spec.TLS.CaBundleSecretName != "" { + extConfigOptions = append(extConfigOptions, util.IniOption{ + Section: backendToken[0], + Key: "s3_store_cacert", + Value: "/etc/pki/tls/certs/ca-bundle.crt", + }) + } } } // If we reach this point, it means that either Cinder is not a backend for Glance @@ -907,7 +918,8 @@ func (r *GlanceAPIReconciler) reconcileNormal( } // Generate service config - err = r.generateServiceConfig(ctx, helper, instance, &configVars, imageConv, memcached, wsgi) + err = r.generateServiceConfig(ctx, helper, instance, &configVars, + imageConv, memcached, wsgi, extConfigOptions) if err != nil { instance.Status.Conditions.Set(condition.FalseCondition( condition.ServiceConfigReadyCondition, @@ -1143,8 +1155,11 @@ func (r *GlanceAPIReconciler) generateServiceConfig( imageConv bool, memcached *memcachedv1.Memcached, wsgi bool, + extConfigOptions []util.IniOption, ) error { + Log := r.GetLogger(ctx) labels := labels.GetLabels(instance, labels.GetGroupLabel(glance.ServiceName), GetServiceLabels(instance)) + extendedConfig := instance.Spec.CustomServiceConfig db, err := mariadbv1.GetDatabaseByNameAndAccount(ctx, h, glance.DatabaseName, instance.Spec.DatabaseAccount, instance.Namespace) if err != nil { @@ -1155,9 +1170,18 @@ func (r *GlanceAPIReconciler) generateServiceConfig( if instance.Spec.TLS.CaBundleSecretName != "" { tlsCfg = &tls.Service{} } + // extend customServiceConfig is []IniOption has elements + for _, opt := range extConfigOptions { + extendedConfig, err = util.ExtendCustomServiceConfig(extendedConfig, opt) + if err != nil { + // The error returned from this library is not blocking, but it is + // useful to log it for troubleshooting purposes + Log.Info(err.Error()) + } + } // 02-config.conf customData := map[string]string{ - glance.CustomServiceConfigFileName: instance.Spec.CustomServiceConfig, + glance.CustomServiceConfigFileName: extendedConfig, "my.cnf": db.GetDatabaseClientConfig(tlsCfg), //(mschuppert) for now just get the default my.cnf } diff --git a/go.mod b/go.mod index c1924259..e19e35fe 100644 --- a/go.mod +++ b/go.mod @@ -94,3 +94,5 @@ replace github.com/openshift/api => github.com/openshift/api v0.0.0-202507112000 // custom RabbitmqClusterSpecCore for OpenStackControlplane (v2.6.0_patches_tag) replace github.com/rabbitmq/cluster-operator/v2 => github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20250717122149-12f70b7f3d8d //allow-merging + +replace github.com/openstack-k8s-operators/lib-common/modules/common => github.com/fmount/lib-common/modules/common v0.0.0-20250924115659-e582f0463eb1 diff --git a/go.sum b/go.sum index 53aebd93..7230c2a0 100644 --- a/go.sum +++ b/go.sum @@ -12,6 +12,8 @@ github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/fmount/lib-common/modules/common v0.0.0-20250924115659-e582f0463eb1 h1:KP/STzbdVe18nbnklg3LVxyNe7PXrdAnJhmXp3UqJtw= +github.com/fmount/lib-common/modules/common v0.0.0-20250924115659-e582f0463eb1/go.mod h1:SmKRclrynSSRCXSLOoWlETalJPvt62ObHsfW8iPvtDA= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= @@ -85,8 +87,6 @@ github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20250922155301-0 github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20250922155301-057562fb7182/go.mod h1:3Im8PFiRKPaOZpOuqYShJRN2O2pfjUuhDTUpW4KMHZw= github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20250916093250-82a76386143d h1:lSRMftk/MbN4qd8ihHh9ucdX4sfR/HUudEcy2h/BNhQ= github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20250916093250-82a76386143d/go.mod h1:7ZuNZNtwRYklS2H5E5YSjsHOI2sYbAl1AD+N0W/G+8A= -github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20250922082314-c83d83092a04 h1:JqJd39rF8rD9KIHmOEFbHP8UyYgttfuouj+kAFNtymU= -github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20250922082314-c83d83092a04/go.mod h1:SmKRclrynSSRCXSLOoWlETalJPvt62ObHsfW8iPvtDA= github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20250922082314-c83d83092a04 h1:1t4qZshLvaTzytFb9foCBtTtKT4uXzYtVaYTlgYbt+4= github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20250922082314-c83d83092a04/go.mod h1:IO6+EHBk1Ttd4L8mfnMtG58cc36tDyvdxzCytn+hKeE= github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20250922082314-c83d83092a04 h1:j5P/ehO4bQ+VqNvqNiX7N/R8wnBweFy7MX685nh4mmY= diff --git a/test/functional/glance_test_data.go b/test/functional/glance_test_data.go index 9c28a9bb..831f11ca 100644 --- a/test/functional/glance_test_data.go +++ b/test/functional/glance_test_data.go @@ -47,6 +47,10 @@ const ( GlanceDummyBackend = "enabled_backends=backend1:type1 # CHANGE_ME" //GlanceCinderBackend - GlanceCinderBackend = "enabled_backends=default_backend:cinder" + //GlanceS3Backend - + GlanceS3Backend = "[DEFAULT]\nenabled_backends=backend1:s3\n[backend1]\ns3_store_create_bucket_on_put = True" + //GlanceS3BackendOverride - + GlanceS3BackendOverride = "[DEFAULT]\nenabled_backends=backend1:s3\n[backend1]\ns3_store_cacert = \"\"" // MemcachedInstance - name of the memcached instance MemcachedInstance = "memcached" // AccountName - name of the MariaDBAccount CR @@ -86,6 +90,7 @@ type GlanceTestData struct { GlanceService types.NamespacedName GlanceConfigMapData types.NamespacedName GlanceInternalConfigMapData types.NamespacedName + GlanceExternalConfigMapData types.NamespacedName GlanceSingleConfigMapData types.NamespacedName GlanceConfigMapScripts types.NamespacedName InternalAPINAD types.NamespacedName @@ -180,6 +185,10 @@ func GetGlanceTestData(glanceName types.NamespacedName) GlanceTestData { Namespace: glanceName.Namespace, Name: fmt.Sprintf("%s-%s", glanceName.Name, "default-internal-config-data"), }, + GlanceExternalConfigMapData: types.NamespacedName{ + Namespace: glanceName.Namespace, + Name: fmt.Sprintf("%s-%s", glanceName.Name, "default-external-config-data"), + }, GlanceSingleConfigMapData: types.NamespacedName{ Namespace: glanceName.Namespace, Name: fmt.Sprintf("%s-%s", glanceName.Name, "default-single-config-data"), diff --git a/test/functional/glanceapi_controller_test.go b/test/functional/glanceapi_controller_test.go index 5784d714..b5abf782 100644 --- a/test/functional/glanceapi_controller_test.go +++ b/test/functional/glanceapi_controller_test.go @@ -247,6 +247,177 @@ var _ = Describe("Glanceapi controller", func() { }, timeout, interval).Should(Succeed()) }) }) + Context("GlanceAPI is deployed with S3 backend and TLS is enabled", func() { + keystoneAPIName := types.NamespacedName{} + + BeforeEach(func() { + DeferCleanup(infra.DeleteMemcached, infra.CreateMemcached(namespace, glanceTest.MemcachedInstance, memcachedSpec)) + infra.SimulateMemcachedReady(glanceTest.GlanceMemcached) + DeferCleanup(th.DeleteInstance, CreateDefaultGlance(glanceTest.Instance)) + DeferCleanup( + mariadb.DeleteDBService, + mariadb.CreateDBService( + glanceName.Namespace, + GetGlance(glanceTest.Instance).Spec.DatabaseInstance, + corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{Port: 3306}}, + }, + ), + ) + + mariadb.CreateMariaDBDatabase(glanceTest.GlanceDatabaseName.Namespace, glanceTest.GlanceDatabaseName.Name, mariadbv1.MariaDBDatabaseSpec{}) + DeferCleanup(k8sClient.Delete, ctx, mariadb.GetMariaDBDatabase(glanceTest.GlanceDatabaseName)) + + DeferCleanup(k8sClient.Delete, ctx, th.CreateCABundleSecret(glanceTest.CABundleSecret)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(glanceTest.InternalCertSecret)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(glanceTest.PublicCertSecret)) + spec := GetTLSGlanceAPISpec(GlanceAPITypeInternal) + spec["customServiceConfig"] = GlanceS3Backend + DeferCleanup(th.DeleteInstance, CreateGlanceAPI(glanceTest.GlanceInternal, spec)) + + keystoneAPIName = keystone.CreateKeystoneAPI(glanceTest.GlanceInternal.Namespace) + DeferCleanup(keystone.DeleteKeystoneAPI, keystoneAPIName) + keystone.CreateKeystoneEndpoint(glanceTest.GlanceInternal) + keystone.SimulateKeystoneEndpointReady(glanceTest.GlanceInternal) + th.SimulateStatefulSetReplicaReady(glanceTest.GlanceInternalStatefulSet) + + th.ExpectCondition( + glanceTest.GlanceInternal, + ConditionGetterFunc(GlanceAPIConditionGetter), + condition.ReadyCondition, + corev1.ConditionTrue, + ) + }) + + It("s3 backend is present in customServiceConfig", func() { + gapi := GetGlanceAPI(glanceTest.GlanceInternal) + Expect(gapi.Spec.CustomServiceConfig).Should(ContainSubstring("s3")) + }) + + It("extends customServiceConfig and inject s3_store_cacert", func() { + Eventually(func(g Gomega) { + confSecret := th.GetSecret(glanceTest.GlanceInternalConfigMapData) + g.Expect(confSecret).ShouldNot(BeNil()) + g.Expect(confSecret.Data).Should(HaveKey("02-config.conf")) + conf := string(confSecret.Data["02-config.conf"]) + g.Expect(string(conf)).Should( + ContainSubstring("s3_store_cacert")) + }, timeout, interval).Should(Succeed()) + }) + }) + Context("GlanceAPI is deployed with S3 backend and a customServiceConfig override and TLS is enabled", func() { + keystoneAPIName := types.NamespacedName{} + + BeforeEach(func() { + DeferCleanup(infra.DeleteMemcached, infra.CreateMemcached(namespace, glanceTest.MemcachedInstance, memcachedSpec)) + infra.SimulateMemcachedReady(glanceTest.GlanceMemcached) + DeferCleanup(th.DeleteInstance, CreateDefaultGlance(glanceTest.Instance)) + DeferCleanup( + mariadb.DeleteDBService, + mariadb.CreateDBService( + glanceName.Namespace, + GetGlance(glanceTest.Instance).Spec.DatabaseInstance, + corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{Port: 3306}}, + }, + ), + ) + + mariadb.CreateMariaDBDatabase(glanceTest.GlanceDatabaseName.Namespace, glanceTest.GlanceDatabaseName.Name, mariadbv1.MariaDBDatabaseSpec{}) + DeferCleanup(k8sClient.Delete, ctx, mariadb.GetMariaDBDatabase(glanceTest.GlanceDatabaseName)) + + DeferCleanup(k8sClient.Delete, ctx, th.CreateCABundleSecret(glanceTest.CABundleSecret)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(glanceTest.InternalCertSecret)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(glanceTest.PublicCertSecret)) + spec := GetTLSGlanceAPISpec(GlanceAPITypeInternal) + spec["customServiceConfig"] = GlanceS3BackendOverride + DeferCleanup(th.DeleteInstance, CreateGlanceAPI(glanceTest.GlanceInternal, spec)) + + keystoneAPIName = keystone.CreateKeystoneAPI(glanceTest.GlanceInternal.Namespace) + DeferCleanup(keystone.DeleteKeystoneAPI, keystoneAPIName) + keystone.CreateKeystoneEndpoint(glanceTest.GlanceInternal) + keystone.SimulateKeystoneEndpointReady(glanceTest.GlanceInternal) + th.SimulateStatefulSetReplicaReady(glanceTest.GlanceInternalStatefulSet) + + th.ExpectCondition( + glanceTest.GlanceInternal, + ConditionGetterFunc(GlanceAPIConditionGetter), + condition.ReadyCondition, + corev1.ConditionTrue, + ) + }) + + It("s3 backend is present in customServiceConfig", func() { + gapi := GetGlanceAPI(glanceTest.GlanceInternal) + Expect(gapi.Spec.CustomServiceConfig).Should(ContainSubstring("s3")) + }) + + It("does not extend customServiceConfig because the key s3_store_cacert is already present", func() { + Eventually(func(g Gomega) { + confSecret := th.GetSecret(glanceTest.GlanceInternalConfigMapData) + g.Expect(confSecret).ShouldNot(BeNil()) + g.Expect(confSecret.Data).Should(HaveKey("02-config.conf")) + conf := string(confSecret.Data["02-config.conf"]) + g.Expect(string(conf)).Should( + ContainSubstring("s3_store_cacert = \"\"")) + }, timeout, interval).Should(Succeed()) + }) + }) + Context("GlanceAPI is deployed with S3 backend and TLS is disabled", func() { + keystoneAPIName := types.NamespacedName{} + + BeforeEach(func() { + DeferCleanup(infra.DeleteMemcached, infra.CreateMemcached(namespace, glanceTest.MemcachedInstance, memcachedSpec)) + infra.SimulateMemcachedReady(glanceTest.GlanceMemcached) + DeferCleanup(th.DeleteInstance, CreateDefaultGlance(glanceTest.Instance)) + DeferCleanup( + mariadb.DeleteDBService, + mariadb.CreateDBService( + glanceName.Namespace, + GetGlance(glanceTest.Instance).Spec.DatabaseInstance, + corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{Port: 3306}}, + }, + ), + ) + + mariadb.CreateMariaDBDatabase(glanceTest.GlanceDatabaseName.Namespace, glanceTest.GlanceDatabaseName.Name, mariadbv1.MariaDBDatabaseSpec{}) + DeferCleanup(k8sClient.Delete, ctx, mariadb.GetMariaDBDatabase(glanceTest.GlanceDatabaseName)) + + spec := CreateGlanceAPISpec(GlanceAPITypeInternal) + spec["customServiceConfig"] = GlanceS3Backend + DeferCleanup(th.DeleteInstance, CreateGlanceAPI(glanceTest.GlanceInternal, spec)) + + keystoneAPIName = keystone.CreateKeystoneAPI(glanceTest.GlanceInternal.Namespace) + DeferCleanup(keystone.DeleteKeystoneAPI, keystoneAPIName) + keystone.CreateKeystoneEndpoint(glanceTest.GlanceInternal) + keystone.SimulateKeystoneEndpointReady(glanceTest.GlanceInternal) + th.SimulateStatefulSetReplicaReady(glanceTest.GlanceInternalStatefulSet) + + th.ExpectCondition( + glanceTest.GlanceInternal, + ConditionGetterFunc(GlanceAPIConditionGetter), + condition.ReadyCondition, + corev1.ConditionTrue, + ) + }) + + It("s3 backend is present in customServiceConfig", func() { + gapi := GetGlanceAPI(glanceTest.GlanceInternal) + Expect(gapi.Spec.CustomServiceConfig).Should(ContainSubstring("s3")) + }) + + It("does not inject s3_store_cacert param", func() { + Eventually(func(g Gomega) { + confSecret := th.GetSecret(glanceTest.GlanceInternalConfigMapData) + g.Expect(confSecret).ShouldNot(BeNil()) + g.Expect(confSecret.Data).Should(HaveKey("02-config.conf")) + conf := string(confSecret.Data["02-config.conf"]) + g.Expect(string(conf)).Should(Not( + ContainSubstring("s3_store_cacert"))) + }, timeout, interval).Should(Succeed()) + }) + }) When("GlanceAPI is deployed with Cinder backend", func() { BeforeEach(func() { DeferCleanup(infra.DeleteMemcached, infra.CreateMemcached(namespace, glanceTest.MemcachedInstance, memcachedSpec)) @@ -771,7 +942,6 @@ var _ = Describe("Glanceapi controller", func() { ) }) }) - When("A split GlanceAPI with TLS is generated by the top-level CR", func() { BeforeEach(func() { DeferCleanup(infra.DeleteMemcached, infra.CreateMemcached(namespace, glanceTest.MemcachedInstance, memcachedSpec)) @@ -892,7 +1062,6 @@ var _ = Describe("Glanceapi controller", func() { ) }) }) - When("A single GlanceAPI with TLS is generated by the top-level CR (single-api)", func() { BeforeEach(func() { DeferCleanup(infra.DeleteMemcached, infra.CreateMemcached(namespace, glanceTest.MemcachedInstance, memcachedSpec)) @@ -1092,7 +1261,6 @@ var _ = Describe("Glanceapi controller", func() { }, timeout, interval).Should(Succeed()) }) }) - When("A GlanceAPI with TLS is created with service override endpointURL", func() { BeforeEach(func() { DeferCleanup(infra.DeleteMemcached, infra.CreateMemcached(namespace, glanceTest.MemcachedInstance, memcachedSpec)) @@ -1151,7 +1319,6 @@ var _ = Describe("Glanceapi controller", func() { ) }) }) - When("GlanceAPI instance overrides a topology", func() { var topologyRefAlt *topologyv1.TopoRef BeforeEach(func() { @@ -1231,7 +1398,6 @@ var _ = Describe("Glanceapi controller", func() { }, timeout, interval).Should(Succeed()) }) }) - Context("GlanceAPI is fully deployed", func() { keystoneAPIName := types.NamespacedName{}