Refactor Work index WorkIndexByResourceBindingID and WorkIndexByClusterResourceBindingID

Signed-off-by: RainbowMango <qdurenhongcai@gmail.com>
This commit is contained in:
RainbowMango 2025-04-12 16:18:53 +08:00
parent 8659599d97
commit 5865ee6ce2
11 changed files with 70 additions and 85 deletions

View File

@ -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())

View File

@ -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)

View File

@ -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 {

View File

@ -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()
}

View File

@ -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()
}

View File

@ -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",

View File

@ -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}
}
}

View File

@ -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()

View File

@ -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).

View File

@ -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.<ResourceBindingPermanentIDLabel>`,
@ -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}
}
}

View File

@ -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)
})
}
}