diff --git a/.codebeatsettings b/.codebeatsettings index 50ce9b9e..22896229 100644 --- a/.codebeatsettings +++ b/.codebeatsettings @@ -24,17 +24,5 @@ 45, 46 ], - "TOTAL_COMPLEXITY": [ - 100, - 180, - 300, - 350 - ] - "ABC": [ - 10, - 20, - 45, - 60 - ] } } \ No newline at end of file diff --git a/internal/view/app.go b/internal/view/app.go index 07da3f0a..ef5f8540 100644 --- a/internal/view/app.go +++ b/internal/view/app.go @@ -271,7 +271,7 @@ func (a *App) switchNS(ns string) bool { log.Error().Err(err).Msg("Config Set NS failed!") return false } - a.factory.SetActive(ns) + a.factory.SetActiveNS(ns) return true } @@ -308,8 +308,7 @@ func (a *App) switchCtx(name string, loadPods bool) error { func (a *App) initFactory(ns string) { a.factory.Terminate() - a.factory.Init() - a.factory.SetActive(ns) + a.factory.Start(ns) } // BailOut exists the application. diff --git a/internal/view/browser.go b/internal/view/browser.go index e1fe595b..6ffa69a8 100644 --- a/internal/view/browser.go +++ b/internal/view/browser.go @@ -23,12 +23,6 @@ import ( "k8s.io/cli-runtime/pkg/printers" ) -// ContextFunc enhances a given context. -type ContextFunc func(context.Context) context.Context - -// BindKeysFunc adds new menu actions. -type BindKeysFunc func(ui.KeyActions) - // Browser represents a generic resource browser. type Browser struct { *Table diff --git a/internal/view/types.go b/internal/view/types.go index 19c930b1..486847a5 100644 --- a/internal/view/types.go +++ b/internal/view/types.go @@ -1,6 +1,8 @@ package view import ( + "context" + "github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/model" "github.com/derailed/k9s/internal/ui" @@ -18,6 +20,12 @@ type ( // ContainerFunc returns the active container name. ContainerFunc func() string + + // ContextFunc enhances a given context. + ContextFunc func(context.Context) context.Context + + // BindKeysFunc adds new menu actions. + BindKeysFunc func(ui.KeyActions) ) // ActionExtender enhances a given viewer by adding new menu actions. diff --git a/internal/watch/factory.go b/internal/watch/factory.go index a76ed407..c72e0317 100644 --- a/internal/watch/factory.go +++ b/internal/watch/factory.go @@ -2,15 +2,12 @@ package watch import ( "fmt" - "path" - "strings" "time" "github.com/derailed/k9s/internal/client" "github.com/rs/zerolog/log" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" di "k8s.io/client-go/dynamic/dynamicinformer" "k8s.io/client-go/informers" ) @@ -26,7 +23,6 @@ type Factory struct { factories map[string]di.DynamicSharedInformerFactory client client.Connection stopChan chan struct{} - activeNS string forwarders Forwarders } @@ -34,14 +30,30 @@ type Factory struct { func NewFactory(client client.Connection) *Factory { return &Factory{ client: client, - stopChan: make(chan struct{}), factories: make(map[string]di.DynamicSharedInformerFactory), forwarders: NewForwarders(), } } -func (f *Factory) String() string { - return fmt.Sprintf("Factory ActiveNS %s", f.activeNS) +// Start initializes the informers until caller cancels the context. +func (f *Factory) Start(ns string) { + f.stopChan = make(chan struct{}) + for ns, fac := range f.factories { + log.Debug().Msgf("Starting factory in ns %q", ns) + fac.Start(f.stopChan) + } +} + +// Terminate terminates all watchers and forwards. +func (f *Factory) Terminate() { + if f.stopChan != nil { + close(f.stopChan) + f.stopChan = nil + } + for k := range f.factories { + delete(f.factories, k) + } + f.forwarders.DeleteAll() } // List returns a resource collection. @@ -81,65 +93,22 @@ func (f *Factory) WaitForCacheSync() { } } -// Init starts a factory. -func (f *Factory) Init() { - f.Start(f.stopChan) +// Client return the factory connection. +func (f *Factory) Client() client.Connection { + return f.client } -// Terminate terminates all watchers and forwards. -func (f *Factory) Terminate() { - if f.stopChan != nil { - close(f.stopChan) - f.stopChan = nil - } - for k := range f.factories { - delete(f.factories, k) - } - f.forwarders.DeleteAll() -} - -// AddForwarder registers a new portforward for a given container. -func (f *Factory) AddForwarder(pf Forwarder) { - f.forwarders[pf.Path()] = pf -} - -// DeleteForwarder deletes portforward for a given container. -func (f *Factory) DeleteForwarder(path string) { - fwd, ok := f.forwarders[path] - if !ok { - log.Warn().Msgf("Unable to delete portForward %q", path) - return - } - fwd.Stop() - delete(f.forwarders, path) -} - -// Forwarders returns all portforwards. -func (f *Factory) Forwarders() Forwarders { - return f.forwarders -} - -// ForwarderFor returns a portforward for a given container or nil if none exists. -func (f *Factory) ForwarderFor(path string) (Forwarder, bool) { - fwd, ok := f.forwarders[path] - return fwd, ok -} - -// Start initializes the informers until caller cancels the context. -func (f *Factory) Start(stopChan chan struct{}) { - for ns, fac := range f.factories { - log.Debug().Msgf("Starting factory in ns %q", ns) - fac.Start(stopChan) - } +// FactoryFor returns a factory for a given namespace. +func (f *Factory) FactoryFor(ns string) di.DynamicSharedInformerFactory { + return f.factories[ns] } // SetActive sets the active namespace. // BOZO!! Check ns access for resource?? -func (f *Factory) SetActive(ns string) { +func (f *Factory) SetActiveNS(ns string) { if !f.isClusterWide() { f.ensureFactory(ns) } - f.activeNS = ns } func (f *Factory) isClusterWide() bool { @@ -148,10 +117,10 @@ func (f *Factory) isClusterWide() bool { } func (f *Factory) preload(_ string) { - // BOZO!! verbs := []string{"get", "list", "watch"} - // _, _ = f.CanForResource(ns, "v1/pods", verbs...) _, _ = f.CanForResource("", "apiextensions.k8s.io/v1beta1/customresourcedefinitions", verbs...) + // BOZO!! + // _, _ = f.CanForResource(ns, "v1/pods", verbs...) // _, _ = f.CanForResource(clusterScope, "rbac.authorization.k8s.io/v1/clusterroles", verbs...) // _, _ = f.CanForResource(allNamespaces, "rbac.authorization.k8s.io/v1/roles", verbs...) } @@ -169,11 +138,6 @@ func (f *Factory) CanForResource(ns, gvr string, verbs ...string) (informers.Gen return f.ForResource(ns, gvr), nil } -// FactoryFor returns a factory for a given namespace. -func (f *Factory) FactoryFor(ns string) di.DynamicSharedInformerFactory { - return f.factories[ns] -} - // ForResource returns an informer for a given resource. func (f *Factory) ForResource(ns, gvr string) informers.GenericInformer { fact := f.ensureFactory(ns) @@ -202,56 +166,29 @@ func (f *Factory) ensureFactory(ns string) di.DynamicSharedInformerFactory { return f.factories[ns] } -func toGVR(gvr string) schema.GroupVersionResource { - tokens := strings.Split(gvr, "/") - if len(tokens) < 3 { - tokens = append([]string{""}, tokens...) - } - - return schema.GroupVersionResource{ - Group: tokens[0], - Version: tokens[1], - Resource: tokens[2], +// AddForwarder registers a new portforward for a given container. +func (f *Factory) AddForwarder(pf Forwarder) { + f.forwarders[pf.Path()] = pf +} + +// DeleteForwarder deletes portforward for a given container. +func (f *Factory) DeleteForwarder(path string) { + fwd, ok := f.forwarders[path] + if !ok { + log.Warn().Msgf("Unable to delete portForward %q", path) + return } + fwd.Stop() + delete(f.forwarders, path) } -// Client return the factory connection. -func (f *Factory) Client() client.Connection { - return f.client +// Forwarders returns all portforwards. +func (f *Factory) Forwarders() Forwarders { + return f.forwarders } -// ---------------------------------------------------------------------------- -// Helpers... - -// Dump for debug. -func (f *Factory) Dump() { - log.Debug().Msgf("----------- FACTORIES -------------") - for ns := range f.factories { - log.Debug().Msgf(" Factory for NS %q", ns) - } - log.Debug().Msgf("-----------------------------------") -} - -// Debug for debug. -func (f *Factory) Debug(gvr string) { - log.Debug().Msgf("----------- DEBUG FACTORY (%s) -------------", gvr) - inf := f.factories[allNamespaces].ForResource(toGVR(gvr)) - for i, k := range inf.Informer().GetStore().ListKeys() { - log.Debug().Msgf("%d -- %s", i, k) - } -} - -// Show for debug. -func (f *Factory) Show(ns, gvr string) { - log.Debug().Msgf("----------- SHOW FACTORIES %q -------------", ns) - inf := f.ForResource(ns, gvr) - for _, k := range inf.Informer().GetStore().ListKeys() { - log.Debug().Msgf(" Key: %s", k) - } -} - -func namespaced(n string) (string, string) { - ns, po := path.Split(n) - - return strings.Trim(ns, "/"), po +// ForwarderFor returns a portforward for a given container or nil if none exists. +func (f *Factory) ForwarderFor(path string) (Forwarder, bool) { + fwd, ok := f.forwarders[path] + return fwd, ok } diff --git a/internal/watch/helper.go b/internal/watch/helper.go new file mode 100644 index 00000000..1bdca839 --- /dev/null +++ b/internal/watch/helper.go @@ -0,0 +1,55 @@ +package watch + +import ( + "path" + "strings" + + "github.com/rs/zerolog/log" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func toGVR(gvr string) schema.GroupVersionResource { + tokens := strings.Split(gvr, "/") + if len(tokens) < 3 { + tokens = append([]string{""}, tokens...) + } + + return schema.GroupVersionResource{ + Group: tokens[0], + Version: tokens[1], + Resource: tokens[2], + } +} + +func namespaced(n string) (string, string) { + ns, po := path.Split(n) + + return strings.Trim(ns, "/"), po +} + +// Dump for debug. +func Dump(f *Factory) { + log.Debug().Msgf("----------- FACTORIES -------------") + for ns := range f.factories { + log.Debug().Msgf(" Factory for NS %q", ns) + } + log.Debug().Msgf("-----------------------------------") +} + +// Debug for debug. +func Debug(f *Factory, gvr string) { + log.Debug().Msgf("----------- DEBUG FACTORY (%s) -------------", gvr) + inf := f.factories[allNamespaces].ForResource(toGVR(gvr)) + for i, k := range inf.Informer().GetStore().ListKeys() { + log.Debug().Msgf("%d -- %s", i, k) + } +} + +// Show for debug. +func Show(f *Factory, ns, gvr string) { + log.Debug().Msgf("----------- SHOW FACTORIES %q -------------", ns) + inf := f.ForResource(ns, gvr) + for _, k := range inf.Informer().GetStore().ListKeys() { + log.Debug().Msgf(" Key: %s", k) + } +}