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  }