/* Copyright 2023 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 plugin import ( v1 "k8s.io/api/core/v1" frameworktypes "sigs.k8s.io/descheduler/pkg/framework/types" ) type Action interface { Handle() frameworktypes.Handle GetExtensionPoint() string DeepCopy() Action } type ReactionFunc func(action Action) (handled, filter bool, err error) // Reactor is an interface to allow the composition of reaction functions. type Reactor interface { // Handles indicates whether or not this Reactor deals with a given // action. Handles(action Action) bool // React handles the action. It may choose to // delegate by indicated handled=false. // filter is used to store results of filter based actions React(action Action) (handled, filter bool, err error) } // SimpleReactor is a Reactor. Each reaction function is attached to a given extensionPoint. "*" in either field matches everything for that value. type SimpleReactor struct { ExtensionPoint string Reaction ReactionFunc } func (r *SimpleReactor) Handles(action Action) bool { return r.ExtensionPoint == "*" || r.ExtensionPoint == action.GetExtensionPoint() } func (r *SimpleReactor) React(action Action) (bool, bool, error) { return r.Reaction(action) } type DescheduleAction interface { Action CanDeschedule() bool Nodes() []*v1.Node } type BalanceAction interface { Action CanBalance() bool Nodes() []*v1.Node } type FilterAction interface { Action CanFilter() bool } type PreEvictionFilterAction interface { Action CanPreEvictionFilter() bool } type ActionImpl struct { handle frameworktypes.Handle extensionPoint string } func (a ActionImpl) Handle() frameworktypes.Handle { return a.handle } func (a ActionImpl) GetExtensionPoint() string { return a.extensionPoint } func (a ActionImpl) DeepCopy() Action { // The handle is expected to be accessed only throuh interface methods // Thus, no deep copy needed. ret := a return ret } type DescheduleActionImpl struct { ActionImpl nodes []*v1.Node } func (d DescheduleActionImpl) CanDeschedule() bool { return true } func (d DescheduleActionImpl) Nodes() []*v1.Node { return d.nodes } func (a DescheduleActionImpl) DeepCopy() Action { nodesCopy := []*v1.Node{} for _, node := range a.nodes { nodesCopy = append(nodesCopy, node.DeepCopy()) } return DescheduleActionImpl{ ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl), nodes: nodesCopy, } } type BalanceActionImpl struct { ActionImpl nodes []*v1.Node } func (d BalanceActionImpl) CanBalance() bool { return true } func (d BalanceActionImpl) Nodes() []*v1.Node { return d.nodes } func (a BalanceActionImpl) DeepCopy() Action { nodesCopy := []*v1.Node{} for _, node := range a.nodes { nodesCopy = append(nodesCopy, node.DeepCopy()) } return BalanceActionImpl{ ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl), nodes: nodesCopy, } } type FilterActionImpl struct { ActionImpl } func (d FilterActionImpl) CanFilter() bool { return true } func (a FilterActionImpl) DeepCopy() Action { return FilterActionImpl{ ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl), } } type PreEvictionFilterActionImpl struct { ActionImpl } func (d PreEvictionFilterActionImpl) CanPreEvictionFilter() bool { return true } func (a PreEvictionFilterActionImpl) DeepCopy() Action { return PreEvictionFilterActionImpl{ ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl), } }