Skip to content

Commit

Permalink
Merge pull request #4074 from Vacant2333/add-resource-deletion-protec…
Browse files Browse the repository at this point in the history
…tion-by-label

[Feat] Resource Deletion Protection
  • Loading branch information
karmada-bot authored Oct 18, 2023
2 parents e2e33a5 + 1df2420 commit 557348f
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 0 deletions.
17 changes: 17 additions & 0 deletions artifacts/deploy/webhook-configuration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -237,3 +237,20 @@ webhooks:
sideEffects: None
admissionReviewVersions: [ "v1" ]
timeoutSeconds: 3
- name: resourcedeletionprotection.karmada.io
rules:
- operations: ["DELETE"]
apiGroups: ["*"]
apiVersions: ["*"]
resources: ["*"]
scope: "*"
clientConfig:
url: https://karmada-webhook.karmada-system.svc:443/validate-resourcedeletionprotection
caBundle: {{caBundle}}
objectSelector:
matchExpressions:
- { key: "resourcetemplate.karmada.io/deletion-protected", operator: "Exists" }
failurePolicy: Fail
sideEffects: None
admissionReviewVersions: [ "v1" ]
timeoutSeconds: 3
17 changes: 17 additions & 0 deletions charts/karmada/templates/_karmada_webhook_configuration.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -213,4 +213,21 @@ webhooks:
sideEffects: None
admissionReviewVersions: [ "v1" ]
timeoutSeconds: 3
- name: resourcedeletionprotection.karmada.io
rules:
- operations: ["DELETE"]
apiGroups: ["*"]
apiVersions: ["*"]
resources: ["*"]
scope: "*"
clientConfig:
url: https://{{ $name }}-webhook.{{ $namespace }}.svc:443/validate-resourcedeletionprotection
{{- include "karmada.webhook.caBundle" . | nindent 6 }}
objectSelector:
matchExpressions:
- { key: "resourcetemplate.karmada.io/deletion-protected", operator: "Exists" }
failurePolicy: Fail
sideEffects: None
admissionReviewVersions: [ "v1" ]
timeoutSeconds: 3
{{- end -}}
2 changes: 2 additions & 0 deletions cmd/webhook/app/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"github.com/karmada-io/karmada/pkg/webhook/multiclusterservice"
"github.com/karmada-io/karmada/pkg/webhook/overridepolicy"
"github.com/karmada-io/karmada/pkg/webhook/propagationpolicy"
"github.com/karmada-io/karmada/pkg/webhook/resourcedeletionprotection"
"github.com/karmada-io/karmada/pkg/webhook/resourceinterpretercustomization"
"github.com/karmada-io/karmada/pkg/webhook/work"
)
Expand Down Expand Up @@ -139,6 +140,7 @@ func Run(ctx context.Context, opts *options.Options) error {
hookServer.Register("/validate-multiclusteringress", &webhook.Admission{Handler: &multiclusteringress.ValidatingAdmission{Decoder: decoder}})
hookServer.Register("/validate-multiclusterservice", &webhook.Admission{Handler: &multiclusterservice.ValidatingAdmission{Decoder: decoder}})
hookServer.Register("/mutate-federatedhpa", &webhook.Admission{Handler: &federatedhpa.MutatingAdmission{Decoder: decoder}})
hookServer.Register("/validate-resourcedeletionprotection", &webhook.Admission{Handler: &resourcedeletionprotection.ValidatingAdmission{Decoder: decoder}})
hookServer.WebhookMux().Handle("/readyz/", http.StripPrefix("/readyz/", &healthz.Handler{}))

// blocks until the context is done.
Expand Down
17 changes: 17 additions & 0 deletions operator/pkg/karmadaresource/webhookconfiguration/manifests.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,5 +245,22 @@ webhooks:
sideEffects: None
admissionReviewVersions: [ "v1" ]
timeoutSeconds: 3
- name: resourcedeletionprotection.karmada.io
rules:
- operations: ["DELETE"]
apiGroups: ["*"]
apiVersions: ["*"]
resources: ["*"]
scope: "*"
clientConfig:
url: https://{{ .Service }}.{{ .Namespace }}.svc:443/validate-resourcedeletionprotection
caBundle: {{ .CaBundle }}
objectSelector:
matchExpressions:
- { key: "resourcetemplate.karmada.io/deletion-protected", operator: "Exists" }
failurePolicy: Fail
sideEffects: None
admissionReviewVersions: [ "v1" ]
timeoutSeconds: 3
`
)
8 changes: 8 additions & 0 deletions pkg/apis/work/v1alpha2/well_known_constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ const (
// E.g. "resourcetemplate.karmada.io/managed-annotations: bar,foo".
// Note: the keys will be sorted in alphabetical order.
ManagedAnnotation = "resourcetemplate.karmada.io/managed-annotations"

// DeletionProtectionLabelKey If a user assigns the DeletionProtectionLabelKey label to a specific resource,
// and the value of this label is DeletionProtectionAlways, then deletion requests
// for this resource will be denied.
// In the current design, only the Value set to 'Always' will be protected,
// Additional options will be added here in the future.
DeletionProtectionLabelKey = "resourcetemplate.karmada.io/deletion-protected"
DeletionProtectionAlways = "Always"
)

// Define eviction reasons.
Expand Down
17 changes: 17 additions & 0 deletions pkg/karmadactl/cmdinit/karmada/webhook_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,23 @@ webhooks:
sideEffects: None
admissionReviewVersions: [ "v1" ]
timeoutSeconds: 3
- name: resourcedeletionprotection.karmada.io
rules:
- operations: ["DELETE"]
apiGroups: ["*"]
apiVersions: ["*"]
resources: ["*"]
scope: "*"
clientConfig:
url: https://karmada-webhook.%[1]s.svc:443/validate-resourcedeletionprotection
caBundle: %[2]s
objectSelector:
matchExpressions:
- { key: "resourcetemplate.karmada.io/deletion-protected", operator: "Exists" }
failurePolicy: Fail
sideEffects: None
admissionReviewVersions: [ "v1" ]
timeoutSeconds: 3
`, systemNamespace, caBundle)
}

