@@ -37,6 +37,10 @@ type Factory struct {
37
37
// TODO(skuznets) we should be able to figure this out from the output dir, ideally
38
38
ClientsetPackagePath string
39
39
40
+ // SingleClusterClientPackagePath is the root directory under which single-cluster-aware clients exist.
41
+ // e.g. "k8s.io/client-go/kubernetes"
42
+ SingleClusterClientPackagePath string `marker:""`
43
+
40
44
// SingleClusterInformerPackagePath is the package under which the cluster-unaware listers are exposed.
41
45
// e.g. "k8s.io/client-go/informers"
42
46
SingleClusterInformerPackagePath string
@@ -52,6 +56,7 @@ func (f *Factory) WriteContent(w io.Writer) error {
52
56
"groups" : f .Groups ,
53
57
"packagePath" : f .PackagePath ,
54
58
"clientsetPackagePath" : f .ClientsetPackagePath ,
59
+ "singleClusterClientPackagePath" : f .SingleClusterClientPackagePath ,
55
60
"singleClusterInformerPackagePath" : f .SingleClusterInformerPackagePath ,
56
61
"useUpstreamInterfaces" : f .SingleClusterInformerPackagePath != "" ,
57
62
}
@@ -80,6 +85,9 @@ import (
80
85
"k8s.io/client-go/tools/cache"
81
86
82
87
clientset "{{.clientsetPackagePath}}"
88
+ {{if not .useUpstreamInterfaces -}}
89
+ scopedclientset "{{.singleClusterClientPackagePath}}"
90
+ {{end -}}
83
91
{{if .useUpstreamInterfaces -}}
84
92
upstreaminformers "{{.singleClusterInformerPackagePath}}"
85
93
{{end -}}
@@ -96,6 +104,9 @@ type SharedInformerOption func(*SharedInformerOptions) *SharedInformerOptions
96
104
type SharedInformerOptions struct {
97
105
customResync map[reflect.Type]time.Duration
98
106
tweakListOptions internalinterfaces.TweakListOptionsFunc
107
+ {{if not .useUpstreamInterfaces -}}
108
+ namespace string
109
+ {{end -}}
99
110
}
100
111
101
112
type sharedInformerFactory struct {
@@ -264,4 +275,136 @@ func (f *scopedDynamicSharedInformerFactory) ForResource(resource schema.GroupVe
264
275
func (f *scopedDynamicSharedInformerFactory) Start(stopCh <-chan struct{}) {
265
276
f.sharedInformerFactory.Start(stopCh)
266
277
}
278
+
279
+ {{if not .useUpstreamInterfaces -}}
280
+ // WithNamespace limits the SharedInformerFactory to the specified namespace.
281
+ func WithNamespace(namespace string) SharedInformerOption {
282
+ return func(opts *SharedInformerOptions) *SharedInformerOptions {
283
+ opts.namespace = namespace
284
+ return opts
285
+ }
286
+ }
287
+
288
+ type sharedScopedInformerFactory struct {
289
+ client scopedclientset.Interface
290
+ namespace string
291
+ tweakListOptions internalinterfaces.TweakListOptionsFunc
292
+ lock sync.Mutex
293
+ defaultResync time.Duration
294
+ customResync map[reflect.Type]time.Duration
295
+
296
+ informers map[reflect.Type]cache.SharedIndexInformer
297
+ // startedInformers is used for tracking which informers have been started.
298
+ // This allows Start() to be called multiple times safely.
299
+ startedInformers map[reflect.Type]bool
300
+ }
301
+
302
+ // NewSharedScopedInformerFactory constructs a new instance of SharedInformerFactory for some or all namespaces.
303
+ func NewSharedScopedInformerFactory(client scopedclientset.Interface, defaultResync time.Duration, namespace string) SharedScopedInformerFactory {
304
+ return NewSharedScopedInformerFactoryWithOptions(client, defaultResync, WithNamespace(namespace))
305
+ }
306
+
307
+ // NewSharedScopedInformerFactoryWithOptions constructs a new instance of a SharedInformerFactory with additional options.
308
+ func NewSharedScopedInformerFactoryWithOptions(client scopedclientset.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedScopedInformerFactory {
309
+ factory := &sharedScopedInformerFactory{
310
+ client: client,
311
+ defaultResync: defaultResync,
312
+ informers: make(map[reflect.Type]cache.SharedIndexInformer),
313
+ startedInformers: make(map[reflect.Type]bool),
314
+ customResync: make(map[reflect.Type]time.Duration),
315
+ }
316
+
317
+ opts := &SharedInformerOptions{
318
+ customResync: make(map[reflect.Type]time.Duration),
319
+ }
320
+
321
+ // Apply all options
322
+ for _, opt := range options {
323
+ opts = opt(opts)
324
+ }
325
+
326
+ // Forward options to the factory
327
+ factory.customResync = opts.customResync
328
+ factory.tweakListOptions = opts.tweakListOptions
329
+ factory.namespace = opts.namespace
330
+
331
+ return factory
332
+ }
333
+
334
+ // Start initializes all requested informers.
335
+ func (f *sharedScopedInformerFactory) Start(stopCh <-chan struct{}) {
336
+ f.lock.Lock()
337
+ defer f.lock.Unlock()
338
+
339
+ for informerType, informer := range f.informers {
340
+ if !f.startedInformers[informerType] {
341
+ go informer.Run(stopCh)
342
+ f.startedInformers[informerType] = true
343
+ }
344
+ }
345
+ }
346
+
347
+ // WaitForCacheSync waits for all started informers' cache were synced.
348
+ func (f *sharedScopedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool {
349
+ informers := func()map[reflect.Type]cache.SharedIndexInformer{
350
+ f.lock.Lock()
351
+ defer f.lock.Unlock()
352
+
353
+ informers := map[reflect.Type]cache.SharedIndexInformer{}
354
+ for informerType, informer := range f.informers {
355
+ if f.startedInformers[informerType] {
356
+ informers[informerType] = informer
357
+ }
358
+ }
359
+ return informers
360
+ }()
361
+
362
+ res := map[reflect.Type]bool{}
363
+ for informType, informer := range informers {
364
+ res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced)
365
+ }
366
+ return res
367
+ }
368
+
369
+ // InformerFor returns the SharedIndexInformer for obj using an internal
370
+ // client.
371
+ func (f *sharedScopedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewScopedInformerFunc) cache.SharedIndexInformer {
372
+ f.lock.Lock()
373
+ defer f.lock.Unlock()
374
+
375
+ informerType := reflect.TypeOf(obj)
376
+ informer, exists := f.informers[informerType]
377
+ if exists {
378
+ return informer
379
+ }
380
+
381
+ resyncPeriod, exists := f.customResync[informerType]
382
+ if !exists {
383
+ resyncPeriod = f.defaultResync
384
+ }
385
+
386
+ informer = newFunc(f.client, resyncPeriod)
387
+ f.informers[informerType] = informer
388
+
389
+ return informer
390
+ }
391
+
392
+ // SharedScopedInformerFactory provides shared informers for resources in all known
393
+ // API group versions, scoped to one workspace.
394
+ type SharedScopedInformerFactory interface {
395
+ internalinterfaces.SharedScopedInformerFactory
396
+ ForResource(resource schema.GroupVersionResource) (GenericInformer, error)
397
+ WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool
398
+
399
+ {{range .groups}} {{.GoName}}() {{.Group.PackageName}}informers.Interface
400
+ {{end -}}
401
+ }
402
+
403
+
404
+ {{range .groups}}
405
+ func (f *sharedScopedInformerFactory) {{.GoName}}() {{.Group.PackageName}}informers.Interface {
406
+ return {{.Group.PackageName}}informers.NewScoped(f, f.namespace, f.tweakListOptions)
407
+ }
408
+ {{end}}
409
+ {{end}}
267
410
`
0 commit comments