Skip to content

Commit

Permalink
Support of the namespaceLabelSelector in DefaultEvictor plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
RomanenkoDenys committed Sep 4, 2024
1 parent 19c8c3d commit e18ba47
Showing 1 changed file with 35 additions and 37 deletions.
72 changes: 35 additions & 37 deletions pkg/framework/plugins/defaultevictor/defaultevictor.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import (
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
clientset "k8s.io/client-go/kubernetes"
listersv1 "k8s.io/client-go/listers/core/v1"

"k8s.io/client-go/tools/cache"
"k8s.io/klog/v2"
Expand Down Expand Up @@ -220,18 +222,12 @@ func (d *DefaultEvictor) PreEvictionFilter(pod *v1.Pod) bool {

// check pod by namespace label filter
if d.args.NamespaceLabelSelector != nil {
indexName := "namespaceWithLabelSelector"
indexer, err := getNamespacesListByLabelSelector(indexName, d.args.NamespaceLabelSelector, d.handle)
ns, err := getNamespaces(context.TODO(), d.handle.ClientSet(), d.handle.SharedInformerFactory().Core().V1().Namespaces().Lister(), metav1.FormatLabelSelector(d.args.NamespaceLabelSelector))
if err != nil {
klog.ErrorS(err, "unable to list namespaces", "pod", klog.KObj(pod))
return false
}
objs, err := indexer.ByIndex(indexName, pod.Namespace)
if err != nil {
klog.ErrorS(err, "unable to list namespaces for namespaceLabelSelector filter in the policy parameter", "pod", klog.KObj(pod))
return false
}
if len(objs) == 0 {

if _, ok := ns[pod.Namespace]; !ok {
klog.InfoS("pod namespace do not match the namespaceLabelSelector filter in the policy parameter", "pod", klog.KObj(pod))
return false
}
Expand Down Expand Up @@ -300,38 +296,40 @@ func getPodIndexerByOwnerRefs(indexName string, handle frameworktypes.Handle) (c
return indexer, nil
}

func getNamespacesListByLabelSelector(indexName string, labelSelector *metav1.LabelSelector, handle frameworktypes.Handle) (cache.Indexer, error) {
nsInformer := handle.SharedInformerFactory().Core().V1().Namespaces().Informer()
indexer := nsInformer.GetIndexer()
func getNamespaces(ctx context.Context, client clientset.Interface, nsLister listersv1.NamespaceLister, labelSelector string) (map[string]struct{}, error) {
ret := make(map[string]struct{})
namespaceSelector, err := labels.Parse(labelSelector)
if err != nil {
return ret, err
}

// do not reinitialize the indexer, if it's been defined already
for name := range indexer.GetIndexers() {
if name == indexName {
return indexer, nil
}
var ns []*v1.Namespace
// err is defined above
if ns, err = nsLister.List(namespaceSelector); err != nil {
return ret, err
}

if err := nsInformer.AddIndexers(cache.Indexers{
indexName: func(obj interface{}) ([]string, error) {
ns, ok := obj.(*v1.Namespace)
if !ok {
return []string{}, errors.New("unexpected object")
}
if len(ns) == 0 {
klog.V(2).InfoS("Namespace lister returned empty list, now fetch directly")

selector, err := metav1.LabelSelectorAsSelector(labelSelector)
if err != nil {
return []string{}, errors.New("could not get selector from label selector")
}
if labelSelector != nil && !selector.Empty() {
if !selector.Matches(labels.Set(ns.Labels)) {
return []string{}, nil
}
}
return []string{ns.GetName()}, nil
},
}); err != nil {
return nil, err
nItems, err := client.CoreV1().Namespaces().List(ctx, metav1.ListOptions{LabelSelector: labelSelector})
if err != nil {
return ret, err
}

if nItems == nil || len(nItems.Items) == 0 {
return ret, nil
}

for i := range nItems.Items {
namespace := nItems.Items[i]
ns = append(ns, &namespace)
}
}

return indexer, nil
for _, n := range ns {
ret[n.Name] = struct{}{}
}

return ret, nil
}

0 comments on commit e18ba47

Please sign in to comment.