@@ -512,6 +512,19 @@ func (r *SwiftProxyReconciler) Reconcile(ctx context.Context, req ctrl.Request)
512512 return ctrlResult , err
513513 }
514514
515+ // Check for Application Credentials
516+ ctrlResult , err = keystonev1 .VerifyApplicationCredentialsForService (
517+ ctx ,
518+ r .Client ,
519+ instance .Namespace ,
520+ "swift" ,
521+ & envVars ,
522+ 10 * time .Second ,
523+ )
524+ if (err != nil || ctrlResult != ctrl.Result {}) {
525+ return ctrlResult , err
526+ }
527+
515528 // Get the service password and pass it to the template
516529 sps , _ , err := secret .GetSecret (ctx , helper , instance .Spec .Secret , instance .Namespace )
517530 if err != nil {
@@ -578,6 +591,20 @@ func (r *SwiftProxyReconciler) Reconcile(ctx context.Context, req ctrl.Request)
578591 return ctrl.Result {}, err
579592 }
580593
594+ // Get Application Credential data if available
595+ useAC := false
596+ acID := ""
597+ acSecret := ""
598+ // Try to get Application Credential for this service (via keystone api helper)
599+ if acData , err := keystonev1 .GetApplicationCredentialFromSecret (ctx , r .Client , instance .Namespace , swift .ServiceName ); err != nil {
600+ Log .Error (err , "Failed to get ApplicationCredential for service" , "service" , swift .ServiceName )
601+ } else if acData != nil {
602+ useAC = true
603+ acID = acData .ID
604+ acSecret = acData .Secret
605+ Log .Info ("Using ApplicationCredentials auth" , "service" , swift .ServiceName )
606+ }
607+
581608 // Create a Secret populated with content from templates/
582609 tpl := swiftproxy .SecretTemplates (
583610 instance ,
@@ -591,6 +618,9 @@ func (r *SwiftProxyReconciler) Reconcile(ctx context.Context, req ctrl.Request)
591618 os .GetRegion (),
592619 transportURLString ,
593620 instance .Spec .APITimeout ,
621+ useAC ,
622+ acID ,
623+ acSecret ,
594624 )
595625 err = secret .EnsureSecrets (ctx , helper , instance , tpl , & envVars )
596626 if err != nil {
@@ -846,6 +876,42 @@ func (r *SwiftProxyReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Ma
846876 return nil
847877 }
848878
879+ // Application Credential secret watching function
880+ acSecretFn := func (_ context.Context , o client.Object ) []reconcile.Request {
881+ name := o .GetName ()
882+ ns := o .GetNamespace ()
883+ result := []reconcile.Request {}
884+
885+ // Only handle Secret objects
886+ if _ , isSecret := o .(* corev1.Secret ); ! isSecret {
887+ return nil
888+ }
889+
890+ // Check if this is a swift AC secret by name pattern (ac-swift-secret)
891+ expectedSecretName := keystonev1 .GetACSecretName ("swift" )
892+ if name == expectedSecretName {
893+ // get all SwiftProxy CRs in this namespace
894+ swiftProxies := & swiftv1beta1.SwiftProxyList {}
895+ listOpts := []client.ListOption {
896+ client .InNamespace (ns ),
897+ }
898+ if err := r .List (context .Background (), swiftProxies , listOpts ... ); err != nil {
899+ return nil
900+ }
901+
902+ // Enqueue reconcile for all swift proxy instances
903+ for _ , cr := range swiftProxies .Items {
904+ objKey := client.ObjectKey {
905+ Namespace : ns ,
906+ Name : cr .Name ,
907+ }
908+ result = append (result , reconcile.Request {NamespacedName : objKey })
909+ }
910+ }
911+
912+ return result
913+ }
914+
849915 return ctrl .NewControllerManagedBy (mgr ).
850916 For (& swiftv1beta1.SwiftProxy {}).
851917 Owns (& corev1.Secret {}).
@@ -859,6 +925,8 @@ func (r *SwiftProxyReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Ma
859925 handler .EnqueueRequestsFromMapFunc (r .findObjectsForSrc ),
860926 builder .WithPredicates (predicate.ResourceVersionChangedPredicate {}),
861927 ).
928+ Watches (& corev1.Secret {},
929+ handler .EnqueueRequestsFromMapFunc (acSecretFn )).
862930 Watches (& memcachedv1.Memcached {},
863931 handler .EnqueueRequestsFromMapFunc (memcachedFn )).
864932 Watches (& topologyv1.Topology {},
0 commit comments