Skip to content

Commit a7f102a

Browse files
operators/olm: record and expose infromers (#3005)
Plugins should re-use informers that the host started, since there's no need to double the number of watches and caches we're doing to reconcile the same set of objects in one process. Signed-off-by: Steve Kuznetsov <[email protected]>
1 parent 2c3434a commit a7f102a

File tree

2 files changed

+62
-3
lines changed

2 files changed

+62
-3
lines changed

pkg/controller/operators/olm/operator.go

+29-3
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ type Operator struct {
9797
serviceAccountQuerier *scoped.UserDefinedServiceAccountQuerier
9898
clientFactory clients.Factory
9999
plugins []plugins.OperatorPlugin
100+
informersByNamespace map[string]*plugins.Informers
101+
}
102+
103+
func (a *Operator) Informers() map[string]*plugins.Informers {
104+
return a.informersByNamespace
100105
}
101106

102107
func NewOperator(ctx context.Context, options ...OperatorOption) (*Operator, error) {
@@ -159,9 +164,11 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
159164
protectedCopiedCSVNamespaces: config.protectedCopiedCSVNamespaces,
160165
}
161166

167+
informersByNamespace := map[string]*plugins.Informers{}
162168
// Set up syncing for namespace-scoped resources
163169
k8sSyncer := queueinformer.LegacySyncHandler(op.syncObject).ToSyncerWithDelete(op.handleDeletion)
164170
for _, namespace := range config.watchedNamespaces {
171+
informersByNamespace[namespace] = &plugins.Informers{}
165172
// Wire CSVs
166173
csvInformer := externalversions.NewSharedInformerFactoryWithOptions(
167174
op.client,
@@ -171,6 +178,7 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
171178
options.LabelSelector = fmt.Sprintf("!%s", v1alpha1.CopiedLabelKey)
172179
}),
173180
).Operators().V1alpha1().ClusterServiceVersions()
181+
informersByNamespace[namespace].CSVInformer = csvInformer
174182
op.lister.OperatorsV1alpha1().RegisterClusterServiceVersionLister(namespace, csvInformer.Lister())
175183
csvQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), fmt.Sprintf("%s/csv", namespace))
176184
op.csvQueueSet.Set(namespace, csvQueue)
@@ -225,6 +233,8 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
225233
},
226234
).Informer()
227235
op.copiedCSVLister = metadatalister.New(copiedCSVInformer.GetIndexer(), gvr)
236+
informersByNamespace[namespace].CopiedCSVInformer = copiedCSVInformer
237+
informersByNamespace[namespace].CopiedCSVLister = op.copiedCSVLister
228238

229239
// Register separate queue for gcing copied csvs
230240
copiedCSVGCQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), fmt.Sprintf("%s/csv-gc", namespace))
@@ -247,6 +257,7 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
247257
// Wire OperatorGroup reconciliation
248258
extInformerFactory := externalversions.NewSharedInformerFactoryWithOptions(op.client, config.resyncPeriod(), externalversions.WithNamespace(namespace))
249259
operatorGroupInformer := extInformerFactory.Operators().V1().OperatorGroups()
260+
informersByNamespace[namespace].OperatorGroupInformer = operatorGroupInformer
250261
op.lister.OperatorsV1().RegisterOperatorGroupLister(namespace, operatorGroupInformer.Lister())
251262
ogQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), fmt.Sprintf("%s/og", namespace))
252263
op.ogQueueSet.Set(namespace, ogQueue)
@@ -266,6 +277,7 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
266277

267278
// Register OperatorCondition QueueInformer
268279
opConditionInformer := extInformerFactory.Operators().V2().OperatorConditions()
280+
informersByNamespace[namespace].OperatorConditionInformer = opConditionInformer
269281
op.lister.OperatorsV2().RegisterOperatorConditionLister(namespace, opConditionInformer.Lister())
270282
opConditionQueueInformer, err := queueinformer.NewQueueInformer(
271283
ctx,
@@ -281,6 +293,7 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
281293
}
282294

