From dc04abc0e62ca4bc26333e59175cdda3bb2cd5cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?vlc=E5=88=98=E8=AF=9A?= Date: Mon, 19 Sep 2022 15:15:59 +0800 Subject: [PATCH] RemovePodsViolatingTopologySpreadConstraint defaulting + moving arguments to its corresponding plugin --- hack/update-generated-conversions.sh | 2 +- hack/update-generated-deep-copies.sh | 2 +- .../validation/validation_pluginargs.go | 37 ----------- .../componentconfig/zz_generated.deepcopy.go | 37 ----------- pkg/descheduler/strategy_migration.go | 6 +- .../topologyspreadconstraint.go | 5 +- .../topologyspreadconstraint_test.go | 61 +++++++++--------- .../types.go} | 3 +- .../validation.go | 38 +++++++++++ .../zz_generated.deepcopy.go | 63 +++++++++++++++++++ 10 files changed, 139 insertions(+), 115 deletions(-) rename pkg/{apis/componentconfig/types_pluginargs.go => framework/plugins/removepodsviolatingtopologyspreadconstraint/types.go} (93%) create mode 100644 pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/validation.go create mode 100644 pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/zz_generated.deepcopy.go diff --git a/hack/update-generated-conversions.sh b/hack/update-generated-conversions.sh index d0cc12db0..493685e8d 100755 --- a/hack/update-generated-conversions.sh +++ b/hack/update-generated-conversions.sh @@ -5,5 +5,5 @@ go build -o "${OS_OUTPUT_BINPATH}/conversion-gen" "k8s.io/code-generator/cmd/con ${OS_OUTPUT_BINPATH}/conversion-gen \ --go-header-file "hack/boilerplate/boilerplate.go.txt" \ - --input-dirs "${PRJ_PREFIX}/pkg/apis/componentconfig/v1alpha1,${PRJ_PREFIX}/pkg/api/v1alpha1,${PRJ_PREFIX}/pkg/framework/plugins/removefailedpods,${PRJ_PREFIX}/pkg/framework/plugins/nodeutilization,${PRJ_PREFIX}/pkg/framework/plugins/podlifetime,${PRJ_PREFIX}/pkg/framework/plugins/removeduplicates,${PRJ_PREFIX}/pkg/framework/plugins/removepodshavingtoomanyrestarts,${PRJ_PREFIX}/pkg/framework/plugins/removepodsviolatinginterpodantiaffinity,${PRJ_PREFIX}/pkg/framework/plugins/removepodsviolatingnodeaffinity,${PRJ_PREFIX}/pkg/framework/plugins/removepodsviolatingnodetaints" \ + --input-dirs "${PRJ_PREFIX}/pkg/apis/componentconfig/v1alpha1,${PRJ_PREFIX}/pkg/api/v1alpha1,${PRJ_PREFIX}/pkg/framework/plugins/removefailedpods,${PRJ_PREFIX}/pkg/framework/plugins/nodeutilization,${PRJ_PREFIX}/pkg/framework/plugins/podlifetime,${PRJ_PREFIX}/pkg/framework/plugins/removeduplicates,${PRJ_PREFIX}/pkg/framework/plugins/removepodshavingtoomanyrestarts,${PRJ_PREFIX}/pkg/framework/plugins/removepodsviolatinginterpodantiaffinity,${PRJ_PREFIX}/pkg/framework/plugins/removepodsviolatingnodeaffinity,${PRJ_PREFIX}/pkg/framework/plugins/removepodsviolatingnodetaints,${PRJ_PREFIX}/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint" \ --output-file-base zz_generated.conversion diff --git a/hack/update-generated-deep-copies.sh b/hack/update-generated-deep-copies.sh index 5fc1c134b..429553d4b 100755 --- a/hack/update-generated-deep-copies.sh +++ b/hack/update-generated-deep-copies.sh @@ -5,6 +5,6 @@ go build -o "${OS_OUTPUT_BINPATH}/deepcopy-gen" "k8s.io/code-generator/cmd/deepc ${OS_OUTPUT_BINPATH}/deepcopy-gen \ --go-header-file "hack/boilerplate/boilerplate.go.txt" \ - --input-dirs "${PRJ_PREFIX}/pkg/apis/componentconfig,${PRJ_PREFIX}/pkg/apis/componentconfig/v1alpha1,${PRJ_PREFIX}/pkg/api,${PRJ_PREFIX}/pkg/api/v1alpha1,${PRJ_PREFIX}/pkg/framework/plugins/defaultevictor/,${PRJ_PREFIX}/pkg/framework/plugins/removefailedpods,${PRJ_PREFIX}/pkg/framework/plugins/nodeutilization,${PRJ_PREFIX}/pkg/framework/plugins/podlifetime,${PRJ_PREFIX}/pkg/framework/plugins/removeduplicates,${PRJ_PREFIX}/pkg/framework/plugins/removepodshavingtoomanyrestarts,${PRJ_PREFIX}/pkg/framework/plugins/removepodsviolatinginterpodantiaffinity,${PRJ_PREFIX}/pkg/framework/plugins/removepodsviolatingnodeaffinity,${PRJ_PREFIX}/pkg/framework/plugins/removepodsviolatingnodetaints" \ + --input-dirs "${PRJ_PREFIX}/pkg/apis/componentconfig,${PRJ_PREFIX}/pkg/apis/componentconfig/v1alpha1,${PRJ_PREFIX}/pkg/api,${PRJ_PREFIX}/pkg/api/v1alpha1,${PRJ_PREFIX}/pkg/framework/plugins/defaultevictor/,${PRJ_PREFIX}/pkg/framework/plugins/removefailedpods,${PRJ_PREFIX}/pkg/framework/plugins/nodeutilization,${PRJ_PREFIX}/pkg/framework/plugins/podlifetime,${PRJ_PREFIX}/pkg/framework/plugins/removeduplicates,${PRJ_PREFIX}/pkg/framework/plugins/removepodshavingtoomanyrestarts,${PRJ_PREFIX}/pkg/framework/plugins/removepodsviolatinginterpodantiaffinity,${PRJ_PREFIX}/pkg/framework/plugins/removepodsviolatingnodeaffinity,${PRJ_PREFIX}/pkg/framework/plugins/removepodsviolatingnodetaints,${PRJ_PREFIX}/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint" \ --output-file-base zz_generated.deepcopy diff --git a/pkg/apis/componentconfig/validation/validation_pluginargs.go b/pkg/apis/componentconfig/validation/validation_pluginargs.go index 605bfefc1..e8ee8d2ff 100644 --- a/pkg/apis/componentconfig/validation/validation_pluginargs.go +++ b/pkg/apis/componentconfig/validation/validation_pluginargs.go @@ -19,52 +19,15 @@ package validation import ( "fmt" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilerrors "k8s.io/apimachinery/pkg/util/errors" - "sigs.k8s.io/descheduler/pkg/api" - "sigs.k8s.io/descheduler/pkg/apis/componentconfig" ) -const ( - // MinResourcePercentage is the minimum value of a resource's percentage - MinResourcePercentage = 0 - // MaxResourcePercentage is the maximum value of a resource's percentage - MaxResourcePercentage = 100 -) - -// ValidateRemovePodsViolatingTopologySpreadConstraintArgs validates RemovePodsViolatingTopologySpreadConstraint arguments -func ValidateRemovePodsViolatingTopologySpreadConstraintArgs(args *componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs) error { - return errorsAggregate( - validateNamespaceArgs(args.Namespaces), - validateLabelSelectorArgs(args.LabelSelector), - ) -} - // errorsAggregate converts all arg validation errors to a single error interface. // if no errors, it will return nil. func errorsAggregate(errors ...error) error { return utilerrors.NewAggregate(errors) } -func validateNamespaceArgs(namespaces *api.Namespaces) error { - // At most one of include/exclude can be set - if namespaces != nil && len(namespaces.Include) > 0 && len(namespaces.Exclude) > 0 { - return fmt.Errorf("only one of Include/Exclude namespaces can be set") - } - - return nil -} - -func validateLabelSelectorArgs(labelSelector *metav1.LabelSelector) error { - if labelSelector != nil { - if _, err := metav1.LabelSelectorAsSelector(labelSelector); err != nil { - return fmt.Errorf("failed to get label selectors from strategy's params: %+v", err) - } - } - - return nil -} - func validatePodRestartThreshold(podRestartThreshold int32) error { if podRestartThreshold < 1 { return fmt.Errorf("PodsHavingTooManyRestarts threshold not set") diff --git a/pkg/apis/componentconfig/zz_generated.deepcopy.go b/pkg/apis/componentconfig/zz_generated.deepcopy.go index 55da51f58..f450e704c 100644 --- a/pkg/apis/componentconfig/zz_generated.deepcopy.go +++ b/pkg/apis/componentconfig/zz_generated.deepcopy.go @@ -22,9 +22,7 @@ limitations under the License. package componentconfig import ( - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" - api "sigs.k8s.io/descheduler/pkg/api" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -53,38 +51,3 @@ func (in *DeschedulerConfiguration) DeepCopyObject() runtime.Object { } return nil } - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RemovePodsViolatingTopologySpreadConstraintArgs) DeepCopyInto(out *RemovePodsViolatingTopologySpreadConstraintArgs) { - *out = *in - out.TypeMeta = in.TypeMeta - if in.Namespaces != nil { - in, out := &in.Namespaces, &out.Namespaces - *out = new(api.Namespaces) - (*in).DeepCopyInto(*out) - } - if in.LabelSelector != nil { - in, out := &in.LabelSelector, &out.LabelSelector - *out = new(v1.LabelSelector) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RemovePodsViolatingTopologySpreadConstraintArgs. -func (in *RemovePodsViolatingTopologySpreadConstraintArgs) DeepCopy() *RemovePodsViolatingTopologySpreadConstraintArgs { - if in == nil { - return nil - } - out := new(RemovePodsViolatingTopologySpreadConstraintArgs) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *RemovePodsViolatingTopologySpreadConstraintArgs) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} diff --git a/pkg/descheduler/strategy_migration.go b/pkg/descheduler/strategy_migration.go index ad4ceeeef..bb2be1686 100644 --- a/pkg/descheduler/strategy_migration.go +++ b/pkg/descheduler/strategy_migration.go @@ -22,8 +22,6 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/klog/v2" "sigs.k8s.io/descheduler/pkg/api" - "sigs.k8s.io/descheduler/pkg/apis/componentconfig" - "sigs.k8s.io/descheduler/pkg/apis/componentconfig/validation" "sigs.k8s.io/descheduler/pkg/framework" "sigs.k8s.io/descheduler/pkg/framework/plugins/nodeutilization" "sigs.k8s.io/descheduler/pkg/framework/plugins/podlifetime" @@ -209,12 +207,12 @@ var pluginsMap = map[string]func(ctx context.Context, nodes []*v1.Node, params * } }, "RemovePodsViolatingTopologySpreadConstraint": func(ctx context.Context, nodes []*v1.Node, params *api.StrategyParameters, handle *handleImpl) { - args := &componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{ + args := &removepodsviolatingtopologyspreadconstraint.RemovePodsViolatingTopologySpreadConstraintArgs{ Namespaces: params.Namespaces, LabelSelector: params.LabelSelector, IncludeSoftConstraints: params.IncludePreferNoSchedule, } - if err := validation.ValidateRemovePodsViolatingTopologySpreadConstraintArgs(args); err != nil { + if err := removepodsviolatingtopologyspreadconstraint.ValidateRemovePodsViolatingTopologySpreadConstraintArgs(args); err != nil { klog.V(1).ErrorS(err, "unable to validate plugin arguments", "pluginName", removepodsviolatingtopologyspreadconstraint.PluginName) return } diff --git a/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/topologyspreadconstraint.go b/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/topologyspreadconstraint.go index 034e4d09b..730bdc365 100644 --- a/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/topologyspreadconstraint.go +++ b/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/topologyspreadconstraint.go @@ -27,7 +27,6 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "k8s.io/klog/v2" - "sigs.k8s.io/descheduler/pkg/apis/componentconfig" "sigs.k8s.io/descheduler/pkg/descheduler/evictions" "sigs.k8s.io/descheduler/pkg/descheduler/node" podutil "sigs.k8s.io/descheduler/pkg/descheduler/pod" @@ -51,7 +50,7 @@ type topology struct { // RemovePodsViolatingTopologySpreadConstraint evicts pods which violate their topology spread constraints type RemovePodsViolatingTopologySpreadConstraint struct { handle framework.Handle - args *componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs + args *RemovePodsViolatingTopologySpreadConstraintArgs podFilter podutil.FilterFunc } @@ -59,7 +58,7 @@ var _ framework.BalancePlugin = &RemovePodsViolatingTopologySpreadConstraint{} // New builds plugin from its arguments while passing a handle func New(args runtime.Object, handle framework.Handle) (framework.Plugin, error) { - pluginArgs, ok := args.(*componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs) + pluginArgs, ok := args.(*RemovePodsViolatingTopologySpreadConstraintArgs) if !ok { return nil, fmt.Errorf("want args to be of type RemovePodsViolatingTopologySpreadConstraintArgs, got %T", args) } diff --git a/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/topologyspreadconstraint_test.go b/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/topologyspreadconstraint_test.go index 86dcf37bd..2b68df1a7 100644 --- a/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/topologyspreadconstraint_test.go +++ b/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/topologyspreadconstraint_test.go @@ -16,7 +16,6 @@ import ( "k8s.io/client-go/tools/events" "sigs.k8s.io/descheduler/pkg/api" - "sigs.k8s.io/descheduler/pkg/apis/componentconfig" "sigs.k8s.io/descheduler/pkg/descheduler/evictions" podutil "sigs.k8s.io/descheduler/pkg/descheduler/pod" "sigs.k8s.io/descheduler/pkg/framework" @@ -33,7 +32,7 @@ func TestTopologySpreadConstraint(t *testing.T) { expectedEvictedPods []string // if specified, will assert specific pods were evicted nodes []*v1.Node namespaces []string - args componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs + args RemovePodsViolatingTopologySpreadConstraintArgs nodeFit bool }{ { @@ -69,7 +68,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 0, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, }, { name: "2 domains, sizes [3,1], maxSkew=1, move 1 pod to achieve [2,2]", @@ -97,7 +96,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 1, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, }, { name: "2 domains, sizes [3,1], maxSkew=1, move 1 pod to achieve [2,2] (soft constraints)", @@ -132,7 +131,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 1, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{IncludeSoftConstraints: true}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{IncludeSoftConstraints: true}, }, { name: "2 domains, sizes [3,1], maxSkew=1, no pods eligible, move 0 pods", @@ -163,7 +162,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 0, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, }, { name: "2 domains, sizes [3,1], maxSkew=1, move 1 pod to achieve [2,2], exclude kube-system namespace", @@ -191,7 +190,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 1, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{Namespaces: &api.Namespaces{Exclude: []string{"kube-system"}}}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{Namespaces: &api.Namespaces{Exclude: []string{"kube-system"}}}, nodeFit: true, }, { @@ -220,7 +219,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 1, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, }, { name: "2 domains, sizes [4,0], maxSkew=1, move 2 pods to achieve [2,2]", @@ -243,7 +242,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 2, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, }, { name: "2 domains, sizes [4,0], maxSkew=1, only move 1 pod since pods with nodeSelector and nodeAffinity aren't evicted", @@ -283,7 +282,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 1, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, nodeFit: true, }, { @@ -327,7 +326,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 2, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, }, { name: "3 domains, sizes [0, 1, 100], maxSkew=1, move 66 pods to get [34, 33, 34]", @@ -351,7 +350,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 66, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, }, { name: "4 domains, sizes [0, 1, 3, 5], should move 3 to get [2, 2, 3, 2]", @@ -381,7 +380,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 3, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, }, { name: "2 domains size [2 6], maxSkew=2, should move 1 to get [3 5]", @@ -409,7 +408,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 1, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, }, { name: "2 domains size [2 6], maxSkew=2, can't move any because of node taints", @@ -453,7 +452,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 0, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, nodeFit: true, }, { @@ -482,7 +481,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 0, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, nodeFit: true, }, { @@ -588,7 +587,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 1, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{IncludeSoftConstraints: true}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{IncludeSoftConstraints: true}, }, { name: "3 domains size [8 7 0], maxSkew=1, should move 5 to get [5 5 5]", @@ -614,7 +613,7 @@ func TestTopologySpreadConstraint(t *testing.T) { expectedEvictedCount: 5, expectedEvictedPods: []string{"pod-5", "pod-6", "pod-7", "pod-8"}, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, }, { name: "3 domains size [5 5 5], maxSkew=1, should move 0 to retain [5 5 5]", @@ -645,7 +644,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 0, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, }, { name: "2 domains, sizes [2,0], maxSkew=1, move 1 pod since pod tolerates the node with taint", @@ -687,7 +686,7 @@ func TestTopologySpreadConstraint(t *testing.T) { expectedEvictedCount: 1, expectedEvictedPods: []string{"pod-0"}, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, }, { name: "2 domains, sizes [2,0], maxSkew=1, move 0 pods since pod does not tolerate the tainted node", @@ -720,7 +719,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 0, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, }, { name: "2 domains, sizes [2,0], maxSkew=1, move 0 pods since pod does not tolerate the tainted node, and NodeFit is enabled", @@ -753,7 +752,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 0, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, nodeFit: true, }, { @@ -788,7 +787,7 @@ func TestTopologySpreadConstraint(t *testing.T) { expectedEvictedCount: 1, expectedEvictedPods: []string{"pod-0"}, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, }, { name: "2 domains, sizes [2,0], maxSkew=1, move 0 pod for node with unmatched label filtering", @@ -811,7 +810,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 0, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{LabelSelector: getLabelSelector("foo", []string{"baz"}, metav1.LabelSelectorOpIn)}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{LabelSelector: getLabelSelector("foo", []string{"baz"}, metav1.LabelSelectorOpIn)}, }, { name: "2 domains, sizes [2,0], maxSkew=1, move 1 pod for node with matched label filtering", @@ -835,7 +834,7 @@ func TestTopologySpreadConstraint(t *testing.T) { expectedEvictedCount: 1, expectedEvictedPods: []string{"pod-1"}, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{LabelSelector: getLabelSelector("foo", []string{"bar"}, metav1.LabelSelectorOpIn)}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{LabelSelector: getLabelSelector("foo", []string{"bar"}, metav1.LabelSelectorOpIn)}, }, { name: "2 domains, sizes [2,0], maxSkew=1, move 1 pod for node with matched label filtering (NotIn op)", @@ -859,7 +858,7 @@ func TestTopologySpreadConstraint(t *testing.T) { expectedEvictedCount: 1, expectedEvictedPods: []string{"pod-1"}, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{LabelSelector: getLabelSelector("foo", []string{"baz"}, metav1.LabelSelectorOpNotIn)}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{LabelSelector: getLabelSelector("foo", []string{"baz"}, metav1.LabelSelectorOpNotIn)}, }, { name: "2 domains, sizes [4,2], maxSkew=1, 2 pods in termination; nothing should be moved", @@ -890,7 +889,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 0, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{LabelSelector: getLabelSelector("foo", []string{"bar"}, metav1.LabelSelectorOpIn)}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{LabelSelector: getLabelSelector("foo", []string{"bar"}, metav1.LabelSelectorOpIn)}, }, { name: "3 domains, sizes [2,3,4], maxSkew=1, NodeFit is enabled, and not enough cpu on zoneA; nothing should be moved", @@ -921,7 +920,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 0, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, nodeFit: true, }, { @@ -968,7 +967,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 0, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, nodeFit: true, }, { @@ -1008,7 +1007,7 @@ func TestTopologySpreadConstraint(t *testing.T) { expectedEvictedCount: 1, expectedEvictedPods: []string{"pod-4"}, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, nodeFit: true, }, { @@ -1115,7 +1114,7 @@ func TestTopologySpreadConstraint(t *testing.T) { }), expectedEvictedCount: 0, namespaces: []string{"ns1"}, - args: componentconfig.RemovePodsViolatingTopologySpreadConstraintArgs{}, + args: RemovePodsViolatingTopologySpreadConstraintArgs{}, nodeFit: true, }, } diff --git a/pkg/apis/componentconfig/types_pluginargs.go b/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/types.go similarity index 93% rename from pkg/apis/componentconfig/types_pluginargs.go rename to pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/types.go index 4b23a67a8..40f2dec86 100644 --- a/pkg/apis/componentconfig/types_pluginargs.go +++ b/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/types.go @@ -14,13 +14,14 @@ See the License for the specific language governing permissions and limitations under the License. */ -package componentconfig +package removepodsviolatingtopologyspreadconstraint import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/descheduler/pkg/api" ) +// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // RemovePodsViolatingTopologySpreadConstraintArgs holds arguments used to configure RemovePodsViolatingTopologySpreadConstraint plugin. diff --git a/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/validation.go b/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/validation.go new file mode 100644 index 000000000..2f30ba507 --- /dev/null +++ b/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/validation.go @@ -0,0 +1,38 @@ +/* +Copyright 2022 The Kubernetes 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 removepodsviolatingtopologyspreadconstraint + +import ( + "fmt" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// ValidateRemovePodsViolatingTopologySpreadConstraintArgs validates RemovePodsViolatingTopologySpreadConstraint arguments +func ValidateRemovePodsViolatingTopologySpreadConstraintArgs(args *RemovePodsViolatingTopologySpreadConstraintArgs) error { + // At most one of include/exclude can be set + if args.Namespaces != nil && len(args.Namespaces.Include) > 0 && len(args.Namespaces.Exclude) > 0 { + return fmt.Errorf("only one of Include/Exclude namespaces can be set") + } + + if args.LabelSelector != nil { + if _, err := metav1.LabelSelectorAsSelector(args.LabelSelector); err != nil { + return fmt.Errorf("failed to get label selectors from strategy's params: %+v", err) + } + } + + return nil +} diff --git a/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/zz_generated.deepcopy.go b/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/zz_generated.deepcopy.go new file mode 100644 index 000000000..93f242a1e --- /dev/null +++ b/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/zz_generated.deepcopy.go @@ -0,0 +1,63 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2022 The Kubernetes 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package removepodsviolatingtopologyspreadconstraint + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + api "sigs.k8s.io/descheduler/pkg/api" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RemovePodsViolatingTopologySpreadConstraintArgs) DeepCopyInto(out *RemovePodsViolatingTopologySpreadConstraintArgs) { + *out = *in + out.TypeMeta = in.TypeMeta + if in.Namespaces != nil { + in, out := &in.Namespaces, &out.Namespaces + *out = new(api.Namespaces) + (*in).DeepCopyInto(*out) + } + if in.LabelSelector != nil { + in, out := &in.LabelSelector, &out.LabelSelector + *out = new(v1.LabelSelector) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RemovePodsViolatingTopologySpreadConstraintArgs. +func (in *RemovePodsViolatingTopologySpreadConstraintArgs) DeepCopy() *RemovePodsViolatingTopologySpreadConstraintArgs { + if in == nil { + return nil + } + out := new(RemovePodsViolatingTopologySpreadConstraintArgs) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RemovePodsViolatingTopologySpreadConstraintArgs) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +}