Merge pull request #2584 from chaunceyjiang/overriders

introduce overriders for annotation and label
This commit is contained in:
karmada-bot 2022-10-11 09:05:24 +08:00 committed by GitHub
commit eceba6480a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 785 additions and 4 deletions

View File

@ -15038,6 +15038,28 @@
}
}
},
"com.github.karmada-io.karmada.pkg.apis.policy.v1alpha1.LabelAnnotationOverrider": {
"description": "LabelAnnotationOverrider represents the rules dedicated to handling workload labels/annotations",
"type": "object",
"required": [
"operator"
],
"properties": {
"operator": {
"description": "Operator represents the operator which will apply on the workload.",
"type": "string",
"default": ""
},
"value": {
"description": "Value to be applied to annotations/labels of workload. Items in Value which will be appended after annotations/labels when Operator is 'add'. Items in Value which match in annotations/labels will be deleted when Operator is 'remove'. Items in Value which match in annotations/labels will be replaced when Operator is 'replace'.",
"type": "object",
"additionalProperties": {
"type": "string",
"default": ""
}
}
}
},
"com.github.karmada-io.karmada.pkg.apis.policy.v1alpha1.OverridePolicy": {
"description": "OverridePolicy represents the policy that overrides a group of resources to one or more clusters.",
"type": "object",
@ -15139,9 +15161,17 @@
}
},
"com.github.karmada-io.karmada.pkg.apis.policy.v1alpha1.Overriders": {
"description": "Overriders offers various alternatives to represent the override rules.\n\nIf more than one alternative exists, they will be applied with following order: - ImageOverrider - CommandOverrider - ArgsOverrider - Plaintext",
"description": "Overriders offers various alternatives to represent the override rules.\n\nIf more than one alternative exists, they will be applied with following order: - ImageOverrider - CommandOverrider - ArgsOverrider - LabelsOverrider - AnnotationsOverrider - Plaintext",
"type": "object",
"properties": {
"annotationsOverrider": {
"description": "AnnotationsOverrider represents the rules dedicated to handling workload annotations",
"type": "array",
"items": {
"default": {},
"$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.policy.v1alpha1.LabelAnnotationOverrider"
}
},
"argsOverrider": {
"description": "ArgsOverrider represents the rules dedicated to handling container args",
"type": "array",
@ -15166,6 +15196,14 @@
"$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.policy.v1alpha1.ImageOverrider"
}
},
"labelsOverrider": {
"description": "LabelsOverrider represents the rules dedicated to handling workload labels",
"type": "array",
"items": {
"default": {},
"$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.policy.v1alpha1.LabelAnnotationOverrider"
}
},
"plaintext": {
"description": "Plaintext represents override rules defined with plaintext overriders.",
"type": "array",

View File

@ -50,6 +50,36 @@ spec:
description: Overriders represents the override rules that would
apply on resources
properties:
annotationsOverrider:
description: AnnotationsOverrider represents the rules dedicated
to handling workload annotations
items:
description: LabelAnnotationOverrider represents the rules
dedicated to handling workload labels/annotations
properties:
operator:
description: Operator represents the operator which
will apply on the workload.
enum:
- add
- remove
- replace
type: string
value:
additionalProperties:
type: string
description: Value to be applied to annotations/labels
of workload. Items in Value which will be appended
after annotations/labels when Operator is 'add'.
Items in Value which match in annotations/labels
will be deleted when Operator is 'remove'. Items
in Value which match in annotations/labels will
be replaced when Operator is 'replace'.
type: object
required:
- operator
type: object
type: array
argsOverrider:
description: ArgsOverrider represents the rules dedicated
to handling container args
@ -171,6 +201,36 @@ spec:
- operator
type: object
type: array
labelsOverrider:
description: LabelsOverrider represents the rules dedicated
to handling workload labels
items:
description: LabelAnnotationOverrider represents the rules
dedicated to handling workload labels/annotations
properties:
operator:
description: Operator represents the operator which
will apply on the workload.
enum:
- add
- remove
- replace
type: string
value:
additionalProperties:
type: string
description: Value to be applied to annotations/labels
of workload. Items in Value which will be appended
after annotations/labels when Operator is 'add'.
Items in Value which match in annotations/labels
will be deleted when Operator is 'remove'. Items
in Value which match in annotations/labels will
be replaced when Operator is 'replace'.
type: object
required:
- operator
type: object
type: array
plaintext:
description: Plaintext represents override rules defined
with plaintext overriders.
@ -314,6 +374,35 @@ spec:
apply on resources \n Deprecated: This filed is deprecated in v1.0
and please use the OverrideRules instead."
properties:
annotationsOverrider:
description: AnnotationsOverrider represents the rules dedicated
to handling workload annotations
items:
description: LabelAnnotationOverrider represents the rules dedicated
to handling workload labels/annotations
properties:
operator:
description: Operator represents the operator which will
apply on the workload.
enum:
- add
- remove
- replace
type: string
value:
additionalProperties:
type: string
description: Value to be applied to annotations/labels of
workload. Items in Value which will be appended after
annotations/labels when Operator is 'add'. Items in Value
which match in annotations/labels will be deleted when
Operator is 'remove'. Items in Value which match in annotations/labels
will be replaced when Operator is 'replace'.
type: object
required:
- operator
type: object
type: array
argsOverrider:
description: ArgsOverrider represents the rules dedicated to handling
container args
@ -430,6 +519,35 @@ spec:
- operator
type: object
type: array
labelsOverrider:
description: LabelsOverrider represents the rules dedicated to
handling workload labels
items:
description: LabelAnnotationOverrider represents the rules dedicated
to handling workload labels/annotations
properties:
operator:
description: Operator represents the operator which will
apply on the workload.
enum:
- add
- remove
- replace
type: string
value:
additionalProperties:
type: string
description: Value to be applied to annotations/labels of
workload. Items in Value which will be appended after
annotations/labels when Operator is 'add'. Items in Value
which match in annotations/labels will be deleted when
Operator is 'remove'. Items in Value which match in annotations/labels
will be replaced when Operator is 'replace'.
type: object
required:
- operator
type: object
type: array
plaintext:
description: Plaintext represents override rules defined with
plaintext overriders.

View File

@ -50,6 +50,36 @@ spec:
description: Overriders represents the override rules that would
apply on resources
properties:
annotationsOverrider:
description: AnnotationsOverrider represents the rules dedicated
to handling workload annotations
items:
description: LabelAnnotationOverrider represents the rules
dedicated to handling workload labels/annotations
properties:
operator:
description: Operator represents the operator which
will apply on the workload.
enum:
- add
- remove
- replace
type: string
value:
additionalProperties:
type: string
description: Value to be applied to annotations/labels
of workload. Items in Value which will be appended
after annotations/labels when Operator is 'add'.
Items in Value which match in annotations/labels
will be deleted when Operator is 'remove'. Items
in Value which match in annotations/labels will
be replaced when Operator is 'replace'.
type: object
required:
- operator
type: object
type: array
argsOverrider:
description: ArgsOverrider represents the rules dedicated
to handling container args
@ -171,6 +201,36 @@ spec:
- operator
type: object
type: array
labelsOverrider:
description: LabelsOverrider represents the rules dedicated
to handling workload labels
items:
description: LabelAnnotationOverrider represents the rules
dedicated to handling workload labels/annotations
properties:
operator:
description: Operator represents the operator which
will apply on the workload.
enum:
- add
- remove
- replace
type: string
value:
additionalProperties:
type: string
description: Value to be applied to annotations/labels
of workload. Items in Value which will be appended
after annotations/labels when Operator is 'add'.
Items in Value which match in annotations/labels
will be deleted when Operator is 'remove'. Items
in Value which match in annotations/labels will
be replaced when Operator is 'replace'.
type: object
required:
- operator
type: object
type: array
plaintext:
description: Plaintext represents override rules defined
with plaintext overriders.
@ -314,6 +374,35 @@ spec:
apply on resources \n Deprecated: This filed is deprecated in v1.0
and please use the OverrideRules instead."
properties:
annotationsOverrider:
description: AnnotationsOverrider represents the rules dedicated
to handling workload annotations
items:
description: LabelAnnotationOverrider represents the rules dedicated
to handling workload labels/annotations
properties:
operator:
description: Operator represents the operator which will
apply on the workload.
enum:
- add
- remove
- replace
type: string
value:
additionalProperties:
type: string
description: Value to be applied to annotations/labels of
workload. Items in Value which will be appended after
annotations/labels when Operator is 'add'. Items in Value
which match in annotations/labels will be deleted when
Operator is 'remove'. Items in Value which match in annotations/labels
will be replaced when Operator is 'replace'.
type: object
required:
- operator
type: object
type: array
argsOverrider:
description: ArgsOverrider represents the rules dedicated to handling
container args
@ -430,6 +519,35 @@ spec:
- operator
type: object
type: array
labelsOverrider:
description: LabelsOverrider represents the rules dedicated to
handling workload labels
items:
description: LabelAnnotationOverrider represents the rules dedicated
to handling workload labels/annotations
properties:
operator:
description: Operator represents the operator which will
apply on the workload.
enum:
- add
- remove
- replace
type: string
value:
additionalProperties:
type: string
description: Value to be applied to annotations/labels of
workload. Items in Value which will be appended after
annotations/labels when Operator is 'add'. Items in Value
which match in annotations/labels will be deleted when
Operator is 'remove'. Items in Value which match in annotations/labels
will be replaced when Operator is 'replace'.
type: object
required:
- operator
type: object
type: array
plaintext:
description: Plaintext represents override rules defined with
plaintext overriders.

View File

@ -83,6 +83,8 @@ type RuleWithCluster struct {
// - ImageOverrider
// - CommandOverrider
// - ArgsOverrider
// - LabelsOverrider
// - AnnotationsOverrider
// - Plaintext
type Overriders struct {
// Plaintext represents override rules defined with plaintext overriders.
@ -100,6 +102,29 @@ type Overriders struct {
// ArgsOverrider represents the rules dedicated to handling container args
// +optional
ArgsOverrider []CommandArgsOverrider `json:"argsOverrider,omitempty"`
// LabelsOverrider represents the rules dedicated to handling workload labels
// +optional
LabelsOverrider []LabelAnnotationOverrider `json:"labelsOverrider,omitempty"`
// AnnotationsOverrider represents the rules dedicated to handling workload annotations
// +optional
AnnotationsOverrider []LabelAnnotationOverrider `json:"annotationsOverrider,omitempty"`
}
// LabelAnnotationOverrider represents the rules dedicated to handling workload labels/annotations
type LabelAnnotationOverrider struct {
// Operator represents the operator which will apply on the workload.
// +kubebuilder:validation:Enum=add;remove;replace
// +required
Operator OverriderOperator `json:"operator"`
// Value to be applied to annotations/labels of workload.
// Items in Value which will be appended after annotations/labels when Operator is 'add'.
// Items in Value which match in annotations/labels will be deleted when Operator is 'remove'.
// Items in Value which match in annotations/labels will be replaced when Operator is 'replace'.
// +required
Value map[string]string `json:"value,omitempty"`
}
// ImageOverrider represents the rules dedicated to handling image overrides.

View File

@ -416,6 +416,29 @@ func (in *ImagePredicate) DeepCopy() *ImagePredicate {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *LabelAnnotationOverrider) DeepCopyInto(out *LabelAnnotationOverrider) {
*out = *in
if in.Value != nil {
in, out := &in.Value, &out.Value
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LabelAnnotationOverrider.
func (in *LabelAnnotationOverrider) DeepCopy() *LabelAnnotationOverrider {
if in == nil {
return nil
}
out := new(LabelAnnotationOverrider)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OverridePolicy) DeepCopyInto(out *OverridePolicy) {
*out = *in
@ -543,6 +566,20 @@ func (in *Overriders) DeepCopyInto(out *Overriders) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.LabelsOverrider != nil {
in, out := &in.LabelsOverrider, &out.LabelsOverrider
*out = make([]LabelAnnotationOverrider, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.AnnotationsOverrider != nil {
in, out := &in.AnnotationsOverrider, &out.AnnotationsOverrider
*out = make([]LabelAnnotationOverrider, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}

View File

@ -57,6 +57,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
"github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1.FieldSelector": schema_pkg_apis_policy_v1alpha1_FieldSelector(ref),
"github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1.ImageOverrider": schema_pkg_apis_policy_v1alpha1_ImageOverrider(ref),
"github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1.ImagePredicate": schema_pkg_apis_policy_v1alpha1_ImagePredicate(ref),
"github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1.LabelAnnotationOverrider": schema_pkg_apis_policy_v1alpha1_LabelAnnotationOverrider(ref),
"github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1.OverridePolicy": schema_pkg_apis_policy_v1alpha1_OverridePolicy(ref),
"github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1.OverridePolicyList": schema_pkg_apis_policy_v1alpha1_OverridePolicyList(ref),
"github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1.OverrideSpec": schema_pkg_apis_policy_v1alpha1_OverrideSpec(ref),
@ -2436,6 +2437,44 @@ func schema_pkg_apis_policy_v1alpha1_ImagePredicate(ref common.ReferenceCallback
}
}
func schema_pkg_apis_policy_v1alpha1_LabelAnnotationOverrider(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "LabelAnnotationOverrider represents the rules dedicated to handling workload labels/annotations",
Type: []string{"object"},
Properties: map[string]spec.Schema{
"operator": {
SchemaProps: spec.SchemaProps{
Description: "Operator represents the operator which will apply on the workload.",
Default: "",
Type: []string{"string"},
Format: "",
},
},
"value": {
SchemaProps: spec.SchemaProps{
Description: "Value to be applied to annotations/labels of workload. Items in Value which will be appended after annotations/labels when Operator is 'add'. Items in Value which match in annotations/labels will be deleted when Operator is 'remove'. Items in Value which match in annotations/labels will be replaced when Operator is 'replace'.",
Type: []string{"object"},
AdditionalProperties: &spec.SchemaOrBool{
Allows: true,
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Default: "",
Type: []string{"string"},
Format: "",
},
},
},
},
},
},
Required: []string{"operator"},
},
},
}
}
func schema_pkg_apis_policy_v1alpha1_OverridePolicy(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
@ -2589,7 +2628,7 @@ func schema_pkg_apis_policy_v1alpha1_Overriders(ref common.ReferenceCallback) co
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "Overriders offers various alternatives to represent the override rules.\n\nIf more than one alternative exists, they will be applied with following order: - ImageOverrider - CommandOverrider - ArgsOverrider - Plaintext",
Description: "Overriders offers various alternatives to represent the override rules.\n\nIf more than one alternative exists, they will be applied with following order: - ImageOverrider - CommandOverrider - ArgsOverrider - LabelsOverrider - AnnotationsOverrider - Plaintext",
Type: []string{"object"},
Properties: map[string]spec.Schema{
"plaintext": {
@ -2648,11 +2687,39 @@ func schema_pkg_apis_policy_v1alpha1_Overriders(ref common.ReferenceCallback) co
},
},
},
"labelsOverrider": {
SchemaProps: spec.SchemaProps{
Description: "LabelsOverrider represents the rules dedicated to handling workload labels",
Type: []string{"array"},
Items: &spec.SchemaOrArray{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Default: map[string]interface{}{},
Ref: ref("github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1.LabelAnnotationOverrider"),
},
},
},
},
},
"annotationsOverrider": {
SchemaProps: spec.SchemaProps{
Description: "AnnotationsOverrider represents the rules dedicated to handling workload annotations",
Type: []string{"array"},
Items: &spec.SchemaOrArray{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Default: map[string]interface{}{},
Ref: ref("github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1.LabelAnnotationOverrider"),
},
},
},
},
},
},
},
},
Dependencies: []string{
"github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1.CommandArgsOverrider", "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1.ImageOverrider", "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1.PlaintextOverrider"},
"github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1.CommandArgsOverrider", "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1.ImageOverrider", "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1.LabelAnnotationOverrider", "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1.PlaintextOverrider"},
}
}

