mirror of
https://github.com/rancher/steve.git
synced 2025-06-26 15:02:05 +00:00
Switch clustercache to index by gvk not gvr
This commit is contained in:
parent
e29561cbf9
commit
a44863b331
@ -21,11 +21,12 @@ import (
|
|||||||
"k8s.io/client-go/util/workqueue"
|
"k8s.io/client-go/util/workqueue"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Handler func(gvr schema2.GroupVersionResource, key string, obj runtime.Object) error
|
type Handler func(gvr schema2.GroupVersionKind, key string, obj runtime.Object) error
|
||||||
type ChangeHandler func(gvr schema2.GroupVersionResource, key string, obj, oldObj runtime.Object) error
|
type ChangeHandler func(gvr schema2.GroupVersionKind, key string, obj, oldObj runtime.Object) error
|
||||||
|
|
||||||
type ClusterCache interface {
|
type ClusterCache interface {
|
||||||
List(gvr schema2.GroupVersionResource) []interface{}
|
Get(gvk schema2.GroupVersionKind, namespace, name string) (interface{}, bool, error)
|
||||||
|
List(gvk schema2.GroupVersionKind) []interface{}
|
||||||
OnAdd(ctx context.Context, handler Handler)
|
OnAdd(ctx context.Context, handler Handler)
|
||||||
OnRemove(ctx context.Context, handler Handler)
|
OnRemove(ctx context.Context, handler Handler)
|
||||||
OnChange(ctx context.Context, handler ChangeHandler)
|
OnChange(ctx context.Context, handler ChangeHandler)
|
||||||
@ -34,7 +35,7 @@ type ClusterCache interface {
|
|||||||
|
|
||||||
type event struct {
|
type event struct {
|
||||||
add bool
|
add bool
|
||||||
gvr schema2.GroupVersionResource
|
gvk schema2.GroupVersionKind
|
||||||
obj runtime.Object
|
obj runtime.Object
|
||||||
oldObj runtime.Object
|
oldObj runtime.Object
|
||||||
}
|
}
|
||||||
@ -52,7 +53,7 @@ type clusterCache struct {
|
|||||||
|
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
summaryClient client.Interface
|
summaryClient client.Interface
|
||||||
watchers map[schema2.GroupVersionResource]*watcher
|
watchers map[schema2.GroupVersionKind]*watcher
|
||||||
workqueue workqueue.DelayingInterface
|
workqueue workqueue.DelayingInterface
|
||||||
|
|
||||||
addHandlers cancelCollection
|
addHandlers cancelCollection
|
||||||
@ -64,7 +65,7 @@ func NewClusterCache(ctx context.Context, dynamicClient dynamic.Interface) Clust
|
|||||||
c := &clusterCache{
|
c := &clusterCache{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
summaryClient: client.NewForDynamicClient(dynamicClient),
|
summaryClient: client.NewForDynamicClient(dynamicClient),
|
||||||
watchers: map[schema2.GroupVersionResource]*watcher{},
|
watchers: map[schema2.GroupVersionKind]*watcher{},
|
||||||
workqueue: workqueue.NewNamedDelayingQueue("cluster-cache"),
|
workqueue: workqueue.NewNamedDelayingQueue("cluster-cache"),
|
||||||
}
|
}
|
||||||
go c.start()
|
go c.start()
|
||||||
@ -90,14 +91,14 @@ func validSchema(schema *types.APISchema) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *clusterCache) addResourceEventHandler(gvr schema2.GroupVersionResource, informer cache.SharedIndexInformer) {
|
func (h *clusterCache) addResourceEventHandler(gvk schema2.GroupVersionKind, informer cache.SharedIndexInformer) {
|
||||||
informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
|
informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||||
AddFunc: func(obj interface{}) {
|
AddFunc: func(obj interface{}) {
|
||||||
if rObj, ok := obj.(runtime.Object); ok {
|
if rObj, ok := obj.(runtime.Object); ok {
|
||||||
h.workqueue.Add(event{
|
h.workqueue.Add(event{
|
||||||
add: true,
|
add: true,
|
||||||
obj: rObj,
|
obj: rObj,
|
||||||
gvr: gvr,
|
gvk: gvk,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -107,7 +108,7 @@ func (h *clusterCache) addResourceEventHandler(gvr schema2.GroupVersionResource,
|
|||||||
h.workqueue.Add(event{
|
h.workqueue.Add(event{
|
||||||
obj: rObj,
|
obj: rObj,
|
||||||
oldObj: rOldObj,
|
oldObj: rOldObj,
|
||||||
gvr: gvr,
|
gvk: gvk,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,7 +117,7 @@ func (h *clusterCache) addResourceEventHandler(gvr schema2.GroupVersionResource,
|
|||||||
if rObj, ok := obj.(runtime.Object); ok {
|
if rObj, ok := obj.(runtime.Object); ok {
|
||||||
h.workqueue.Add(event{
|
h.workqueue.Add(event{
|
||||||
obj: rObj,
|
obj: rObj,
|
||||||
gvr: gvr,
|
gvk: gvk,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -128,7 +129,7 @@ func (h *clusterCache) OnSchemas(schemas *schema.Collection) error {
|
|||||||
defer h.Unlock()
|
defer h.Unlock()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
gvrs = map[schema2.GroupVersionResource]bool{}
|
gvks = map[schema2.GroupVersionKind]bool{}
|
||||||
toWait []*watcher
|
toWait []*watcher
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -140,9 +141,9 @@ func (h *clusterCache) OnSchemas(schemas *schema.Collection) error {
|
|||||||
|
|
||||||
gvr := attributes.GVR(schema)
|
gvr := attributes.GVR(schema)
|
||||||
gvk := attributes.GVK(schema)
|
gvk := attributes.GVK(schema)
|
||||||
gvrs[gvr] = true
|
gvks[gvk] = true
|
||||||
|
|
||||||
if h.watchers[gvr] != nil {
|
if h.watchers[gvk] != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,19 +157,19 @@ func (h *clusterCache) OnSchemas(schemas *schema.Collection) error {
|
|||||||
gvr: gvr,
|
gvr: gvr,
|
||||||
informer: summaryInformer.Informer(),
|
informer: summaryInformer.Informer(),
|
||||||
}
|
}
|
||||||
h.watchers[gvr] = w
|
h.watchers[gvk] = w
|
||||||
toWait = append(toWait, w)
|
toWait = append(toWait, w)
|
||||||
|
|
||||||
logrus.Infof("Watching metadata for %s", w.gvk)
|
logrus.Infof("Watching metadata for %s", w.gvk)
|
||||||
h.addResourceEventHandler(w.gvr, w.informer)
|
h.addResourceEventHandler(w.gvk, w.informer)
|
||||||
go w.informer.Run(w.ctx.Done())
|
go w.informer.Run(w.ctx.Done())
|
||||||
}
|
}
|
||||||
|
|
||||||
for gvr, w := range h.watchers {
|
for gvk, w := range h.watchers {
|
||||||
if !gvrs[gvr] {
|
if !gvks[gvk] {
|
||||||
logrus.Infof("Stopping metadata watch on %s", gvr)
|
logrus.Infof("Stopping metadata watch on %s", gvk)
|
||||||
w.cancel()
|
w.cancel()
|
||||||
delete(h.watchers, gvr)
|
delete(h.watchers, gvk)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,7 +179,7 @@ func (h *clusterCache) OnSchemas(schemas *schema.Collection) error {
|
|||||||
logrus.Errorf("failed to sync cache for %v", w.gvk)
|
logrus.Errorf("failed to sync cache for %v", w.gvk)
|
||||||
cancel()
|
cancel()
|
||||||
w.cancel()
|
w.cancel()
|
||||||
delete(h.watchers, w.gvr)
|
delete(h.watchers, w.gvk)
|
||||||
}
|
}
|
||||||
cancel()
|
cancel()
|
||||||
}
|
}
|
||||||
@ -186,11 +187,30 @@ func (h *clusterCache) OnSchemas(schemas *schema.Collection) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *clusterCache) List(gvr schema2.GroupVersionResource) []interface{} {
|
func (h *clusterCache) Get(gvk schema2.GroupVersionKind, namespace, name string) (interface{}, bool, error) {
|
||||||
h.RLock()
|
h.RLock()
|
||||||
defer h.RUnlock()
|
defer h.RUnlock()
|
||||||
|
|
||||||
w, ok := h.watchers[gvr]
|
w, ok := h.watchers[gvk]
|
||||||
|
if !ok {
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var key string
|
||||||
|
if namespace == "" {
|
||||||
|
key = name
|
||||||
|
} else {
|
||||||
|
key = namespace + "/" + name
|
||||||
|
}
|
||||||
|
|
||||||
|
return w.informer.GetStore().GetByKey(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *clusterCache) List(gvk schema2.GroupVersionKind) []interface{} {
|
||||||
|
h.RLock()
|
||||||
|
defer h.RUnlock()
|
||||||
|
|
||||||
|
w, ok := h.watchers[gvk]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -208,7 +228,7 @@ func (h *clusterCache) start() {
|
|||||||
|
|
||||||
event := eventObj.(event)
|
event := eventObj.(event)
|
||||||
h.RLock()
|
h.RLock()
|
||||||
w := h.watchers[event.gvr]
|
w := h.watchers[event.gvk]
|
||||||
h.RUnlock()
|
h.RUnlock()
|
||||||
if w == nil {
|
if w == nil {
|
||||||
h.workqueue.Done(eventObj)
|
h.workqueue.Done(eventObj)
|
||||||
@ -217,17 +237,17 @@ func (h *clusterCache) start() {
|
|||||||
|
|
||||||
key := toKey(event.obj)
|
key := toKey(event.obj)
|
||||||
if event.oldObj != nil {
|
if event.oldObj != nil {
|
||||||
_, err := callAll(h.changeHandlers.List(), event.gvr, key, event.obj, event.oldObj)
|
_, err := callAll(h.changeHandlers.List(), event.gvk, key, event.obj, event.oldObj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("failed to handle add event: %v", err)
|
logrus.Errorf("failed to handle add event: %v", err)
|
||||||
}
|
}
|
||||||
} else if event.add {
|
} else if event.add {
|
||||||
_, err := callAll(h.addHandlers.List(), event.gvr, key, event.obj, nil)
|
_, err := callAll(h.addHandlers.List(), event.gvk, key, event.obj, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("failed to handle add event: %v", err)
|
logrus.Errorf("failed to handle add event: %v", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_, err := callAll(h.removeHandlers.List(), event.gvr, key, event.obj, nil)
|
_, err := callAll(h.removeHandlers.List(), event.gvk, key, event.obj, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("failed to handle remove event: %v", err)
|
logrus.Errorf("failed to handle remove event: %v", err)
|
||||||
}
|
}
|
||||||
@ -260,7 +280,7 @@ func (h *clusterCache) OnChange(ctx context.Context, handler ChangeHandler) {
|
|||||||
h.changeHandlers.Add(ctx, handler)
|
h.changeHandlers.Add(ctx, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
func callAll(handlers []interface{}, gvr schema2.GroupVersionResource, key string, obj, oldObj runtime.Object) (runtime.Object, error) {
|
func callAll(handlers []interface{}, gvr schema2.GroupVersionKind, key string, obj, oldObj runtime.Object) (runtime.Object, error) {
|
||||||
var errs []error
|
var errs []error
|
||||||
for _, handler := range handlers {
|
for _, handler := range handlers {
|
||||||
if f, ok := handler.(Handler); ok {
|
if f, ok := handler.(Handler); ok {
|
||||||
|
@ -51,18 +51,18 @@ func New(key string, cg proxy.ClientGetter, roleTimeout time.Duration, imageName
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PodImpersonation) PurgeOldRoles(gvr schema.GroupVersionResource, key string, obj runtime.Object) error {
|
func (s *PodImpersonation) PurgeOldRoles(gvk schema.GroupVersionKind, key string, obj runtime.Object) error {
|
||||||
if obj == nil ||
|
if obj == nil ||
|
||||||
gvr.Version != "v1" ||
|
gvk.Version != "v1" ||
|
||||||
gvr.Group != rbacv1.GroupName ||
|
gvk.Group != rbacv1.GroupName ||
|
||||||
gvr.Resource != "clusterroles" {
|
gvk.Kind != "ClusterRole" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
meta, err := meta.Accessor(obj)
|
meta, err := meta.Accessor(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// ignore error
|
// ignore error
|
||||||
logrus.Warnf("failed to find metadata for %v, %s", gvr, key)
|
logrus.Warnf("failed to find metadata for %v, %s", gvk, key)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ func (s *Store) Watch(apiOp *types.APIRequest, schema *types.APISchema, w types.
|
|||||||
var (
|
var (
|
||||||
result = make(chan types.APIEvent, 100)
|
result = make(chan types.APIEvent, 100)
|
||||||
counts map[string]ItemCount
|
counts map[string]ItemCount
|
||||||
gvrToSchema = map[schema2.GroupVersionResource]*types.APISchema{}
|
gvkToSchema = map[schema2.GroupVersionKind]*types.APISchema{}
|
||||||
countLock sync.Mutex
|
countLock sync.Mutex
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -133,10 +133,10 @@ func (s *Store) Watch(apiOp *types.APIRequest, schema *types.APISchema, w types.
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
gvrToSchema[attributes.GVR(schema)] = schema
|
gvkToSchema[attributes.GVK(schema)] = schema
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange := func(add bool, gvr schema2.GroupVersionResource, _ string, obj, oldObj runtime.Object) error {
|
onChange := func(add bool, gvk schema2.GroupVersionKind, _ string, obj, oldObj runtime.Object) error {
|
||||||
countLock.Lock()
|
countLock.Lock()
|
||||||
defer countLock.Unlock()
|
defer countLock.Unlock()
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ func (s *Store) Watch(apiOp *types.APIRequest, schema *types.APISchema, w types.
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
schema := gvrToSchema[gvr]
|
schema := gvkToSchema[gvk]
|
||||||
if schema == nil {
|
if schema == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -195,14 +195,14 @@ func (s *Store) Watch(apiOp *types.APIRequest, schema *types.APISchema, w types.
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
s.ccache.OnAdd(apiOp.Context(), func(gvr schema2.GroupVersionResource, key string, obj runtime.Object) error {
|
s.ccache.OnAdd(apiOp.Context(), func(gvk schema2.GroupVersionKind, key string, obj runtime.Object) error {
|
||||||
return onChange(true, gvr, key, obj, nil)
|
return onChange(true, gvk, key, obj, nil)
|
||||||
})
|
})
|
||||||
s.ccache.OnChange(apiOp.Context(), func(gvr schema2.GroupVersionResource, key string, obj, oldObj runtime.Object) error {
|
s.ccache.OnChange(apiOp.Context(), func(gvk schema2.GroupVersionKind, key string, obj, oldObj runtime.Object) error {
|
||||||
return onChange(true, gvr, key, obj, oldObj)
|
return onChange(true, gvk, key, obj, oldObj)
|
||||||
})
|
})
|
||||||
s.ccache.OnRemove(apiOp.Context(), func(gvr schema2.GroupVersionResource, key string, obj runtime.Object) error {
|
s.ccache.OnRemove(apiOp.Context(), func(gvk schema2.GroupVersionKind, key string, obj runtime.Object) error {
|
||||||
return onChange(false, gvr, key, obj, nil)
|
return onChange(false, gvk, key, obj, nil)
|
||||||
})
|
})
|
||||||
|
|
||||||
return buffer(result), nil
|
return buffer(result), nil
|
||||||
@ -315,7 +315,7 @@ func (s *Store) getCount(apiOp *types.APIRequest) Count {
|
|||||||
counts := map[string]ItemCount{}
|
counts := map[string]ItemCount{}
|
||||||
|
|
||||||
for _, schema := range s.schemasToWatch(apiOp) {
|
for _, schema := range s.schemasToWatch(apiOp) {
|
||||||
gvr := attributes.GVR(schema)
|
gvk := attributes.GVK(schema)
|
||||||
access, _ := attributes.Access(schema).(accesscontrol.AccessListByVerb)
|
access, _ := attributes.Access(schema).(accesscontrol.AccessListByVerb)
|
||||||
|
|
||||||
rev := 0
|
rev := 0
|
||||||
@ -325,7 +325,7 @@ func (s *Store) getCount(apiOp *types.APIRequest) Count {
|
|||||||
|
|
||||||
all := access.Grants("list", "*", "*")
|
all := access.Grants("list", "*", "*")
|
||||||
|
|
||||||
for _, obj := range s.ccache.List(gvr) {
|
for _, obj := range s.ccache.List(gvk) {
|
||||||
name, ns, revision, summary, ok := getInfo(obj)
|
name, ns, revision, summary, ok := getInfo(obj)
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
|
Loading…
Reference in New Issue
Block a user