From e5c969c1d16f0a67eaf2b94ecc668cde9fd349c7 Mon Sep 17 00:00:00 2001 From: Shafeeque E S Date: Tue, 20 Dec 2022 15:22:48 +0530 Subject: [PATCH] Drop `NewClientWithFieldSelectorSupport` function in favor of controller-runtime `WithIndex` function https://github.com/kubernetes-sigs/controller-runtime/pull/2025 --- pkg/api/indexer/core.go | 28 +++--- pkg/api/indexer/operations.go | 16 ++-- .../controller/bastion/add_test.go | 11 +-- .../controller/project/activity/add_test.go | 11 +-- .../backupbucketscheck/reconciler_test.go | 11 +-- pkg/utils/test/client.go | 94 ------------------- 6 files changed, 41 insertions(+), 130 deletions(-) delete mode 100644 pkg/utils/test/client.go diff --git a/pkg/api/indexer/core.go b/pkg/api/indexer/core.go index b505fac629a..4cf0854b966 100644 --- a/pkg/api/indexer/core.go +++ b/pkg/api/indexer/core.go @@ -25,15 +25,27 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) -// AddProjectNamespace adds an index for core.ProjectNamespace to the given indexer. -func AddProjectNamespace(ctx context.Context, indexer client.FieldIndexer) error { - if err := indexer.IndexField(ctx, &gardencorev1beta1.Project{}, core.ProjectNamespace, func(obj client.Object) []string { +var ( + ProjectNamespaceIndexerFunc = func(obj client.Object) []string { project, ok := obj.(*gardencorev1beta1.Project) if !ok { return []string{""} } return []string{pointer.StringDeref(project.Spec.Namespace, "")} - }); err != nil { + } + + BackupBucketSeedNameIndexerFunc = func(obj client.Object) []string { + backupBucket, ok := obj.(*gardencorev1beta1.BackupBucket) + if !ok { + return []string{""} + } + return []string{pointer.StringDeref(backupBucket.Spec.SeedName, "")} + } +) + +// AddProjectNamespace adds an index for core.ProjectNamespace to the given indexer. +func AddProjectNamespace(ctx context.Context, indexer client.FieldIndexer) error { + if err := indexer.IndexField(ctx, &gardencorev1beta1.Project{}, core.ProjectNamespace, ProjectNamespaceIndexerFunc); err != nil { return fmt.Errorf("failed to add indexer for %s to Project Informer: %w", core.ProjectNamespace, err) } return nil @@ -69,13 +81,7 @@ func AddShootStatusSeedName(ctx context.Context, indexer client.FieldIndexer) er // AddBackupBucketSeedName adds an index for core.BackupBucketSeedName to the given indexer. func AddBackupBucketSeedName(ctx context.Context, indexer client.FieldIndexer) error { - if err := indexer.IndexField(ctx, &gardencorev1beta1.BackupBucket{}, core.BackupBucketSeedName, func(obj client.Object) []string { - backupBucket, ok := obj.(*gardencorev1beta1.BackupBucket) - if !ok { - return []string{""} - } - return []string{pointer.StringDeref(backupBucket.Spec.SeedName, "")} - }); err != nil { + if err := indexer.IndexField(ctx, &gardencorev1beta1.BackupBucket{}, core.BackupBucketSeedName, BackupBucketSeedNameIndexerFunc); err != nil { return fmt.Errorf("failed to add indexer for %s to BackupBucket Informer: %w", core.BackupBucketSeedName, err) } return nil diff --git a/pkg/api/indexer/operations.go b/pkg/api/indexer/operations.go index 2e76709b788..5d99dd894b2 100644 --- a/pkg/api/indexer/operations.go +++ b/pkg/api/indexer/operations.go @@ -24,15 +24,17 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) +var BastionShootNameIndexerFunc = func(obj client.Object) []string { + bastion, ok := obj.(*operationsv1alpha1.Bastion) + if !ok { + return []string{""} + } + return []string{bastion.Spec.ShootRef.Name} +} + // AddBastionShootName adds an index for operations.BastionShootName to the given indexer. func AddBastionShootName(ctx context.Context, indexer client.FieldIndexer) error { - if err := indexer.IndexField(ctx, &operationsv1alpha1.Bastion{}, operations.BastionShootName, func(obj client.Object) []string { - bastion, ok := obj.(*operationsv1alpha1.Bastion) - if !ok { - return []string{""} - } - return []string{bastion.Spec.ShootRef.Name} - }); err != nil { + if err := indexer.IndexField(ctx, &operationsv1alpha1.Bastion{}, operations.BastionShootName, BastionShootNameIndexerFunc); err != nil { return fmt.Errorf("failed to add indexer for %s to Bastion Informer: %w", operations.BastionShootName, err) } return nil diff --git a/pkg/controllermanager/controller/bastion/add_test.go b/pkg/controllermanager/controller/bastion/add_test.go index 725afc75812..d8f3475c884 100644 --- a/pkg/controllermanager/controller/bastion/add_test.go +++ b/pkg/controllermanager/controller/bastion/add_test.go @@ -17,12 +17,12 @@ package bastion_test import ( "context" + "github.com/gardener/gardener/pkg/api/indexer" gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1" + "github.com/gardener/gardener/pkg/apis/operations" operationsv1alpha1 "github.com/gardener/gardener/pkg/apis/operations/v1alpha1" "github.com/gardener/gardener/pkg/client/kubernetes" . "github.com/gardener/gardener/pkg/controllermanager/controller/bastion" - bastionstrategy "github.com/gardener/gardener/pkg/registry/operations/bastion" - "github.com/gardener/gardener/pkg/utils/test" "github.com/go-logr/logr" . "github.com/onsi/ginkgo/v2" @@ -152,10 +152,9 @@ var _ = Describe("Add", func() { BeforeEach(func() { log = logr.Discard() - fakeClient = test.NewClientWithFieldSelectorSupport( - fakeclient.NewClientBuilder().WithScheme(kubernetes.GardenScheme).Build(), - bastionstrategy.ToSelectableFields, - ) + fakeClient = fakeclient.NewClientBuilder().WithScheme(kubernetes.GardenScheme).WithIndex( + &operationsv1alpha1.Bastion{}, operations.BastionShootName, indexer.BastionShootNameIndexerFunc, + ).Build() }) It("should do nothing if the object is no shoot", func() { diff --git a/pkg/controllermanager/controller/project/activity/add_test.go b/pkg/controllermanager/controller/project/activity/add_test.go index 0e780c3ee2a..c8a8c2d5a91 100644 --- a/pkg/controllermanager/controller/project/activity/add_test.go +++ b/pkg/controllermanager/controller/project/activity/add_test.go @@ -18,11 +18,11 @@ import ( "context" "time" + "github.com/gardener/gardener/pkg/api/indexer" + "github.com/gardener/gardener/pkg/apis/core" gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1" "github.com/gardener/gardener/pkg/client/kubernetes" . "github.com/gardener/gardener/pkg/controllermanager/controller/project/activity" - projectstrategy "github.com/gardener/gardener/pkg/registry/core/project" - "github.com/gardener/gardener/pkg/utils/test" "github.com/go-logr/logr" . "github.com/onsi/ginkgo/v2" @@ -172,10 +172,9 @@ var _ = Describe("Add", func() { BeforeEach(func() { log = logr.Discard() - fakeClient = test.NewClientWithFieldSelectorSupport( - fakeclient.NewClientBuilder().WithScheme(kubernetes.GardenScheme).Build(), - projectstrategy.ToSelectableFields, - ) + fakeClient = fakeclient.NewClientBuilder().WithScheme(kubernetes.GardenScheme).WithIndex( + &gardencorev1beta1.Project{}, core.ProjectNamespace, indexer.ProjectNamespaceIndexerFunc, + ).Build() project = &gardencorev1beta1.Project{ ObjectMeta: metav1.ObjectMeta{ diff --git a/pkg/controllermanager/controller/seed/backupbucketscheck/reconciler_test.go b/pkg/controllermanager/controller/seed/backupbucketscheck/reconciler_test.go index 2286dd2afdd..447c77bc134 100644 --- a/pkg/controllermanager/controller/seed/backupbucketscheck/reconciler_test.go +++ b/pkg/controllermanager/controller/seed/backupbucketscheck/reconciler_test.go @@ -18,12 +18,12 @@ import ( "context" "time" + "github.com/gardener/gardener/pkg/api/indexer" + "github.com/gardener/gardener/pkg/apis/core" gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1" "github.com/gardener/gardener/pkg/client/kubernetes" "github.com/gardener/gardener/pkg/controllermanager/apis/config" . "github.com/gardener/gardener/pkg/controllermanager/controller/seed/backupbucketscheck" - backupbucketstrategy "github.com/gardener/gardener/pkg/registry/core/backupbucket" - "github.com/gardener/gardener/pkg/utils/test" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -73,10 +73,9 @@ var _ = Describe("Reconciler", func() { fakeClock = testclock.NewFakeClock(time.Now().Round(time.Second)) - c = test.NewClientWithFieldSelectorSupport( - fakeclient.NewClientBuilder().WithScheme(kubernetes.GardenScheme).WithObjects(seed).Build(), - backupbucketstrategy.ToSelectableFields, - ) + c = fakeclient.NewClientBuilder().WithScheme(kubernetes.GardenScheme).WithObjects(seed).WithIndex( + &gardencorev1beta1.BackupBucket{}, core.BackupBucketSeedName, indexer.BackupBucketSeedNameIndexerFunc, + ).Build() conf = config.SeedBackupBucketsCheckControllerConfiguration{ SyncPeriod: &metav1.Duration{Duration: syncPeriod}, diff --git a/pkg/utils/test/client.go b/pkg/utils/test/client.go deleted file mode 100644 index 057a21b3f49..00000000000 --- a/pkg/utils/test/client.go +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) 2022 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file -// -// 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 test - -import ( - "context" - "fmt" - - "github.com/gardener/gardener/pkg/client/kubernetes" - - "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/fields" - "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -// NewClientWithFieldSelectorSupport takes a fake client and a function that returns selectable fields for the type T -// and adds support for field selectors to the client. -// TODO(plkokanov): remove this once the controller-runtime fake client supports field selectors. -func NewClientWithFieldSelectorSupport[T any](c client.Client, toSelectableFieldsFunc func(t *T) fields.Set) client.Client { - return &clientWithFieldSelectorSupport[T]{ - Client: c, - toSelectableFieldsFunc: toSelectableFieldsFunc, - } -} - -type clientWithFieldSelectorSupport[T any] struct { - client.Client - toSelectableFieldsFunc func(t *T) fields.Set -} - -func (c clientWithFieldSelectorSupport[T]) List(ctx context.Context, obj client.ObjectList, opts ...client.ListOption) error { - if err := c.Client.List(ctx, obj, opts...); err != nil { - return err - } - - listOpts := client.ListOptions{} - listOpts.ApplyOptions(opts) - - if listOpts.FieldSelector != nil { - objs, err := meta.ExtractList(obj) - if err != nil { - return err - } - filteredObjs, err := c.filterWithFieldSelector(objs, listOpts.FieldSelector) - if err != nil { - return err - } - err = meta.SetList(obj, filteredObjs) - if err != nil { - return err - } - } - - return nil -} - -func (c clientWithFieldSelectorSupport[T]) filterWithFieldSelector(objs []runtime.Object, sel fields.Selector) ([]runtime.Object, error) { - outItems := make([]runtime.Object, 0, len(objs)) - for _, obj := range objs { - // convert to internal - internalObj := new(T) - if err := kubernetes.GardenScheme.Convert(obj, internalObj, nil); err != nil { - return nil, err - } - - fieldSet := c.toSelectableFieldsFunc(internalObj) - - // complain about non-selectable fields if any - for _, req := range sel.Requirements() { - if !fieldSet.Has(req.Field) { - return nil, fmt.Errorf("field selector not supported for field %q", req.Field) - } - } - - if !sel.Matches(fieldSet) { - continue - } - outItems = append(outItems, obj.DeepCopyObject()) - } - return outItems, nil -}