github.com/cilium/cilium@v1.16.2/pkg/k8s/utils/listwatcher.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package utils 5 6 import ( 7 "context" 8 9 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 10 "k8s.io/apimachinery/pkg/fields" 11 k8sRuntime "k8s.io/apimachinery/pkg/runtime" 12 "k8s.io/apimachinery/pkg/watch" 13 "k8s.io/client-go/tools/cache" 14 ) 15 16 // typedListWatcher is a generic interface that all the typed k8s clients match. 17 type typedListWatcher[T k8sRuntime.Object] interface { 18 List(ctx context.Context, opts metav1.ListOptions) (T, error) 19 Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) 20 } 21 22 // genListWatcher takes a typed list watcher and implements cache.ListWatch 23 // using it. 24 type genListWatcher[T k8sRuntime.Object] struct { 25 lw typedListWatcher[T] 26 } 27 28 func (g *genListWatcher[T]) List(opts metav1.ListOptions) (k8sRuntime.Object, error) { 29 return g.lw.List(context.Background(), opts) 30 } 31 32 func (g *genListWatcher[T]) Watch(opts metav1.ListOptions) (watch.Interface, error) { 33 return g.lw.Watch(context.Background(), opts) 34 } 35 36 // ListerWatcherFromTyped adapts a typed k8s client to cache.ListerWatcher so it can be used 37 // with an informer. With this construction we can use fake clients for testing, 38 // which would not be possible if we used NewListWatchFromClient and RESTClient(). 39 func ListerWatcherFromTyped[T k8sRuntime.Object](lw typedListWatcher[T]) cache.ListerWatcher { 40 return &genListWatcher[T]{lw: lw} 41 } 42 43 type listWatcherWithModifier struct { 44 inner cache.ListerWatcher 45 optsModifier func(*metav1.ListOptions) 46 } 47 48 func (lw *listWatcherWithModifier) List(opts metav1.ListOptions) (k8sRuntime.Object, error) { 49 lw.optsModifier(&opts) 50 return lw.inner.List(opts) 51 } 52 53 func (lw *listWatcherWithModifier) Watch(opts metav1.ListOptions) (watch.Interface, error) { 54 lw.optsModifier(&opts) 55 return lw.inner.Watch(opts) 56 } 57 58 func ListerWatcherWithFields(lw cache.ListerWatcher, fieldSelector fields.Selector) cache.ListerWatcher { 59 return ListerWatcherWithModifier( 60 lw, 61 func(opts *metav1.ListOptions) { opts.FieldSelector = fieldSelector.String() }) 62 } 63 64 func ListerWatcherWithModifier(lw cache.ListerWatcher, optsModifier func(*metav1.ListOptions)) cache.ListerWatcher { 65 return &listWatcherWithModifier{ 66 inner: lw, 67 optsModifier: optsModifier, 68 } 69 } 70 71 func ListerWatcherWithModifiers(lw cache.ListerWatcher, opts ...func(*metav1.ListOptions)) cache.ListerWatcher { 72 for _, opt := range opts { 73 lw = ListerWatcherWithModifier(lw, opt) 74 } 75 return lw 76 }