283295
subInformer := extInformerFactory.Operators().V1alpha1().Subscriptions()
296+
informersByNamespace[namespace].SubscriptionInformer = subInformer
284297
op.lister.OperatorsV1alpha1().RegisterSubscriptionLister(namespace, subInformer.Lister())
285298
subQueueInformer, err := queueinformer.NewQueueInformer(
286299
ctx,
@@ -298,6 +311,7 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
298311
// Wire Deployments
299312
k8sInformerFactory := informers.NewSharedInformerFactoryWithOptions(op.opClient.KubernetesInterface(), config.resyncPeriod(), informers.WithNamespace(namespace))
300313
depInformer := k8sInformerFactory.Apps().V1().Deployments()
314+
informersByNamespace[namespace].DeploymentInformer = depInformer
301315
op.lister.AppsV1().RegisterDeploymentLister(namespace, depInformer.Lister())
302316
depQueueInformer, err := queueinformer.NewQueueInformer(
303317
ctx,
@@ -314,6 +328,7 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
314328

315329
// Set up RBAC informers
316330
roleInformer := k8sInformerFactory.Rbac().V1().Roles()
331+
informersByNamespace[namespace].RoleInformer = roleInformer
317332
op.lister.RbacV1().RegisterRoleLister(namespace, roleInformer.Lister())
318333
roleQueueInformer, err := queueinformer.NewQueueInformer(
319334
ctx,
@@ -329,6 +344,7 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
329344
}
330345

331346
roleBindingInformer := k8sInformerFactory.Rbac().V1().RoleBindings()
347+
informersByNamespace[namespace].RoleBindingInformer = roleBindingInformer
332348
op.lister.RbacV1().RegisterRoleBindingLister(namespace, roleBindingInformer.Lister())
333349
roleBindingQueueInformer, err := queueinformer.NewQueueInformer(
334350
ctx,
@@ -347,6 +363,7 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
347363
secretInformer := informers.NewSharedInformerFactoryWithOptions(op.opClient.KubernetesInterface(), config.resyncPeriod(), informers.WithNamespace(namespace), informers.WithTweakListOptions(func(options *metav1.ListOptions) {
348364
options.LabelSelector = labels.SelectorFromValidatedSet(map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}).String()
349365
})).Core().V1().Secrets()
366+
informersByNamespace[namespace].SecretInformer = secretInformer
350367
op.lister.CoreV1().RegisterSecretLister(namespace, secretInformer.Lister())
351368
secretQueueInformer, err := queueinformer.NewQueueInformer(
352369
ctx,
@@ -363,6 +380,7 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
363380

364381
// Register Service QueueInformer
365382
serviceInformer := k8sInformerFactory.Core().V1().Services()
383+
informersByNamespace[namespace].ServiceInformer = serviceInformer
366384
op.lister.CoreV1().RegisterServiceLister(namespace, serviceInformer.Lister())
367385
serviceQueueInformer, err := queueinformer.NewQueueInformer(
368386
ctx,
@@ -379,6 +397,7 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
379397

380398
// Register ServiceAccount QueueInformer
381399
serviceAccountInformer := k8sInformerFactory.Core().V1().ServiceAccounts()
400+
informersByNamespace[namespace].ServiceAccountInformer = serviceAccountInformer
382401
op.lister.CoreV1().RegisterServiceAccountLister(metav1.NamespaceAll, serviceAccountInformer.Lister())
383402
serviceAccountQueueInformer, err := queueinformer.NewQueueInformer(
384403
ctx,
@@ -429,13 +448,14 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
429448
olmConfigInformer := externalversions.NewSharedInformerFactoryWithOptions(
430449
op.client,
431450
config.resyncPeriod(),
432-
).Operators().V1().OLMConfigs().Informer()
451+
).Operators().V1().OLMConfigs()
452+
informersByNamespace[metav1.NamespaceAll].OLMConfigInformer = olmConfigInformer
433453
olmConfigQueueInformer, err := queueinformer.NewQueueInformer(
434454
ctx,
435-
queueinformer.WithInformer(olmConfigInformer),
455+
queueinformer.WithInformer(olmConfigInformer.Informer()),
436456
queueinformer.WithLogger(op.logger),
437457
queueinformer.WithQueue(op.olmConfigQueue),
438-
queueinformer.WithIndexer(olmConfigInformer.GetIndexer()),
458+
queueinformer.WithIndexer(olmConfigInformer.Informer().GetIndexer()),
439459
queueinformer.WithSyncer(queueinformer.LegacySyncHandler(op.syncOLMConfig).ToSyncer()),
440460
)
441461
if err != nil {
@@ -447,6 +467,7 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
447467

448468
k8sInformerFactory := informers.NewSharedInformerFactory(op.opClient.KubernetesInterface(), config.resyncPeriod())
449469
clusterRoleInformer := k8sInformerFactory.Rbac().V1().ClusterRoles()
470+
informersByNamespace[metav1.NamespaceAll].ClusterRoleInformer = clusterRoleInformer
450471
op.lister.RbacV1().RegisterClusterRoleLister(clusterRoleInformer.Lister())
451472
clusterRoleQueueInformer, err := queueinformer.NewQueueInformer(
452473
ctx,
@@ -462,6 +483,7 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
462483
}
463484

464485
clusterRoleBindingInformer := k8sInformerFactory.Rbac().V1().ClusterRoleBindings()
486+
informersByNamespace[metav1.NamespaceAll].ClusterRoleBindingInformer = clusterRoleBindingInformer
465487
op.lister.RbacV1().RegisterClusterRoleBindingLister(clusterRoleBindingInformer.Lister())
466488
clusterRoleBindingQueueInformer, err := queueinformer.NewQueueInformer(
467489
ctx,
@@ -478,6 +500,7 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
478500

479501
// register namespace queueinformer
480502
namespaceInformer := k8sInformerFactory.Core().V1().Namespaces()
503+
informersByNamespace[metav1.NamespaceAll].NamespaceInformer = namespaceInformer
481504
op.lister.CoreV1().RegisterNamespaceLister(namespaceInformer.Lister())
482505
op.nsQueueSet = workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "resolver")
483506
namespaceInformer.Informer().AddEventHandler(
@@ -502,6 +525,7 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
502525

503526
// Register APIService QueueInformer
504527
apiServiceInformer := kagg.NewSharedInformerFactory(op.opClient.ApiregistrationV1Interface(), config.resyncPeriod()).Apiregistration().V1().APIServices()
528+
informersByNamespace[metav1.NamespaceAll].APIServiceInformer = apiServiceInformer
505529
op.lister.APIRegistrationV1().RegisterAPIServiceLister(apiServiceInformer.Lister())
506530
apiServiceQueueInformer, err := queueinformer.NewQueueInformer(
507531
ctx,
@@ -519,6 +543,7 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
519543

520544
// Register CustomResourceDefinition QueueInformer
521545
crdInformer := extinf.NewSharedInformerFactory(op.opClient.ApiextensionsInterface(), config.resyncPeriod()).Apiextensions().V1().CustomResourceDefinitions()
546+
informersByNamespace[metav1.NamespaceAll].CRDInformer = crdInformer
522547
op.lister.APIExtensionsV1().RegisterCustomResourceDefinitionLister(crdInformer.Lister())
523548
crdQueueInformer, err := queueinformer.NewQueueInformer(
524549
ctx,
@@ -572,6 +597,7 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
572597
op.resolver = &install.StrategyResolver{
573598
OverridesBuilderFunc: overridesBuilderFunc.GetDeploymentInitializer,
574599
}
600+
op.informersByNamespace = informersByNamespace
575601

576602
// initialize plugins
577603
for _, makePlugIn := range operatorPlugInFactoryFuncs {

pkg/controller/operators/olm/plugins/operator_plugin.go

+33
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,48 @@ import (
55
"time"
66

77
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned"
8+
operatorsv1informers "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1"
9+
operatorsv1alpha1informers "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1"
10+
operatorsv2informers "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v2"
811
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
912
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer"
1013
"github.com/sirupsen/logrus"
14+
extensionsv1informers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1"
15+
appsv1informers "k8s.io/client-go/informers/apps/v1"
16+
corev1informers "k8s.io/client-go/informers/core/v1"
17+
rbacv1informers "k8s.io/client-go/informers/rbac/v1"
18+
"k8s.io/client-go/metadata/metadatalister"
19+
"k8s.io/client-go/tools/cache"
20+
apiregistrationv1informers "k8s.io/kube-aggregator/pkg/client/informers/externalversions/apiregistration/v1"
1121
)
1222

1323
// HostOperator is an extensible and observable operator that hosts the plug-in, i.e. which the plug-in is extending
1424
type HostOperator interface {
1525
queueinformer.ObservableOperator
1626
queueinformer.ExtensibleOperator
27+
Informers() map[string]*Informers
28+
}
29+
30+
// Informers exposes informer caches that the host operator has already started, for re-use by plugins.
31+
type Informers struct {
32+
CSVInformer operatorsv1alpha1informers.ClusterServiceVersionInformer
33+
CopiedCSVInformer cache.SharedIndexInformer
34+
CopiedCSVLister metadatalister.Lister
35+
OperatorGroupInformer operatorsv1informers.OperatorGroupInformer
36+
OperatorConditionInformer operatorsv2informers.OperatorConditionInformer
37+
SubscriptionInformer operatorsv1alpha1informers.SubscriptionInformer
38+
DeploymentInformer appsv1informers.DeploymentInformer
39+
RoleInformer rbacv1informers.RoleInformer
40+
RoleBindingInformer rbacv1informers.RoleBindingInformer
41+
SecretInformer corev1informers.SecretInformer
42+
ServiceInformer corev1informers.ServiceInformer
43+
ServiceAccountInformer corev1informers.ServiceAccountInformer
44+
OLMConfigInformer operatorsv1informers.OLMConfigInformer
45+
ClusterRoleInformer rbacv1informers.ClusterRoleInformer
46+
ClusterRoleBindingInformer rbacv1informers.ClusterRoleBindingInformer
47+
NamespaceInformer corev1informers.NamespaceInformer
48+
APIServiceInformer apiregistrationv1informers.APIServiceInformer
49+
CRDInformer extensionsv1informers.CustomResourceDefinitionInformer
1750
}
1851

1952
// OperatorConfig gives access to required configuration from the host operator

0 commit comments

Comments
 (0)