Documentation ¶
Overview ¶
Package typed converts (dynamic) kube informers, listers, and indexers into typed counterparts via generics.
It can be useful to access the informer cache of one controller from another place, so that multiple controllers in the same binary don't need to open separate connections against the kube apiserver and maintain separate caches of the same objects.
The `typed` package also provides a `Registry` that synchronizes access to shared informer factories across multiple controllers.
Index ¶
- func IndexerListToTypedList[K runtime.Object](objs []any) []K
- func ObjToUnstructuredObj(typedObj runtime.Object) (*unstructured.Unstructured, error)
- func UnstructuredListToTypeList[K runtime.Object](objs []runtime.Object) ([]K, error)
- func UnstructuredObjToTypedObj[K runtime.Object](obj runtime.Object) (K, error)
- type FactoryKey
- type Indexer
- func (t Indexer[K]) Add(obj K) error
- func (t Indexer[K]) AddIndexers(newIndexers cache.Indexers) error
- func (t Indexer[K]) ByIndex(indexName, indexedValue string) ([]K, error)
- func (t Indexer[K]) Delete(obj K) error
- func (t Indexer[K]) Get(obj K) (item K, exists bool, err error)
- func (t Indexer[K]) GetByKey(key string) (item interface{}, exists bool, err error)
- func (t Indexer[K]) GetIndexers() cache.Indexers
- func (t Indexer[K]) IndexKeys(indexName, indexedValue string) ([]string, error)
- func (t Indexer[K]) List() []K
- func (t Indexer[K]) ListIndexFuncValues(indexName string) []string
- func (t Indexer[K]) ListKeys() []string
- func (t Indexer[K]) Update(obj K) error
- type Lister
- type NamespaceLister
- type Registry
- func (r *Registry) Add(key FactoryKey, factory dynamicinformer.DynamicSharedInformerFactory) error
- func (r *Registry) IndexerFor(key RegistryKey) cache.Indexer
- func (r *Registry) InformerFactoryFor(key RegistryKey) informers.GenericInformer
- func (r *Registry) InformerFor(key RegistryKey) cache.SharedIndexInformer
- func (r *Registry) ListerFor(key RegistryKey) cache.GenericLister
- func (r *Registry) MustNewFilteredDynamicSharedInformerFactory(key FactoryKey, client dynamic.Interface, defaultResync time.Duration, ...) dynamicinformer.DynamicSharedInformerFactory
- func (r *Registry) NewFilteredDynamicSharedInformerFactory(key FactoryKey, client dynamic.Interface, defaultResync time.Duration, ...) (dynamicinformer.DynamicSharedInformerFactory, error)
- func (r *Registry) Remove(key FactoryKey)
- type RegistryKey
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IndexerListToTypedList ¶
IndexerListToTypedList is a helper that converts a list of unstructured to a particular type.
func ObjToUnstructuredObj ¶ added in v0.9.0
func ObjToUnstructuredObj(typedObj runtime.Object) (*unstructured.Unstructured, error)
ObjToUnstructuredObj is a helper that converts a typed object to unstructured.
func UnstructuredListToTypeList ¶
UnstructuredListToTypeList is a helper that converts a list of unstructured to a particular type.
Types ¶
type FactoryKey ¶
type FactoryKey string
FactoryKey gives a name to a SharedInformerFactory. SharedInformerFactories can be instantiated against different kube apis or with different filters; the key should uniquely identify the factory in the registry.
For example, one factory might be watching all objects in a namespace, while another might be watching all objects in a cluster with a specific label.
It's a good idea to include the name of the controller doing initialization.
func NewFactoryKey ¶
func NewFactoryKey(controllerName, clusterName, id string) FactoryKey
NewFactoryKey generates a simple FactoryKey from an id for the controller, the cluster it watches, and an extra value.
type Indexer ¶
Indexer provides a generically typed interface for cache.Index It assumes the objects are unstructured.Unstructured, as you would get from a dynamic informer.
Example ¶
ctx, cancel := context.WithCancel(context.Background()) defer cancel() client := fake.NewSimpleDynamicClient(runtime.NewScheme()) informerFactory := dynamicinformer.NewDynamicSharedInformerFactory(client, 0) informerFactory.Start(ctx.Done()) informerFactory.WaitForCacheSync(ctx.Done()) indexer := NewIndexer[*corev1.Secret](informerFactory.ForResource(corev1.SchemeGroupVersion.WithResource("secrets")).Informer().GetIndexer()) secrets, _ := indexer.ByIndex("indexName", "indexValue") fmt.Printf("%T", secrets)
Output: []*v1.Secret
func IndexerFor ¶
func IndexerFor[K runtime.Object](r *Registry, key RegistryKey) *Indexer[K]
IndexerFor returns a typed Indexer from a Registry
Example ¶
ctx, cancel := context.WithCancel(context.Background()) defer cancel() secretGVR := corev1.SchemeGroupVersion.WithResource("secrets") secret := corev1.Secret{ObjectMeta: metav1.ObjectMeta{ Namespace: "example", Name: "mysecret", Labels: map[string]string{ "my-controller.com/related-to": "myobjecttype", }, }} scheme := runtime.NewScheme() if err := corev1.AddToScheme(scheme); err != nil { panic(err) } client := fake.NewSimpleDynamicClient(scheme, &secret) registry := NewRegistry() dependentObjectKey := NewFactoryKey("my-controller", "localCluster", "dependentObjects") informerFactory := registry.MustNewFilteredDynamicSharedInformerFactory( dependentObjectKey, client, 0, metav1.NamespaceAll, func(options *metav1.ListOptions) { options.LabelSelector = "my-controller.com/related-to=myobjecttype" }, ) // add an index that indexes all objects with a constant value const indexName = "ExampleIndex" const constantIndexValue = "indexVal" if err := informerFactory.ForResource(secretGVR).Informer().AddIndexers(map[string]cache.IndexFunc{ indexName: func(obj interface{}) ([]string, error) { return []string{constantIndexValue}, nil }, }); err != nil { panic(err) } informerFactory.Start(ctx.Done()) informerFactory.WaitForCacheSync(ctx.Done()) dependentSecretKey := NewRegistryKey(dependentObjectKey, secretGVR) matchingCachedSecrets, _ := IndexerFor[*corev1.Secret](registry, dependentSecretKey).ByIndex(indexName, constantIndexValue) fmt.Printf("%T %s/%s", matchingCachedSecrets, matchingCachedSecrets[0].GetNamespace(), matchingCachedSecrets[0].GetName())
Output: []*v1.Secret example/mysecret
func NewIndexer ¶
NewIndexer creates an Indexer from a cache.Indexer
func (Indexer[K]) GetIndexers ¶
func (Indexer[K]) ListIndexFuncValues ¶
type Lister ¶
Lister provides a generically typed interface for cache.GenericLister It assumes the objects are unstructured.Unstructured, as you would get from a dynamic informer.
Example ¶
ctx, cancel := context.WithCancel(context.Background()) defer cancel() client := fake.NewSimpleDynamicClient(runtime.NewScheme()) informerFactory := dynamicinformer.NewDynamicSharedInformerFactory(client, 0) informerFactory.Start(ctx.Done()) informerFactory.WaitForCacheSync(ctx.Done()) lister := NewLister[*corev1.Secret](informerFactory.ForResource(corev1.SchemeGroupVersion.WithResource("secrets")).Lister()) secret, _ := lister.ByNamespace("example").Get("mysecret") fmt.Printf("%T", secret)
Output: *v1.Secret
func ListerFor ¶
func ListerFor[K runtime.Object](r *Registry, key RegistryKey) *Lister[K]
ListerFor returns a typed Lister from a Registry
Example ¶
ctx, cancel := context.WithCancel(context.Background()) defer cancel() secretGVR := corev1.SchemeGroupVersion.WithResource("secrets") secret := corev1.Secret{ObjectMeta: metav1.ObjectMeta{ Namespace: "example", Name: "mysecret", Labels: map[string]string{ "my-controller.com/related-to": "myobjecttype", }, }} scheme := runtime.NewScheme() if err := corev1.AddToScheme(scheme); err != nil { panic(err) } client := fake.NewSimpleDynamicClient(scheme, &secret) registry := NewRegistry() dependentObjectKey := NewFactoryKey("my-controller", "localCluster", "dependentObjects") informerFactory := registry.MustNewFilteredDynamicSharedInformerFactory( dependentObjectKey, client, 0, metav1.NamespaceAll, func(options *metav1.ListOptions) { options.LabelSelector = "my-controller.com/related-to=myobjecttype" }, ) informerFactory.ForResource(secretGVR) informerFactory.Start(ctx.Done()) informerFactory.WaitForCacheSync(ctx.Done()) dependentSecretKey := NewRegistryKey(dependentObjectKey, secretGVR) cachedSecret, _ := ListerFor[*corev1.Secret](registry, dependentSecretKey).ByNamespace("example").Get("mysecret") fmt.Printf("%T %s/%s", cachedSecret, cachedSecret.GetNamespace(), cachedSecret.GetName())
Output: *v1.Secret example/mysecret
func NewLister ¶
func NewLister[K runtime.Object](lister cache.GenericLister) *Lister[K]
NewLister returns a Lister for a cache.GenericLister
func (Lister[K]) ByNamespace ¶
func (t Lister[K]) ByNamespace(namespace string) NamespaceLister[K]
type NamespaceLister ¶
NamespaceLister provides a generically typed interface for cache.GenericNamespaceLister. It assumes the objects are unstructured.Unstructured, as you would get from a dynamic informer.
func (NamespaceLister[K]) Get ¶
func (t NamespaceLister[K]) Get(name string) (K, error)
type Registry ¶
Registry is a threadsafe map of DynamicSharedInformerFactory By registering informer factories with the registry, handlers from other controllers can easily access the cached resources held by the informer.
Example ¶
ctx, cancel := context.WithCancel(context.Background()) defer cancel() secretGVR := corev1.SchemeGroupVersion.WithResource("secrets") secret := corev1.Secret{ObjectMeta: metav1.ObjectMeta{ Namespace: "example", Name: "mysecret", Labels: map[string]string{ "my-controller.com/related-to": "myobjecttype", }, }} scheme := runtime.NewScheme() if err := corev1.AddToScheme(scheme); err != nil { panic(err) } client := fake.NewSimpleDynamicClient(scheme, &secret) registry := NewRegistry() dependentObjectKey := NewFactoryKey("my-controller", "localCluster", "dependentObjects") informerFactory := registry.MustNewFilteredDynamicSharedInformerFactory( dependentObjectKey, client, 0, metav1.NamespaceAll, func(options *metav1.ListOptions) { options.LabelSelector = "my-controller.com/related-to=myobjecttype" }, ) informerFactory.ForResource(secretGVR) informerFactory.Start(ctx.Done()) informerFactory.WaitForCacheSync(ctx.Done()) dependentSecretKey := NewRegistryKey(dependentObjectKey, secretGVR) // the registry can be passed around, and other controllers can get direct // access to the cache's contents anotherController := func(r *Registry) { cachedSecret, _ := r.ListerFor(dependentSecretKey).ByNamespace("example").Get("mysecret") fmt.Printf("%s/%s", cachedSecret.(metav1.Object).GetNamespace(), cachedSecret.(metav1.Object).GetName()) } anotherController(registry)
Output: example/mysecret
func (*Registry) Add ¶
func (r *Registry) Add(key FactoryKey, factory dynamicinformer.DynamicSharedInformerFactory) error
Add adds a factory to the registry under the given FactoryKey
func (*Registry) IndexerFor ¶
func (r *Registry) IndexerFor(key RegistryKey) cache.Indexer
IndexerFor returns the GVR-specific Indexer from the Registry
func (*Registry) InformerFactoryFor ¶
func (r *Registry) InformerFactoryFor(key RegistryKey) informers.GenericInformer
InformerFactoryFor returns GVR-specific InformerFactory from the Registry.
func (*Registry) InformerFor ¶
func (r *Registry) InformerFor(key RegistryKey) cache.SharedIndexInformer
InformerFor returns the GVR-specific Informer from the Registry
func (*Registry) ListerFor ¶
func (r *Registry) ListerFor(key RegistryKey) cache.GenericLister
ListerFor returns the GVR-specific Lister from the Registry
func (*Registry) MustNewFilteredDynamicSharedInformerFactory ¶
func (r *Registry) MustNewFilteredDynamicSharedInformerFactory(key FactoryKey, client dynamic.Interface, defaultResync time.Duration, namespace string, tweakListOptions dynamicinformer.TweakListOptionsFunc) dynamicinformer.DynamicSharedInformerFactory
MustNewFilteredDynamicSharedInformerFactory creates a new SharedInformerFactory and registers it under the given FactoryKey. It panics if there is already an entry with that key.
func (*Registry) NewFilteredDynamicSharedInformerFactory ¶
func (r *Registry) NewFilteredDynamicSharedInformerFactory(key FactoryKey, client dynamic.Interface, defaultResync time.Duration, namespace string, tweakListOptions dynamicinformer.TweakListOptionsFunc) (dynamicinformer.DynamicSharedInformerFactory, error)
NewFilteredDynamicSharedInformerFactory creates a new SharedInformerFactory and registers it under the given FactoryKey
func (*Registry) Remove ¶ added in v0.2.0
func (r *Registry) Remove(key FactoryKey)
Remove removes a factory from the registry. Note that it does not stop any informers that were started via the factory; they should be stopped via context cancellation.
type RegistryKey ¶
type RegistryKey struct { schema.GroupVersionResource FactoryKey }
RegistryKey identifies a specific GVR within a factory provided by a Registry
func NewRegistryKey ¶
func NewRegistryKey(key FactoryKey, gvr schema.GroupVersionResource) RegistryKey
NewRegistryKey creates a RegistryKey from a FactoryKey
func (RegistryKey) String ¶
func (k RegistryKey) String() string