diff --git a/config/crd/bases/controlplane.cluster.x-k8s.io_rosacontrolplanes.yaml b/config/crd/bases/controlplane.cluster.x-k8s.io_rosacontrolplanes.yaml index 20273c1288..3e07f2f6c7 100644 --- a/config/crd/bases/controlplane.cluster.x-k8s.io_rosacontrolplanes.yaml +++ b/config/crd/bases/controlplane.cluster.x-k8s.io_rosacontrolplanes.yaml @@ -53,20 +53,10 @@ spec: description: AdditionalTags are user-defined tags to be added on the AWS resources associated with the control plane. type: object - autoscaling: - description: Autoscaling specifies auto scaling behaviour for the - MachinePools. - properties: - maxReplicas: - minimum: 1 - type: integer - minReplicas: - minimum: 1 - type: integer - type: object availabilityZones: - description: AWS AvailabilityZones of the worker nodes should match - the AvailabilityZones of the Subnets. + description: AvailabilityZones describe AWS AvailabilityZones of the + worker nodes. should match the AvailabilityZones of the provided + Subnets. a machinepool will be created for each availabilityZone. items: type: string type: array @@ -108,6 +98,33 @@ spec: type: string type: object x-kubernetes-map-type: atomic + defaultMachinePoolSpec: + description: "DefaultMachinePoolSpec defines the configuration for + the default machinepool(s) provisioned as part of the cluster creation. + One MachinePool will be created with this configuration per AvailabilityZone. + Those default machinepools are required for openshift cluster operators + to work properly. As these machinepool not created using ROSAMachinePool + CR, they will not be visible/managed by ROSA CAPI provider. `rosa + list machinepools -c ` can be used to view those + machinepools. \n This field will be removed in the future once the + current limitation is resolved." + properties: + autoscaling: + description: Autoscaling specifies auto scaling behaviour for + this MachinePool. + properties: + maxReplicas: + minimum: 1 + type: integer + minReplicas: + minimum: 1 + type: integer + type: object + instanceType: + description: The instance type to use, for example `r5.xlarge`. + Instance type ref; https://aws.amazon.com/ec2/instance-types/ + type: string + type: object domainPrefix: description: DomainPrefix is an optional prefix added to the cluster's domain name. It will be used when generating a sub-domain for the @@ -155,12 +172,8 @@ spec: - name type: object installerRoleARN: - description: 'TODO: these are to satisfy ocm sdk. Explore how to drop - them.' - type: string - instanceType: - description: The instance type to use, for example `r5.xlarge`. Instance - type ref; https://aws.amazon.com/ec2/instance-types/ + description: InstallerRoleARN is an AWS IAM role that OpenShift Cluster + Manager will assume to create the cluster.. type: string network: description: Network config for the ROSA HCP cluster. @@ -371,11 +384,15 @@ spec: type: string type: array supportRoleARN: + description: SupportRoleARN is an AWS IAM role used by Red Hat SREs + to enable access to the cluster account in order to provide support. type: string version: description: OpenShift semantic version, for example "4.14.5". type: string workerRoleARN: + description: WorkerRoleARN is an AWS IAM role that will be attached + to worker instances. type: string required: - availabilityZones diff --git a/controlplane/rosa/api/v1beta2/conditions_consts.go b/controlplane/rosa/api/v1beta2/conditions_consts.go index a80e534c61..50dc2dc5d9 100644 --- a/controlplane/rosa/api/v1beta2/conditions_consts.go +++ b/controlplane/rosa/api/v1beta2/conditions_consts.go @@ -31,6 +31,9 @@ const ( // ROSAControlPlaneReconciliationFailedReason used to report failures while reconciling ROSAControlPlane. ROSAControlPlaneReconciliationFailedReason = "ReconciliationFailed" + // ROSAControlPlaneDeletionFailedReason used to report failures while deleting ROSAControlPlane. + ROSAControlPlaneDeletionFailedReason = "DeletionFailed" + // ROSAControlPlaneInvalidConfigurationReason used to report invalid user input. ROSAControlPlaneInvalidConfigurationReason = "InvalidConfiguration" ) diff --git a/controlplane/rosa/api/v1beta2/rosacontrolplane_types.go b/controlplane/rosa/api/v1beta2/rosacontrolplane_types.go index 8c491425c6..6504913dd9 100644 --- a/controlplane/rosa/api/v1beta2/rosacontrolplane_types.go +++ b/controlplane/rosa/api/v1beta2/rosacontrolplane_types.go @@ -66,8 +66,9 @@ type RosaControlPlaneSpec struct { //nolint: maligned // SubnetIDs should come in pairs; two per availability zone, one private and one public. Subnets []string `json:"subnets"` - // AWS AvailabilityZones of the worker nodes - // should match the AvailabilityZones of the Subnets. + // AvailabilityZones describe AWS AvailabilityZones of the worker nodes. + // should match the AvailabilityZones of the provided Subnets. + // a machinepool will be created for each availabilityZone. AvailabilityZones []string `json:"availabilityZones"` // The AWS Region the cluster lives in. @@ -82,10 +83,13 @@ type RosaControlPlaneSpec struct { //nolint: maligned // The ID of the OpenID Connect Provider. OIDCID string `json:"oidcID"` - // TODO: these are to satisfy ocm sdk. Explore how to drop them. - InstallerRoleARN *string `json:"installerRoleARN"` - SupportRoleARN *string `json:"supportRoleARN"` - WorkerRoleARN *string `json:"workerRoleARN"` + // InstallerRoleARN is an AWS IAM role that OpenShift Cluster Manager will assume to create the cluster.. + InstallerRoleARN string `json:"installerRoleARN"` + // SupportRoleARN is an AWS IAM role used by Red Hat SREs to enable + // access to the cluster account in order to provide support. + SupportRoleARN string `json:"supportRoleARN"` + // WorkerRoleARN is an AWS IAM role that will be attached to worker instances. + WorkerRoleARN string `json:"workerRoleARN"` // BillingAccount is an optional AWS account to use for billing the subscription fees for ROSA clusters. // 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 // +optional BillingAccount string `json:"billingAccount,omitempty"` - // CredentialsSecretRef references a secret with necessary credentials to connect to the OCM API. - // The secret should contain the following data keys: - // - ocmToken: eyJhbGciOiJIUzI1NiIsI.... - // - ocmApiUrl: Optional, defaults to 'https://api.openshift.com' - // +optional - CredentialsSecretRef *corev1.LocalObjectReference `json:"credentialsSecretRef,omitempty"` - - // IdentityRef is a reference to an identity to be used when reconciling the managed control plane. - // If no identity is specified, the default identity for this controller will be used. + // DefaultMachinePoolSpec defines the configuration for the default machinepool(s) provisioned as part of the cluster creation. + // One MachinePool will be created with this configuration per AvailabilityZone. Those default machinepools are required for openshift cluster operators + // to work properly. + // As these machinepool not created using ROSAMachinePool CR, they will not be visible/managed by ROSA CAPI provider. + // `rosa list machinepools -c ` can be used to view those machinepools. + // + // This field will be removed in the future once the current limitation is resolved. // // +optional - IdentityRef *infrav1.AWSIdentityReference `json:"identityRef,omitempty"` + DefaultMachinePoolSpec DefaultMachinePoolSpec `json:"defaultMachinePoolSpec,omitempty"` // Network config for the ROSA HCP cluster. // +optional @@ -123,14 +125,6 @@ type RosaControlPlaneSpec struct { //nolint: maligned // +optional EndpointAccess RosaEndpointAccessType `json:"endpointAccess,omitempty"` - // The instance type to use, for example `r5.xlarge`. Instance type ref; https://aws.amazon.com/ec2/instance-types/ - // +optional - InstanceType string `json:"instanceType,omitempty"` - - // Autoscaling specifies auto scaling behaviour for the MachinePools. - // +optional - Autoscaling *expinfrav1.RosaMachinePoolAutoScaling `json:"autoscaling,omitempty"` - // AdditionalTags are user-defined tags to be added on the AWS resources associated with the control plane. // +optional AdditionalTags infrav1.Tags `json:"additionalTags,omitempty"` @@ -140,6 +134,19 @@ type RosaControlPlaneSpec struct { //nolint: maligned // +optional EtcdEncryptionKMSArn string `json:"etcdEncryptionKMSArn,omitempty"` + // CredentialsSecretRef references a secret with necessary credentials to connect to the OCM API. + // The secret should contain the following data keys: + // - ocmToken: eyJhbGciOiJIUzI1NiIsI.... + // - ocmApiUrl: Optional, defaults to 'https://api.openshift.com' + // +optional + CredentialsSecretRef *corev1.LocalObjectReference `json:"credentialsSecretRef,omitempty"` + + // IdentityRef is a reference to an identity to be used when reconciling the managed control plane. + // If no identity is specified, the default identity for this controller will be used. + // + // +optional + IdentityRef *infrav1.AWSIdentityReference `json:"identityRef,omitempty"` + // ControlPlaneEndpoint represents the endpoint used to communicate with the control plane. // +optional ControlPlaneEndpoint clusterv1.APIEndpoint `json:"controlPlaneEndpoint"` @@ -174,6 +181,17 @@ type NetworkSpec struct { NetworkType string `json:"networkType,omitempty"` } +// DefaultMachinePoolSpec defines the configuration for the required worker nodes provisioned as part of the cluster creation. +type DefaultMachinePoolSpec struct { + // The instance type to use, for example `r5.xlarge`. Instance type ref; https://aws.amazon.com/ec2/instance-types/ + // +optional + InstanceType string `json:"instanceType,omitempty"` + + // Autoscaling specifies auto scaling behaviour for this MachinePool. + // +optional + Autoscaling *expinfrav1.RosaMachinePoolAutoScaling `json:"autoscaling,omitempty"` +} + // AWSRolesRef contains references to various AWS IAM roles required for operators to make calls against the AWS API. type AWSRolesRef struct { // The referenced role must have a trust relationship that allows it to be assumed via web identity. diff --git a/controlplane/rosa/api/v1beta2/zz_generated.deepcopy.go b/controlplane/rosa/api/v1beta2/zz_generated.deepcopy.go index 7600d4cad2..91e37e290a 100644 --- a/controlplane/rosa/api/v1beta2/zz_generated.deepcopy.go +++ b/controlplane/rosa/api/v1beta2/zz_generated.deepcopy.go @@ -43,6 +43,26 @@ func (in *AWSRolesRef) DeepCopy() *AWSRolesRef { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DefaultMachinePoolSpec) DeepCopyInto(out *DefaultMachinePoolSpec) { + *out = *in + if in.Autoscaling != nil { + in, out := &in.Autoscaling, &out.Autoscaling + *out = new(expapiv1beta2.RosaMachinePoolAutoScaling) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DefaultMachinePoolSpec. +func (in *DefaultMachinePoolSpec) DeepCopy() *DefaultMachinePoolSpec { + if in == nil { + return nil + } + out := new(DefaultMachinePoolSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NetworkSpec) DeepCopyInto(out *NetworkSpec) { *out = *in @@ -131,20 +151,18 @@ func (in *RosaControlPlaneSpec) DeepCopyInto(out *RosaControlPlaneSpec) { copy(*out, *in) } out.RolesRef = in.RolesRef - if in.InstallerRoleARN != nil { - in, out := &in.InstallerRoleARN, &out.InstallerRoleARN - *out = new(string) - **out = **in - } - if in.SupportRoleARN != nil { - in, out := &in.SupportRoleARN, &out.SupportRoleARN - *out = new(string) + in.DefaultMachinePoolSpec.DeepCopyInto(&out.DefaultMachinePoolSpec) + if in.Network != nil { + in, out := &in.Network, &out.Network + *out = new(NetworkSpec) **out = **in } - if in.WorkerRoleARN != nil { - in, out := &in.WorkerRoleARN, &out.WorkerRoleARN - *out = new(string) - **out = **in + if in.AdditionalTags != nil { + in, out := &in.AdditionalTags, &out.AdditionalTags + *out = make(apiv1beta2.Tags, len(*in)) + for key, val := range *in { + (*out)[key] = val + } } if in.CredentialsSecretRef != nil { in, out := &in.CredentialsSecretRef, &out.CredentialsSecretRef @@ -156,23 +174,6 @@ func (in *RosaControlPlaneSpec) DeepCopyInto(out *RosaControlPlaneSpec) { *out = new(apiv1beta2.AWSIdentityReference) **out = **in } - if in.Network != nil { - in, out := &in.Network, &out.Network - *out = new(NetworkSpec) - **out = **in - } - if in.Autoscaling != nil { - in, out := &in.Autoscaling, &out.Autoscaling - *out = new(expapiv1beta2.RosaMachinePoolAutoScaling) - **out = **in - } - if in.AdditionalTags != nil { - in, out := &in.AdditionalTags, &out.AdditionalTags - *out = make(apiv1beta2.Tags, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } out.ControlPlaneEndpoint = in.ControlPlaneEndpoint } diff --git a/controlplane/rosa/controllers/rosacontrolplane_controller.go b/controlplane/rosa/controllers/rosacontrolplane_controller.go index 2aaf9dd496..534679ce95 100644 --- a/controlplane/rosa/controllers/rosacontrolplane_controller.go +++ b/controlplane/rosa/controllers/rosacontrolplane_controller.go @@ -50,6 +50,7 @@ import ( rosacontrolplanev1 "sigs.k8s.io/cluster-api-provider-aws/v2/controlplane/rosa/api/v1beta2" expinfrav1 "sigs.k8s.io/cluster-api-provider-aws/v2/exp/api/v1beta2" + "sigs.k8s.io/cluster-api-provider-aws/v2/pkg/annotations" "sigs.k8s.io/cluster-api-provider-aws/v2/pkg/cloud/scope" "sigs.k8s.io/cluster-api-provider-aws/v2/pkg/logger" "sigs.k8s.io/cluster-api-provider-aws/v2/pkg/rosa" @@ -66,6 +67,9 @@ const ( rosaControlPlaneKind = "ROSAControlPlane" // ROSAControlPlaneFinalizer allows the controller to clean up resources on delete. ROSAControlPlaneFinalizer = "rosacontrolplane.controlplane.cluster.x-k8s.io" + + // ROSAControlPlaneForceDeleteAnnotation annotation can be set to force the deletion of ROSAControlPlane bypassing any deletion validations/errors. + ROSAControlPlaneForceDeleteAnnotation = "controlplane.cluster.x-k8s.io/rosacontrolplane-force-delete" ) // ROSAControlPlaneReconciler reconciles a ROSAControlPlane object. @@ -283,20 +287,20 @@ func (r *ROSAControlPlaneReconciler) reconcileNormal(ctx context.Context, rosaSc ChannelGroup: ocm.DefaultChannelGroup, DisableWorkloadMonitoring: ptr.To(true), DefaultIngress: ocm.NewDefaultIngressSpec(), // n.b. this is a no-op when it's set to the default value - ComputeMachineType: rosaScope.ControlPlane.Spec.InstanceType, + ComputeMachineType: rosaScope.ControlPlane.Spec.DefaultMachinePoolSpec.InstanceType, + AvailabilityZones: rosaScope.ControlPlane.Spec.AvailabilityZones, Tags: rosaScope.ControlPlane.Spec.AdditionalTags, EtcdEncryption: rosaScope.ControlPlane.Spec.EtcdEncryptionKMSArn != "", EtcdEncryptionKMSArn: rosaScope.ControlPlane.Spec.EtcdEncryptionKMSArn, - SubnetIds: rosaScope.ControlPlane.Spec.Subnets, - AvailabilityZones: rosaScope.ControlPlane.Spec.AvailabilityZones, - IsSTS: true, - RoleARN: *rosaScope.ControlPlane.Spec.InstallerRoleARN, - SupportRoleARN: *rosaScope.ControlPlane.Spec.SupportRoleARN, - WorkerRoleARN: *rosaScope.ControlPlane.Spec.WorkerRoleARN, - OperatorIAMRoles: operatorIAMRoles(rosaScope.ControlPlane.Spec.RolesRef), - OidcConfigId: rosaScope.ControlPlane.Spec.OIDCID, - Mode: "auto", + SubnetIds: rosaScope.ControlPlane.Spec.Subnets, + IsSTS: true, + RoleARN: rosaScope.ControlPlane.Spec.InstallerRoleARN, + SupportRoleARN: rosaScope.ControlPlane.Spec.SupportRoleARN, + WorkerRoleARN: rosaScope.ControlPlane.Spec.WorkerRoleARN, + OperatorIAMRoles: operatorIAMRoles(rosaScope.ControlPlane.Spec.RolesRef), + OidcConfigId: rosaScope.ControlPlane.Spec.OIDCID, + Mode: "auto", Hypershift: ocm.Hypershift{ Enabled: true, }, @@ -338,10 +342,10 @@ func (r *ROSAControlPlaneReconciler) reconcileNormal(ctx context.Context, rosaSc ocmClusterSpec.NetworkType = networkSpec.NetworkType } - // Set autoscale replica - if rosaScope.ControlPlane.Spec.Autoscaling != nil { - ocmClusterSpec.MaxReplicas = rosaScope.ControlPlane.Spec.Autoscaling.MaxReplicas - ocmClusterSpec.MinReplicas = rosaScope.ControlPlane.Spec.Autoscaling.MinReplicas + // Set cluster compute autoscaling replicas + if computeAutoscaling := rosaScope.ControlPlane.Spec.DefaultMachinePoolSpec.Autoscaling; computeAutoscaling != nil { + ocmClusterSpec.MaxReplicas = computeAutoscaling.MaxReplicas + ocmClusterSpec.MinReplicas = computeAutoscaling.MinReplicas } cluster, err = ocmClient.CreateCluster(ocmClusterSpec) @@ -429,12 +433,29 @@ func (r *ROSAControlPlaneReconciler) reconcileDelete(ctx context.Context, rosaSc return ctrl.Result{}, nil } + bestEffort := false + if value, found := annotations.Get(rosaScope.ControlPlane, ROSAControlPlaneForceDeleteAnnotation); found && value != "false" { + bestEffort = true + } + if cluster.Status().State() != cmv1.ClusterStateUninstalling { - if _, err := ocmClient.DeleteCluster(cluster.ID(), true, creator); err != nil { + if _, err := ocmClient.DeleteCluster(cluster.ID(), bestEffort, creator); err != nil { + conditions.MarkFalse(rosaScope.ControlPlane, + rosacontrolplanev1.ROSAControlPlaneReadyCondition, + rosacontrolplanev1.ROSAControlPlaneDeletionFailedReason, + clusterv1.ConditionSeverityError, + "failed to delete ROSAControlPlane: %s; if the error can't be resolved, set '%s' annotation to force the deletion", + err.Error(), + ROSAControlPlaneForceDeleteAnnotation) return ctrl.Result{}, err } } + conditions.MarkFalse(rosaScope.ControlPlane, + rosacontrolplanev1.ROSAControlPlaneReadyCondition, + string(cluster.Status().State()), + clusterv1.ConditionSeverityInfo, + "deleting") rosaScope.ControlPlane.Status.Ready = false rosaScope.Info("waiting for cluster to be deleted") // Requeue to remove the finalizer when the cluster is fully deleted. diff --git a/docs/book/src/crd/index.md b/docs/book/src/crd/index.md index 1bc6c3aada..ff7618b852 100644 --- a/docs/book/src/crd/index.md +++ b/docs/book/src/crd/index.md @@ -2636,6 +2636,9 @@ string

