Skip to content

Commit

Permalink
webhook rule for protected cluster (#408)
Browse files Browse the repository at this point in the history
  • Loading branch information
MegaByte875 authored Dec 12, 2023
1 parent caf7acc commit 552e89d
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 8 deletions.
15 changes: 15 additions & 0 deletions apis/pkg/annotation/annotation.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ const (
AnnPodConfigMapHash = "nebula-graph.io/cm-hash"
// AnnPvReclaimKey is annotation key that indicate whether reclaim persistent volume
AnnPvReclaimKey = "nebula-graph.io/enable-pv-reclaim"
// AnnDeleteProtection is an annotation key used to prevent the deletion of a nebula cluster that has been annotated by this key
AnnDeleteProtection = "nebula-graph.io/delete-protection"

// AnnRestartTimestamp is annotation key to indicate the timestamp that operator restart the workload
AnnRestartTimestamp = "nebula-graph.io/restart-timestamp"
Expand All @@ -53,6 +55,9 @@ const (
// AnnRestoreStageKey is the annotation key to indicate what is the current stage
AnnRestoreStageKey = "restore-stage"

// AnnDeleteProtectionVal is annotation value to indicate whether nebula cluster is protected
AnnDeleteProtectionVal = "true"

// AnnHaModeVal is annotation value to indicate whether in HA mode
AnnHaModeVal = "true"

Expand Down Expand Up @@ -126,3 +131,13 @@ func CopyAnnotations(src map[string]string) map[string]string {
}
return dst
}

func ISDeleteProtected(ann map[string]string) bool {
if ann != nil {
val, ok := ann[AnnDeleteProtection]
if ok && val == AnnDeleteProtectionVal {
return true
}
}
return false
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ webhooks:
operations:
- CREATE
- UPDATE
- DELETE
resources:
- nebulaclusters
scope: "*"
Expand Down
6 changes: 3 additions & 3 deletions pkg/nebula/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@ func ClientOptions(nc *v1alpha1.NebulaCluster, opts ...Option) ([]Option, error)

if nc.IsMetadSSLEnabled() && !nc.IsClusterSSLEnabled() {
options = append(options, SetMetaTLS(true))
klog.Infof("cluster [%s/%s] metad SSL enabled", nc.Namespace, nc.Name)
klog.V(4).Infof("cluster [%s/%s] metad SSL enabled", nc.Namespace, nc.Name)
}
if nc.IsStoragedSSLEnabled() && !nc.IsClusterSSLEnabled() {
options = append(options, SetStorageTLS(true))
klog.Infof("cluster [%s/%s] storaged SSL enabled", nc.Namespace, nc.Name)
klog.V(4).Infof("cluster [%s/%s] storaged SSL enabled", nc.Namespace, nc.Name)
}
if nc.IsClusterSSLEnabled() {
options = append(options, SetClusterTLS(true))
klog.Infof("cluster [%s/%s] SSL enabled", nc.Namespace, nc.Name)
klog.V(4).Infof("cluster [%s/%s] SSL enabled", nc.Namespace, nc.Name)
}

caCert, clientCert, clientKey, err := getCerts(nc.Namespace, nc.Spec.SSLCerts)
Expand Down
16 changes: 16 additions & 0 deletions pkg/webhook/nebulacluster/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,19 @@ func validateNebulaClusterUpdate(nc, oldNC *v1alpha1.NebulaCluster) (allErrs fie

return allErrs
}

// validateNebulaClusterDelete validates a NebulaCluster on Delete.
func validateNebulaClusterDelete(nc *v1alpha1.NebulaCluster) (allErrs field.ErrorList) {
name := nc.Name
namespace := nc.Namespace

klog.Infof("receive admission with resource [%s/%s], GVK %s, operation %s", namespace, name,
nc.GroupVersionKind().String(), admissionv1.Delete)

if annotation.ISDeleteProtected(nc.Annotations) {
fldPath := field.NewPath("metadata")
allErrs = append(allErrs, field.Forbidden(fldPath.Child("annotations").Key(annotation.AnnDeleteProtection),
"protected cluster cannot be deleted"))
}
return allErrs
}
18 changes: 13 additions & 5 deletions pkg/webhook/nebulacluster/validating.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,19 @@ func (h *ValidatingAdmission) Handle(_ context.Context, req admission.Request) (

obj := &v1alpha1.NebulaCluster{}

err := h.Decoder.Decode(req, obj)
if err != nil {
return admission.Errored(http.StatusBadRequest, err)
if req.Operation == admissionv1.Delete {
if err := h.Decoder.DecodeRaw(req.OldObject, obj); err != nil {
return admission.Errored(http.StatusBadRequest, err)
}
} else {
if err := h.Decoder.Decode(req, obj); err != nil {
return admission.Errored(http.StatusBadRequest, err)
}
}

operation := req.AdmissionRequest.Operation

// If not Create or Update, return earlier.
if !(operation == admissionv1.Create || operation == admissionv1.Update) {
if operation == admissionv1.Connect {
return admission.ValidationResponse(true, "")
}

Expand All @@ -72,6 +76,10 @@ func (h *ValidatingAdmission) Handle(_ context.Context, req admission.Request) (
if allErrs := validateNebulaClusterUpdate(obj, oldObj); len(allErrs) > 0 {
return admission.Errored(http.StatusUnprocessableEntity, allErrs.ToAggregate())
}
} else if operation == admissionv1.Delete {
if allErrs := validateNebulaClusterDelete(obj); len(allErrs) > 0 {
return admission.Errored(http.StatusUnprocessableEntity, allErrs.ToAggregate())
}
}

return admission.ValidationResponse(true, "")
Expand Down

0 comments on commit 552e89d

Please sign in to comment.