diff --git a/internal/webhooks/cluster.go b/internal/webhooks/cluster.go index 1abfa1d7e927..087bb0e14c8c 100644 --- a/internal/webhooks/cluster.go +++ b/internal/webhooks/cluster.go @@ -101,6 +101,18 @@ func (webhook *Cluster) Default(ctx context.Context, obj runtime.Object) error { if !strings.HasPrefix(cluster.Spec.Topology.Version, "v") { cluster.Spec.Topology.Version = "v" + cluster.Spec.Topology.Version } + + if cluster.Spec.Topology.Class == "" { + allErrs = append( + allErrs, + field.Required( + field.NewPath("spec", "topology", "class"), + "class cannot be empty", + ), + ) + return apierrors.NewInvalid(clusterv1.GroupVersion.WithKind("Cluster").GroupKind(), cluster.Name, allErrs) + } + clusterClass, err := webhook.pollClusterClassForCluster(ctx, cluster) if err != nil { // If the ClusterClass can't be found or is not up to date ignore the error. diff --git a/internal/webhooks/cluster_test.go b/internal/webhooks/cluster_test.go index cbe948d0d444..02c066287e8a 100644 --- a/internal/webhooks/cluster_test.go +++ b/internal/webhooks/cluster_test.go @@ -897,6 +897,23 @@ func TestClusterDefaultTopologyVersion(t *testing.T) { g.Expect(c.Spec.Topology.Version).To(HavePrefix("v")) } +func TestClusterFailOnMissingClassField(t *testing.T) { + // NOTE: ClusterTopology feature flag is disabled by default, thus preventing to set Cluster.Topologies. + // Enabling the feature flag temporarily for this test. + defer utilfeature.SetFeatureGateDuringTest(t, feature.Gates, feature.ClusterTopology, true)() + + g := NewWithT(t) + + c := builder.Cluster("fooboo", "cluster1"). + WithTopology(builder.ClusterTopology(). + WithClass(""). // THis is invalid. + WithVersion("1.19.1"). + Build()). + Build() + + g.Expect((&Cluster{}).Default(ctx, c)).ToNot(Succeed()) +} + func TestClusterValidation(t *testing.T) { // NOTE: ClusterTopology feature flag is disabled by default, thus preventing to set Cluster.Topologies.