mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 10:33:35 +00:00
rebase: Bump sigs.k8s.io/controller-runtime from 0.15.1 to 0.16.0
Bumps [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) from 0.15.1 to 0.16.0. - [Release notes](https://github.com/kubernetes-sigs/controller-runtime/releases) - [Changelog](https://github.com/kubernetes-sigs/controller-runtime/blob/main/RELEASE.md) - [Commits](https://github.com/kubernetes-sigs/controller-runtime/compare/v0.15.1...v0.16.0) --- updated-dependencies: - dependency-name: sigs.k8s.io/controller-runtime dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
committed by
mergify[bot]
parent
97d9f701ec
commit
a51516501c
337
vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go
generated
vendored
337
vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go
generated
vendored
@ -22,8 +22,8 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@ -31,6 +31,7 @@ import (
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
toolscache "k8s.io/client-go/tools/cache"
|
||||
"k8s.io/utils/pointer"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/cache/internal"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
@ -43,14 +44,28 @@ var (
|
||||
defaultSyncPeriod = 10 * time.Hour
|
||||
)
|
||||
|
||||
// InformerGetOptions defines the behavior of how informers are retrieved.
|
||||
type InformerGetOptions internal.GetOptions
|
||||
|
||||
// InformerGetOption defines an option that alters the behavior of how informers are retrieved.
|
||||
type InformerGetOption func(*InformerGetOptions)
|
||||
|
||||
// BlockUntilSynced determines whether a get request for an informer should block
|
||||
// until the informer's cache has synced.
|
||||
func BlockUntilSynced(shouldBlock bool) InformerGetOption {
|
||||
return func(opts *InformerGetOptions) {
|
||||
opts.BlockUntilSynced = &shouldBlock
|
||||
}
|
||||
}
|
||||
|
||||
// Cache knows how to load Kubernetes objects, fetch informers to request
|
||||
// to receive events for Kubernetes objects (at a low-level),
|
||||
// and add indices to fields on the objects stored in the cache.
|
||||
type Cache interface {
|
||||
// Cache acts as a client to objects stored in the cache.
|
||||
// Reader acts as a client to objects stored in the cache.
|
||||
client.Reader
|
||||
|
||||
// Cache loads informers and adds field indices.
|
||||
// Informers loads informers and adds field indices.
|
||||
Informers
|
||||
}
|
||||
|
||||
@ -60,49 +75,53 @@ type Cache interface {
|
||||
type Informers interface {
|
||||
// GetInformer fetches or constructs an informer for the given object that corresponds to a single
|
||||
// API kind and resource.
|
||||
GetInformer(ctx context.Context, obj client.Object) (Informer, error)
|
||||
GetInformer(ctx context.Context, obj client.Object, opts ...InformerGetOption) (Informer, error)
|
||||
|
||||
// GetInformerForKind is similar to GetInformer, except that it takes a group-version-kind, instead
|
||||
// of the underlying object.
|
||||
GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind) (Informer, error)
|
||||
GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind, opts ...InformerGetOption) (Informer, error)
|
||||
|
||||
// Start runs all the informers known to this cache until the context is closed.
|
||||
// It blocks.
|
||||
Start(ctx context.Context) error
|
||||
|
||||
// WaitForCacheSync waits for all the caches to sync. Returns false if it could not sync a cache.
|
||||
// WaitForCacheSync waits for all the caches to sync. Returns false if it could not sync a cache.
|
||||
WaitForCacheSync(ctx context.Context) bool
|
||||
|
||||
// Informers knows how to add indices to the caches (informers) that it manages.
|
||||
// FieldIndexer adds indices to the managed informers.
|
||||
client.FieldIndexer
|
||||
}
|
||||
|
||||
// Informer - informer allows you interact with the underlying informer.
|
||||
// Informer allows you to interact with the underlying informer.
|
||||
type Informer interface {
|
||||
// AddEventHandler adds an event handler to the shared informer using the shared informer's resync
|
||||
// period. Events to a single handler are delivered sequentially, but there is no coordination
|
||||
// period. Events to a single handler are delivered sequentially, but there is no coordination
|
||||
// between different handlers.
|
||||
// It returns a registration handle for the handler that can be used to remove
|
||||
// the handler again.
|
||||
// the handler again and an error if the handler cannot be added.
|
||||
AddEventHandler(handler toolscache.ResourceEventHandler) (toolscache.ResourceEventHandlerRegistration, error)
|
||||
|
||||
// AddEventHandlerWithResyncPeriod adds an event handler to the shared informer using the
|
||||
// specified resync period. Events to a single handler are delivered sequentially, but there is
|
||||
// specified resync period. Events to a single handler are delivered sequentially, but there is
|
||||
// no coordination between different handlers.
|
||||
// It returns a registration handle for the handler that can be used to remove
|
||||
// the handler again and an error if the handler cannot be added.
|
||||
AddEventHandlerWithResyncPeriod(handler toolscache.ResourceEventHandler, resyncPeriod time.Duration) (toolscache.ResourceEventHandlerRegistration, error)
|
||||
// RemoveEventHandler removes a formerly added event handler given by
|
||||
|
||||
// RemoveEventHandler removes a previously added event handler given by
|
||||
// its registration handle.
|
||||
// This function is guaranteed to be idempotent, and thread-safe.
|
||||
// This function is guaranteed to be idempotent and thread-safe.
|
||||
RemoveEventHandler(handle toolscache.ResourceEventHandlerRegistration) error
|
||||
// AddIndexers adds more indexers to this store. If you call this after you already have data
|
||||
|
||||
// AddIndexers adds indexers to this store. If this is called after there is already data
|
||||
// in the store, the results are undefined.
|
||||
AddIndexers(indexers toolscache.Indexers) error
|
||||
|
||||
// HasSynced return true if the informers underlying store has synced.
|
||||
HasSynced() bool
|
||||
}
|
||||
|
||||
// Options are the optional arguments for creating a new InformersMap object.
|
||||
// Options are the optional arguments for creating a new Cache object.
|
||||
type Options struct {
|
||||
// HTTPClient is the http client to use for the REST client
|
||||
HTTPClient *http.Client
|
||||
@ -140,45 +159,80 @@ type Options struct {
|
||||
// instead of `reconcile.Result{}`.
|
||||
SyncPeriod *time.Duration
|
||||
|
||||
// Namespaces restricts the cache's ListWatch to the desired namespaces
|
||||
// Default watches all namespaces
|
||||
Namespaces []string
|
||||
// ReaderFailOnMissingInformer configures the cache to return a ErrResourceNotCached error when a user
|
||||
// requests, using Get() and List(), a resource the cache does not already have an informer for.
|
||||
//
|
||||
// This error is distinct from an errors.NotFound.
|
||||
//
|
||||
// Defaults to false, which means that the cache will start a new informer
|
||||
// for every new requested resource.
|
||||
ReaderFailOnMissingInformer bool
|
||||
|
||||
// DefaultLabelSelector will be used as a label selectors for all object types
|
||||
// unless they have a more specific selector set in ByObject.
|
||||
// DefaultNamespaces maps namespace names to cache configs. If set, only
|
||||
// the namespaces in here will be watched and it will by used to default
|
||||
// ByObject.Namespaces for all objects if that is nil.
|
||||
//
|
||||
// The options in the Config that are nil will be defaulted from
|
||||
// the respective Default* settings.
|
||||
DefaultNamespaces map[string]Config
|
||||
|
||||
// DefaultLabelSelector will be used as a label selector for all objects
|
||||
// unless there is already one set in ByObject or DefaultNamespaces.
|
||||
DefaultLabelSelector labels.Selector
|
||||
|
||||
// DefaultFieldSelector will be used as a field selectors for all object types
|
||||
// unless they have a more specific selector set in ByObject.
|
||||
// DefaultFieldSelector will be used as a field selector for all object types
|
||||
// unless there is already one set in ByObject or DefaultNamespaces.
|
||||
DefaultFieldSelector fields.Selector
|
||||
|
||||
// DefaultTransform will be used as transform for all object types
|
||||
// unless they have a more specific transform set in ByObject.
|
||||
// unless there is already one set in ByObject or DefaultNamespaces.
|
||||
DefaultTransform toolscache.TransformFunc
|
||||
|
||||
// ByObject restricts the cache's ListWatch to the desired fields per GVK at the specified object.
|
||||
ByObject map[client.Object]ByObject
|
||||
|
||||
// UnsafeDisableDeepCopy indicates not to deep copy objects during get or
|
||||
// list objects for EVERY object.
|
||||
// DefaultUnsafeDisableDeepCopy is the default for UnsafeDisableDeepCopy
|
||||
// for everything that doesn't specify this.
|
||||
//
|
||||
// Be very careful with this, when enabled you must DeepCopy any object before mutating it,
|
||||
// otherwise you will mutate the object in the cache.
|
||||
//
|
||||
// This is a global setting for all objects, and can be overridden by the ByObject setting.
|
||||
UnsafeDisableDeepCopy *bool
|
||||
// This will be used for all object types, unless it is set in ByObject or
|
||||
// DefaultNamespaces.
|
||||
DefaultUnsafeDisableDeepCopy *bool
|
||||
|
||||
// ByObject restricts the cache's ListWatch to the desired fields per GVK at the specified object.
|
||||
// object, this will fall through to Default* settings.
|
||||
ByObject map[client.Object]ByObject
|
||||
|
||||
// newInformer allows overriding of NewSharedIndexInformer for testing.
|
||||
newInformer *func(toolscache.ListerWatcher, runtime.Object, time.Duration, toolscache.Indexers) toolscache.SharedIndexInformer
|
||||
}
|
||||
|
||||
// ByObject offers more fine-grained control over the cache's ListWatch by object.
|
||||
type ByObject struct {
|
||||
// Namespaces maps a namespace name to cache configs. If set, only the
|
||||
// namespaces in this map will be cached.
|
||||
//
|
||||
// Settings in the map value that are unset will be defaulted.
|
||||
// Use an empty value for the specific setting to prevent that.
|
||||
//
|
||||
// A nil map allows to default this to the cache's DefaultNamespaces setting.
|
||||
// An empty map prevents this and means that all namespaces will be cached.
|
||||
//
|
||||
// The defaulting follows the following precedence order:
|
||||
// 1. ByObject
|
||||
// 2. DefaultNamespaces[namespace]
|
||||
// 3. Default*
|
||||
//
|
||||
// This must be unset for cluster-scoped objects.
|
||||
Namespaces map[string]Config
|
||||
|
||||
// Label represents a label selector for the object.
|
||||
Label labels.Selector
|
||||
|
||||
// Field represents a field selector for the object.
|
||||
Field fields.Selector
|
||||
|
||||
// Transform is a map from objects to transformer functions which
|
||||
// get applied when objects of the transformation are about to be committed
|
||||
// to cache.
|
||||
// Transform is a transformer function for the object which gets applied
|
||||
// when objects of the transformation are about to be committed to the cache.
|
||||
//
|
||||
// This function is called both for new objects to enter the cache,
|
||||
// and for updated objects.
|
||||
@ -191,48 +245,120 @@ type ByObject struct {
|
||||
UnsafeDisableDeepCopy *bool
|
||||
}
|
||||
|
||||
// Config describes all potential options for a given watch.
|
||||
type Config struct {
|
||||
// LabelSelector specifies a label selector. A nil value allows to
|
||||
// default this.
|
||||
//
|
||||
// Set to labels.Everything() if you don't want this defaulted.
|
||||
LabelSelector labels.Selector
|
||||
|
||||
// FieldSelector specifics a field selector. A nil value allows to
|
||||
// default this.
|
||||
//
|
||||
// Set to fields.Everything() if you don't want this defaulted.
|
||||
FieldSelector fields.Selector
|
||||
|
||||
// Transform specifies a transform func. A nil value allows to default
|
||||
// this.
|
||||
//
|
||||
// Set to an empty func to prevent this:
|
||||
// func(in interface{}) (interface{}, error) { return in, nil }
|
||||
Transform toolscache.TransformFunc
|
||||
|
||||
// UnsafeDisableDeepCopy specifies if List and Get requests against the
|
||||
// cache should not DeepCopy. A nil value allows to default this.
|
||||
UnsafeDisableDeepCopy *bool
|
||||
}
|
||||
|
||||
// NewCacheFunc - Function for creating a new cache from the options and a rest config.
|
||||
type NewCacheFunc func(config *rest.Config, opts Options) (Cache, error)
|
||||
|
||||
// New initializes and returns a new Cache.
|
||||
func New(config *rest.Config, opts Options) (Cache, error) {
|
||||
if len(opts.Namespaces) == 0 {
|
||||
opts.Namespaces = []string{metav1.NamespaceAll}
|
||||
}
|
||||
if len(opts.Namespaces) > 1 {
|
||||
return newMultiNamespaceCache(config, opts)
|
||||
}
|
||||
|
||||
opts, err := defaultOpts(config, opts)
|
||||
func New(cfg *rest.Config, opts Options) (Cache, error) {
|
||||
opts, err := defaultOpts(cfg, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
byGVK, err := convertToInformerOptsByGVK(opts.ByObject, opts.Scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
newCacheFunc := newCache(cfg, opts)
|
||||
|
||||
var defaultCache Cache
|
||||
if len(opts.DefaultNamespaces) > 0 {
|
||||
defaultConfig := optionDefaultsToConfig(&opts)
|
||||
defaultCache = newMultiNamespaceCache(newCacheFunc, opts.Scheme, opts.Mapper, opts.DefaultNamespaces, &defaultConfig)
|
||||
} else {
|
||||
defaultCache = newCacheFunc(optionDefaultsToConfig(&opts), corev1.NamespaceAll)
|
||||
}
|
||||
// Set the default selector and transform.
|
||||
byGVK[schema.GroupVersionKind{}] = internal.InformersOptsByGVK{
|
||||
Selector: internal.Selector{
|
||||
Label: opts.DefaultLabelSelector,
|
||||
Field: opts.DefaultFieldSelector,
|
||||
},
|
||||
|
||||
if len(opts.ByObject) == 0 {
|
||||
return defaultCache, nil
|
||||
}
|
||||
|
||||
delegating := &delegatingByGVKCache{
|
||||
scheme: opts.Scheme,
|
||||
caches: make(map[schema.GroupVersionKind]Cache, len(opts.ByObject)),
|
||||
defaultCache: defaultCache,
|
||||
}
|
||||
|
||||
for obj, config := range opts.ByObject {
|
||||
gvk, err := apiutil.GVKForObject(obj, opts.Scheme)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get GVK for type %T: %w", obj, err)
|
||||
}
|
||||
var cache Cache
|
||||
if len(config.Namespaces) > 0 {
|
||||
cache = newMultiNamespaceCache(newCacheFunc, opts.Scheme, opts.Mapper, config.Namespaces, nil)
|
||||
} else {
|
||||
cache = newCacheFunc(byObjectToConfig(config), corev1.NamespaceAll)
|
||||
}
|
||||
delegating.caches[gvk] = cache
|
||||
}
|
||||
|
||||
return delegating, nil
|
||||
}
|
||||
|
||||
func optionDefaultsToConfig(opts *Options) Config {
|
||||
return Config{
|
||||
LabelSelector: opts.DefaultLabelSelector,
|
||||
FieldSelector: opts.DefaultFieldSelector,
|
||||
Transform: opts.DefaultTransform,
|
||||
UnsafeDisableDeepCopy: opts.UnsafeDisableDeepCopy,
|
||||
UnsafeDisableDeepCopy: opts.DefaultUnsafeDisableDeepCopy,
|
||||
}
|
||||
}
|
||||
|
||||
return &informerCache{
|
||||
scheme: opts.Scheme,
|
||||
Informers: internal.NewInformers(config, &internal.InformersOpts{
|
||||
HTTPClient: opts.HTTPClient,
|
||||
Scheme: opts.Scheme,
|
||||
Mapper: opts.Mapper,
|
||||
ResyncPeriod: *opts.SyncPeriod,
|
||||
Namespace: opts.Namespaces[0],
|
||||
ByGVK: byGVK,
|
||||
}),
|
||||
}, nil
|
||||
func byObjectToConfig(byObject ByObject) Config {
|
||||
return Config{
|
||||
LabelSelector: byObject.Label,
|
||||
FieldSelector: byObject.Field,
|
||||
Transform: byObject.Transform,
|
||||
UnsafeDisableDeepCopy: byObject.UnsafeDisableDeepCopy,
|
||||
}
|
||||
}
|
||||
|
||||
type newCacheFunc func(config Config, namespace string) Cache
|
||||
|
||||
func newCache(restConfig *rest.Config, opts Options) newCacheFunc {
|
||||
return func(config Config, namespace string) Cache {
|
||||
return &informerCache{
|
||||
scheme: opts.Scheme,
|
||||
Informers: internal.NewInformers(restConfig, &internal.InformersOpts{
|
||||
HTTPClient: opts.HTTPClient,
|
||||
Scheme: opts.Scheme,
|
||||
Mapper: opts.Mapper,
|
||||
ResyncPeriod: *opts.SyncPeriod,
|
||||
Namespace: namespace,
|
||||
Selector: internal.Selector{
|
||||
Label: config.LabelSelector,
|
||||
Field: config.FieldSelector,
|
||||
},
|
||||
Transform: config.Transform,
|
||||
UnsafeDisableDeepCopy: pointer.BoolDeref(config.UnsafeDisableDeepCopy, false),
|
||||
NewInformer: opts.newInformer,
|
||||
}),
|
||||
readerFailOnMissingInformer: opts.ReaderFailOnMissingInformer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func defaultOpts(config *rest.Config, opts Options) (Options, error) {
|
||||
@ -241,15 +367,12 @@ func defaultOpts(config *rest.Config, opts Options) (Options, error) {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
logger := log.WithName("setup")
|
||||
|
||||
// Use the rest HTTP client for the provided config if unset
|
||||
if opts.HTTPClient == nil {
|
||||
var err error
|
||||
opts.HTTPClient, err = rest.HTTPClientFor(config)
|
||||
if err != nil {
|
||||
logger.Error(err, "Failed to get HTTP client")
|
||||
return opts, fmt.Errorf("could not create HTTP client from config: %w", err)
|
||||
return Options{}, fmt.Errorf("could not create HTTP client from config: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,11 +386,54 @@ func defaultOpts(config *rest.Config, opts Options) (Options, error) {
|
||||
var err error
|
||||
opts.Mapper, err = apiutil.NewDiscoveryRESTMapper(config, opts.HTTPClient)
|
||||
if err != nil {
|
||||
logger.Error(err, "Failed to get API Group-Resources")
|
||||
return opts, fmt.Errorf("could not create RESTMapper from config: %w", err)
|
||||
return Options{}, fmt.Errorf("could not create RESTMapper from config: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
for namespace, cfg := range opts.DefaultNamespaces {
|
||||
cfg = defaultConfig(cfg, optionDefaultsToConfig(&opts))
|
||||
opts.DefaultNamespaces[namespace] = cfg
|
||||
}
|
||||
|
||||
for obj, byObject := range opts.ByObject {
|
||||
isNamespaced, err := apiutil.IsObjectNamespaced(obj, opts.Scheme, opts.Mapper)
|
||||
if err != nil {
|
||||
return opts, fmt.Errorf("failed to determine if %T is namespaced: %w", obj, err)
|
||||
}
|
||||
if !isNamespaced && byObject.Namespaces != nil {
|
||||
return opts, fmt.Errorf("type %T is not namespaced, but its ByObject.Namespaces setting is not nil", obj)
|
||||
}
|
||||
|
||||
// Default the namespace-level configs first, because they need to use the undefaulted type-level config.
|
||||
for namespace, config := range byObject.Namespaces {
|
||||
// 1. Default from the undefaulted type-level config
|
||||
config = defaultConfig(config, byObjectToConfig(byObject))
|
||||
|
||||
// 2. Default from the namespace-level config. This was defaulted from the global default config earlier, but
|
||||
// might not have an entry for the current namespace.
|
||||
if defaultNamespaceSettings, hasDefaultNamespace := opts.DefaultNamespaces[namespace]; hasDefaultNamespace {
|
||||
config = defaultConfig(config, defaultNamespaceSettings)
|
||||
}
|
||||
|
||||
// 3. Default from the global defaults
|
||||
config = defaultConfig(config, optionDefaultsToConfig(&opts))
|
||||
|
||||
byObject.Namespaces[namespace] = config
|
||||
}
|
||||
|
||||
defaultedConfig := defaultConfig(byObjectToConfig(byObject), optionDefaultsToConfig(&opts))
|
||||
byObject.Label = defaultedConfig.LabelSelector
|
||||
byObject.Field = defaultedConfig.FieldSelector
|
||||
byObject.Transform = defaultedConfig.Transform
|
||||
byObject.UnsafeDisableDeepCopy = defaultedConfig.UnsafeDisableDeepCopy
|
||||
|
||||
if byObject.Namespaces == nil {
|
||||
byObject.Namespaces = opts.DefaultNamespaces
|
||||
}
|
||||
|
||||
opts.ByObject[obj] = byObject
|
||||
}
|
||||
|
||||
// Default the resync period to 10 hours if unset
|
||||
if opts.SyncPeriod == nil {
|
||||
opts.SyncPeriod = &defaultSyncPeriod
|
||||
@ -275,24 +441,19 @@ func defaultOpts(config *rest.Config, opts Options) (Options, error) {
|
||||
return opts, nil
|
||||
}
|
||||
|
||||
func convertToInformerOptsByGVK(in map[client.Object]ByObject, scheme *runtime.Scheme) (map[schema.GroupVersionKind]internal.InformersOptsByGVK, error) {
|
||||
out := map[schema.GroupVersionKind]internal.InformersOptsByGVK{}
|
||||
for object, byObject := range in {
|
||||
gvk, err := apiutil.GVKForObject(object, scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, ok := out[gvk]; ok {
|
||||
return nil, fmt.Errorf("duplicate cache options for GVK %v, cache.Options.ByObject has multiple types with the same GroupVersionKind", gvk)
|
||||
}
|
||||
out[gvk] = internal.InformersOptsByGVK{
|
||||
Selector: internal.Selector{
|
||||
Field: byObject.Field,
|
||||
Label: byObject.Label,
|
||||
},
|
||||
Transform: byObject.Transform,
|
||||
UnsafeDisableDeepCopy: byObject.UnsafeDisableDeepCopy,
|
||||
}
|
||||
func defaultConfig(toDefault, defaultFrom Config) Config {
|
||||
if toDefault.LabelSelector == nil {
|
||||
toDefault.LabelSelector = defaultFrom.LabelSelector
|
||||
}
|
||||
return out, nil
|
||||
if toDefault.FieldSelector == nil {
|
||||
toDefault.FieldSelector = defaultFrom.FieldSelector
|
||||
}
|
||||
if toDefault.Transform == nil {
|
||||
toDefault.Transform = defaultFrom.Transform
|
||||
}
|
||||
if toDefault.UnsafeDisableDeepCopy == nil {
|
||||
toDefault.UnsafeDisableDeepCopy = defaultFrom.UnsafeDisableDeepCopy
|
||||
}
|
||||
|
||||
return toDefault
|
||||
}
|
||||
|
127
vendor/sigs.k8s.io/controller-runtime/pkg/cache/delegating_by_gvk_cache.go
generated
vendored
Normal file
127
vendor/sigs.k8s.io/controller-runtime/pkg/cache/delegating_by_gvk_cache.go
generated
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
Copyright 2023 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/exp/maps"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||
)
|
||||
|
||||
// delegatingByGVKCache delegates to a type-specific cache if present
|
||||
// and uses the defaultCache otherwise.
|
||||
type delegatingByGVKCache struct {
|
||||
scheme *runtime.Scheme
|
||||
caches map[schema.GroupVersionKind]Cache
|
||||
defaultCache Cache
|
||||
}
|
||||
|
||||
func (dbt *delegatingByGVKCache) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error {
|
||||
cache, err := dbt.cacheForObject(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cache.Get(ctx, key, obj, opts...)
|
||||
}
|
||||
|
||||
func (dbt *delegatingByGVKCache) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error {
|
||||
cache, err := dbt.cacheForObject(list)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cache.List(ctx, list, opts...)
|
||||
}
|
||||
|
||||
func (dbt *delegatingByGVKCache) GetInformer(ctx context.Context, obj client.Object, opts ...InformerGetOption) (Informer, error) {
|
||||
cache, err := dbt.cacheForObject(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cache.GetInformer(ctx, obj, opts...)
|
||||
}
|
||||
|
||||
func (dbt *delegatingByGVKCache) GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind, opts ...InformerGetOption) (Informer, error) {
|
||||
return dbt.cacheForGVK(gvk).GetInformerForKind(ctx, gvk, opts...)
|
||||
}
|
||||
|
||||
func (dbt *delegatingByGVKCache) Start(ctx context.Context) error {
|
||||
allCaches := maps.Values(dbt.caches)
|
||||
allCaches = append(allCaches, dbt.defaultCache)
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
errs := make(chan error)
|
||||
for idx := range allCaches {
|
||||
cache := allCaches[idx]
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if err := cache.Start(ctx); err != nil {
|
||||
errs <- err
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
select {
|
||||
case err := <-errs:
|
||||
return err
|
||||
case <-ctx.Done():
|
||||
wg.Wait()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (dbt *delegatingByGVKCache) WaitForCacheSync(ctx context.Context) bool {
|
||||
synced := true
|
||||
for _, cache := range append(maps.Values(dbt.caches), dbt.defaultCache) {
|
||||
if !cache.WaitForCacheSync(ctx) {
|
||||
synced = false
|
||||
}
|
||||
}
|
||||
|
||||
return synced
|
||||
}
|
||||
|
||||
func (dbt *delegatingByGVKCache) IndexField(ctx context.Context, obj client.Object, field string, extractValue client.IndexerFunc) error {
|
||||
cache, err := dbt.cacheForObject(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cache.IndexField(ctx, obj, field, extractValue)
|
||||
}
|
||||
|
||||
func (dbt *delegatingByGVKCache) cacheForObject(o runtime.Object) (Cache, error) {
|
||||
gvk, err := apiutil.GVKForObject(o, dbt.scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gvk.Kind = strings.TrimSuffix(gvk.Kind, "List")
|
||||
return dbt.cacheForGVK(gvk), nil
|
||||
}
|
||||
|
||||
func (dbt *delegatingByGVKCache) cacheForGVK(gvk schema.GroupVersionKind) Cache {
|
||||
if specific, hasSpecific := dbt.caches[gvk]; hasSpecific {
|
||||
return specific
|
||||
}
|
||||
|
||||
return dbt.defaultCache
|
||||
}
|
74
vendor/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache.go
generated
vendored
74
vendor/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache.go
generated
vendored
@ -27,6 +27,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/cache/internal"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||
@ -45,11 +46,28 @@ func (*ErrCacheNotStarted) Error() string {
|
||||
return "the cache is not started, can not read objects"
|
||||
}
|
||||
|
||||
var _ error = (*ErrCacheNotStarted)(nil)
|
||||
|
||||
// ErrResourceNotCached indicates that the resource type
|
||||
// the client asked the cache for is not cached, i.e. the
|
||||
// corresponding informer does not exist yet.
|
||||
type ErrResourceNotCached struct {
|
||||
GVK schema.GroupVersionKind
|
||||
}
|
||||
|
||||
// Error returns the error
|
||||
func (r ErrResourceNotCached) Error() string {
|
||||
return fmt.Sprintf("%s is not cached", r.GVK.String())
|
||||
}
|
||||
|
||||
var _ error = (*ErrResourceNotCached)(nil)
|
||||
|
||||
// informerCache is a Kubernetes Object cache populated from internal.Informers.
|
||||
// informerCache wraps internal.Informers.
|
||||
type informerCache struct {
|
||||
scheme *runtime.Scheme
|
||||
*internal.Informers
|
||||
readerFailOnMissingInformer bool
|
||||
}
|
||||
|
||||
// Get implements Reader.
|
||||
@ -59,7 +77,7 @@ func (ic *informerCache) Get(ctx context.Context, key client.ObjectKey, out clie
|
||||
return err
|
||||
}
|
||||
|
||||
started, cache, err := ic.Informers.Get(ctx, gvk, out)
|
||||
started, cache, err := ic.getInformerForKind(ctx, gvk, out)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -67,7 +85,7 @@ func (ic *informerCache) Get(ctx context.Context, key client.ObjectKey, out clie
|
||||
if !started {
|
||||
return &ErrCacheNotStarted{}
|
||||
}
|
||||
return cache.Reader.Get(ctx, key, out)
|
||||
return cache.Reader.Get(ctx, key, out, opts...)
|
||||
}
|
||||
|
||||
// List implements Reader.
|
||||
@ -77,7 +95,7 @@ func (ic *informerCache) List(ctx context.Context, out client.ObjectList, opts .
|
||||
return err
|
||||
}
|
||||
|
||||
started, cache, err := ic.Informers.Get(ctx, *gvk, cacheTypeObj)
|
||||
started, cache, err := ic.getInformerForKind(ctx, *gvk, cacheTypeObj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -123,33 +141,53 @@ func (ic *informerCache) objectTypeForListObject(list client.ObjectList) (*schem
|
||||
return &gvk, cacheTypeObj, nil
|
||||
}
|
||||
|
||||
// GetInformerForKind returns the informer for the GroupVersionKind.
|
||||
func (ic *informerCache) GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind) (Informer, error) {
|
||||
func applyGetOptions(opts ...InformerGetOption) *internal.GetOptions {
|
||||
cfg := &InformerGetOptions{}
|
||||
for _, opt := range opts {
|
||||
opt(cfg)
|
||||
}
|
||||
return (*internal.GetOptions)(cfg)
|
||||
}
|
||||
|
||||
// GetInformerForKind returns the informer for the GroupVersionKind. If no informer exists, one will be started.
|
||||
func (ic *informerCache) GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind, opts ...InformerGetOption) (Informer, error) {
|
||||
// Map the gvk to an object
|
||||
obj, err := ic.scheme.New(gvk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, i, err := ic.Informers.Get(ctx, gvk, obj)
|
||||
_, i, err := ic.Informers.Get(ctx, gvk, obj, applyGetOptions(opts...))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return i.Informer, err
|
||||
return i.Informer, nil
|
||||
}
|
||||
|
||||
// GetInformer returns the informer for the obj.
|
||||
func (ic *informerCache) GetInformer(ctx context.Context, obj client.Object) (Informer, error) {
|
||||
// GetInformer returns the informer for the obj. If no informer exists, one will be started.
|
||||
func (ic *informerCache) GetInformer(ctx context.Context, obj client.Object, opts ...InformerGetOption) (Informer, error) {
|
||||
gvk, err := apiutil.GVKForObject(obj, ic.scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, i, err := ic.Informers.Get(ctx, gvk, obj)
|
||||
_, i, err := ic.Informers.Get(ctx, gvk, obj, applyGetOptions(opts...))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return i.Informer, err
|
||||
return i.Informer, nil
|
||||
}
|
||||
|
||||
func (ic *informerCache) getInformerForKind(ctx context.Context, gvk schema.GroupVersionKind, obj runtime.Object) (bool, *internal.Cache, error) {
|
||||
if ic.readerFailOnMissingInformer {
|
||||
cache, started, ok := ic.Informers.Peek(gvk, obj)
|
||||
if !ok {
|
||||
return false, nil, &ErrResourceNotCached{GVK: gvk}
|
||||
}
|
||||
return started, cache, nil
|
||||
}
|
||||
|
||||
return ic.Informers.Get(ctx, gvk, obj, &internal.GetOptions{})
|
||||
}
|
||||
|
||||
// NeedLeaderElection implements the LeaderElectionRunnable interface
|
||||
@ -158,11 +196,11 @@ func (ic *informerCache) NeedLeaderElection() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IndexField adds an indexer to the underlying cache, using extraction function to get
|
||||
// value(s) from the given field. This index can then be used by passing a field selector
|
||||
// IndexField adds an indexer to the underlying informer, using extractValue function to get
|
||||
// value(s) from the given field. This index can then be used by passing a field selector
|
||||
// to List. For one-to-one compatibility with "normal" field selectors, only return one value.
|
||||
// The values may be anything. They will automatically be prefixed with the namespace of the
|
||||
// given object, if present. The objects passed are guaranteed to be objects of the correct type.
|
||||
// The values may be anything. They will automatically be prefixed with the namespace of the
|
||||
// given object, if present. The objects passed are guaranteed to be objects of the correct type.
|
||||
func (ic *informerCache) IndexField(ctx context.Context, obj client.Object, field string, extractValue client.IndexerFunc) error {
|
||||
informer, err := ic.GetInformer(ctx, obj)
|
||||
if err != nil {
|
||||
@ -171,7 +209,7 @@ func (ic *informerCache) IndexField(ctx context.Context, obj client.Object, fiel
|
||||
return indexByField(informer, field, extractValue)
|
||||
}
|
||||
|
||||
func indexByField(indexer Informer, field string, extractor client.IndexerFunc) error {
|
||||
func indexByField(informer Informer, field string, extractValue client.IndexerFunc) error {
|
||||
indexFunc := func(objRaw interface{}) ([]string, error) {
|
||||
// TODO(directxman12): check if this is the correct type?
|
||||
obj, isObj := objRaw.(client.Object)
|
||||
@ -184,7 +222,7 @@ func indexByField(indexer Informer, field string, extractor client.IndexerFunc)
|
||||
}
|
||||
ns := meta.GetNamespace()
|
||||
|
||||
rawVals := extractor(obj)
|
||||
rawVals := extractValue(obj)
|
||||
var vals []string
|
||||
if ns == "" {
|
||||
// if we're not doubling the keys for the namespaced case, just create a new slice with same length
|
||||
@ -207,5 +245,5 @@ func indexByField(indexer Informer, field string, extractor client.IndexerFunc)
|
||||
return vals, nil
|
||||
}
|
||||
|
||||
return indexer.AddIndexers(cache.Indexers{internal.FieldIndexName(field): indexFunc})
|
||||
return informer.AddIndexers(cache.Indexers{internal.FieldIndexName(field): indexFunc})
|
||||
}
|
||||
|
18
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/cache_reader.go
generated
vendored
18
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/cache_reader.go
generated
vendored
@ -53,7 +53,7 @@ type CacheReader struct {
|
||||
}
|
||||
|
||||
// Get checks the indexer for the object and writes a copy of it if found.
|
||||
func (c *CacheReader) Get(_ context.Context, key client.ObjectKey, out client.Object, opts ...client.GetOption) error {
|
||||
func (c *CacheReader) Get(_ context.Context, key client.ObjectKey, out client.Object, _ ...client.GetOption) error {
|
||||
if c.scopeName == apimeta.RESTScopeNameRoot {
|
||||
key.Namespace = ""
|
||||
}
|
||||
@ -67,9 +67,9 @@ func (c *CacheReader) Get(_ context.Context, key client.ObjectKey, out client.Ob
|
||||
|
||||
// Not found, return an error
|
||||
if !exists {
|
||||
// Resource gets transformed into Kind in the error anyway, so this is fine
|
||||
return apierrors.NewNotFound(schema.GroupResource{
|
||||
Group: c.groupVersionKind.Group,
|
||||
Group: c.groupVersionKind.Group,
|
||||
// Resource gets set as Kind in the error so this is fine
|
||||
Resource: c.groupVersionKind.Kind,
|
||||
}, key.Name)
|
||||
}
|
||||
@ -111,6 +111,10 @@ func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...cli
|
||||
listOpts := client.ListOptions{}
|
||||
listOpts.ApplyOptions(opts)
|
||||
|
||||
if listOpts.Continue != "" {
|
||||
return fmt.Errorf("continue list option is not supported by the cache")
|
||||
}
|
||||
|
||||
switch {
|
||||
case listOpts.FieldSelector != nil:
|
||||
// TODO(directxman12): support more complicated field selectors by
|
||||
@ -119,8 +123,8 @@ func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...cli
|
||||
if !requiresExact {
|
||||
return fmt.Errorf("non-exact field matches are not supported by the cache")
|
||||
}
|
||||
// list all objects by the field selector. If this is namespaced and we have one, ask for the
|
||||
// namespaced index key. Otherwise, ask for the non-namespaced variant by using the fake "all namespaces"
|
||||
// list all objects by the field selector. If this is namespaced and we have one, ask for the
|
||||
// namespaced index key. Otherwise, ask for the non-namespaced variant by using the fake "all namespaces"
|
||||
// namespace.
|
||||
objs, err = c.indexer.ByIndex(FieldIndexName(field), KeyToNamespacedKey(listOpts.Namespace, val))
|
||||
case listOpts.Namespace != "":
|
||||
@ -175,7 +179,7 @@ func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...cli
|
||||
}
|
||||
|
||||
// objectKeyToStorageKey converts an object key to store key.
|
||||
// It's akin to MetaNamespaceKeyFunc. It's separate from
|
||||
// It's akin to MetaNamespaceKeyFunc. It's separate from
|
||||
// String to allow keeping the key format easily in sync with
|
||||
// MetaNamespaceKeyFunc.
|
||||
func objectKeyToStoreKey(k client.ObjectKey) string {
|
||||
@ -191,7 +195,7 @@ func FieldIndexName(field string) string {
|
||||
return "field:" + field
|
||||
}
|
||||
|
||||
// noNamespaceNamespace is used as the "namespace" when we want to list across all namespaces.
|
||||
// allNamespacesNamespace is used as the "namespace" when we want to list across all namespaces.
|
||||
const allNamespacesNamespace = "__all_namespaces"
|
||||
|
||||
// KeyToNamespacedKey prefixes the given index key with a namespace
|
||||
|
124
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers.go
generated
vendored
124
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers.go
generated
vendored
@ -40,24 +40,23 @@ import (
|
||||
|
||||
// InformersOpts configures an InformerMap.
|
||||
type InformersOpts struct {
|
||||
HTTPClient *http.Client
|
||||
Scheme *runtime.Scheme
|
||||
Mapper meta.RESTMapper
|
||||
ResyncPeriod time.Duration
|
||||
Namespace string
|
||||
ByGVK map[schema.GroupVersionKind]InformersOptsByGVK
|
||||
}
|
||||
|
||||
// InformersOptsByGVK configured additional by group version kind (or object)
|
||||
// in an InformerMap.
|
||||
type InformersOptsByGVK struct {
|
||||
HTTPClient *http.Client
|
||||
Scheme *runtime.Scheme
|
||||
Mapper meta.RESTMapper
|
||||
ResyncPeriod time.Duration
|
||||
Namespace string
|
||||
NewInformer *func(cache.ListerWatcher, runtime.Object, time.Duration, cache.Indexers) cache.SharedIndexInformer
|
||||
Selector Selector
|
||||
Transform cache.TransformFunc
|
||||
UnsafeDisableDeepCopy *bool
|
||||
UnsafeDisableDeepCopy bool
|
||||
}
|
||||
|
||||
// NewInformers creates a new InformersMap that can create informers under the hood.
|
||||
func NewInformers(config *rest.Config, options *InformersOpts) *Informers {
|
||||
newInformer := cache.NewSharedIndexInformer
|
||||
if options.NewInformer != nil {
|
||||
newInformer = *options.NewInformer
|
||||
}
|
||||
return &Informers{
|
||||
config: config,
|
||||
httpClient: options.HTTPClient,
|
||||
@ -68,12 +67,15 @@ func NewInformers(config *rest.Config, options *InformersOpts) *Informers {
|
||||
Unstructured: make(map[schema.GroupVersionKind]*Cache),
|
||||
Metadata: make(map[schema.GroupVersionKind]*Cache),
|
||||
},
|
||||
codecs: serializer.NewCodecFactory(options.Scheme),
|
||||
paramCodec: runtime.NewParameterCodec(options.Scheme),
|
||||
resync: options.ResyncPeriod,
|
||||
startWait: make(chan struct{}),
|
||||
namespace: options.Namespace,
|
||||
byGVK: options.ByGVK,
|
||||
codecs: serializer.NewCodecFactory(options.Scheme),
|
||||
paramCodec: runtime.NewParameterCodec(options.Scheme),
|
||||
resync: options.ResyncPeriod,
|
||||
startWait: make(chan struct{}),
|
||||
namespace: options.Namespace,
|
||||
selector: options.Selector,
|
||||
transform: options.Transform,
|
||||
unsafeDisableDeepCopy: options.UnsafeDisableDeepCopy,
|
||||
newInformer: newInformer,
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,6 +94,13 @@ type tracker struct {
|
||||
Metadata map[schema.GroupVersionKind]*Cache
|
||||
}
|
||||
|
||||
// GetOptions provides configuration to customize the behavior when
|
||||
// getting an informer.
|
||||
type GetOptions struct {
|
||||
// BlockUntilSynced controls if the informer retrieval will block until the informer is synced. Defaults to `true`.
|
||||
BlockUntilSynced *bool
|
||||
}
|
||||
|
||||
// Informers create and caches Informers for (runtime.Object, schema.GroupVersionKind) pairs.
|
||||
// It uses a standard parameter codec constructed based on the given generated Scheme.
|
||||
type Informers struct {
|
||||
@ -144,49 +153,15 @@ type Informers struct {
|
||||
// default or empty string means all namespaces
|
||||
namespace string
|
||||
|
||||
byGVK map[schema.GroupVersionKind]InformersOptsByGVK
|
||||
selector Selector
|
||||
transform cache.TransformFunc
|
||||
unsafeDisableDeepCopy bool
|
||||
|
||||
// NewInformer allows overriding of the shared index informer constructor for testing.
|
||||
newInformer func(cache.ListerWatcher, runtime.Object, time.Duration, cache.Indexers) cache.SharedIndexInformer
|
||||
}
|
||||
|
||||
func (ip *Informers) getSelector(gvk schema.GroupVersionKind) Selector {
|
||||
if ip.byGVK == nil {
|
||||
return Selector{}
|
||||
}
|
||||
if res, ok := ip.byGVK[gvk]; ok {
|
||||
return res.Selector
|
||||
}
|
||||
if res, ok := ip.byGVK[schema.GroupVersionKind{}]; ok {
|
||||
return res.Selector
|
||||
}
|
||||
return Selector{}
|
||||
}
|
||||
|
||||
func (ip *Informers) getTransform(gvk schema.GroupVersionKind) cache.TransformFunc {
|
||||
if ip.byGVK == nil {
|
||||
return nil
|
||||
}
|
||||
if res, ok := ip.byGVK[gvk]; ok {
|
||||
return res.Transform
|
||||
}
|
||||
if res, ok := ip.byGVK[schema.GroupVersionKind{}]; ok {
|
||||
return res.Transform
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ip *Informers) getDisableDeepCopy(gvk schema.GroupVersionKind) bool {
|
||||
if ip.byGVK == nil {
|
||||
return false
|
||||
}
|
||||
if res, ok := ip.byGVK[gvk]; ok && res.UnsafeDisableDeepCopy != nil {
|
||||
return *res.UnsafeDisableDeepCopy
|
||||
}
|
||||
if res, ok := ip.byGVK[schema.GroupVersionKind{}]; ok && res.UnsafeDisableDeepCopy != nil {
|
||||
return *res.UnsafeDisableDeepCopy
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Start calls Run on each of the informers and sets started to true. Blocks on the context.
|
||||
// Start calls Run on each of the informers and sets started to true. Blocks on the context.
|
||||
// It doesn't return start because it can't return an error, and it's not a runnable directly.
|
||||
func (ip *Informers) Start(ctx context.Context) error {
|
||||
func() {
|
||||
@ -271,18 +246,19 @@ func (ip *Informers) WaitForCacheSync(ctx context.Context) bool {
|
||||
return cache.WaitForCacheSync(ctx.Done(), ip.getHasSyncedFuncs()...)
|
||||
}
|
||||
|
||||
func (ip *Informers) get(gvk schema.GroupVersionKind, obj runtime.Object) (res *Cache, started bool, ok bool) {
|
||||
// Peek attempts to get the informer for the GVK, but does not start one if one does not exist.
|
||||
func (ip *Informers) Peek(gvk schema.GroupVersionKind, obj runtime.Object) (res *Cache, started bool, ok bool) {
|
||||
ip.mu.RLock()
|
||||
defer ip.mu.RUnlock()
|
||||
i, ok := ip.informersByType(obj)[gvk]
|
||||
return i, ip.started, ok
|
||||
}
|
||||
|
||||
// Get will create a new Informer and add it to the map of specificInformersMap if none exists. Returns
|
||||
// Get will create a new Informer and add it to the map of specificInformersMap if none exists. Returns
|
||||
// the Informer from the map.
|
||||
func (ip *Informers) Get(ctx context.Context, gvk schema.GroupVersionKind, obj runtime.Object) (bool, *Cache, error) {
|
||||
func (ip *Informers) Get(ctx context.Context, gvk schema.GroupVersionKind, obj runtime.Object, opts *GetOptions) (bool, *Cache, error) {
|
||||
// Return the informer if it is found
|
||||
i, started, ok := ip.get(gvk, obj)
|
||||
i, started, ok := ip.Peek(gvk, obj)
|
||||
if !ok {
|
||||
var err error
|
||||
if i, started, err = ip.addInformerToMap(gvk, obj); err != nil {
|
||||
@ -290,7 +266,12 @@ func (ip *Informers) Get(ctx context.Context, gvk schema.GroupVersionKind, obj r
|
||||
}
|
||||
}
|
||||
|
||||
if started && !i.Informer.HasSynced() {
|
||||
shouldBlock := true
|
||||
if opts.BlockUntilSynced != nil {
|
||||
shouldBlock = *opts.BlockUntilSynced
|
||||
}
|
||||
|
||||
if shouldBlock && started && !i.Informer.HasSynced() {
|
||||
// Wait for it to sync before returning the Informer so that folks don't read from a stale cache.
|
||||
if !cache.WaitForCacheSync(ctx.Done(), i.Informer.HasSynced) {
|
||||
return started, nil, apierrors.NewTimeoutError(fmt.Sprintf("failed waiting for %T Informer to sync", obj), 0)
|
||||
@ -311,11 +292,12 @@ func (ip *Informers) informersByType(obj runtime.Object) map[schema.GroupVersion
|
||||
}
|
||||
}
|
||||
|
||||
// addInformerToMap either returns an existing informer or creates a new informer, adds it to the map and returns it.
|
||||
func (ip *Informers) addInformerToMap(gvk schema.GroupVersionKind, obj runtime.Object) (*Cache, bool, error) {
|
||||
ip.mu.Lock()
|
||||
defer ip.mu.Unlock()
|
||||
|
||||
// Check the cache to see if we already have an Informer. If we do, return the Informer.
|
||||
// Check the cache to see if we already have an Informer. If we do, return the Informer.
|
||||
// This is for the case where 2 routines tried to get the informer when it wasn't in the map
|
||||
// so neither returned early, but the first one created it.
|
||||
if i, ok := ip.informersByType(obj)[gvk]; ok {
|
||||
@ -327,13 +309,13 @@ func (ip *Informers) addInformerToMap(gvk schema.GroupVersionKind, obj runtime.O
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
sharedIndexInformer := cache.NewSharedIndexInformer(&cache.ListWatch{
|
||||
sharedIndexInformer := ip.newInformer(&cache.ListWatch{
|
||||
ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) {
|
||||
ip.getSelector(gvk).ApplyToList(&opts)
|
||||
ip.selector.ApplyToList(&opts)
|
||||
return listWatcher.ListFunc(opts)
|
||||
},
|
||||
WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
ip.getSelector(gvk).ApplyToList(&opts)
|
||||
ip.selector.ApplyToList(&opts)
|
||||
opts.Watch = true // Watch needs to be set to true separately
|
||||
return listWatcher.WatchFunc(opts)
|
||||
},
|
||||
@ -342,7 +324,7 @@ func (ip *Informers) addInformerToMap(gvk schema.GroupVersionKind, obj runtime.O
|
||||
})
|
||||
|
||||
// Check to see if there is a transformer for this gvk
|
||||
if err := sharedIndexInformer.SetTransform(ip.getTransform(gvk)); err != nil {
|
||||
if err := sharedIndexInformer.SetTransform(ip.transform); err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
@ -358,7 +340,7 @@ func (ip *Informers) addInformerToMap(gvk schema.GroupVersionKind, obj runtime.O
|
||||
indexer: sharedIndexInformer.GetIndexer(),
|
||||
groupVersionKind: gvk,
|
||||
scopeName: mapping.Scope.Name(),
|
||||
disableDeepCopy: ip.getDisableDeepCopy(gvk),
|
||||
disableDeepCopy: ip.unsafeDisableDeepCopy,
|
||||
},
|
||||
}
|
||||
ip.informersByType(obj)[gvk] = i
|
||||
@ -382,7 +364,7 @@ func (ip *Informers) makeListWatcher(gvk schema.GroupVersionKind, obj runtime.Ob
|
||||
// Figure out if the GVK we're dealing with is global, or namespace scoped.
|
||||
var namespace string
|
||||
if mapping.Scope.Name() == meta.RESTScopeNameNamespace {
|
||||
namespace = restrictNamespaceBySelector(ip.namespace, ip.getSelector(gvk))
|
||||
namespace = restrictNamespaceBySelector(ip.namespace, ip.selector)
|
||||
}
|
||||
|
||||
switch obj.(type) {
|
||||
|
55
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/transformers.go
generated
vendored
55
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/transformers.go
generated
vendored
@ -1,55 +0,0 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||
)
|
||||
|
||||
// TransformFuncByGVK provides access to the correct transform function for
|
||||
// any given GVK.
|
||||
type TransformFuncByGVK interface {
|
||||
Set(runtime.Object, *runtime.Scheme, cache.TransformFunc) error
|
||||
Get(schema.GroupVersionKind) cache.TransformFunc
|
||||
SetDefault(transformer cache.TransformFunc)
|
||||
}
|
||||
|
||||
type transformFuncByGVK struct {
|
||||
defaultTransform cache.TransformFunc
|
||||
transformers map[schema.GroupVersionKind]cache.TransformFunc
|
||||
}
|
||||
|
||||
// TransformFuncByGVKFromMap creates a TransformFuncByGVK from a map that
|
||||
// maps GVKs to TransformFuncs.
|
||||
func TransformFuncByGVKFromMap(in map[schema.GroupVersionKind]cache.TransformFunc) TransformFuncByGVK {
|
||||
byGVK := &transformFuncByGVK{}
|
||||
if defaultFunc, hasDefault := in[schema.GroupVersionKind{}]; hasDefault {
|
||||
byGVK.defaultTransform = defaultFunc
|
||||
}
|
||||
delete(in, schema.GroupVersionKind{})
|
||||
byGVK.transformers = in
|
||||
return byGVK
|
||||
}
|
||||
|
||||
func (t *transformFuncByGVK) SetDefault(transformer cache.TransformFunc) {
|
||||
t.defaultTransform = transformer
|
||||
}
|
||||
|
||||
func (t *transformFuncByGVK) Set(obj runtime.Object, scheme *runtime.Scheme, transformer cache.TransformFunc) error {
|
||||
gvk, err := apiutil.GVKForObject(obj, scheme)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.transformers[gvk] = transformer
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t transformFuncByGVK) Get(gvk schema.GroupVersionKind) cache.TransformFunc {
|
||||
if val, ok := t.transformers[gvk]; ok {
|
||||
return val
|
||||
}
|
||||
return t.defaultTransform
|
||||
}
|
160
vendor/sigs.k8s.io/controller-runtime/pkg/cache/multi_namespace_cache.go
generated
vendored
160
vendor/sigs.k8s.io/controller-runtime/pkg/cache/multi_namespace_cache.go
generated
vendored
@ -25,8 +25,8 @@ import (
|
||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/rest"
|
||||
toolscache "k8s.io/client-go/tools/cache"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||
)
|
||||
@ -34,49 +34,31 @@ import (
|
||||
// a new global namespaced cache to handle cluster scoped resources.
|
||||
const globalCache = "_cluster-scope"
|
||||
|
||||
// MultiNamespacedCacheBuilder - Builder function to create a new multi-namespaced cache.
|
||||
// This will scope the cache to a list of namespaces. Listing for all namespaces
|
||||
// will list for all the namespaces that this knows about. By default this will create
|
||||
// a global cache for cluster scoped resource. Note that this is not intended
|
||||
// to be used for excluding namespaces, this is better done via a Predicate. Also note that
|
||||
// you may face performance issues when using this with a high number of namespaces.
|
||||
//
|
||||
// Deprecated: Use cache.Options.Namespaces instead.
|
||||
func MultiNamespacedCacheBuilder(namespaces []string) NewCacheFunc {
|
||||
return func(config *rest.Config, opts Options) (Cache, error) {
|
||||
opts.Namespaces = namespaces
|
||||
return newMultiNamespaceCache(config, opts)
|
||||
}
|
||||
}
|
||||
|
||||
func newMultiNamespaceCache(config *rest.Config, opts Options) (Cache, error) {
|
||||
if len(opts.Namespaces) < 2 {
|
||||
return nil, fmt.Errorf("must specify more than one namespace to use multi-namespace cache")
|
||||
}
|
||||
opts, err := defaultOpts(config, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func newMultiNamespaceCache(
|
||||
newCache newCacheFunc,
|
||||
scheme *runtime.Scheme,
|
||||
restMapper apimeta.RESTMapper,
|
||||
namespaces map[string]Config,
|
||||
globalConfig *Config, // may be nil in which case no cache for cluster-scoped objects will be created
|
||||
) Cache {
|
||||
// Create every namespace cache.
|
||||
caches := map[string]Cache{}
|
||||
for _, ns := range opts.Namespaces {
|
||||
opts.Namespaces = []string{ns}
|
||||
c, err := New(config, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
caches[ns] = c
|
||||
for namespace, config := range namespaces {
|
||||
caches[namespace] = newCache(config, namespace)
|
||||
}
|
||||
|
||||
// Create a cache for cluster scoped resources.
|
||||
opts.Namespaces = []string{}
|
||||
gCache, err := New(config, opts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating global cache: %w", err)
|
||||
// Create a cache for cluster scoped resources if requested
|
||||
var clusterCache Cache
|
||||
if globalConfig != nil {
|
||||
clusterCache = newCache(*globalConfig, corev1.NamespaceAll)
|
||||
}
|
||||
|
||||
return &multiNamespaceCache{namespaceToCache: caches, Scheme: opts.Scheme, RESTMapper: opts.Mapper, clusterCache: gCache}, nil
|
||||
return &multiNamespaceCache{
|
||||
namespaceToCache: caches,
|
||||
Scheme: scheme,
|
||||
RESTMapper: restMapper,
|
||||
clusterCache: clusterCache,
|
||||
}
|
||||
}
|
||||
|
||||
// multiNamespaceCache knows how to handle multiple namespaced caches
|
||||
@ -84,90 +66,96 @@ func newMultiNamespaceCache(config *rest.Config, opts Options) (Cache, error) {
|
||||
// operator to a list of namespaces instead of watching every namespace
|
||||
// in the cluster.
|
||||
type multiNamespaceCache struct {
|
||||
namespaceToCache map[string]Cache
|
||||
Scheme *runtime.Scheme
|
||||
RESTMapper apimeta.RESTMapper
|
||||
namespaceToCache map[string]Cache
|
||||
clusterCache Cache
|
||||
}
|
||||
|
||||
var _ Cache = &multiNamespaceCache{}
|
||||
|
||||
// Methods for multiNamespaceCache to conform to the Informers interface.
|
||||
func (c *multiNamespaceCache) GetInformer(ctx context.Context, obj client.Object) (Informer, error) {
|
||||
informers := map[string]Informer{}
|
||||
|
||||
// If the object is clusterscoped, get the informer from clusterCache,
|
||||
func (c *multiNamespaceCache) GetInformer(ctx context.Context, obj client.Object, opts ...InformerGetOption) (Informer, error) {
|
||||
// If the object is cluster scoped, get the informer from clusterCache,
|
||||
// if not use the namespaced caches.
|
||||
isNamespaced, err := apiutil.IsObjectNamespaced(obj, c.Scheme, c.RESTMapper)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !isNamespaced {
|
||||
clusterCacheInf, err := c.clusterCache.GetInformer(ctx, obj)
|
||||
clusterCacheInformer, err := c.clusterCache.GetInformer(ctx, obj, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
informers[globalCache] = clusterCacheInf
|
||||
|
||||
return &multiNamespaceInformer{namespaceToInformer: informers}, nil
|
||||
return &multiNamespaceInformer{
|
||||
namespaceToInformer: map[string]Informer{
|
||||
globalCache: clusterCacheInformer,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
namespaceToInformer := map[string]Informer{}
|
||||
for ns, cache := range c.namespaceToCache {
|
||||
informer, err := cache.GetInformer(ctx, obj)
|
||||
informer, err := cache.GetInformer(ctx, obj, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
informers[ns] = informer
|
||||
namespaceToInformer[ns] = informer
|
||||
}
|
||||
|
||||
return &multiNamespaceInformer{namespaceToInformer: informers}, nil
|
||||
return &multiNamespaceInformer{namespaceToInformer: namespaceToInformer}, nil
|
||||
}
|
||||
|
||||
func (c *multiNamespaceCache) GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind) (Informer, error) {
|
||||
informers := map[string]Informer{}
|
||||
|
||||
// If the object is clusterscoped, get the informer from clusterCache,
|
||||
func (c *multiNamespaceCache) GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind, opts ...InformerGetOption) (Informer, error) {
|
||||
// If the object is cluster scoped, get the informer from clusterCache,
|
||||
// if not use the namespaced caches.
|
||||
isNamespaced, err := apiutil.IsGVKNamespaced(gvk, c.RESTMapper)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !isNamespaced {
|
||||
clusterCacheInf, err := c.clusterCache.GetInformerForKind(ctx, gvk)
|
||||
clusterCacheInformer, err := c.clusterCache.GetInformerForKind(ctx, gvk, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
informers[globalCache] = clusterCacheInf
|
||||
|
||||
return &multiNamespaceInformer{namespaceToInformer: informers}, nil
|
||||
return &multiNamespaceInformer{
|
||||
namespaceToInformer: map[string]Informer{
|
||||
globalCache: clusterCacheInformer,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
namespaceToInformer := map[string]Informer{}
|
||||
for ns, cache := range c.namespaceToCache {
|
||||
informer, err := cache.GetInformerForKind(ctx, gvk)
|
||||
informer, err := cache.GetInformerForKind(ctx, gvk, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
informers[ns] = informer
|
||||
namespaceToInformer[ns] = informer
|
||||
}
|
||||
|
||||
return &multiNamespaceInformer{namespaceToInformer: informers}, nil
|
||||
return &multiNamespaceInformer{namespaceToInformer: namespaceToInformer}, nil
|
||||
}
|
||||
|
||||
func (c *multiNamespaceCache) Start(ctx context.Context) error {
|
||||
// start global cache
|
||||
go func() {
|
||||
err := c.clusterCache.Start(ctx)
|
||||
if err != nil {
|
||||
log.Error(err, "cluster scoped cache failed to start")
|
||||
}
|
||||
}()
|
||||
if c.clusterCache != nil {
|
||||
go func() {
|
||||
err := c.clusterCache.Start(ctx)
|
||||
if err != nil {
|
||||
log.Error(err, "cluster scoped cache failed to start")
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// start namespaced caches
|
||||
for ns, cache := range c.namespaceToCache {
|
||||
go func(ns string, cache Cache) {
|
||||
err := cache.Start(ctx)
|
||||
if err != nil {
|
||||
log.Error(err, "multinamespace cache failed to start namespaced informer", "namespace", ns)
|
||||
if err := cache.Start(ctx); err != nil {
|
||||
log.Error(err, "multi-namespace cache failed to start namespaced informer", "namespace", ns)
|
||||
}
|
||||
}(ns, cache)
|
||||
}
|
||||
@ -179,13 +167,13 @@ func (c *multiNamespaceCache) Start(ctx context.Context) error {
|
||||
func (c *multiNamespaceCache) WaitForCacheSync(ctx context.Context) bool {
|
||||
synced := true
|
||||
for _, cache := range c.namespaceToCache {
|
||||
if s := cache.WaitForCacheSync(ctx); !s {
|
||||
synced = s
|
||||
if !cache.WaitForCacheSync(ctx) {
|
||||
synced = false
|
||||
}
|
||||
}
|
||||
|
||||
// check if cluster scoped cache has synced
|
||||
if !c.clusterCache.WaitForCacheSync(ctx) {
|
||||
if c.clusterCache != nil && !c.clusterCache.WaitForCacheSync(ctx) {
|
||||
synced = false
|
||||
}
|
||||
return synced
|
||||
@ -224,7 +212,7 @@ func (c *multiNamespaceCache) Get(ctx context.Context, key client.ObjectKey, obj
|
||||
if !ok {
|
||||
return fmt.Errorf("unable to get: %v because of unknown namespace for the cache", key)
|
||||
}
|
||||
return cache.Get(ctx, key, obj)
|
||||
return cache.Get(ctx, key, obj, opts...)
|
||||
}
|
||||
|
||||
// List multi namespace cache will get all the objects in the namespaces that the cache is watching if asked for all namespaces.
|
||||
@ -245,7 +233,7 @@ func (c *multiNamespaceCache) List(ctx context.Context, list client.ObjectList,
|
||||
if listOpts.Namespace != corev1.NamespaceAll {
|
||||
cache, ok := c.namespaceToCache[listOpts.Namespace]
|
||||
if !ok {
|
||||
return fmt.Errorf("unable to get: %v because of unknown namespace for the cache", listOpts.Namespace)
|
||||
return fmt.Errorf("unable to list: %v because of unknown namespace for the cache", listOpts.Namespace)
|
||||
}
|
||||
return cache.List(ctx, list, opts...)
|
||||
}
|
||||
@ -278,12 +266,14 @@ func (c *multiNamespaceCache) List(ctx context.Context, list client.ObjectList,
|
||||
return fmt.Errorf("object: %T must be a list type", list)
|
||||
}
|
||||
allItems = append(allItems, items...)
|
||||
|
||||
// The last list call should have the most correct resource version.
|
||||
resourceVersion = accessor.GetResourceVersion()
|
||||
if limitSet {
|
||||
// decrement Limit by the number of items
|
||||
// fetched from the current namespace.
|
||||
listOpts.Limit -= int64(len(items))
|
||||
|
||||
// if a Limit was set and the number of
|
||||
// items read has reached this set limit,
|
||||
// then stop reading.
|
||||
@ -325,9 +315,12 @@ func (h handlerRegistration) HasSynced() bool {
|
||||
|
||||
var _ Informer = &multiNamespaceInformer{}
|
||||
|
||||
// AddEventHandler adds the handler to each namespaced informer.
|
||||
// AddEventHandler adds the handler to each informer.
|
||||
func (i *multiNamespaceInformer) AddEventHandler(handler toolscache.ResourceEventHandler) (toolscache.ResourceEventHandlerRegistration, error) {
|
||||
handles := handlerRegistration{handles: make(map[string]toolscache.ResourceEventHandlerRegistration, len(i.namespaceToInformer))}
|
||||
handles := handlerRegistration{
|
||||
handles: make(map[string]toolscache.ResourceEventHandlerRegistration, len(i.namespaceToInformer)),
|
||||
}
|
||||
|
||||
for ns, informer := range i.namespaceToInformer {
|
||||
registration, err := informer.AddEventHandler(handler)
|
||||
if err != nil {
|
||||
@ -335,12 +328,16 @@ func (i *multiNamespaceInformer) AddEventHandler(handler toolscache.ResourceEven
|
||||
}
|
||||
handles.handles[ns] = registration
|
||||
}
|
||||
|
||||
return handles, nil
|
||||
}
|
||||
|
||||
// AddEventHandlerWithResyncPeriod adds the handler with a resync period to each namespaced informer.
|
||||
func (i *multiNamespaceInformer) AddEventHandlerWithResyncPeriod(handler toolscache.ResourceEventHandler, resyncPeriod time.Duration) (toolscache.ResourceEventHandlerRegistration, error) {
|
||||
handles := handlerRegistration{handles: make(map[string]toolscache.ResourceEventHandlerRegistration, len(i.namespaceToInformer))}
|
||||
handles := handlerRegistration{
|
||||
handles: make(map[string]toolscache.ResourceEventHandlerRegistration, len(i.namespaceToInformer)),
|
||||
}
|
||||
|
||||
for ns, informer := range i.namespaceToInformer {
|
||||
registration, err := informer.AddEventHandlerWithResyncPeriod(handler, resyncPeriod)
|
||||
if err != nil {
|
||||
@ -348,14 +345,15 @@ func (i *multiNamespaceInformer) AddEventHandlerWithResyncPeriod(handler toolsca
|
||||
}
|
||||
handles.handles[ns] = registration
|
||||
}
|
||||
|
||||
return handles, nil
|
||||
}
|
||||
|
||||
// RemoveEventHandler removes a formerly added event handler given by its registration handle.
|
||||
// RemoveEventHandler removes a previously added event handler given by its registration handle.
|
||||
func (i *multiNamespaceInformer) RemoveEventHandler(h toolscache.ResourceEventHandlerRegistration) error {
|
||||
handles, ok := h.(handlerRegistration)
|
||||
if !ok {
|
||||
return fmt.Errorf("it is not the registration returned by multiNamespaceInformer")
|
||||
return fmt.Errorf("registration is not a registration returned by multiNamespaceInformer")
|
||||
}
|
||||
for ns, informer := range i.namespaceToInformer {
|
||||
registration, ok := handles.handles[ns]
|
||||
@ -369,7 +367,7 @@ func (i *multiNamespaceInformer) RemoveEventHandler(h toolscache.ResourceEventHa
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddIndexers adds the indexer for each namespaced informer.
|
||||
// AddIndexers adds the indexers to each informer.
|
||||
func (i *multiNamespaceInformer) AddIndexers(indexers toolscache.Indexers) error {
|
||||
for _, informer := range i.namespaceToInformer {
|
||||
err := informer.AddIndexers(indexers)
|
||||
@ -380,11 +378,11 @@ func (i *multiNamespaceInformer) AddIndexers(indexers toolscache.Indexers) error
|
||||
return nil
|
||||
}
|
||||
|
||||
// HasSynced checks if each namespaced informer has synced.
|
||||
// HasSynced checks if each informer has synced.
|
||||
func (i *multiNamespaceInformer) HasSynced() bool {
|
||||
for _, informer := range i.namespaceToInformer {
|
||||
if ok := informer.HasSynced(); !ok {
|
||||
return ok
|
||||
if !informer.HasSynced() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
Reference in New Issue
Block a user