diff --git a/cmd/webhook/app/webhook.go b/cmd/webhook/app/webhook.go index e50ceeb3ce49..50c7c348d849 100644 --- a/cmd/webhook/app/webhook.go +++ b/cmd/webhook/app/webhook.go @@ -41,6 +41,7 @@ import ( "github.com/karmada-io/karmada/pkg/version/sharedcommand" "github.com/karmada-io/karmada/pkg/webhook/clusteroverridepolicy" "github.com/karmada-io/karmada/pkg/webhook/clusterpropagationpolicy" + "github.com/karmada-io/karmada/pkg/webhook/clusterresourcebinding" "github.com/karmada-io/karmada/pkg/webhook/configuration" "github.com/karmada-io/karmada/pkg/webhook/cronfederatedhpa" "github.com/karmada-io/karmada/pkg/webhook/federatedhpa" @@ -49,6 +50,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/resourcebinding" "github.com/karmada-io/karmada/pkg/webhook/resourcedeletionprotection" "github.com/karmada-io/karmada/pkg/webhook/resourceinterpretercustomization" "github.com/karmada-io/karmada/pkg/webhook/work" @@ -158,6 +160,8 @@ func Run(ctx context.Context, opts *options.Options) error { hookServer.Register("/mutate-multiclusterservice", &webhook.Admission{Handler: &multiclusterservice.MutatingAdmission{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.Register("/mutate-resourcebinding", &webhook.Admission{Handler: &resourcebinding.MutatingAdmission{Decoder: decoder}}) + hookServer.Register("/mutate-clusterresourcebinding", &webhook.Admission{Handler: &clusterresourcebinding.MutatingAdmission{Decoder: decoder}}) hookServer.WebhookMux().Handle("/readyz/", http.StripPrefix("/readyz/", &healthz.Handler{})) // blocks until the context is done. diff --git a/pkg/webhook/clusterpropagationpolicy/mutating.go b/pkg/webhook/clusterpropagationpolicy/mutating.go index 20d1933a657f..d67f4c6ae640 100644 --- a/pkg/webhook/clusterpropagationpolicy/mutating.go +++ b/pkg/webhook/clusterpropagationpolicy/mutating.go @@ -22,9 +22,11 @@ import ( "fmt" "net/http" + "github.com/google/uuid" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1" + "github.com/karmada-io/karmada/pkg/util" "github.com/karmada-io/karmada/pkg/util/helper" "github.com/karmada-io/karmada/pkg/util/validation" ) @@ -80,6 +82,11 @@ func (a *MutatingAdmission) Handle(_ context.Context, req admission.Request) adm } } + if util.GetLabelValue(policy.Labels, policyv1alpha1.ClusterPropagationPolicyPermanentIDLabel) == "" { + id := uuid.New().String() + policy.Labels = util.DedupeAndMergeLabels(policy.Labels, map[string]string{policyv1alpha1.ClusterPropagationPolicyPermanentIDLabel: id}) + } + marshaledBytes, err := json.Marshal(policy) if err != nil { return admission.Errored(http.StatusInternalServerError, err) diff --git a/pkg/webhook/clusterresourcebinding/mutating.go b/pkg/webhook/clusterresourcebinding/mutating.go new file mode 100644 index 000000000000..de399f11c709 --- /dev/null +++ b/pkg/webhook/clusterresourcebinding/mutating.go @@ -0,0 +1,59 @@ +/* +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 clusterresourcebinding + +import ( + "context" + "encoding/json" + "net/http" + + "github.com/google/uuid" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + + workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2" + "github.com/karmada-io/karmada/pkg/util" +) + +// MutatingAdmission mutates API request if necessary. +type MutatingAdmission struct { + Decoder *admission.Decoder +} + +// Check if our MutatingAdmission implements necessary interface +var _ admission.Handler = &MutatingAdmission{} + +// Handle yields a response to an AdmissionRequest. +func (a *MutatingAdmission) Handle(_ context.Context, req admission.Request) admission.Response { + mcs := &workv1alpha2.ClusterResourceBinding{} + + err := a.Decoder.Decode(req, mcs) + if err != nil { + return admission.Errored(http.StatusBadRequest, err) + } + + if util.GetLabelValue(mcs.Labels, workv1alpha2.ClusterResourceBindingPermanentIDLabel) == "" { + id := uuid.New().String() + mcs.Labels = util.DedupeAndMergeLabels(mcs.Labels, map[string]string{workv1alpha2.ClusterResourceBindingPermanentIDLabel: id}) + } + + marshaledBytes, err := json.Marshal(mcs) + if err != nil { + return admission.Errored(http.StatusInternalServerError, err) + } + + return admission.PatchResponseFromRaw(req.Object.Raw, marshaledBytes) +} diff --git a/pkg/webhook/propagationpolicy/mutating.go b/pkg/webhook/propagationpolicy/mutating.go index 7bd5879a63a3..db89d67927e0 100644 --- a/pkg/webhook/propagationpolicy/mutating.go +++ b/pkg/webhook/propagationpolicy/mutating.go @@ -22,10 +22,12 @@ import ( "fmt" "net/http" + "github.com/google/uuid" "k8s.io/klog/v2" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1" + "github.com/karmada-io/karmada/pkg/util" "github.com/karmada-io/karmada/pkg/util/helper" "github.com/karmada-io/karmada/pkg/util/validation" ) @@ -92,6 +94,11 @@ func (a *MutatingAdmission) Handle(_ context.Context, req admission.Request) adm } } + if util.GetLabelValue(policy.Labels, policyv1alpha1.PropagationPolicyPermanentIDLabel) == "" { + id := uuid.New().String() + policy.Labels = util.DedupeAndMergeLabels(policy.Labels, map[string]string{policyv1alpha1.PropagationPolicyPermanentIDLabel: id}) + } + marshaledBytes, err := json.Marshal(policy) if err != nil { return admission.Errored(http.StatusInternalServerError, err) diff --git a/pkg/webhook/resourcebinding/mutating.go b/pkg/webhook/resourcebinding/mutating.go new file mode 100644 index 000000000000..7d1f3686f0a3 --- /dev/null +++ b/pkg/webhook/resourcebinding/mutating.go @@ -0,0 +1,59 @@ +/* +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 resourcebinding + +import ( + "context" + "encoding/json" + "net/http" + + "github.com/google/uuid" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + + workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2" + "github.com/karmada-io/karmada/pkg/util" +) + +// MutatingAdmission mutates API request if necessary. +type MutatingAdmission struct { + Decoder *admission.Decoder +} + +// Check if our MutatingAdmission implements necessary interface +var _ admission.Handler = &MutatingAdmission{} + +// Handle yields a response to an AdmissionRequest. +func (a *MutatingAdmission) Handle(_ context.Context, req admission.Request) admission.Response { + mcs := &workv1alpha2.ResourceBinding{} + + err := a.Decoder.Decode(req, mcs) + if err != nil { + return admission.Errored(http.StatusBadRequest, err) + } + + if util.GetLabelValue(mcs.Labels, workv1alpha2.ResourceBindingPermanentIDLabel) == "" { + id := uuid.New().String() + mcs.Labels = util.DedupeAndMergeLabels(mcs.Labels, map[string]string{workv1alpha2.ResourceBindingPermanentIDLabel: id}) + } + + marshaledBytes, err := json.Marshal(mcs) + if err != nil { + return admission.Errored(http.StatusInternalServerError, err) + } + + return admission.PatchResponseFromRaw(req.Object.Raw, marshaledBytes) +} diff --git a/pkg/webhook/work/mutating.go b/pkg/webhook/work/mutating.go index 4d788bdd57cc..706842b8c7e7 100644 --- a/pkg/webhook/work/mutating.go +++ b/pkg/webhook/work/mutating.go @@ -21,13 +21,16 @@ import ( "encoding/json" "net/http" + "github.com/google/uuid" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/klog/v2" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" workv1alpha1 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha1" + workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2" "github.com/karmada-io/karmada/pkg/resourceinterpreter/default/native/prune" + "github.com/karmada-io/karmada/pkg/util" ) // MutatingAdmission mutates API request if necessary. @@ -78,5 +81,10 @@ func (a *MutatingAdmission) Handle(_ context.Context, req admission.Request) adm return admission.Errored(http.StatusInternalServerError, err) } + if util.GetLabelValue(work.Labels, workv1alpha2.WorkPermanentIDLabel) == "" { + id := uuid.New().String() + work.Labels = util.DedupeAndMergeLabels(work.Labels, map[string]string{workv1alpha2.WorkPermanentIDLabel: id}) + } + return admission.PatchResponseFromRaw(req.Object.Raw, marshaledBytes) }