From f1b2729dcb72729a06be8aa3ddc23a86781cf978 Mon Sep 17 00:00:00 2001 From: Nader Ziada Date: Mon, 9 Mar 2020 13:31:32 -0400 Subject: [PATCH] validation for not having both local and external etcd in kcp --- .../v1alpha3/kubeadm_control_plane_webhook.go | 27 +++++++++++++++++++ .../kubeadm_control_plane_webhook_test.go | 25 +++++++++++++++-- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/controlplane/kubeadm/api/v1alpha3/kubeadm_control_plane_webhook.go b/controlplane/kubeadm/api/v1alpha3/kubeadm_control_plane_webhook.go index ba709020d84e..30497618196c 100644 --- a/controlplane/kubeadm/api/v1alpha3/kubeadm_control_plane_webhook.go +++ b/controlplane/kubeadm/api/v1alpha3/kubeadm_control_plane_webhook.go @@ -82,6 +82,9 @@ func (in *KubeadmControlPlane) ValidateUpdate(old runtime.Object) error { allErrs := in.validateCommon() prev := old.(*KubeadmControlPlane) + + allErrs = append(allErrs, in.validateEtcd(prev)...) + originalJSON, err := json.Marshal(prev) if err != nil { return apierrors.NewInternalError(err) @@ -229,6 +232,30 @@ func (in *KubeadmControlPlane) validateCommon() (allErrs field.ErrorList) { return allErrs } +func (in *KubeadmControlPlane) validateEtcd(prev *KubeadmControlPlane) (allErrs field.ErrorList) { + if in.Spec.KubeadmConfigSpec.InitConfiguration.Etcd.External != nil && prev.Spec.KubeadmConfigSpec.InitConfiguration.Etcd.Local != nil { + allErrs = append( + allErrs, + field.Forbidden( + field.NewPath("spec", "kubeadmConfigSpec", "initConfiguration", "etcd", "local"), + "cannot have both local and external etcd at the same time", + ), + ) + } + + if in.Spec.KubeadmConfigSpec.InitConfiguration.Etcd.Local != nil && prev.Spec.KubeadmConfigSpec.InitConfiguration.Etcd.External != nil { + allErrs = append( + allErrs, + field.Forbidden( + field.NewPath("spec", "kubeadmConfigSpec", "initConfiguration", "etcd", "local"), + "cannot have both local and external etcd at the same time", + ), + ) + } + + return allErrs +} + // ValidateDelete implements webhook.Validator so a webhook will be registered for the type func (in *KubeadmControlPlane) ValidateDelete() error { return nil diff --git a/controlplane/kubeadm/api/v1alpha3/kubeadm_control_plane_webhook_test.go b/controlplane/kubeadm/api/v1alpha3/kubeadm_control_plane_webhook_test.go index 1634936ad9f0..a624601200a3 100644 --- a/controlplane/kubeadm/api/v1alpha3/kubeadm_control_plane_webhook_test.go +++ b/controlplane/kubeadm/api/v1alpha3/kubeadm_control_plane_webhook_test.go @@ -21,11 +21,9 @@ import ( "time" . "github.com/onsi/gomega" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/pointer" - bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha3" kubeadmv1beta1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/types/v1beta1" ) @@ -293,6 +291,23 @@ func TestKubeadmControlPlaneValidateUpdate(t *testing.T) { scaleToEvenExternalEtcdCluster := beforeExternalEtcdCluster.DeepCopy() scaleToEvenExternalEtcdCluster.Spec.Replicas = pointer.Int32Ptr(2) + beforeInvalidEtcdCluster := before.DeepCopy() + beforeInvalidEtcdCluster.Spec.KubeadmConfigSpec.InitConfiguration.ClusterConfiguration.Etcd = kubeadmv1beta1.Etcd{ + Local: &kubeadmv1beta1.LocalEtcd{ + ImageMeta: kubeadmv1beta1.ImageMeta{ + ImageRepository: "image-repository", + ImageTag: "latest", + }, + }, + } + + afterInvalidEtcdCluster := beforeInvalidEtcdCluster.DeepCopy() + afterInvalidEtcdCluster.Spec.KubeadmConfigSpec.InitConfiguration.ClusterConfiguration.Etcd = kubeadmv1beta1.Etcd{ + External: &kubeadmv1beta1.ExternalEtcd{ + Endpoints: []string{"127.0.0.1"}, + }, + } + tests := []struct { name string expectErr bool @@ -473,6 +488,12 @@ func TestKubeadmControlPlaneValidateUpdate(t *testing.T) { before: localDataDir, kcp: modifyLocalDataDir, }, + { + name: "should fail if both local and external etcd are set", + expectErr: true, + before: beforeInvalidEtcdCluster, + kcp: afterInvalidEtcdCluster, + }, } for _, tt := range tests {