diff --git a/cmd/controller-manager/app/controllermanager.go b/cmd/controller-manager/app/controllermanager.go index 39a60393c..d09ac1e9f 100644 --- a/cmd/controller-manager/app/controllermanager.go +++ b/cmd/controller-manager/app/controllermanager.go @@ -85,6 +85,7 @@ import ( "github.com/karmada-io/karmada/pkg/util/fedinformer/typedmanager" "github.com/karmada-io/karmada/pkg/util/gclient" "github.com/karmada-io/karmada/pkg/util/helper" + "github.com/karmada-io/karmada/pkg/util/indexregistry" "github.com/karmada-io/karmada/pkg/util/names" "github.com/karmada-io/karmada/pkg/util/objectwatcher" "github.com/karmada-io/karmada/pkg/util/overridemanager" @@ -194,8 +195,11 @@ func Run(ctx context.Context, opts *options.Options) error { ctrlmetrics.Registry.MustRegister(metrics.PoolCollectors()...) ctrlmetrics.Registry.MustRegister(metrics.NewBuildInfoCollector()) - if err := helper.IndexWork(ctx, controllerManager); err != nil { - klog.Fatalf("Failed to index Work: %v", err) + if err = indexregistry.RegisterWorkParentRBIndex(ctx, controllerManager); err != nil { + klog.Fatalf("Failed to register index for Work based on ResourceBinding ID: %v", err) + } + if err = indexregistry.RegisterWorkParentCRBIndex(ctx, controllerManager); err != nil { + klog.Fatalf("Failed to register index for Work based on ClusterResourceBinding ID: %v", err) } setupControllers(controllerManager, opts, ctx.Done()) diff --git a/pkg/controllers/binding/binding_controller_test.go b/pkg/controllers/binding/binding_controller_test.go index 22a34b391..9093c3c95 100644 --- a/pkg/controllers/binding/binding_controller_test.go +++ b/pkg/controllers/binding/binding_controller_test.go @@ -43,7 +43,6 @@ import ( "github.com/karmada-io/karmada/pkg/util" "github.com/karmada-io/karmada/pkg/util/fedinformer/genericmanager" "github.com/karmada-io/karmada/pkg/util/gclient" - utilhelper "github.com/karmada-io/karmada/pkg/util/helper" "github.com/karmada-io/karmada/pkg/util/indexregistry" testingutil "github.com/karmada-io/karmada/pkg/util/testing" "github.com/karmada-io/karmada/test/helper" @@ -56,7 +55,7 @@ func makeFakeRBCByResource(rs *workv1alpha2.ObjectReference) (*ResourceBindingCo c := fake.NewClientBuilder().WithScheme(gclient.NewSchema()).WithIndex( &workv1alpha1.Work{}, indexregistry.WorkIndexByResourceBindingID, - utilhelper.IndexerFuncBasedOnLabel(workv1alpha2.ResourceBindingPermanentIDLabel), + indexregistry.GenLabelIndexerFunc(workv1alpha2.ResourceBindingPermanentIDLabel), ).Build() tempDyClient := fakedynamic.NewSimpleDynamicClient(scheme.Scheme) diff --git a/pkg/controllers/binding/cluster_resource_binding_controller_test.go b/pkg/controllers/binding/cluster_resource_binding_controller_test.go index 3ae69eae1..7bd0e4a50 100644 --- a/pkg/controllers/binding/cluster_resource_binding_controller_test.go +++ b/pkg/controllers/binding/cluster_resource_binding_controller_test.go @@ -43,7 +43,6 @@ import ( "github.com/karmada-io/karmada/pkg/util" "github.com/karmada-io/karmada/pkg/util/fedinformer/genericmanager" "github.com/karmada-io/karmada/pkg/util/gclient" - utilhelper "github.com/karmada-io/karmada/pkg/util/helper" "github.com/karmada-io/karmada/pkg/util/indexregistry" testingutil "github.com/karmada-io/karmada/pkg/util/testing" "github.com/karmada-io/karmada/test/helper" @@ -53,7 +52,7 @@ func makeFakeCRBCByResource(rs *workv1alpha2.ObjectReference) (*ClusterResourceB c := fake.NewClientBuilder().WithScheme(gclient.NewSchema()).WithIndex( &workv1alpha1.Work{}, indexregistry.WorkIndexByClusterResourceBindingID, - utilhelper.IndexerFuncBasedOnLabel(workv1alpha2.ClusterResourceBindingPermanentIDLabel), + indexregistry.GenLabelIndexerFunc(workv1alpha2.ClusterResourceBindingPermanentIDLabel), ).Build() tempDyClient := fakedynamic.NewSimpleDynamicClient(scheme.Scheme) if rs == nil { diff --git a/pkg/controllers/status/crb_status_controller_test.go b/pkg/controllers/status/crb_status_controller_test.go index 6e6ef8fd1..0c3757fa5 100644 --- a/pkg/controllers/status/crb_status_controller_test.go +++ b/pkg/controllers/status/crb_status_controller_test.go @@ -38,7 +38,6 @@ import ( "github.com/karmada-io/karmada/pkg/resourceinterpreter/default/native" "github.com/karmada-io/karmada/pkg/util/fedinformer/genericmanager" "github.com/karmada-io/karmada/pkg/util/gclient" - utilhelper "github.com/karmada-io/karmada/pkg/util/helper" "github.com/karmada-io/karmada/pkg/util/indexregistry" ) @@ -56,7 +55,7 @@ func generateCRBStatusController() *CRBStatusController { Client: fake.NewClientBuilder().WithScheme(gclient.NewSchema()).WithIndex( &workv1alpha1.Work{}, indexregistry.WorkIndexByClusterResourceBindingID, - utilhelper.IndexerFuncBasedOnLabel(workv1alpha2.ClusterResourceBindingPermanentIDLabel), + indexregistry.GenLabelIndexerFunc(workv1alpha2.ClusterResourceBindingPermanentIDLabel), ).Build(), DynamicClient: dynamicClient, InformerManager: m, @@ -138,7 +137,7 @@ func TestCRBStatusController_Reconcile(t *testing.T) { // Prepare binding and create it in client if tt.binding != nil { c.Client = fake.NewClientBuilder().WithScheme(gclient.NewSchema()).WithObjects(tt.binding).WithStatusSubresource(tt.binding). - WithIndex(&workv1alpha1.Work{}, indexregistry.WorkIndexByClusterResourceBindingID, utilhelper.IndexerFuncBasedOnLabel(workv1alpha2.ClusterResourceBindingPermanentIDLabel)). + WithIndex(&workv1alpha1.Work{}, indexregistry.WorkIndexByClusterResourceBindingID, indexregistry.GenLabelIndexerFunc(workv1alpha2.ClusterResourceBindingPermanentIDLabel)). Build() } @@ -210,7 +209,7 @@ func TestCRBStatusController_syncBindingStatus(t *testing.T) { if tt.resourceExistInClient { c.Client = fake.NewClientBuilder().WithScheme(gclient.NewSchema()).WithObjects(binding).WithStatusSubresource(binding). - WithIndex(&workv1alpha1.Work{}, indexregistry.WorkIndexByClusterResourceBindingID, utilhelper.IndexerFuncBasedOnLabel(workv1alpha2.ClusterResourceBindingPermanentIDLabel)). + WithIndex(&workv1alpha1.Work{}, indexregistry.WorkIndexByClusterResourceBindingID, indexregistry.GenLabelIndexerFunc(workv1alpha2.ClusterResourceBindingPermanentIDLabel)). Build() } diff --git a/pkg/controllers/status/rb_status_controller_test.go b/pkg/controllers/status/rb_status_controller_test.go index d6ab81f8c..b5d084346 100644 --- a/pkg/controllers/status/rb_status_controller_test.go +++ b/pkg/controllers/status/rb_status_controller_test.go @@ -39,7 +39,6 @@ import ( "github.com/karmada-io/karmada/pkg/resourceinterpreter/default/native" "github.com/karmada-io/karmada/pkg/util/fedinformer/genericmanager" "github.com/karmada-io/karmada/pkg/util/gclient" - utilhelper "github.com/karmada-io/karmada/pkg/util/helper" "github.com/karmada-io/karmada/pkg/util/indexregistry" ) @@ -57,7 +56,7 @@ func generateRBStatusController() *RBStatusController { Client: fake.NewClientBuilder().WithScheme(gclient.NewSchema()).WithIndex( &workv1alpha1.Work{}, indexregistry.WorkIndexByResourceBindingID, - utilhelper.IndexerFuncBasedOnLabel(workv1alpha2.ClusterResourceBindingPermanentIDLabel), + indexregistry.GenLabelIndexerFunc(workv1alpha2.ClusterResourceBindingPermanentIDLabel), ).Build(), DynamicClient: dynamicClient, InformerManager: m, @@ -144,7 +143,7 @@ func TestRBStatusController_Reconcile(t *testing.T) { // Prepare binding and create it in client if tt.binding != nil { c.Client = fake.NewClientBuilder().WithScheme(gclient.NewSchema()).WithObjects(tt.binding).WithStatusSubresource(tt.binding). - WithIndex(&workv1alpha1.Work{}, indexregistry.WorkIndexByResourceBindingID, utilhelper.IndexerFuncBasedOnLabel(workv1alpha2.ResourceBindingPermanentIDLabel)). + WithIndex(&workv1alpha1.Work{}, indexregistry.WorkIndexByResourceBindingID, indexregistry.GenLabelIndexerFunc(workv1alpha2.ResourceBindingPermanentIDLabel)). Build() } @@ -219,7 +218,7 @@ func TestRBStatusController_syncBindingStatus(t *testing.T) { if tt.resourceExistInClient { c.Client = fake.NewClientBuilder().WithScheme(gclient.NewSchema()).WithObjects(binding).WithStatusSubresource(binding). - WithIndex(&workv1alpha1.Work{}, indexregistry.WorkIndexByResourceBindingID, utilhelper.IndexerFuncBasedOnLabel(workv1alpha2.ResourceBindingPermanentIDLabel)). + WithIndex(&workv1alpha1.Work{}, indexregistry.WorkIndexByResourceBindingID, indexregistry.GenLabelIndexerFunc(workv1alpha2.ResourceBindingPermanentIDLabel)). Build() } diff --git a/pkg/util/helper/binding_test.go b/pkg/util/helper/binding_test.go index 9fb2555fe..a7b852813 100644 --- a/pkg/util/helper/binding_test.go +++ b/pkg/util/helper/binding_test.go @@ -468,7 +468,7 @@ func TestFindOrphanWorks(t *testing.T) { ).WithIndex( &workv1alpha1.Work{}, indexregistry.WorkIndexByResourceBindingID, - IndexerFuncBasedOnLabel(workv1alpha2.ResourceBindingPermanentIDLabel), + indexregistry.GenLabelIndexerFunc(workv1alpha2.ResourceBindingPermanentIDLabel), ).Build(), bindingNamespace: "default", bindingName: "binding", @@ -517,7 +517,7 @@ func TestFindOrphanWorks(t *testing.T) { ).WithIndex( &workv1alpha1.Work{}, indexregistry.WorkIndexByResourceBindingID, - IndexerFuncBasedOnLabel(workv1alpha2.ResourceBindingPermanentIDLabel), + indexregistry.GenLabelIndexerFunc(workv1alpha2.ResourceBindingPermanentIDLabel), ).Build(), bindingNamespace: "default", bindingName: "binding", @@ -573,7 +573,7 @@ func TestFindOrphanWorks(t *testing.T) { ).WithIndex( &workv1alpha1.Work{}, indexregistry.WorkIndexByClusterResourceBindingID, - IndexerFuncBasedOnLabel(workv1alpha2.ClusterResourceBindingPermanentIDLabel), + indexregistry.GenLabelIndexerFunc(workv1alpha2.ClusterResourceBindingPermanentIDLabel), ).Build(), bindingNamespace: "", bindingName: "binding", @@ -1034,7 +1034,7 @@ func TestDeleteWorkByRBNamespaceAndName(t *testing.T) { c: fake.NewClientBuilder().WithScheme(gclient.NewSchema()).WithIndex( &workv1alpha1.Work{}, indexregistry.WorkIndexByResourceBindingID, - IndexerFuncBasedOnLabel(workv1alpha2.ResourceBindingPermanentIDLabel), + indexregistry.GenLabelIndexerFunc(workv1alpha2.ResourceBindingPermanentIDLabel), ).Build(), namespace: "default", name: "foo", @@ -1062,7 +1062,7 @@ func TestDeleteWorkByRBNamespaceAndName(t *testing.T) { ).WithIndex( &workv1alpha1.Work{}, indexregistry.WorkIndexByResourceBindingID, - IndexerFuncBasedOnLabel(workv1alpha2.ResourceBindingPermanentIDLabel), + indexregistry.GenLabelIndexerFunc(workv1alpha2.ResourceBindingPermanentIDLabel), ).Build(), namespace: "default", name: "foo", @@ -1089,7 +1089,7 @@ func TestDeleteWorkByRBNamespaceAndName(t *testing.T) { ).WithIndex( &workv1alpha1.Work{}, indexregistry.WorkIndexByClusterResourceBindingID, - IndexerFuncBasedOnLabel(workv1alpha2.ClusterResourceBindingPermanentIDLabel), + indexregistry.GenLabelIndexerFunc(workv1alpha2.ClusterResourceBindingPermanentIDLabel), ).Build(), name: "foo", bindingID: "3617252f-b1bb-43b0-98a1-c7de833c472c", diff --git a/pkg/util/helper/index.go b/pkg/util/helper/index.go deleted file mode 100644 index 6f1761eb0..000000000 --- a/pkg/util/helper/index.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 2024 The Karmada 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 helper - -import ( - "context" - - "k8s.io/klog/v2" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - - workv1alpha1 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha1" - workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2" - "github.com/karmada-io/karmada/pkg/util/indexregistry" -) - -// IndexWork creates index for Work. -func IndexWork(ctx context.Context, mgr ctrl.Manager) error { - err := mgr.GetFieldIndexer().IndexField(ctx, &workv1alpha1.Work{}, indexregistry.WorkIndexByResourceBindingID, - IndexerFuncBasedOnLabel(workv1alpha2.ResourceBindingPermanentIDLabel)) - if err != nil { - klog.Errorf("failed to create index for work, err: %v", err) - return err - } - err = mgr.GetFieldIndexer().IndexField(ctx, &workv1alpha1.Work{}, indexregistry.WorkIndexByClusterResourceBindingID, - IndexerFuncBasedOnLabel(workv1alpha2.ClusterResourceBindingPermanentIDLabel)) - if err != nil { - klog.Errorf("failed to create index for work, err: %v", err) - return err - } - return nil -} - -// IndexerFuncBasedOnLabel returns an IndexerFunc used to index resource with the given key as label key. -func IndexerFuncBasedOnLabel(key string) client.IndexerFunc { - return func(obj client.Object) []string { - val, ok := obj.GetLabels()[key] - if !ok { - return nil - } - return []string{val} - } -} diff --git a/pkg/util/helper/work_test.go b/pkg/util/helper/work_test.go index fb40d87b7..58a7e6540 100644 --- a/pkg/util/helper/work_test.go +++ b/pkg/util/helper/work_test.go @@ -155,7 +155,7 @@ func TestGetWorksByBindingID(t *testing.T) { WithIndex( &workv1alpha1.Work{}, tt.indexName, - IndexerFuncBasedOnLabel(tt.permanentIDLabelKey), + indexregistry.GenLabelIndexerFunc(tt.permanentIDLabelKey), ). WithObjects(tt.works...). Build() diff --git a/pkg/util/helper/workstatus_test.go b/pkg/util/helper/workstatus_test.go index ba424ffc7..0b9e6479e 100644 --- a/pkg/util/helper/workstatus_test.go +++ b/pkg/util/helper/workstatus_test.go @@ -203,7 +203,7 @@ func TestAggregateResourceBindingWorkStatus(t *testing.T) { WithIndex( &workv1alpha1.Work{}, indexregistry.WorkIndexByResourceBindingID, - IndexerFuncBasedOnLabel(workv1alpha2.ResourceBindingPermanentIDLabel), + indexregistry.GenLabelIndexerFunc(workv1alpha2.ResourceBindingPermanentIDLabel), ). WithObjects(objects...). WithStatusSubresource(tt.binding). @@ -400,7 +400,7 @@ func TestAggregateClusterResourceBindingWorkStatus(t *testing.T) { WithIndex( &workv1alpha1.Work{}, indexregistry.WorkIndexByClusterResourceBindingID, - IndexerFuncBasedOnLabel(workv1alpha2.ClusterResourceBindingPermanentIDLabel), + indexregistry.GenLabelIndexerFunc(workv1alpha2.ClusterResourceBindingPermanentIDLabel), ). WithObjects(objects...). WithStatusSubresource(tt.binding). diff --git a/pkg/util/indexregistry/fieldindex.go b/pkg/util/indexregistry/fieldindex.go index 910c2e3e3..755d7def6 100644 --- a/pkg/util/indexregistry/fieldindex.go +++ b/pkg/util/indexregistry/fieldindex.go @@ -16,6 +16,17 @@ limitations under the License. package indexregistry +import ( + "context" + + "k8s.io/klog/v2" + controllerruntime "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + + workv1alpha1 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha1" + workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2" +) + const ( // WorkIndexByResourceBindingID is the index name for Works that are associated with a ResourceBinding ID. // This index allows efficient lookup of Works by their `metadata.labels.`, @@ -27,3 +38,34 @@ const ( // of Works linked to specific ClusterResourceBinding objects across all namespaces. WorkIndexByClusterResourceBindingID = "WorkIndexByClusterResourceBindingID" ) + +// RegisterWorkParentRBIndex registers index for Work object based on the referencing ResourceBinding ID. +func RegisterWorkParentRBIndex(ctx context.Context, mgr controllerruntime.Manager) error { + err := mgr.GetFieldIndexer().IndexField(ctx, &workv1alpha1.Work{}, WorkIndexByResourceBindingID, GenLabelIndexerFunc(workv1alpha2.ResourceBindingPermanentIDLabel)) + if err != nil { + klog.Errorf("failed to create index for work, err: %v", err) + return err + } + return nil +} + +// RegisterWorkParentCRBIndex registers index for Work object based on the referencing ClusterResourceBinding ID. +func RegisterWorkParentCRBIndex(ctx context.Context, mgr controllerruntime.Manager) error { + err := mgr.GetFieldIndexer().IndexField(ctx, &workv1alpha1.Work{}, WorkIndexByClusterResourceBindingID, GenLabelIndexerFunc(workv1alpha2.ClusterResourceBindingPermanentIDLabel)) + if err != nil { + klog.Errorf("failed to create index for work, err: %v", err) + return err + } + return nil +} + +// GenLabelIndexerFunc returns an IndexerFunc used to index resource with the given label key. +func GenLabelIndexerFunc(labelKey string) client.IndexerFunc { + return func(obj client.Object) []string { + labelValue, ok := obj.GetLabels()[labelKey] + if !ok { + return nil + } + return []string{labelValue} + } +} diff --git a/pkg/util/helper/index_test.go b/pkg/util/indexregistry/fieldindex_test.go similarity index 85% rename from pkg/util/helper/index_test.go rename to pkg/util/indexregistry/fieldindex_test.go index fd6041688..96e1c5d49 100644 --- a/pkg/util/helper/index_test.go +++ b/pkg/util/indexregistry/fieldindex_test.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Karmada Authors. +Copyright 2025 The Karmada Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package helper +package indexregistry import ( "testing" @@ -25,7 +25,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) -func TestIndexerFuncBasedOnLabel(t *testing.T) { +func TestGenLabelIndexerFunc(t *testing.T) { type args struct { key string obj client.Object @@ -66,11 +66,11 @@ func TestIndexerFuncBasedOnLabel(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - fn := IndexerFuncBasedOnLabel(tt.args.key) + fn := GenLabelIndexerFunc(tt.args.key) if !assert.NotNil(t, fn) { t.FailNow() } - assert.Equalf(t, tt.want, fn(tt.args.obj), "IndexerFuncBasedOnLabel(%v)", tt.args.key) + assert.Equalf(t, tt.want, fn(tt.args.obj), "GenLabelIndexerFunc(%v)", tt.args.key) }) } }