Expand Down
File renamed without changes.
File renamed without changes.
61 changes: 61 additions & 0 deletions pkg/webhook/resourcedeletionprotection/validating.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
Copyright 2023 The Karmada Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package resourcedeletionprotection

import (
"context"
"fmt"
"net/http"

admissionv1 "k8s.io/api/admission/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"

workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
)

// ValidatingAdmission validates resource templates to ensure those protected resources are not delectable.
type ValidatingAdmission struct {
Decoder *admission.Decoder
}

// Check if our ValidatingAdmission implements necessary interface
var _ admission.Handler = &ValidatingAdmission{}

// Handle implements admission.Handler interface.
// It yields a response to an AdmissionRequest.
func (v *ValidatingAdmission) Handle(_ context.Context, req admission.Request) admission.Response {
if req.Operation != admissionv1.Delete {
// We only care about the Delete operation.
return admission.Allowed("")
}

// Parse the uncertain type resource object
obj := &unstructured.Unstructured{}
if err := v.Decoder.DecodeRaw(req.OldObject, obj); err != nil {
return admission.Errored(http.StatusBadRequest, err)
}

klog.V(2).Infof("Validating ResourceDeletionProtection for resource: Kind:%s Name:%s Namespace:%s", req.Kind.Kind, obj.GetName(), obj.GetNamespace())

if value, ok := obj.GetLabels()[workv1alpha2.DeletionProtectionLabelKey]; ok {
// In normal, requests will be processed here.
// Only v1alpha2.DeletionProtectionAlways value will be denied
if value == workv1alpha2.DeletionProtectionAlways {
return admission.Denied(fmt.Sprintf("This resource is protected, please make sure to remove the label: %s", workv1alpha2.DeletionProtectionLabelKey))
}
}
return admission.Allowed("")
}

0 comments on commit 557348f

Please sign in to comment.