k8s.io/client-go@v0.22.2/metadata/metadatainformer/informer.go (about)

     1  /*
     2  Copyright 2018 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package metadatainformer
    18  
    19  import (
    20  	"context"
    21  	"sync"
    22  	"time"
    23  
    24  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    25  	"k8s.io/apimachinery/pkg/runtime"
    26  	"k8s.io/apimachinery/pkg/runtime/schema"
    27  	"k8s.io/apimachinery/pkg/watch"
    28  	"k8s.io/client-go/informers"
    29  	"k8s.io/client-go/metadata"
    30  	"k8s.io/client-go/metadata/metadatalister"
    31  	"k8s.io/client-go/tools/cache"
    32  )
    33  
    34  // NewSharedInformerFactory constructs a new instance of metadataSharedInformerFactory for all namespaces.
    35  func NewSharedInformerFactory(client metadata.Interface, defaultResync time.Duration) SharedInformerFactory {
    36  	return NewFilteredSharedInformerFactory(client, defaultResync, metav1.NamespaceAll, nil)
    37  }
    38  
    39  // NewFilteredSharedInformerFactory constructs a new instance of metadataSharedInformerFactory.
    40  // Listers obtained via this factory will be subject to the same filters as specified here.
    41  func NewFilteredSharedInformerFactory(client metadata.Interface, defaultResync time.Duration, namespace string, tweakListOptions TweakListOptionsFunc) SharedInformerFactory {
    42  	return &metadataSharedInformerFactory{
    43  		client:           client,
    44  		defaultResync:    defaultResync,
    45  		namespace:        namespace,
    46  		informers:        map[schema.GroupVersionResource]informers.GenericInformer{},
    47  		startedInformers: make(map[schema.GroupVersionResource]bool),
    48  		tweakListOptions: tweakListOptions,
    49  	}
    50  }
    51  
    52  type metadataSharedInformerFactory struct {
    53  	client        metadata.Interface
    54  	defaultResync time.Duration
    55  	namespace     string
    56  
    57  	lock      sync.Mutex
    58  	informers map[schema.GroupVersionResource]informers.GenericInformer
    59  	// startedInformers is used for tracking which informers have been started.
    60  	// This allows Start() to be called multiple times safely.
    61  	startedInformers map[schema.GroupVersionResource]bool
    62  	tweakListOptions TweakListOptionsFunc
    63  }
    64  
    65  var _ SharedInformerFactory = &metadataSharedInformerFactory{}
    66  
    67  func (f *metadataSharedInformerFactory) ForResource(gvr schema.GroupVersionResource) informers.GenericInformer {
    68  	f.lock.Lock()
    69  	defer f.lock.Unlock()
    70  
    71  	key := gvr
    72  	informer, exists := f.informers[key]
    73  	if exists {
    74  		return informer
    75  	}
    76  
    77  	informer = NewFilteredMetadataInformer(f.client, gvr, f.namespace, f.defaultResync, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
    78  	f.informers[key] = informer
    79  
    80  	return informer
    81  }
    82  
    83  // Start initializes all requested informers.
    84  func (f *metadataSharedInformerFactory) Start(stopCh <-chan struct{}) {
    85  	f.lock.Lock()
    86  	defer f.lock.Unlock()
    87  
    88  	for informerType, informer := range f.informers {
    89  		if !f.startedInformers[informerType] {
    90  			go informer.Informer().Run(stopCh)
    91  			f.startedInformers[informerType] = true
    92  		}
    93  	}
    94  }
    95  
    96  // WaitForCacheSync waits for all started informers' cache were synced.
    97  func (f *metadataSharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[schema.GroupVersionResource]bool {
    98  	informers := func() map[schema.GroupVersionResource]cache.SharedIndexInformer {
    99  		f.lock.Lock()
   100  		defer f.lock.Unlock()
   101  
   102  		informers := map[schema.GroupVersionResource]cache.SharedIndexInformer{}
   103  		for informerType, informer := range f.informers {
   104  			if f.startedInformers[informerType] {
   105  				informers[informerType] = informer.Informer()
   106  			}
   107  		}
   108  		return informers
   109  	}()
   110  
   111  	res := map[schema.GroupVersionResource]bool{}
   112  	for informType, informer := range informers {
   113  		res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced)
   114  	}
   115  	return res
   116  }
   117  
   118  // NewFilteredMetadataInformer constructs a new informer for a metadata type.
   119  func NewFilteredMetadataInformer(client metadata.Interface, gvr schema.GroupVersionResource, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions TweakListOptionsFunc) informers.GenericInformer {
   120  	return &metadataInformer{
   121  		gvr: gvr,
   122  		informer: cache.NewSharedIndexInformer(
   123  			&cache.ListWatch{
   124  				ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
   125  					if tweakListOptions != nil {
   126  						tweakListOptions(&options)
   127  					}
   128  					return client.Resource(gvr).Namespace(namespace).List(context.TODO(), options)
   129  				},
   130  				WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
   131  					if tweakListOptions != nil {
   132  						tweakListOptions(&options)
   133  					}
   134  					return client.Resource(gvr).Namespace(namespace).Watch(context.TODO(), options)
   135  				},
   136  			},
   137  			&metav1.PartialObjectMetadata{},
   138  			resyncPeriod,
   139  			indexers,
   140  		),
   141  	}
   142  }
   143  
   144  type metadataInformer struct {
   145  	informer cache.SharedIndexInformer
   146  	gvr      schema.GroupVersionResource
   147  }
   148  
   149  var _ informers.GenericInformer = &metadataInformer{}
   150  
   151  func (d *metadataInformer) Informer() cache.SharedIndexInformer {
   152  	return d.informer
   153  }
   154  
   155  func (d *metadataInformer) Lister() cache.GenericLister {
   156  	return metadatalister.NewRuntimeObjectShim(metadatalister.New(d.informer.GetIndexer(), d.gvr))
   157  }