From 1c599c14a0c567d5fc81c450523cb3ea7af6c69b 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 | 44 +++++---- pkg/api/indexer/operations.go | 16 ++-- pkg/api/indexer/seedmanagement.go | 22 +++-- .../controller/bastion/add_test.go | 12 +-- .../controller/project/activity/add_test.go | 12 +-- .../backupbucketscheck/reconciler_test.go | 13 +-- .../seed/extensionscheck/reconciler_test.go | 8 +- .../kube_apiserver_sni_test.go | 12 ++- pkg/utils/kubernetes/managedseed_test.go | 8 +- pkg/utils/test/client.go | 94 ------------------- 10 files changed, 91 insertions(+), 150 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..ab2f5b07dd3 100644 --- a/pkg/api/indexer/core.go +++ b/pkg/api/indexer/core.go @@ -25,15 +25,35 @@ 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, "")} + } + + ControllerInstallationSeedRefNameIndexerFunc = func(obj client.Object) []string { + controllerInstallation, ok := obj.(*gardencorev1beta1.ControllerInstallation) + if !ok { + return []string{""} + } + return []string{controllerInstallation.Spec.SeedRef.Name} + } +) + +// 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 +89,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 @@ -111,13 +125,7 @@ func AddBackupEntryBucketName(ctx context.Context, indexer client.FieldIndexer) // AddControllerInstallationSeedRefName adds an index for core.ControllerInstallationSeedRefName to the given indexer. func AddControllerInstallationSeedRefName(ctx context.Context, indexer client.FieldIndexer) error { - if err := indexer.IndexField(ctx, &gardencorev1beta1.ControllerInstallation{}, core.SeedRefName, func(obj client.Object) []string { - controllerInstallation, ok := obj.(*gardencorev1beta1.ControllerInstallation) - if !ok { - return []string{""} - } - return []string{controllerInstallation.Spec.SeedRef.Name} - }); err != nil { + if err := indexer.IndexField(ctx, &gardencorev1beta1.ControllerInstallation{}, core.SeedRefName, ControllerInstallationSeedRefNameIndexerFunc); err != nil { return fmt.Errorf("failed to add indexer for %s to ControllerInstallation Informer: %w", core.SeedRefName, 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/api/indexer/seedmanagement.go b/pkg/api/indexer/seedmanagement.go index c47543f2e1a..0e174a6eed0 100644 --- a/pkg/api/indexer/seedmanagement.go +++ b/pkg/api/indexer/seedmanagement.go @@ -24,18 +24,20 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) +var ManagedSeedShootNameIndexerFunc = func(obj client.Object) []string { + managedSeed, ok := obj.(*seedmanagementv1alpha1.ManagedSeed) + if !ok { + return []string{""} + } + if managedSeed.Spec.Shoot == nil { + return []string{""} + } + return []string{managedSeed.Spec.Shoot.Name} +} + // AddManagedSeedShootName adds an index for seedmanagement.ManagedSeedShootName to the given indexer. func AddManagedSeedShootName(ctx context.Context, indexer client.FieldIndexer) error { - if err := indexer.IndexField(ctx, &seedmanagementv1alpha1.ManagedSeed{}, seedmanagement.ManagedSeedShootName, func(obj client.Object) []string { - managedSeed, ok := obj.(*seedmanagementv1alpha1.ManagedSeed) - if !ok { - return []string{""} - } - if managedSeed.Spec.Shoot == nil { - return []string{""} - } - return []string{managedSeed.Spec.Shoot.Name} - }); err != nil { + if err := indexer.IndexField(ctx, &seedmanagementv1alpha1.ManagedSeed{}, seedmanagement.ManagedSeedShootName, ManagedSeedShootNameIndexerFunc); err != nil { return fmt.Errorf("failed to add indexer for %s to ManagedSeed Informer: %w", seedmanagement.ManagedSeedShootName, err) } return nil diff --git a/pkg/controllermanager/controller/bastion/add_test.go b/pkg/controllermanager/controller/bastion/add_test.go index 725afc75812..3bb774aa56b 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,10 @@ 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..70c82e08c38 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,10 @@ 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..83051c79fc3 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,11 @@ 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/controllermanager/controller/seed/extensionscheck/reconciler_test.go b/pkg/controllermanager/controller/seed/extensionscheck/reconciler_test.go index 5b88eb72482..f4f3c3097a1 100644 --- a/pkg/controllermanager/controller/seed/extensionscheck/reconciler_test.go +++ b/pkg/controllermanager/controller/seed/extensionscheck/reconciler_test.go @@ -18,6 +18,8 @@ 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" @@ -64,7 +66,11 @@ var _ = Describe("Reconciler", func() { fakeClock = testclock.NewFakeClock(time.Now().Round(time.Second)) - c = fakeclient.NewClientBuilder().WithScheme(kubernetes.GardenScheme).WithObjects(seed).Build() + c = fakeclient.NewClientBuilder(). + WithScheme(kubernetes.GardenScheme). + WithObjects(seed). + WithIndex(&gardencorev1beta1.ControllerInstallation{}, core.SeedRefName, indexer.ControllerInstallationSeedRefNameIndexerFunc). + Build() conf := config.SeedExtensionsCheckControllerConfiguration{ SyncPeriod: &metav1.Duration{Duration: syncPeriodDuration}, } diff --git a/pkg/operation/botanist/component/kubeapiserverexposure/kube_apiserver_sni_test.go b/pkg/operation/botanist/component/kubeapiserverexposure/kube_apiserver_sni_test.go index 08d7bbac5f4..0096a0f8c30 100644 --- a/pkg/operation/botanist/component/kubeapiserverexposure/kube_apiserver_sni_test.go +++ b/pkg/operation/botanist/component/kubeapiserverexposure/kube_apiserver_sni_test.go @@ -289,7 +289,17 @@ var _ = Describe("#SNI", func() { // TODO(mvladev): can't directly import the istio apis due to dependency issues. s.AddKnownTypeWithName(schema.FromAPIVersionAndKind("networking.istio.io/v1beta1", "VirtualServiceList"), &unstructured.UnstructuredList{}) s.AddKnownTypeWithName(schema.FromAPIVersionAndKind("networking.istio.io/v1beta1", "VirtualService"), &unstructured.Unstructured{}) - c = fake.NewClientBuilder().WithScheme(s).Build() + virtualServiceObj := &unstructured.Unstructured{} + virtualServiceObj.SetGroupVersionKind(schema.FromAPIVersionAndKind("networking.istio.io/v1beta1", "VirtualService")) + + c = fake.NewClientBuilder(). + WithScheme(s). + WithIndex( + virtualServiceObj, "metadata.name", func(o client.Object) []string { + return []string{o.GetName()} + }, + ). + Build() }) It("returns true when exists", func() { diff --git a/pkg/utils/kubernetes/managedseed_test.go b/pkg/utils/kubernetes/managedseed_test.go index 96d23a849e5..b36290eb7cb 100644 --- a/pkg/utils/kubernetes/managedseed_test.go +++ b/pkg/utils/kubernetes/managedseed_test.go @@ -27,6 +27,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake" + "github.com/gardener/gardener/pkg/api/indexer" + "github.com/gardener/gardener/pkg/apis/seedmanagement" seedmanagementv1alpha1 "github.com/gardener/gardener/pkg/apis/seedmanagement/v1alpha1" "github.com/gardener/gardener/pkg/client/kubernetes" mockclient "github.com/gardener/gardener/pkg/mock/controller-runtime/client" @@ -66,7 +68,11 @@ var _ = Describe("managedseed", func() { ) BeforeEach(func() { - fakeClient = fakeclient.NewClientBuilder().WithScheme(kubernetes.GardenScheme).WithObjects(managedSeed).Build() + fakeClient = fakeclient.NewClientBuilder(). + WithScheme(kubernetes.GardenScheme). + WithObjects(managedSeed). + WithIndex(&seedmanagementv1alpha1.ManagedSeed{}, seedmanagement.ManagedSeedShootName, indexer.ManagedSeedShootNameIndexerFunc). + Build() }) It("should return the ManagedSeed for the given shoot namespace and name, if it exists", func() { 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 -}