Skip to content

Commit f17676b

Browse files
committed
Review fixes
1 parent 6b7a84f commit f17676b

File tree

11 files changed

+190
-49
lines changed

11 files changed

+190
-49
lines changed

controlplane/rosa/api/v1beta2/rosacontrolplane_webhook.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
Copyright 2023 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
117
package v1beta2
218

319
import (

exp/api/v1beta2/rosaroleconfig_types.go

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright The Kubernetes Authors.
2+
Copyright 2025 The Kubernetes Authors.
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -25,9 +25,6 @@ import (
2525
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
2626
)
2727

28-
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
29-
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
30-
3128
// ROSARoleConfigSpec defines the desired state of ROSARoleConfig
3229
type ROSARoleConfigSpec struct {
3330
AccountRoleConfig AccountRoleConfig `json:"accountRoleConfig"`
@@ -158,6 +155,25 @@ const (
158155
RosaRoleConfigCreatedReason = "Created"
159156
)
160157

158+
const (
159+
// IngressOperatorARNSuffix is the suffix for the ingress operator role.
160+
IngressOperatorARNSuffix = "openshift-ingress-operator-cloud-credentials"
161+
// ImageRegistryARNSuffix is the suffix for the image registry operator role.
162+
ImageRegistryARNSuffix = "openshift-image-registry-installer-cloud-credentials"
163+
// StorageARNSuffix is the suffix for the storage operator role.
164+
StorageARNSuffix = "openshift-cluster-csi-drivers-ebs-cloud-credentials"
165+
// NetworkARNSuffix is the suffix for the network operator role.
166+
NetworkARNSuffix = "openshift-cloud-network-config-controller-cloud-credentials"
167+
// KubeCloudControllerARNSuffix is the suffix for the kube cloud controller role.
168+
KubeCloudControllerARNSuffix = "kube-system-kube-controller-manager"
169+
// NodePoolManagementARNSuffix is the suffix for the node pool management role.
170+
NodePoolManagementARNSuffix = "kube-system-capa-controller-manager"
171+
// ControlPlaneOperatorARNSuffix is the suffix for the control plane operator role.
172+
ControlPlaneOperatorARNSuffix = "kube-system-control-plane-operator"
173+
// KMSProviderARNSuffix is the suffix for the kms provider role.
174+
KMSProviderARNSuffix = "kube-system-kms-provider"
175+
)
176+
161177
// SetConditions sets the conditions of the ROSARoleConfig.
162178
func (r *ROSARoleConfig) SetConditions(conditions clusterv1.Conditions) {
163179
r.Status.Conditions = conditions
@@ -168,6 +184,11 @@ func (r *ROSARoleConfig) GetConditions() clusterv1.Conditions {
168184
return r.Status.Conditions
169185
}
170186

187+
// IsSharedVPC checks if the shared VPC config is set.
188+
func (s SharedVPCConfig) IsSharedVPC() bool {
189+
return s.VPCEndpointRoleARN != "" && s.RouteRoleARN != ""
190+
}
191+
171192
func init() {
172193
SchemeBuilder.Register(&ROSARoleConfig{}, &ROSARoleConfigList{})
173194
}

exp/controllers/rosamachinepool_controller.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
Copyright 2023 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
117
package controllers
218

319
import (

exp/controllers/rosaroleconfig_controller.go

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright The Kubernetes Authors.
2+
Copyright 2025 The Kubernetes Authors.
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -93,6 +93,7 @@ func (r *ROSARoleConfigReconciler) Reconcile(ctx context.Context, req ctrl.Reque
9393
if apierrors.IsNotFound(err) {
9494
return ctrl.Result{}, nil
9595
}
96+
log.Error(err, "Failed to get ROSARoleConfig")
9697
return ctrl.Result{Requeue: true}, nil
9798
}
9899

@@ -113,7 +114,7 @@ func (r *ROSARoleConfigReconciler) Reconcile(ctx context.Context, req ctrl.Reque
113114
defer func() {
114115
conditions.SetSummary(scope.RosaRoleConfig, conditions.WithConditions(expinfrav1.RosaRoleConfigReadyCondition), conditions.WithStepCounter())
115116

116-
if err := scope.Close(); err != nil {
117+
if err := scope.PatchObject(); err != nil {
117118
reterr = errors.Join(reterr, err)
118119
}
119120
}()
@@ -134,9 +135,7 @@ func (r *ROSARoleConfigReconciler) Reconcile(ctx context.Context, req ctrl.Reque
134135
}
135136

136137
if controllerutil.AddFinalizer(scope.RosaRoleConfig, expinfrav1.RosaRoleConfigFinalizer) {
137-
if err := scope.PatchObject(); err != nil {
138-
return ctrl.Result{}, err
139-
}
138+
return ctrl.Result{}, err
140139
}
141140

142141
err = r.createAccountRoles(ctx, roleConfig, scope, ocmClient)
@@ -260,7 +259,6 @@ func (r *ROSARoleConfigReconciler) createOperatorRoles(ctx context.Context, role
260259
version := roleConfig.Spec.AccountRoleConfig.Version
261260
hostedCp := true
262261
forcePolicyCreation := true
263-
isSharedVpc := config.SharedVPCConfig.VPCEndpointRoleARN != "" && config.SharedVPCConfig.RouteRoleARN != ""
264262

265263
operatorRoles, err := runtime.AWSClient.ListOperatorRoles(version, "", config.Prefix)
266264

@@ -270,28 +268,35 @@ func (r *ROSARoleConfigReconciler) createOperatorRoles(ctx context.Context, role
270268

271269
for _, roles := range operatorRoles {
272270
for _, role := range roles {
273-
if role.RoleName == fmt.Sprintf("%s-openshift-ingress-operator-cloud-credentials", config.Prefix) {
271+
roleSuffix := strings.TrimPrefix(role.RoleName, config.Prefix)
272+
if roleSuffix == role.RoleName {
273+
continue
274+
}
275+
switch roleSuffix {
276+
case expinfrav1.IngressOperatorARNSuffix:
274277
scope.RosaRoleConfig.Status.OperatorRolesRef.IngressARN = role.RoleARN
275-
} else if role.RoleName == fmt.Sprintf("%s-openshift-image-registry-installer-cloud-credentials", config.Prefix) {
278+
case expinfrav1.ImageRegistryARNSuffix:
276279
scope.RosaRoleConfig.Status.OperatorRolesRef.ImageRegistryARN = role.RoleARN
277-
} else if role.RoleName == fmt.Sprintf("%s-openshift-cluster-csi-drivers-ebs-cloud-credentials", config.Prefix) {
280+
case expinfrav1.StorageARNSuffix:
278281
scope.RosaRoleConfig.Status.OperatorRolesRef.StorageARN = role.RoleARN
279-
} else if role.RoleName == fmt.Sprintf("%s-openshift-cloud-network-config-controller-cloud-credentials", config.Prefix) {
282+
case expinfrav1.NetworkARNSuffix:
280283
scope.RosaRoleConfig.Status.OperatorRolesRef.NetworkARN = role.RoleARN
281-
} else if role.RoleName == fmt.Sprintf("%s-kube-system-kube-controller-manager", config.Prefix) {
284+
case expinfrav1.KubeCloudControllerARNSuffix:
282285
scope.RosaRoleConfig.Status.OperatorRolesRef.KubeCloudControllerARN = role.RoleARN
283-
} else if role.RoleName == fmt.Sprintf("%s-kube-system-capa-controller-manager", config.Prefix) {
286+
case expinfrav1.NodePoolManagementARNSuffix:
284287
scope.RosaRoleConfig.Status.OperatorRolesRef.NodePoolManagementARN = role.RoleARN
285-
} else if role.RoleName == fmt.Sprintf("%s-kube-system-control-plane-operator", config.Prefix) {
288+
case expinfrav1.ControlPlaneOperatorARNSuffix:
286289
scope.RosaRoleConfig.Status.OperatorRolesRef.ControlPlaneOperatorARN = role.RoleARN
287-
} else if role.RoleName == fmt.Sprintf("%s-kube-system-kms-provider", config.Prefix) {
290+
case expinfrav1.KMSProviderARNSuffix:
288291
scope.RosaRoleConfig.Status.OperatorRolesRef.KMSProviderARN = role.RoleARN
292+
default:
293+
return fmt.Errorf("unknown role suffix: when listing operator roles %s", roleSuffix)
289294
}
290295
}
291296
}
292297

293298
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,
299+
err = operatorroles.CreateOperatorRoles(runtime, ocm.Production, config.PermissionsBoundaryARN, interactive.ModeAuto, policies, version, config.SharedVPCConfig.IsSharedVPC(), config.Prefix, hostedCp, installerRoleArn, forcePolicyCreation,
295300
oidcConfigID, config.SharedVPCConfig.RouteRoleARN, ocm.DefaultChannelGroup, config.SharedVPCConfig.VPCEndpointRoleARN)
296301
return err
297302
}
@@ -423,8 +428,7 @@ func (r *ROSARoleConfigReconciler) createAccountRoles(ctx context.Context, roleC
423428
}
424429

425430
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)
431+
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)
428432
return err
429433
}
430434

@@ -471,23 +475,16 @@ func (r *ROSARoleConfigReconciler) deleteAccountRoles(ocmClient *ocm.Client, aws
471475
return err
472476
}
473477

474-
var err2, err3 error
475478
if canDeleteRole(clusters, roles.InstallerRoleARN) {
476-
err = awsClient.DeleteAccountRole(strings.Split(roles.InstallerRoleARN, "/")[1], config.Prefix, true, deleteHcpSharedVpcPolicies)
479+
err = errors.Join(err, awsClient.DeleteAccountRole(strings.Split(roles.InstallerRoleARN, "/")[1], config.Prefix, true, deleteHcpSharedVpcPolicies))
477480
}
478481
if canDeleteRole(clusters, roles.WorkerRoleARN) {
479-
err2 = awsClient.DeleteAccountRole(strings.Split(roles.WorkerRoleARN, "/")[1], config.Prefix, true, deleteHcpSharedVpcPolicies)
482+
err = errors.Join(err, awsClient.DeleteAccountRole(strings.Split(roles.WorkerRoleARN, "/")[1], config.Prefix, true, deleteHcpSharedVpcPolicies))
480483
}
481484
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
485+
err = errors.Join(err, awsClient.DeleteAccountRole(strings.Split(roles.SupportRoleARN, "/")[1], config.Prefix, true, deleteHcpSharedVpcPolicies))
489486
}
490-
return err3
487+
return err
491488
}
492489

493490
func (r *ROSARoleConfigReconciler) deleteOIDCProvider(ocmClient *ocm.Client, awsClient aws.Client, oidcConfigID string) error {

pkg/cloud/scope/rosaroleconfig.go

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright The Kubernetes Authors.
2+
Copyright 2025 The Kubernetes Authors.
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -19,8 +19,8 @@ package scope
1919
import (
2020
"context"
2121

22-
awsv2 "github.com/aws/aws-sdk-go-v2/aws"
23-
iamv2 "github.com/aws/aws-sdk-go-v2/service/iam"
22+
"github.com/aws/aws-sdk-go-v2/aws"
23+
"github.com/aws/aws-sdk-go-v2/service/iam"
2424
"github.com/pkg/errors"
2525
corev1 "k8s.io/api/core/v1"
2626
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -52,8 +52,8 @@ type RosaRoleConfigScope struct {
5252
patchHelper *patch.Helper
5353
RosaRoleConfig *expinfrav1.ROSARoleConfig
5454
serviceLimiters throttle.ServiceLimiters
55-
session awsv2.Config
56-
iamClient *iamv2.Client
55+
session aws.Config
56+
iamClient *iam.Client
5757
}
5858

5959
// NewRosaRoleConfigScope creates a new RosaRoleConfigScope from the supplied parameters.
@@ -71,21 +71,21 @@ func NewRosaRoleConfigScope(params RosaRoleConfigScopeParams) (*RosaRoleConfigSc
7171
RosaRoleConfig: params.RosaRoleConfig,
7272
}
7373

74-
sessionv2, serviceLimitersv2, err := sessionForClusterWithRegionV2(params.Client, RosaRoleConfigScope, "", params.Endpoints, params.Logger)
74+
session, serviceLimiters, err := sessionForClusterWithRegionV2(params.Client, RosaRoleConfigScope, "", params.Endpoints, params.Logger)
7575
if err != nil {
7676
return nil, errors.Errorf("failed to create aws V2 session: %v", err)
7777
}
7878

79-
iamClient := iamv2.NewFromConfig(*sessionv2)
79+
iamClient := iam.NewFromConfig(*session)
8080

8181
patchHelper, err := patch.NewHelper(params.RosaRoleConfig, params.Client)
8282
if err != nil {
8383
return nil, errors.Wrap(err, "failed to init patch helper")
8484
}
8585

8686
RosaRoleConfigScope.patchHelper = patchHelper
87-
RosaRoleConfigScope.session = *sessionv2
88-
RosaRoleConfigScope.serviceLimiters = serviceLimitersv2
87+
RosaRoleConfigScope.session = *session
88+
RosaRoleConfigScope.serviceLimiters = serviceLimiters
8989
RosaRoleConfigScope.iamClient = iamClient
9090

9191
return RosaRoleConfigScope, nil
@@ -97,7 +97,7 @@ func (s *RosaRoleConfigScope) IdentityRef() *infrav1.AWSIdentityReference {
9797
}
9898

9999
// Session returns the AWS SDK V2 session. Used for creating clients.
100-
func (s *RosaRoleConfigScope) Session() awsv2.Config {
100+
func (s *RosaRoleConfigScope) Session() aws.Config {
101101
return s.session
102102
}
103103

@@ -140,15 +140,10 @@ func (s *RosaRoleConfigScope) GetClient() client.Client {
140140
// PatchObject persists the RosaRoleConfig configuration and status.
141141
func (s *RosaRoleConfigScope) PatchObject() error {
142142
return s.patchHelper.Patch(
143-
context.TODO(),
143+
context.Background(),
144144
s.RosaRoleConfig)
145145
}
146146

147-
// Close closes the current scope persisting the RosaRoleConfig configuration and status.
148-
func (s *RosaRoleConfigScope) Close() error {
149-
return s.PatchObject()
150-
}
151-
152147
// CredentialsSecret returns the CredentialsSecret object.
153148
func (s *RosaRoleConfigScope) CredentialsSecret() *corev1.Secret {
154149
secretRef := s.RosaRoleConfig.Spec.CredentialsSecretRef
@@ -165,6 +160,6 @@ func (s *RosaRoleConfigScope) CredentialsSecret() *corev1.Secret {
165160
}
166161

167162
// IAMClient returns the IAM client.
168-
func (s *RosaRoleConfigScope) IAMClient() *iamv2.Client {
163+
func (s *RosaRoleConfigScope) IAMClient() *iam.Client {
169164
return s.iamClient
170165
}

pkg/rosa/client.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
117
// Package rosa provides a way to interact with the Red Hat OpenShift Service on AWS (ROSA) API.
218
package rosa
319

pkg/rosa/externalauthproviders.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
117
package rosa
218

319
import (

pkg/rosa/helpers.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
117
package rosa
218

319
import (

pkg/rosa/idps.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
117
package rosa
218

319
import (

0 commit comments

Comments
 (0)