From a523a0254da9f728866cb8211a8af0929ab69fff Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Mon, 22 Jul 2024 23:46:47 +0200 Subject: [PATCH] update webhook to reject decreasing storage size Signed-off-by: Andrei Kvapil --- api/v1alpha1/etcdcluster_webhook.go | 18 +++++++++++ api/v1alpha1/etcdcluster_webhook_test.go | 40 ++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/api/v1alpha1/etcdcluster_webhook.go b/api/v1alpha1/etcdcluster_webhook.go index 18c7971..941a737 100644 --- a/api/v1alpha1/etcdcluster_webhook.go +++ b/api/v1alpha1/etcdcluster_webhook.go @@ -107,11 +107,26 @@ func (r *EtcdCluster) ValidateUpdate(old runtime.Object) (admission.Warnings, er etcdclusterlog.Info("validate update", "name", r.Name) var warnings admission.Warnings oldCluster := old.(*EtcdCluster) + + // Check if replicas are being resized if *oldCluster.Spec.Replicas != *r.Spec.Replicas { warnings = append(warnings, "cluster resize is not currently supported") } var allErrors field.ErrorList + + // Check if storage size is being decreased + oldStorage := oldCluster.Spec.Storage.VolumeClaimTemplate.Spec.Resources.Requests[corev1.ResourceStorage] + newStorage := r.Spec.Storage.VolumeClaimTemplate.Spec.Resources.Requests[corev1.ResourceStorage] + if newStorage.Cmp(oldStorage) < 0 { + allErrors = append(allErrors, field.Invalid( + field.NewPath("spec", "storage", "volumeClaimTemplate", "resources", "requests", "storage"), + newStorage.String(), + "decreasing storage size is not allowed"), + ) + } + + // Check if storage type is changing if oldCluster.Spec.Storage.EmptyDir == nil && r.Spec.Storage.EmptyDir != nil || oldCluster.Spec.Storage.EmptyDir != nil && r.Spec.Storage.EmptyDir == nil { allErrors = append(allErrors, field.Invalid( @@ -121,6 +136,7 @@ func (r *EtcdCluster) ValidateUpdate(old runtime.Object) (admission.Warnings, er ) } + // Validate PodDisruptionBudget pdbWarnings, pdbErr := r.validatePdb() if pdbErr != nil { allErrors = append(allErrors, pdbErr...) @@ -129,11 +145,13 @@ func (r *EtcdCluster) ValidateUpdate(old runtime.Object) (admission.Warnings, er warnings = append(warnings, pdbWarnings...) } + // Validate Security securityErr := r.validateSecurity() if securityErr != nil { allErrors = append(allErrors, securityErr...) } + // Validate Options if errOptions := validateOptions(r); errOptions != nil { allErrors = append(allErrors, field.Invalid( field.NewPath("spec", "options"), diff --git a/api/v1alpha1/etcdcluster_webhook_test.go b/api/v1alpha1/etcdcluster_webhook_test.go index 23fe9c7..fa72ee7 100644 --- a/api/v1alpha1/etcdcluster_webhook_test.go +++ b/api/v1alpha1/etcdcluster_webhook_test.go @@ -111,6 +111,46 @@ var _ = Describe("EtcdCluster Webhook", func() { } }) + It("Should reject decreasing storage size", func() { + etcdCluster := &EtcdCluster{ + Spec: EtcdClusterSpec{ + Replicas: ptr.To(int32(1)), + Storage: StorageSpec{ + VolumeClaimTemplate: EmbeddedPersistentVolumeClaim{ + Spec: corev1.PersistentVolumeClaimSpec{ + Resources: corev1.VolumeResourceRequirements{ + Requests: map[corev1.ResourceName]resource.Quantity{ + corev1.ResourceStorage: resource.MustParse("5Gi"), + }, + }, + }, + }, + }, + }, + } + oldCluster := &EtcdCluster{ + Spec: EtcdClusterSpec{ + Replicas: ptr.To(int32(1)), + Storage: StorageSpec{ + VolumeClaimTemplate: EmbeddedPersistentVolumeClaim{ + Spec: corev1.PersistentVolumeClaimSpec{ + Resources: corev1.VolumeResourceRequirements{ + Requests: map[corev1.ResourceName]resource.Quantity{ + corev1.ResourceStorage: resource.MustParse("10Gi"), + }, + }, + }, + }, + }, + }, + } + _, err := etcdCluster.ValidateUpdate(oldCluster) + if Expect(err).To(HaveOccurred()) { + statusErr := err.(*errors.StatusError) + Expect(statusErr.ErrStatus.Message).To(ContainSubstring("decreasing storage size is not allowed")) + } + }) + It("Should allow changing emptydir size", func() { etcdCluster := &EtcdCluster{ Spec: EtcdClusterSpec{