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.9.2 to 0.10.0
Bumps [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) from 0.9.2 to 0.10.0. - [Release notes](https://github.com/kubernetes-sigs/controller-runtime/releases) - [Commits](https://github.com/kubernetes-sigs/controller-runtime/compare/v0.9.2...v0.10.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
60c2afbcca
commit
fb000647b5
42
vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go
generated
vendored
42
vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go
generated
vendored
@ -113,6 +113,12 @@ type Options struct {
|
||||
// [1] https://pkg.go.dev/k8s.io/apimachinery/pkg/fields#Selector
|
||||
// [2] https://pkg.go.dev/k8s.io/apimachinery/pkg/fields#Set
|
||||
SelectorsByObject SelectorsByObject
|
||||
|
||||
// UnsafeDisableDeepCopyByObject indicates not to deep copy objects during get or
|
||||
// list objects per GVK at the specified object.
|
||||
// Be very careful with this, when enabled you must DeepCopy any object before mutating it,
|
||||
// otherwise you will mutate the object in the cache.
|
||||
UnsafeDisableDeepCopyByObject DisableDeepCopyByObject
|
||||
}
|
||||
|
||||
var defaultResyncTime = 10 * time.Hour
|
||||
@ -127,7 +133,11 @@ func New(config *rest.Config, opts Options) (Cache, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
im := internal.NewInformersMap(config, opts.Scheme, opts.Mapper, *opts.Resync, opts.Namespace, selectorsByGVK)
|
||||
disableDeepCopyByGVK, err := convertToDisableDeepCopyByGVK(opts.UnsafeDisableDeepCopyByObject, opts.Scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
im := internal.NewInformersMap(config, opts.Scheme, opts.Mapper, *opts.Resync, opts.Namespace, selectorsByGVK, disableDeepCopyByGVK)
|
||||
return &informerCache{InformersMap: im}, nil
|
||||
}
|
||||
|
||||
@ -136,6 +146,8 @@ func New(config *rest.Config, opts Options) (Cache, error) {
|
||||
// SelectorsByObject
|
||||
// WARNING: if SelectorsByObject is specified. filtered out resources are not
|
||||
// returned.
|
||||
// WARNING: if UnsafeDisableDeepCopy is enabled, you must DeepCopy any object
|
||||
// returned from cache get/list before mutating it.
|
||||
func BuilderWithOptions(options Options) NewCacheFunc {
|
||||
return func(config *rest.Config, opts Options) (Cache, error) {
|
||||
if opts.Scheme == nil {
|
||||
@ -151,6 +163,7 @@ func BuilderWithOptions(options Options) NewCacheFunc {
|
||||
opts.Namespace = options.Namespace
|
||||
}
|
||||
opts.SelectorsByObject = options.SelectorsByObject
|
||||
opts.UnsafeDisableDeepCopyByObject = options.UnsafeDisableDeepCopyByObject
|
||||
return New(config, opts)
|
||||
}
|
||||
}
|
||||
@ -189,3 +202,30 @@ func convertToSelectorsByGVK(selectorsByObject SelectorsByObject, scheme *runtim
|
||||
}
|
||||
return selectorsByGVK, nil
|
||||
}
|
||||
|
||||
// DisableDeepCopyByObject associate a client.Object's GVK to disable DeepCopy during get or list from cache.
|
||||
type DisableDeepCopyByObject map[client.Object]bool
|
||||
|
||||
var _ client.Object = &ObjectAll{}
|
||||
|
||||
// ObjectAll is the argument to represent all objects' types.
|
||||
type ObjectAll struct {
|
||||
client.Object
|
||||
}
|
||||
|
||||
func convertToDisableDeepCopyByGVK(disableDeepCopyByObject DisableDeepCopyByObject, scheme *runtime.Scheme) (internal.DisableDeepCopyByGVK, error) {
|
||||
disableDeepCopyByGVK := internal.DisableDeepCopyByGVK{}
|
||||
for obj, disable := range disableDeepCopyByObject {
|
||||
switch obj.(type) {
|
||||
case ObjectAll, *ObjectAll:
|
||||
disableDeepCopyByGVK[internal.GroupVersionKindAll] = disable
|
||||
default:
|
||||
gvk, err := apiutil.GVKForObject(obj, scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
disableDeepCopyByGVK[gvk] = disable
|
||||
}
|
||||
}
|
||||
return disableDeepCopyByGVK, nil
|
||||
}
|
||||
|
34
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/cache_reader.go
generated
vendored
34
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/cache_reader.go
generated
vendored
@ -46,6 +46,11 @@ type CacheReader struct {
|
||||
|
||||
// scopeName is the scope of the resource (namespaced or cluster-scoped).
|
||||
scopeName apimeta.RESTScopeName
|
||||
|
||||
// disableDeepCopy indicates not to deep copy objects during get or list objects.
|
||||
// Be very careful with this, when enabled you must DeepCopy any object before mutating it,
|
||||
// otherwise you will mutate the object in the cache.
|
||||
disableDeepCopy bool
|
||||
}
|
||||
|
||||
// Get checks the indexer for the object and writes a copy of it if found.
|
||||
@ -76,9 +81,13 @@ func (c *CacheReader) Get(_ context.Context, key client.ObjectKey, out client.Ob
|
||||
return fmt.Errorf("cache contained %T, which is not an Object", obj)
|
||||
}
|
||||
|
||||
// deep copy to avoid mutating cache
|
||||
// TODO(directxman12): revisit the decision to always deepcopy
|
||||
obj = obj.(runtime.Object).DeepCopyObject()
|
||||
if c.disableDeepCopy {
|
||||
// skip deep copy which might be unsafe
|
||||
// you must DeepCopy any object before mutating it outside
|
||||
} else {
|
||||
// deep copy to avoid mutating cache
|
||||
obj = obj.(runtime.Object).DeepCopyObject()
|
||||
}
|
||||
|
||||
// Copy the value of the item in the cache to the returned value
|
||||
// TODO(directxman12): this is a terrible hack, pls fix (we should have deepcopyinto)
|
||||
@ -88,7 +97,9 @@ func (c *CacheReader) Get(_ context.Context, key client.ObjectKey, out client.Ob
|
||||
return fmt.Errorf("cache had type %s, but %s was asked for", objVal.Type(), outVal.Type())
|
||||
}
|
||||
reflect.Indirect(outVal).Set(reflect.Indirect(objVal))
|
||||
out.GetObjectKind().SetGroupVersionKind(c.groupVersionKind)
|
||||
if !c.disableDeepCopy {
|
||||
out.GetObjectKind().SetGroupVersionKind(c.groupVersionKind)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -129,10 +140,10 @@ func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...cli
|
||||
limitSet := listOpts.Limit > 0
|
||||
|
||||
runtimeObjs := make([]runtime.Object, 0, len(objs))
|
||||
for i, item := range objs {
|
||||
for _, item := range objs {
|
||||
// if the Limit option is set and the number of items
|
||||
// listed exceeds this limit, then stop reading.
|
||||
if limitSet && int64(i) >= listOpts.Limit {
|
||||
if limitSet && int64(len(runtimeObjs)) >= listOpts.Limit {
|
||||
break
|
||||
}
|
||||
obj, isObj := item.(runtime.Object)
|
||||
@ -150,8 +161,15 @@ func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...cli
|
||||
}
|
||||
}
|
||||
|
||||
outObj := obj.DeepCopyObject()
|
||||
outObj.GetObjectKind().SetGroupVersionKind(c.groupVersionKind)
|
||||
var outObj runtime.Object
|
||||
if c.disableDeepCopy {
|
||||
// skip deep copy which might be unsafe
|
||||
// you must DeepCopy any object before mutating it outside
|
||||
outObj = obj
|
||||
} else {
|
||||
outObj = obj.DeepCopyObject()
|
||||
outObj.GetObjectKind().SetGroupVersionKind(c.groupVersionKind)
|
||||
}
|
||||
runtimeObjs = append(runtimeObjs, outObj)
|
||||
}
|
||||
return apimeta.SetList(out, runtimeObjs)
|
||||
|
19
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/deleg_map.go
generated
vendored
19
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/deleg_map.go
generated
vendored
@ -51,11 +51,12 @@ func NewInformersMap(config *rest.Config,
|
||||
resync time.Duration,
|
||||
namespace string,
|
||||
selectors SelectorsByGVK,
|
||||
disableDeepCopy DisableDeepCopyByGVK,
|
||||
) *InformersMap {
|
||||
return &InformersMap{
|
||||
structured: newStructuredInformersMap(config, scheme, mapper, resync, namespace, selectors),
|
||||
unstructured: newUnstructuredInformersMap(config, scheme, mapper, resync, namespace, selectors),
|
||||
metadata: newMetadataInformersMap(config, scheme, mapper, resync, namespace, selectors),
|
||||
structured: newStructuredInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy),
|
||||
unstructured: newUnstructuredInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy),
|
||||
metadata: newMetadataInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy),
|
||||
|
||||
Scheme: scheme,
|
||||
}
|
||||
@ -107,18 +108,18 @@ func (m *InformersMap) Get(ctx context.Context, gvk schema.GroupVersionKind, obj
|
||||
|
||||
// newStructuredInformersMap creates a new InformersMap for structured objects.
|
||||
func newStructuredInformersMap(config *rest.Config, scheme *runtime.Scheme, mapper meta.RESTMapper, resync time.Duration,
|
||||
namespace string, selectors SelectorsByGVK) *specificInformersMap {
|
||||
return newSpecificInformersMap(config, scheme, mapper, resync, namespace, selectors, createStructuredListWatch)
|
||||
namespace string, selectors SelectorsByGVK, disableDeepCopy DisableDeepCopyByGVK) *specificInformersMap {
|
||||
return newSpecificInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy, createStructuredListWatch)
|
||||
}
|
||||
|
||||
// newUnstructuredInformersMap creates a new InformersMap for unstructured objects.
|
||||
func newUnstructuredInformersMap(config *rest.Config, scheme *runtime.Scheme, mapper meta.RESTMapper, resync time.Duration,
|
||||
namespace string, selectors SelectorsByGVK) *specificInformersMap {
|
||||
return newSpecificInformersMap(config, scheme, mapper, resync, namespace, selectors, createUnstructuredListWatch)
|
||||
namespace string, selectors SelectorsByGVK, disableDeepCopy DisableDeepCopyByGVK) *specificInformersMap {
|
||||
return newSpecificInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy, createUnstructuredListWatch)
|
||||
}
|
||||
|
||||
// newMetadataInformersMap creates a new InformersMap for metadata-only objects.
|
||||
func newMetadataInformersMap(config *rest.Config, scheme *runtime.Scheme, mapper meta.RESTMapper, resync time.Duration,
|
||||
namespace string, selectors SelectorsByGVK) *specificInformersMap {
|
||||
return newSpecificInformersMap(config, scheme, mapper, resync, namespace, selectors, createMetadataListWatch)
|
||||
namespace string, selectors SelectorsByGVK, disableDeepCopy DisableDeepCopyByGVK) *specificInformersMap {
|
||||
return newSpecificInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy, createMetadataListWatch)
|
||||
}
|
||||
|
35
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/disabledeepcopy.go
generated
vendored
Normal file
35
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/disabledeepcopy.go
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright 2021 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 internal
|
||||
|
||||
import "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
// GroupVersionKindAll is the argument to represent all GroupVersionKind types.
|
||||
var GroupVersionKindAll = schema.GroupVersionKind{}
|
||||
|
||||
// DisableDeepCopyByGVK associate a GroupVersionKind to disable DeepCopy during get or list from cache.
|
||||
type DisableDeepCopyByGVK map[schema.GroupVersionKind]bool
|
||||
|
||||
// IsDisabled returns whether a GroupVersionKind is disabled DeepCopy.
|
||||
func (disableByGVK DisableDeepCopyByGVK) IsDisabled(gvk schema.GroupVersionKind) bool {
|
||||
if d, ok := disableByGVK[gvk]; ok {
|
||||
return d
|
||||
} else if d, ok = disableByGVK[GroupVersionKindAll]; ok {
|
||||
return d
|
||||
}
|
||||
return false
|
||||
}
|
62
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers_map.go
generated
vendored
62
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers_map.go
generated
vendored
@ -52,6 +52,7 @@ func newSpecificInformersMap(config *rest.Config,
|
||||
resync time.Duration,
|
||||
namespace string,
|
||||
selectors SelectorsByGVK,
|
||||
disableDeepCopy DisableDeepCopyByGVK,
|
||||
createListWatcher createListWatcherFunc) *specificInformersMap {
|
||||
ip := &specificInformersMap{
|
||||
config: config,
|
||||
@ -65,6 +66,7 @@ func newSpecificInformersMap(config *rest.Config,
|
||||
createListWatcher: createListWatcher,
|
||||
namespace: namespace,
|
||||
selectors: selectors,
|
||||
disableDeepCopy: disableDeepCopy,
|
||||
}
|
||||
return ip
|
||||
}
|
||||
@ -129,6 +131,9 @@ type specificInformersMap struct {
|
||||
// selectors are the label or field selectors that will be added to the
|
||||
// ListWatch ListOptions.
|
||||
selectors SelectorsByGVK
|
||||
|
||||
// disableDeepCopy indicates not to deep copy objects during get or list objects.
|
||||
disableDeepCopy DisableDeepCopyByGVK
|
||||
}
|
||||
|
||||
// Start calls Run on each of the informers and sets started to true. Blocks on the context.
|
||||
@ -234,7 +239,12 @@ func (ip *specificInformersMap) addInformerToMap(gvk schema.GroupVersionKind, ob
|
||||
|
||||
i := &MapEntry{
|
||||
Informer: ni,
|
||||
Reader: CacheReader{indexer: ni.GetIndexer(), groupVersionKind: gvk, scopeName: rm.Scope.Name()},
|
||||
Reader: CacheReader{
|
||||
indexer: ni.GetIndexer(),
|
||||
groupVersionKind: gvk,
|
||||
scopeName: rm.Scope.Name(),
|
||||
disableDeepCopy: ip.disableDeepCopy.IsDisabled(gvk),
|
||||
},
|
||||
}
|
||||
ip.informersByGVK[gvk] = i
|
||||
|
||||
@ -274,8 +284,9 @@ func createStructuredListWatch(gvk schema.GroupVersionKind, ip *specificInformer
|
||||
ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) {
|
||||
ip.selectors[gvk].ApplyToList(&opts)
|
||||
res := listObj.DeepCopyObject()
|
||||
isNamespaceScoped := ip.namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot
|
||||
err := client.Get().NamespaceIfScoped(ip.namespace, isNamespaceScoped).Resource(mapping.Resource.Resource).VersionedParams(&opts, ip.paramCodec).Do(ctx).Into(res)
|
||||
namespace := restrictNamespaceBySelector(ip.namespace, ip.selectors[gvk])
|
||||
isNamespaceScoped := namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot
|
||||
err := client.Get().NamespaceIfScoped(namespace, isNamespaceScoped).Resource(mapping.Resource.Resource).VersionedParams(&opts, ip.paramCodec).Do(ctx).Into(res)
|
||||
return res, err
|
||||
},
|
||||
// Setup the watch function
|
||||
@ -283,8 +294,9 @@ func createStructuredListWatch(gvk schema.GroupVersionKind, ip *specificInformer
|
||||
ip.selectors[gvk].ApplyToList(&opts)
|
||||
// Watch needs to be set to true separately
|
||||
opts.Watch = true
|
||||
isNamespaceScoped := ip.namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot
|
||||
return client.Get().NamespaceIfScoped(ip.namespace, isNamespaceScoped).Resource(mapping.Resource.Resource).VersionedParams(&opts, ip.paramCodec).Watch(ctx)
|
||||
namespace := restrictNamespaceBySelector(ip.namespace, ip.selectors[gvk])
|
||||
isNamespaceScoped := namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot
|
||||
return client.Get().NamespaceIfScoped(namespace, isNamespaceScoped).Resource(mapping.Resource.Resource).VersionedParams(&opts, ip.paramCodec).Watch(ctx)
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
@ -313,8 +325,9 @@ func createUnstructuredListWatch(gvk schema.GroupVersionKind, ip *specificInform
|
||||
return &cache.ListWatch{
|
||||
ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) {
|
||||
ip.selectors[gvk].ApplyToList(&opts)
|
||||
if ip.namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot {
|
||||
return dynamicClient.Resource(mapping.Resource).Namespace(ip.namespace).List(ctx, opts)
|
||||
namespace := restrictNamespaceBySelector(ip.namespace, ip.selectors[gvk])
|
||||
if namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot {
|
||||
return dynamicClient.Resource(mapping.Resource).Namespace(namespace).List(ctx, opts)
|
||||
}
|
||||
return dynamicClient.Resource(mapping.Resource).List(ctx, opts)
|
||||
},
|
||||
@ -323,8 +336,9 @@ func createUnstructuredListWatch(gvk schema.GroupVersionKind, ip *specificInform
|
||||
ip.selectors[gvk].ApplyToList(&opts)
|
||||
// Watch needs to be set to true separately
|
||||
opts.Watch = true
|
||||
if ip.namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot {
|
||||
return dynamicClient.Resource(mapping.Resource).Namespace(ip.namespace).Watch(ctx, opts)
|
||||
namespace := restrictNamespaceBySelector(ip.namespace, ip.selectors[gvk])
|
||||
if namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot {
|
||||
return dynamicClient.Resource(mapping.Resource).Namespace(namespace).Watch(ctx, opts)
|
||||
}
|
||||
return dynamicClient.Resource(mapping.Resource).Watch(ctx, opts)
|
||||
},
|
||||
@ -358,8 +372,9 @@ func createMetadataListWatch(gvk schema.GroupVersionKind, ip *specificInformersM
|
||||
return &cache.ListWatch{
|
||||
ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) {
|
||||
ip.selectors[gvk].ApplyToList(&opts)
|
||||
if ip.namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot {
|
||||
return client.Resource(mapping.Resource).Namespace(ip.namespace).List(ctx, opts)
|
||||
namespace := restrictNamespaceBySelector(ip.namespace, ip.selectors[gvk])
|
||||
if namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot {
|
||||
return client.Resource(mapping.Resource).Namespace(namespace).List(ctx, opts)
|
||||
}
|
||||
return client.Resource(mapping.Resource).List(ctx, opts)
|
||||
},
|
||||
@ -368,8 +383,9 @@ func createMetadataListWatch(gvk schema.GroupVersionKind, ip *specificInformersM
|
||||
ip.selectors[gvk].ApplyToList(&opts)
|
||||
// Watch needs to be set to true separately
|
||||
opts.Watch = true
|
||||
if ip.namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot {
|
||||
return client.Resource(mapping.Resource).Namespace(ip.namespace).Watch(ctx, opts)
|
||||
namespace := restrictNamespaceBySelector(ip.namespace, ip.selectors[gvk])
|
||||
if namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot {
|
||||
return client.Resource(mapping.Resource).Namespace(namespace).Watch(ctx, opts)
|
||||
}
|
||||
return client.Resource(mapping.Resource).Watch(ctx, opts)
|
||||
},
|
||||
@ -386,3 +402,23 @@ func resyncPeriod(resync time.Duration) func() time.Duration {
|
||||
return time.Duration(float64(resync.Nanoseconds()) * factor)
|
||||
}
|
||||
}
|
||||
|
||||
// restrictNamespaceBySelector returns either a global restriction for all ListWatches
|
||||
// if not default/empty, or the namespace that a ListWatch for the specific resource
|
||||
// is restricted to, based on a specified field selector for metadata.namespace field.
|
||||
func restrictNamespaceBySelector(namespaceOpt string, s Selector) string {
|
||||
if namespaceOpt != "" {
|
||||
// namespace is already restricted
|
||||
return namespaceOpt
|
||||
}
|
||||
fieldSelector := s.Field
|
||||
if fieldSelector == nil || fieldSelector.Empty() {
|
||||
return ""
|
||||
}
|
||||
// check whether a selector includes the namespace field
|
||||
value, found := fieldSelector.RequiresExactMatch("metadata.namespace")
|
||||
if found {
|
||||
return value
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
29
vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/apimachinery.go
generated
vendored
29
vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/apimachinery.go
generated
vendored
@ -21,6 +21,7 @@ package apiutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
@ -163,9 +164,35 @@ func createRestConfig(gvk schema.GroupVersionKind, isUnstructured bool, baseConf
|
||||
// Use our own custom serializer.
|
||||
cfg.NegotiatedSerializer = serializerWithDecodedGVK{serializer.WithoutConversionCodecFactory{CodecFactory: codecs}}
|
||||
} else {
|
||||
cfg.NegotiatedSerializer = serializer.WithoutConversionCodecFactory{CodecFactory: codecs}
|
||||
cfg.NegotiatedSerializer = serializerWithTargetZeroingDecode{NegotiatedSerializer: serializer.WithoutConversionCodecFactory{CodecFactory: codecs}}
|
||||
}
|
||||
}
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
type serializerWithTargetZeroingDecode struct {
|
||||
runtime.NegotiatedSerializer
|
||||
}
|
||||
|
||||
func (s serializerWithTargetZeroingDecode) DecoderToVersion(serializer runtime.Decoder, r runtime.GroupVersioner) runtime.Decoder {
|
||||
return targetZeroingDecoder{upstream: s.NegotiatedSerializer.DecoderToVersion(serializer, r)}
|
||||
}
|
||||
|
||||
type targetZeroingDecoder struct {
|
||||
upstream runtime.Decoder
|
||||
}
|
||||
|
||||
func (t targetZeroingDecoder) Decode(data []byte, defaults *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
|
||||
zero(into)
|
||||
return t.upstream.Decode(data, defaults, into)
|
||||
}
|
||||
|
||||
// zero zeros the value of a pointer.
|
||||
func zero(x interface{}) {
|
||||
if x == nil {
|
||||
return
|
||||
}
|
||||
res := reflect.ValueOf(x).Elem()
|
||||
res.Set(reflect.Zero(res.Type()))
|
||||
}
|
||||
|
63
vendor/sigs.k8s.io/controller-runtime/pkg/client/namespaced_client.go
generated
vendored
63
vendor/sigs.k8s.io/controller-runtime/pkg/client/namespaced_client.go
generated
vendored
@ -18,14 +18,11 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||
"sigs.k8s.io/controller-runtime/pkg/internal/objectutil"
|
||||
)
|
||||
|
||||
// NewNamespacedClient wraps an existing client enforcing the namespace value.
|
||||
@ -55,49 +52,9 @@ func (n *namespacedClient) RESTMapper() meta.RESTMapper {
|
||||
return n.client.RESTMapper()
|
||||
}
|
||||
|
||||
// isNamespaced returns true if the object is namespace scoped.
|
||||
// For unstructured objects the gvk is found from the object itself.
|
||||
// TODO: this is repetitive code. Remove this and use ojectutil.IsNamespaced.
|
||||
func isNamespaced(c Client, obj runtime.Object) (bool, error) {
|
||||
var gvk schema.GroupVersionKind
|
||||
var err error
|
||||
|
||||
_, isUnstructured := obj.(*unstructured.Unstructured)
|
||||
_, isUnstructuredList := obj.(*unstructured.UnstructuredList)
|
||||
|
||||
isUnstructured = isUnstructured || isUnstructuredList
|
||||
if isUnstructured {
|
||||
gvk = obj.GetObjectKind().GroupVersionKind()
|
||||
} else {
|
||||
gvk, err = apiutil.GVKForObject(obj, c.Scheme())
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
gk := schema.GroupKind{
|
||||
Group: gvk.Group,
|
||||
Kind: gvk.Kind,
|
||||
}
|
||||
restmapping, err := c.RESTMapper().RESTMapping(gk)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to get restmapping: %w", err)
|
||||
}
|
||||
scope := restmapping.Scope.Name()
|
||||
|
||||
if scope == "" {
|
||||
return false, errors.New("scope cannot be identified, empty scope returned")
|
||||
}
|
||||
|
||||
if scope != meta.RESTScopeNameRoot {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Create implements clinet.Client.
|
||||
func (n *namespacedClient) Create(ctx context.Context, obj Object, opts ...CreateOption) error {
|
||||
isNamespaceScoped, err := isNamespaced(n.client, obj)
|
||||
isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, n.Scheme(), n.RESTMapper())
|
||||
if err != nil {
|
||||
return fmt.Errorf("error finding the scope of the object: %v", err)
|
||||
}
|
||||
@ -115,7 +72,7 @@ func (n *namespacedClient) Create(ctx context.Context, obj Object, opts ...Creat
|
||||
|
||||
// Update implements client.Client.
|
||||
func (n *namespacedClient) Update(ctx context.Context, obj Object, opts ...UpdateOption) error {
|
||||
isNamespaceScoped, err := isNamespaced(n.client, obj)
|
||||
isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, n.Scheme(), n.RESTMapper())
|
||||
if err != nil {
|
||||
return fmt.Errorf("error finding the scope of the object: %v", err)
|
||||
}
|
||||
@ -133,7 +90,7 @@ func (n *namespacedClient) Update(ctx context.Context, obj Object, opts ...Updat
|
||||
|
||||
// Delete implements client.Client.
|
||||
func (n *namespacedClient) Delete(ctx context.Context, obj Object, opts ...DeleteOption) error {
|
||||
isNamespaceScoped, err := isNamespaced(n.client, obj)
|
||||
isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, n.Scheme(), n.RESTMapper())
|
||||
if err != nil {
|
||||
return fmt.Errorf("error finding the scope of the object: %v", err)
|
||||
}
|
||||
@ -151,7 +108,7 @@ func (n *namespacedClient) Delete(ctx context.Context, obj Object, opts ...Delet
|
||||
|
||||
// DeleteAllOf implements client.Client.
|
||||
func (n *namespacedClient) DeleteAllOf(ctx context.Context, obj Object, opts ...DeleteAllOfOption) error {
|
||||
isNamespaceScoped, err := isNamespaced(n.client, obj)
|
||||
isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, n.Scheme(), n.RESTMapper())
|
||||
if err != nil {
|
||||
return fmt.Errorf("error finding the scope of the object: %v", err)
|
||||
}
|
||||
@ -164,7 +121,7 @@ func (n *namespacedClient) DeleteAllOf(ctx context.Context, obj Object, opts ...
|
||||
|
||||
// Patch implements client.Client.
|
||||
func (n *namespacedClient) Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error {
|
||||
isNamespaceScoped, err := isNamespaced(n.client, obj)
|
||||
isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, n.Scheme(), n.RESTMapper())
|
||||
if err != nil {
|
||||
return fmt.Errorf("error finding the scope of the object: %v", err)
|
||||
}
|
||||
@ -182,7 +139,7 @@ func (n *namespacedClient) Patch(ctx context.Context, obj Object, patch Patch, o
|
||||
|
||||
// Get implements client.Client.
|
||||
func (n *namespacedClient) Get(ctx context.Context, key ObjectKey, obj Object) error {
|
||||
isNamespaceScoped, err := isNamespaced(n.client, obj)
|
||||
isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, n.Scheme(), n.RESTMapper())
|
||||
if err != nil {
|
||||
return fmt.Errorf("error finding the scope of the object: %v", err)
|
||||
}
|
||||
@ -219,7 +176,8 @@ type namespacedClientStatusWriter struct {
|
||||
|
||||
// Update implements client.StatusWriter.
|
||||
func (nsw *namespacedClientStatusWriter) Update(ctx context.Context, obj Object, opts ...UpdateOption) error {
|
||||
isNamespaceScoped, err := isNamespaced(nsw.namespacedclient, obj)
|
||||
isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, nsw.namespacedclient.Scheme(), nsw.namespacedclient.RESTMapper())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("error finding the scope of the object: %v", err)
|
||||
}
|
||||
@ -237,7 +195,8 @@ func (nsw *namespacedClientStatusWriter) Update(ctx context.Context, obj Object,
|
||||
|
||||
// Patch implements client.StatusWriter.
|
||||
func (nsw *namespacedClientStatusWriter) Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error {
|
||||
isNamespaceScoped, err := isNamespaced(nsw.namespacedclient, obj)
|
||||
isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, nsw.namespacedclient.Scheme(), nsw.namespacedclient.RESTMapper())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("error finding the scope of the object: %v", err)
|
||||
}
|
||||
|
4
vendor/sigs.k8s.io/controller-runtime/pkg/controller/controller.go
generated
vendored
4
vendor/sigs.k8s.io/controller-runtime/pkg/controller/controller.go
generated
vendored
@ -52,6 +52,9 @@ type Options struct {
|
||||
// CacheSyncTimeout refers to the time limit set to wait for syncing caches.
|
||||
// Defaults to 2 minutes if not set.
|
||||
CacheSyncTimeout time.Duration
|
||||
|
||||
// RecoverPanic indicates whether the panic caused by reconcile should be recovered.
|
||||
RecoverPanic bool
|
||||
}
|
||||
|
||||
// Controller implements a Kubernetes API. A Controller manages a work queue fed reconcile.Requests
|
||||
@ -133,5 +136,6 @@ func NewUnmanaged(name string, mgr manager.Manager, options Options) (Controller
|
||||
SetFields: mgr.SetFields,
|
||||
Name: name,
|
||||
Log: options.Log.WithName("controller").WithName(name),
|
||||
RecoverPanic: options.RecoverPanic,
|
||||
}, nil
|
||||
}
|
||||
|
17
vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go
generated
vendored
17
vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go
generated
vendored
@ -85,6 +85,9 @@ type Controller struct {
|
||||
|
||||
// Log is used to log messages to users during reconciliation, or for example when a watch is started.
|
||||
Log logr.Logger
|
||||
|
||||
// RecoverPanic indicates whether the panic caused by reconcile should be recovered.
|
||||
RecoverPanic bool
|
||||
}
|
||||
|
||||
// watchDescription contains all the information necessary to start a watch.
|
||||
@ -95,7 +98,17 @@ type watchDescription struct {
|
||||
}
|
||||
|
||||
// Reconcile implements reconcile.Reconciler.
|
||||
func (c *Controller) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {
|
||||
func (c *Controller) Reconcile(ctx context.Context, req reconcile.Request) (_ reconcile.Result, err error) {
|
||||
if c.RecoverPanic {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
for _, fn := range utilruntime.PanicHandlers {
|
||||
fn(r)
|
||||
}
|
||||
err = fmt.Errorf("panic: %v [recovered]", r)
|
||||
}
|
||||
}()
|
||||
}
|
||||
log := c.Log.WithValues("name", req.Name, "namespace", req.Namespace)
|
||||
ctx = logf.IntoContext(ctx, log)
|
||||
return c.Do.Reconcile(ctx, req)
|
||||
@ -295,7 +308,7 @@ func (c *Controller) reconcileHandler(ctx context.Context, obj interface{}) {
|
||||
|
||||
// RunInformersAndControllers the syncHandler, passing it the Namespace/Name string of the
|
||||
// resource to be synced.
|
||||
result, err := c.Do.Reconcile(ctx, req)
|
||||
result, err := c.Reconcile(ctx, req)
|
||||
switch {
|
||||
case err != nil:
|
||||
c.Queue.AddRateLimited(req)
|
||||
|
13
vendor/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder.go
generated
vendored
13
vendor/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder.go
generated
vendored
@ -24,8 +24,7 @@ import (
|
||||
"github.com/go-logr/logr"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/record"
|
||||
)
|
||||
@ -45,7 +44,7 @@ type Provider struct {
|
||||
scheme *runtime.Scheme
|
||||
// logger is the logger to use when logging diagnostic event info
|
||||
logger logr.Logger
|
||||
evtClient typedcorev1.EventInterface
|
||||
evtClient corev1client.EventInterface
|
||||
makeBroadcaster EventBroadcasterProducer
|
||||
|
||||
broadcasterOnce sync.Once
|
||||
@ -98,7 +97,7 @@ func (p *Provider) getBroadcaster() record.EventBroadcaster {
|
||||
|
||||
p.broadcasterOnce.Do(func() {
|
||||
broadcaster, stop := p.makeBroadcaster()
|
||||
broadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: p.evtClient})
|
||||
broadcaster.StartRecordingToSink(&corev1client.EventSinkImpl{Interface: p.evtClient})
|
||||
broadcaster.StartEventWatcher(
|
||||
func(e *corev1.Event) {
|
||||
p.logger.V(1).Info(e.Type, "object", e.InvolvedObject, "reason", e.Reason, "message", e.Message)
|
||||
@ -112,12 +111,12 @@ func (p *Provider) getBroadcaster() record.EventBroadcaster {
|
||||
|
||||
// NewProvider create a new Provider instance.
|
||||
func NewProvider(config *rest.Config, scheme *runtime.Scheme, logger logr.Logger, makeBroadcaster EventBroadcasterProducer) (*Provider, error) {
|
||||
clientSet, err := kubernetes.NewForConfig(config)
|
||||
corev1Client, err := corev1client.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to init clientSet: %w", err)
|
||||
return nil, fmt.Errorf("failed to init client: %w", err)
|
||||
}
|
||||
|
||||
p := &Provider{scheme: scheme, logger: logger, makeBroadcaster: makeBroadcaster, evtClient: clientSet.CoreV1().Events("")}
|
||||
p := &Provider{scheme: scheme, logger: logger, makeBroadcaster: makeBroadcaster, evtClient: corev1Client.Events("")}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
|
17
vendor/sigs.k8s.io/controller-runtime/pkg/leaderelection/leader_election.go
generated
vendored
17
vendor/sigs.k8s.io/controller-runtime/pkg/leaderelection/leader_election.go
generated
vendored
@ -23,7 +23,8 @@ import (
|
||||
"os"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/uuid"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
coordinationv1client "k8s.io/client-go/kubernetes/typed/coordination/v1"
|
||||
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/leaderelection/resourcelock"
|
||||
"sigs.k8s.io/controller-runtime/pkg/recorder"
|
||||
@ -84,8 +85,14 @@ func NewResourceLock(config *rest.Config, recorderProvider recorder.Provider, op
|
||||
}
|
||||
id = id + "_" + string(uuid.NewUUID())
|
||||
|
||||
// Construct client for leader election
|
||||
client, err := kubernetes.NewForConfig(rest.AddUserAgent(config, "leader-election"))
|
||||
// Construct clients for leader election
|
||||
rest.AddUserAgent(config, "leader-election")
|
||||
corev1Client, err := corev1client.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
coordinationClient, err := coordinationv1client.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -93,8 +100,8 @@ func NewResourceLock(config *rest.Config, recorderProvider recorder.Provider, op
|
||||
return resourcelock.New(options.LeaderElectionResourceLock,
|
||||
options.LeaderElectionNamespace,
|
||||
options.LeaderElectionID,
|
||||
client.CoreV1(),
|
||||
client.CoordinationV1(),
|
||||
corev1Client,
|
||||
coordinationClient,
|
||||
resourcelock.ResourceLockConfig{
|
||||
Identity: id,
|
||||
EventRecorder: recorderProvider.GetEventRecorderFor(id),
|
||||
|
2
vendor/sigs.k8s.io/controller-runtime/pkg/log/deleg.go
generated
vendored
2
vendor/sigs.k8s.io/controller-runtime/pkg/log/deleg.go
generated
vendored
@ -76,7 +76,7 @@ func (p *loggerPromise) V(l *DelegatingLogger, level int) *loggerPromise {
|
||||
|
||||
// Fulfill instantiates the Logger with the provided logger.
|
||||
func (p *loggerPromise) Fulfill(parentLogger logr.Logger) {
|
||||
var logger = parentLogger
|
||||
logger := logr.WithCallDepth(parentLogger, 1)
|
||||
if p.name != nil {
|
||||
logger = logger.WithName(*p.name)
|
||||
}
|
||||
|
2
vendor/sigs.k8s.io/controller-runtime/pkg/manager/internal.go
generated
vendored
2
vendor/sigs.k8s.io/controller-runtime/pkg/manager/internal.go
generated
vendored
@ -47,7 +47,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// Values taken from: https://github.com/kubernetes/apiserver/blob/master/pkg/apis/config/v1alpha1/defaults.go
|
||||
// Values taken from: https://github.com/kubernetes/component-base/blob/master/config/v1alpha1/defaults.go
|
||||
defaultLeaseDuration = 15 * time.Second
|
||||
defaultRenewDeadline = 10 * time.Second
|
||||
defaultRetryPeriod = 2 * time.Second
|
||||
|
4
vendor/sigs.k8s.io/controller-runtime/pkg/manager/manager.go
generated
vendored
4
vendor/sigs.k8s.io/controller-runtime/pkg/manager/manager.go
generated
vendored
@ -37,9 +37,9 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/config"
|
||||
"sigs.k8s.io/controller-runtime/pkg/config/v1alpha1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/healthz"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/internal/log"
|
||||
intrec "sigs.k8s.io/controller-runtime/pkg/internal/recorder"
|
||||
"sigs.k8s.io/controller-runtime/pkg/leaderelection"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/metrics"
|
||||
"sigs.k8s.io/controller-runtime/pkg/recorder"
|
||||
"sigs.k8s.io/controller-runtime/pkg/runtime/inject"
|
||||
@ -572,7 +572,7 @@ func setOptionsDefaults(options Options) Options {
|
||||
}
|
||||
|
||||
if options.Logger == nil {
|
||||
options.Logger = logf.RuntimeLog.WithName("manager")
|
||||
options.Logger = log.Log
|
||||
}
|
||||
|
||||
return options
|
||||
|
29
vendor/sigs.k8s.io/controller-runtime/pkg/metrics/client_go_adapter.go
generated
vendored
29
vendor/sigs.k8s.io/controller-runtime/pkg/metrics/client_go_adapter.go
generated
vendored
@ -52,7 +52,24 @@ const (
|
||||
|
||||
var (
|
||||
// client metrics.
|
||||
requestLatency = prometheus.NewHistogramVec(prometheus.HistogramOpts{
|
||||
|
||||
// RequestLatency reports the request latency in seconds per verb/URL.
|
||||
// Deprecated: This metric is deprecated for removal in a future release: using the URL as a
|
||||
// dimension results in cardinality explosion for some consumers. It was deprecated upstream
|
||||
// in k8s v1.14 and hidden in v1.17 via https://github.com/kubernetes/kubernetes/pull/83836.
|
||||
// It is not registered by default. To register:
|
||||
// import (
|
||||
// clientmetrics "k8s.io/client-go/tools/metrics"
|
||||
// clmetrics "sigs.k8s.io/controller-runtime/metrics"
|
||||
// )
|
||||
//
|
||||
// func init() {
|
||||
// clmetrics.Registry.MustRegister(clmetrics.RequestLatency)
|
||||
// clientmetrics.Register(clientmetrics.RegisterOpts{
|
||||
// RequestLatency: clmetrics.LatencyAdapter
|
||||
// })
|
||||
// }
|
||||
RequestLatency = prometheus.NewHistogramVec(prometheus.HistogramOpts{
|
||||
Subsystem: RestClientSubsystem,
|
||||
Name: LatencyKey,
|
||||
Help: "Request latency in seconds. Broken down by verb and URL.",
|
||||
@ -127,13 +144,11 @@ func init() {
|
||||
// registerClientMetrics sets up the client latency metrics from client-go.
|
||||
func registerClientMetrics() {
|
||||
// register the metrics with our registry
|
||||
Registry.MustRegister(requestLatency)
|
||||
Registry.MustRegister(requestResult)
|
||||
|
||||
// register the metrics with client-go
|
||||
clientmetrics.Register(clientmetrics.RegisterOpts{
|
||||
RequestLatency: &latencyAdapter{metric: requestLatency},
|
||||
RequestResult: &resultAdapter{metric: requestResult},
|
||||
RequestResult: &resultAdapter{metric: requestResult},
|
||||
})
|
||||
}
|
||||
|
||||
@ -159,11 +174,13 @@ func registerReflectorMetrics() {
|
||||
// copied (more-or-less directly) from k8s.io/kubernetes setup code
|
||||
// (which isn't anywhere in an easily-importable place).
|
||||
|
||||
type latencyAdapter struct {
|
||||
// LatencyAdapter implements LatencyMetric.
|
||||
type LatencyAdapter struct {
|
||||
metric *prometheus.HistogramVec
|
||||
}
|
||||
|
||||
func (l *latencyAdapter) Observe(_ context.Context, verb string, u url.URL, latency time.Duration) {
|
||||
// Observe increments the request latency metric for the given verb/URL.
|
||||
func (l *LatencyAdapter) Observe(_ context.Context, verb string, u url.URL, latency time.Duration) {
|
||||
l.metric.WithLabelValues(verb, u.String()).Observe(latency.Seconds())
|
||||
}
|
||||
|
||||
|
37
vendor/sigs.k8s.io/controller-runtime/pkg/webhook/server.go
generated
vendored
37
vendor/sigs.k8s.io/controller-runtime/pkg/webhook/server.go
generated
vendored
@ -28,10 +28,12 @@ import (
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
kscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
"sigs.k8s.io/controller-runtime/pkg/certwatcher"
|
||||
"sigs.k8s.io/controller-runtime/pkg/healthz"
|
||||
"sigs.k8s.io/controller-runtime/pkg/runtime/inject"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics"
|
||||
)
|
||||
@ -87,6 +89,10 @@ type Server struct {
|
||||
// defaultingOnce ensures that the default fields are only ever set once.
|
||||
defaultingOnce sync.Once
|
||||
|
||||
// started is set to true immediately before the server is started
|
||||
// and thus can be used to check if the server has been started
|
||||
started bool
|
||||
|
||||
// mu protects access to the webhook map & setFields for Start, Register, etc
|
||||
mu sync.Mutex
|
||||
}
|
||||
@ -272,6 +278,9 @@ func (s *Server) Start(ctx context.Context) error {
|
||||
close(idleConnsClosed)
|
||||
}()
|
||||
|
||||
s.mu.Lock()
|
||||
s.started = true
|
||||
s.mu.Unlock()
|
||||
if err := srv.Serve(listener); err != nil && err != http.ErrServerClosed {
|
||||
return err
|
||||
}
|
||||
@ -280,6 +289,34 @@ func (s *Server) Start(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// StartedChecker returns an healthz.Checker which is healthy after the
|
||||
// server has been started.
|
||||
func (s *Server) StartedChecker() healthz.Checker {
|
||||
config := &tls.Config{
|
||||
InsecureSkipVerify: true, // nolint:gosec // config is used to connect to our own webhook port.
|
||||
}
|
||||
return func(req *http.Request) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if !s.started {
|
||||
return fmt.Errorf("webhook server has not been started yet")
|
||||
}
|
||||
|
||||
d := &net.Dialer{Timeout: 10 * time.Second}
|
||||
conn, err := tls.DialWithDialer(d, "tcp", net.JoinHostPort(s.Host, strconv.Itoa(s.Port)), config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("webhook server is not reachable: %v", err)
|
||||
}
|
||||
|
||||
if err := conn.Close(); err != nil {
|
||||
return fmt.Errorf("webhook server is not reachable: closing connection: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// InjectFunc injects the field setter into the server.
|
||||
func (s *Server) InjectFunc(f inject.Func) error {
|
||||
s.setFields = f
|
||||
|
Reference in New Issue
Block a user