View File

@ -0,0 +1,50 @@
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:
}
patches = append(patches, overrideOption{
Op: string(overrider.Operator),
Path: "/" + strings.Join(append(path, key), "/"),
Value: value,
})
}
return patches
}

View File

@ -0,0 +1,276 @@
package overridemanager
import (
"reflect"
"testing"
appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
utilhelper "github.com/karmada-io/karmada/pkg/util/helper"
"github.com/karmada-io/karmada/test/helper"
)
func Test_applyLabelsOverriders(t *testing.T) {
type args struct {
rawObj *unstructured.Unstructured
commandOverriders []policyv1alpha1.LabelAnnotationOverrider
}
deployment := helper.NewDeployment(metav1.NamespaceDefault, "test")
deployment.Labels = map[string]string{
"foo": "foo",
"bar": "bar",
}
tests := []struct {
name string
args args
want map[string]string
wantErr bool
}{
{
name: "test labels replace",
args: args{
rawObj: func() *unstructured.Unstructured {
deploymentObj, _ := utilhelper.ToUnstructured(deployment)
return deploymentObj
}(),
commandOverriders: []policyv1alpha1.LabelAnnotationOverrider{
{
Operator: policyv1alpha1.OverriderOpReplace,
Value: map[string]string{
"foo": "exist",
"non-exist": "non-exist",
},
},
},
},
want: map[string]string{
"foo": "exist",
"bar": "bar",
},
wantErr: false,
},
{
name: "test labels add",
args: args{
rawObj: func() *unstructured.Unstructured {
deploymentObj, _ := utilhelper.ToUnstructured(deployment)
return deploymentObj
}(),
commandOverriders: []policyv1alpha1.LabelAnnotationOverrider{
{
Operator: policyv1alpha1.OverriderOpAdd,
Value: map[string]string{
"test": "test",
},
},
},
},
want: map[string]string{
"test": "test",
"foo": "foo",
"bar": "bar",
},
wantErr: false,
},
{
name: "test labels remove",
args: args{
rawObj: func() *unstructured.Unstructured {
deploymentObj, _ := utilhelper.ToUnstructured(deployment)
return deploymentObj
}(),
commandOverriders: []policyv1alpha1.LabelAnnotationOverrider{
{
Operator: policyv1alpha1.OverriderOpRemove,
Value: map[string]string{
"foo": "foo",
"non-exist": "non-exist",
},
},
},
},
want: map[string]string{
"bar": "bar",
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := applyLabelsOverriders(tt.args.rawObj, tt.args.commandOverriders); (err != nil) != tt.wantErr {
t.Fatalf("applyLabelsOverriders() error = %v, wantErr %v", err, tt.wantErr)
}
newDeployment := &appsv1.Deployment{}
_ = utilhelper.ConvertToTypedObject(tt.args.rawObj, newDeployment)
if !reflect.DeepEqual(tt.want, newDeployment.Labels) {
t.Errorf("expect: %v, but got: %v", tt.want, newDeployment.Labels)
}
})
}
}
func Test_applyAnnotationsOverriders(t *testing.T) {
type args struct {
rawObj *unstructured.Unstructured
commandOverriders []policyv1alpha1.LabelAnnotationOverrider
}
deployment := helper.NewDeployment(metav1.NamespaceDefault, "test")
deployment.Annotations = map[string]string{
"foo": "foo",
"bar": "bar",
}
tests := []struct {
name string
args args
want map[string]string
wantErr bool
}{
{
name: "test labels replace",
args: args{
rawObj: func() *unstructured.Unstructured {
deploymentObj, _ := utilhelper.ToUnstructured(deployment)
return deploymentObj
}(),
commandOverriders: []policyv1alpha1.LabelAnnotationOverrider{
{
Operator: policyv1alpha1.OverriderOpReplace,
Value: map[string]string{
"foo": "exist",
"non-exist": "non-exist",
},
},
},
},
want: map[string]string{
"foo": "exist",
"bar": "bar",
},
wantErr: false,
},
{
name: "test labels add",
args: args{
rawObj: func() *unstructured.Unstructured {
deploymentObj, _ := utilhelper.ToUnstructured(deployment)
return deploymentObj
}(),
commandOverriders: []policyv1alpha1.LabelAnnotationOverrider{
{
Operator: policyv1alpha1.OverriderOpAdd,
Value: map[string]string{
"test": "test",
},
},
},
},
want: map[string]string{
"test": "test",
"foo": "foo",
"bar": "bar",
},
wantErr: false,
},
{
name: "test labels remove",
args: args{
rawObj: func() *unstructured.Unstructured {
deploymentObj, _ := utilhelper.ToUnstructured(deployment)
return deploymentObj
}(),
commandOverriders: []policyv1alpha1.LabelAnnotationOverrider{
{
Operator: policyv1alpha1.OverriderOpRemove,
Value: map[string]string{
"foo": "foo",
"non-exist": "non-exist",
},
},
},
},
want: map[string]string{
"bar": "bar",
},
wantErr: false,
},
{
name: "test labels remain the same",
args: args{
rawObj: func() *unstructured.Unstructured {
deploymentObj, _ := utilhelper.ToUnstructured(deployment)
return deploymentObj
}(),
commandOverriders: []policyv1alpha1.LabelAnnotationOverrider{
{
Operator: policyv1alpha1.OverriderOpRemove,
Value: map[string]string{},
},
},
},
want: map[string]string{
"bar": "bar",
"foo": "foo",
},
wantErr: false,
},
{
name: "test labels remain the same",
args: args{
rawObj: func() *unstructured.Unstructured {
deploymentObj, _ := utilhelper.ToUnstructured(deployment)
return deploymentObj
}(),
commandOverriders: []policyv1alpha1.LabelAnnotationOverrider{
{
Operator: policyv1alpha1.OverriderOpReplace,
Value: map[string]string{
"test": "test",
},
},
},
},
want: map[string]string{
"bar": "bar",
"foo": "foo",
},
wantErr: false,
},
{
name: "test labels remain the same",
args: args{
rawObj: func() *unstructured.Unstructured {
deploymentObj, _ := utilhelper.ToUnstructured(deployment)
return deploymentObj
}(),
commandOverriders: []policyv1alpha1.LabelAnnotationOverrider{
{
Operator: policyv1alpha1.OverriderOpRemove,
Value: map[string]string{
"test": "test",
},
},
},
},
want: map[string]string{
"bar": "bar",
"foo": "foo",
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := applyAnnotationsOverriders(tt.args.rawObj, tt.args.commandOverriders); (err != nil) != tt.wantErr {
t.Fatalf("applyAnnotationsOverriders() error = %v, wantErr %v", err, tt.wantErr)
}
newDeployment := &appsv1.Deployment{}
_ = utilhelper.ConvertToTypedObject(tt.args.rawObj, newDeployment)
if !reflect.DeepEqual(tt.want, newDeployment.Annotations) {
t.Errorf("expect: %v, but got: %v", tt.want, newDeployment.Annotations)
}
})
}
}

