From 61ee8245371aa74b79e37b81cbc76b8d00e1911c Mon Sep 17 00:00:00 2001 From: derailed Date: Tue, 5 Mar 2024 16:37:42 -0700 Subject: [PATCH] [Bug] Fix #2582 --- internal/client/client.go | 15 +++++++- internal/dao/registry.go | 66 ++++++++++------------------------- internal/model/table.go | 4 +++ internal/model1/table_data.go | 2 +- 4 files changed, 37 insertions(+), 50 deletions(-) diff --git a/internal/client/client.go b/internal/client/client.go index e12f900530..aaac43e8e4 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -246,7 +246,7 @@ func (a *APIClient) ValidNamespaceNames() (NamespaceNames, error) { } } - ok, err := a.CanI(ClusterScope, "v1/namespaces", "", []string{ListVerb}) + ok, err := a.CanI(ClusterScope, "v1/namespaces", "", ListAccess) if !ok || err != nil { return nil, fmt.Errorf("user not authorized to list all namespaces") } @@ -524,12 +524,25 @@ func (a *APIClient) MXDial() (*versioned.Clientset, error) { return a.getMxsClient(), err } +func (a *APIClient) invalidateCache() error { + dial, err := a.CachedDiscovery() + if err != nil { + return err + } + dial.Invalidate() + + return nil +} + // SwitchContext handles kubeconfig context switches. func (a *APIClient) SwitchContext(name string) error { log.Debug().Msgf("Switching context %q", name) if err := a.config.SwitchContext(name); err != nil { return err } + if err := a.invalidateCache(); err != nil { + return err + } a.reset() ResetMetrics() diff --git a/internal/dao/registry.go b/internal/dao/registry.go index fd19c6c4e9..e19ad58600 100644 --- a/internal/dao/registry.go +++ b/internal/dao/registry.go @@ -21,50 +21,24 @@ const ( crdCat = "crd" k9sCat = "k9s" helmCat = "helm" + crdGVR = "apiextensions.k8s.io/v1/customresourcedefinitions" ) // MetaAccess tracks resources metadata. var MetaAccess = NewMeta() -var stdGroups = []string{ - "admissionregistration.k8s.io/v1", - "admissionregistration.k8s.io/v1beta1", - "apiextensions.k8s.io/v1", - "apiextensions.k8s.io/v1beta1", - "apiregistration.k8s.io/v1", - "apiregistration.k8s.io/v1beta1", - "apps/v1", - "authentication.k8s.io/v1", - "authentication.k8s.io/v1beta1", - "authorization.k8s.io/v1", - "authorization.k8s.io/v1beta1", - "autoscaling/v1", - "autoscaling/v2beta1", - "autoscaling/v2beta2", - "batch/v1", - "batch/v1beta1", - "certificates.k8s.io/v1", - "certificates.k8s.io/v1beta1", - "coordination.k8s.io/v1", - "coordination.k8s.io/v1beta1", - "discovery.k8s.io/v1beta1", - "dynatrace.com/v1alpha1", - "events.k8s.io/v1", - "extensions/v1beta1", - "flowcontrol.apiserver.k8s.io/v1beta1", - "metrics.k8s.io/v1beta1", - "networking.k8s.io/v1", - "networking.k8s.io/v1beta1", - "node.k8s.io/v1", - "node.k8s.io/v1beta1", - "policy/v1beta1", - "rbac.authorization.k8s.io/v1", - "rbac.authorization.k8s.io/v1beta1", - "scheduling.k8s.io/v1", - "scheduling.k8s.io/v1beta1", - "storage.k8s.io/v1", - "storage.k8s.io/v1beta1", - "v1", +var stdGroups = map[string]struct{}{ + "apps/v1": {}, + "autoscaling/v1": {}, + "autoscaling/v2": {}, + "autoscaling/v2beta1": {}, + "autoscaling/v2beta2": {}, + "batch/v1": {}, + "batch/v1beta1": {}, + "extensions/v1beta1": {}, + "policy/v1beta1": {}, + "policy/v1": {}, + "v1": {}, } func (m ResourceMetas) clear() { @@ -372,7 +346,6 @@ func loadPreferred(f Factory, m ResourceMetas) error { if err != nil { return err } - dial.Invalidate() rr, err := dial.ServerPreferredResources() if err != nil { log.Debug().Err(err).Msgf("Failed to load preferred resources") @@ -387,7 +360,7 @@ func loadPreferred(f Factory, m ResourceMetas) error { if res.SingularName == "" { res.SingularName = strings.ToLower(res.Kind) } - if !isStandardGroup(res.Group) { + if !isStandardGroup(r.GroupVersion) { res.Categories = append(res.Categories, crdCat) } m[gvr] = res @@ -397,14 +370,12 @@ func loadPreferred(f Factory, m ResourceMetas) error { return nil } -func isStandardGroup(r string) bool { - for _, res := range stdGroups { - if strings.Index(res, r) == 0 { - return true - } +func isStandardGroup(gv string) bool { + if _, ok := stdGroups[gv]; ok { + return true } - return false + return strings.Contains(gv, "k8s.io") } var deprecatedGVRs = map[client.GVR]struct{}{ @@ -420,7 +391,6 @@ func loadCRDs(f Factory, m ResourceMetas) { if f.Client() == nil || !f.Client().ConnectionOK() { return } - const crdGVR = "apiextensions.k8s.io/v1/customresourcedefinitions" oo, err := f.List(crdGVR, client.ClusterScope, false, labels.Everything()) if err != nil { log.Warn().Err(err).Msgf("Fail CRDs load") diff --git a/internal/model/table.go b/internal/model/table.go index ce848724ab..be1157b587 100644 --- a/internal/model/table.go +++ b/internal/model/table.go @@ -204,6 +204,10 @@ func (t *Table) updater(ctx context.Context) { } func (t *Table) refresh(ctx context.Context) error { + defer func(ti time.Time) { + log.Trace().Msgf("Refresh [%s](%d) %s ", t.gvr, t.data.RowCount(), time.Since(ti)) + }(time.Now()) + if !atomic.CompareAndSwapInt32(&t.inUpdate, 0, 1) { log.Debug().Msgf("Dropping update...") return nil diff --git a/internal/model1/table_data.go b/internal/model1/table_data.go index 10b0c3c654..13ef48ce81 100644 --- a/internal/model1/table_data.go +++ b/internal/model1/table_data.go @@ -244,7 +244,6 @@ func (t *TableData) Reset(ns string) { func (t *TableData) Reconcile(ctx context.Context, r Renderer, oo []runtime.Object) error { var rows Rows - if len(oo) > 0 { if r.IsGeneric() { table, ok := oo[0].(*metav1.Table) @@ -399,6 +398,7 @@ func (t *TableData) Clone() *TableData { header: t.header.Clone(), rowEvents: t.rowEvents.Clone(), namespace: t.namespace, + gvr: t.gvr, } }