Merge pull request #105623 from ash2k/ash2k/resettable-rest-mapper
ResettableRESTMapper to make it possible to reset wrapped mappers
This commit is contained in:
commit
165b581759
@ -24,8 +24,6 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
@ -45,6 +43,7 @@ import (
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/controller-manager/controller"
|
||||
"k8s.io/controller-manager/pkg/informerfactory"
|
||||
"k8s.io/klog/v2"
|
||||
c "k8s.io/kubernetes/pkg/controller"
|
||||
"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
|
||||
// up to date as the notification is sent.
|
||||
type GarbageCollector struct {
|
||||
restMapper resettableRESTMapper
|
||||
restMapper meta.ResettableRESTMapper
|
||||
metadataClient metadata.Interface
|
||||
// garbage collector attempts to delete the items in attemptToDelete queue when the time is ripe.
|
||||
attemptToDelete workqueue.RateLimitingInterface
|
||||
@ -87,7 +86,7 @@ var _ controller.Debuggable = (*GarbageCollector)(nil)
|
||||
func NewGarbageCollector(
|
||||
kubeClient clientset.Interface,
|
||||
metadataClient metadata.Interface,
|
||||
mapper resettableRESTMapper,
|
||||
mapper meta.ResettableRESTMapper,
|
||||
ignoredResources map[schema.GroupResource]struct{},
|
||||
sharedInformers informerfactory.InformerFactory,
|
||||
informersStarted <-chan struct{},
|
||||
@ -164,13 +163,6 @@ func (gc *GarbageCollector) Run(ctx context.Context, workers int) {
|
||||
<-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
|
||||
// observed from discovery. When new resources are detected, Sync will stop all
|
||||
// GC workers, reset gc.restMapper, and resync the monitors.
|
||||
|
@ -67,7 +67,9 @@ type testRESTMapper struct {
|
||||
meta.RESTMapper
|
||||
}
|
||||
|
||||
func (*testRESTMapper) Reset() {}
|
||||
func (m *testRESTMapper) Reset() {
|
||||
meta.MaybeResetRESTMapper(m.RESTMapper)
|
||||
}
|
||||
|
||||
func TestGarbageCollectorConstruction(t *testing.T) {
|
||||
config := &restclient.Config{}
|
||||
|
@ -23,6 +23,10 @@ import (
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
_ ResettableRESTMapper = &FirstHitRESTMapper{}
|
||||
)
|
||||
|
||||
// FirstHitRESTMapper is a wrapper for multiple RESTMappers which returns the
|
||||
// first successful result for the singular requests
|
||||
type FirstHitRESTMapper struct {
|
||||
@ -75,6 +79,10 @@ func (m FirstHitRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string)
|
||||
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
|
||||
// by returning the item, and collapses all NoMatchErrors to a single one (since they should all be the same)
|
||||
func collapseAggregateErrors(errors []error) error {
|
||||
|
@ -132,3 +132,12 @@ type RESTMapper interface {
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
// initialization and any server calls until a client actually needs to perform the action.
|
||||
func NewLazyRESTMapperLoader(fn func() (RESTMapper, error)) RESTMapper {
|
||||
@ -52,7 +52,7 @@ func (o *lazyObject) init() error {
|
||||
return o.err
|
||||
}
|
||||
|
||||
var _ RESTMapper = &lazyObject{}
|
||||
var _ ResettableRESTMapper = &lazyObject{}
|
||||
|
||||
func (o *lazyObject) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) {
|
||||
if err := o.init(); err != nil {
|
||||
@ -102,3 +102,11 @@ func (o *lazyObject) ResourceSingularizer(resource string) (singular string, err
|
||||
}
|
||||
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"
|
||||
)
|
||||
|
||||
var (
|
||||
_ ResettableRESTMapper = MultiRESTMapper{}
|
||||
)
|
||||
|
||||
// MultiRESTMapper is a wrapper for multiple RESTMappers.
|
||||
type MultiRESTMapper []RESTMapper
|
||||
|
||||
func (m MultiRESTMapper) String() string {
|
||||
nested := []string{}
|
||||
nested := make([]string, 0, len(m))
|
||||
for _, t := range m {
|
||||
currString := fmt.Sprintf("%v", t)
|
||||
splitStrings := strings.Split(currString, "\n")
|
||||
@ -208,3 +212,9 @@ func (m MultiRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string) (
|
||||
}
|
||||
return allMappings, nil
|
||||
}
|
||||
|
||||
func (m MultiRESTMapper) Reset() {
|
||||
for _, t := range m {
|
||||
MaybeResetRESTMapper(t)
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,10 @@ const (
|
||||
AnyKind = "*"
|
||||
)
|
||||
|
||||
var (
|
||||
_ ResettableRESTMapper = PriorityRESTMapper{}
|
||||
)
|
||||
|
||||
// PriorityRESTMapper is a wrapper for automatically choosing a particular Resource or Kind
|
||||
// when multiple matches are possible
|
||||
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) {
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
func (l *errorRestMapper) Reset() {
|
||||
meta.MaybeResetRESTMapper(l.RESTMapper)
|
||||
}
|
||||
|
||||
func newDefaultBuilderWithMapperError(fakeClientFn FakeClientFunc, err error) *Builder {
|
||||
return NewFakeBuilder(
|
||||
fakeClientFn,
|
||||
|
@ -335,4 +335,4 @@ func (d *DeferredDiscoveryRESTMapper) String() string {
|
||||
}
|
||||
|
||||
// Make sure it satisfies the interface
|
||||
var _ meta.RESTMapper = &DeferredDiscoveryRESTMapper{}
|
||||
var _ meta.ResettableRESTMapper = &DeferredDiscoveryRESTMapper{}
|
||||
|
@ -34,7 +34,7 @@ type shortcutExpander struct {
|
||||
discoveryClient discovery.DiscoveryInterface
|
||||
}
|
||||
|
||||
var _ meta.RESTMapper = &shortcutExpander{}
|
||||
var _ meta.ResettableRESTMapper = shortcutExpander{}
|
||||
|
||||
// NewShortcutExpander wraps a restmapper in a layer that expands shortcuts found via discovery
|
||||
func NewShortcutExpander(delegate meta.RESTMapper, client discovery.DiscoveryInterface) meta.RESTMapper {
|
||||
@ -164,6 +164,10 @@ func (e shortcutExpander) expandResourceShortcut(resource schema.GroupVersionRes
|
||||
return resource
|
||||
}
|
||||
|
||||
func (e shortcutExpander) Reset() {
|
||||
meta.MaybeResetRESTMapper(e.RESTMapper)
|
||||
}
|
||||
|
||||
// ResourceShortcuts represents a structure that holds the information how to
|
||||
// transition from resource's shortcut to its full name.
|
||||
type resourceShortcuts struct {
|
||||
|
Loading…
Reference in New Issue
Block a user