diff --git a/docs/book/src/tasks/experimental-features/cluster-class/upgrade-cluster.md b/docs/book/src/tasks/experimental-features/cluster-class/upgrade-cluster.md index f16c30ec4417..e3a66f9f7726 100644 --- a/docs/book/src/tasks/experimental-features/cluster-class/upgrade-cluster.md +++ b/docs/book/src/tasks/experimental-features/cluster-class/upgrade-cluster.md @@ -21,6 +21,7 @@ Change `1.21.2` to `1.22.0` as below. ```bash kubectl patch cluster clusterclass-quickstart --type json --patch '[{"op": "replace", "path": "/spec/topology/version", "value": "v1.22.0"}]' ``` +**Important Note**: A +2 minor Kubernetes version upgrade is not allowed in Cluster Topologies. This is to align with existing control plane providers, like KubeadmControlPlane provider, that limit a +2 minor version upgrade. Example: Upgrading from `1.21.2` to `1.23.0` is not allowed. The upgrade will take some time to roll out as it will take place machine by machine with older versions of the machines only being removed after healthy newer versions come online. diff --git a/internal/webhooks/cluster.go b/internal/webhooks/cluster.go index 9fd7648c7492..c15ce8dc4a49 100644 --- a/internal/webhooks/cluster.go +++ b/internal/webhooks/cluster.go @@ -268,6 +268,21 @@ func (webhook *Cluster) validateTopology(ctx context.Context, oldCluster, newClu ), ) } + // A +2 minor version upgrade is not allowed. + ceilVersion := semver.Version{ + Major: oldVersion.Major, + Minor: oldVersion.Minor + 2, + Patch: 0, + } + if inVersion.GTE(ceilVersion) { + allErrs = append( + allErrs, + field.Forbidden( + field.NewPath("spec", "topology", "version"), + fmt.Sprintf("version cannot be increased from %q to %q", oldVersion, inVersion), + ), + ) + } // If the ClusterClass referenced in the Topology has changed compatibility checks are needed. if oldCluster.Spec.Topology.Class != newCluster.Spec.Topology.Class { diff --git a/internal/webhooks/cluster_test.go b/internal/webhooks/cluster_test.go index 4c07a7dfcae8..b11f1621cf11 100644 --- a/internal/webhooks/cluster_test.go +++ b/internal/webhooks/cluster_test.go @@ -397,6 +397,22 @@ func TestClusterTopologyValidation(t *testing.T) { Build()). Build(), }, + { + name: "should return error when upgrading +2 minor version", + expectErr: true, + old: builder.Cluster("fooboo", "cluster1"). + WithTopology(builder.ClusterTopology(). + WithClass("foo"). + WithVersion("v1.2.3"). + Build()). + Build(), + in: builder.Cluster("fooboo", "cluster1"). + WithTopology(builder.ClusterTopology(). + WithClass("foo"). + WithVersion("v1.4.0"). + Build()). + Build(), + }, { name: "should return error when duplicated MachineDeployments names exists in a Topology", expectErr: true,