@@ -245,6 +245,41 @@ var allWatchFields = []string{
245245 topologyField ,
246246}
247247
248+ // Application Credential secret watching function
249+ func (r * NeutronAPIReconciler ) acSecretFn (_ context.Context , o client.Object ) []reconcile.Request {
250+ name := o .GetName ()
251+ ns := o .GetNamespace ()
252+ result := []reconcile.Request {}
253+
254+ // Only handle Secret objects
255+ if _ , isSecret := o .(* corev1.Secret ); ! isSecret {
256+ return nil
257+ }
258+
259+ // Check if this is a neutron AC secret by name pattern (ac-neutron-secret)
260+ expectedSecretName := keystonev1 .GetACSecretName (neutronapi .ServiceName )
261+ if name == expectedSecretName {
262+ // get all NeutronAPI CRs in this namespace
263+ neutronAPIs := & neutronv1beta1.NeutronAPIList {}
264+ listOpts := []client.ListOption {
265+ client .InNamespace (ns ),
266+ }
267+ if err := r .List (context .Background (), neutronAPIs , listOpts ... ); err != nil {
268+ return nil
269+ }
270+
271+ for _ , cr := range neutronAPIs .Items {
272+ result = append (result , reconcile.Request {
273+ NamespacedName : types.NamespacedName {
274+ Namespace : cr .Namespace ,
275+ Name : cr .Name ,
276+ },
277+ })
278+ }
279+ }
280+ return result
281+ }
282+
248283// SetupWithManager -
249284func (r * NeutronAPIReconciler ) SetupWithManager (ctx context.Context , mgr ctrl.Manager ) error {
250285 // index passwordSecretField
@@ -341,6 +376,8 @@ func (r *NeutronAPIReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Ma
341376 handler .EnqueueRequestsFromMapFunc (r .findObjectsForSrc ),
342377 builder .WithPredicates (predicate.ResourceVersionChangedPredicate {}),
343378 ).
379+ Watches (& corev1.Secret {},
380+ handler .EnqueueRequestsFromMapFunc (r .acSecretFn )).
344381 Watches (& topologyv1.Topology {},
345382 handler .EnqueueRequestsFromMapFunc (r .findObjectsForSrc ),
346383 builder .WithPredicates (predicate.GenerationChangedPredicate {})).
@@ -501,6 +538,11 @@ func (r *NeutronAPIReconciler) reconcileInit(
501538 // Create Secrets required as input for the Service and calculate an overall hash of hashes
502539 //
503540
541+ // Verify Application Credentials if available
542+ if result , err := keystonev1 .VerifyApplicationCredentialsForService (ctx , r .Client , instance .Namespace , neutronapi .ServiceName , & secretVars , 10 * time .Second ); err != nil || result .RequeueAfter > 0 {
543+ return result , err
544+ }
545+
504546 //
505547 // create Secret required for neutronapi and dbsync input. It contains minimal neutron config required
506548 // to get the service up, user can add additional files to be added to the service.
@@ -1854,6 +1896,18 @@ func (r *NeutronAPIReconciler) generateServiceSecrets(
18541896 servicePassword := string (ospSecret .Data [instance .Spec .PasswordSelectors .Service ])
18551897 templateParameters ["ServicePassword" ] = servicePassword
18561898
1899+ templateParameters ["UseApplicationCredentials" ] = false
1900+ // Try to get Application Credential for this service
1901+ if acData , err := keystonev1 .GetApplicationCredentialFromSecret (ctx , r .Client , instance .Namespace , neutronapi .ServiceName ); err != nil {
1902+ h .GetLogger ().Error (err , "Failed to get ApplicationCredential for service" , "service" , neutronapi .ServiceName )
1903+ return err
1904+ } else if acData != nil {
1905+ templateParameters ["UseApplicationCredentials" ] = true
1906+ templateParameters ["ACID" ] = acData .ID
1907+ templateParameters ["ACSecret" ] = acData .Secret
1908+ h .GetLogger ().Info ("Using ApplicationCredentials auth" , "service" , neutronapi .ServiceName )
1909+ }
1910+
18571911 // Database
18581912 databaseAccount := db .GetAccount ()
18591913 dbSecret := db .GetSecret ()
0 commit comments