mirror of
https://github.com/prometheus-operator/prometheus-operator.git
synced 2025-04-16 09:16:38 +00:00
Replace ocured with occurred in the comment of the Get function. Signed-off-by: jaehanbyun <awbrg789@naver.com>
219 lines
7.1 KiB
Go
219 lines
7.1 KiB
Go
// Copyright 2020 The prometheus-operator 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 informers
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
|
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/labels"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
"k8s.io/apimachinery/pkg/util/sets"
|
|
"k8s.io/client-go/tools/cache"
|
|
|
|
"github.com/prometheus-operator/prometheus-operator/pkg/listwatch"
|
|
)
|
|
|
|
// InformLister is the interface that both exposes a shared index informer
|
|
// and a generic lister.
|
|
// Usually generated clients declare this interface as "GenericInformer".
|
|
type InformLister interface {
|
|
Informer() cache.SharedIndexInformer
|
|
Lister() cache.GenericLister
|
|
}
|
|
|
|
// FactoriesForNamespaces is a way to combine several shared informers into a single struct with unified listing power.
|
|
type FactoriesForNamespaces interface {
|
|
ForResource(namespace string, resource schema.GroupVersionResource) (InformLister, error)
|
|
Namespaces() sets.Set[string]
|
|
}
|
|
|
|
// ForResource contains a slice of InformLister for a concrete resource type,
|
|
// one per namespace.
|
|
type ForResource struct {
|
|
informers []InformLister
|
|
}
|
|
|
|
// NewInformersForResource returns a composite informer exposing the most basic set of operations
|
|
// needed from informers and listers. It does not implement a formal interface,
|
|
// but exposes a minimal set of methods from underlying slice of cache.SharedIndexInformers and cache.GenericListers.
|
|
//
|
|
// It takes a namespace aware informer factory, wrapped in a FactoriesForNamespaces interface
|
|
// that is able to instantiate an informer for a given namespace.
|
|
func NewInformersForResource(ifs FactoriesForNamespaces, resource schema.GroupVersionResource) (*ForResource, error) {
|
|
return NewInformersForResourceWithTransform(ifs, resource, nil)
|
|
}
|
|
|
|
func NewInformersForResourceWithTransform(ifs FactoriesForNamespaces, resource schema.GroupVersionResource, handler cache.TransformFunc) (*ForResource, error) {
|
|
namespaces := ifs.Namespaces().UnsortedList()
|
|
sort.Strings(namespaces)
|
|
|
|
informers := make([]InformLister, 0, len(namespaces))
|
|
|
|
for _, ns := range namespaces {
|
|
informer, err := ifs.ForResource(ns, resource)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error getting informer in namespace %q for resource %v: %w", ns, resource, err)
|
|
}
|
|
if handler != nil {
|
|
if err := informer.Informer().SetTransform(handler); err != nil {
|
|
return nil, fmt.Errorf("error setting transform in namespace %q for resource %v: %w", ns, resource, err)
|
|
}
|
|
}
|
|
informers = append(informers, informer)
|
|
}
|
|
|
|
return &ForResource{
|
|
informers: informers,
|
|
}, nil
|
|
}
|
|
|
|
// PartialObjectMetadataStrip removes the following fields from PartialObjectMetadata objects:
|
|
// * Annotations
|
|
// * Labels
|
|
// * ManagedFields
|
|
// * Finalizers
|
|
// * OwnerReferences.
|
|
//
|
|
// If the passed object isn't of type *v1.PartialObjectMetadata, it is returned unmodified.
|
|
//
|
|
// It matches the cache.TransformFunc type and can be used by informers
|
|
// watching PartialObjectMetadata objects to reduce memory consumption.
|
|
// See https://pkg.go.dev/k8s.io/client-go@v0.29.1/tools/cache#TransformFunc for details.
|
|
func PartialObjectMetadataStrip(obj interface{}) (interface{}, error) {
|
|
partialMeta, ok := obj.(*v1.PartialObjectMetadata)
|
|
if !ok {
|
|
// Don't do anything if the cast isn't successful.
|
|
// The object might be of type "cache.DeletedFinalStateUnknown".
|
|
return obj, nil
|
|
}
|
|
|
|
partialMeta.Annotations = nil
|
|
partialMeta.Labels = nil
|
|
partialMeta.ManagedFields = nil
|
|
partialMeta.Finalizers = nil
|
|
partialMeta.OwnerReferences = nil
|
|
|
|
return partialMeta, nil
|
|
}
|
|
|
|
// Start starts all underlying informers, passing the given stop channel to each of them.
|
|
func (w *ForResource) Start(stopCh <-chan struct{}) {
|
|
for _, i := range w.informers {
|
|
go i.Informer().Run(stopCh)
|
|
}
|
|
}
|
|
|
|
// GetInformers returns all wrapped informers.
|
|
func (w *ForResource) GetInformers() []InformLister {
|
|
return w.informers
|
|
}
|
|
|
|
// AddEventHandler registers the given handler to all wrapped informers.
|
|
func (w *ForResource) AddEventHandler(handler cache.ResourceEventHandler) {
|
|
for _, i := range w.informers {
|
|
_, _ = i.Informer().AddEventHandler(handler)
|
|
}
|
|
}
|
|
|
|
// HasSynced returns true if all underlying informers have synced, else false.
|
|
func (w *ForResource) HasSynced() bool {
|
|
for _, i := range w.informers {
|
|
if !i.Informer().HasSynced() {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// ListAll invokes the ListAll method for all wrapped informers passing the
|
|
// same selector and appendFn.
|
|
func (w *ForResource) ListAll(selector labels.Selector, appendFn cache.AppendFunc) error {
|
|
for _, inf := range w.informers {
|
|
err := cache.ListAll(inf.Informer().GetIndexer(), selector, appendFn)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ListAllByNamespace invokes all wrapped informers passing the same appendFn.
|
|
// While wrapped informers are usually namespace aware, it is still important to iterate over all of them
|
|
// as some informers might wrap k8s.io/apimachinery/pkg/apis/meta/v1.NamespaceAll.
|
|
func (w *ForResource) ListAllByNamespace(namespace string, selector labels.Selector, appendFn cache.AppendFunc) error {
|
|
for _, inf := range w.informers {
|
|
err := cache.ListAllByNamespace(inf.Informer().GetIndexer(), namespace, selector, appendFn)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Get invokes all wrapped informers and returns the first found runtime object.
|
|
// It returns the first occurred error.
|
|
func (w *ForResource) Get(name string) (runtime.Object, error) {
|
|
var err error
|
|
|
|
for _, inf := range w.informers {
|
|
var ret runtime.Object
|
|
ret, err = inf.Lister().Get(name)
|
|
if apierrors.IsNotFound(err) {
|
|
continue
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return ret, nil
|
|
}
|
|
|
|
return nil, err
|
|
}
|
|
|
|
// newInformerOptions returns a list option tweak function and a list of namespaces
|
|
// based on the given allowed and denied namespaces.
|
|
//
|
|
// If allowedNamespaces contains one only entry equal to k8s.io/apimachinery/pkg/apis/meta/v1.NamespaceAll
|
|
// then it returns it and a tweak function filtering denied namespaces using a field selector.
|
|
//
|
|
// Else, denied namespaces are ignored and just the set of allowed namespaces is returned.
|
|
func newInformerOptions(allowedNamespaces, deniedNamespaces map[string]struct{}, tweaks func(*v1.ListOptions)) (func(*v1.ListOptions), []string) {
|
|
if tweaks == nil {
|
|
tweaks = func(*v1.ListOptions) {} // nop
|
|
}
|
|
|
|
var namespaces []string
|
|
|
|
if listwatch.IsAllNamespaces(allowedNamespaces) {
|
|
return func(options *v1.ListOptions) {
|
|
tweaks(options)
|
|
listwatch.DenyTweak(options, "metadata.namespace", deniedNamespaces)
|
|
}, []string{v1.NamespaceAll}
|
|
}
|
|
|
|
for ns := range allowedNamespaces {
|
|
namespaces = append(namespaces, ns)
|
|
}
|
|
|
|
return tweaks, namespaces
|
|
}
|