karmada/pkg/util/overridemanager/labelannotationoverrider.go

65 lines
2.4 KiB
Go

package overridemanager
import (
"strings"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
)
func applyLabelsOverriders(rawObj *unstructured.Unstructured, labelOverriders []policyv1alpha1.LabelAnnotationOverrider) error {
return applyLabelAnnotationOverriders(rawObj, labelOverriders, "metadata", "labels")
}
func applyAnnotationsOverriders(rawObj *unstructured.Unstructured, annotationOverriders []policyv1alpha1.LabelAnnotationOverrider) error {
return applyLabelAnnotationOverriders(rawObj, annotationOverriders, "metadata", "annotations")
}
func applyLabelAnnotationOverriders(rawObj *unstructured.Unstructured, labelAnnotationOverriders []policyv1alpha1.LabelAnnotationOverrider, path ...string) error {
for index := range labelAnnotationOverriders {
patches := buildLabelAnnotationOverriderPatches(rawObj, labelAnnotationOverriders[index], path)
if len(patches) == 0 {
continue
}
if err := applyJSONPatch(rawObj, patches); err != nil {
return err
}
}
return nil
}
func buildLabelAnnotationOverriderPatches(rawObj *unstructured.Unstructured, overrider policyv1alpha1.LabelAnnotationOverrider, path []string) []overrideOption {
patches := make([]overrideOption, 0)
for key, value := range overrider.Value {
switch overrider.Operator {
case policyv1alpha1.OverriderOpRemove, policyv1alpha1.OverriderOpReplace:
match, _, _ := unstructured.NestedStringMap(rawObj.Object, path...)
if _, exist := match[key]; !exist {
continue
}
case policyv1alpha1.OverriderOpAdd:
_, exist, _ := unstructured.NestedStringMap(rawObj.Object, path...)
if exist {
break
}
if err := unstructured.SetNestedStringMap(rawObj.Object, map[string]string{}, path...); err != nil {
continue
}
}
// If the key contains '/', we must replace(escape) it to '~1' according to the
// rule of jsonpath identifying a specific value.
// See https://jsonpatch.com/#json-pointer for more details.
// Note: here don't replace '~' because it is not a valid character for
// both annotations and labels, the key with '~' should be prevented at
// the validation phase.
key = strings.ReplaceAll(key, "/", "~1")
patches = append(patches, overrideOption{
Op: string(overrider.Operator),
Path: "/" + strings.Join(append(path, key), "/"),
Value: value,
})
}
return patches
}