@@ -19,6 +19,7 @@ package controller
1919import (
2020 "context"
2121 "fmt"
22+ "time"
2223
2324 "github.com/go-logr/logr"
2425 "github.com/google/uuid"
@@ -33,7 +34,6 @@ import (
3334
3435 postgresqlv1alpha1 "go.lunarway.com/postgresql-controller/api/v1alpha1"
3536 ctlerrors "go.lunarway.com/postgresql-controller/pkg/errors"
36- "go.lunarway.com/postgresql-controller/pkg/kube"
3737 "go.lunarway.com/postgresql-controller/pkg/postgres"
3838)
3939
@@ -61,7 +61,7 @@ func (r *CustomRoleReconciler) Reconcile(ctx context.Context, req ctrl.Request)
6161 reqLogger = reqLogger .WithValues ("requestId" , requestID .String ())
6262
6363 err = r .reconcile (ctx , reqLogger , req )
64- return requeueStrategy (reqLogger , err )
64+ return customRoleRequeueStrategy (reqLogger , err )
6565}
6666
6767// SetupWithManager sets up the controller with the Manager.
@@ -109,53 +109,55 @@ func (r *CustomRoleReconciler) reconcile(ctx context.Context, reqLogger logr.Log
109109 reqLogger = reqLogger .WithValues ("roleName" , customRole .Spec .RoleName )
110110 reqLogger .V (1 ).Info ("Reconciling CustomRole resource" )
111111
112- host , adminCredentials , err := r .resolveHostCredentials (ctx , req .Namespace , customRole .Spec .HostCredentials )
113- if err != nil {
114- r .persistStatus (ctx , customRole , err )
115- return fmt .Errorf ("resolve host credentials: %w" , err )
112+ grants := toPostgresGrants (customRole .Spec .Grants )
113+
114+ for host , creds := range r .HostCredentials {
115+ if err := r .reconcileOnHost (reqLogger , host , creds , customRole .Spec .RoleName , customRole .Spec .GrantRoles , grants ); err != nil {
116+ r .persistStatus (ctx , customRole , err )
117+ return fmt .Errorf ("reconcile on host %s: %w" , host , err )
118+ }
116119 }
117- reqLogger = reqLogger .WithValues ("host" , host )
120+
121+ r .persistStatus (ctx , customRole , nil )
122+ return nil
123+ }
124+
125+ func (r * CustomRoleReconciler ) reconcileOnHost (log logr.Logger , host string , creds postgres.Credentials , roleName string , grantRoles []string , grants []postgres.CustomRoleGrant ) error {
126+ log = log .WithValues ("host" , host )
118127
119128 // Connect to the postgres maintenance database for server-level operations.
120129 adminConnStr := postgres.ConnectionString {
121130 Host : host ,
122131 Database : "postgres" ,
123- User : adminCredentials .User ,
124- Password : adminCredentials .Password ,
125- Params : adminCredentials .Params ,
132+ User : creds .User ,
133+ Password : creds .Password ,
134+ Params : creds .Params ,
126135 }
127- adminDB , err := postgres .Connect (reqLogger , adminConnStr )
136+ adminDB , err := postgres .Connect (log , adminConnStr )
128137 if err != nil {
129- r .persistStatus (ctx , customRole , err )
130138 return fmt .Errorf ("connect to host: %w" , err )
131139 }
132140 defer adminDB .Close ()
133141
134142 // Create the role and apply server-level role grants.
135- if err := postgres .EnsureCustomRole (reqLogger , adminDB , customRole .Spec .RoleName , customRole .Spec .GrantRoles ); err != nil {
136- r .persistStatus (ctx , customRole , err )
143+ if err := postgres .EnsureCustomRole (log , adminDB , roleName , grantRoles ); err != nil {
137144 return fmt .Errorf ("ensure role: %w" , err )
138145 }
139146
140- // Apply per-database grants across all user databases.
141- if len (customRole . Spec . Grants ) > 0 {
147+ // Apply per-database grants across all user databases on this host .
148+ if len (grants ) > 0 {
142149 databases , err := postgres .UserDatabases (adminDB )
143150 if err != nil {
144- r .persistStatus (ctx , customRole , err )
145151 return fmt .Errorf ("list databases: %w" , err )
146152 }
147153
148- grants := toPostgresGrants (customRole .Spec .Grants )
149-
150154 for _ , dbName := range databases {
151- if err := r .applyGrantsOnDatabase (reqLogger , host , * adminCredentials , customRole .Spec .RoleName , dbName , grants ); err != nil {
152- r .persistStatus (ctx , customRole , err )
155+ if err := r .applyGrantsOnDatabase (log , host , creds , roleName , dbName , grants ); err != nil {
153156 return fmt .Errorf ("apply grants on database %s: %w" , dbName , err )
154157 }
155158 }
156159 }
157160
158- r .persistStatus (ctx , customRole , nil )
159161 return nil
160162}
161163
@@ -192,39 +194,6 @@ func (r *CustomRoleReconciler) applyGrantsOnDatabase(log logr.Logger, host strin
192194 return postgres .ApplyDatabaseGrants (log , db , roleName , grants )
193195}
194196
195- func (r * CustomRoleReconciler ) resolveHostCredentials (ctx context.Context , namespace , hostCredentialsName string ) (string , * postgres.Credentials , error ) {
196- var hostCreds postgresqlv1alpha1.PostgreSQLHostCredentials
197- err := r .Client .Get (ctx , types.NamespacedName {Namespace : namespace , Name : hostCredentialsName }, & hostCreds )
198- if err != nil {
199- if apierrors .IsNotFound (err ) {
200- return "" , nil , ctlerrors .NewTemporary (fmt .Errorf ("PostgreSQLHostCredentials %s/%s not found" , namespace , hostCredentialsName ))
201- }
202- return "" , nil , fmt .Errorf ("get PostgreSQLHostCredentials %s/%s: %w" , namespace , hostCredentialsName , err )
203- }
204-
205- user , err := kube .ResourceValue (r .Client , hostCreds .Spec .User , hostCreds .Namespace )
206- if err != nil {
207- return "" , nil , fmt .Errorf ("resolve user: %w" , err )
208- }
209-
210- password , err := kube .ResourceValue (r .Client , hostCreds .Spec .Password , hostCreds .Namespace )
211- if err != nil {
212- return "" , nil , fmt .Errorf ("resolve password: %w" , err )
213- }
214-
215- host , err := kube .ResourceValue (r .Client , hostCreds .Spec .Host , hostCreds .Namespace )
216- if err != nil {
217- return "" , nil , fmt .Errorf ("resolve host: %w" , err )
218- }
219-
220- return host , & postgres.Credentials {
221- Name : user ,
222- User : user ,
223- Password : password ,
224- Params : hostCreds .Spec .Params ,
225- }, nil
226- }
227-
228197func (r * CustomRoleReconciler ) persistStatus (ctx context.Context , customRole * postgresqlv1alpha1.CustomRole , reconcileErr error ) {
229198 var phase postgresqlv1alpha1.CustomRolePhase
230199 var errorMessage string
@@ -252,3 +221,22 @@ func (r *CustomRoleReconciler) persistStatus(ctx context.Context, customRole *po
252221 r .Log .Error (err , "failed to update CustomRole status" )
253222 }
254223}
224+
225+ func customRoleRequeueStrategy (log logr.Logger , err error ) (ctrl.Result , error ) {
226+ if err == nil {
227+ return ctrl.Result {}, nil
228+ }
229+
230+ if ctlerrors .IsInvalid (err ) {
231+ log .Info ("Dropping CustomRole from queue as it is invalid" , "error" , err )
232+ return reconcile.Result {}, nil
233+ }
234+
235+ if ctlerrors .IsTemporary (err ) {
236+ log .Info ("Failed to reconcile CustomRole object, attempting again shortly" , "error" , err )
237+ return ctrl.Result {RequeueAfter : 10 * time .Second }, nil
238+ }
239+
240+ log .Info ("Failed to reconcile CustomRole object due to unknown error" , "error" , err )
241+ return ctrl.Result {RequeueAfter : 10 * time .Second }, nil
242+ }
0 commit comments