View File

@ -255,7 +255,12 @@ func applyPolicyOverriders(rawObj *unstructured.Unstructured, overriders policyv
if err := applyArgsOverriders(rawObj, overriders.ArgsOverrider); err != nil {
return err
}
if err := applyLabelsOverriders(rawObj, overriders.LabelsOverrider); err != nil {
return err
}
if err := applyAnnotationsOverriders(rawObj, overriders.AnnotationsOverrider); err != nil {
return err
}
return applyJSONPatch(rawObj, parseJSONPatchesByPlaintext(overriders.Plaintext))
}

View File

@ -68,5 +68,11 @@ func EmptyOverrides(overriders policyv1alpha1.Overriders) bool {
if len(overriders.ArgsOverrider) != 0 {
return false
}
if len(overriders.LabelsOverrider) != 0 {
return false
}
if len(overriders.AnnotationsOverrider) != 0 {
return false
}
return true
}

View File

@ -0,0 +1,41 @@
apiVersion: policy.karmada.io/v1alpha1
kind: OverridePolicy
metadata:
name: nginx-op
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
name: nginx
overrideRules:
- targetCluster:
clusterNames:
- member2
overriders:
labelsOverrider:
- operator: add
value:
env: skoala-dev
- operator: add
value:
env-stat: skoala-stage
- operator: remove
value:
for: for
- operator: replace
value:
bar: test
- targetCluster:
clusterNames:
- member1
overriders:
annotationsOverrider:
- operator: add
value:
env: skoala-stage
- operator: remove
value:
bom: bom
- operator: replace
value:
emma: sophia