diff --git a/api/v1alpha4/conversion.go b/api/v1alpha4/conversion.go index 7ebffb92f3c8..5b1c45c25a22 100644 --- a/api/v1alpha4/conversion.go +++ b/api/v1alpha4/conversion.go @@ -139,8 +139,6 @@ func (src *ClusterClass) ConvertTo(dstRaw conversion.Hub) error { dst.Spec.Workers.MachineDeployments[i].Strategy = restored.Spec.Workers.MachineDeployments[i].Strategy } - dst.Spec.Workers.MachinePools = restored.Spec.Workers.MachinePools - dst.Status = restored.Status return nil diff --git a/api/v1beta1/cluster_types.go b/api/v1beta1/cluster_types.go index 7996b98b83e6..456d83622393 100644 --- a/api/v1beta1/cluster_types.go +++ b/api/v1beta1/cluster_types.go @@ -263,10 +263,10 @@ type MachinePoolTopology struct { // the values are hashed together. Name string `json:"name"` - // FailureDomain is the failure domain the machine pools will be created in. - // Must match a key in the FailureDomain map stored on the cluster object. + // FailureDomains is the list of failure domains the machine pool will be created in. + // Must match a key in the FailureDomains map stored on the cluster object. // +optional - FailureDomain *string `json:"failureDomain,omitempty"` + FailureDomains []string `json:"failureDomains,omitempty"` // NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. // The default value is 0, meaning that the node can be drained without any time limitations. diff --git a/api/v1beta1/clusterclass_types.go b/api/v1beta1/clusterclass_types.go index 5087fa1d0be3..f699df58143d 100644 --- a/api/v1beta1/clusterclass_types.go +++ b/api/v1beta1/clusterclass_types.go @@ -157,7 +157,7 @@ type MachineDeploymentClass struct { MachineHealthCheck *MachineHealthCheckClass `json:"machineHealthCheck,omitempty"` // FailureDomain is the failure domain the machines will be created in. - // Must match a key in the FailureDomain map stored on the cluster object. + // Must match a key in the FailureDomains map stored on the cluster object. // NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass. // +optional FailureDomain *string `json:"failureDomain,omitempty"` @@ -261,11 +261,11 @@ type MachinePoolClass struct { // MachinePools objects representing a pool of worker nodes. Template MachinePoolClassTemplate `json:"template"` - // FailureDomain is the failure domain the machine pools will be created in. - // Must match a key in the FailureDomain map stored on the cluster object. + // FailureDomains is the list of failure domains the MachinePool should be attached to. + // Must match a key in the FailureDomains map stored on the cluster object. // NOTE: This value can be overridden while defining a Cluster.Topology using this MachinePoolClass. // +optional - FailureDomain *string `json:"failureDomain,omitempty"` + FailureDomains []string `json:"failureDomains,omitempty"` // NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. // The default value is 0, meaning that the node can be drained without any time limitations. diff --git a/api/v1beta1/condition_consts.go b/api/v1beta1/condition_consts.go index 4d0202be35df..5e2bc212ecdf 100644 --- a/api/v1beta1/condition_consts.go +++ b/api/v1beta1/condition_consts.go @@ -305,6 +305,7 @@ const ( // TopologyReconciledMachinePoolsCreatePendingReason (Severity=Info) documents reconciliation of a Cluster topology // not yet completed because at least one of the MachinePools is yet to be created. + // This generally happens because new MachinePool creations are held off while the ControlPlane is not stable. TopologyReconciledMachinePoolsCreatePendingReason = "MachinePoolsCreatePending" // TopologyReconciledMachinePoolsUpgradeDeferredReason (Severity=Info) documents reconciliation of a Cluster topology diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 3482b40fa162..9c40a39b105e 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -1394,10 +1394,10 @@ func (in *MachineList) DeepCopyObject() runtime.Object { func (in *MachinePoolClass) DeepCopyInto(out *MachinePoolClass) { *out = *in in.Template.DeepCopyInto(&out.Template) - if in.FailureDomain != nil { - in, out := &in.FailureDomain, &out.FailureDomain - *out = new(string) - **out = **in + if in.FailureDomains != nil { + in, out := &in.FailureDomains, &out.FailureDomains + *out = make([]string, len(*in)) + copy(*out, *in) } if in.NodeDrainTimeout != nil { in, out := &in.NodeDrainTimeout, &out.NodeDrainTimeout @@ -1453,10 +1453,10 @@ func (in *MachinePoolClassTemplate) DeepCopy() *MachinePoolClassTemplate { func (in *MachinePoolTopology) DeepCopyInto(out *MachinePoolTopology) { *out = *in in.Metadata.DeepCopyInto(&out.Metadata) - if in.FailureDomain != nil { - in, out := &in.FailureDomain, &out.FailureDomain - *out = new(string) - **out = **in + if in.FailureDomains != nil { + in, out := &in.FailureDomains, &out.FailureDomains + *out = make([]string, len(*in)) + copy(*out, *in) } if in.NodeDrainTimeout != nil { in, out := &in.NodeDrainTimeout, &out.NodeDrainTimeout diff --git a/api/v1beta1/zz_generated.openapi.go b/api/v1beta1/zz_generated.openapi.go index 700a349f144d..c46127a35fd7 100644 --- a/api/v1beta1/zz_generated.openapi.go +++ b/api/v1beta1/zz_generated.openapi.go @@ -1555,7 +1555,7 @@ func schema_sigsk8sio_cluster_api_api_v1beta1_MachineDeploymentClass(ref common. }, "failureDomain": { SchemaProps: spec.SchemaProps{ - Description: "FailureDomain is the failure domain the machines will be created in. Must match a key in the FailureDomain map stored on the cluster object. NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass.", + Description: "FailureDomain is the failure domain the machines will be created in. Must match a key in the FailureDomains map stored on the cluster object. NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass.", Type: []string{"string"}, Format: "", }, @@ -2443,11 +2443,19 @@ func schema_sigsk8sio_cluster_api_api_v1beta1_MachinePoolClass(ref common.Refere Ref: ref("sigs.k8s.io/cluster-api/api/v1beta1.MachinePoolClassTemplate"), }, }, - "failureDomain": { + "failureDomains": { SchemaProps: spec.SchemaProps{ - Description: "FailureDomain is the failure domain the machine pools will be created in. Must match a key in the FailureDomain map stored on the cluster object. NOTE: This value can be overridden while defining a Cluster.Topology using this MachinePoolClass.", - Type: []string{"string"}, - Format: "", + Description: "FailureDomains is the list of failure domains the MachinePool should be attached to. Must match a key in the FailureDomains map stored on the cluster object. NOTE: This value can be overridden while defining a Cluster.Topology using this MachinePoolClass.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, }, }, "nodeDrainTimeout": { @@ -2551,11 +2559,19 @@ func schema_sigsk8sio_cluster_api_api_v1beta1_MachinePoolTopology(ref common.Ref Format: "", }, }, - "failureDomain": { + "failureDomains": { SchemaProps: spec.SchemaProps{ - Description: "FailureDomain is the failure domain the machine pools will be created in. Must match a key in the FailureDomain map stored on the cluster object.", - Type: []string{"string"}, - Format: "", + Description: "FailureDomains is the list of failure domains the machine pool will be created in. Must match a key in the FailureDomains map stored on the cluster object.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, }, }, "nodeDrainTimeout": { diff --git a/config/crd/bases/cluster.x-k8s.io_clusterclasses.yaml b/config/crd/bases/cluster.x-k8s.io_clusterclasses.yaml index 12405e97d8d7..809563f1a371 100644 --- a/config/crd/bases/cluster.x-k8s.io_clusterclasses.yaml +++ b/config/crd/bases/cluster.x-k8s.io_clusterclasses.yaml @@ -1052,7 +1052,7 @@ spec: type: string failureDomain: description: 'FailureDomain is the failure domain the machines - will be created in. Must match a key in the FailureDomain + will be created in. Must match a key in the FailureDomains map stored on the cluster object. NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass.' @@ -1420,13 +1420,15 @@ spec: and can be referenced in the Cluster to create a managed MachinePool. type: string - failureDomain: - description: 'FailureDomain is the failure domain the machine - pools will be created in. Must match a key in the FailureDomain - map stored on the cluster object. NOTE: This value can - be overridden while defining a Cluster.Topology using - this MachinePoolClass.' - type: string + failureDomains: + description: 'FailureDomains is the list of failure domains + the MachinePool should be attached to. Must match a key + in the FailureDomains map stored on the cluster object. + NOTE: This value can be overridden while defining a Cluster.Topology + using this MachinePoolClass.' + items: + type: string + type: array minReadySeconds: description: 'Minimum number of seconds for which a newly created machine pool should be ready. Defaults to 0 (machine diff --git a/config/crd/bases/cluster.x-k8s.io_clusters.yaml b/config/crd/bases/cluster.x-k8s.io_clusters.yaml index bf4b778115c0..3bd1c08fb613 100644 --- a/config/crd/bases/cluster.x-k8s.io_clusters.yaml +++ b/config/crd/bases/cluster.x-k8s.io_clusters.yaml @@ -1408,11 +1408,14 @@ spec: ClusterClass object mentioned in the `Cluster.Spec.Class` field. type: string - failureDomain: - description: FailureDomain is the failure domain the - machine pools will be created in. Must match a key - in the FailureDomain map stored on the cluster object. - type: string + failureDomains: + description: FailureDomains is the list of failure domains + the machine pool will be created in. Must match a + key in the FailureDomains map stored on the cluster + object. + items: + type: string + type: array metadata: description: Metadata is the metadata applied to the MachinePool. At runtime this metadata is merged with diff --git a/internal/controllers/topology/cluster/desired_state.go b/internal/controllers/topology/cluster/desired_state.go index 36fa6894e0fe..365f459fdac7 100644 --- a/internal/controllers/topology/cluster/desired_state.go +++ b/internal/controllers/topology/cluster/desired_state.go @@ -975,9 +975,9 @@ func computeMachinePool(_ context.Context, s *scope.Scope, desiredControlPlaneSt version := computeMachinePoolVersion(s, desiredControlPlaneState, machinePoolTopology, currentMachinePool) // Compute values that can be set both in the MachinePoolClass and in the MachinePoolTopology - failureDomain := machinePoolClass.FailureDomain - if machinePoolTopology.FailureDomain != nil { - failureDomain = machinePoolTopology.FailureDomain + failureDomains := machinePoolClass.FailureDomains + if machinePoolTopology.FailureDomains != nil { + failureDomains = machinePoolTopology.FailureDomains } nodeDrainTimeout := machinePoolClass.NodeDrainTimeout @@ -1015,15 +1015,14 @@ func computeMachinePool(_ context.Context, s *scope.Scope, desiredControlPlaneSt Namespace: s.Current.Cluster.Namespace, }, Spec: expv1.MachinePoolSpec{ - ClusterName: s.Current.Cluster.Name, - //Replicas: , + ClusterName: s.Current.Cluster.Name, + FailureDomains: failureDomains, Template: clusterv1.MachineTemplateSpec{ Spec: clusterv1.MachineSpec{ ClusterName: s.Current.Cluster.Name, Version: pointer.String(version), Bootstrap: clusterv1.Bootstrap{ConfigRef: desiredBootstrapTemplateRef}, InfrastructureRef: *desiredInfraMachineTemplateRef, - FailureDomain: failureDomain, NodeDrainTimeout: nodeDrainTimeout, NodeVolumeDetachTimeout: nodeVolumeDetachTimeout, NodeDeletionTimeout: nodeDeletionTimeout,