@@ -2202,6 +2202,145 @@ func getNeutronAPIControllerSuite(ml2MechanismDrivers []string) func() {
22022202 }, timeout , interval ).Should (Succeed ())
22032203 })
22042204 })
2205+
2206+ When ("ApplicationCredential consumer finalizer is managed" , func () {
2207+ var acSecretName string
2208+
2209+ BeforeEach (func () {
2210+ acSecretName = "ac-neutron-a1b2c-secret" //nolint:gosec // G101
2211+ secret := & corev1.Secret {
2212+ ObjectMeta : metav1.ObjectMeta {
2213+ Namespace : namespace ,
2214+ Name : acSecretName ,
2215+ },
2216+ Data : map [string ][]byte {
2217+ keystonev1 .ACIDSecretKey : []byte ("a1b2ctest-ac-id" ),
2218+ keystonev1 .ACSecretSecretKey : []byte ("test-ac-secret" ),
2219+ },
2220+ }
2221+ DeferCleanup (k8sClient .Delete , ctx , secret )
2222+ Expect (k8sClient .Create (ctx , secret )).To (Succeed ())
2223+
2224+ spec ["auth" ] = map [string ]any {
2225+ "applicationCredentialSecret" : acSecretName ,
2226+ }
2227+
2228+ DeferCleanup (th .DeleteInstance , CreateNeutronAPI (neutronAPIName .Namespace , neutronAPIName .Name , spec ))
2229+ DeferCleanup (k8sClient .Delete , ctx , CreateNeutronAPISecret (namespace , SecretName ))
2230+ DeferCleanup (infra .DeleteMemcached , infra .CreateMemcached (namespace , "memcached" , memcachedSpec ))
2231+ infra .SimulateMemcachedReady (memcachedName )
2232+ DeferCleanup (
2233+ mariadb .DeleteDBService ,
2234+ mariadb .CreateDBService (
2235+ namespace ,
2236+ GetNeutronAPI (neutronAPIName ).Spec .DatabaseInstance ,
2237+ corev1.ServiceSpec {
2238+ Ports : []corev1.ServicePort {{Port : 3306 }},
2239+ },
2240+ ),
2241+ )
2242+ SimulateTransportURLReady (apiTransportURLName )
2243+ mariadb .SimulateMariaDBAccountCompleted (types.NamespacedName {Namespace : namespace , Name : GetNeutronAPI (neutronAPIName ).Spec .DatabaseAccount })
2244+ mariadb .SimulateMariaDBDatabaseCompleted (types.NamespacedName {Namespace : namespace , Name : neutronapi .DatabaseCRName })
2245+
2246+ if isOVNEnabled {
2247+ DeferCleanup (DeleteOVNDBClusters , CreateOVNDBClusters (namespace ))
2248+ }
2249+ DeferCleanup (keystone .DeleteKeystoneAPI , keystone .CreateKeystoneAPI (namespace ))
2250+ })
2251+
2252+ It ("should add the consumer finalizer to the AC secret" , func () {
2253+ Eventually (func (g Gomega ) {
2254+ secret := th .GetSecret (types.NamespacedName {
2255+ Namespace : namespace ,
2256+ Name : acSecretName ,
2257+ })
2258+ g .Expect (secret .Finalizers ).To (
2259+ ContainElement (neutronapi .ACConsumerFinalizer ))
2260+ }, timeout , interval ).Should (Succeed ())
2261+ })
2262+
2263+ It ("should track the consumed AC secret in status" , func () {
2264+ Eventually (func (g Gomega ) {
2265+ n := GetNeutronAPI (neutronAPIName )
2266+ g .Expect (n .Status .ApplicationCredentialSecret ).To (Equal (acSecretName ))
2267+ }, timeout , interval ).Should (Succeed ())
2268+ })
2269+
2270+ It ("should move the finalizer from the old to the new secret on rotation" , func () {
2271+ Eventually (func (g Gomega ) {
2272+ secret := th .GetSecret (types.NamespacedName {
2273+ Namespace : namespace ,
2274+ Name : acSecretName ,
2275+ })
2276+ g .Expect (secret .Finalizers ).To (
2277+ ContainElement (neutronapi .ACConsumerFinalizer ))
2278+ }, timeout , interval ).Should (Succeed ())
2279+
2280+ newACSecretName := "ac-neutron-x9y8z-secret" //nolint:gosec // G101
2281+ newSecret := & corev1.Secret {
2282+ ObjectMeta : metav1.ObjectMeta {
2283+ Namespace : namespace ,
2284+ Name : newACSecretName ,
2285+ },
2286+ Data : map [string ][]byte {
2287+ keystonev1 .ACIDSecretKey : []byte ("x9y8zrotated-ac-id" ),
2288+ keystonev1 .ACSecretSecretKey : []byte ("rotated-ac-secret" ),
2289+ },
2290+ }
2291+ DeferCleanup (k8sClient .Delete , ctx , newSecret )
2292+ Expect (k8sClient .Create (ctx , newSecret )).To (Succeed ())
2293+
2294+ Eventually (func (g Gomega ) {
2295+ n := GetNeutronAPI (neutronAPIName )
2296+ n .Spec .Auth .ApplicationCredentialSecret = newACSecretName
2297+ g .Expect (k8sClient .Update (ctx , n )).Should (Succeed ())
2298+ }, timeout , interval ).Should (Succeed ())
2299+
2300+ Eventually (func (g Gomega ) {
2301+ secret := th .GetSecret (types.NamespacedName {
2302+ Namespace : namespace ,
2303+ Name : newACSecretName ,
2304+ })
2305+ g .Expect (secret .Finalizers ).To (
2306+ ContainElement (neutronapi .ACConsumerFinalizer ))
2307+ }, timeout , interval ).Should (Succeed ())
2308+
2309+ Eventually (func (g Gomega ) {
2310+ secret := th .GetSecret (types.NamespacedName {
2311+ Namespace : namespace ,
2312+ Name : acSecretName ,
2313+ })
2314+ g .Expect (secret .Finalizers ).NotTo (
2315+ ContainElement (neutronapi .ACConsumerFinalizer ))
2316+ }, timeout , interval ).Should (Succeed ())
2317+
2318+ Eventually (func (g Gomega ) {
2319+ n := GetNeutronAPI (neutronAPIName )
2320+ g .Expect (n .Status .ApplicationCredentialSecret ).To (Equal (newACSecretName ))
2321+ }, timeout , interval ).Should (Succeed ())
2322+ })
2323+
2324+ It ("should remove the consumer finalizer from AC secret on CR deletion" , func () {
2325+ Eventually (func (g Gomega ) {
2326+ secret := th .GetSecret (types.NamespacedName {
2327+ Namespace : namespace ,
2328+ Name : acSecretName ,
2329+ })
2330+ g .Expect (secret .Finalizers ).To (
2331+ ContainElement (neutronapi .ACConsumerFinalizer ))
2332+ }, timeout , interval ).Should (Succeed ())
2333+
2334+ th .DeleteInstance (GetNeutronAPI (neutronAPIName ))
2335+
2336+ secret := th .GetSecret (types.NamespacedName {
2337+ Namespace : namespace ,
2338+ Name : acSecretName ,
2339+ })
2340+ Expect (secret .Finalizers ).NotTo (
2341+ ContainElement (neutronapi .ACConsumerFinalizer ))
2342+ })
2343+ })
22052344 }
22062345}
22072346
0 commit comments