@@ -377,6 +377,39 @@ func (r *GlanceAPIReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Man
377377 return nil
378378 }
379379
380+ keystoneOverrideSecretFn := func (_ context.Context , o client.Object ) []reconcile.Request {
381+ secret := o .(* corev1.Secret )
382+ result := []reconcile.Request {}
383+ // get all GlanceAPI CRs
384+ glances := & glancev1.GlanceAPIList {}
385+ listOpts := []client.ListOption {
386+ client .InNamespace (o .GetNamespace ()),
387+ }
388+ if err := r .Client .List (context .Background (), glances , listOpts ... ); err != nil {
389+ Log .Error (err , "Unable to retrieve GlanceAPI CRs %v" )
390+ return nil
391+ }
392+ // Check if the secret has a specific label
393+ if ls := secret .GetLabels (); ls != nil {
394+ lSelector := labels .GetLabelSelector (ls )
395+ kSelector := labels .GetLabelSelector (keystonev1 .KeystoneOverridesLabelSelector )
396+ if labels .EqualLabelSelectors (lSelector , kSelector ) {
397+ for _ , cr := range glances .Items {
398+ name := client.ObjectKey {
399+ Namespace : o .GetNamespace (),
400+ Name : cr .Name ,
401+ }
402+ // append the request for this particular glance instance
403+ result = append (result , reconcile.Request {NamespacedName : name })
404+ }
405+ }
406+ }
407+ if len (result ) > 0 {
408+ return result
409+ }
410+ return nil
411+ }
412+
380413 return ctrl .NewControllerManagedBy (mgr ).
381414 For (& glancev1.GlanceAPI {}).
382415 Owns (& keystonev1.KeystoneEndpoint {}).
@@ -385,6 +418,8 @@ func (r *GlanceAPIReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Man
385418 Owns (& appsv1.StatefulSet {}).
386419 Watches (& corev1.Secret {},
387420 handler .EnqueueRequestsFromMapFunc (svcSecretFn )).
421+ Watches (& corev1.Secret {},
422+ handler .EnqueueRequestsFromMapFunc (keystoneOverrideSecretFn )).
388423 Watches (& networkv1.NetworkAttachmentDefinition {},
389424 handler .EnqueueRequestsFromMapFunc (nadFn )).
390425 Watches (
@@ -1174,6 +1209,10 @@ func (r *GlanceAPIReconciler) generateServiceConfig(
11741209 }
11751210 customData [glance .CustomServiceConfigSecretsFileName ] = customSecrets
11761211
1212+ // Collect the keystone information required to render the config templates
1213+ // in a dedicated structure. By doing this it is easy enough to process any
1214+ // parameter override
1215+ keystoneData := map [string ]string {}
11771216 keystoneAPI , err := keystonev1 .GetKeystoneAPI (ctx , h , instance .Namespace , map [string ]string {})
11781217 // KeystoneAPI not available we should not aggregate the error and continue
11791218 if err != nil {
@@ -1188,6 +1227,22 @@ func (r *GlanceAPIReconciler) generateServiceConfig(
11881227 return err
11891228 }
11901229
1230+ keystoneData ["www_authenticate_uri" ] = keystonePublicURL
1231+ keystoneData ["auth_url" ] = keystoneInternalURL
1232+ keystoneData ["region" ] = keystoneAPI .GetRegion ()
1233+
1234+ // If keystoneOverrides are available, update keystoneData with the values
1235+ // returned by the keystoneAPI function
1236+ err = r .ensureKeystoneOverrides (
1237+ ctx ,
1238+ h ,
1239+ instance ,
1240+ & keystoneData ,
1241+ )
1242+ if err != nil {
1243+ return err
1244+ }
1245+
11911246 ospSecret , _ , err := secret .GetSecret (ctx , h , instance .Spec .Secret , instance .Namespace )
11921247 if err != nil {
11931248 return err
@@ -1224,8 +1279,9 @@ func (r *GlanceAPIReconciler) generateServiceConfig(
12241279 templateParameters := map [string ]interface {}{
12251280 "ServiceUser" : instance .Spec .ServiceUser ,
12261281 "ServicePassword" : string (ospSecret .Data [instance .Spec .PasswordSelectors .Service ]),
1227- "KeystoneInternalURL" : keystoneInternalURL ,
1228- "KeystonePublicURL" : keystonePublicURL ,
1282+ "KeystoneInternalURL" : keystoneData ["auth_url" ],
1283+ "KeystonePublicURL" : keystoneData ["www_authenticate_uri" ],
1284+ "Region" : keystoneData ["region" ],
12291285 "DatabaseConnection" : fmt .Sprintf ("mysql+pymysql://%s:%s@%s/%s?read_default_file=/etc/my.cnf" ,
12301286 databaseAccount .Spec .UserName ,
12311287 string (dbSecret .Data [mariadbv1 .DatabasePasswordSelector ]),
@@ -1247,7 +1303,6 @@ func (r *GlanceAPIReconciler) generateServiceConfig(
12471303 // .Status.
12481304 if len (endpointID ) > 0 {
12491305 templateParameters ["EndpointID" ] = endpointID
1250- templateParameters ["Region" ] = keystoneAPI .GetRegion ()
12511306 }
12521307
12531308 // Configure the internal GlanceAPI to provide image location data, and the
@@ -1680,3 +1735,33 @@ func (r *GlanceAPIReconciler) GetHorizonEndpoint(
16801735
16811736 return ep , nil
16821737}
1738+
1739+ // ensureKeystoneOverrides - update keystone information based on the overrides
1740+ // passed as input
1741+ func (r * GlanceAPIReconciler ) ensureKeystoneOverrides (
1742+ ctx context.Context ,
1743+ h * helper.Helper ,
1744+ instance * glancev1.GlanceAPI ,
1745+ keystoneData * map [string ]string ,
1746+ ) error {
1747+ var err error
1748+ // make sure keystoneData is not nil
1749+ if keystoneData == nil {
1750+ keystoneData = & map [string ]string {}
1751+ }
1752+ // Check for keystone overrides for multi-region deployments
1753+ keystoneOverrides , err := keystonev1 .GetKeystoneOverrides (
1754+ ctx , h , instance .Namespace , keystonev1 .KeystoneOverridesLabelSelector )
1755+ if err != nil {
1756+ // Log the error but continue with defaults - keystone overrides are optional
1757+ h .GetLogger ().V (1 ).Info ("Could not get keystone overrides, using defaults" , "error" , err .Error ())
1758+ return nil
1759+ }
1760+ Log := r .GetLogger (ctx )
1761+ for k , v := range keystoneOverrides {
1762+ (* keystoneData )[k ] = v
1763+ }
1764+ // DEBUG
1765+ Log .Info (fmt .Sprintf ("overrides: %v\n " , keystoneData ))
1766+ return nil
1767+ }
0 commit comments