11/*
2- Copyright The Kubernetes Authors.
2+ Copyright 2025 The Kubernetes Authors.
33
44Licensed under the Apache License, Version 2.0 (the "License");
55you may not use this file except in compliance with the License.
@@ -63,7 +63,6 @@ type ROSARoleConfigReconciler struct {
6363 client.Client
6464 Log logr.Logger
6565 Scheme * runtime.Scheme
66- Endpoints []scope.ServiceEndpoint
6766 WatchFilterValue string
6867 NewStsClient func (cloud.ScopeUsage , cloud.Session , logger.Wrapper , runtime.Object ) stsiface.STSClient
6968 NewOCMClient func (ctx context.Context , scope rosa.OCMSecretsRetriever ) (rosa.OCMClient , error )
@@ -93,6 +92,7 @@ func (r *ROSARoleConfigReconciler) Reconcile(ctx context.Context, req ctrl.Reque
9392 if apierrors .IsNotFound (err ) {
9493 return ctrl.Result {}, nil
9594 }
95+ log .Error (err , "Failed to get ROSARoleConfig" )
9696 return ctrl.Result {Requeue : true }, nil
9797 }
9898
@@ -101,7 +101,6 @@ func (r *ROSARoleConfigReconciler) Reconcile(ctx context.Context, req ctrl.Reque
101101 Client : r .Client ,
102102 RosaRoleConfig : roleConfig ,
103103 ControllerName : "rosaroleconfig" ,
104- Endpoints : r .Endpoints ,
105104 Logger : log ,
106105 })
107106
@@ -113,7 +112,7 @@ func (r *ROSARoleConfigReconciler) Reconcile(ctx context.Context, req ctrl.Reque
113112 defer func () {
114113 conditions .SetSummary (scope .RosaRoleConfig , conditions .WithConditions (expinfrav1 .RosaRoleConfigReadyCondition ), conditions .WithStepCounter ())
115114
116- if err := scope .Close (); err != nil {
115+ if err := scope .PatchObject (); err != nil {
117116 reterr = errors .Join (reterr , err )
118117 }
119118 }()
@@ -134,9 +133,7 @@ func (r *ROSARoleConfigReconciler) Reconcile(ctx context.Context, req ctrl.Reque
134133 }
135134
136135 if controllerutil .AddFinalizer (scope .RosaRoleConfig , expinfrav1 .RosaRoleConfigFinalizer ) {
137- if err := scope .PatchObject (); err != nil {
138- return ctrl.Result {}, err
139- }
136+ return ctrl.Result {}, err
140137 }
141138
142139 err = r .createAccountRoles (ctx , roleConfig , scope , ocmClient )
@@ -260,7 +257,6 @@ func (r *ROSARoleConfigReconciler) createOperatorRoles(ctx context.Context, role
260257 version := roleConfig .Spec .AccountRoleConfig .Version
261258 hostedCp := true
262259 forcePolicyCreation := true
263- isSharedVpc := config .SharedVPCConfig .VPCEndpointRoleARN != "" && config .SharedVPCConfig .RouteRoleARN != ""
264260
265261 operatorRoles , err := runtime .AWSClient .ListOperatorRoles (version , "" , config .Prefix )
266262
@@ -270,28 +266,35 @@ func (r *ROSARoleConfigReconciler) createOperatorRoles(ctx context.Context, role
270266
271267 for _ , roles := range operatorRoles {
272268 for _ , role := range roles {
273- if role .RoleName == fmt .Sprintf ("%s-openshift-ingress-operator-cloud-credentials" , config .Prefix ) {
269+ roleSuffix := strings .TrimPrefix (role .RoleName , config .Prefix )
270+ if roleSuffix == role .RoleName {
271+ continue
272+ }
273+ switch roleSuffix {
274+ case expinfrav1 .IngressOperatorARNSuffix :
274275 scope .RosaRoleConfig .Status .OperatorRolesRef .IngressARN = role .RoleARN
275- } else if role . RoleName == fmt . Sprintf ( "%s-openshift-image-registry-installer-cloud-credentials" , config . Prefix ) {
276+ case expinfrav1 . ImageRegistryARNSuffix :
276277 scope .RosaRoleConfig .Status .OperatorRolesRef .ImageRegistryARN = role .RoleARN
277- } else if role . RoleName == fmt . Sprintf ( "%s-openshift-cluster-csi-drivers-ebs-cloud-credentials" , config . Prefix ) {
278+ case expinfrav1 . StorageARNSuffix :
278279 scope .RosaRoleConfig .Status .OperatorRolesRef .StorageARN = role .RoleARN
279- } else if role . RoleName == fmt . Sprintf ( "%s-openshift-cloud-network-config-controller-cloud-credentials" , config . Prefix ) {
280+ case expinfrav1 . NetworkARNSuffix :
280281 scope .RosaRoleConfig .Status .OperatorRolesRef .NetworkARN = role .RoleARN
281- } else if role . RoleName == fmt . Sprintf ( "%s-kube-system-kube-controller-manager" , config . Prefix ) {
282+ case expinfrav1 . KubeCloudControllerARNSuffix :
282283 scope .RosaRoleConfig .Status .OperatorRolesRef .KubeCloudControllerARN = role .RoleARN
283- } else if role . RoleName == fmt . Sprintf ( "%s-kube-system-capa-controller-manager" , config . Prefix ) {
284+ case expinfrav1 . NodePoolManagementARNSuffix :
284285 scope .RosaRoleConfig .Status .OperatorRolesRef .NodePoolManagementARN = role .RoleARN
285- } else if role . RoleName == fmt . Sprintf ( "%s-kube-system-control-plane-operator" , config . Prefix ) {
286+ case expinfrav1 . ControlPlaneOperatorARNSuffix :
286287 scope .RosaRoleConfig .Status .OperatorRolesRef .ControlPlaneOperatorARN = role .RoleARN
287- } else if role . RoleName == fmt . Sprintf ( "%s-kube-system-kms-provider" , config . Prefix ) {
288+ case expinfrav1 . KMSProviderARNSuffix :
288289 scope .RosaRoleConfig .Status .OperatorRolesRef .KMSProviderARN = role .RoleARN
289290 }
290291 }
291292 }
292293
293294 if ! r .operatorRolesReady (& scope .RosaRoleConfig .Status .OperatorRolesRef ) {
294- err = operatorroles .CreateOperatorRoles (runtime , ocm .Production , config .PermissionsBoundaryARN , interactive .ModeAuto , policies , version , isSharedVpc , config .Prefix , hostedCp , installerRoleArn , forcePolicyCreation ,
295+ // not all operator roles are set, operator roles are not ready yet.
296+ r .clearOperatorRolesRef (& scope .RosaRoleConfig .Status .OperatorRolesRef )
297+ err = operatorroles .CreateOperatorRoles (runtime , ocm .Production , config .PermissionsBoundaryARN , interactive .ModeAuto , policies , version , config .SharedVPCConfig .IsSharedVPC (), config .Prefix , hostedCp , installerRoleArn , forcePolicyCreation ,
295298 oidcConfigID , config .SharedVPCConfig .RouteRoleARN , ocm .DefaultChannelGroup , config .SharedVPCConfig .VPCEndpointRoleARN )
296299 return err
297300 }
@@ -301,33 +304,21 @@ func (r *ROSARoleConfigReconciler) createOperatorRoles(ctx context.Context, role
301304
302305func (r * ROSARoleConfigReconciler ) reconcileOIDCConfig (roleConfig * expinfrav1.ROSARoleConfig , scope * scope.RosaRoleConfigScope , ocmClient * ocm.Client ) error {
303306 if scope .RosaRoleConfig .Status .OIDCID != "" {
307+ oidcConfig , err := ocmClient .GetOidcConfig (scope .RosaRoleConfig .Status .OIDCID )
308+ if err != nil || oidcConfig == nil {
309+ return fmt .Errorf ("failed to get OIDC config: %w" , err )
310+ }
304311 return nil
305312 }
306313 if roleConfig .Spec .OperatorRoleConfig .OIDCID != "" {
307314 scope .RosaRoleConfig .Status .OIDCID = roleConfig .Spec .OperatorRoleConfig .OIDCID
308315 return nil
309316 }
310- // Try to get OIDC UUID from some operator role policy document.
311- roleName := fmt .Sprintf ("%s-openshift-ingress-operator-cloud-credentials" , roleConfig .Spec .OperatorRoleConfig .Prefix )
312- roleDetails , err := scope .IAMClient ().GetRole (context .TODO (), & iamv2.GetRoleInput {
313- RoleName : & roleName ,
314- })
315- if err != nil {
316- return r .createOIDCConfig (scope , ocmClient )
317- }
318- oidcID , err := r .GetOIDCIDFromOperatorRole (scope , roleDetails )
319- if err != nil {
320- return r .createOIDCConfig (scope , ocmClient )
321- }
322- scope .RosaRoleConfig .Status .OIDCID = oidcID
323- return nil
317+
318+ return r .createOIDCConfig (scope , ocmClient )
324319}
325320
326321func (r * ROSARoleConfigReconciler ) createOIDCProvider (scope * scope.RosaRoleConfigScope , ocmClient * ocm.Client ) error {
327- if scope .RosaRoleConfig .Status .OIDCProviderARN != "" {
328- return nil
329- }
330-
331322 var err error
332323 oidcID := scope .RosaRoleConfig .Status .OIDCID
333324 if oidcID == "" {
@@ -423,8 +414,7 @@ func (r *ROSARoleConfigReconciler) createAccountRoles(ctx context.Context, roleC
423414 }
424415
425416 managedPolicies := true
426- isSharedVpc := config .SharedVPCConfig .VPCEndpointRoleARN != "" && config .SharedVPCConfig .RouteRoleARN != ""
427- err := accountroles .CreateHCPRoles (runtime , config .Prefix , managedPolicies , config .PermissionsBoundaryARN , ocm .Production , policies , config .Version , config .Path , isSharedVpc , config .SharedVPCConfig .RouteRoleARN , config .SharedVPCConfig .VPCEndpointRoleARN )
417+ err := accountroles .CreateHCPRoles (runtime , config .Prefix , managedPolicies , config .PermissionsBoundaryARN , ocm .Production , policies , config .Version , config .Path , config .SharedVPCConfig .IsSharedVPC (), config .SharedVPCConfig .RouteRoleARN , config .SharedVPCConfig .VPCEndpointRoleARN )
428418 return err
429419 }
430420
@@ -471,23 +461,16 @@ func (r *ROSARoleConfigReconciler) deleteAccountRoles(ocmClient *ocm.Client, aws
471461 return err
472462 }
473463
474- var err2 , err3 error
475464 if canDeleteRole (clusters , roles .InstallerRoleARN ) {
476- err = awsClient .DeleteAccountRole (strings .Split (roles .InstallerRoleARN , "/" )[1 ], config .Prefix , true , deleteHcpSharedVpcPolicies )
465+ err = errors . Join ( err , awsClient .DeleteAccountRole (strings .Split (roles .InstallerRoleARN , "/" )[1 ], config .Prefix , true , deleteHcpSharedVpcPolicies ) )
477466 }
478467 if canDeleteRole (clusters , roles .WorkerRoleARN ) {
479- err2 = awsClient .DeleteAccountRole (strings .Split (roles .WorkerRoleARN , "/" )[1 ], config .Prefix , true , deleteHcpSharedVpcPolicies )
468+ err = errors . Join ( err , awsClient .DeleteAccountRole (strings .Split (roles .WorkerRoleARN , "/" )[1 ], config .Prefix , true , deleteHcpSharedVpcPolicies ) )
480469 }
481470 if canDeleteRole (clusters , roles .SupportRoleARN ) {
482- err3 = awsClient .DeleteAccountRole (strings .Split (roles .SupportRoleARN , "/" )[1 ], config .Prefix , true , deleteHcpSharedVpcPolicies )
483- }
484- if err != nil {
485- return err
486- }
487- if err2 != nil {
488- return err2
471+ err = errors .Join (err , awsClient .DeleteAccountRole (strings .Split (roles .SupportRoleARN , "/" )[1 ], config .Prefix , true , deleteHcpSharedVpcPolicies ))
489472 }
490- return err3
473+ return err
491474}
492475
493476func (r * ROSARoleConfigReconciler ) deleteOIDCProvider (ocmClient * ocm.Client , awsClient aws.Client , oidcConfigID string ) error {
@@ -661,3 +644,19 @@ func (r *ROSARoleConfigReconciler) GetOIDCIDFromOperatorRole(scope *scope.RosaRo
661644
662645 return "" , fmt .Errorf ("cant extract oidc uuid from the %s policy document" , * roleDetails .Role .RoleName )
663646}
647+
648+ // clearOperatorRolesRef clears all field values in the OperatorRolesRef by setting them to empty strings.
649+ func (r ROSARoleConfigReconciler ) clearOperatorRolesRef (operatorRolesRef * v1beta2.AWSRolesRef ) {
650+ if operatorRolesRef == nil {
651+ return
652+ }
653+
654+ operatorRolesRef .IngressARN = ""
655+ operatorRolesRef .ImageRegistryARN = ""
656+ operatorRolesRef .StorageARN = ""
657+ operatorRolesRef .NetworkARN = ""
658+ operatorRolesRef .KubeCloudControllerARN = ""
659+ operatorRolesRef .NodePoolManagementARN = ""
660+ operatorRolesRef .ControlPlaneOperatorARN = ""
661+ operatorRolesRef .KMSProviderARN = ""
662+ }
0 commit comments