From 49b6c51f43dfd3ad3faf6170ba356f6540c8d73b Mon Sep 17 00:00:00 2001 From: Stefan Bueringer Date: Thu, 26 Jun 2025 15:18:52 +0200 Subject: [PATCH] KCP: Set MinItems=1 on ExternalEtcd.Endpoints --- api/bootstrap/kubeadm/v1beta2/kubeadm_types.go | 1 + .../crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigs.yaml | 1 + .../bootstrap.cluster.x-k8s.io_kubeadmconfigtemplates.yaml | 1 + .../controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml | 1 + ...olplane.cluster.x-k8s.io_kubeadmcontrolplanetemplates.yaml | 1 + controlplane/kubeadm/internal/filters.go | 2 ++ controlplane/kubeadm/internal/filters_test.go | 4 +++- 7 files changed, 10 insertions(+), 1 deletion(-) diff --git a/api/bootstrap/kubeadm/v1beta2/kubeadm_types.go b/api/bootstrap/kubeadm/v1beta2/kubeadm_types.go index 982a5f9a555a..e735ac564a29 100644 --- a/api/bootstrap/kubeadm/v1beta2/kubeadm_types.go +++ b/api/bootstrap/kubeadm/v1beta2/kubeadm_types.go @@ -459,6 +459,7 @@ type LocalEtcd struct { type ExternalEtcd struct { // endpoints of etcd members. Required for ExternalEtcd. // +required + // +kubebuilder:validation:MinItems=1 // +kubebuilder:validation:MaxItems=50 // +kubebuilder:validation:items:MinLength=1 // +kubebuilder:validation:items:MaxLength=512 diff --git a/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigs.yaml b/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigs.yaml index e8cda57918c5..1ae9689fafd5 100644 --- a/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigs.yaml +++ b/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigs.yaml @@ -4601,6 +4601,7 @@ spec: minLength: 1 type: string maxItems: 50 + minItems: 1 type: array keyFile: description: |- diff --git a/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigtemplates.yaml b/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigtemplates.yaml index 2d8cd5ca7558..943b639b976b 100644 --- a/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigtemplates.yaml +++ b/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigtemplates.yaml @@ -4482,6 +4482,7 @@ spec: minLength: 1 type: string maxItems: 50 + minItems: 1 type: array keyFile: description: |- diff --git a/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml b/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml index 3841b59206dd..ac503e645ece 100644 --- a/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml +++ b/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml @@ -5528,6 +5528,7 @@ spec: minLength: 1 type: string maxItems: 50 + minItems: 1 type: array keyFile: description: |- diff --git a/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanetemplates.yaml b/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanetemplates.yaml index b575572e3186..4864846140a6 100644 --- a/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanetemplates.yaml +++ b/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanetemplates.yaml @@ -3904,6 +3904,7 @@ spec: minLength: 1 type: string maxItems: 50 + minItems: 1 type: array keyFile: description: |- diff --git a/controlplane/kubeadm/internal/filters.go b/controlplane/kubeadm/internal/filters.go index 994e569e5ba0..87ac60733fab 100644 --- a/controlplane/kubeadm/internal/filters.go +++ b/controlplane/kubeadm/internal/filters.go @@ -428,6 +428,8 @@ func dropOmittableFields(spec *bootstrapv1.KubeadmConfigSpec) { } // NOTE: we are not dropping spec.ClusterConfiguration.Etcd.ExternalEtcd.Endpoints because this field // doesn't have omitempty, so [] array is different from nil when serialized. + // But this field is also required and has MinItems=1, so it will + // never actually be nil or an empty array so that difference also won't trigger any rollouts. if len(spec.ClusterConfiguration.APIServer.ExtraArgs) == 0 { spec.ClusterConfiguration.APIServer.ExtraArgs = nil } diff --git a/controlplane/kubeadm/internal/filters_test.go b/controlplane/kubeadm/internal/filters_test.go index e9b6ae777b91..5c096f3256df 100644 --- a/controlplane/kubeadm/internal/filters_test.go +++ b/controlplane/kubeadm/internal/filters_test.go @@ -1896,7 +1896,9 @@ func TestOmittableFieldsClusterConfiguration(t *testing.T) { PeerCertSANs: nil, }, External: &bootstrapv1.ExternalEtcd{ - Endpoints: []string{}, // The field doesn't have omit empty. + // The field doesn't have omit empty. It also is required and has MinItems=1, so it will + // never actually be nil or an empty array so that difference also won't trigger any rollouts. + Endpoints: []string{}, }, }, APIServer: bootstrapv1.APIServer{