bootstrap.cluster.x-k8s.io/v1beta2

+

+

Package v1beta2 contains API Schema definitions for the Amazon EKS Bootstrap v1beta2 API group.

+

Resource Types:

DiskSetup @@ -5752,6 +5755,7 @@ bool (Appears on:AWSManagedControlPlaneStatus)

+

IdentityProviderStatus holds the status for associated identity provider

@@ -5864,6 +5868,7 @@ string (Appears on:AWSManagedControlPlaneSpec)

+

OIDCIdentityProviderConfig defines the configuration for an OIDC identity provider.

@@ -6168,7 +6173,7 @@ KubernetesMapping

controlplane.cluster.x-k8s.io/v1beta2

-

package v1beta2 contains API Schema definitions for the controlplane v1beta2 API group

+

Package v1beta2 contains API Schema definitions for the controlplane v1beta2 API group

Resource Types:
    @@ -7631,6 +7636,7 @@ bool (Appears on:AWSManagedControlPlaneStatus)

    +

    IdentityProviderStatus holds the status for associated identity provider.

    @@ -7743,6 +7749,7 @@ string (Appears on:AWSManagedControlPlaneSpec)

    +

    OIDCIdentityProviderConfig represents the configuration for an OIDC identity provider.

    @@ -8498,6 +8505,50 @@ string
    +

    DefaultMachinePoolSpec +

    +

    +(Appears on:RosaControlPlaneSpec) +

    +

    +

    DefaultMachinePoolSpec defines the configuration for the required worker nodes provisioned as part of the cluster creation.

    +

    + + + + + + + + + + + + + + + + + +
    FieldDescription
    +instanceType
    + +string + +
    +(Optional) +

    The instance type to use, for example r5.xlarge. Instance type ref; https://aws.amazon.com/ec2/instance-types/

    +
    +autoscaling
    + + +RosaMachinePoolAutoScaling + + +
    +(Optional) +

    Autoscaling specifies auto scaling behaviour for this MachinePool.

    +

    NetworkSpec

    @@ -8579,6 +8630,7 @@ string

    ROSAControlPlane

    +

    ROSAControlPlane is the Schema for the ROSAControlPlanes API.

    @@ -8625,7 +8677,22 @@ string + + + + @@ -8648,8 +8715,9 @@ SubnetIDs should come in pairs; two per availability zone, one private and one p @@ -8706,7 +8774,7 @@ string @@ -8717,6 +8785,8 @@ string @@ -8727,6 +8797,7 @@ string @@ -8745,34 +8816,21 @@ is running.

    - - - - @@ -8806,55 +8864,61 @@ default is Public.

    @@ -8894,6 +8958,7 @@ RosaControlPlaneStatus (Appears on:ROSAControlPlane)

    +

    RosaControlPlaneSpec defines the desired state of ROSAControlPlane.

    Cluster name must be valid DNS-1035 label, so it must consist of lower case alphanumeric characters or ‘-’, start with an alphabetic character, end with an alphanumeric character -and have a max length of 15 characters.

    +and have a max length of 54 characters.

    +
    +domainPrefix
    + +string + +
    +(Optional) +

    DomainPrefix is an optional prefix added to the cluster’s domain name. It will be used +when generating a sub-domain for the cluster on openshiftapps domain. It must be valid DNS-1035 label +consisting of lower case alphanumeric characters or ‘-’, start with an alphabetic character +end with an alphanumeric character and have a max length of 15 characters.

    -

    AWS AvailabilityZones of the worker nodes -should match the AvailabilityZones of the Subnets.

    +

    AvailabilityZones describe AWS AvailabilityZones of the worker nodes. +should match the AvailabilityZones of the provided Subnets. +a machinepool will be created for each availabilityZone.

    -

    TODO: these are to satisfy ocm sdk. Explore how to drop them.

    +

    InstallerRoleARN is an AWS IAM role that OpenShift Cluster Manager will assume to create the cluster..

    +

    SupportRoleARN is an AWS IAM role used by Red Hat SREs to enable +access to the cluster account in order to provide support.

    +

    WorkerRoleARN is an AWS IAM role that will be attached to worker instances.

    -credentialsSecretRef
    - - -Kubernetes core/v1.LocalObjectReference - - -
    -(Optional) -

    CredentialsSecretRef references a secret with necessary credentials to connect to the OCM API. -The secret should contain the following data keys: -- ocmToken: eyJhbGciOiJIUzI1NiIsI…. -- ocmApiUrl: Optional, defaults to ‘https://api.openshift.com’

    -
    -identityRef
    +defaultMachinePoolSpec
    - -AWSIdentityReference + +DefaultMachinePoolSpec
    (Optional) -

    IdentityRef is a reference to an identity to be used when reconciling the managed control plane. -If no identity is specified, the default identity for this controller will be used.

    +

    DefaultMachinePoolSpec defines the configuration for the default machinepool(s) provisioned as part of the cluster creation. +One MachinePool will be created with this configuration per AvailabilityZone. Those default machinepools are required for openshift cluster operators +to work properly. +As these machinepool not created using ROSAMachinePool CR, they will not be visible/managed by ROSA CAPI provider. +rosa list machinepools -c <rosaClusterName> can be used to view those machinepools.

    +

    This field will be removed in the future once the current limitation is resolved.

    -instanceType
    +additionalTags
    -string + +Tags +
    (Optional) -

    The instance type to use, for example r5.xlarge. Instance type ref; https://aws.amazon.com/ec2/instance-types/

    +

    AdditionalTags are user-defined tags to be added on the AWS resources associated with the control plane.

    -autoscaling
    +etcdEncryptionKMSArn
    - -RosaMachinePoolAutoScaling - +string
    (Optional) -

    Autoscaling specifies auto scaling behaviour for the MachinePools.

    +

    EtcdEncryptionKMSArn is the ARN of the KMS key used to encrypt etcd. The key itself needs to be +created out-of-band by the user and tagged with red-hat:true.

    -additionalTags
    +credentialsSecretRef
    - -Tags + +Kubernetes core/v1.LocalObjectReference
    (Optional) -

    AdditionalTags are user-defined tags to be added on the AWS resources associated with the control plane.

    +

    CredentialsSecretRef references a secret with necessary credentials to connect to the OCM API. +The secret should contain the following data keys: +- ocmToken: eyJhbGciOiJIUzI1NiIsI…. +- ocmApiUrl: Optional, defaults to ‘https://api.openshift.com’

    -etcdEncryptionKMSArn
    +identityRef
    -string + +AWSIdentityReference +
    (Optional) -

    EtcdEncryptionKMSArn is the ARN of the KMS key used to encrypt etcd. The key itself needs to be -created out-of-band by the user and tagged with red-hat:true.

    +

    IdentityRef is a reference to an identity to be used when reconciling the managed control plane. +If no identity is specified, the default identity for this controller will be used.

    @@ -8913,7 +8978,22 @@ string + + + + @@ -8936,8 +9016,9 @@ SubnetIDs should come in pairs; two per availability zone, one private and one p @@ -8994,7 +9075,7 @@ string @@ -9005,6 +9086,8 @@ string @@ -9015,6 +9098,7 @@ string @@ -9033,34 +9117,21 @@ is running.

    - - - - @@ -9094,55 +9165,61 @@ default is Public.

    @@ -9167,6 +9244,7 @@ Cluster API api/v1beta1.APIEndpoint (Appears on:ROSAControlPlane)

    +

    RosaControlPlaneStatus defines the observed state of ROSAControlPlane.

    Cluster name must be valid DNS-1035 label, so it must consist of lower case alphanumeric characters or ‘-’, start with an alphabetic character, end with an alphanumeric character -and have a max length of 15 characters.

    +and have a max length of 54 characters.

    +
    +domainPrefix
    + +string + +
    +(Optional) +

    DomainPrefix is an optional prefix added to the cluster’s domain name. It will be used +when generating a sub-domain for the cluster on openshiftapps domain. It must be valid DNS-1035 label +consisting of lower case alphanumeric characters or ‘-’, start with an alphabetic character +end with an alphanumeric character and have a max length of 15 characters.

    -

    AWS AvailabilityZones of the worker nodes -should match the AvailabilityZones of the Subnets.

    +

    AvailabilityZones describe AWS AvailabilityZones of the worker nodes. +should match the AvailabilityZones of the provided Subnets. +a machinepool will be created for each availabilityZone.

    -

    TODO: these are to satisfy ocm sdk. Explore how to drop them.

    +

    InstallerRoleARN is an AWS IAM role that OpenShift Cluster Manager will assume to create the cluster..

    +

    SupportRoleARN is an AWS IAM role used by Red Hat SREs to enable +access to the cluster account in order to provide support.

    +

    WorkerRoleARN is an AWS IAM role that will be attached to worker instances.

    -credentialsSecretRef
    - - -Kubernetes core/v1.LocalObjectReference - - -
    -(Optional) -

    CredentialsSecretRef references a secret with necessary credentials to connect to the OCM API. -The secret should contain the following data keys: -- ocmToken: eyJhbGciOiJIUzI1NiIsI…. -- ocmApiUrl: Optional, defaults to ‘https://api.openshift.com’

    -
    -identityRef
    +defaultMachinePoolSpec
    - -AWSIdentityReference + +DefaultMachinePoolSpec
    (Optional) -

    IdentityRef is a reference to an identity to be used when reconciling the managed control plane. -If no identity is specified, the default identity for this controller will be used.

    +

    DefaultMachinePoolSpec defines the configuration for the default machinepool(s) provisioned as part of the cluster creation. +One MachinePool will be created with this configuration per AvailabilityZone. Those default machinepools are required for openshift cluster operators +to work properly. +As these machinepool not created using ROSAMachinePool CR, they will not be visible/managed by ROSA CAPI provider. +rosa list machinepools -c <rosaClusterName> can be used to view those machinepools.

    +

    This field will be removed in the future once the current limitation is resolved.

    -instanceType
    +additionalTags
    -string + +Tags +
    (Optional) -

    The instance type to use, for example r5.xlarge. Instance type ref; https://aws.amazon.com/ec2/instance-types/

    +

    AdditionalTags are user-defined tags to be added on the AWS resources associated with the control plane.

    -autoscaling
    +etcdEncryptionKMSArn
    - -RosaMachinePoolAutoScaling - +string
    (Optional) -

    Autoscaling specifies auto scaling behaviour for the MachinePools.

    +

    EtcdEncryptionKMSArn is the ARN of the KMS key used to encrypt etcd. The key itself needs to be +created out-of-band by the user and tagged with red-hat:true.

    -additionalTags
    +credentialsSecretRef
    - -Tags + +Kubernetes core/v1.LocalObjectReference
    (Optional) -

    AdditionalTags are user-defined tags to be added on the AWS resources associated with the control plane.

    +

    CredentialsSecretRef references a secret with necessary credentials to connect to the OCM API. +The secret should contain the following data keys: +- ocmToken: eyJhbGciOiJIUzI1NiIsI…. +- ocmApiUrl: Optional, defaults to ‘https://api.openshift.com’

    -etcdEncryptionKMSArn
    +identityRef
    -string + +AWSIdentityReference +
    (Optional) -

    EtcdEncryptionKMSArn is the ARN of the KMS key used to encrypt etcd. The key itself needs to be -created out-of-band by the user and tagged with red-hat:true.

    +

    IdentityRef is a reference to an identity to be used when reconciling the managed control plane. +If no identity is specified, the default identity for this controller will be used.

    @@ -10369,6 +10447,7 @@ AWSClusterTemplateResource (Appears on:AWSClusterTemplateSpec)

    +

    AWSClusterTemplateResource defines the desired state of AWSClusterTemplate.

    @@ -13617,6 +13696,7 @@ string (Appears on:AWSClusterSpec)

    +

    S3Bucket defines a supporting S3 bucket for the cluster, currently can be optionally used for Ignition.

    @@ -16714,7 +16794,7 @@ percentage of nodes will be updated in parallel, up to 100 nodes at once.


    infrastructure.cluster.x-k8s.io/v1beta2

    -

    package v1beta2 contains the v1beta2 API implementation.

    +

    Package v1beta2 contains the v1beta2 API implementation.

    Resource Types: @@ -17833,6 +17913,7 @@ AWSClusterTemplateResource (Appears on:AWSClusterTemplateSpec)

    +

    AWSClusterTemplateResource defines the desired state of AWSClusterTemplateResource.

    @@ -20721,6 +20802,7 @@ string

    GCTask (string alias)

    +

    GCTask defines a task to be executed by the garbage collector.

    HTTPTokensState (string alias)

    @@ -20861,7 +20943,8 @@ Mutually exclusive with CidrBlock.

    (Appears on:AWSMachineSpec)

    -

    Ignition defines options related to the bootstrapping systems where Ignition is used.

    +

    Ignition defines options related to the bootstrapping systems where Ignition is used. +For more information on Ignition configuration, see https://coreos.github.io/butane/specs/

    @@ -20907,6 +20990,121 @@ that can access the ec2 metadata service have access to this sensitive informati So this is only to be used at ones own risk, and only when other more secure options are not viable.

    + + + + + + + + + +
    +proxy
    + + +IgnitionProxy + + +
    +(Optional) +

    Proxy defines proxy settings for Ignition. +Only valid for Ignition versions 3.1 and above.

    +
    +tls
    + + +IgnitionTLS + + +
    +(Optional) +

    TLS defines TLS settings for Ignition. +Only valid for Ignition versions 3.1 and above.

    +
    +

    IgnitionCASource +(string alias)

    +

    +(Appears on:IgnitionTLS) +

    +

    +

    IgnitionCASource defines the source of the certificate authority to use for Ignition.

    +

    +

    IgnitionNoProxy +(string alias)

    +

    +(Appears on:IgnitionProxy) +

    +

    +

    IgnitionNoProxy defines the list of domains to not proxy for Ignition.

    +

    +

    IgnitionProxy +

    +

    +(Appears on:Ignition) +

    +

    +

    IgnitionProxy defines proxy settings for Ignition.

    +

    + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    +httpProxy
    + +string + +
    +(Optional) +

    HTTPProxy is the HTTP proxy to use for Ignition. +A single URL that specifies the proxy server to use for HTTP and HTTPS requests, +unless overridden by the HTTPSProxy or NoProxy options.

    +
    +httpsProxy
    + +string + +
    +(Optional) +

    HTTPSProxy is the HTTPS proxy to use for Ignition. +A single URL that specifies the proxy server to use for HTTPS requests, +unless overridden by the NoProxy option.

    +
    +noProxy
    + + +[]IgnitionNoProxy + + +
    +(Optional) +

    NoProxy is the list of domains to not proxy for Ignition. +Specifies a list of strings to hosts that should be excluded from proxying.

    +

    Each value is represented by: +- An IP address prefix (1.2.3.4) +- An IP address prefix in CIDR notation (1.2.3.48) +- A domain name +- A domain name matches that name and all subdomains +- A domain name with a leading . matches subdomains only +- A special DNS label (*), indicates that no proxying should be done

    +

    An IP address prefix and domain name can also include a literal port number (1.2.3.4:80).

    +

    IgnitionStorageTypeOption @@ -20917,6 +21115,40 @@ So this is only to be used at ones own risk, and only when other more secure opt

    IgnitionStorageTypeOption defines the different storage types for Ignition.

    +

    IgnitionTLS +

    +

    +(Appears on:Ignition) +

    +

    +

    IgnitionTLS defines TLS settings for Ignition.

    +

    + + + + + + + + + + + + + +
    FieldDescription
    +certificateAuthorities
    + + +[]IgnitionCASource + + +
    +(Optional) +

    CASources defines the list of certificate authorities to use for Ignition. +The value is the certificate bundle (in PEM format). The bundle can contain multiple concatenated certificates. +Supported schemes are http, https, tftp, s3, arn, gs, and data (RFC 2397) URL scheme.

    +

    IngressRule

    @@ -21706,6 +21938,7 @@ LoadBalancerType (Appears on:AWSLoadBalancerSpec, LoadBalancer)

    +

    LoadBalancerType defines the type of load balancer to use.

    NetworkSpec

    @@ -21955,6 +22188,7 @@ string (Appears on:AWSClusterSpec)

    +

    S3Bucket defines a supporting S3 bucket for the cluster, currently can be optionally used for Ignition.

    @@ -25417,6 +25651,7 @@ bool

    ROSACluster

    +

    ROSACluster is the Schema for the ROSAClusters API.

    @@ -25490,6 +25725,7 @@ ROSAClusterStatus (Appears on:ROSACluster)

    +

    ROSAClusterSpec defines the desired state of ROSACluster.

    @@ -25521,7 +25757,7 @@ Cluster API api/v1beta1.APIEndpoint (Appears on:ROSACluster)

    -

    ROSAClusterStatus defines the observed state of ROSACluster

    +

    ROSAClusterStatus defines the observed state of ROSACluster.

    @@ -25728,6 +25964,19 @@ Tuning configs must already exist.

    + + + + + + + +
    +additionalSecurityGroups
    + +[]string + +
    +(Optional) +

    AdditionalSecurityGroups is an optional set of security groups to associate +with all node instances of the machine pool.

    +
    providerIDList
    []string @@ -25830,7 +26079,7 @@ during an instance refresh. The default is 90.

    RosaMachinePoolAutoScaling

    -(Appears on:RosaControlPlaneSpec, RosaMachinePoolSpec) +(Appears on:DefaultMachinePoolSpec, RosaMachinePoolSpec)

    RosaMachinePoolAutoScaling specifies scaling options.

    @@ -26010,6 +26259,19 @@ Tuning configs must already exist.

    +additionalSecurityGroups
    + +[]string + +
    +(Optional) +

    AdditionalSecurityGroups is an optional set of security groups to associate +with all node instances of the machine pool.

    +
    providerIDList
    []string @@ -26113,6 +26375,7 @@ string (Appears on:RosaMachinePoolSpec)

    +

    RosaTaint represents a taint to be applied to a node.

    diff --git a/exp/api/v1beta2/conditions_consts.go b/exp/api/v1beta2/conditions_consts.go index 45e8bf3923..2d052fae53 100644 --- a/exp/api/v1beta2/conditions_consts.go +++ b/exp/api/v1beta2/conditions_consts.go @@ -108,7 +108,11 @@ const ( RosaMachinePoolReadyCondition clusterv1.ConditionType = "RosaMchinePoolReady" // RosaMachinePoolUpgradingCondition condition reports whether ROSAMachinePool is upgrading or not. RosaMachinePoolUpgradingCondition clusterv1.ConditionType = "RosaMchinePoolUpgrading" + // WaitingForRosaControlPlaneReason used when the machine pool is waiting for // ROSA control plane infrastructure to be ready before proceeding. WaitingForRosaControlPlaneReason = "WaitingForRosaControlPlane" + + // RosaMachinePoolReconciliationFailedReason used to report failures while reconciling ROSAMachinePool. + RosaMachinePoolReconciliationFailedReason = "ReconciliationFailed" ) diff --git a/exp/controllers/rosamachinepool_controller.go b/exp/controllers/rosamachinepool_controller.go index 8d1936c309..e145b50ee3 100644 --- a/exp/controllers/rosamachinepool_controller.go +++ b/exp/controllers/rosamachinepool_controller.go @@ -272,6 +272,11 @@ func (r *ROSAMachinePoolReconciler) reconcileNormal(ctx context.Context, nodePool, err = ocmClient.CreateNodePool(machinePoolScope.ControlPlane.Status.ID, nodePoolSpec) if err != nil { + conditions.MarkFalse(rosaMachinePool, + expinfrav1.RosaMachinePoolReadyCondition, + expinfrav1.RosaMachinePoolReconciliationFailedReason, + clusterv1.ConditionSeverityError, + "failed to create ROSAMachinePool: %s", err.Error()) return ctrl.Result{}, fmt.Errorf("failed to create nodepool: %w", err) } @@ -308,11 +313,7 @@ func (r *ROSAMachinePoolReconciler) reconcileDelete( func (r *ROSAMachinePoolReconciler) reconcileMachinePoolVersion(machinePoolScope *scope.RosaMachinePoolScope, ocmClient *ocm.Client, nodePool *cmv1.NodePool) error { version := machinePoolScope.RosaMachinePool.Spec.Version - if version == "" { - version = machinePoolScope.ControlPlane.Spec.Version - } - - if version == rosa.RawVersionID(nodePool.Version()) { + if version == "" || version == rosa.RawVersionID(nodePool.Version()) { conditions.MarkFalse(machinePoolScope.RosaMachinePool, expinfrav1.RosaMachinePoolUpgradingCondition, "upgraded", clusterv1.ConditionSeverityInfo, "") return nil } @@ -370,6 +371,11 @@ func (r *ROSAMachinePoolReconciler) updateNodePool(machinePoolScope *scope.RosaM updatedNodePool, err := ocmClient.UpdateNodePool(machinePoolScope.ControlPlane.Status.ID, nodePoolSpec) if err != nil { + conditions.MarkFalse(machinePoolScope.RosaMachinePool, + expinfrav1.RosaMachinePoolReadyCondition, + expinfrav1.RosaMachinePoolReconciliationFailedReason, + clusterv1.ConditionSeverityError, + "failed to update ROSAMachinePool: %s", err.Error()) return nil, fmt.Errorf("failed to update nodePool: %w", err) }