From 433f0dbb8c2caebfc6ad7e3b1915281ec248fa1b Mon Sep 17 00:00:00 2001 From: Jan Chaloupka Date: Thu, 22 Jan 2026 23:16:49 +0100 Subject: [PATCH 1/3] refactor(pkg/descheduler): define a helper for newKubeClientSandbox with the default list of resources --- pkg/descheduler/descheduler.go | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/pkg/descheduler/descheduler.go b/pkg/descheduler/descheduler.go index 5735b66d2..59db3b946 100644 --- a/pkg/descheduler/descheduler.go +++ b/pkg/descheduler/descheduler.go @@ -160,6 +160,17 @@ type kubeClientSandbox struct { podEvictionReactionFnc func(*fakeclientset.Clientset, *evictedPodsCache) func(action core.Action) (bool, runtime.Object, error) } +func newDefaultKubeClientSandbox(client clientset.Interface, sharedInformerFactory informers.SharedInformerFactory) (*kubeClientSandbox, error) { + return newKubeClientSandbox(client, sharedInformerFactory, + v1.SchemeGroupVersion.WithResource("pods"), + v1.SchemeGroupVersion.WithResource("nodes"), + v1.SchemeGroupVersion.WithResource("namespaces"), + schedulingv1.SchemeGroupVersion.WithResource("priorityclasses"), + policyv1.SchemeGroupVersion.WithResource("poddisruptionbudgets"), + v1.SchemeGroupVersion.WithResource("persistentvolumeclaims"), + ) +} + func newKubeClientSandbox(client clientset.Interface, sharedInformerFactory informers.SharedInformerFactory, resources ...schema.GroupVersionResource) (*kubeClientSandbox, error) { sandbox := &kubeClientSandbox{ client: client, @@ -272,14 +283,7 @@ func newDescheduler(ctx context.Context, rs *options.DeschedulerServer, deschedu // Future work could be to let each plugin declare what type of resources it needs; that way dry runs would stay // consistent with the real runs without having to keep the list here in sync. - kubeClientSandbox, err := newKubeClientSandbox(rs.Client, sharedInformerFactory, - v1.SchemeGroupVersion.WithResource("pods"), - v1.SchemeGroupVersion.WithResource("nodes"), - v1.SchemeGroupVersion.WithResource("namespaces"), - schedulingv1.SchemeGroupVersion.WithResource("priorityclasses"), - policyv1.SchemeGroupVersion.WithResource("poddisruptionbudgets"), - v1.SchemeGroupVersion.WithResource("persistentvolumeclaims"), - ) + kubeClientSandbox, err := newDefaultKubeClientSandbox(rs.Client, sharedInformerFactory) if err != nil { return nil, fmt.Errorf("failed to create kube client sandbox: %v", err) } From 4daa7e2fbf38cbb224728054520ef9553e0beaf3 Mon Sep 17 00:00:00 2001 From: Jan Chaloupka Date: Thu, 22 Jan 2026 23:21:31 +0100 Subject: [PATCH 2/3] refactor(pkg/descheduler): move prometheus setup under a helper Prometheus is not used anywhere in the tests so there's no need to setup it there. --- pkg/descheduler/descheduler.go | 36 ++++++++++++++++++----------- pkg/descheduler/descheduler_test.go | 5 ++++ 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/pkg/descheduler/descheduler.go b/pkg/descheduler/descheduler.go index 59db3b946..0fba7fb0c 100644 --- a/pkg/descheduler/descheduler.go +++ b/pkg/descheduler/descheduler.go @@ -278,6 +278,23 @@ func metricsProviderListToMap(providersList []api.MetricsProvider) map[api.Metri return providersMap } +// setupPrometheusProvider sets up the prometheus provider on the descheduler if configured +func setupPrometheusProvider(d *descheduler, namespacedSharedInformerFactory informers.SharedInformerFactory) error { + prometheusProvider := d.metricsProviders[api.PrometheusMetrics] + if prometheusProvider != nil && prometheusProvider.Prometheus != nil && prometheusProvider.Prometheus.AuthToken != nil { + authTokenSecret := prometheusProvider.Prometheus.AuthToken.SecretReference + if authTokenSecret == nil || authTokenSecret.Namespace == "" { + return fmt.Errorf("prometheus metrics source configuration is missing authentication token secret") + } + if namespacedSharedInformerFactory == nil { + return fmt.Errorf("namespacedSharedInformerFactory not configured") + } + namespacedSharedInformerFactory.Core().V1().Secrets().Informer().AddEventHandler(d.eventHandler()) + d.namespacedSecretsLister = namespacedSharedInformerFactory.Core().V1().Secrets().Lister().Secrets(authTokenSecret.Namespace) + } + return nil +} + func newDescheduler(ctx context.Context, rs *options.DeschedulerServer, deschedulerPolicy *api.DeschedulerPolicy, evictionPolicyGroupVersion string, eventRecorder events.EventRecorder, sharedInformerFactory, namespacedSharedInformerFactory informers.SharedInformerFactory) (*descheduler, error) { podInformer := sharedInformerFactory.Core().V1().Pods().Informer() @@ -339,19 +356,6 @@ func newDescheduler(ctx context.Context, rs *options.DeschedulerServer, deschedu desch.metricsCollector = metricscollector.NewMetricsCollector(sharedInformerFactory.Core().V1().Nodes().Lister(), rs.MetricsClient, nodeSelector) } - prometheusProvider := desch.metricsProviders[api.PrometheusMetrics] - if prometheusProvider != nil && prometheusProvider.Prometheus != nil && prometheusProvider.Prometheus.AuthToken != nil { - authTokenSecret := prometheusProvider.Prometheus.AuthToken.SecretReference - if authTokenSecret == nil || authTokenSecret.Namespace == "" { - return nil, fmt.Errorf("prometheus metrics source configuration is missing authentication token secret") - } - if namespacedSharedInformerFactory == nil { - return nil, fmt.Errorf("namespacedSharedInformerFactory not configured") - } - namespacedSharedInformerFactory.Core().V1().Secrets().Informer().AddEventHandler(desch.eventHandler()) - desch.namespacedSecretsLister = namespacedSharedInformerFactory.Core().V1().Secrets().Lister().Secrets(authTokenSecret.Namespace) - } - return desch, nil } @@ -766,6 +770,12 @@ func RunDeschedulerStrategies(ctx context.Context, rs *options.DeschedulerServer ctx, cancel := context.WithCancel(ctx) defer cancel() + // Setup Prometheus provider (only for real client case, not for dry run) + if err := setupPrometheusProvider(descheduler, namespacedSharedInformerFactory); err != nil { + span.AddEvent("Failed to setup Prometheus provider", trace.WithAttributes(attribute.String("err", err.Error()))) + return err + } + sharedInformerFactory.Start(ctx.Done()) if metricProviderTokenReconciliation == secretReconciliation { namespacedSharedInformerFactory.Start(ctx.Done()) diff --git a/pkg/descheduler/descheduler_test.go b/pkg/descheduler/descheduler_test.go index b8773151d..e572dc7cb 100644 --- a/pkg/descheduler/descheduler_test.go +++ b/pkg/descheduler/descheduler_test.go @@ -202,6 +202,11 @@ func initDescheduler(t *testing.T, ctx context.Context, featureGates featuregate t.Fatalf("Unable to create a descheduler instance: %v", err) } + if err := setupPrometheusProvider(descheduler, nil); err != nil { + eventBroadcaster.Shutdown() + t.Fatalf("Failed to setup Prometheus provider: %v", err) + } + sharedInformerFactory.Start(ctx.Done()) sharedInformerFactory.WaitForCacheSync(ctx.Done()) From 8f5a83279ecfc12ca21f5a818d7e4ea7c127bfbc Mon Sep 17 00:00:00 2001 From: Jan Chaloupka Date: Thu, 22 Jan 2026 23:35:59 +0100 Subject: [PATCH 3/3] refactor(pkg/descheduler): drop unused fakeEvictedPods variables in the unit tests --- pkg/descheduler/descheduler_test.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/pkg/descheduler/descheduler_test.go b/pkg/descheduler/descheduler_test.go index e572dc7cb..e59e64ebc 100644 --- a/pkg/descheduler/descheduler_test.go +++ b/pkg/descheduler/descheduler_test.go @@ -647,11 +647,6 @@ func TestEvictionRequestsCache(t *testing.T) { _, descheduler, client := initDescheduler(t, ctxCancel, featureGates, internalDeschedulerPolicy, nil, false, node1, node2, p1, p2, p3, p4) defer cancel() - var fakeEvictedPods []string - descheduler.kubeClientSandbox.podEvictionReactionFnc = func(*fakeclientset.Clientset, *evictedPodsCache) func(action core.Action) (bool, runtime.Object, error) { - return podEvictionReactionTestingFnc(&fakeEvictedPods, nil, podEvictionError) - } - var evictedPods []string client.PrependReactor("create", "pods", podEvictionReactionTestingFnc(&evictedPods, func(name string) bool { return name == "p1" || name == "p2" }, nil)) @@ -788,11 +783,6 @@ func TestDeschedulingLimits(t *testing.T) { _, descheduler, client := initDescheduler(t, ctxCancel, featureGates, tc.policy, nil, false, node1, node2) defer cancel() - var fakeEvictedPods []string - descheduler.kubeClientSandbox.podEvictionReactionFnc = func(*fakeclientset.Clientset, *evictedPodsCache) func(action core.Action) (bool, runtime.Object, error) { - return podEvictionReactionTestingFnc(&fakeEvictedPods, nil, podEvictionError) - } - var evictedPods []string client.PrependReactor("create", "pods", podEvictionReactionTestingFnc(&evictedPods, func(name string) bool { return name == "p1" || name == "p2" }, nil))