@@ -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/internal/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
@@ -1452,4 +1454,116 @@ var _ = Describe("Glanceapi controller", func() {
14521454 }, timeout , interval ).Should (Succeed ())
14531455 })
14541456 })
1457+
1458+ When ("An ApplicationCredential is created for Glance" , func () {
1459+ var (
1460+ acName string
1461+ acSecretName string
1462+ servicePasswordSecret string
1463+ passwordSelector string
1464+ )
1465+ BeforeEach (func () {
1466+ servicePasswordSecret = "ac-test-osp-secret" //nolint:gosec // G101
1467+ passwordSelector = "GlancePassword"
1468+
1469+ DeferCleanup (k8sClient .Delete , ctx , CreateGlanceSecret (glanceTest .Instance .Namespace , servicePasswordSecret ))
1470+ DeferCleanup (k8sClient .Delete , ctx , CreateGlanceMessageBusSecret (glanceTest .Instance .Namespace , glanceTest .RabbitmqSecretName ))
1471+ DeferCleanup (th .DeleteInstance , CreateDefaultGlance (glanceTest .Instance ))
1472+ DeferCleanup (
1473+ mariadb .DeleteDBService ,
1474+ mariadb .CreateDBService (
1475+ glanceTest .Instance .Namespace ,
1476+ glanceTest .GlanceDatabaseName .Name ,
1477+ corev1.ServiceSpec {
1478+ Ports : []corev1.ServicePort {{Port : 3306 }}}))
1479+ mariadb .CreateMariaDBDatabase (glanceTest .GlanceDatabaseName .Namespace , glanceTest .GlanceDatabaseName .Name , mariadbv1.MariaDBDatabaseSpec {})
1480+ DeferCleanup (k8sClient .Delete , ctx , mariadb .GetMariaDBDatabase (glanceTest .GlanceDatabaseName ))
1481+
1482+ DeferCleanup (keystone .DeleteKeystoneAPI , keystone .CreateKeystoneAPI (glanceTest .Instance .Namespace ))
1483+ DeferCleanup (infra .DeleteMemcached , infra .CreateMemcached (glanceTest .Instance .Namespace , MemcachedInstance , memcachedv1.MemcachedSpec {}))
1484+ infra .SimulateMemcachedReady (glanceTest .GlanceMemcached )
1485+
1486+ // Create AC secret with test credentials
1487+ acName = fmt .Sprintf ("ac-%s" , glance .ServiceName )
1488+ acSecretName = acName + "-secret"
1489+ acSecret := & corev1.Secret {
1490+ ObjectMeta : metav1.ObjectMeta {
1491+ Namespace : glanceTest .Instance .Namespace ,
1492+ Name : acSecretName ,
1493+ },
1494+ Data : map [string ][]byte {
1495+ "AC_ID" : []byte ("test-ac-id" ),
1496+ "AC_SECRET" : []byte ("test-ac-secret" ),
1497+ },
1498+ }
1499+ DeferCleanup (k8sClient .Delete , ctx , acSecret )
1500+ Expect (k8sClient .Create (ctx , acSecret )).To (Succeed ())
1501+
1502+ // Create AC CR
1503+ ac := & keystonev1.KeystoneApplicationCredential {
1504+ ObjectMeta : metav1.ObjectMeta {
1505+ Namespace : glanceTest .Instance .Namespace ,
1506+ Name : acName ,
1507+ },
1508+ Spec : keystonev1.KeystoneApplicationCredentialSpec {
1509+ UserName : glance .ServiceName ,
1510+ Secret : servicePasswordSecret ,
1511+ PasswordSelector : passwordSelector ,
1512+ Roles : []string {"admin" , "member" },
1513+ AccessRules : []keystonev1.ACRule {{Service : "identity" , Method : "POST" , Path : "/auth/tokens" }},
1514+ ExpirationDays : 30 ,
1515+ GracePeriodDays : 5 ,
1516+ },
1517+ }
1518+ DeferCleanup (k8sClient .Delete , ctx , ac )
1519+ Expect (k8sClient .Create (ctx , ac )).To (Succeed ())
1520+
1521+ // Simulate AC controller updating the status
1522+ fetched := & keystonev1.KeystoneApplicationCredential {}
1523+ key := types.NamespacedName {Namespace : ac .Namespace , Name : ac .Name }
1524+ Expect (k8sClient .Get (ctx , key , fetched )).To (Succeed ())
1525+
1526+ fetched .Status .SecretName = acSecretName
1527+ now := metav1 .Now ()
1528+ readyCond := condition.Condition {
1529+ Type : condition .ReadyCondition ,
1530+ Status : corev1 .ConditionTrue ,
1531+ Reason : condition .ReadyReason ,
1532+ Message : condition .ReadyMessage ,
1533+ LastTransitionTime : now ,
1534+ }
1535+ fetched .Status .Conditions = condition.Conditions {readyCond }
1536+ Expect (k8sClient .Status ().Update (ctx , fetched )).To (Succeed ())
1537+
1538+ // Create GlanceAPI using the service password secret
1539+ spec := CreateGlanceAPISpec (GlanceAPITypeInternal )
1540+ spec ["secret" ] = servicePasswordSecret
1541+ DeferCleanup (th .DeleteInstance , CreateGlanceAPI (glanceTest .GlanceInternal , spec ))
1542+
1543+ mariadb .SimulateMariaDBAccountCompleted (glanceTest .GlanceDatabaseAccount )
1544+ mariadb .SimulateMariaDBDatabaseCompleted (glanceTest .GlanceDatabaseName )
1545+ th .SimulateStatefulSetReplicaReady (glanceTest .GlanceInternalStatefulSet )
1546+
1547+ keystone .SimulateKeystoneEndpointReady (glanceTest .GlanceInternal )
1548+ })
1549+
1550+ It ("should render ApplicationCredential auth in 00-config.conf" , func () {
1551+ keystone .SimulateKeystoneEndpointReady (glanceTest .GlanceInternal )
1552+
1553+ // Wait for the config to be generated and updated with AC auth
1554+ Eventually (func (g Gomega ) {
1555+ cfgSecret := th .GetSecret (glanceTest .GlanceInternalConfigMapData )
1556+ g .Expect (cfgSecret ).NotTo (BeNil ())
1557+
1558+ conf := string (cfgSecret .Data ["00-config.conf" ])
1559+
1560+ g .Expect (conf ).To (ContainSubstring (
1561+ "application_credential_id = test-ac-id" ),
1562+ )
1563+ g .Expect (conf ).To (ContainSubstring (
1564+ "application_credential_secret = test-ac-secret" ),
1565+ )
1566+ }, timeout , interval ).Should (Succeed ())
1567+ })
1568+ })
14551569})
0 commit comments