From 9cf03ec4ea76c366d6269463cac9900a37d856fb Mon Sep 17 00:00:00 2001 From: kqzh <35095889+kqzh@users.noreply.github.com> Date: Thu, 21 Sep 2023 16:57:41 +0800 Subject: [PATCH 1/2] feat: add webhook rule --- pkg/webhook/nebulacluster/helper.go | 47 ++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/pkg/webhook/nebulacluster/helper.go b/pkg/webhook/nebulacluster/helper.go index da188e0e..56fb87f9 100644 --- a/pkg/webhook/nebulacluster/helper.go +++ b/pkg/webhook/nebulacluster/helper.go @@ -109,7 +109,12 @@ func validateNebulaClusterCreate(nc *v1alpha1.NebulaCluster) (allErrs field.Erro // validateNebulaClusterGraphd validates a NebulaCluster for Graphd on update. func validateNebulaClusterUpdateGraphd(nc, oldNC *v1alpha1.NebulaCluster) (allErrs field.ErrorList) { - _ = oldNC // unused + allErrs = append(allErrs, apivalidation.ValidateImmutableField( + nc.Spec.Graphd.Port, + oldNC.Spec.Graphd.Port, + field.NewPath("spec").Child("graphd").Child("port"), + )...) + allErrs = append(allErrs, validateNebulaClusterGraphd(nc)...) return allErrs @@ -117,6 +122,11 @@ func validateNebulaClusterUpdateGraphd(nc, oldNC *v1alpha1.NebulaCluster) (allEr // validateNebulaClusterMetad validates a NebulaCluster for Metad on Update. func validateNebulaClusterUpdateMetad(nc, oldNC *v1alpha1.NebulaCluster) (allErrs field.ErrorList) { + allErrs = append(allErrs, apivalidation.ValidateImmutableField( + nc.Spec.Metad.Port, + oldNC.Spec.Metad.Port, + field.NewPath("spec").Child("metad").Child("port"), + )...) allErrs = append(allErrs, apivalidation.ValidateImmutableField( nc.Spec.Metad.Replicas, oldNC.Spec.Metad.Replicas, @@ -129,6 +139,13 @@ func validateNebulaClusterUpdateMetad(nc, oldNC *v1alpha1.NebulaCluster) (allErr // validateNebulaClusterStoraged validates a NebulaCluster for Storaged on Update. func validateNebulaClusterUpdateStoraged(nc, oldNC *v1alpha1.NebulaCluster) (allErrs field.ErrorList) { + if oldNC.Status.Storaged.Phase == v1alpha1.ScaleInPhase || oldNC.Status.Storaged.Phase == v1alpha1.ScaleOutPhase { + allErrs = append(allErrs, field.Forbidden( + field.NewPath("spec", "storaged"), + fmt.Sprintf("field is immutable while in %s phase", oldNC.Status.Storaged.Phase), + )) + } + if nc.Status.Storaged.Phase != v1alpha1.RunningPhase { if *nc.Spec.Storaged.Replicas != *oldNC.Spec.Storaged.Replicas { allErrs = append(allErrs, field.Invalid( @@ -139,11 +156,39 @@ func validateNebulaClusterUpdateStoraged(nc, oldNC *v1alpha1.NebulaCluster) (all } } + allErrs = append(allErrs, apivalidation.ValidateImmutableField( + nc.Spec.Storaged.Port, + oldNC.Spec.Storaged.Port, + field.NewPath("spec").Child("storaged").Child("port"), + )...) + + allErrs = append(allErrs, validateNebulaClusterUpdateStoragedDataVolume(nc, oldNC)...) allErrs = append(allErrs, validateNebulaClusterStoraged(nc)...) return allErrs } +// validateNebulaClusterUpdateStoragedDataVolume validates a NebulaCluster for Storaged data volume on Update. +func validateNebulaClusterUpdateStoragedDataVolume(nc, oldNC *v1alpha1.NebulaCluster) (allErrs field.ErrorList) { + if len(nc.Spec.Storaged.DataVolumeClaims) != len(oldNC.Spec.Storaged.DataVolumeClaims) { + allErrs = append(allErrs, field.Forbidden( + field.NewPath("spec", "storaged", "dataVolumeClaims"), + "storaged dataVolumeClaims len is immutable", + )) + } + for i, pvc := range nc.Spec.Storaged.DataVolumeClaims { + if pvc.Resources.Requests.Storage().Cmp(*oldNC.Spec.Storaged.DataVolumeClaims[i].Resources.Requests.Storage()) == -1 { + allErrs = append(allErrs, field.Invalid( + field.NewPath("spec", "storaged", "dataVolumeClaims"), + pvc.Resources.Requests.Storage(), + "data volume size can only be increased", + )) + } + } + + return allErrs +} + // ValidateNebulaCluster validates a NebulaCluster on Update. func validateNebulaClusterUpdate(nc, oldNC *v1alpha1.NebulaCluster) (allErrs field.ErrorList) { name := nc.Name From c86b0e242cd83c1067ba176cd00932d4ba1400a5 Mon Sep 17 00:00:00 2001 From: kqzh <35095889+kqzh@users.noreply.github.com> Date: Thu, 21 Sep 2023 18:30:59 +0800 Subject: [PATCH 2/2] feat: add rule --- pkg/webhook/nebulacluster/helper.go | 14 ++++++++------ pkg/webhook/util/validation/nebulacluster.go | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/pkg/webhook/nebulacluster/helper.go b/pkg/webhook/nebulacluster/helper.go index 56fb87f9..0f95ca1f 100644 --- a/pkg/webhook/nebulacluster/helper.go +++ b/pkg/webhook/nebulacluster/helper.go @@ -203,12 +203,14 @@ func validateNebulaClusterUpdate(nc, oldNC *v1alpha1.NebulaCluster) (allErrs fie field.NewPath("metadata"), )...) - allErrs = append(allErrs, apivalidation.ValidateImmutableAnnotation( - nc.Annotations[annotation.AnnHaModeKey], - oldNC.Annotations[annotation.AnnHaModeKey], - annotation.AnnHaModeKey, - field.NewPath("metadata"), - )...) + if !validation.IsNebulaClusterHA(oldNC) { + allErrs = append(allErrs, apivalidation.ValidateImmutableAnnotation( + nc.Annotations[annotation.AnnHaModeKey], + oldNC.Annotations[annotation.AnnHaModeKey], + annotation.AnnHaModeKey, + field.NewPath("metadata"), + )...) + } allErrs = append(allErrs, validateNebulaClusterUpdateGraphd(nc, oldNC)...) allErrs = append(allErrs, validateNebulaClusterUpdateMetad(nc, oldNC)...) diff --git a/pkg/webhook/util/validation/nebulacluster.go b/pkg/webhook/util/validation/nebulacluster.go index ddcc3347..8d54a9af 100644 --- a/pkg/webhook/util/validation/nebulacluster.go +++ b/pkg/webhook/util/validation/nebulacluster.go @@ -18,6 +18,8 @@ package validation import ( "k8s.io/apimachinery/pkg/util/validation/field" + + "github.com/vesoft-inc/nebula-operator/apis/apps/v1alpha1" ) const ( @@ -72,3 +74,16 @@ func ValidateMinReplicasStoraged(fldPath *field.Path, replicas int, bHaMode bool return allErrs } + +func IsNebulaClusterHA(nc *v1alpha1.NebulaCluster) bool { + if int(*nc.Spec.Graphd.Replicas) < minReplicasGraphdInHaMode { + return false + } + if int(*nc.Spec.Metad.Replicas) < minReplicasMetadInHaMode { + return false + } + if int(*nc.Spec.Storaged.Replicas) < minReplicasStoragedInHaMode { + return false + } + return true +}