Skip to content

Commit a3c9481

Browse files
zhujian7claude
andcommitted
Add ManagedClusterAddOn filter functionality to addon framework
This commit introduces a new filtering mechanism for ManagedClusterAddOn objects to enable selective processing of addons based on custom criteria. Key changes: 1. Created pkg/utils/addon.go with filter functions: - ManagedClusterAddOnFilterFunc type for custom filtering - AllowAllAddOns function that accepts all addons - FilterTemplateBasedAddOns function that filters template-based addons 2. Updated all addon controllers to accept and use the filter function: - addonconfig controller - agentdeploy controller - certificate controllers (CSR approve/sign) - registration controller 3. Added comprehensive test coverage in pkg/utils/addon_test.go 4. Updated BaseAddonManager interface to include mcaFilterFunc parameter This enables selective processing of addons, particularly useful for filtering template-based addons vs regular addons based on their status.configReferences. 🤖 Generated with Claude Code Co-Authored-By: Claude <[email protected]> Signed-off-by: zhujian <[email protected]>
1 parent 1db1757 commit a3c9481

File tree

13 files changed

+328
-10
lines changed

13 files changed

+328
-10
lines changed

pkg/addonmanager/base_manager.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,12 @@ func (a *BaseAddonManagerImpl) StartWithInformers(ctx context.Context,
7777
kubeInformers kubeinformers.SharedInformerFactory,
7878
addonInformers addoninformers.SharedInformerFactory,
7979
clusterInformers clusterv1informers.SharedInformerFactory,
80-
dynamicInformers dynamicinformer.DynamicSharedInformerFactory) error {
80+
dynamicInformers dynamicinformer.DynamicSharedInformerFactory,
81+
mcaFilterFunc utils.ManagedClusterAddOnFilterFunc,
82+
) error {
83+
if mcaFilterFunc == nil {
84+
mcaFilterFunc = utils.AllowAllAddOns
85+
}
8186

8287
kubeClient, err := kubernetes.NewForConfig(a.config)
8388
if err != nil {
@@ -107,13 +112,15 @@ func (a *BaseAddonManagerImpl) StartWithInformers(ctx context.Context,
107112
addonInformers.Addon().V1alpha1().ManagedClusterAddOns(),
108113
workInformers,
109114
a.addonAgents,
115+
mcaFilterFunc,
110116
)
111117

112118
registrationController := registration.NewAddonRegistrationController(
113119
addonClient,
114120
clusterInformers.Cluster().V1().ManagedClusters(),
115121
addonInformers.Addon().V1alpha1().ManagedClusterAddOns(),
116122
a.addonAgents,
123+
mcaFilterFunc,
117124
)
118125

119126
// This controller is used during migrating addons to be managed by addon-manager.
@@ -135,6 +142,7 @@ func (a *BaseAddonManagerImpl) StartWithInformers(ctx context.Context,
135142
dynamicInformers,
136143
a.addonConfigs,
137144
utils.FilterByAddonName(a.addonAgents),
145+
mcaFilterFunc,
138146
)
139147
managementAddonConfigController = cmaconfig.NewCMAConfigController(
140148
addonClient,
@@ -159,13 +167,15 @@ func (a *BaseAddonManagerImpl) StartWithInformers(ctx context.Context,
159167
nil,
160168
addonInformers.Addon().V1alpha1().ManagedClusterAddOns(),
161169
a.addonAgents,
170+
mcaFilterFunc,
162171
)
163172
csrSignController = certificate.NewCSRSignController(
164173
kubeClient,
165174
clusterInformers.Cluster().V1().ManagedClusters(),
166175
kubeInformers.Certificates().V1().CertificateSigningRequests(),
167176
addonInformers.Addon().V1alpha1().ManagedClusterAddOns(),
168177
a.addonAgents,
178+
mcaFilterFunc,
169179
)
170180
} else if v1beta1Supported {
171181
csrApproveController = certificate.NewCSRApprovingController(
@@ -175,6 +185,7 @@ func (a *BaseAddonManagerImpl) StartWithInformers(ctx context.Context,
175185
kubeInformers.Certificates().V1beta1().CertificateSigningRequests(),
176186
addonInformers.Addon().V1alpha1().ManagedClusterAddOns(),
177187
a.addonAgents,
188+
mcaFilterFunc,
178189
)
179190
}
180191

pkg/addonmanager/cloudevents/manager.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121

2222
"open-cluster-management.io/addon-framework/pkg/addonmanager"
2323
"open-cluster-management.io/addon-framework/pkg/index"
24+
"open-cluster-management.io/addon-framework/pkg/utils"
2425
workclientset "open-cluster-management.io/api/client/work/clientset/versioned"
2526
"open-cluster-management.io/sdk-go/pkg/cloudevents/clients/options"
2627
cloudeventswork "open-cluster-management.io/sdk-go/pkg/cloudevents/clients/work"
@@ -176,7 +177,8 @@ func (a *cloudeventsAddonManager) Start(ctx context.Context) error {
176177
return err
177178
}
178179

179-
err = a.StartWithInformers(ctx, workClient, workInformers, kubeInformers, addonInformers, clusterInformers, dynamicInformers)
180+
err = a.StartWithInformers(ctx, workClient, workInformers, kubeInformers, addonInformers, clusterInformers,
181+
dynamicInformers, utils.AllowAllAddOns)
180182
if err != nil {
181183
return err
182184
}

pkg/addonmanager/controllers/addonconfig/controller.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ type addonConfigController struct {
3737
configListers map[schema.GroupResource]dynamiclister.Lister
3838
queue workqueue.TypedRateLimitingInterface[string]
3939
cmaFilterFunc factory.EventFilterFunc
40+
mcaFilterFunc utils.ManagedClusterAddOnFilterFunc
4041
configGVRs map[schema.GroupVersionResource]bool
4142
clusterManagementAddonLister addonlisterv1alpha1.ClusterManagementAddOnLister
4243
}
@@ -48,6 +49,7 @@ func NewAddonConfigController(
4849
configInformerFactory dynamicinformer.DynamicSharedInformerFactory,
4950
configGVRs map[schema.GroupVersionResource]bool,
5051
cmaFilterFunc factory.EventFilterFunc,
52+
mcaFilterFunc utils.ManagedClusterAddOnFilterFunc,
5153
) factory.Controller {
5254
syncCtx := factory.NewSyncContext(controllerName)
5355

@@ -58,6 +60,7 @@ func NewAddonConfigController(
5860
configListers: map[schema.GroupResource]dynamiclister.Lister{},
5961
queue: syncCtx.Queue(),
6062
cmaFilterFunc: cmaFilterFunc,
63+
mcaFilterFunc: mcaFilterFunc,
6164
configGVRs: configGVRs,
6265
clusterManagementAddonLister: clusterManagementAddonInformers.Lister(),
6366
}
@@ -144,6 +147,10 @@ func (c *addonConfigController) sync(ctx context.Context, syncCtx factory.SyncCo
144147
return err
145148
}
146149

150+
if c.mcaFilterFunc != nil && !c.mcaFilterFunc(addon) {
151+
return nil
152+
}
153+
147154
cma, err := c.clusterManagementAddonLister.Get(addonName)
148155
if errors.IsNotFound(err) {
149156
// cluster management addon could be deleted, ignore
@@ -153,7 +160,7 @@ func (c *addonConfigController) sync(ctx context.Context, syncCtx factory.SyncCo
153160
return err
154161
}
155162

156-
if !c.cmaFilterFunc(cma) {
163+
if c.cmaFilterFunc != nil && !c.cmaFilterFunc(cma) {
157164
return nil
158165
}
159166

pkg/addonmanager/controllers/agentdeploy/controller.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"open-cluster-management.io/addon-framework/pkg/addonmanager/constants"
3333
"open-cluster-management.io/addon-framework/pkg/agent"
3434
"open-cluster-management.io/addon-framework/pkg/index"
35+
"open-cluster-management.io/addon-framework/pkg/utils"
3536
"open-cluster-management.io/sdk-go/pkg/basecontroller/factory"
3637
)
3738

@@ -50,6 +51,7 @@ type addonDeployController struct {
5051
workIndexer cache.Indexer
5152
agentAddons map[string]agent.AgentAddon
5253
queue workqueue.TypedRateLimitingInterface[string]
54+
mcaFilterFunc utils.ManagedClusterAddOnFilterFunc
5355
}
5456

5557
func NewAddonDeployController(
@@ -59,6 +61,7 @@ func NewAddonDeployController(
5961
addonInformers addoninformerv1alpha1.ManagedClusterAddOnInformer,
6062
workInformers workinformers.ManifestWorkInformer,
6163
agentAddons map[string]agent.AgentAddon,
64+
mcaFilterFunc utils.ManagedClusterAddOnFilterFunc,
6265
) factory.Controller {
6366
syncCtx := factory.NewSyncContext(controllerName)
6467

@@ -74,6 +77,7 @@ func NewAddonDeployController(
7477
managedClusterAddonIndexer: addonInformers.Informer().GetIndexer(),
7578
workIndexer: workInformers.Informer().GetIndexer(),
7679
agentAddons: agentAddons,
80+
mcaFilterFunc: mcaFilterFunc,
7781
}
7882

7983
c.setClusterInformerHandler(clusterInformers)
@@ -235,6 +239,10 @@ func (c *addonDeployController) sync(ctx context.Context, syncCtx factory.SyncCo
235239
return err
236240
}
237241

242+
if c.mcaFilterFunc != nil && !c.mcaFilterFunc(addon) {
243+
return nil
244+
}
245+
238246
// to deploy agents if there is RegistrationApplied condition.
239247
if meta.FindStatusCondition(addon.Status.Conditions, addonapiv1alpha1.ManagedClusterAddOnRegistrationApplied) == nil {
240248
return nil
@@ -307,7 +315,7 @@ func (c *addonDeployController) sync(ctx context.Context, syncCtx factory.SyncCo
307315
}
308316

309317
if err = c.updateAddon(ctx, addon, oldAddon); err != nil {
310-
return err
318+
return fmt.Errorf("failed to update addon %s/%s: %w", addon.Namespace, addon.Name, err)
311319
}
312320
return errorsutil.NewAggregate(errs)
313321
}
@@ -317,7 +325,10 @@ func (c *addonDeployController) sync(ctx context.Context, syncCtx factory.SyncCo
317325
func (c *addonDeployController) updateAddon(ctx context.Context, new, old *addonapiv1alpha1.ManagedClusterAddOn) error {
318326
if !equality.Semantic.DeepEqual(new.GetFinalizers(), old.GetFinalizers()) {
319327
_, err := c.addonClient.AddonV1alpha1().ManagedClusterAddOns(new.Namespace).Update(ctx, new, metav1.UpdateOptions{})
320-
return err
328+
if err != nil {
329+
return fmt.Errorf("failed to update addon finalizers: %w", err)
330+
}
331+
return nil
321332
}
322333

323334
addonPatcher := patcher.NewPatcher[
@@ -326,7 +337,10 @@ func (c *addonDeployController) updateAddon(ctx context.Context, new, old *addon
326337
addonapiv1alpha1.ManagedClusterAddOnStatus](c.addonClient.AddonV1alpha1().ManagedClusterAddOns(new.Namespace))
327338

328339
_, err := addonPatcher.PatchStatus(ctx, new, new.Status, old.Status)
329-
return err
340+
if err != nil {
341+
return fmt.Errorf("failed to update addon status: %w", err)
342+
}
343+
return nil
330344
}
331345

332346
func (c *addonDeployController) applyWork(ctx context.Context, appliedType string,

pkg/addonmanager/controllers/certificate/csrapprove.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
clusterv1 "open-cluster-management.io/api/cluster/v1"
2828

2929
"open-cluster-management.io/addon-framework/pkg/agent"
30+
"open-cluster-management.io/addon-framework/pkg/utils"
3031
"open-cluster-management.io/sdk-go/pkg/basecontroller/factory"
3132
)
3233

@@ -58,6 +59,7 @@ type csrApprovingController struct {
5859
managedClusterAddonLister addonlisterv1alpha1.ManagedClusterAddOnLister
5960
csrLister certificateslisters.CertificateSigningRequestLister
6061
csrListerBeta v1beta1certificateslisters.CertificateSigningRequestLister
62+
mcaFilterFunc utils.ManagedClusterAddOnFilterFunc
6163
}
6264

6365
// NewCSRApprovingController creates a new csr approving controller
@@ -68,6 +70,7 @@ func NewCSRApprovingController(
6870
csrBetaInformer v1beta1certificatesinformers.CertificateSigningRequestInformer,
6971
addonInformers addoninformerv1alpha1.ManagedClusterAddOnInformer,
7072
agentAddons map[string]agent.AgentAddon,
73+
mcaFilterFunc utils.ManagedClusterAddOnFilterFunc,
7174
) factory.Controller {
7275
if (csrV1Informer != nil) == (csrBetaInformer != nil) {
7376
klog.Fatalf("V1 and V1beta1 CSR informer cannot be present or absent at the same time")
@@ -77,6 +80,7 @@ func NewCSRApprovingController(
7780
agentAddons: agentAddons,
7881
managedClusterLister: clusterInformers.Lister(),
7982
managedClusterAddonLister: addonInformers.Lister(),
83+
mcaFilterFunc: mcaFilterFunc,
8084
}
8185
var csrInformer cache.SharedIndexInformer
8286
if csrV1Informer != nil {
@@ -162,6 +166,9 @@ func (c *csrApprovingController) sync(ctx context.Context, syncCtx factory.SyncC
162166
if err != nil {
163167
return err
164168
}
169+
if c.mcaFilterFunc != nil && !c.mcaFilterFunc(managedClusterAddon) {
170+
return nil
171+
}
165172

166173
if registrationOption.CSRApproveCheck == nil {
167174
klog.V(4).Infof("addon csr %q cannont be auto approved due to approve check not defined", csr.GetName())

pkg/addonmanager/controllers/certificate/csrsign.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
clusterv1 "open-cluster-management.io/api/cluster/v1"
2323

2424
"open-cluster-management.io/addon-framework/pkg/agent"
25+
"open-cluster-management.io/addon-framework/pkg/utils"
2526
"open-cluster-management.io/sdk-go/pkg/basecontroller/factory"
2627
)
2728

@@ -32,6 +33,7 @@ type csrSignController struct {
3233
managedClusterLister clusterlister.ManagedClusterLister
3334
managedClusterAddonLister addonlisterv1alpha1.ManagedClusterAddOnLister
3435
csrLister certificateslisters.CertificateSigningRequestLister
36+
mcaFilterFunc utils.ManagedClusterAddOnFilterFunc
3537
}
3638

3739
// NewCSRApprovingController creates a new csr approving controller
@@ -41,13 +43,15 @@ func NewCSRSignController(
4143
csrInformer certificatesinformers.CertificateSigningRequestInformer,
4244
addonInformers addoninformerv1alpha1.ManagedClusterAddOnInformer,
4345
agentAddons map[string]agent.AgentAddon,
46+
mcaFilterFunc utils.ManagedClusterAddOnFilterFunc,
4447
) factory.Controller {
4548
c := &csrSignController{
4649
kubeClient: kubeClient,
4750
agentAddons: agentAddons,
4851
managedClusterLister: clusterInformers.Lister(),
4952
managedClusterAddonLister: addonInformers.Lister(),
5053
csrLister: csrInformer.Lister(),
54+
mcaFilterFunc: mcaFilterFunc,
5155
}
5256
return factory.New().
5357
WithFilteredEventsInformersQueueKeysFunc(
@@ -131,6 +135,9 @@ func (c *csrSignController) sync(ctx context.Context, syncCtx factory.SyncContex
131135
if err != nil {
132136
return err
133137
}
138+
if c.mcaFilterFunc != nil && !c.mcaFilterFunc(addon) {
139+
return nil
140+
}
134141

135142
if registrationOption.CSRSign == nil {
136143
return nil

pkg/addonmanager/controllers/cmaconfig/controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ func (c *cmaConfigController) sync(ctx context.Context, syncCtx factory.SyncCont
145145
return err
146146
}
147147

148-
if !c.cmaFilterFunc(cma) {
148+
if c.cmaFilterFunc != nil && !c.cmaFilterFunc(cma) {
149149
return nil
150150
}
151151

pkg/addonmanager/controllers/registration/controller.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,22 @@ type addonRegistrationController struct {
2929
managedClusterLister clusterlister.ManagedClusterLister
3030
managedClusterAddonLister addonlisterv1alpha1.ManagedClusterAddOnLister
3131
agentAddons map[string]agent.AgentAddon
32+
mcaFilterFunc utils.ManagedClusterAddOnFilterFunc
3233
}
3334

3435
func NewAddonRegistrationController(
3536
addonClient addonv1alpha1client.Interface,
3637
clusterInformers clusterinformers.ManagedClusterInformer,
3738
addonInformers addoninformerv1alpha1.ManagedClusterAddOnInformer,
3839
agentAddons map[string]agent.AgentAddon,
40+
mcaFilterFunc utils.ManagedClusterAddOnFilterFunc,
3941
) factory.Controller {
4042
c := &addonRegistrationController{
4143
addonClient: addonClient,
4244
managedClusterLister: clusterInformers.Lister(),
4345
managedClusterAddonLister: addonInformers.Lister(),
4446
agentAddons: agentAddons,
47+
mcaFilterFunc: mcaFilterFunc,
4548
}
4649

4750
return factory.New().WithFilteredEventsInformersQueueKeysFunc(
@@ -94,6 +97,10 @@ func (c *addonRegistrationController) sync(ctx context.Context, syncCtx factory.
9497
return err
9598
}
9699

100+
if c.mcaFilterFunc != nil && !c.mcaFilterFunc(managedClusterAddon) {
101+
return nil
102+
}
103+
97104
managedClusterAddonCopy := managedClusterAddon.DeepCopy()
98105

99106
// wait until the mca's ownerref is set.

pkg/addonmanager/interface.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"k8s.io/client-go/dynamic/dynamicinformer"
77
kubeinformers "k8s.io/client-go/informers"
88
"open-cluster-management.io/addon-framework/pkg/agent"
9+
"open-cluster-management.io/addon-framework/pkg/utils"
910
addoninformers "open-cluster-management.io/api/client/addon/informers/externalversions"
1011
clusterv1informers "open-cluster-management.io/api/client/cluster/informers/externalversions"
1112
workclientset "open-cluster-management.io/api/client/work/clientset/versioned"
@@ -23,13 +24,19 @@ type BaseAddonManager interface {
2324
Trigger(clusterName, addonName string)
2425

2526
// StartWithInformers starts all registered addon agent with the given informers.
27+
// mcaFilterFunc is a filter function that controls which ManagedClusterAddOn objects should be processed.
28+
// It can be used to filter addons or wait until addons meet specific criteria before processing.
29+
// For example:
30+
// - Wait for addon.status.configReferences to contain templates before processing: utils.FilterTemplateBasedAddOns
2631
StartWithInformers(ctx context.Context,
2732
workClient workclientset.Interface,
2833
workInformers workv1informers.ManifestWorkInformer,
2934
kubeInformers kubeinformers.SharedInformerFactory,
3035
addonInformers addoninformers.SharedInformerFactory,
3136
clusterInformers clusterv1informers.SharedInformerFactory,
32-
dynamicInformers dynamicinformer.DynamicSharedInformerFactory) error
37+
dynamicInformers dynamicinformer.DynamicSharedInformerFactory,
38+
mcaFilterFunc utils.ManagedClusterAddOnFilterFunc,
39+
) error
3340
}
3441

3542
// AddonManager is the interface based on BaseAddonManager to initialize a manager on hub

pkg/addonmanager/manager.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
workv1informers "open-cluster-management.io/api/client/work/informers/externalversions"
2121

2222
"open-cluster-management.io/addon-framework/pkg/index"
23+
"open-cluster-management.io/addon-framework/pkg/utils"
2324
)
2425

2526
// addonManager is the implementation of AddonManager with the base implementation.
@@ -122,7 +123,8 @@ func (a *addonManager) Start(ctx context.Context) error {
122123
return err
123124
}
124125

125-
err = a.StartWithInformers(ctx, workClient, workInformers.Work().V1().ManifestWorks(), kubeInformers, addonInformers, clusterInformers, dynamicInformers)
126+
err = a.StartWithInformers(ctx, workClient, workInformers.Work().V1().ManifestWorks(), kubeInformers,
127+
addonInformers, clusterInformers, dynamicInformers, utils.AllowAllAddOns)
126128
if err != nil {
127129
return err
128130
}

0 commit comments

Comments
 (0)