1
1
/*
2
- Copyright The Kubernetes Authors.
2
+ Copyright 2025 The Kubernetes Authors.
3
3
4
4
Licensed under the Apache License, Version 2.0 (the "License");
5
5
you may not use this file except in compliance with the License.
@@ -63,7 +63,6 @@ type ROSARoleConfigReconciler struct {
63
63
client.Client
64
64
Log logr.Logger
65
65
Scheme * runtime.Scheme
66
- Endpoints []scope.ServiceEndpoint
67
66
WatchFilterValue string
68
67
NewStsClient func (cloud.ScopeUsage , cloud.Session , logger.Wrapper , runtime.Object ) stsiface.STSClient
69
68
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
93
92
if apierrors .IsNotFound (err ) {
94
93
return ctrl.Result {}, nil
95
94
}
95
+ log .Error (err , "Failed to get ROSARoleConfig" )
96
96
return ctrl.Result {Requeue : true }, nil
97
97
}
98
98
@@ -101,7 +101,6 @@ func (r *ROSARoleConfigReconciler) Reconcile(ctx context.Context, req ctrl.Reque
101
101
Client : r .Client ,
102
102
RosaRoleConfig : roleConfig ,
103
103
ControllerName : "rosaroleconfig" ,
104
- Endpoints : r .Endpoints ,
105
104
Logger : log ,
106
105
})
107
106
@@ -113,7 +112,7 @@ func (r *ROSARoleConfigReconciler) Reconcile(ctx context.Context, req ctrl.Reque
113
112
defer func () {
114
113
conditions .SetSummary (scope .RosaRoleConfig , conditions .WithConditions (expinfrav1 .RosaRoleConfigReadyCondition ), conditions .WithStepCounter ())
115
114
116
- if err := scope .Close (); err != nil {
115
+ if err := scope .PatchObject (); err != nil {
117
116
reterr = errors .Join (reterr , err )
118
117
}
119
118
}()
@@ -134,9 +133,7 @@ func (r *ROSARoleConfigReconciler) Reconcile(ctx context.Context, req ctrl.Reque
134
133
}
135
134
136
135
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
140
137
}
141
138
142
139
err = r .createAccountRoles (ctx , roleConfig , scope , ocmClient )
@@ -260,7 +257,6 @@ func (r *ROSARoleConfigReconciler) createOperatorRoles(ctx context.Context, role
260
257
version := roleConfig .Spec .AccountRoleConfig .Version
261
258
hostedCp := true
262
259
forcePolicyCreation := true
263
- isSharedVpc := config .SharedVPCConfig .VPCEndpointRoleARN != "" && config .SharedVPCConfig .RouteRoleARN != ""
264
260
265
261
operatorRoles , err := runtime .AWSClient .ListOperatorRoles (version , "" , config .Prefix )
266
262
@@ -270,28 +266,35 @@ func (r *ROSARoleConfigReconciler) createOperatorRoles(ctx context.Context, role
270
266
271
267
for _ , roles := range operatorRoles {
272
268
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 :
274
275
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 :
276
277
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 :
278
279
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 :
280
281
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 :
282
283
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 :
284
285
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 :
286
287
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 :
288
289
scope .RosaRoleConfig .Status .OperatorRolesRef .KMSProviderARN = role .RoleARN
289
290
}
290
291
}
291
292
}
292
293
293
294
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 ,
295
298
oidcConfigID , config .SharedVPCConfig .RouteRoleARN , ocm .DefaultChannelGroup , config .SharedVPCConfig .VPCEndpointRoleARN )
296
299
return err
297
300
}
@@ -301,33 +304,21 @@ func (r *ROSARoleConfigReconciler) createOperatorRoles(ctx context.Context, role
301
304
302
305
func (r * ROSARoleConfigReconciler ) reconcileOIDCConfig (roleConfig * expinfrav1.ROSARoleConfig , scope * scope.RosaRoleConfigScope , ocmClient * ocm.Client ) error {
303
306
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
+ }
304
311
return nil
305
312
}
306
313
if roleConfig .Spec .OperatorRoleConfig .OIDCID != "" {
307
314
scope .RosaRoleConfig .Status .OIDCID = roleConfig .Spec .OperatorRoleConfig .OIDCID
308
315
return nil
309
316
}
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 )
324
319
}
325
320
326
321
func (r * ROSARoleConfigReconciler ) createOIDCProvider (scope * scope.RosaRoleConfigScope , ocmClient * ocm.Client ) error {
327
- if scope .RosaRoleConfig .Status .OIDCProviderARN != "" {
328
- return nil
329
- }
330
-
331
322
var err error
332
323
oidcID := scope .RosaRoleConfig .Status .OIDCID
333
324
if oidcID == "" {
@@ -423,8 +414,7 @@ func (r *ROSARoleConfigReconciler) createAccountRoles(ctx context.Context, roleC
423
414
}
424
415
425
416
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 )
428
418
return err
429
419
}
430
420
@@ -471,23 +461,16 @@ func (r *ROSARoleConfigReconciler) deleteAccountRoles(ocmClient *ocm.Client, aws
471
461
return err
472
462
}
473
463
474
- var err2 , err3 error
475
464
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 ) )
477
466
}
478
467
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 ) )
480
469
}
481
470
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 ))
489
472
}
490
- return err3
473
+ return err
491
474
}
492
475
493
476
func (r * ROSARoleConfigReconciler ) deleteOIDCProvider (ocmClient * ocm.Client , awsClient aws.Client , oidcConfigID string ) error {
@@ -661,3 +644,19 @@ func (r *ROSARoleConfigReconciler) GetOIDCIDFromOperatorRole(scope *scope.RosaRo
661
644
662
645
return "" , fmt .Errorf ("cant extract oidc uuid from the %s policy document" , * roleDetails .Role .RoleName )
663
646
}
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