@@ -26,8 +26,10 @@ import (
2626 . "github.com/onsi/ginkgo/v2" //revive:disable:dot-imports
2727 . "github.com/onsi/gomega" //revive:disable:dot-imports
2828 glancev1 "github.com/openstack-k8s-operators/glance-operator/api/v1beta1"
29+ "github.com/openstack-k8s-operators/glance-operator/pkg/glance"
2930 memcachedv1 "github.com/openstack-k8s-operators/infra-operator/apis/memcached/v1beta1"
3031 topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
32+ keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1"
3133 "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
3234
3335 //revive:disable-next-line:dot-imports
@@ -1286,4 +1288,116 @@ var _ = Describe("Glanceapi controller", func() {
12861288 }, timeout , interval ).Should (Succeed ())
12871289 })
12881290 })
1291+
1292+ When ("An ApplicationCredential is created for Glance" , func () {
1293+ var (
1294+ acName string
1295+ acSecretName string
1296+ servicePasswordSecret string
1297+ passwordSelector string
1298+ )
1299+ BeforeEach (func () {
1300+ servicePasswordSecret = "ac-test-osp-secret" //nolint:gosec // G101
1301+ passwordSelector = "GlancePassword"
1302+
1303+ DeferCleanup (k8sClient .Delete , ctx , CreateGlanceSecret (glanceTest .Instance .Namespace , servicePasswordSecret ))
1304+ DeferCleanup (k8sClient .Delete , ctx , CreateGlanceMessageBusSecret (glanceTest .Instance .Namespace , glanceTest .RabbitmqSecretName ))
1305+ DeferCleanup (th .DeleteInstance , CreateDefaultGlance (glanceTest .Instance ))
1306+ DeferCleanup (
1307+ mariadb .DeleteDBService ,
1308+ mariadb .CreateDBService (
1309+ glanceTest .Instance .Namespace ,
1310+ glanceTest .GlanceDatabaseName .Name ,
1311+ corev1.ServiceSpec {
1312+ Ports : []corev1.ServicePort {{Port : 3306 }}}))
1313+ mariadb .CreateMariaDBDatabase (glanceTest .GlanceDatabaseName .Namespace , glanceTest .GlanceDatabaseName .Name , mariadbv1.MariaDBDatabaseSpec {})
1314+ DeferCleanup (k8sClient .Delete , ctx , mariadb .GetMariaDBDatabase (glanceTest .GlanceDatabaseName ))
1315+
1316+ DeferCleanup (keystone .DeleteKeystoneAPI , keystone .CreateKeystoneAPI (glanceTest .Instance .Namespace ))
1317+ DeferCleanup (infra .DeleteMemcached , infra .CreateMemcached (glanceTest .Instance .Namespace , MemcachedInstance , memcachedv1.MemcachedSpec {}))
1318+ infra .SimulateMemcachedReady (glanceTest .GlanceMemcached )
1319+
1320+ // Create AC secret with test credentials
1321+ acName = fmt .Sprintf ("ac-%s" , glance .ServiceName )
1322+ acSecretName = acName + "-secret"
1323+ acSecret := & corev1.Secret {
1324+ ObjectMeta : metav1.ObjectMeta {
1325+ Namespace : glanceTest .Instance .Namespace ,
1326+ Name : acSecretName ,
1327+ },
1328+ Data : map [string ][]byte {
1329+ "AC_ID" : []byte ("test-ac-id" ),
1330+ "AC_SECRET" : []byte ("test-ac-secret" ),
1331+ },
1332+ }
1333+ DeferCleanup (k8sClient .Delete , ctx , acSecret )
1334+ Expect (k8sClient .Create (ctx , acSecret )).To (Succeed ())
1335+
1336+ // Create AC CR
1337+ ac := & keystonev1.KeystoneApplicationCredential {
1338+ ObjectMeta : metav1.ObjectMeta {
1339+ Namespace : glanceTest .Instance .Namespace ,
1340+ Name : acName ,
1341+ },
1342+ Spec : keystonev1.KeystoneApplicationCredentialSpec {
1343+ UserName : glance .ServiceName ,
1344+ Secret : servicePasswordSecret ,
1345+ PasswordSelector : passwordSelector ,
1346+ Roles : []string {"admin" , "member" },
1347+ AccessRules : []keystonev1.ACRule {{Service : "identity" , Method : "POST" , Path : "/auth/tokens" }},
1348+ ExpirationDays : 30 ,
1349+ GracePeriodDays : 5 ,
1350+ },
1351+ }
1352+ DeferCleanup (k8sClient .Delete , ctx , ac )
1353+ Expect (k8sClient .Create (ctx , ac )).To (Succeed ())
1354+
1355+ // Simulate AC controller updating the status
1356+ fetched := & keystonev1.KeystoneApplicationCredential {}
1357+ key := types.NamespacedName {Namespace : ac .Namespace , Name : ac .Name }
1358+ Expect (k8sClient .Get (ctx , key , fetched )).To (Succeed ())
1359+
1360+ fetched .Status .SecretName = acSecretName
1361+ now := metav1 .Now ()
1362+ readyCond := condition.Condition {
1363+ Type : condition .ReadyCondition ,
1364+ Status : corev1 .ConditionTrue ,
1365+ Reason : condition .ReadyReason ,
1366+ Message : condition .ReadyMessage ,
1367+ LastTransitionTime : now ,
1368+ }
1369+ fetched .Status .Conditions = condition.Conditions {readyCond }
1370+ Expect (k8sClient .Status ().Update (ctx , fetched )).To (Succeed ())
1371+
1372+ // Create GlanceAPI using the service password secret
1373+ spec := CreateGlanceAPISpec (GlanceAPITypeInternal )
1374+ spec ["secret" ] = servicePasswordSecret
1375+ DeferCleanup (th .DeleteInstance , CreateGlanceAPI (glanceTest .GlanceInternal , spec ))
1376+
1377+ mariadb .SimulateMariaDBAccountCompleted (glanceTest .GlanceDatabaseAccount )
1378+ mariadb .SimulateMariaDBDatabaseCompleted (glanceTest .GlanceDatabaseName )
1379+ th .SimulateStatefulSetReplicaReady (glanceTest .GlanceInternalStatefulSet )
1380+
1381+ keystone .SimulateKeystoneEndpointReady (glanceTest .GlanceInternal )
1382+ })
1383+
1384+ It ("should render ApplicationCredential auth in 00-config.conf" , func () {
1385+ keystone .SimulateKeystoneEndpointReady (glanceTest .GlanceInternal )
1386+
1387+ // Wait for the config to be generated and updated with AC auth
1388+ Eventually (func (g Gomega ) {
1389+ cfgSecret := th .GetSecret (glanceTest .GlanceInternalConfigMapData )
1390+ g .Expect (cfgSecret ).NotTo (BeNil ())
1391+
1392+ conf := string (cfgSecret .Data ["00-config.conf" ])
1393+
1394+ g .Expect (conf ).To (ContainSubstring (
1395+ "application_credential_id = test-ac-id" ),
1396+ )
1397+ g .Expect (conf ).To (ContainSubstring (
1398+ "application_credential_secret = test-ac-secret" ),
1399+ )
1400+ }, timeout , interval ).Should (Succeed ())
1401+ })
1402+ })
12891403})
0 commit comments