@@ -1974,6 +1974,179 @@ var _ = Describe("Barbican controller", func() {
19741974 })
19751975 })
19761976
1977+ When ("ApplicationCredential consumer finalizer is managed" , func () {
1978+ var (
1979+ acSecretName string
1980+ servicePasswordSecret string
1981+ )
1982+
1983+ BeforeEach (func () {
1984+ servicePasswordSecret = "ac-test-osp-secret" //nolint:gosec // G101
1985+
1986+ DeferCleanup (k8sClient .Delete , ctx ,
1987+ CreateBarbicanMessageBusSecret (
1988+ barbicanTest .Instance .Namespace ,
1989+ barbicanTest .RabbitmqSecretName ,
1990+ ),
1991+ )
1992+ DeferCleanup (k8sClient .Delete , ctx ,
1993+ CreateBarbicanSecret (
1994+ barbicanTest .Instance .Namespace , servicePasswordSecret ))
1995+
1996+ acSecretName = "ac-barbican-a1b2c-secret" //nolint:gosec // G101
1997+ secret := & corev1.Secret {
1998+ ObjectMeta : metav1.ObjectMeta {
1999+ Namespace : barbicanTest .Instance .Namespace ,
2000+ Name : acSecretName ,
2001+ },
2002+ Data : map [string ][]byte {
2003+ keystonev1 .ACIDSecretKey : []byte ("a1b2ctest-ac-id" ),
2004+ keystonev1 .ACSecretSecretKey : []byte ("test-ac-secret" ),
2005+ },
2006+ }
2007+ DeferCleanup (k8sClient .Delete , ctx , secret )
2008+ Expect (k8sClient .Create (ctx , secret )).To (Succeed ())
2009+
2010+ spec := GetDefaultBarbicanSpec ()
2011+ spec ["secret" ] = servicePasswordSecret
2012+ spec ["simpleCryptoBackendSecret" ] = servicePasswordSecret
2013+ spec ["auth" ] = map [string ]any {
2014+ "applicationCredentialSecret" : acSecretName ,
2015+ }
2016+ DeferCleanup (th .DeleteInstance ,
2017+ CreateBarbican (barbicanTest .Instance , spec ))
2018+ DeferCleanup (
2019+ mariadb .DeleteDBService ,
2020+ mariadb .CreateDBService (
2021+ barbicanTest .Instance .Namespace ,
2022+ GetBarbican (barbicanTest .Instance ).Spec .DatabaseInstance ,
2023+ corev1.ServiceSpec {
2024+ Ports : []corev1.ServicePort {{Port : 3306 }}}))
2025+
2026+ DeferCleanup (keystone .DeleteKeystoneAPI ,
2027+ keystone .CreateKeystoneAPI (barbicanTest .Instance .Namespace ))
2028+
2029+ infra .SimulateTransportURLReady (barbicanTest .BarbicanTransportURL )
2030+ mariadb .SimulateMariaDBAccountCompleted (barbicanTest .BarbicanDatabaseAccount )
2031+ mariadb .SimulateMariaDBDatabaseCompleted (barbicanTest .BarbicanDatabaseName )
2032+ th .SimulateJobSuccess (barbicanTest .BarbicanDBSync )
2033+ keystone .SimulateKeystoneEndpointReady (barbicanTest .BarbicanKeystoneEndpoint )
2034+ })
2035+
2036+ It ("should add the consumer finalizer to the AC secret" , func () {
2037+ Eventually (func (g Gomega ) {
2038+ secret := th .GetSecret (types.NamespacedName {
2039+ Namespace : barbicanTest .Instance .Namespace ,
2040+ Name : acSecretName ,
2041+ })
2042+ g .Expect (secret .Finalizers ).To (
2043+ ContainElement (barbican .ACConsumerFinalizer ))
2044+ }, timeout , interval ).Should (Succeed ())
2045+ })
2046+
2047+ It ("should track the consumed AC secret in status" , func () {
2048+ Eventually (func (g Gomega ) {
2049+ b := GetBarbican (barbicanTest .Instance )
2050+ g .Expect (b .Status .ApplicationCredentialSecret ).To (Equal (acSecretName ))
2051+ }, timeout , interval ).Should (Succeed ())
2052+ })
2053+
2054+ It ("should move the finalizer from the old to the new secret on rotation" , func () {
2055+ // Wait for the initial finalizer to appear
2056+ Eventually (func (g Gomega ) {
2057+ secret := th .GetSecret (types.NamespacedName {
2058+ Namespace : barbicanTest .Instance .Namespace ,
2059+ Name : acSecretName ,
2060+ })
2061+ g .Expect (secret .Finalizers ).To (
2062+ ContainElement (barbican .ACConsumerFinalizer ))
2063+ }, timeout , interval ).Should (Succeed ())
2064+
2065+ // Simulate all sub-services becoming Ready so that the split
2066+ // finalizer pattern allows removing the old secret's finalizer
2067+ // after rotation.
2068+ th .SimulateDeploymentReplicaReady (barbicanTest .BarbicanAPI )
2069+ th .SimulateDeploymentReplicaReady (barbicanTest .BarbicanKeystoneListener )
2070+ th .SimulateDeploymentReplicaReady (barbicanTest .BarbicanWorker )
2071+ Eventually (func (g Gomega ) {
2072+ b := GetBarbican (barbicanTest .Instance )
2073+ g .Expect (b .Status .Conditions .IsTrue (barbicanv1beta1 .BarbicanAPIReadyCondition )).To (BeTrue ())
2074+ g .Expect (b .Status .Conditions .IsTrue (barbicanv1beta1 .BarbicanWorkerReadyCondition )).To (BeTrue ())
2075+ g .Expect (b .Status .Conditions .IsTrue (barbicanv1beta1 .BarbicanKeystoneListenerReadyCondition )).To (BeTrue ())
2076+ }, timeout , interval ).Should (Succeed ())
2077+
2078+ // Create a new AC secret
2079+ newACSecretName := "ac-barbican-x9y8z-secret" //nolint:gosec // G101
2080+ newSecret := & corev1.Secret {
2081+ ObjectMeta : metav1.ObjectMeta {
2082+ Namespace : barbicanTest .Instance .Namespace ,
2083+ Name : newACSecretName ,
2084+ },
2085+ Data : map [string ][]byte {
2086+ keystonev1 .ACIDSecretKey : []byte ("x9y8zrotated-ac-id" ),
2087+ keystonev1 .ACSecretSecretKey : []byte ("rotated-ac-secret" ),
2088+ },
2089+ }
2090+ DeferCleanup (k8sClient .Delete , ctx , newSecret )
2091+ Expect (k8sClient .Create (ctx , newSecret )).To (Succeed ())
2092+
2093+ // Update the Barbican CR to reference the new AC secret
2094+ Eventually (func (g Gomega ) {
2095+ b := GetBarbican (barbicanTest .Instance )
2096+ b .Spec .Auth .ApplicationCredentialSecret = newACSecretName
2097+ g .Expect (k8sClient .Update (ctx , b )).Should (Succeed ())
2098+ }, timeout , interval ).Should (Succeed ())
2099+
2100+ // New secret should gain the consumer finalizer
2101+ Eventually (func (g Gomega ) {
2102+ secret := th .GetSecret (types.NamespacedName {
2103+ Namespace : barbicanTest .Instance .Namespace ,
2104+ Name : newACSecretName ,
2105+ })
2106+ g .Expect (secret .Finalizers ).To (
2107+ ContainElement (barbican .ACConsumerFinalizer ))
2108+ }, timeout , interval ).Should (Succeed ())
2109+
2110+ // Old secret should lose the consumer finalizer
2111+ Eventually (func (g Gomega ) {
2112+ secret := th .GetSecret (types.NamespacedName {
2113+ Namespace : barbicanTest .Instance .Namespace ,
2114+ Name : acSecretName ,
2115+ })
2116+ g .Expect (secret .Finalizers ).NotTo (
2117+ ContainElement (barbican .ACConsumerFinalizer ))
2118+ }, timeout , interval ).Should (Succeed ())
2119+
2120+ // Status should reflect the new secret
2121+ Eventually (func (g Gomega ) {
2122+ b := GetBarbican (barbicanTest .Instance )
2123+ g .Expect (b .Status .ApplicationCredentialSecret ).To (Equal (newACSecretName ))
2124+ }, timeout , interval ).Should (Succeed ())
2125+ })
2126+
2127+ It ("should remove the consumer finalizer from AC secret on CR deletion" , func () {
2128+ Eventually (func (g Gomega ) {
2129+ secret := th .GetSecret (types.NamespacedName {
2130+ Namespace : barbicanTest .Instance .Namespace ,
2131+ Name : acSecretName ,
2132+ })
2133+ g .Expect (secret .Finalizers ).To (
2134+ ContainElement (barbican .ACConsumerFinalizer ))
2135+ }, timeout , interval ).Should (Succeed ())
2136+
2137+ th .DeleteInstance (GetBarbican (barbicanTest .Instance ))
2138+
2139+ Eventually (func (g Gomega ) {
2140+ secret := th .GetSecret (types.NamespacedName {
2141+ Namespace : barbicanTest .Instance .Namespace ,
2142+ Name : acSecretName ,
2143+ })
2144+ g .Expect (secret .Finalizers ).NotTo (
2145+ ContainElement (barbican .ACConsumerFinalizer ))
2146+ }, timeout , interval ).Should (Succeed ())
2147+ })
2148+ })
2149+
19772150 // Run MariaDBAccount suite tests. these are pre-packaged ginkgo tests
19782151 // that exercise standard account create / update patterns that should be
19792152 // common to all controllers that ensure MariaDBAccount CRs.
0 commit comments