mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-09 21:21:14 +00:00
Merge pull request #105623 from ash2k/ash2k/resettable-rest-mapper
ResettableRESTMapper to make it possible to reset wrapped mappers
This commit is contained in:
@@ -24,8 +24,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"k8s.io/klog/v2"
|
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
@@ -45,6 +43,7 @@ import (
|
|||||||
"k8s.io/client-go/util/workqueue"
|
"k8s.io/client-go/util/workqueue"
|
||||||
"k8s.io/controller-manager/controller"
|
"k8s.io/controller-manager/controller"
|
||||||
"k8s.io/controller-manager/pkg/informerfactory"
|
"k8s.io/controller-manager/pkg/informerfactory"
|
||||||
|
"k8s.io/klog/v2"
|
||||||
c "k8s.io/kubernetes/pkg/controller"
|
c "k8s.io/kubernetes/pkg/controller"
|
||||||
"k8s.io/kubernetes/pkg/controller/apis/config/scheme"
|
"k8s.io/kubernetes/pkg/controller/apis/config/scheme"
|
||||||
|
|
||||||
@@ -67,7 +66,7 @@ const ResourceResyncTime time.Duration = 0
|
|||||||
// ensures that the garbage collector operates with a graph that is at least as
|
// ensures that the garbage collector operates with a graph that is at least as
|
||||||
// up to date as the notification is sent.
|
// up to date as the notification is sent.
|
||||||
type GarbageCollector struct {
|
type GarbageCollector struct {
|
||||||
restMapper resettableRESTMapper
|
restMapper meta.ResettableRESTMapper
|
||||||
metadataClient metadata.Interface
|
metadataClient metadata.Interface
|
||||||
// garbage collector attempts to delete the items in attemptToDelete queue when the time is ripe.
|
// garbage collector attempts to delete the items in attemptToDelete queue when the time is ripe.
|
||||||
attemptToDelete workqueue.RateLimitingInterface
|
attemptToDelete workqueue.RateLimitingInterface
|
||||||
@@ -87,7 +86,7 @@ var _ controller.Debuggable = (*GarbageCollector)(nil)
|
|||||||
func NewGarbageCollector(
|
func NewGarbageCollector(
|
||||||
kubeClient clientset.Interface,
|
kubeClient clientset.Interface,
|
||||||
metadataClient metadata.Interface,
|
metadataClient metadata.Interface,
|
||||||
mapper resettableRESTMapper,
|
mapper meta.ResettableRESTMapper,
|
||||||
ignoredResources map[schema.GroupResource]struct{},
|
ignoredResources map[schema.GroupResource]struct{},
|
||||||
sharedInformers informerfactory.InformerFactory,
|
sharedInformers informerfactory.InformerFactory,
|
||||||
informersStarted <-chan struct{},
|
informersStarted <-chan struct{},
|
||||||
@@ -164,13 +163,6 @@ func (gc *GarbageCollector) Run(ctx context.Context, workers int) {
|
|||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
}
|
}
|
||||||
|
|
||||||
// resettableRESTMapper is a RESTMapper which is capable of resetting itself
|
|
||||||
// from discovery.
|
|
||||||
type resettableRESTMapper interface {
|
|
||||||
meta.RESTMapper
|
|
||||||
Reset()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sync periodically resyncs the garbage collector when new resources are
|
// Sync periodically resyncs the garbage collector when new resources are
|
||||||
// observed from discovery. When new resources are detected, Sync will stop all
|
// observed from discovery. When new resources are detected, Sync will stop all
|
||||||
// GC workers, reset gc.restMapper, and resync the monitors.
|
// GC workers, reset gc.restMapper, and resync the monitors.
|
||||||
|
@@ -67,7 +67,9 @@ type testRESTMapper struct {
|
|||||||
meta.RESTMapper
|
meta.RESTMapper
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*testRESTMapper) Reset() {}
|
func (m *testRESTMapper) Reset() {
|
||||||
|
meta.MaybeResetRESTMapper(m.RESTMapper)
|
||||||
|
}
|
||||||
|
|
||||||
func TestGarbageCollectorConstruction(t *testing.T) {
|
func TestGarbageCollectorConstruction(t *testing.T) {
|
||||||
config := &restclient.Config{}
|
config := &restclient.Config{}
|
||||||
|
@@ -23,6 +23,10 @@ import (
|
|||||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ ResettableRESTMapper = &FirstHitRESTMapper{}
|
||||||
|
)
|
||||||
|
|
||||||
// FirstHitRESTMapper is a wrapper for multiple RESTMappers which returns the
|
// FirstHitRESTMapper is a wrapper for multiple RESTMappers which returns the
|
||||||
// first successful result for the singular requests
|
// first successful result for the singular requests
|
||||||
type FirstHitRESTMapper struct {
|
type FirstHitRESTMapper struct {
|
||||||
@@ -75,6 +79,10 @@ func (m FirstHitRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string)
|
|||||||
return nil, collapseAggregateErrors(errors)
|
return nil, collapseAggregateErrors(errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m FirstHitRESTMapper) Reset() {
|
||||||
|
m.MultiRESTMapper.Reset()
|
||||||
|
}
|
||||||
|
|
||||||
// collapseAggregateErrors returns the minimal errors. it handles empty as nil, handles one item in a list
|
// collapseAggregateErrors returns the minimal errors. it handles empty as nil, handles one item in a list
|
||||||
// by returning the item, and collapses all NoMatchErrors to a single one (since they should all be the same)
|
// by returning the item, and collapses all NoMatchErrors to a single one (since they should all be the same)
|
||||||
func collapseAggregateErrors(errors []error) error {
|
func collapseAggregateErrors(errors []error) error {
|
||||||
|
@@ -132,3 +132,12 @@ type RESTMapper interface {
|
|||||||
|
|
||||||
ResourceSingularizer(resource string) (singular string, err error)
|
ResourceSingularizer(resource string) (singular string, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ResettableRESTMapper is a RESTMapper which is capable of resetting itself
|
||||||
|
// from discovery.
|
||||||
|
// All rest mappers that delegate to other rest mappers must implement this interface and dynamically
|
||||||
|
// check if the delegate mapper supports the Reset() operation.
|
||||||
|
type ResettableRESTMapper interface {
|
||||||
|
RESTMapper
|
||||||
|
Reset()
|
||||||
|
}
|
||||||
|
@@ -32,7 +32,7 @@ type lazyObject struct {
|
|||||||
mapper RESTMapper
|
mapper RESTMapper
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLazyObjectLoader handles unrecoverable errors when creating a RESTMapper / ObjectTyper by
|
// NewLazyRESTMapperLoader handles unrecoverable errors when creating a RESTMapper / ObjectTyper by
|
||||||
// returning those initialization errors when the interface methods are invoked. This defers the
|
// returning those initialization errors when the interface methods are invoked. This defers the
|
||||||
// initialization and any server calls until a client actually needs to perform the action.
|
// initialization and any server calls until a client actually needs to perform the action.
|
||||||
func NewLazyRESTMapperLoader(fn func() (RESTMapper, error)) RESTMapper {
|
func NewLazyRESTMapperLoader(fn func() (RESTMapper, error)) RESTMapper {
|
||||||
@@ -52,7 +52,7 @@ func (o *lazyObject) init() error {
|
|||||||
return o.err
|
return o.err
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ RESTMapper = &lazyObject{}
|
var _ ResettableRESTMapper = &lazyObject{}
|
||||||
|
|
||||||
func (o *lazyObject) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) {
|
func (o *lazyObject) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) {
|
||||||
if err := o.init(); err != nil {
|
if err := o.init(); err != nil {
|
||||||
@@ -102,3 +102,11 @@ func (o *lazyObject) ResourceSingularizer(resource string) (singular string, err
|
|||||||
}
|
}
|
||||||
return o.mapper.ResourceSingularizer(resource)
|
return o.mapper.ResourceSingularizer(resource)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *lazyObject) Reset() {
|
||||||
|
o.lock.Lock()
|
||||||
|
defer o.lock.Unlock()
|
||||||
|
if o.loaded && o.err == nil {
|
||||||
|
MaybeResetRESTMapper(o.mapper)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -24,11 +24,15 @@ import (
|
|||||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ ResettableRESTMapper = MultiRESTMapper{}
|
||||||
|
)
|
||||||
|
|
||||||
// MultiRESTMapper is a wrapper for multiple RESTMappers.
|
// MultiRESTMapper is a wrapper for multiple RESTMappers.
|
||||||
type MultiRESTMapper []RESTMapper
|
type MultiRESTMapper []RESTMapper
|
||||||
|
|
||||||
func (m MultiRESTMapper) String() string {
|
func (m MultiRESTMapper) String() string {
|
||||||
nested := []string{}
|
nested := make([]string, 0, len(m))
|
||||||
for _, t := range m {
|
for _, t := range m {
|
||||||
currString := fmt.Sprintf("%v", t)
|
currString := fmt.Sprintf("%v", t)
|
||||||
splitStrings := strings.Split(currString, "\n")
|
splitStrings := strings.Split(currString, "\n")
|
||||||
@@ -208,3 +212,9 @@ func (m MultiRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string) (
|
|||||||
}
|
}
|
||||||
return allMappings, nil
|
return allMappings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m MultiRESTMapper) Reset() {
|
||||||
|
for _, t := range m {
|
||||||
|
MaybeResetRESTMapper(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -29,6 +29,10 @@ const (
|
|||||||
AnyKind = "*"
|
AnyKind = "*"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ ResettableRESTMapper = PriorityRESTMapper{}
|
||||||
|
)
|
||||||
|
|
||||||
// PriorityRESTMapper is a wrapper for automatically choosing a particular Resource or Kind
|
// PriorityRESTMapper is a wrapper for automatically choosing a particular Resource or Kind
|
||||||
// when multiple matches are possible
|
// when multiple matches are possible
|
||||||
type PriorityRESTMapper struct {
|
type PriorityRESTMapper struct {
|
||||||
@@ -220,3 +224,7 @@ func (m PriorityRESTMapper) ResourcesFor(partiallySpecifiedResource schema.Group
|
|||||||
func (m PriorityRESTMapper) KindsFor(partiallySpecifiedResource schema.GroupVersionResource) (gvk []schema.GroupVersionKind, err error) {
|
func (m PriorityRESTMapper) KindsFor(partiallySpecifiedResource schema.GroupVersionResource) (gvk []schema.GroupVersionKind, err error) {
|
||||||
return m.Delegate.KindsFor(partiallySpecifiedResource)
|
return m.Delegate.KindsFor(partiallySpecifiedResource)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m PriorityRESTMapper) Reset() {
|
||||||
|
MaybeResetRESTMapper(m.Delegate)
|
||||||
|
}
|
||||||
|
@@ -519,3 +519,12 @@ func (m *DefaultRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string
|
|||||||
}
|
}
|
||||||
return mappings, nil
|
return mappings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MaybeResetRESTMapper calls Reset() on the mapper if it is a ResettableRESTMapper.
|
||||||
|
func MaybeResetRESTMapper(mapper RESTMapper) bool {
|
||||||
|
m, ok := mapper.(ResettableRESTMapper)
|
||||||
|
if ok {
|
||||||
|
m.Reset()
|
||||||
|
}
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
@@ -335,6 +335,10 @@ func (l *errorRestMapper) RESTMapping(gk schema.GroupKind, versions ...string) (
|
|||||||
return nil, l.err
|
return nil, l.err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *errorRestMapper) Reset() {
|
||||||
|
meta.MaybeResetRESTMapper(l.RESTMapper)
|
||||||
|
}
|
||||||
|
|
||||||
func newDefaultBuilderWithMapperError(fakeClientFn FakeClientFunc, err error) *Builder {
|
func newDefaultBuilderWithMapperError(fakeClientFn FakeClientFunc, err error) *Builder {
|
||||||
return NewFakeBuilder(
|
return NewFakeBuilder(
|
||||||
fakeClientFn,
|
fakeClientFn,
|
||||||
|
@@ -335,4 +335,4 @@ func (d *DeferredDiscoveryRESTMapper) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make sure it satisfies the interface
|
// Make sure it satisfies the interface
|
||||||
var _ meta.RESTMapper = &DeferredDiscoveryRESTMapper{}
|
var _ meta.ResettableRESTMapper = &DeferredDiscoveryRESTMapper{}
|
||||||
|
@@ -34,7 +34,7 @@ type shortcutExpander struct {
|
|||||||
discoveryClient discovery.DiscoveryInterface
|
discoveryClient discovery.DiscoveryInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ meta.RESTMapper = &shortcutExpander{}
|
var _ meta.ResettableRESTMapper = shortcutExpander{}
|
||||||
|
|
||||||
// NewShortcutExpander wraps a restmapper in a layer that expands shortcuts found via discovery
|
// NewShortcutExpander wraps a restmapper in a layer that expands shortcuts found via discovery
|
||||||
func NewShortcutExpander(delegate meta.RESTMapper, client discovery.DiscoveryInterface) meta.RESTMapper {
|
func NewShortcutExpander(delegate meta.RESTMapper, client discovery.DiscoveryInterface) meta.RESTMapper {
|
||||||
@@ -164,6 +164,10 @@ func (e shortcutExpander) expandResourceShortcut(resource schema.GroupVersionRes
|
|||||||
return resource
|
return resource
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e shortcutExpander) Reset() {
|
||||||
|
meta.MaybeResetRESTMapper(e.RESTMapper)
|
||||||
|
}
|
||||||
|
|
||||||
// ResourceShortcuts represents a structure that holds the information how to
|
// ResourceShortcuts represents a structure that holds the information how to
|
||||||
// transition from resource's shortcut to its full name.
|
// transition from resource's shortcut to its full name.
|
||||||
type resourceShortcuts struct {
|
type resourceShortcuts struct {
|
||||||
|
Reference in New Issue
Block a user