mirror of
https://github.com/kubernetes-sigs/descheduler.git
synced 2026-01-26 05:14:13 +01:00
RemovePodsViolatingTopologySpreadConstraint defaulting + moving arguments to its corresponding plugin
This commit is contained in:
@@ -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")
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user