Skip to content

Commit 52469b2

Browse files
authored
Merge pull request #4850 from muraee/rosa-cleanup-api
✨ ROSA: Cleanup
2 parents 5aa9d22 + d60bc63 commit 52469b2

File tree

8 files changed

+514
-181
lines changed

8 files changed

+514
-181
lines changed

config/crd/bases/controlplane.cluster.x-k8s.io_rosacontrolplanes.yaml

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -53,20 +53,10 @@ spec:
5353
description: AdditionalTags are user-defined tags to be added on the
5454
AWS resources associated with the control plane.
5555
type: object
56-
autoscaling:
57-
description: Autoscaling specifies auto scaling behaviour for the
58-
MachinePools.
59-
properties:
60-
maxReplicas:
61-
minimum: 1
62-
type: integer
63-
minReplicas:
64-
minimum: 1
65-
type: integer
66-
type: object
6756
availabilityZones:
68-
description: AWS AvailabilityZones of the worker nodes should match
69-
the AvailabilityZones of the Subnets.
57+
description: AvailabilityZones describe AWS AvailabilityZones of the
58+
worker nodes. should match the AvailabilityZones of the provided
59+
Subnets. a machinepool will be created for each availabilityZone.
7060
items:
7161
type: string
7262
type: array
@@ -108,6 +98,33 @@ spec:
10898
type: string
10999
type: object
110100
x-kubernetes-map-type: atomic
101+
defaultMachinePoolSpec:
102+
description: "DefaultMachinePoolSpec defines the configuration for
103+
the default machinepool(s) provisioned as part of the cluster creation.
104+
One MachinePool will be created with this configuration per AvailabilityZone.
105+
Those default machinepools are required for openshift cluster operators
106+
to work properly. As these machinepool not created using ROSAMachinePool
107+
CR, they will not be visible/managed by ROSA CAPI provider. `rosa
108+
list machinepools -c <rosaClusterName>` can be used to view those
109+
machinepools. \n This field will be removed in the future once the
110+
current limitation is resolved."
111+
properties:
112+
autoscaling:
113+
description: Autoscaling specifies auto scaling behaviour for
114+
this MachinePool.
115+
properties:
116+
maxReplicas:
117+
minimum: 1
118+
type: integer
119+
minReplicas:
120+
minimum: 1
121+
type: integer
122+
type: object
123+
instanceType:
124+
description: The instance type to use, for example `r5.xlarge`.
125+
Instance type ref; https://aws.amazon.com/ec2/instance-types/
126+
type: string
127+
type: object
111128
domainPrefix:
112129
description: DomainPrefix is an optional prefix added to the cluster's
113130
domain name. It will be used when generating a sub-domain for the
@@ -155,12 +172,8 @@ spec:
155172
- name
156173
type: object
157174
installerRoleARN:
158-
description: 'TODO: these are to satisfy ocm sdk. Explore how to drop
159-
them.'
160-
type: string
161-
instanceType:
162-
description: The instance type to use, for example `r5.xlarge`. Instance
163-
type ref; https://aws.amazon.com/ec2/instance-types/
175+
description: InstallerRoleARN is an AWS IAM role that OpenShift Cluster
176+
Manager will assume to create the cluster..
164177
type: string
165178
network:
166179
description: Network config for the ROSA HCP cluster.
@@ -371,11 +384,15 @@ spec:
371384
type: string
372385
type: array
373386
supportRoleARN:
387+
description: SupportRoleARN is an AWS IAM role used by Red Hat SREs
388+
to enable access to the cluster account in order to provide support.
374389
type: string
375390
version:
376391
description: OpenShift semantic version, for example "4.14.5".
377392
type: string
378393
workerRoleARN:
394+
description: WorkerRoleARN is an AWS IAM role that will be attached
395+
to worker instances.
379396
type: string
380397
required:
381398
- availabilityZones

controlplane/rosa/api/v1beta2/conditions_consts.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ const (
3131
// ROSAControlPlaneReconciliationFailedReason used to report failures while reconciling ROSAControlPlane.
3232
ROSAControlPlaneReconciliationFailedReason = "ReconciliationFailed"
3333

34+
// ROSAControlPlaneDeletionFailedReason used to report failures while deleting ROSAControlPlane.
35+
ROSAControlPlaneDeletionFailedReason = "DeletionFailed"
36+
3437
// ROSAControlPlaneInvalidConfigurationReason used to report invalid user input.
3538
ROSAControlPlaneInvalidConfigurationReason = "InvalidConfiguration"
3639
)

controlplane/rosa/api/v1beta2/rosacontrolplane_types.go

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,9 @@ type RosaControlPlaneSpec struct { //nolint: maligned
6666
// SubnetIDs should come in pairs; two per availability zone, one private and one public.
6767
Subnets []string `json:"subnets"`
6868

69-
// AWS AvailabilityZones of the worker nodes
70-
// should match the AvailabilityZones of the Subnets.
69+
// AvailabilityZones describe AWS AvailabilityZones of the worker nodes.
70+
// should match the AvailabilityZones of the provided Subnets.
71+
// a machinepool will be created for each availabilityZone.
7172
AvailabilityZones []string `json:"availabilityZones"`
7273

7374
// The AWS Region the cluster lives in.
@@ -82,10 +83,13 @@ type RosaControlPlaneSpec struct { //nolint: maligned
8283
// The ID of the OpenID Connect Provider.
8384
OIDCID string `json:"oidcID"`
8485

85-
// TODO: these are to satisfy ocm sdk. Explore how to drop them.
86-
InstallerRoleARN *string `json:"installerRoleARN"`
87-
SupportRoleARN *string `json:"supportRoleARN"`
88-
WorkerRoleARN *string `json:"workerRoleARN"`
86+
// InstallerRoleARN is an AWS IAM role that OpenShift Cluster Manager will assume to create the cluster..
87+
InstallerRoleARN string `json:"installerRoleARN"`
88+
// SupportRoleARN is an AWS IAM role used by Red Hat SREs to enable
89+
// access to the cluster account in order to provide support.
90+
SupportRoleARN string `json:"supportRoleARN"`
91+
// WorkerRoleARN is an AWS IAM role that will be attached to worker instances.
92+
WorkerRoleARN string `json:"workerRoleARN"`
8993

9094
// BillingAccount is an optional AWS account to use for billing the subscription fees for ROSA clusters.
9195
// The cost of running each ROSA cluster will be billed to the infrastructure account in which the cluster
@@ -98,18 +102,16 @@ type RosaControlPlaneSpec struct { //nolint: maligned
98102
// +optional
99103
BillingAccount string `json:"billingAccount,omitempty"`
100104

101-
// CredentialsSecretRef references a secret with necessary credentials to connect to the OCM API.
102-
// The secret should contain the following data keys:
103-
// - ocmToken: eyJhbGciOiJIUzI1NiIsI....
104-
// - ocmApiUrl: Optional, defaults to 'https://api.openshift.com'
105-
// +optional
106-
CredentialsSecretRef *corev1.LocalObjectReference `json:"credentialsSecretRef,omitempty"`
107-
108-
// IdentityRef is a reference to an identity to be used when reconciling the managed control plane.
109-
// If no identity is specified, the default identity for this controller will be used.
105+
// DefaultMachinePoolSpec defines the configuration for the default machinepool(s) provisioned as part of the cluster creation.
106+
// One MachinePool will be created with this configuration per AvailabilityZone. Those default machinepools are required for openshift cluster operators
107+
// to work properly.
108+
// As these machinepool not created using ROSAMachinePool CR, they will not be visible/managed by ROSA CAPI provider.
109+
// `rosa list machinepools -c <rosaClusterName>` can be used to view those machinepools.
110+
//
111+
// This field will be removed in the future once the current limitation is resolved.
110112
//
111113
// +optional
112-
IdentityRef *infrav1.AWSIdentityReference `json:"identityRef,omitempty"`
114+
DefaultMachinePoolSpec DefaultMachinePoolSpec `json:"defaultMachinePoolSpec,omitempty"`
113115

114116
// Network config for the ROSA HCP cluster.
115117
// +optional
@@ -123,14 +125,6 @@ type RosaControlPlaneSpec struct { //nolint: maligned
123125
// +optional
124126
EndpointAccess RosaEndpointAccessType `json:"endpointAccess,omitempty"`
125127

126-
// The instance type to use, for example `r5.xlarge`. Instance type ref; https://aws.amazon.com/ec2/instance-types/
127-
// +optional
128-
InstanceType string `json:"instanceType,omitempty"`
129-
130-
// Autoscaling specifies auto scaling behaviour for the MachinePools.
131-
// +optional
132-
Autoscaling *expinfrav1.RosaMachinePoolAutoScaling `json:"autoscaling,omitempty"`
133-
134128
// AdditionalTags are user-defined tags to be added on the AWS resources associated with the control plane.
135129
// +optional
136130
AdditionalTags infrav1.Tags `json:"additionalTags,omitempty"`
@@ -140,6 +134,19 @@ type RosaControlPlaneSpec struct { //nolint: maligned
140134
// +optional
141135
EtcdEncryptionKMSArn string `json:"etcdEncryptionKMSArn,omitempty"`
142136

137+
// CredentialsSecretRef references a secret with necessary credentials to connect to the OCM API.
138+
// The secret should contain the following data keys:
139+
// - ocmToken: eyJhbGciOiJIUzI1NiIsI....
140+
// - ocmApiUrl: Optional, defaults to 'https://api.openshift.com'
141+
// +optional
142+
CredentialsSecretRef *corev1.LocalObjectReference `json:"credentialsSecretRef,omitempty"`
143+
144+
// IdentityRef is a reference to an identity to be used when reconciling the managed control plane.
145+
// If no identity is specified, the default identity for this controller will be used.
146+
//
147+
// +optional
148+
IdentityRef *infrav1.AWSIdentityReference `json:"identityRef,omitempty"`
149+
143150
// ControlPlaneEndpoint represents the endpoint used to communicate with the control plane.
144151
// +optional
145152
ControlPlaneEndpoint clusterv1.APIEndpoint `json:"controlPlaneEndpoint"`
@@ -174,6 +181,17 @@ type NetworkSpec struct {
174181
NetworkType string `json:"networkType,omitempty"`
175182
}
176183

184+
// DefaultMachinePoolSpec defines the configuration for the required worker nodes provisioned as part of the cluster creation.
185+
type DefaultMachinePoolSpec struct {
186+
// The instance type to use, for example `r5.xlarge`. Instance type ref; https://aws.amazon.com/ec2/instance-types/
187+
// +optional
188+
InstanceType string `json:"instanceType,omitempty"`
189+
190+
// Autoscaling specifies auto scaling behaviour for this MachinePool.
191+
// +optional
192+
Autoscaling *expinfrav1.RosaMachinePoolAutoScaling `json:"autoscaling,omitempty"`
193+
}
194+
177195
// AWSRolesRef contains references to various AWS IAM roles required for operators to make calls against the AWS API.
178196
type AWSRolesRef struct {
179197
// The referenced role must have a trust relationship that allows it to be assumed via web identity.

controlplane/rosa/api/v1beta2/zz_generated.deepcopy.go

Lines changed: 30 additions & 29 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

controlplane/rosa/controllers/rosacontrolplane_controller.go

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import (
5050

5151
rosacontrolplanev1 "sigs.k8s.io/cluster-api-provider-aws/v2/controlplane/rosa/api/v1beta2"
5252
expinfrav1 "sigs.k8s.io/cluster-api-provider-aws/v2/exp/api/v1beta2"
53+
"sigs.k8s.io/cluster-api-provider-aws/v2/pkg/annotations"
5354
"sigs.k8s.io/cluster-api-provider-aws/v2/pkg/cloud/scope"
5455
"sigs.k8s.io/cluster-api-provider-aws/v2/pkg/logger"
5556
"sigs.k8s.io/cluster-api-provider-aws/v2/pkg/rosa"
@@ -66,6 +67,9 @@ const (
6667
rosaControlPlaneKind = "ROSAControlPlane"
6768
// ROSAControlPlaneFinalizer allows the controller to clean up resources on delete.
6869
ROSAControlPlaneFinalizer = "rosacontrolplane.controlplane.cluster.x-k8s.io"
70+
71+
// ROSAControlPlaneForceDeleteAnnotation annotation can be set to force the deletion of ROSAControlPlane bypassing any deletion validations/errors.
72+
ROSAControlPlaneForceDeleteAnnotation = "controlplane.cluster.x-k8s.io/rosacontrolplane-force-delete"
6973
)
7074

7175
// ROSAControlPlaneReconciler reconciles a ROSAControlPlane object.
@@ -283,20 +287,20 @@ func (r *ROSAControlPlaneReconciler) reconcileNormal(ctx context.Context, rosaSc
283287
ChannelGroup: ocm.DefaultChannelGroup,
284288
DisableWorkloadMonitoring: ptr.To(true),
285289
DefaultIngress: ocm.NewDefaultIngressSpec(), // n.b. this is a no-op when it's set to the default value
286-
ComputeMachineType: rosaScope.ControlPlane.Spec.InstanceType,
290+
ComputeMachineType: rosaScope.ControlPlane.Spec.DefaultMachinePoolSpec.InstanceType,
291+
AvailabilityZones: rosaScope.ControlPlane.Spec.AvailabilityZones,
287292
Tags: rosaScope.ControlPlane.Spec.AdditionalTags,
288293
EtcdEncryption: rosaScope.ControlPlane.Spec.EtcdEncryptionKMSArn != "",
289294
EtcdEncryptionKMSArn: rosaScope.ControlPlane.Spec.EtcdEncryptionKMSArn,
290295

291-
SubnetIds: rosaScope.ControlPlane.Spec.Subnets,
292-
AvailabilityZones: rosaScope.ControlPlane.Spec.AvailabilityZones,
293-
IsSTS: true,
294-
RoleARN: *rosaScope.ControlPlane.Spec.InstallerRoleARN,
295-
SupportRoleARN: *rosaScope.ControlPlane.Spec.SupportRoleARN,
296-
WorkerRoleARN: *rosaScope.ControlPlane.Spec.WorkerRoleARN,
297-
OperatorIAMRoles: operatorIAMRoles(rosaScope.ControlPlane.Spec.RolesRef),
298-
OidcConfigId: rosaScope.ControlPlane.Spec.OIDCID,
299-
Mode: "auto",
296+
SubnetIds: rosaScope.ControlPlane.Spec.Subnets,
297+
IsSTS: true,
298+
RoleARN: rosaScope.ControlPlane.Spec.InstallerRoleARN,
299+
SupportRoleARN: rosaScope.ControlPlane.Spec.SupportRoleARN,
300+
WorkerRoleARN: rosaScope.ControlPlane.Spec.WorkerRoleARN,
301+
OperatorIAMRoles: operatorIAMRoles(rosaScope.ControlPlane.Spec.RolesRef),
302+
OidcConfigId: rosaScope.ControlPlane.Spec.OIDCID,
303+
Mode: "auto",
300304
Hypershift: ocm.Hypershift{
301305
Enabled: true,
302306
},
@@ -338,10 +342,10 @@ func (r *ROSAControlPlaneReconciler) reconcileNormal(ctx context.Context, rosaSc
338342
ocmClusterSpec.NetworkType = networkSpec.NetworkType
339343
}
340344

341-
// Set autoscale replica
342-
if rosaScope.ControlPlane.Spec.Autoscaling != nil {
343-
ocmClusterSpec.MaxReplicas = rosaScope.ControlPlane.Spec.Autoscaling.MaxReplicas
344-
ocmClusterSpec.MinReplicas = rosaScope.ControlPlane.Spec.Autoscaling.MinReplicas
345+
// Set cluster compute autoscaling replicas
346+
if computeAutoscaling := rosaScope.ControlPlane.Spec.DefaultMachinePoolSpec.Autoscaling; computeAutoscaling != nil {
347+
ocmClusterSpec.MaxReplicas = computeAutoscaling.MaxReplicas
348+
ocmClusterSpec.MinReplicas = computeAutoscaling.MinReplicas
345349
}
346350

347351
cluster, err = ocmClient.CreateCluster(ocmClusterSpec)
@@ -429,12 +433,29 @@ func (r *ROSAControlPlaneReconciler) reconcileDelete(ctx context.Context, rosaSc
429433
return ctrl.Result{}, nil
430434
}
431435

436+
bestEffort := false
437+
if value, found := annotations.Get(rosaScope.ControlPlane, ROSAControlPlaneForceDeleteAnnotation); found && value != "false" {
438+
bestEffort = true
439+
}
440+
432441
if cluster.Status().State() != cmv1.ClusterStateUninstalling {
433-
if _, err := ocmClient.DeleteCluster(cluster.ID(), true, creator); err != nil {
442+
if _, err := ocmClient.DeleteCluster(cluster.ID(), bestEffort, creator); err != nil {
443+
conditions.MarkFalse(rosaScope.ControlPlane,
444+
rosacontrolplanev1.ROSAControlPlaneReadyCondition,
445+
rosacontrolplanev1.ROSAControlPlaneDeletionFailedReason,
446+
clusterv1.ConditionSeverityError,
447+
"failed to delete ROSAControlPlane: %s; if the error can't be resolved, set '%s' annotation to force the deletion",
448+
err.Error(),
449+
ROSAControlPlaneForceDeleteAnnotation)
434450
return ctrl.Result{}, err
435451
}
436452
}
437453

454+
conditions.MarkFalse(rosaScope.ControlPlane,
455+
rosacontrolplanev1.ROSAControlPlaneReadyCondition,
456+
string(cluster.Status().State()),
457+
clusterv1.ConditionSeverityInfo,
458+
"deleting")
438459
rosaScope.ControlPlane.Status.Ready = false
439460
rosaScope.Info("waiting for cluster to be deleted")
440461
// Requeue to remove the finalizer when the cluster is fully deleted.

0 commit comments

Comments
 (0)