From e68e8bf145d7c1fb78ccdc632a85917bb771dc6e Mon Sep 17 00:00:00 2001 From: Paul Varache Date: Fri, 10 Jan 2020 14:31:35 +0000 Subject: [PATCH 01/58] Add instructions for scoop --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 08190740..46ed1caa 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,12 @@ K9s is available on Linux, OSX and Windows platforms. yay -S k9s-bin ``` +* Via [Scoop](https://scoop.sh) for Windows + + ```shell + scoop install k9s + ``` + * Building from source K9s was built using go 1.13 or above. In order to build K9 from source you must: 1. Clone the repo From dec03ceb912cf6a46d4da9282b03d94c63861e1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=2E=20R=C3=B8dseth?= Date: Sun, 26 Jan 2020 12:59:56 +0100 Subject: [PATCH 02/58] Update documentation --- README.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index dfec5388..ce8a8dff 100644 --- a/README.md +++ b/README.md @@ -31,11 +31,11 @@ Wanna discuss K9s features with your fellow `K9sers` or simply show your support ## Installation -K9s is available on Linux, OSX and Windows platforms. +K9s is available on Linux, macOS and Windows platforms. * Binaries for Linux, Windows and Mac are available as tarballs in the [release](https://github.com/derailed/k9s/releases) page. -* Via Homebrew or LinuxBrew for OSX and Linux +* Via Homebrew or LinuxBrew for macOS and Linux ```shell brew install derailed/k9s/k9s @@ -47,12 +47,10 @@ K9s is available on Linux, OSX and Windows platforms. sudo port install k9s ``` -* Archlinux (AUR) - - K9s is available in the Arch User Repository under the name [k9s-bin](https://aur.archlinux.org/packages/k9s-bin/), you can install it with your favorite AUR helper like so: +* On Arch Linux ```shell - yay -S k9s-bin + pacman -S k9s ``` * Building from source From e07c968432d627cdfbea8ec94cda19e9b5f1da59 Mon Sep 17 00:00:00 2001 From: derailed Date: Fri, 7 Feb 2020 07:06:57 -0800 Subject: [PATCH 03/58] fix #529 --- internal/config/alias.go | 2 +- internal/render/np.go | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/internal/config/alias.go b/internal/config/alias.go index 25f76bbb..ff8075da 100644 --- a/internal/config/alias.go +++ b/internal/config/alias.go @@ -147,7 +147,7 @@ func (a *Aliases) LoadAliases(path string) error { return nil } - var aa *Aliases + var aa Aliases if err := yaml.Unmarshal(f, &aa); err != nil { return err } diff --git a/internal/render/np.go b/internal/render/np.go index e1c1b881..bdedf401 100644 --- a/internal/render/np.go +++ b/internal/render/np.go @@ -111,7 +111,14 @@ func egress(ee []v1beta1.NetworkPolicyEgressRule) (string, string, string) { func portsToStr(pp []v1beta1.NetworkPolicyPort) string { ports := make([]string, 0, len(pp)) for _, p := range pp { - ports = append(ports, string(*p.Protocol)+":"+p.Port.String()) + proto, port := NAValue, NAValue + if p.Protocol != nil { + proto = string(*p.Protocol) + } + if p.Port != nil { + port = p.Port.String() + } + ports = append(ports, proto+":"+port) } return strings.Join(ports, ",") } From 5b707c656efd374ccffd7e7888d845c16d52f511 Mon Sep 17 00:00:00 2001 From: derailed Date: Fri, 7 Feb 2020 07:21:21 -0800 Subject: [PATCH 04/58] fix #528 --- internal/view/browser.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/view/browser.go b/internal/view/browser.go index b83f9bfb..89cb8126 100644 --- a/internal/view/browser.go +++ b/internal/view/browser.go @@ -310,6 +310,9 @@ func (b *Browser) switchNamespaceCmd(evt *tcell.EventKey) *tcell.EventKey { auth, err := b.App().factory.Client().CanI(ns, b.GVR(), client.MonitorAccess) if !auth { + if err == nil { + err = fmt.Errorf("current user can't access namespace %s", ns) + } b.App().Flash().Err(err) return nil } From 1ff60bbc7429e8cf546ce536a14a930a4e23ff7f Mon Sep 17 00:00:00 2001 From: Joscha Alisch Date: Fri, 7 Feb 2020 19:14:12 +0100 Subject: [PATCH 05/58] Don't segfault on empty aliases and silence warning --- internal/config/alias.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/internal/config/alias.go b/internal/config/alias.go index ff8075da..dd22e22c 100644 --- a/internal/config/alias.go +++ b/internal/config/alias.go @@ -2,6 +2,7 @@ package config import ( "io/ioutil" + "os" "path/filepath" "sync" @@ -87,6 +88,12 @@ func (a *Aliases) loadDefaults() { // Load K9s aliases. func (a *Aliases) Load() error { a.loadDefaults() + + _, err := os.Stat(K9sAlias) + if os.IsNotExist(err) { + return nil + } + return a.LoadAliases(K9sAlias) } @@ -143,8 +150,7 @@ func (a *Aliases) Define(gvr string, aliases ...string) { func (a *Aliases) LoadAliases(path string) error { f, err := ioutil.ReadFile(path) if err != nil { - log.Warn().Err(err).Msgf("No custom aliases found") - return nil + return err } var aa Aliases From 8482f26341bf08ed0e07460addbba2a31965f45b Mon Sep 17 00:00:00 2001 From: Joscha Alisch Date: Fri, 7 Feb 2020 19:17:45 +0100 Subject: [PATCH 06/58] Get message back but as debug only --- internal/config/alias.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/config/alias.go b/internal/config/alias.go index dd22e22c..b5da63fb 100644 --- a/internal/config/alias.go +++ b/internal/config/alias.go @@ -91,6 +91,7 @@ func (a *Aliases) Load() error { _, err := os.Stat(K9sAlias) if os.IsNotExist(err) { + log.Debug().Err(err).Msgf("No custom aliases found") return nil } From 7d56789a200b965d68fac28497555abae5b75973 Mon Sep 17 00:00:00 2001 From: Joscha Alisch Date: Fri, 7 Feb 2020 20:22:55 +0100 Subject: [PATCH 07/58] Allow setting info message on command execution --- internal/view/actions.go | 2 +- internal/view/browser.go | 2 +- internal/view/exec.go | 14 ++++++++------ internal/view/pod.go | 3 ++- internal/view/xray.go | 2 +- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/internal/view/actions.go b/internal/view/actions.go index c15ed77c..4d91f2ee 100644 --- a/internal/view/actions.go +++ b/internal/view/actions.go @@ -129,7 +129,7 @@ func execCmd(r Runner, bin string, bg bool, args ...string) ui.ActionHandler { return nil } } - if run(true, r.App(), bin, bg, aa...) { + if run(true, r.App(), bin, bg, "", aa...) { r.App().Flash().Info("Plugin command launched successfully!") } else { r.App().Flash().Info("Plugin command failed!") diff --git a/internal/view/browser.go b/internal/view/browser.go index b83f9bfb..5999840b 100644 --- a/internal/view/browser.go +++ b/internal/view/browser.go @@ -292,7 +292,7 @@ func (b *Browser) editCmd(evt *tcell.EventKey) *tcell.EventKey { if cfg := b.app.Conn().Config().Flags().KubeConfig; cfg != nil && *cfg != "" { args = append(args, "--kubeconfig", *cfg) } - if !runK(true, b.app, append(args, n)...) { + if !runK(true, b.app, "", append(args, n)...) { b.app.Flash().Err(errors.New("Edit exec failed")) } } diff --git a/internal/view/exec.go b/internal/view/exec.go index dc5e39e2..f9407d1e 100644 --- a/internal/view/exec.go +++ b/internal/view/exec.go @@ -13,22 +13,22 @@ import ( "github.com/rs/zerolog/log" ) -func runK(clear bool, app *App, args ...string) bool { +func runK(clear bool, app *App, info string, args ...string) bool { bin, err := exec.LookPath("kubectl") if err != nil { log.Error().Msgf("Unable to find kubectl command in path %v", err) return false } - return run(clear, app, bin, false, args...) + return run(clear, app, bin, false, info, args...) } -func run(clear bool, app *App, bin string, bg bool, args ...string) bool { +func run(clear bool, app *App, bin string, bg bool, info string, args ...string) bool { app.Halt() defer app.Resume() return app.Suspend(func() { - if err := execute(clear, bin, bg, args...); err != nil { + if err := execute(clear, bin, bg, info, args...); err != nil { app.Flash().Errf("Command exited: %v", err) } }) @@ -41,10 +41,10 @@ func edit(clear bool, app *App, args ...string) bool { return false } - return run(clear, app, bin, false, args...) + return run(clear, app, bin, false, "", args...) } -func execute(clear bool, bin string, bg bool, args ...string) error { +func execute(clear bool, bin string, bg bool, info string, args ...string) error { if clear { clearScreen() } @@ -71,6 +71,8 @@ func execute(clear bool, bin string, bg bool, args ...string) error { err = cmd.Start() } else { cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr + + _, _ = cmd.Stdout.Write([]byte(info)) err = cmd.Run() } log.Debug().Msgf("Command returned error?? %v", err) diff --git a/internal/view/pod.go b/internal/view/pod.go index cc03de98..73e508f4 100644 --- a/internal/view/pod.go +++ b/internal/view/pod.go @@ -176,7 +176,8 @@ func fetchContainers(f *watch.Factory, path string, includeInit bool) ([]string, func shellIn(a *App, path, co string) { args := computeShellArgs(path, co, a.Config.K9s.CurrentContext, a.Conn().Config().Flags().KubeConfig) log.Debug().Msgf("Shell args %v", args) - if !runK(true, a, args...) { + + if !runK(true, a, "", args...) { a.Flash().Err(errors.New("Shell exec failed")) } } diff --git a/internal/view/xray.go b/internal/view/xray.go index d16ce4bc..3e809d95 100644 --- a/internal/view/xray.go +++ b/internal/view/xray.go @@ -345,7 +345,7 @@ func (x *Xray) editCmd(evt *tcell.EventKey) *tcell.EventKey { if cfg := x.app.Conn().Config().Flags().KubeConfig; cfg != nil && *cfg != "" { args = append(args, "--kubeconfig", *cfg) } - if !runK(true, x.app, append(args, n)...) { + if !runK(true, x.app, "", append(args, n)...) { x.app.Flash().Err(errors.New("Edit exec failed")) } } From 7d0febf4b0b74604bd168095b4c472481e2e55a6 Mon Sep 17 00:00:00 2001 From: Joscha Alisch Date: Fri, 7 Feb 2020 20:24:28 +0100 Subject: [PATCH 08/58] Print pod on shell access --- internal/view/pod.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/view/pod.go b/internal/view/pod.go index 73e508f4..7a2bdd2f 100644 --- a/internal/view/pod.go +++ b/internal/view/pod.go @@ -177,7 +177,7 @@ func shellIn(a *App, path, co string) { args := computeShellArgs(path, co, a.Config.K9s.CurrentContext, a.Conn().Config().Flags().KubeConfig) log.Debug().Msgf("Shell args %v", args) - if !runK(true, a, "", args...) { + if !runK(true, a, fmt.Sprintf("Pod: %s\n\n", path, co), args...) { a.Flash().Err(errors.New("Shell exec failed")) } } From fc2de70dea0ab87240836b66beb2d9daface1bde Mon Sep 17 00:00:00 2001 From: Joscha Alisch Date: Fri, 7 Feb 2020 20:25:24 +0100 Subject: [PATCH 09/58] Print container name on shell access as well --- internal/view/pod.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/view/pod.go b/internal/view/pod.go index 7a2bdd2f..92a6a5f4 100644 --- a/internal/view/pod.go +++ b/internal/view/pod.go @@ -177,7 +177,7 @@ func shellIn(a *App, path, co string) { args := computeShellArgs(path, co, a.Config.K9s.CurrentContext, a.Conn().Config().Flags().KubeConfig) log.Debug().Msgf("Shell args %v", args) - if !runK(true, a, fmt.Sprintf("Pod: %s\n\n", path, co), args...) { + if !runK(true, a, fmt.Sprintf("Pod: %s | Container: %s\n\n", path, co), args...) { a.Flash().Err(errors.New("Shell exec failed")) } } From 4b3ed1674908eeec2bfae61cf345c0f94bf8556e Mon Sep 17 00:00:00 2001 From: Joscha Alisch Date: Fri, 7 Feb 2020 20:25:55 +0100 Subject: [PATCH 10/58] Print container name even if there is only one --- internal/view/pod.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/view/pod.go b/internal/view/pod.go index 92a6a5f4..ef1d98a0 100644 --- a/internal/view/pod.go +++ b/internal/view/pod.go @@ -125,7 +125,7 @@ func (p *Pod) shellCmd(evt *tcell.EventKey) *tcell.EventKey { return evt } if len(cc) == 1 { - p.shellIn(sel, "") + p.shellIn(sel, cc[0]) return nil } picker := NewPicker() From 0e68e92e9891f106d8b45ac9dac99c5a60c7114f Mon Sep 17 00:00:00 2001 From: Joscha Alisch Date: Fri, 7 Feb 2020 20:26:37 +0100 Subject: [PATCH 11/58] Colour the output --- go.mod | 1 + go.sum | 36 +++++++++++++++++++++++++++--------- internal/view/pod.go | 4 +++- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 898850ec..5af8ab15 100644 --- a/go.mod +++ b/go.mod @@ -33,6 +33,7 @@ require ( github.com/derailed/tview v0.3.3 github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f // indirect github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f // indirect + github.com/fatih/color v1.6.0 github.com/fsnotify/fsnotify v1.4.7 github.com/gdamore/tcell v1.3.0 github.com/ghodss/yaml v1.0.0 diff --git a/go.sum b/go.sum index b37542d1..16167445 100644 --- a/go.sum +++ b/go.sum @@ -43,6 +43,7 @@ github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcy github.com/Microsoft/go-winio v0.4.12 h1:xAfWHN1IrQ0NJ9TBC0KBZoqLjzDTr1ML+4MywiUOryc= github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/hcsshim v0.0.0-20190417211021-672e52e9209d/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= +github.com/Microsoft/hcsshim v0.8.6 h1:ZfF0+zZeYdzMIVMZHKtDKJvLHj76XCuVae/jNkjj0IA= github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46 h1:lsxEuwrXEAokXB9qhlbKWPpo3KMLZQ5WB5WLQRW1uq0= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -56,6 +57,7 @@ github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdko github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Rican7/retry v0.1.0/go.mod h1:FgOROf8P5bebcC1DS0PdOQiqGUridaZvikzUmkFW6gg= +github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -78,13 +80,18 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bifurcation/mint v0.0.0-20180715133206-93c51c6ce115/go.mod h1:zVt7zX3K/aDCk9Tj+VM7YymsX66ERvzCJzw8rFCX2JU= +github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y= github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/bshuster-repo/logrus-logstash-hook v0.4.1 h1:pgAtgj+A31JBVtEHu2uHuEx0n+2ukqUJnS2vVe5pQNA= github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= +github.com/bugsnag/bugsnag-go v1.5.0 h1:tP8hiPv1pGGW3LA6LKy5lW6WG+y9J2xWUdPd3WC452k= github.com/bugsnag/bugsnag-go v1.5.0/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= +github.com/bugsnag/panicwrap v1.2.0 h1:OzrKrRvXis8qEvOkfcxNcYbOd2O7xXS2nnKMEMABFQA= github.com/bugsnag/panicwrap v1.2.0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= github.com/caddyserver/caddy v1.0.3/go.mod h1:G+ouvOY32gENkJC+jhgl62TyhvqEsFaDiZ4uw0RzP1E= github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= @@ -134,7 +141,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE= github.com/deislabs/oras v0.7.0 h1:RnDoFd3tQYODMiUqxgQ8JxlrlWL0/VMKIKRD01MmNYk= github.com/deislabs/oras v0.7.0/go.mod h1:sqMKPG3tMyIX9xwXUBRLhZ24o+uT4y6jgBD2RzUTKDM= -github.com/deislabs/oras v0.8.0 h1:WZqPI25DlEmth2VE/pIcnEh6msL2yHrzS5lV5gwaCsQ= github.com/derailed/tview v0.3.3 h1:tipPwxcDhx0zRBZuc8VKIrNgWL40FL5JeF/30XVieUE= github.com/derailed/tview v0.3.3/go.mod h1:yApPszFU62FoaGkf7swy2nIdV/h7Nid3dhMSVy6+OFI= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= @@ -145,7 +151,6 @@ github.com/docker/cli v0.0.0-20190506213505-d88565df0c2d/go.mod h1:JLrzqnKDaYBop github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v1.4.2-0.20181221150755-2cb26cfe9cbf h1:+Hdbkr8QbGSQ4dY50mmgZEGtzjhv0we2Ws2XCz3c0Q8= github.com/docker/docker v1.4.2-0.20181221150755-2cb26cfe9cbf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.1 h1:Dq4iIfcM7cNtddhLVWe9h4QDjsi4OER3Z8voPu/I52g= @@ -159,6 +164,7 @@ github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/libnetwork v0.0.0-20180830151422-a9cd636e3789/go.mod h1:93m0aTqz6z+g32wla4l4WxTrdtvBRmVzYRkYvasA5Z8= +github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4= github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= @@ -185,10 +191,12 @@ github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwC github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= +github.com/fatih/color v1.6.0 h1:66qjqZk8kalYAvDRtM1AdAJQI0tj4Wrue3Eq3B3pmFU= github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc= github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= @@ -267,6 +275,7 @@ github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= @@ -274,10 +283,10 @@ github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09Vjb github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 h1:uHTyIjqVhYRhLbJ8nIiOJHkEZZ+5YoOsAbD3sk82NiE= github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -313,14 +322,13 @@ github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.2.0 h1:l6N3VoaVzTncYYW+9yOz2LJJammFZGBO13sqgEhpy9g= -github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk= github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZsA= github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U= github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= @@ -368,6 +376,7 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 h1:PJPDf8OUfOK1bb/NeTKd4f1QXZItOX389VN3B6qC8ro= github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/karrick/godirwalk v1.7.5/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= @@ -407,7 +416,9 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk= +github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.5 h1:jrGtp51JOKTWgvLFzfG6OtZOJcK2sEnzc/U+zw7TtbA= @@ -419,6 +430,7 @@ github.com/mesos/mesos-go v0.0.9/go.mod h1:kPYCMQ9gsOXVAle1OsoY4I1+9kPu8GHkf88aV github.com/mholt/certmagic v0.6.2-0.20190624175158-6a42ef9fe8c2/go.mod h1:g4cOPxcjV0oFq3qwpjSA30LReKD8AoIfwAY9VvG35NY= github.com/miekg/dns v0.0.0-20181005163659-0d29b283ac0f/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.3/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.4 h1:rCMZsU2ScVSYcAsOXgmC6+AKOK+6pmQTOcw03nfwYV0= github.com/miekg/dns v1.1.4/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mindprince/gonvml v0.0.0-20171110221305-fee913ce8fb2/go.mod h1:2eu9pRWp8mo84xCg6KswZ+USQHjwgRhNp06sozOdsTY= github.com/mistifyio/go-zfs v2.1.1+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= @@ -452,6 +464,7 @@ github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -476,6 +489,7 @@ github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+v github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/petergtz/pegomock v2.6.0+incompatible h1:gD9YvI42LylIA/il2Cy8lMfg+CncNFMqexYepyEWGaQ= github.com/petergtz/pegomock v2.6.0+incompatible/go.mod h1:nuBLWZpVyv/fLo56qTwt/AUau7jgouO1h7bEvZCq82o= +github.com/phayes/freeport v0.0.0-20171002181615-b8543db493a5 h1:rZQtoozkfsiNs36c7Tdv/gyGNzD1X1XWKO8rptVNZuM= github.com/phayes/freeport v0.0.0-20171002181615-b8543db493a5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= @@ -580,13 +594,17 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.1.0 h1:ngVtJC9TY/lg0AA/1k48FYhBrhRoFlEmWzsehpNAaZg= github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= github.com/xenolf/lego v0.0.0-20160613233155-a9d8cec0e656/go.mod h1:fwiGnfsIjG7OHPfOvgK7Y/Qo6+2Ox0iozjNTkZICKbY= +github.com/xenolf/lego v0.3.2-0.20160613233155-a9d8cec0e656 h1:BTvU+npm3/yjuBd53EvgiFLl5+YLikf2WvHsjRQ4KrY= github.com/xenolf/lego v0.3.2-0.20160613233155-a9d8cec0e656/go.mod h1:fwiGnfsIjG7OHPfOvgK7Y/Qo6+2Ox0iozjNTkZICKbY= github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1 h1:j2hhcujLRHAg872RWAV5yaUrEjHEObwDv3aImCaNLek= github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940 h1:p7OofyZ509h8DmPLh8Hn+EIIZm/xYhdZHJ9GnXHdr6U= github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= +github.com/yvasiyarov/gorelic v0.0.6 h1:qMJQYPNdtJ7UNYHjX38KXZtltKTqimMuoQjNnSVIuJg= github.com/yvasiyarov/gorelic v0.0.6/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= +github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -686,8 +704,6 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20170824195420-5d2fd3ccab98/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -718,6 +734,7 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190128161407-8ac453e89fca/go.mod h1:L3J43x8/uS+qIUoksaLKe6OS3nUKxOKuIFz1sl2/jx4= @@ -750,6 +767,7 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/mcuadros/go-syslog.v2 v2.2.1/go.mod h1:l5LPIyOOyIdQquNg+oU6Z3524YwrcqEm0aKH+5zpt2U= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/square/go-jose.v1 v1.1.2 h1:/5jmADZB+RiKtZGr4HxsEFOEfbfsjTKsVnqpThUpE30= gopkg.in/square/go-jose.v1 v1.1.2/go.mod h1:QpYS+a4WhS+DTlyQIi6Ka7MS3SuR9a055rgXNEe6EiA= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= @@ -764,7 +782,6 @@ gotest.tools v2.1.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81 gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/gotestsum v0.3.5/go.mod h1:Mnf3e5FUzXbkCfynWBGOwLssY7gTQgCHObK9tMpAriY= -helm.sh/helm v2.16.1+incompatible h1:np11uYeEtlYcFIFRya8Xs5ZweV1z6MvaWQqJAW+1SZQ= helm.sh/helm/v3 v3.0.2 h1:BggvLisIMrAc+Is5oAHVrlVxgwOOrMN8nddfQbm5gKo= helm.sh/helm/v3 v3.0.2/go.mod h1:KBxE6XWO57XSNA1PA9CvVLYRY0zWqYQTad84bNXp1lw= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -828,6 +845,7 @@ modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= +rsc.io/letsencrypt v0.0.1 h1:DV0d09Ne9E7UUa9ZqWktZ9L2VmybgTgfq7xlfFR/bbU= rsc.io/letsencrypt v0.0.1/go.mod h1:buyQKZ6IXrRnB7TdkHP0RyEybLx18HHyOSoTyoOLqNY= sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0= sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= diff --git a/internal/view/pod.go b/internal/view/pod.go index ef1d98a0..a442f140 100644 --- a/internal/view/pod.go +++ b/internal/view/pod.go @@ -10,6 +10,7 @@ import ( "github.com/derailed/k9s/internal/render" "github.com/derailed/k9s/internal/ui" "github.com/derailed/k9s/internal/watch" + "github.com/fatih/color" "github.com/gdamore/tcell" "github.com/rs/zerolog/log" v1 "k8s.io/api/core/v1" @@ -177,7 +178,8 @@ func shellIn(a *App, path, co string) { args := computeShellArgs(path, co, a.Config.K9s.CurrentContext, a.Conn().Config().Flags().KubeConfig) log.Debug().Msgf("Shell args %v", args) - if !runK(true, a, fmt.Sprintf("Pod: %s | Container: %s\n\n", path, co), args...) { + c := color.New(color.BgGreen).Add(color.FgBlack).Add(color.Bold) + if !runK(true, a, c.Sprintf("Pod: %s | Container: %s\n\n", path, co), args...) { a.Flash().Err(errors.New("Shell exec failed")) } } From e7031ed20a4d12238ece5dea68e67ce1b0fd762c Mon Sep 17 00:00:00 2001 From: Joscha Alisch Date: Fri, 7 Feb 2020 20:27:10 +0100 Subject: [PATCH 12/58] Make output a bit nicer --- internal/view/pod.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/view/pod.go b/internal/view/pod.go index a442f140..cd0c6b60 100644 --- a/internal/view/pod.go +++ b/internal/view/pod.go @@ -179,7 +179,7 @@ func shellIn(a *App, path, co string) { log.Debug().Msgf("Shell args %v", args) c := color.New(color.BgGreen).Add(color.FgBlack).Add(color.Bold) - if !runK(true, a, c.Sprintf("Pod: %s | Container: %s\n\n", path, co), args...) { + if !runK(true, a, c.Sprintf(" Pod: %s | Container: %s \n\n", path, co), args...) { a.Flash().Err(errors.New("Shell exec failed")) } } From 67c0702bf2abe183c8f8dfd9467e4b9871d8d445 Mon Sep 17 00:00:00 2001 From: derailed Date: Mon, 10 Feb 2020 14:28:22 -0700 Subject: [PATCH 13/58] add searchable yaml/describe. Fix #464, #526 --- internal/config/alias.go | 2 +- internal/model/text.go | 120 ++++++++++++++++++ internal/model/text_test.go | 90 ++++++++++++++ internal/ui/app.go | 4 +- internal/ui/table.go | 6 +- internal/view/benchmark.go | 2 +- internal/view/browser.go | 2 +- internal/view/details.go | 238 +++++++++++++++++++++++++++++++----- internal/view/exec.go | 4 +- internal/view/helpers.go | 2 +- internal/view/log.go | 4 +- internal/view/node.go | 2 +- internal/view/pod.go | 3 +- internal/view/secret.go | 2 +- internal/view/xray.go | 4 +- internal/view/yaml.go | 14 ++- internal/view/yaml_test.go | 14 ++- 17 files changed, 453 insertions(+), 60 deletions(-) create mode 100644 internal/model/text.go create mode 100644 internal/model/text_test.go diff --git a/internal/config/alias.go b/internal/config/alias.go index ff8075da..622f94e3 100644 --- a/internal/config/alias.go +++ b/internal/config/alias.go @@ -143,7 +143,7 @@ func (a *Aliases) Define(gvr string, aliases ...string) { func (a *Aliases) LoadAliases(path string) error { f, err := ioutil.ReadFile(path) if err != nil { - log.Warn().Err(err).Msgf("No custom aliases found") + log.Debug().Err(err).Msgf("No custom aliases found") return nil } diff --git a/internal/model/text.go b/internal/model/text.go new file mode 100644 index 00000000..1da28560 --- /dev/null +++ b/internal/model/text.go @@ -0,0 +1,120 @@ +package model + +import ( + "regexp" + "strings" + + "github.com/sahilm/fuzzy" +) + +// TextListener represents a text model listener. +type TextListener interface { + // TextChanged notifies the model changed. + TextChanged([]string) + + // TextFiltered notifies when the filter changed. + TextFiltered([]string, fuzzy.Matches) +} + +// Text represents a text model. +type Text struct { + lines []string + listeners []TextListener + query string +} + +// NewText returns a new model. +func NewText() *Text { + return &Text{} +} + +// Peek returns the current model state. +func (t *Text) Peek() []string { + return t.lines +} + +// ClearFilter clear out filter. +func (t *Text) ClearFilter() { + t.query = "" + t.filterChanged(t.lines) +} + +// Filter filters out the text. +func (t *Text) Filter(q string) { + t.query = q + t.filterChanged(t.lines) +} + +// SetText sets the current model content. +func (t *Text) SetText(buff string) { + t.lines = strings.Split(buff, "\n") + t.fireTextChanged(t.lines) +} + +// AddListener adds a new model listener. +func (t *Text) AddListener(listener TextListener) { + t.listeners = append(t.listeners, listener) +} + +// RemoveListener delete a listener from the list. +func (t *Text) RemoveListener(listener TextListener) { + victim := -1 + for i, lis := range t.listeners { + if lis == listener { + victim = i + break + } + } + + if victim >= 0 { + t.listeners = append(t.listeners[:victim], t.listeners[victim+1:]...) + } +} + +func (t *Text) filterChanged(lines []string) { + t.fireTextFiltered(lines, t.filter(t.query, lines)) +} + +func (t *Text) fireTextChanged(lines []string) { + for _, lis := range t.listeners { + lis.TextChanged(lines) + } +} + +func (t *Text) fireTextFiltered(lines []string, matches fuzzy.Matches) { + for _, lis := range t.listeners { + lis.TextFiltered(lines, matches) + } +} + +// ---------------------------------------------------------------------------- +// Helpers... + +func (t *Text) filter(q string, lines []string) fuzzy.Matches { + if q == "" { + return nil + } + if isFuzzySelector(q) { + return t.fuzzyFilter(strings.TrimSpace(q[2:]), lines) + } + return t.rxFilter(q, lines) +} + +func (*Text) fuzzyFilter(q string, lines []string) fuzzy.Matches { + return fuzzy.Find(q, lines) +} + +func (*Text) rxFilter(q string, lines []string) fuzzy.Matches { + rx, err := regexp.Compile(`(?i)` + q) + if err != nil { + return nil + } + matches := make(fuzzy.Matches, 0, len(lines)) + for i, l := range lines { + if loc := rx.FindStringIndex(l); len(loc) == 2 { + matches = append(matches, fuzzy.Match{Str: q, Index: i, MatchedIndexes: loc}) + } + } + + return matches +} diff --git a/internal/model/text_test.go b/internal/model/text_test.go new file mode 100644 index 00000000..d8c2f949 --- /dev/null +++ b/internal/model/text_test.go @@ -0,0 +1,90 @@ +package model_test + +import ( + "testing" + + "github.com/derailed/k9s/internal/model" + "github.com/sahilm/fuzzy" + "github.com/stretchr/testify/assert" +) + +func TestNewText(t *testing.T) { + m := model.NewText() + + lis := textLis{} + m.AddListener(&lis) + + m.SetText("Hello World\nBumbleBeeTuna") + + assert.Equal(t, 1, lis.changed) + assert.Equal(t, 2, lis.lines) + assert.Equal(t, 0, lis.filtered) + assert.Equal(t, 0, lis.matches) +} + +func TestTextFilterRXMatch(t *testing.T) { + m := model.NewText() + + lis := textLis{} + m.AddListener(&lis) + + m.SetText("Hello World\nBumbleBeeTuna") + m.Filter("world") + + assert.Equal(t, 1, lis.changed) + assert.Equal(t, 2, lis.lines) + assert.Equal(t, 1, lis.filtered) + assert.Equal(t, 1, lis.matches) + assert.Equal(t, 6, lis.index) +} + +func TestTextFilterFuzzyMatch(t *testing.T) { + m := model.NewText() + + lis := textLis{} + m.AddListener(&lis) + + m.SetText("Hello World\nBumbleBeeTuna") + m.Filter("-f world") + + assert.Equal(t, 1, lis.changed) + assert.Equal(t, 2, lis.lines) + assert.Equal(t, 1, lis.filtered) + assert.Equal(t, 1, lis.matches) + assert.Equal(t, 6, lis.index) +} + +func TestTextFilterNoMatch(t *testing.T) { + m := model.NewText() + + lis := textLis{} + m.AddListener(&lis) + + m.SetText("Hello World\nBumbleBeeTuna") + m.Filter("blee") + + assert.Equal(t, 1, lis.changed) + assert.Equal(t, 2, lis.lines) + assert.Equal(t, 1, lis.filtered) + assert.Equal(t, 0, lis.matches) + assert.Equal(t, 0, lis.index) +} + +// Helpers... + +type textLis struct { + changed, filtered, matches, lines, index int +} + +func (l *textLis) TextChanged(ll []string) { + l.lines = len(ll) + l.changed++ +} + +func (l *textLis) TextFiltered(ll []string, mm fuzzy.Matches) { + l.matches = len(mm) + l.filtered++ + if len(mm) > 0 && len(mm[0].MatchedIndexes) > 0 { + l.index = mm[0].MatchedIndexes[0] + } +} diff --git a/internal/ui/app.go b/internal/ui/app.go index e200f282..54f2a833 100644 --- a/internal/ui/app.go +++ b/internal/ui/app.go @@ -175,7 +175,7 @@ func (a *App) keyboard(evt *tcell.EventKey) *tcell.EventKey { a.cmdBuff.Add(evt.Rune()) return nil } - key = asKey(evt) + key = AsKey(evt) } if a, ok := a.actions[key]; ok { @@ -258,7 +258,7 @@ func (a *App) Menu() *Menu { // Helpers... // AsKey converts rune to keyboard key., -func asKey(evt *tcell.EventKey) tcell.Key { +func AsKey(evt *tcell.EventKey) tcell.Key { key := tcell.Key(evt.Rune()) if evt.Modifiers() == tcell.ModAlt { key = tcell.Key(int16(evt.Rune()) * int16(evt.Modifiers())) diff --git a/internal/ui/table.go b/internal/ui/table.go index 2c091cf2..a9c8c9e5 100644 --- a/internal/ui/table.go +++ b/internal/ui/table.go @@ -121,7 +121,7 @@ func (t *Table) keyboard(evt *tcell.EventKey) *tcell.EventKey { if t.filterInput(evt.Rune()) { return nil } - key = asKey(evt) + key = AsKey(evt) } if a, ok := t.actions[key]; ok { @@ -370,17 +370,17 @@ func (t *Table) styleTitle() string { } } - buff := t.cmdBuff.String() var title string if ns == client.ClusterScope { title = SkinTitle(fmt.Sprintf(TitleFmt, base, rc), t.styles.Frame()) } else { title = SkinTitle(fmt.Sprintf(NSTitleFmt, base, ns, rc), t.styles.Frame()) } + + buff := t.cmdBuff.String() if buff == "" { return title } - if IsLabelSelector(buff) { buff = TrimLabelSelector(buff) } diff --git a/internal/view/benchmark.go b/internal/view/benchmark.go index 681eddee..7fdc78f2 100644 --- a/internal/view/benchmark.go +++ b/internal/view/benchmark.go @@ -46,7 +46,7 @@ func (b *Benchmark) viewBench(app *App, model ui.Tabular, gvr, path string) { return } - details := NewDetails(b.App(), "Benchmark", fileToSubject(path)).Update(data) + details := NewDetails(b.App(), "Benchmark", fileToSubject(path), false).Update(data) if err := app.inject(details); err != nil { app.Flash().Err(err) } diff --git a/internal/view/browser.go b/internal/view/browser.go index 89cb8126..e416df6f 100644 --- a/internal/view/browser.go +++ b/internal/view/browser.go @@ -175,7 +175,7 @@ func (b *Browser) viewCmd(evt *tcell.EventKey) *tcell.EventKey { return nil } - details := NewDetails(b.app, "YAML", path).Update(raw) + details := NewDetails(b.app, "YAML", path, true).Update(raw) if err := b.App().inject(details); err != nil { b.App().Flash().Err(err) } diff --git a/internal/view/details.go b/internal/view/details.go index c1e52f67..76bf5916 100644 --- a/internal/view/details.go +++ b/internal/view/details.go @@ -3,6 +3,7 @@ package view import ( "context" "fmt" + "strings" "github.com/atotto/clipboard" "github.com/derailed/k9s/internal/config" @@ -10,6 +11,7 @@ import ( "github.com/derailed/k9s/internal/ui" "github.com/derailed/tview" "github.com/gdamore/tcell" + "github.com/sahilm/fuzzy" ) const detailsTitleFmt = "[fg:bg:b] %s([hilite:bg:b]%s[fg:bg:-])[fg:bg:-] " @@ -18,20 +20,26 @@ const detailsTitleFmt = "[fg:bg:b] %s([hilite:bg:b]%s[fg:bg:-])[fg:bg:-] " type Details struct { *tview.TextView - actions ui.KeyActions - app *App - title, subject string - buff string + actions ui.KeyActions + app *App + title, subject string + cmdBuff *ui.CmdBuff + model *model.Text + currentRegion, maxRegions int + searchable bool } // NewDetails returns a details viewer. -func NewDetails(app *App, title, subject string) *Details { +func NewDetails(app *App, title, subject string, searchable bool) *Details { d := Details{ - TextView: tview.NewTextView(), - app: app, - title: title, - subject: subject, - actions: make(ui.KeyActions), + TextView: tview.NewTextView(), + app: app, + title: title, + subject: subject, + actions: make(ui.KeyActions), + cmdBuff: ui.NewCmdBuff('/', ui.FilterBuff), + model: model.NewText(), + searchable: searchable, } return &d @@ -42,37 +50,123 @@ func (d *Details) Init(_ context.Context) error { if d.title != "" { d.SetBorder(true) } - d.SetScrollable(true) - d.SetWrap(true) + d.SetScrollable(true).SetWrap(true).SetRegions(true) d.SetDynamicColors(true) d.SetHighlightColor(tcell.ColorOrange) d.SetTitleColor(tcell.ColorAqua) d.SetInputCapture(d.keyboard) - d.bindKeys() d.SetChangedFunc(func() { d.app.Draw() }) d.updateTitle() + d.app.Styles.AddListener(d) d.StylesChanged(d.app.Styles) + d.cmdBuff.AddListener(d.app.Cmd()) + d.cmdBuff.AddListener(d) + + d.bindKeys() + d.SetInputCapture(d.keyboard) + d.model.AddListener(d) + return nil } +func (d *Details) TextChanged(lines []string) { + d.SetText(colorizeYAML(d.app.Styles.Views().Yaml, strings.Join(lines, "\n"))) + d.ScrollToBeginning() +} + +func (d *Details) TextFiltered(lines []string, matches fuzzy.Matches) { + d.currentRegion, d.maxRegions = 0, 0 + + ll := make([]string, len(lines)) + copy(ll, lines) + for _, m := range matches { + loc, line := m.MatchedIndexes, ll[m.Index] + ll[m.Index] = line[:loc[0]] + fmt.Sprintf(`<<<"search_%d">>>`, d.maxRegions) + line[loc[0]:loc[1]] + `<<<"">>>` + line[loc[1]:] + d.maxRegions++ + } + + d.SetText(colorizeYAML(d.app.Styles.Views().Yaml, strings.Join(ll, "\n"))) + d.Highlight() + if d.maxRegions > 0 { + d.Highlight("search_0") + d.ScrollToHighlight() + } +} + +// BufferChanged indicates the buffer was changed. +func (d *Details) BufferChanged(s string) {} + +// BufferActive indicates the buff activity changed. +func (d *Details) BufferActive(state bool, k ui.BufferKind) { + d.app.BufferActive(state, k) +} + +func (d *Details) bindKeys() { + d.actions.Set(ui.KeyActions{ + tcell.KeyEnter: ui.NewSharedKeyAction("Filter", d.filterCmd, false), + tcell.KeyEscape: ui.NewKeyAction("Back", d.resetCmd, false), + tcell.KeyCtrlS: ui.NewKeyAction("Save", d.saveCmd, false), + ui.KeyC: ui.NewKeyAction("Copy", d.cpCmd, true), + ui.KeyN: ui.NewKeyAction("Next Match", d.nextCmd, true), + ui.KeyShiftN: ui.NewKeyAction("Prev Match", d.prevCmd, true), + ui.KeySlash: ui.NewSharedKeyAction("Filter Mode", d.activateCmd, false), + tcell.KeyCtrlU: ui.NewSharedKeyAction("Clear Filter", d.clearCmd, false), + tcell.KeyBackspace2: ui.NewSharedKeyAction("Erase", d.eraseCmd, false), + tcell.KeyBackspace: ui.NewSharedKeyAction("Erase", d.eraseCmd, false), + tcell.KeyDelete: ui.NewSharedKeyAction("Erase", d.eraseCmd, false), + }) + + if !d.searchable { + d.actions.Delete(ui.KeyN, ui.KeyShiftN) + } +} + +func (d *Details) keyboard(evt *tcell.EventKey) *tcell.EventKey { + key := evt.Key() + if key == tcell.KeyUp || key == tcell.KeyDown { + return evt + } + + if key == tcell.KeyRune { + if d.filterInput(evt.Rune()) { + return nil + } + key = ui.AsKey(evt) + } + + if a, ok := d.actions[key]; ok { + return a.Action(evt) + } + + return evt +} + +func (d *Details) filterInput(r rune) bool { + if !d.cmdBuff.IsActive() { + return false + } + d.cmdBuff.Add(r) + d.updateTitle() + + return true +} + // StylesChanged notifies the skin changed. func (d *Details) StylesChanged(s *config.Styles) { d.SetBackgroundColor(d.app.Styles.BgColor()) d.SetTextColor(d.app.Styles.FgColor()) d.SetBorderFocusColor(config.AsColor(d.app.Styles.Frame().Border.FocusColor)) - d.Update(d.buff) + d.TextChanged(d.model.Peek()) } // Update updates the view content. func (d *Details) Update(buff string) *Details { - d.buff = buff - d.SetText(colorizeYAML(d.app.Styles.Views().Yaml, buff)) - d.ScrollToBeginning() + d.model.SetText(buff) return d } @@ -108,24 +202,89 @@ func (d *Details) ExtraHints() map[string]string { return nil } -func (d *Details) bindKeys() { - d.actions.Set(ui.KeyActions{ - tcell.KeyEscape: ui.NewKeyAction("Back", d.app.PrevCmd, false), - tcell.KeyCtrlS: ui.NewKeyAction("Save", d.saveCmd, false), - ui.KeyC: ui.NewKeyAction("Copy", d.cpCmd, true), - }) +func (d *Details) nextCmd(evt *tcell.EventKey) *tcell.EventKey { + if d.cmdBuff.Empty() { + return evt + } + + d.currentRegion++ + if d.currentRegion >= d.maxRegions { + d.currentRegion = 0 + } + d.Highlight(fmt.Sprintf("search_%d", d.currentRegion)) + d.ScrollToHighlight() + d.updateTitle() + + return nil } -func (d *Details) keyboard(evt *tcell.EventKey) *tcell.EventKey { - key := evt.Key() - if key == tcell.KeyRune { - key = tcell.Key(evt.Rune()) - } - if a, ok := d.actions[key]; ok { - return a.Action(evt) +func (d *Details) prevCmd(evt *tcell.EventKey) *tcell.EventKey { + if d.cmdBuff.Empty() { + return evt } - return evt + d.currentRegion-- + if d.currentRegion < 0 { + d.currentRegion = d.maxRegions - 1 + } + d.Highlight(fmt.Sprintf("search_%d", d.currentRegion)) + d.ScrollToHighlight() + d.updateTitle() + + return nil +} + +func (d *Details) filterCmd(evt *tcell.EventKey) *tcell.EventKey { + d.model.Filter(d.cmdBuff.String()) + d.cmdBuff.SetActive(false) + d.updateTitle() + + return nil +} + +func (d *Details) activateCmd(evt *tcell.EventKey) *tcell.EventKey { + if d.app.InCmdMode() { + return evt + } + d.app.Flash().Info("Filter mode activated.") + d.cmdBuff.SetActive(true) + + return nil +} + +func (d *Details) clearCmd(*tcell.EventKey) *tcell.EventKey { + if !d.app.InCmdMode() { + return nil + } + d.cmdBuff.Clear() + + return nil +} + +func (d *Details) eraseCmd(evt *tcell.EventKey) *tcell.EventKey { + if !d.cmdBuff.IsActive() { + return nil + } + d.cmdBuff.Delete() + + return nil +} + +func (d *Details) resetCmd(evt *tcell.EventKey) *tcell.EventKey { + if !d.cmdBuff.InCmdMode() { + d.cmdBuff.Reset() + return d.app.PrevCmd(evt) + } + + if d.cmdBuff.String() != "" { + d.model.ClearFilter() + } + d.app.Flash().Info("Clearing filter...") + d.cmdBuff.SetActive(false) + d.cmdBuff.Reset() + d.updateTitle() + + return nil } func (d *Details) saveCmd(evt *tcell.EventKey) *tcell.EventKey { @@ -149,6 +308,19 @@ func (d *Details) updateTitle() { if d.title == "" { return } - title := ui.SkinTitle(fmt.Sprintf(detailsTitleFmt, d.title, d.subject), d.app.Styles.Frame()) - d.SetTitle(title) + fmat := fmt.Sprintf(detailsTitleFmt, d.title, d.subject) + + buff := d.cmdBuff.String() + if buff == "" { + d.SetTitle(ui.SkinTitle(fmat, d.app.Styles.Frame())) + return + } + + search := d.cmdBuff.String() + if d.maxRegions != 0 { + search += fmt.Sprintf("[%d:%d]", d.currentRegion+1, d.maxRegions) + } + fmat += fmt.Sprintf(ui.SearchFmt, search) + + d.SetTitle(ui.SkinTitle(fmat, d.app.Styles.Frame())) } diff --git a/internal/view/exec.go b/internal/view/exec.go index dc5e39e2..8516e34b 100644 --- a/internal/view/exec.go +++ b/internal/view/exec.go @@ -13,6 +13,8 @@ import ( "github.com/rs/zerolog/log" ) +const shellCheck = `command -v bash >/dev/null && exec bash || exec sh` + func runK(clear bool, app *App, args ...string) bool { bin, err := exec.LookPath("kubectl") if err != nil { @@ -73,7 +75,7 @@ func execute(clear bool, bin string, bg bool, args ...string) error { cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr err = cmd.Run() } - log.Debug().Msgf("Command returned error?? %v", err) + select { case <-ctx.Done(): return errors.New("canceled by operator") diff --git a/internal/view/helpers.go b/internal/view/helpers.go index bafeacfb..58d05ffe 100644 --- a/internal/view/helpers.go +++ b/internal/view/helpers.go @@ -67,7 +67,7 @@ func describeResource(app *App, model ui.Tabular, gvr, path string) { return } - details := NewDetails(app, "Describe", path).Update(yaml) + details := NewDetails(app, "Describe", path, true).Update(yaml) if err := app.inject(details); err != nil { app.Flash().Err(err) } diff --git a/internal/view/log.go b/internal/view/log.go index 3865590e..5e7ede41 100644 --- a/internal/view/log.go +++ b/internal/view/log.go @@ -67,7 +67,7 @@ func (l *Log) Init(ctx context.Context) (err error) { l.indicator = NewLogIndicator(l.app.Config, l.app.Styles) l.AddItem(l.indicator, 1, 1, false) - l.logs = NewDetails(l.app, "", "") + l.logs = NewDetails(l.app, "", "", false) if err = l.logs.Init(ctx); err != nil { return err } @@ -173,7 +173,7 @@ func (l *Log) bindKeys() { ui.KeyW: ui.NewKeyAction("Toggle Wrap", l.textWrapCmd, true), tcell.KeyCtrlS: ui.NewKeyAction("Save", l.SaveCmd, true), ui.KeySlash: ui.NewSharedKeyAction("Filter Mode", l.activateCmd, false), - tcell.KeyCtrlU: ui.NewSharedKeyAction("Clear Filter", l.clearCmd, false), + tcell.KeyCtrlU: ui.NewSharedKeyAction("Clear Filter", l.resetCmd, false), tcell.KeyBackspace2: ui.NewSharedKeyAction("Erase", l.eraseCmd, false), tcell.KeyBackspace: ui.NewSharedKeyAction("Erase", l.eraseCmd, false), tcell.KeyDelete: ui.NewSharedKeyAction("Erase", l.eraseCmd, false), diff --git a/internal/view/node.go b/internal/view/node.go index 4d69e677..dafbad67 100644 --- a/internal/view/node.go +++ b/internal/view/node.go @@ -59,7 +59,7 @@ func (n *Node) viewCmd(evt *tcell.EventKey) *tcell.EventKey { return nil } - details := NewDetails(n.App(), "YAML", sel).Update(raw) + details := NewDetails(n.App(), "YAML", sel, true).Update(raw) if err := n.App().inject(details); err != nil { n.App().Flash().Err(err) } diff --git a/internal/view/pod.go b/internal/view/pod.go index cc03de98..2463a808 100644 --- a/internal/view/pod.go +++ b/internal/view/pod.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "github.com/derailed/k9s/internal" "github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/dao" @@ -18,8 +19,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" ) -const shellCheck = "command -v bash >/dev/null && exec bash || exec sh" - // Pod represents a pod viewer. type Pod struct { ResourceViewer diff --git a/internal/view/secret.go b/internal/view/secret.go index a8ea94f0..82eca65c 100644 --- a/internal/view/secret.go +++ b/internal/view/secret.go @@ -62,7 +62,7 @@ func (s *Secret) decodeCmd(evt *tcell.EventKey) *tcell.EventKey { return nil } - details := NewDetails(s.App(), "Secret Decoder", path).Update(string(raw)) + details := NewDetails(s.App(), "Secret Decoder", path, false).Update(string(raw)) if err := s.App().inject(details); err != nil { s.App().Flash().Err(err) } diff --git a/internal/view/xray.go b/internal/view/xray.go index d16ce4bc..9613c2d5 100644 --- a/internal/view/xray.go +++ b/internal/view/xray.go @@ -269,7 +269,7 @@ func (x *Xray) viewCmd(evt *tcell.EventKey) *tcell.EventKey { return nil } - details := NewDetails(x.app, "YAML", ref.Path).Update(raw) + details := NewDetails(x.app, "YAML", ref.Path, true).Update(raw) if err := x.app.inject(details); err != nil { x.app.Flash().Err(err) } @@ -321,7 +321,7 @@ func (x *Xray) describe(gvr, path string) { return } - details := NewDetails(x.app, "Describe", path).Update(yaml) + details := NewDetails(x.app, "Describe", path, true).Update(yaml) if err := x.app.inject(details); err != nil { x.app.Flash().Err(err) } diff --git a/internal/view/yaml.go b/internal/view/yaml.go index a25580b9..9ab389e9 100644 --- a/internal/view/yaml.go +++ b/internal/view/yaml.go @@ -8,9 +8,8 @@ import ( "strings" "time" - "github.com/derailed/tview" - "github.com/derailed/k9s/internal/config" + "github.com/derailed/tview" "github.com/rs/zerolog/log" ) @@ -26,6 +25,7 @@ const ( ) func colorizeYAML(style config.Yaml, raw string) string { + // lines := strings.Split(raw, "\n") lines := strings.Split(tview.Escape(raw), "\n") fullFmt := strings.Replace(yamlFullFmt, "[key", "["+style.KeyColor, 1) @@ -41,22 +41,26 @@ func colorizeYAML(style config.Yaml, raw string) string { for _, l := range lines { res := keyValRX.FindStringSubmatch(l) if len(res) == 4 { - buff = append(buff, fmt.Sprintf(fullFmt, res[1], res[2], res[3])) + buff = append(buff, enableRegion(fmt.Sprintf(fullFmt, res[1], res[2], res[3]))) continue } res = keyRX.FindStringSubmatch(l) if len(res) == 3 { - buff = append(buff, fmt.Sprintf(keyFmt, res[1], res[2])) + buff = append(buff, enableRegion(fmt.Sprintf(keyFmt, res[1], res[2]))) continue } - buff = append(buff, fmt.Sprintf(valFmt, l)) + buff = append(buff, enableRegion(fmt.Sprintf(valFmt, l))) } return strings.Join(buff, "\n") } +func enableRegion(str string) string { + return strings.ReplaceAll(strings.ReplaceAll(str, "<<<", "["), ">>>", "]") +} + func saveYAML(cluster, name, data string) (string, error) { dir := filepath.Join(config.K9sDumpDir, cluster) if err := ensureDir(dir); err != nil { diff --git a/internal/view/yaml_test.go b/internal/view/yaml_test.go index 41451559..5e7ed5e9 100644 --- a/internal/view/yaml_test.go +++ b/internal/view/yaml_test.go @@ -13,15 +13,21 @@ func TestYaml(t *testing.T) { }{ { `api: fred - version: v1`, + version: v1`, `[steelblue::b]api[white::-]: [papayawhip::]fred - [steelblue::b]version[white::-]: [papayawhip::]v1`, + [steelblue::b]version[white::-]: [papayawhip::]v1`, + }, + { + `api: <<<"search_0">>>fred<<<"">>> + version: v1`, + `[steelblue::b]api[white::-]: [papayawhip::]["search_0"]fred[""] + [steelblue::b]version[white::-]: [papayawhip::]v1`, }, { `api: - version: v1`, + version: v1`, `[steelblue::b]api[white::-]: - [steelblue::b]version[white::-]: [papayawhip::]v1`, + [steelblue::b]version[white::-]: [papayawhip::]v1`, }, { " fred:blee", From 1a6ff3bfa38cdf650824f27c9fda49fe0110a020 Mon Sep 17 00:00:00 2001 From: derailed Date: Mon, 10 Feb 2020 15:36:46 -0700 Subject: [PATCH 14/58] rows age sort bust. Fix #536 --- internal/render/row_event.go | 30 ++++++++++++++++++++++++++---- internal/render/row_event_test.go | 20 ++++++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/internal/render/row_event.go b/internal/render/row_event.go index aeb3d0e5..5b607c69 100644 --- a/internal/render/row_event.go +++ b/internal/render/row_event.go @@ -4,8 +4,10 @@ import ( "fmt" "reflect" "sort" + "time" "github.com/rs/zerolog/log" + "k8s.io/apimachinery/pkg/util/duration" ) const ( @@ -139,19 +141,31 @@ func (rr RowEvents) FindIndex(id string) (int, bool) { return 0, false } +func (rr RowEvents) isAgeCol(col int) bool { + var age bool + if len(rr) == 0 { + return age + } + return col == len(rr[0].Row.Fields)-1 +} + // Sort rows based on column index and order. func (rr RowEvents) Sort(ns string, col int, asc bool) { t := RowEventSorter{NS: ns, Events: rr, Index: col, Asc: asc} sort.Sort(t) + ageCol := rr.isAgeCol(col) gg, kk := map[string][]string{}, make(StringSet, 0, len(rr)) - for _, e := range rr { - g := e.Row.Fields[col] + for _, r := range rr { + g := r.Row.Fields[col] + if ageCol { + g = toAgeDuration(g) + } kk = kk.Add(g) if ss, ok := gg[g]; ok { - gg[g] = append(ss, e.Row.ID) + gg[g] = append(ss, r.Row.ID) } else { - gg[g] = []string{e.Row.ID} + gg[g] = []string{r.Row.ID} } } @@ -164,6 +178,14 @@ func (rr RowEvents) Sort(ns string, col int, asc bool) { sort.Sort(s) } +func toAgeDuration(dur string) string { + d, err := time.ParseDuration(dur) + if err != nil { + return "n/a" + } + return duration.HumanDuration(d) +} + // ---------------------------------------------------------------------------- // RowEventSorter sorts row events by a given colon. diff --git a/internal/render/row_event_test.go b/internal/render/row_event_test.go index 496eca65..347940ac 100644 --- a/internal/render/row_event_test.go +++ b/internal/render/row_event_test.go @@ -81,6 +81,26 @@ func TestSort(t *testing.T) { {Row: render.Row{ID: "C", Fields: render.Fields{"10", "2", "3"}}}, }, }, + "id_preserve": { + re: render.RowEvents{ + {Row: render.Row{ID: "ns1/B", Fields: render.Fields{"B", "2", "3"}}}, + {Row: render.Row{ID: "ns1/A", Fields: render.Fields{"A", "2", "3"}}}, + {Row: render.Row{ID: "ns1/C", Fields: render.Fields{"C", "2", "3"}}}, + {Row: render.Row{ID: "ns2/B", Fields: render.Fields{"B", "2", "3"}}}, + {Row: render.Row{ID: "ns2/A", Fields: render.Fields{"A", "2", "3"}}}, + {Row: render.Row{ID: "ns2/C", Fields: render.Fields{"C", "2", "3"}}}, + }, + col: 1, + asc: true, + e: render.RowEvents{ + {Row: render.Row{ID: "ns1/A", Fields: render.Fields{"A", "2", "3"}}}, + {Row: render.Row{ID: "ns1/B", Fields: render.Fields{"B", "2", "3"}}}, + {Row: render.Row{ID: "ns1/C", Fields: render.Fields{"C", "2", "3"}}}, + {Row: render.Row{ID: "ns2/A", Fields: render.Fields{"A", "2", "3"}}}, + {Row: render.Row{ID: "ns2/B", Fields: render.Fields{"B", "2", "3"}}}, + {Row: render.Row{ID: "ns2/C", Fields: render.Fields{"C", "2", "3"}}}, + }, + }, } for k := range uu { From 47d8bfb6e8aedfa0722d3904204769003e46d54b Mon Sep 17 00:00:00 2001 From: derailed Date: Mon, 10 Feb 2020 16:01:16 -0700 Subject: [PATCH 15/58] add rel notes --- change_logs/release_v0.13.9.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 change_logs/release_v0.13.9.md diff --git a/change_logs/release_v0.13.9.md b/change_logs/release_v0.13.9.md new file mode 100644 index 00000000..789faeea --- /dev/null +++ b/change_logs/release_v0.13.9.md @@ -0,0 +1,31 @@ + + +# Release v0.13.9 + +## Notes + +Thank you to all that contributed with flushing out issues and enhancements for K9s! I'll try to mark some of these issues as fixed. But if you don't mind grab the latest rev and see if we're happier with some of the fixes! If you've filed an issue please help me verify and close. Your support, kindness and awesome suggestions to make K9s better is as ever very much noticed and appreciated! + +Also if you dig this tool, please make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer) + +On Slack? Please join us [K9slackers](https://join.slack.com/t/k9sers/shared_invite/enQtOTA5MDEyNzI5MTU0LWQ1ZGI3MzliYzZhZWEyNzYxYzA3NjE0YTk1YmFmNzViZjIyNzhkZGI0MmJjYzhlNjdlMGJhYzE2ZGU1NjkyNTM) + +--- + +Maintenance Release! + +## Resolved Bugs/Features/PRs + +* [Issue #536](https://github.com/derailed/k9s/issues/536) +* [Issue #526](https://github.com/derailed/k9s/issues/526) +* [Issue #564](https://github.com/derailed/k9s/issues/464) + +* [PR #532](https://github.com/derailed/k9s/pull/532) Thank you!! [Joscha Alisch](https://github.com/joscha-alisch) +* [PR #525](https://github.com/derailed/k9s/pull/525) Big Thanks!! [darklore](https://github.com/darklore) +* [PR #524](https://github.com/derailed/k9s/pull/524) Thank you (Again)!! [Joscha Alisch](https://github.com/joscha-alisch) +* [PR #514](https://github.com/derailed/k9s/pull/514) ATTA Boy!! [Alexander F. Rødseth](https://github.com/xyproto) +* [PR #483](https://github.com/derailed/k9s/pull/483) Thank you!! [Paul Varache](https://github.com/paulvarache) + +--- + + © 2020 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0) From 6670600756a4affe09517ba31be9358e751e9b4d Mon Sep 17 00:00:00 2001 From: derailed Date: Mon, 10 Feb 2020 17:31:44 -0700 Subject: [PATCH 16/58] update rel notes --- change_logs/release_v0.13.9.md | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/change_logs/release_v0.13.9.md b/change_logs/release_v0.13.9.md index 098b3cd6..86a83f37 100644 --- a/change_logs/release_v0.13.9.md +++ b/change_logs/release_v0.13.9.md @@ -12,7 +12,39 @@ On Slack? Please join us [K9slackers](https://join.slack.com/t/k9sers/shared_inv --- -Maintenance Release! +## Happy Birthday K9s!! + +🎉🥳🎊 Doh! Almost missed it... 🎉🥳🎊 + + Yes sir, it's been a year (already...) since K9s was first launched 🎉. I can't tell you what a year this has been 🙀. Difficult? sure. However, you guys are making this project a total gas, by your candor, kindness and for giving back via your creative issues, prs, sponsorships, slack channel help to name a few... I do think, you've all been all too quiet tho 🐭... So if K9s helps make your K8s life bett'a on a day to day basis, please reach out for your shoe-phones and dial up [@kitesurfer](https://twitter.com/kitesurfer) or write an article/blog and /cc the K8s/CNCF royalties. Lastly I am so humbled by this... but we're closing on 5k stars/136k downloads in this repo, so please invite 28 of your closest friends soon... + +Major Thanks to all of you for you patience and for making this project a reality to all our K8s friends! You're all redefining awesomeness!! + +Also I'd like to take this opportunity to recognize and thank a few folks that have willingly volunteered their own time to track down issues and help improve K9s for all of us!! + +* [Gustavo Silva Paiva](https://github.com/paivagustavo) +* [Joscha Alisch](https://github.com/joscha-alisch) +* [Michael Christina](https://github.com/mcristina422) +* [Bruno Meneguello](https://github.com/bkmeneguello) +* [Tuomo Syvänperä](https://github.com/syvanpera) +* [Oskar F](https://github.com/fridokus) +* [Bruno Ohms](https://github.com/brunohms) +* [IgorRamalho](https://github.com/IgorRamalho) +* [Benjamin](https://github.com/binarycoded) +* [Norbert Csibra](https://github.com/ncsibra) +* [Andrew Roth](https://github.com/RothAndrew) +* [Sgandon](https://github.com/sgandon) +* [Chris Werner Rau](https://github.com/cwrau) +* [Eldad Assis](https://github.com/eldada) +* [Tobias](https://github.com/mycrEEpy) +* [Helge Sychla](https://github.com/hsychla) +* [Markusi75](https://github.com/Makusi75) +* [Swe-Covis](https://github.com/swe-covis) +* [Evgeniy Shubin](https://github.com/com30n) + +## And On Another Note... + +More bugz...😿 ## Resolved Bugs/Features/PRs From adb1475474a8e7bf79a62d0da754228cf8eaf865 Mon Sep 17 00:00:00 2001 From: derailed Date: Mon, 10 Feb 2020 17:42:37 -0700 Subject: [PATCH 17/58] update rel config --- .goreleaser.yml | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index ffb43d7c..71ceb931 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -22,16 +22,17 @@ builds: - 7 ldflags: - -s -w -X github.com/derailed/k9s/cmd.version={{.Version}} -X github.com/derailed/k9s/cmd.commit={{.Commit}} -X github.com/derailed/k9s/cmd.date={{.Date}} -archive: - replacements: - darwin: Darwin - linux: Linux - windows: Windows - bit: Arm - bitv6: Arm6 - bitv7: Arm7 - 386: i386 - amd64: x86_64 +archives: + - name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}" + replacements: + darwin: Darwin + linux: Linux + windows: Windows + bit: Arm + bitv6: Arm6 + bitv7: Arm7 + 386: i386 + amd64: x86_64 checksum: name_template: "checksums.txt" snapshot: @@ -43,7 +44,7 @@ changelog: - "^docs:" - "^test:" -# Homebrew +# Homebrews brews: - name: k9s github: From 659117a7e4e0069adbf20dd73e50aee0769682a9 Mon Sep 17 00:00:00 2001 From: derailed Date: Mon, 10 Feb 2020 17:43:33 -0700 Subject: [PATCH 18/58] update rel notes --- change_logs/release_v0.13.9.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/change_logs/release_v0.13.9.md b/change_logs/release_v0.13.9.md index 86a83f37..42fe34c2 100644 --- a/change_logs/release_v0.13.9.md +++ b/change_logs/release_v0.13.9.md @@ -16,7 +16,7 @@ On Slack? Please join us [K9slackers](https://join.slack.com/t/k9sers/shared_inv 🎉🥳🎊 Doh! Almost missed it... 🎉🥳🎊 - Yes sir, it's been a year (already...) since K9s was first launched 🎉. I can't tell you what a year this has been 🙀. Difficult? sure. However, you guys are making this project a total gas, by your candor, kindness and for giving back via your creative issues, prs, sponsorships, slack channel help to name a few... I do think, you've all been all too quiet tho 🐭... So if K9s helps make your K8s life bett'a on a day to day basis, please reach out for your shoe-phones and dial up [@kitesurfer](https://twitter.com/kitesurfer) or write an article/blog and /cc the K8s/CNCF royalties. Lastly I am so humbled by this... but we're closing on 5k stars/136k downloads in this repo, so please invite 28 of your closest friends soon... + Yes sir, it's been a year (already...) since K9s was first launched 🎉. I can't tell you what a year this has been 🙀. Difficult? sure. However, you guys are making this project a total gas, by your candor, kindness and for giving back via your creative issues, prs, sponsorships, slack channel help to name a few... I do think, you've all been all too quiet tho 🐭... So if K9s helps make your K8s life bett'a on a day to day basis, please reach out for your shoe-phones and dial up [@kitesurfer](https://twitter.com/kitesurfer) or write an article/blog and share it! Lastly I am so humbled by this... but we're closing on 5k stars/136k downloads in this repo, so please invite 28 of your closest friends soon... Major Thanks to all of you for you patience and for making this project a reality to all our K8s friends! You're all redefining awesomeness!! From e09d61f10d0ab49338b30401a2ba71f3b5c1ac70 Mon Sep 17 00:00:00 2001 From: derailed Date: Mon, 10 Feb 2020 17:51:26 -0700 Subject: [PATCH 19/58] update rel notes --- change_logs/{release_v0.13.9.md => release_v0.14.0.md} | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) rename change_logs/{release_v0.13.9.md => release_v0.14.0.md} (89%) diff --git a/change_logs/release_v0.13.9.md b/change_logs/release_v0.14.0.md similarity index 89% rename from change_logs/release_v0.13.9.md rename to change_logs/release_v0.14.0.md index 42fe34c2..20112695 100644 --- a/change_logs/release_v0.13.9.md +++ b/change_logs/release_v0.14.0.md @@ -1,6 +1,6 @@ -# Release v0.13.9 +# Release v0.14.0 ## Notes @@ -42,6 +42,10 @@ Also I'd like to take this opportunity to recognize and thank a few folks that h * [Swe-Covis](https://github.com/swe-covis) * [Evgeniy Shubin](https://github.com/com30n) +## Search Enabled For Describe/YAML views + +In this drop we made the Describe/YAML views searchable. So you no longer need to plow thru your resource configurations and get directly to the just of it by using the search command ie `/elvis` + `enter`. You can use the familiar keys `n` and `N` to nav back and forth to the next occurrence in a circular buffer fashion once you've reached the BOF/EOF. It's the little things in life... + ## And On Another Note... More bugz...😿 From 54582b9274046d19ca425fc803372f6e1dfc9ac3 Mon Sep 17 00:00:00 2001 From: derailed Date: Mon, 10 Feb 2020 18:01:59 -0700 Subject: [PATCH 20/58] update build target --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index afbae2da..4685f5b8 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ NAME := k9s PACKAGE := github.com/derailed/$(NAME) GIT := $(shell git rev-parse --short HEAD) DATE := $(shell date +%FT%T%Z) -VERSION := v0.12.0 +VERSION ?= v0.14.0 IMG_NAME := derailed/k9s IMAGE := ${IMG_NAME}:${VERSION} From bf0fabcb9e2e742eeaa8c3c07489c4b69c1f2567 Mon Sep 17 00:00:00 2001 From: derailed Date: Mon, 10 Feb 2020 18:04:51 -0700 Subject: [PATCH 21/58] udpate rel targets --- .goreleaser.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 71ceb931..2643bb05 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -15,7 +15,6 @@ builds: goarch: - 386 - amd64 - - arm - arm64 goarm: - 6 From 8299129baf56c705bed35d294411400d954e358b Mon Sep 17 00:00:00 2001 From: derailed Date: Mon, 10 Feb 2020 19:27:22 -0700 Subject: [PATCH 22/58] cleaning up --- internal/view/details.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/view/details.go b/internal/view/details.go index 76bf5916..66d64624 100644 --- a/internal/view/details.go +++ b/internal/view/details.go @@ -73,11 +73,13 @@ func (d *Details) Init(_ context.Context) error { return nil } +// TextChanged notifies the model changed. func (d *Details) TextChanged(lines []string) { d.SetText(colorizeYAML(d.app.Styles.Views().Yaml, strings.Join(lines, "\n"))) d.ScrollToBeginning() } +// TextFiltered notifies when the filter changed. func (d *Details) TextFiltered(lines []string, matches fuzzy.Matches) { d.currentRegion, d.maxRegions = 0, 0 From aa58d1063aa9e325afabacbe561c3368e939a80d Mon Sep 17 00:00:00 2001 From: derailed Date: Tue, 11 Feb 2020 15:26:49 -0700 Subject: [PATCH 23/58] fix pod xray menu + layout --- go.mod | 1 + go.sum | 26 +++ internal/client/client.go | 38 ++-- internal/client/config.go | 4 + internal/client/types.go | 2 +- internal/config/mock_connection_test.go | 6 +- internal/config/styles.go | 3 + internal/dao/container_test.go | 2 +- internal/dao/context.go | 3 +- internal/dao/node.go | 2 - internal/model/mock_clustermeta_test.go | 6 +- internal/model/table.go | 14 +- internal/ui/logo.go | 4 + internal/ui/tree.go | 4 +- internal/view/actions.go | 8 +- internal/view/app.go | 36 ++-- internal/view/browser.go | 3 - internal/view/context.go | 1 + internal/view/exec.go | 2 +- internal/view/helpers.go | 25 ++- internal/view/pod.go | 117 +++++++----- internal/view/xray.go | 179 ++++++++++-------- internal/xray/container.go | 6 +- internal/xray/container_test.go | 2 +- internal/xray/pod.go | 9 +- internal/xray/pod_test.go | 34 ++-- .../{test_assets => testdata}/cilium.json | 0 .../xray/{test_assets => testdata}/dp.json | 0 .../xray/{test_assets => testdata}/ds.json | 0 .../xray/{test_assets => testdata}/init.json | 0 .../xray/{test_assets => testdata}/ns.json | 0 .../xray/{test_assets => testdata}/po.json | 0 .../xray/{test_assets => testdata}/rs.json | 0 .../xray/{test_assets => testdata}/sa.json | 0 .../xray/{test_assets => testdata}/sts.json | 0 .../xray/{test_assets => testdata}/svc.json | 0 internal/xray/tree_node.go | 90 ++++++--- internal/xray/tree_node_test.go | 116 ++++++------ 38 files changed, 443 insertions(+), 300 deletions(-) rename internal/xray/{test_assets => testdata}/cilium.json (100%) rename internal/xray/{test_assets => testdata}/dp.json (100%) rename internal/xray/{test_assets => testdata}/ds.json (100%) rename internal/xray/{test_assets => testdata}/init.json (100%) rename internal/xray/{test_assets => testdata}/ns.json (100%) rename internal/xray/{test_assets => testdata}/po.json (100%) rename internal/xray/{test_assets => testdata}/rs.json (100%) rename internal/xray/{test_assets => testdata}/sa.json (100%) rename internal/xray/{test_assets => testdata}/sts.json (100%) rename internal/xray/{test_assets => testdata}/svc.json (100%) diff --git a/go.mod b/go.mod index 5af8ab15..b8356134 100644 --- a/go.mod +++ b/go.mod @@ -28,6 +28,7 @@ replace ( ) require ( + fyne.io/fyne v1.2.2 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/atotto/clipboard v0.1.2 github.com/derailed/tview v0.3.3 diff --git a/go.sum b/go.sum index 16167445..824aab0a 100644 --- a/go.sum +++ b/go.sum @@ -3,6 +3,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +fyne.io/fyne v1.2.2 h1:mf7EseASp3CAC5vLWVPLnsoKxvp/ARdu3Seh0HvAQak= +fyne.io/fyne v1.2.2/go.mod h1:Ab+3DIB/FVteW0y4DXfmZv4N3JdnCBh2lHkINI02BOU= github.com/Azure/azure-sdk-for-go v32.5.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= @@ -29,6 +31,7 @@ github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFD github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14= github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5hodBMJ5+l/7J4xAyMeuM2PNuepvHlGs8yilUCA= +github.com/Kodeworks/golang-image-ico v0.0.0-20141118225523-73f0f4cfade9/go.mod h1:7uhhqiBaR4CpN0k9rMjOtjpcfGd6DG2m04zQxKnWQ0I= github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e h1:eb0Pzkt15Bm7f2FFYv7sjY7NPFi3cPkS3tv1CcrFBWA= github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= @@ -59,6 +62,7 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdko github.com/Rican7/retry v0.1.0/go.mod h1:FgOROf8P5bebcC1DS0PdOQiqGUridaZvikzUmkFW6gg= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= +github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -212,6 +216,10 @@ github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8 h1:DujepqpGd1hyOd7a github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/go-acme/lego v2.5.0+incompatible/go.mod h1:yzMNe9CasVUhkquNvti5nAtPmG94USbYxYrZfTkIn0M= github.com/go-bindata/go-bindata v3.1.1+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo= +github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7 h1:SCYMcCJ89LjRGwEa0tRluNRiMjZHalQZrVrvTbPh+qw= +github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk= +github.com/go-gl/glfw v0.0.0-20181213070059-819e8ce5125f h1:7MsFMbSn8Lcw0blK4+NEOf8DuHoOBDhJsHz04yh13pM= +github.com/go-gl/glfw v0.0.0-20181213070059-819e8ce5125f/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= @@ -283,6 +291,8 @@ github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09Vjb github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff h1:W71vTCKoxtdXgnm1ECDFkfQnpdqAO00zzGXLA5yaEX8= +github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff/go.mod h1:wfqRWLHRBsRgkp5dmbG56SA0DmVtwrF5N3oPdI8t+Aw= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -366,9 +376,11 @@ github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jackmordaunt/icns v0.0.0-20181231085925-4f16af745526/go.mod h1:UQkeMHVoNcyXYq9otUupF7/h/2tmHlhrS2zw7ZVvUqc= github.com/jimstudt/http-authentication v0.0.0-20140401203705-3eca13d6893a/go.mod h1:wK6yTYYcgjHE1Z1QtXACPDjcFJyBskHEdagmnq3vsP8= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/josephspurrier/goversioninfo v0.0.0-20190124120936-8611f5a5ff3f/go.mod h1:eJTEwMjXb7kZ633hO3Ln9mBUCOjX2+FlTljvpl9SYdE= github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= @@ -460,6 +472,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= github.com/naoina/toml v0.1.1/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= @@ -568,6 +582,10 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/srwiley/oksvg v0.0.0-20190829233741-58e08c8fe40e h1:LJUrNHytcMXWKxnULIHPe5SCb1jDpO9o672VB1x2EuQ= +github.com/srwiley/oksvg v0.0.0-20190829233741-58e08c8fe40e/go.mod h1:afMbS0qvv1m5tfENCwnOdZGOF8RGR/FsZ7bvBxQGZG4= +github.com/srwiley/rasterx v0.0.0-20181219215540-696f7edb7a7e h1:FFotfUvew9Eg02LYRl8YybAnm0HCwjjfY5JlOI1oB00= +github.com/srwiley/rasterx v0.0.0-20181219215540-696f7edb7a7e/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU= github.com/storageos/go-api v0.0.0-20180912212459-343b3eff91fc/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -577,6 +595,7 @@ github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRci github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/syndtr/gocapability v0.0.0-20160928074757-e7cb7fa329f4/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= @@ -630,8 +649,12 @@ golang.org/x/crypto v0.0.0-20191028145041-f83a4685e152 h1:ZC1Xn5A1nlpSmQCIva4bZ3 golang.org/x/crypto v0.0.0-20191028145041-f83a4685e152/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495 h1:I6A9Ag9FpEKOjcKrRNjQkPHawoXIhKyTGfvvjFAiiAk= golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -639,6 +662,8 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -695,6 +720,7 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756 h1:9nuHUbU8dRnRRfj9KjWUVrJeoexdbeMjttk6Oh1rD10= golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191028164358-195ce5e7f934 h1:u/E0NqCIWRDAo9WCFo6Ko49njPFDLSd3z+X1HgWDMpE= golang.org/x/sys v0.0.0-20191028164358-195ce5e7f934/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/internal/client/client.go b/internal/client/client.go index 7c287284..11a1132e 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -77,6 +77,12 @@ func makeCacheKey(ns, gvr string, vv []string) string { return ns + ":" + gvr + "::" + strings.Join(vv, ",") } +func (a *APIClient) clearCache() { + for _, k := range a.cache.Keys() { + a.cache.Remove(k) + } +} + // CanI checks if user has access to a certain resource. func (a *APIClient) CanI(ns, gvr string, verbs []string) (auth bool, err error) { if IsClusterWide(ns) { @@ -131,6 +137,9 @@ func (a *APIClient) ValidNamespaces() ([]v1.Namespace, error) { // BOZO!! No super sure about this approach either?? func (a *APIClient) CheckConnectivity() (status bool) { defer func() { + if !status { + a.clearCache() + } if err := recover(); err != nil { status = false } @@ -149,10 +158,10 @@ func (a *APIClient) CheckConnectivity() (status bool) { } } - if _, err := a.checkClientSet.ServerVersion(); err != nil { - log.Error().Err(err).Msgf("K9s can't connect to cluster") - } else { + if _, err := a.checkClientSet.ServerVersion(); err == nil { status = true + } else { + log.Error().Err(err).Msgf("K9s can't connect to cluster") } return @@ -258,21 +267,24 @@ func (a *APIClient) MXDial() (*versioned.Clientset, error) { return a.mxsClient, err } -// SwitchContextOrDie handles kubeconfig context switches. -func (a *APIClient) SwitchContextOrDie(ctx string) { +// SwitchContext handles kubeconfig context switches. +func (a *APIClient) SwitchContext(ctx string) error { currentCtx, err := a.config.CurrentContextName() if err != nil { - log.Fatal().Err(err).Msg("Fetching current context") + return err + } + if currentCtx == ctx { + return nil } - if currentCtx != ctx { - a.cachedClient = nil - a.reset() - if err := a.config.SwitchContext(ctx); err != nil { - log.Fatal().Err(err).Msg("Switching context") - } - _ = a.supportsMxServer() + if err := a.config.SwitchContext(ctx); err != nil { + return err } + a.clearCache() + a.reset() + _ = a.supportsMxServer() + + return nil } func (a *APIClient) reset() { diff --git a/internal/client/config.go b/internal/client/config.go index bcfec129..58f9d74d 100644 --- a/internal/client/config.go +++ b/internal/client/config.go @@ -48,6 +48,10 @@ func (c *Config) SwitchContext(name string) error { return err } + if _, err := c.GetContext(name); err != nil { + return fmt.Errorf("context %s does not exist", name) + } + if currentCtx != name { c.reset() c.flags.Context, c.currentContext = &name, name diff --git a/internal/client/types.go b/internal/client/types.go index 91e1f247..48fe4146 100644 --- a/internal/client/types.go +++ b/internal/client/types.go @@ -64,7 +64,7 @@ type Connection interface { Config() *Config DialOrDie() kubernetes.Interface - SwitchContextOrDie(ctx string) + SwitchContext(ctx string) error CachedDiscoveryOrDie() *disk.CachedDiscoveryClient RestConfigOrDie() *restclient.Config MXDial() (*versioned.Clientset, error) diff --git a/internal/config/mock_connection_test.go b/internal/config/mock_connection_test.go index 57a8104b..d2fd8c48 100644 --- a/internal/config/mock_connection_test.go +++ b/internal/config/mock_connection_test.go @@ -267,12 +267,14 @@ func (mock *MockConnection) SupportsResource(_param0 string) bool { return ret0 } -func (mock *MockConnection) SwitchContextOrDie(_param0 string) { +func (mock *MockConnection) SwitchContext(_param0 string) error { if mock == nil { panic("mock must not be nil. Use myMock := NewMockConnection().") } params := []pegomock.Param{_param0} - pegomock.GetGenericMockFrom(mock).Invoke("SwitchContextOrDie", params, []reflect.Type{}) + pegomock.GetGenericMockFrom(mock).Invoke("SwitchContext", params, []reflect.Type{reflect.TypeOf((*error)(nil)).Elem()}) + + return nil } func (mock *MockConnection) ValidNamespaces() ([]v1.Namespace, error) { diff --git a/internal/config/styles.go b/internal/config/styles.go index f72c8233..ef7596bd 100644 --- a/internal/config/styles.go +++ b/internal/config/styles.go @@ -389,6 +389,9 @@ func (s *Styles) Update() { // AsColor checks color index, if match return color otherwise pink it is. func AsColor(c string) tcell.Color { + if c == "default" { + return tcell.ColorDefault + } if color, ok := tcell.ColorNames[c]; ok { return color } diff --git a/internal/dao/container_test.go b/internal/dao/container_test.go index 2b61a9d1..a486017f 100644 --- a/internal/dao/container_test.go +++ b/internal/dao/container_test.go @@ -44,7 +44,7 @@ func makeConn() *conn { func (c *conn) Config() *client.Config { return nil } func (c *conn) DialOrDie() kubernetes.Interface { return nil } -func (c *conn) SwitchContextOrDie(ctx string) {} +func (c *conn) SwitchContext(ctx string) error { return nil } func (c *conn) CachedDiscoveryOrDie() *disk.CachedDiscoveryClient { return nil } func (c *conn) RestConfigOrDie() *restclient.Config { return nil } func (c *conn) MXDial() (*versioned.Clientset, error) { return nil, nil } diff --git a/internal/dao/context.go b/internal/dao/context.go index 1741dbd1..da13e7b2 100644 --- a/internal/dao/context.go +++ b/internal/dao/context.go @@ -58,8 +58,7 @@ func (c *Context) MustCurrentContextName() string { // Switch to another context. func (c *Context) Switch(ctx string) error { - c.Factory.Client().SwitchContextOrDie(ctx) - return nil + return c.Factory.Client().SwitchContext(ctx) } // KubeUpdate modifies kubeconfig default context. diff --git a/internal/dao/node.go b/internal/dao/node.go index c821fdc1..ec58eb6d 100644 --- a/internal/dao/node.go +++ b/internal/dao/node.go @@ -29,8 +29,6 @@ type Node struct { // List returns a collection of node resources. func (n *Node) List(ctx context.Context, ns string) ([]runtime.Object, error) { - log.Debug().Msgf("NODE-LIST %q:%q", ns, n.gvr) - labels, ok := ctx.Value(internal.KeyLabels).(string) if !ok { log.Warn().Msgf("No label selector found in context") diff --git a/internal/model/mock_clustermeta_test.go b/internal/model/mock_clustermeta_test.go index cf5426c2..a47a8434 100644 --- a/internal/model/mock_clustermeta_test.go +++ b/internal/model/mock_clustermeta_test.go @@ -332,12 +332,14 @@ func (mock *MockClusterMeta) SupportsResource(_param0 string) bool { return ret0 } -func (mock *MockClusterMeta) SwitchContextOrDie(_param0 string) { +func (mock *MockClusterMeta) SwitchContext(_param0 string) error { if mock == nil { panic("mock must not be nil. Use myMock := NewMockClusterMeta().") } params := []pegomock.Param{_param0} - pegomock.GetGenericMockFrom(mock).Invoke("SwitchContextOrDie", params, []reflect.Type{}) + pegomock.GetGenericMockFrom(mock).Invoke("SwitchContext", params, []reflect.Type{reflect.TypeOf((*error)(nil)).Elem()}) + + return nil } func (mock *MockClusterMeta) UserName() (string, error) { diff --git a/internal/model/table.go b/internal/model/table.go index 327d5586..2fbb6376 100644 --- a/internal/model/table.go +++ b/internal/model/table.go @@ -2,6 +2,7 @@ package model import ( "context" + "errors" "fmt" "sync" "sync/atomic" @@ -75,10 +76,15 @@ func (t *Table) RemoveListener(l TableListener) { // Watch initiates model updates. func (t *Table) Watch(ctx context.Context) { - t.Refresh(ctx) + t.refresh(ctx) go t.updater(ctx) } +// Refresh updates the table content. +func (t *Table) Refresh(ctx context.Context) { + t.refresh(ctx) +} + // Get returns a resource instance if found, else an error. func (t *Table) Get(ctx context.Context, path string) (runtime.Object, error) { meta, err := t.getMeta(ctx) @@ -134,11 +140,6 @@ func (t *Table) ToYAML(ctx context.Context, path string) (string, error) { return desc.ToYAML(path) } -// Refresh update the model now. -func (t *Table) Refresh(ctx context.Context) { - t.refresh(ctx) -} - // GetNamespace returns the model namespace. func (t *Table) GetNamespace() string { return t.namespace @@ -185,6 +186,7 @@ func (t *Table) updater(ctx context.Context) { for { select { case <-ctx.Done(): + t.fireTableLoadFailed(errors.New("operation canceled")) return case <-time.After(rate): rate = t.refreshRate diff --git a/internal/ui/logo.go b/internal/ui/logo.go index 7789833e..0935de22 100644 --- a/internal/ui/logo.go +++ b/internal/ui/logo.go @@ -3,6 +3,8 @@ package ui import ( "fmt" + "github.com/gdamore/tcell" + "github.com/derailed/k9s/internal/config" "github.com/derailed/tview" ) @@ -94,6 +96,7 @@ func (l *Logo) refreshLogo(c string) { func logo() *tview.TextView { v := tview.NewTextView() + v.SetBackgroundColor(tcell.ColorDefault) v.SetWordWrap(false) v.SetWrap(false) v.SetTextAlign(tview.AlignLeft) @@ -104,6 +107,7 @@ func logo() *tview.TextView { func status() *tview.TextView { v := tview.NewTextView() + v.SetBackgroundColor(tcell.ColorDefault) v.SetWordWrap(false) v.SetWrap(false) v.SetTextAlign(tview.AlignCenter) diff --git a/internal/ui/tree.go b/internal/ui/tree.go index 61363d14..8179418c 100644 --- a/internal/ui/tree.go +++ b/internal/ui/tree.go @@ -35,7 +35,7 @@ func NewTree() *Tree { // Init initializes the view func (t *Tree) Init(ctx context.Context) error { - t.bindKeys() + t.BindKeys() t.SetBorder(true) t.SetBorderAttributes(tcell.AttrBold) t.SetBorderPadding(0, 0, 1, 1) @@ -86,7 +86,7 @@ func (t *Tree) ExtraHints() map[string]string { return nil } -func (t *Tree) bindKeys() { +func (t *Tree) BindKeys() { t.Actions().Add(KeyActions{ KeySpace: NewKeyAction("Expand/Collapse", t.noopCmd, true), KeyX: NewKeyAction("Expand/Collapse All", t.toggleCollapseCmd, true), diff --git a/internal/view/actions.go b/internal/view/actions.go index 38ccec30..f0ec5529 100644 --- a/internal/view/actions.go +++ b/internal/view/actions.go @@ -118,12 +118,16 @@ func execCmd(r Runner, bin string, bg bool, args ...string) ui.ActionHandler { ns, _ := client.Namespaced(path) var ( - env = r.EnvFn()() aa = make([]string, len(args)) err error ) + + if r.EnvFn() == nil { + return nil + } + for i, a := range args { - aa[i], err = env.envFor(ns, a) + aa[i], err = r.EnvFn()().envFor(ns, a) if err != nil { log.Error().Err(err).Msg("Plugin Args match failed") return nil diff --git a/internal/view/app.go b/internal/view/app.go index 43efb7f8..aded6e6f 100644 --- a/internal/view/app.go +++ b/internal/view/app.go @@ -4,7 +4,7 @@ import ( "context" "errors" "fmt" - "sync" + "sync/atomic" "time" "github.com/derailed/k9s/internal" @@ -24,7 +24,7 @@ var ExitStatus = "" const ( splashDelay = 1 * time.Second clusterRefresh = 5 * time.Second - maxConRetry = 5 + maxConRetry = 10 clusterInfoWidth = 50 clusterInfoPad = 15 ) @@ -39,9 +39,8 @@ type App struct { version string showHeader bool cancelFn context.CancelFunc - conRetry int + conRetry int32 clusterModel *model.ClusterInfo - mx sync.Mutex } // NewApp returns a K9s app instance. @@ -61,9 +60,7 @@ func NewApp(cfg *config.Config) *App { // ConOK checks the connection is cool, returns false otherwise. func (a *App) ConOK() bool { - a.mx.Lock() - defer a.mx.Unlock() - return a.conRetry == 0 + return atomic.LoadInt32(&a.conRetry) == 0 } // Init initializes the application. @@ -198,32 +195,31 @@ func (a *App) clusterUpdater(ctx context.Context) { } func (a *App) refreshCluster() { - a.mx.Lock() - defer a.mx.Unlock() - c := a.Content.Top() if ok := a.Conn().CheckConnectivity(); ok { - if a.conRetry > 0 { + if atomic.LoadInt32(&a.conRetry) > 0 { + atomic.StoreInt32(&a.conRetry, 0) + a.Status(ui.FlashInfo, "K8s connectivity OK") if c != nil { c.Start() } - a.Status(ui.FlashInfo, "K8s connectivity OK") } - a.conRetry = 0 } else { - a.conRetry++ - log.Warn().Msgf("Conn check failed (%d/%d)", a.conRetry, maxConRetry) + atomic.AddInt32(&a.conRetry, 1) if c != nil { c.Stop() } - a.Status(ui.FlashWarn, fmt.Sprintf("Dial K8s failed (%d)", a.conRetry)) - + count := atomic.LoadInt32(&a.conRetry) + log.Warn().Msgf("Conn check failed (%d/%d)", count, maxConRetry) + a.Status(ui.FlashWarn, fmt.Sprintf("Dial K8s failed (%d)", count)) } - if a.conRetry >= maxConRetry { - ExitStatus = fmt.Sprintf("Lost K8s connection (%d). Bailing out!", a.conRetry) + + count := atomic.LoadInt32(&a.conRetry) + if count >= maxConRetry { + ExitStatus = fmt.Sprintf("Lost K8s connection (%d). Bailing out!", count) a.BailOut() } - if a.conRetry > 0 { + if count > 0 { return } diff --git a/internal/view/browser.go b/internal/view/browser.go index 4d265775..8dc6d351 100644 --- a/internal/view/browser.go +++ b/internal/view/browser.go @@ -93,7 +93,6 @@ func (b *Browser) SetInstance(path string) { func (b *Browser) Start() { b.Stop() - log.Debug().Msgf("BROWSER started!") b.Table.Start() ctx := b.defaultContext() ctx, b.cancelFn = context.WithCancel(ctx) @@ -111,7 +110,6 @@ func (b *Browser) Stop() { if b.cancelFn == nil { return } - log.Debug().Msgf("BROWSER Stopped!") b.Table.Stop() b.cancelFn() b.cancelFn = nil @@ -373,7 +371,6 @@ func (b *Browser) refreshActions() { if b.app.ConOK() { b.namespaceActions(aa) - if !b.app.Config.K9s.GetReadOnly() { if client.Can(b.meta.Verbs, "edit") { aa[ui.KeyE] = ui.NewKeyAction("Edit", b.editCmd, true) diff --git a/internal/view/context.go b/internal/view/context.go index 54ffb613..fce01e41 100644 --- a/internal/view/context.go +++ b/internal/view/context.go @@ -55,6 +55,7 @@ func useContext(app *App, name string) error { return errors.New("Expecting a switchable resource") } if err := switcher.Switch(name); err != nil { + log.Error().Err(err).Msgf("Context switch failed") return err } if err := app.switchCtx(name, false); err != nil { diff --git a/internal/view/exec.go b/internal/view/exec.go index f85d010c..ff905ca7 100644 --- a/internal/view/exec.go +++ b/internal/view/exec.go @@ -76,7 +76,7 @@ func execute(opts shellOpts) error { cancel() }() - log.Debug().Msgf("Running command > %s %s", opts.binary, strings.Join(opts.args, " ")) + log.Debug().Msgf("Running command> %s %s", opts.binary, strings.Join(opts.args, " ")) cmd := exec.Command(opts.binary, opts.args...) diff --git a/internal/view/helpers.go b/internal/view/helpers.go index 58d05ffe..a48e5057 100644 --- a/internal/view/helpers.go +++ b/internal/view/helpers.go @@ -16,39 +16,44 @@ import ( "github.com/rs/zerolog/log" ) -func defaultK9sEnv(app *App, sel string, row render.Row) K9sEnv { - ns, n := client.Namespaced(sel) - ctx, err := app.Conn().Config().CurrentContextName() +func generalEnv(a *App) K9sEnv { + ctx, err := a.Conn().Config().CurrentContextName() if err != nil { ctx = render.NAValue } - cluster, err := app.Conn().Config().CurrentClusterName() + cluster, err := a.Conn().Config().CurrentClusterName() if err != nil { cluster = render.NAValue } - user, err := app.Conn().Config().CurrentUserName() + user, err := a.Conn().Config().CurrentUserName() if err != nil { user = render.NAValue } - groups, err := app.Conn().Config().CurrentGroupNames() + groups, err := a.Conn().Config().CurrentGroupNames() if err != nil { groups = []string{render.NAValue} } + var cfg string - kcfg := app.Conn().Config().Flags().KubeConfig + kcfg := a.Conn().Config().Flags().KubeConfig if kcfg != nil && *kcfg != "" { cfg = *kcfg } - env := K9sEnv{ - "NAMESPACE": ns, - "NAME": n, + return K9sEnv{ "CONTEXT": ctx, "CLUSTER": cluster, "USER": user, "GROUPS": strings.Join(groups, ","), "KUBECONFIG": cfg, } +} + +func defaultK9sEnv(a *App, sel string, row render.Row) K9sEnv { + ns, n := client.Namespaced(sel) + + env := generalEnv(a) + env["NAMESPACE"], env["NAME"] = ns, n for i, r := range row.Fields { env["COL"+strconv.Itoa(i)] = r diff --git a/internal/view/pod.go b/internal/view/pod.go index 436fa883..11f50ec0 100644 --- a/internal/view/pod.go +++ b/internal/view/pod.go @@ -8,6 +8,7 @@ import ( "github.com/derailed/k9s/internal" "github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/dao" + "github.com/derailed/k9s/internal/model" "github.com/derailed/k9s/internal/render" "github.com/derailed/k9s/internal/ui" "github.com/derailed/k9s/internal/watch" @@ -108,47 +109,86 @@ func (p *Pod) killCmd(evt *tcell.EventKey) *tcell.EventKey { } func (p *Pod) shellCmd(evt *tcell.EventKey) *tcell.EventKey { - sel := p.GetTable().GetSelectedItem() - if sel == "" { + path := p.GetTable().GetSelectedItem() + if path == "" { return evt } row := p.GetTable().GetSelectedRowIndex() status := ui.TrimCell(p.GetTable().SelectTable, row, p.GetTable().NameColIndex()+2) if status != render.Running { - p.App().Flash().Errf("%s is not in a running state", sel) + p.App().Flash().Errf("%s is not in a running state", path) return nil } - cc, err := fetchContainers(p.App().factory, sel, false) - if err != nil { - p.App().Flash().Errf("Unable to retrieve containers %s", err) - return evt - } - if len(cc) == 1 { - p.shellIn(sel, cc[0]) - return nil - } - picker := NewPicker() - picker.populate(cc) - picker.SetSelectedFunc(func(i int, t, d string, r rune) { - p.shellIn(sel, t) - }) - if err := p.App().inject(picker); err != nil { + + if err := containerShellin(p.App(), p, path, ""); err != nil { p.App().Flash().Err(err) } - return evt -} - -func (p *Pod) shellIn(path, co string) { - p.Stop() - shellIn(p.App(), path, co) - p.Start() + return nil } // ---------------------------------------------------------------------------- // Helpers... +func containerShellin(a *App, comp model.Component, path, co string) error { + if co != "" { + resumeShellIn(a, comp, path, co) + return nil + } + + cc, err := fetchContainers(a.factory, path, false) + if err != nil { + return err + } + if len(cc) == 1 { + resumeShellIn(a, comp, path, cc[0]) + return nil + } + picker := NewPicker() + picker.populate(cc) + picker.SetSelectedFunc(func(_ int, co, _ string, _ rune) { + resumeShellIn(a, comp, path, co) + }) + if err := a.inject(picker); err != nil { + return err + } + + return nil +} + +func resumeShellIn(a *App, c model.Component, path, co string) { + c.Stop() + defer c.Start() + shellIn(a, path, co) +} + +func shellIn(a *App, path, co string) { + args := computeShellArgs(path, co, a.Config.K9s.CurrentContext, a.Conn().Config().Flags().KubeConfig) + + c := color.New(color.BgGreen).Add(color.FgBlack).Add(color.Bold) + if !runK(a, shellOpts{clear: true, banner: c.Sprintf(bannerFmt, path, co), args: args}) { + a.Flash().Err(errors.New("Shell exec failed")) + } +} + +func computeShellArgs(path, co, context string, kcfg *string) []string { + args := make([]string, 0, 15) + args = append(args, "exec", "-it") + args = append(args, "--context", context) + ns, po := client.Namespaced(path) + args = append(args, "-n", ns) + args = append(args, po) + if kcfg != nil && *kcfg != "" { + args = append(args, "--kubeconfig", *kcfg) + } + if co != "" { + args = append(args, "-c", co) + } + + return append(args, "--", "sh", "-c", shellCheck) +} + func fetchContainers(f *watch.Factory, path string, includeInit bool) ([]string, error) { o, err := f.Get("v1/pods", path, true, labels.Everything()) if err != nil { @@ -172,30 +212,3 @@ func fetchContainers(f *watch.Factory, path string, includeInit bool) ([]string, } return nn, nil } - -func shellIn(a *App, path, co string) { - args := computeShellArgs(path, co, a.Config.K9s.CurrentContext, a.Conn().Config().Flags().KubeConfig) - log.Debug().Msgf("Shell args %v", args) - - c := color.New(color.BgGreen).Add(color.FgBlack).Add(color.Bold) - if !runK(a, shellOpts{clear: true, banner: c.Sprintf(bannerFmt, path, co), args: args}) { - a.Flash().Err(errors.New("Shell exec failed")) - } -} - -func computeShellArgs(path, co, context string, kcfg *string) []string { - args := make([]string, 0, 15) - args = append(args, "exec", "-it") - args = append(args, "--context", context) - ns, po := client.Namespaced(path) - args = append(args, "-n", ns) - args = append(args, po) - if kcfg != nil && *kcfg != "" { - args = append(args, "--kubeconfig", *kcfg) - } - if co != "" { - args = append(args, "-c", co) - } - - return append(args, "--", "sh", "-c", shellCheck) -} diff --git a/internal/view/xray.go b/internal/view/xray.go index c4847839..8d0841e9 100644 --- a/internal/view/xray.go +++ b/internal/view/xray.go @@ -50,6 +50,8 @@ func NewXray(gvr client.GVR) ResourceViewer { // Init initializes the view func (x *Xray) Init(ctx context.Context) error { + x.envFn = x.k9sEnv + if err := x.Tree.Init(ctx); err != nil { return err } @@ -77,12 +79,12 @@ func (x *Xray) Init(ctx context.Context) error { x.model.AddListener(x) x.SetChangedFunc(func(n *tview.TreeNode) { - ref, ok := n.GetReference().(xray.NodeSpec) + spec, ok := n.GetReference().(xray.NodeSpec) if !ok { log.Error().Msgf("No ref found on node %s", n.GetText()) return } - x.SetSelectedItem(ref.Path) + x.SetSelectedItem(spec.AsPath()) x.refreshActions() }) x.refreshActions() @@ -131,16 +133,18 @@ func (x *Xray) refreshActions() { x.Actions().Clear() x.bindKeys() + x.Tree.BindKeys() - ref := x.selectedSpec() - if ref == nil { + spec := x.selectedSpec() + if spec == nil { return } + gvr := spec.GVR() var err error - x.meta, err = dao.MetaAccess.MetaFor(client.NewGVR(ref.GVR)) + x.meta, err = dao.MetaAccess.MetaFor(client.NewGVR(gvr)) if err != nil { - log.Warn().Msgf("NO meta for %q -- %s", ref.GVR, err) + log.Warn().Msgf("NO meta for %q -- %s", gvr, err) return } @@ -155,22 +159,27 @@ func (x *Xray) refreshActions() { aa[ui.KeyD] = ui.NewKeyAction("Describe", x.describeCmd, true) } - if ref.GVR == "containers" { + switch gvr { + case "containers": + x.Actions().Delete(tcell.KeyEnter) + aa[ui.KeyS] = ui.NewKeyAction("Shell", x.shellCmd, true) + aa[ui.KeyL] = ui.NewKeyAction("Logs", x.logsCmd(false), true) + aa[ui.KeyShiftL] = ui.NewKeyAction("Logs Previous", x.logsCmd(true), true) + case "v1/pods": aa[ui.KeyS] = ui.NewKeyAction("Shell", x.shellCmd, true) aa[ui.KeyL] = ui.NewKeyAction("Logs", x.logsCmd(false), true) aa[ui.KeyShiftL] = ui.NewKeyAction("Logs Previous", x.logsCmd(true), true) } - x.Actions().Add(aa) } // GetSelectedPath returns the current selection as string. func (x *Xray) GetSelectedPath() string { - ref := x.selectedSpec() - if ref == nil { + spec := x.selectedSpec() + if spec == nil { return "" } - return ref.Path + return spec.Path() } func (x *Xray) selectedSpec() *xray.NodeSpec { @@ -193,6 +202,34 @@ func (x *Xray) EnvFn() EnvFunc { return x.envFn } +func (x *Xray) k9sEnv() K9sEnv { + env := generalEnv(x.app) + + spec := x.selectedSpec() + if spec == nil { + return env + } + + env["FILTER"] = x.CmdBuff().String() + if env["FILTER"] == "" { + ns, n := client.Namespaced(spec.Path()) + env["NAMESPACE"], env["FILTER"] = ns, n + } + + switch spec.GVR() { + case "containers": + _, co := client.Namespaced(spec.Path()) + env["CONTAINER"] = co + ns, n := client.Namespaced(*spec.ParentPath()) + env["NAMESPACE"], env["POD"], env["NAME"] = ns, n, co + default: + ns, n := client.Namespaced(spec.Path()) + env["NAMESPACE"], env["NAME"] = ns, n + } + + return env +} + // Aliases returns all available aliases. func (x *Xray) Aliases() []string { return append(x.meta.ShortNames, x.meta.SingularName, x.meta.Name) @@ -200,100 +237,98 @@ func (x *Xray) Aliases() []string { func (x *Xray) logsCmd(prev bool) func(evt *tcell.EventKey) *tcell.EventKey { return func(evt *tcell.EventKey) *tcell.EventKey { - ref := x.selectedSpec() - if ref == nil { + spec := x.selectedSpec() + if spec == nil { return nil } - if ref.Parent != nil { - x.showLogs(ref.Parent, ref, prev) - } else { - log.Error().Msgf("No parent found for container %q", ref.Path) - } + x.showLogs(spec, prev) return nil } } -func (x *Xray) showLogs(pod, co *xray.NodeSpec, prev bool) { +func (x *Xray) showLogs(spec *xray.NodeSpec, prev bool) { // Need to load and wait for pods - ns, _ := client.Namespaced(pod.Path) + path, co := spec.Path(), "" + if spec.GVR() == "containers" { + _, coName := client.Namespaced(spec.Path()) + path, co = *spec.ParentPath(), coName + } + + ns, _ := client.Namespaced(path) _, err := x.app.factory.CanForResource(ns, "v1/pods", client.MonitorAccess) if err != nil { x.app.Flash().Err(err) return } - if err := x.app.inject(NewLog(client.NewGVR(co.GVR), pod.Path, co.Path, prev)); err != nil { + if err := x.app.inject(NewLog(client.NewGVR("v1/pods"), path, co, prev)); err != nil { x.app.Flash().Err(err) } } func (x *Xray) shellCmd(evt *tcell.EventKey) *tcell.EventKey { - ref := x.selectedSpec() - if ref == nil { + spec := x.selectedSpec() + if spec == nil { return nil } - if ref.Status != "" { - x.app.Flash().Errf("%s is not in a running state", ref.Path) + if spec.Status() != "ok" { + x.app.Flash().Errf("%s is not in a running state", spec.Path()) return nil } - if ref.Parent != nil { - _, co := client.Namespaced(ref.Path) - x.shellIn(ref.Parent.Path, co) - } else { - log.Error().Msgf("No parent found on container node %q", ref.Path) + path, co := spec.Path(), "" + if spec.GVR() == "containers" { + _, co = client.Namespaced(spec.Path()) + path = *spec.ParentPath() + } + + if err := containerShellin(x.app, x, path, co); err != nil { + x.app.Flash().Err(err) } return nil } -func (x *Xray) shellIn(path, co string) { - x.Stop() - shellIn(x.app, path, co) - x.Start() -} - func (x *Xray) viewCmd(evt *tcell.EventKey) *tcell.EventKey { - ref := x.selectedSpec() - if ref == nil { + spec := x.selectedSpec() + if spec == nil { return evt } ctx := x.defaultContext() - raw, err := x.model.ToYAML(ctx, ref.GVR, ref.Path) + raw, err := x.model.ToYAML(ctx, spec.GVR(), spec.Path()) if err != nil { - x.App().Flash().Errf("unable to get resource %q -- %s", ref.GVR, err) + x.App().Flash().Errf("unable to get resource %q -- %s", spec.GVR(), err) return nil } - details := NewDetails(x.app, "YAML", ref.Path, true).Update(raw) + details := NewDetails(x.app, "YAML", spec.Path(), true).Update(raw) if err := x.app.inject(details); err != nil { x.app.Flash().Err(err) } return nil - } func (x *Xray) deleteCmd(evt *tcell.EventKey) *tcell.EventKey { - ref := x.selectedSpec() - if ref == nil { + spec := x.selectedSpec() + if spec == nil { return evt } x.Stop() defer x.Start() { - gvr := client.NewGVR(ref.GVR) + gvr := client.NewGVR(spec.GVR()) meta, err := dao.MetaAccess.MetaFor(gvr) if err != nil { - log.Warn().Msgf("NO meta for %q -- %s", ref.GVR, err) + log.Warn().Msgf("NO meta for %q -- %s", spec.GVR(), err) return nil } - x.resourceDelete(gvr, ref, fmt.Sprintf("Delete %s %s?", meta.SingularName, ref.Path)) + x.resourceDelete(gvr, spec, fmt.Sprintf("Delete %s %s?", meta.SingularName, spec.Path())) } return nil @@ -301,12 +336,12 @@ func (x *Xray) deleteCmd(evt *tcell.EventKey) *tcell.EventKey { } func (x *Xray) describeCmd(evt *tcell.EventKey) *tcell.EventKey { - ref := x.selectedSpec() - if ref == nil { + spec := x.selectedSpec() + if spec == nil { return evt } - x.describe(ref.GVR, ref.Path) + x.describe(spec.GVR(), spec.Path()) return nil } @@ -328,18 +363,18 @@ func (x *Xray) describe(gvr, path string) { } func (x *Xray) editCmd(evt *tcell.EventKey) *tcell.EventKey { - ref := x.selectedSpec() - if ref == nil { + spec := x.selectedSpec() + if spec == nil { return evt } x.Stop() defer x.Start() { - ns, n := client.Namespaced(ref.Path) + ns, n := client.Namespaced(spec.Path()) args := make([]string, 0, 10) args = append(args, "edit") - args = append(args, client.NewGVR(ref.GVR).R()) + args = append(args, client.NewGVR(spec.GVR()).R()) args = append(args, "-n", ns) args = append(args, "--context", x.app.Config.K9s.CurrentContext) if cfg := x.app.Conn().Config().Flags().KubeConfig; cfg != nil && *cfg != "" { @@ -408,14 +443,15 @@ func (x *Xray) gotoCmd(evt *tcell.EventKey) *tcell.EventKey { return nil } - ref := x.selectedSpec() - if ref == nil { + spec := x.selectedSpec() + if spec == nil { return nil } - if len(strings.Split(ref.Path, "/")) == 1 { + log.Debug().Msgf("SELECTED REF %#v", spec) + if len(strings.Split(spec.Path(), "/")) == 1 { return nil } - if err := x.app.viewResource(client.NewGVR(ref.GVR).R(), ref.Path, false); err != nil { + if err := x.app.viewResource(client.NewGVR(spec.GVR()).R(), spec.Path(), false); err != nil { x.app.Flash().Err(err) } @@ -464,13 +500,13 @@ func (x *Xray) update(node *xray.TreeNode) { x.hydrate(root, c) } if x.GetSelectedItem() == "" { - x.SetSelectedItem(node.ID) + x.SetSelectedItem(node.Spec().Path()) } x.app.QueueUpdateDraw(func() { x.SetRoot(root) root.Walk(func(node, parent *tview.TreeNode) bool { - ref, ok := node.GetReference().(xray.NodeSpec) + spec, ok := node.GetReference().(xray.NodeSpec) if !ok { log.Error().Msgf("Expecting a NodeSpec but got %T", node.GetReference()) return false @@ -482,7 +518,8 @@ func (x *Xray) update(node *xray.TreeNode) { node.SetExpanded(true) } - if ref.Path == x.GetSelectedItem() { + if spec.AsPath() == x.GetSelectedItem() { + log.Debug().Msgf("SEL %q--%q", spec.Path(), x.GetSelectedItem()) node.SetExpanded(true).SetSelectable(true) x.SetCurrentNode(node) } @@ -611,9 +648,9 @@ func (x *Xray) styleTitle() string { return title + ui.SkinTitle(fmt.Sprintf(ui.SearchFmt, buff), x.app.Styles.Frame()) } -func (x *Xray) resourceDelete(gvr client.GVR, ref *xray.NodeSpec, msg string) { +func (x *Xray) resourceDelete(gvr client.GVR, spec *xray.NodeSpec, msg string) { dialog.ShowDelete(x.app.Content.Pages, msg, func(cascade, force bool) { - x.app.Flash().Infof("Delete resource %s %s", ref.GVR, ref.Path) + x.app.Flash().Infof("Delete resource %s %s", spec.GVR(), spec.Path()) accessor, err := dao.AccessorFor(x.app.factory, gvr) if err != nil { log.Error().Err(err).Msgf("No accessor") @@ -625,11 +662,11 @@ func (x *Xray) resourceDelete(gvr client.GVR, ref *xray.NodeSpec, msg string) { x.app.Flash().Errf("Invalid nuker %T", accessor) return } - if err := nuker.Delete(ref.Path, true, true); err != nil { + if err := nuker.Delete(spec.Path(), true, true); err != nil { x.app.Flash().Errf("Delete failed with `%s", err) } else { - x.app.Flash().Infof("%s `%s deleted successfully", x.GVR(), ref.Path) - x.app.factory.DeleteForwarder(ref.Path) + x.app.Flash().Infof("%s `%s deleted successfully", x.GVR(), spec.Path()) + x.app.factory.DeleteForwarder(spec.Path()) } x.Refresh() }, func() {}) @@ -661,15 +698,7 @@ func makeTreeNode(node *xray.TreeNode, expanded bool, styles *config.Styles) *tv n := tview.NewTreeNode("No data...") if node != nil { n.SetText(node.Title(styles.Xray())) - spec := xray.NodeSpec{} - if p := node.Parent; p != nil { - spec.GVR, spec.Path = p.GVR, p.ID - } - n.SetReference(xray.NodeSpec{ - GVR: node.GVR, - Path: node.ID, - Parent: &spec, - }) + n.SetReference(node.Spec()) } n.SetSelectable(true) n.SetExpanded(expanded) diff --git a/internal/xray/container.go b/internal/xray/container.go index ae1a8eb5..c4ba5ead 100644 --- a/internal/xray/container.go +++ b/internal/xray/container.go @@ -35,9 +35,9 @@ func (c *Container) Render(ctx context.Context, ns string, o interface{}) error } pns, _ := client.Namespaced(parent.ID) c.envRefs(f, root, pns, co.Container) - if !root.IsLeaf() { - parent.Add(root) - } + // if !root.IsLeaf() { + parent.Add(root) + // } return nil } diff --git a/internal/xray/container_test.go b/internal/xray/container_test.go index 31aca2a3..bf18164c 100644 --- a/internal/xray/container_test.go +++ b/internal/xray/container_test.go @@ -235,7 +235,7 @@ func makeDoubleCMKeysContainer(n string, optional bool) *v1.Container { } func load(t *testing.T, n string) *unstructured.Unstructured { - raw, err := ioutil.ReadFile(fmt.Sprintf("test_assets/%s.json", n)) + raw, err := ioutil.ReadFile(fmt.Sprintf("testdata/%s.json", n)) assert.Nil(t, err) var o unstructured.Unstructured diff --git a/internal/xray/pod.go b/internal/xray/pod.go index 9a9e0cf6..434253a0 100644 --- a/internal/xray/pod.go +++ b/internal/xray/pod.go @@ -40,7 +40,6 @@ func (p *Pod) Render(ctx context.Context, ns string, o interface{}) error { if !ok { return fmt.Errorf("Expecting a TreeNode but got %T", ctx.Value(KeyParent)) } - parent.Add(node) if err := p.containerRefs(ctx, node, po.Namespace, po.Spec); err != nil { return err @@ -50,6 +49,14 @@ func (p *Pod) Render(ctx context.Context, ns string, o interface{}) error { return err } + gvr, nsID := "v1/namespaces", client.FQN(client.ClusterScope, po.Namespace) + nsn := parent.Find(gvr, nsID) + if nsn == nil { + nsn = NewTreeNode(gvr, nsID) + parent.Add(nsn) + } + nsn.Add(node) + return p.validate(node, po) } diff --git a/internal/xray/pod_test.go b/internal/xray/pod_test.go index ffa1fbc8..7d144304 100644 --- a/internal/xray/pod_test.go +++ b/internal/xray/pod_test.go @@ -12,27 +12,27 @@ import ( func TestPodRender(t *testing.T) { uu := map[string]struct { - file string - level1, level2 int - status string + file string + count, children int + status string }{ "plain": { - file: "po", - level1: 1, - level2: 3, - status: xray.OkStatus, + file: "po", + children: 1, + count: 7, + status: xray.OkStatus, }, "withInit": { - file: "init", - level1: 1, - level2: 2, - status: xray.OkStatus, + file: "init", + children: 1, + count: 7, + status: xray.OkStatus, }, "cilium": { - file: "cilium", - level1: 1, - level2: 3, - status: xray.OkStatus, + file: "cilium", + children: 1, + count: 8, + status: xray.OkStatus, }, } @@ -46,8 +46,8 @@ func TestPodRender(t *testing.T) { ctx = context.WithValue(ctx, internal.KeyFactory, makeFactory()) assert.Nil(t, re.Render(ctx, "", &render.PodWithMetrics{Raw: o})) - assert.Equal(t, u.level1, root.CountChildren()) - assert.Equal(t, u.level2, root.Children[0].CountChildren()) + assert.Equal(t, u.children, root.CountChildren()) + assert.Equal(t, u.count, root.Count("")) }) } } diff --git a/internal/xray/test_assets/cilium.json b/internal/xray/testdata/cilium.json similarity index 100% rename from internal/xray/test_assets/cilium.json rename to internal/xray/testdata/cilium.json diff --git a/internal/xray/test_assets/dp.json b/internal/xray/testdata/dp.json similarity index 100% rename from internal/xray/test_assets/dp.json rename to internal/xray/testdata/dp.json diff --git a/internal/xray/test_assets/ds.json b/internal/xray/testdata/ds.json similarity index 100% rename from internal/xray/test_assets/ds.json rename to internal/xray/testdata/ds.json diff --git a/internal/xray/test_assets/init.json b/internal/xray/testdata/init.json similarity index 100% rename from internal/xray/test_assets/init.json rename to internal/xray/testdata/init.json diff --git a/internal/xray/test_assets/ns.json b/internal/xray/testdata/ns.json similarity index 100% rename from internal/xray/test_assets/ns.json rename to internal/xray/testdata/ns.json diff --git a/internal/xray/test_assets/po.json b/internal/xray/testdata/po.json similarity index 100% rename from internal/xray/test_assets/po.json rename to internal/xray/testdata/po.json diff --git a/internal/xray/test_assets/rs.json b/internal/xray/testdata/rs.json similarity index 100% rename from internal/xray/test_assets/rs.json rename to internal/xray/testdata/rs.json diff --git a/internal/xray/test_assets/sa.json b/internal/xray/testdata/sa.json similarity index 100% rename from internal/xray/test_assets/sa.json rename to internal/xray/testdata/sa.json diff --git a/internal/xray/test_assets/sts.json b/internal/xray/testdata/sts.json similarity index 100% rename from internal/xray/test_assets/sts.json rename to internal/xray/testdata/sts.json diff --git a/internal/xray/test_assets/svc.json b/internal/xray/testdata/svc.json similarity index 100% rename from internal/xray/test_assets/svc.json rename to internal/xray/testdata/svc.json diff --git a/internal/xray/tree_node.go b/internal/xray/tree_node.go index bab59321..8825e408 100644 --- a/internal/xray/tree_node.go +++ b/internal/xray/tree_node.go @@ -52,8 +52,51 @@ type TreeRef string // NodeSpec represents a node resource specification. type NodeSpec struct { - GVR, Path, Status string - Parent *NodeSpec + GVRs, Paths, Statuses []string +} + +func (s NodeSpec) ParentGVR() *string { + if len(s.GVRs) > 1 { + return &s.GVRs[1] + } + return nil +} + +func (s NodeSpec) ParentPath() *string { + if len(s.Paths) > 1 { + return &s.Paths[1] + } + return nil +} + +// GVR returns the current GVR. +func (s NodeSpec) GVR() string { + return s.GVRs[0] +} + +// Path returns the current path. +func (s NodeSpec) Path() string { + return s.Paths[0] +} + +// Status returns the current status. +func (s NodeSpec) Status() string { + return s.Statuses[0] +} + +// AsPath returns path hierarchy as string. +func (s NodeSpec) AsPath() string { + return strings.Join(s.Paths, PathSeparator) +} + +// AsGVR returns a gvr hierarchy as string. +func (s NodeSpec) AsGVR() string { + return strings.Join(s.GVRs, PathSeparator) +} + +// AsStatus returns a status hierarchy as string. +func (s NodeSpec) AsStatus() string { + return strings.Join(s.Statuses, PathSeparator) } // ---------------------------------------------------------------------------- @@ -145,19 +188,17 @@ func (t *TreeNode) Sort() { // Spec returns this node specification. func (t *TreeNode) Spec() NodeSpec { - parent := t - var gvr, path, status []string - for parent != nil { - gvr = append(gvr, parent.GVR) - path = append(path, parent.ID) - status = append(status, parent.Extras[StatusKey]) - parent = parent.Parent + var GVRs, Paths, Statuses []string + for parent := t; parent != nil; parent = parent.Parent { + GVRs = append(GVRs, parent.GVR) + Paths = append(Paths, parent.ID) + Statuses = append(Statuses, parent.Extras[StatusKey]) } return NodeSpec{ - GVR: strings.Join(gvr, PathSeparator), - Path: strings.Join(path, PathSeparator), - Status: strings.Join(status, PathSeparator), + GVRs: GVRs, + Paths: Paths, + Statuses: Statuses, } } @@ -180,21 +221,18 @@ func (t *TreeNode) Blank() bool { } // Hydrate hydrates a full tree bases on a collection of specifications. -func Hydrate(refs []NodeSpec) *TreeNode { +func Hydrate(specs []NodeSpec) *TreeNode { root := NewTreeNode("", "") nav := root - for _, ref := range refs { - gvrs := strings.Split(ref.GVR, PathSeparator) - paths := strings.Split(ref.Path, PathSeparator) - statuses := strings.Split(ref.Status, PathSeparator) - for i := len(paths) - 1; i >= 0; i-- { + for _, spec := range specs { + for i := len(spec.Paths) - 1; i >= 0; i-- { if nav.Blank() { - nav.GVR, nav.ID, nav.Extras[StatusKey] = gvrs[i], paths[i], statuses[i] + nav.GVR, nav.ID, nav.Extras[StatusKey] = spec.GVRs[i], spec.Paths[i], spec.Statuses[i] continue } - c := NewTreeNode(gvrs[i], paths[i]) - c.Extras[StatusKey] = statuses[i] - if n := nav.Find(gvrs[i], paths[i]); n == nil { + c := NewTreeNode(spec.GVRs[i], spec.Paths[i]) + c.Extras[StatusKey] = spec.Statuses[i] + if n := nav.Find(spec.GVRs[i], spec.Paths[i]); n == nil { nav.Add(c) nav = c } else { @@ -260,7 +298,7 @@ func (t *TreeNode) Filter(q string, filter func(q, path string) bool) *TreeNode specs := t.Flatten() matches := make([]NodeSpec, 0, len(specs)) for _, s := range specs { - if filter(q, s.Path+s.Status) { + if filter(q, s.AsPath()+s.AsStatus()) { matches = append(matches, s) } } @@ -461,7 +499,7 @@ func toEmoji(gvr string) string { // EmojiInfo returns emoji help. func EmojiInfo() map[string]string { - gvrs := []string{ + GVRs := []string{ "containers", "v1/namespaces", "v1/pods", @@ -476,8 +514,8 @@ func EmojiInfo() map[string]string { "apps/v1/daemonsets", } - m := make(map[string]string, len(gvrs)) - for _, g := range gvrs { + m := make(map[string]string, len(GVRs)) + for _, g := range GVRs { m[client.NewGVR(g).R()] = toEmoji(g) } diff --git a/internal/xray/tree_node_test.go b/internal/xray/tree_node_test.go index 652bc7fd..fbce2e10 100644 --- a/internal/xray/tree_node_test.go +++ b/internal/xray/tree_node_test.go @@ -86,8 +86,8 @@ func TestTreeNodeFilter(t *testing.T) { } func TestTreeNodeHydrate(t *testing.T) { - threeOK := strings.Join([]string{"ok", "ok", "ok"}, xray.PathSeparator) - fiveOK := strings.Join([]string{"ok", "ok", "ok", "ok", "ok"}, xray.PathSeparator) + threeOK := []string{"ok", "ok", "ok"} + fiveOK := append(threeOK, "ok", "ok") uu := map[string]struct { spec []xray.NodeSpec @@ -96,14 +96,14 @@ func TestTreeNodeHydrate(t *testing.T) { "flat_simple": { spec: []xray.NodeSpec{ { - GVR: "containers::v1/pods", - Path: "c1::default/p1", - Status: threeOK, + GVRs: []string{"containers", "v1/pods"}, + Paths: []string{"c1", "default/p1"}, + Statuses: threeOK, }, { - GVR: "containers::v1/pods", - Path: "c2::default/p1", - Status: threeOK, + GVRs: []string{"containers", "v1/pods"}, + Paths: []string{"c2", "default/p1"}, + Statuses: threeOK, }, }, e: root1(), @@ -111,14 +111,14 @@ func TestTreeNodeHydrate(t *testing.T) { "flat_complex": { spec: []xray.NodeSpec{ { - GVR: "v1/secrets::containers::v1/pods", - Path: "s1::c1::default/p1", - Status: threeOK, + GVRs: []string{"v1/secrets", "containers", "v1/pods"}, + Paths: []string{"s1", "c1", "default/p1"}, + Statuses: threeOK, }, { - GVR: "v1/secrets::containers::v1/pods", - Path: "s2::c2::default/p1", - Status: threeOK, + GVRs: []string{"v1/secrets", "containers", "v1/pods"}, + Paths: []string{"s2", "c2", "default/p1"}, + Statuses: threeOK, }, }, e: root2(), @@ -126,49 +126,49 @@ func TestTreeNodeHydrate(t *testing.T) { "complex1": { spec: []xray.NodeSpec{ { - GVR: "v1/secrets::v1/pods::apps/v1/deployments::v1/namespaces::apps/v1/deployments", - Path: "default/default-token-rr22g::default/nginx-6b866d578b-c6tcn::default/nginx::-/default::deployments", - Status: fiveOK, + GVRs: []string{"v1/secrets", "v1/pods", "apps/v1/deployments", "v1/namespaces", "apps/v1/deployments"}, + Paths: []string{"default/default-token-rr22g", "default/nginx-6b866d578b-c6tcn", "default/nginx", "-/default", "deployments"}, + Statuses: fiveOK, }, { - GVR: "v1/configmaps::v1/pods::apps/v1/deployments::v1/namespaces::apps/v1/deployments", - Path: "kube-system/coredns::kube-system/coredns-6955765f44-89q2p::kube-system/coredns::-/kube-system::deployments", - Status: fiveOK, + GVRs: []string{"v1/configmaps", "v1/pods", "apps/v1/deployments", "v1/namespaces", "apps/v1/deployments"}, + Paths: []string{"kube-system/coredns", "kube-system/coredns-6955765f44-89q2p", "kube-system/coredns", "-/kube-system", "deployments"}, + Statuses: fiveOK, }, { - GVR: "v1/secrets::v1/pods::apps/v1/deployments::v1/namespaces::apps/v1/deployments", - Path: "kube-system/coredns-token-5cq9j::kube-system/coredns-6955765f44-89q2p::kube-system/coredns::-/kube-system::deployments", - Status: fiveOK, + GVRs: []string{"v1/secrets", "v1/pods", "apps/v1/deployments", "v1/namespaces", "apps/v1/deployments"}, + Paths: []string{"kube-system/coredns-token-5cq9j", "kube-system/coredns-6955765f44-89q2p", "kube-system/coredns", "-/kube-system", "deployments"}, + Statuses: fiveOK, }, { - GVR: "v1/configmaps::v1/pods::apps/v1/deployments::v1/namespaces::apps/v1/deployments", - Path: "kube-system/coredns::kube-system/coredns-6955765f44-r9j9t::kube-system/coredns::-/kube-system::deployments", - Status: fiveOK, + GVRs: []string{"v1/configmaps", "v1/pods", "apps/v1/deployments", "v1/namespaces", "apps/v1/deployments"}, + Paths: []string{"kube-system/coredns", "kube-system/coredns-6955765f44-r9j9t", "kube-system/coredns", "-/kube-system", "deployments"}, + Statuses: fiveOK, }, { - GVR: "v1/secrets::v1/pods::apps/v1/deployments::v1/namespaces::apps/v1/deployments", - Path: "kube-system/coredns-token-5cq9j::kube-system/coredns-6955765f44-r9j9t::kube-system/coredns::-/kube-system::deployments", - Status: fiveOK, + GVRs: []string{"v1/secrets", "v1/pods", "apps/v1/deployments", "v1/namespaces", "apps/v1/deployments"}, + Paths: []string{"kube-system/coredns-token-5cq9j", "kube-system/coredns-6955765f44-r9j9t", "kube-system/coredns", "-/kube-system", "deployments"}, + Statuses: fiveOK, }, { - GVR: "v1/secrets::v1/pods::apps/v1/deployments::v1/namespaces::apps/v1/deployments", - Path: "kube-system/default-token-thzt8::kube-system/metrics-server-6754dbc9df-88bk4::kube-system/metrics-server::-/kube-system::deployments", - Status: fiveOK, + GVRs: []string{"v1/secrets", "v1/pods", "apps/v1/deployments", "v1/namespaces", "apps/v1/deployments"}, + Paths: []string{"kube-system/default-token-thzt8", "kube-system/metrics-server-6754dbc9df-88bk4", "kube-system/metrics-server", "-/kube-system", "deployments"}, + Statuses: fiveOK, }, { - GVR: "v1/secrets::v1/pods::apps/v1/deployments::v1/namespaces::apps/v1/deployments", - Path: "kube-system/nginx-ingress-token-kff5q::kube-system/nginx-ingress-controller-6fc5bcc8c9-cwp55::kube-system/nginx-ingress-controller::-/kube-system::deployments", - Status: fiveOK, + GVRs: []string{"v1/secrets", "v1/pods", "apps/v1/deployments", "v1/namespaces", "apps/v1/deployments"}, + Paths: []string{"kube-system/nginx-ingress-token-kff5q", "kube-system/nginx-ingress-controller-6fc5bcc8c9-cwp55", "kube-system/nginx-ingress-controller", "-/kube-system", "deployments"}, + Statuses: fiveOK, }, { - GVR: "v1/secrets::v1/pods::apps/v1/deployments::v1/namespaces::apps/v1/deployments", - Path: "kubernetes-dashboard/kubernetes-dashboard-token-d6rt4::kubernetes-dashboard/dashboard-metrics-scraper-7b64584c5c-c7b56::kubernetes-dashboard/dashboard-metrics-scraper::-/kubernetes-dashboard::deployments", - Status: fiveOK, + GVRs: []string{"v1/secrets", "v1/pods", "apps/v1/deployments", "v1/namespaces", "apps/v1/deployments"}, + Paths: []string{"kubernetes-dashboard/kubernetes-dashboard-token-d6rt4", "kubernetes-dashboard/dashboard-metrics-scraper-7b64584c5c-c7b56", "kubernetes-dashboard/dashboard-metrics-scraper", "-/kubernetes-dashboard", "deployments"}, + Statuses: fiveOK, }, { - GVR: "v1/secrets::v1/pods::apps/v1/deployments::v1/namespaces::apps/v1/deployments", - Path: "kubernetes-dashboard/kubernetes-dashboard-token-d6rt4::kubernetes-dashboard/kubernetes-dashboard-79d9cd965-b4c7d::kubernetes-dashboard/kubernetes-dashboard::-/kubernetes-dashboard::deployments", - Status: fiveOK, + GVRs: []string{"v1/secrets", "v1/pods", "apps/v1/deployments", "v1/namespaces", "apps/v1/deployments"}, + Paths: []string{"kubernetes-dashboard/kubernetes-dashboard-token-d6rt4", "kubernetes-dashboard/kubernetes-dashboard-79d9cd965-b4c7d", "kubernetes-dashboard/kubernetes-dashboard", "-/kubernetes-dashboard", "deployments"}, + Statuses: fiveOK, }, }, e: root3(), @@ -193,14 +193,14 @@ func TestTreeNodeFlatten(t *testing.T) { root: root1(), e: []xray.NodeSpec{ { - GVR: "containers::v1/pods", - Path: "c1::default/p1", - Status: strings.Join([]string{"ok", "ok"}, xray.PathSeparator), + GVRs: []string{"containers", "v1/pods"}, + Paths: []string{"c1", "default/p1"}, + Statuses: []string{"ok", "ok"}, }, { - GVR: "containers::v1/pods", - Path: "c2::default/p1", - Status: strings.Join([]string{"ok", "ok"}, xray.PathSeparator), + GVRs: []string{"containers", "v1/pods"}, + Paths: []string{"c2", "default/p1"}, + Statuses: []string{"ok", "ok"}, }, }, }, @@ -208,14 +208,14 @@ func TestTreeNodeFlatten(t *testing.T) { root: root2(), e: []xray.NodeSpec{ { - GVR: "v1/secrets::containers::v1/pods", - Path: "s1::c1::default/p1", - Status: strings.Join([]string{"ok", "ok", "ok"}, xray.PathSeparator), + GVRs: []string{"v1/secrets", "containers", "v1/pods"}, + Paths: []string{"s1", "c1", "default/p1"}, + Statuses: []string{"ok", "ok", "ok"}, }, { - GVR: "v1/secrets::containers::v1/pods", - Path: "s2::c2::default/p1", - Status: strings.Join([]string{"ok", "ok", "ok"}, xray.PathSeparator), + GVRs: []string{"v1/secrets", "containers", "v1/pods"}, + Paths: []string{"s2", "c2", "default/p1"}, + Statuses: []string{"ok", "ok", "ok"}, }, }, }, @@ -323,18 +323,18 @@ func diff1() *xray.TreeNode { } func root2() *xray.TreeNode { - n := xray.NewTreeNode("v1/pods", "default/p1") c1 := xray.NewTreeNode("containers", "c1") - c2 := xray.NewTreeNode("containers", "c2") - n.Add(c1) - n.Add(c2) - s1 := xray.NewTreeNode("v1/secrets", "s1") c1.Add(s1) + c2 := xray.NewTreeNode("containers", "c2") s2 := xray.NewTreeNode("v1/secrets", "s2") c2.Add(s2) + n := xray.NewTreeNode("v1/pods", "default/p1") + n.Add(c1) + n.Add(c2) + return n } From 7000b93d4e64fadd10ee2c04c1fa5498a4d1a7a6 Mon Sep 17 00:00:00 2001 From: derailed Date: Tue, 11 Feb 2020 23:44:49 -0700 Subject: [PATCH 24/58] enhanced xray pod view and add support for transparent background --- README.md | 8 +-- go.mod | 2 +- go.sum | 2 + internal/config/styles.go | 6 ++ internal/render/helpers.go | 2 +- internal/render/helpers_test.go | 2 +- internal/ui/config.go | 3 + internal/ui/menu.go | 4 +- internal/ui/menu_test.go | 6 +- internal/ui/splash.go | 4 +- internal/ui/table_helper.go | 11 +++- internal/view/app.go | 2 +- internal/view/cluster_info.go | 12 +++- skins/black_and_wtf.yml | 92 ++++++++++++++++------------ skins/dracula.yml | 3 + skins/in_the_navy.yml | 104 +++++++++++++++++++------------- 16 files changed, 161 insertions(+), 102 deletions(-) diff --git a/README.md b/README.md index 038f0ccb..114ff127 100644 --- a/README.md +++ b/README.md @@ -454,7 +454,7 @@ You can style K9s based on your own sense of look and style. Skins are YAML file You can also change K9s skins based on the cluster you are connecting too. In this case, you can specify the skin file name as `$HOME/.k9s/mycluster_skin.yml` Below is a sample skin file, more skins are available in the skins directory in this repo, just simply copy any of these in your user's home dir as `skin.yml`. -Colors can be defined by name or uing an hex representation. +Colors can be defined by name or uing an hex representation. Of recent, we've added a color named `default` to indicate a transparent background color to preserve your terminal background color settings if so desired. > NOTE: This is very much an experimental feature at this time, more will be added/modified if this feature has legs so thread accordingly! @@ -464,8 +464,8 @@ k9s: # General K9s styles body: fgColor: dodgerblue - bgColor: #ffffff - logoColor: #0000ff + bgColor: '#ffffff' + logoColor: '#0000ff' # ClusterInfoView styles. info: fgColor: lightskyblue @@ -488,7 +488,7 @@ k9s: activeColor: skyblue # Resource status and update styles status: - newColor: #00ff00 + newColor: '#00ff00' modifyColor: powderblue addColor: lightskyblue errorColor: indianred diff --git a/go.mod b/go.mod index b8356134..a42b7e03 100644 --- a/go.mod +++ b/go.mod @@ -31,7 +31,7 @@ require ( fyne.io/fyne v1.2.2 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/atotto/clipboard v0.1.2 - github.com/derailed/tview v0.3.3 + github.com/derailed/tview v0.3.4 github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f // indirect github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f // indirect github.com/fatih/color v1.6.0 diff --git a/go.sum b/go.sum index 824aab0a..847d5a31 100644 --- a/go.sum +++ b/go.sum @@ -147,6 +147,8 @@ github.com/deislabs/oras v0.7.0 h1:RnDoFd3tQYODMiUqxgQ8JxlrlWL0/VMKIKRD01MmNYk= github.com/deislabs/oras v0.7.0/go.mod h1:sqMKPG3tMyIX9xwXUBRLhZ24o+uT4y6jgBD2RzUTKDM= github.com/derailed/tview v0.3.3 h1:tipPwxcDhx0zRBZuc8VKIrNgWL40FL5JeF/30XVieUE= github.com/derailed/tview v0.3.3/go.mod h1:yApPszFU62FoaGkf7swy2nIdV/h7Nid3dhMSVy6+OFI= +github.com/derailed/tview v0.3.4 h1:PnF64fLqm48LEjC/XwOS7JufDgFuuPYx85YVt5t3rwE= +github.com/derailed/tview v0.3.4/go.mod h1:yApPszFU62FoaGkf7swy2nIdV/h7Nid3dhMSVy6+OFI= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= diff --git a/internal/config/styles.go b/internal/config/styles.go index ef7596bd..854ad73b 100644 --- a/internal/config/styles.go +++ b/internal/config/styles.go @@ -292,6 +292,11 @@ func NewStyles() *Styles { } } +// LoadDefaults loads the default skin +func (s *Styles) DefaultSkins() { + s.K9s = newStyle() +} + // FgColor returns the foreground color. func (s *Styles) FgColor() tcell.Color { return AsColor(s.Body().FgColor) @@ -385,6 +390,7 @@ func (s *Styles) Update() { tview.Styles.PrimaryTextColor = s.FgColor() tview.Styles.BorderColor = AsColor(s.K9s.Frame.Border.FgColor) tview.Styles.FocusColor = AsColor(s.K9s.Frame.Border.FocusColor) + s.fireStylesChanged() } // AsColor checks color index, if match return color otherwise pink it is. diff --git a/internal/render/helpers.go b/internal/render/helpers.go index 33996772..a598065d 100644 --- a/internal/render/helpers.go +++ b/internal/render/helpers.go @@ -151,7 +151,7 @@ func Truncate(str string, width int) string { func mapToStr(m map[string]string) (s string) { if len(m) == 0 { - return MissingValue + return "" } kk := make([]string, 0, len(m)) diff --git a/internal/render/helpers_test.go b/internal/render/helpers_test.go index b45edd36..ed366a46 100644 --- a/internal/render/helpers_test.go +++ b/internal/render/helpers_test.go @@ -305,7 +305,7 @@ func TestMapToStr(t *testing.T) { e string }{ {map[string]string{"blee": "duh", "aa": "bb"}, "aa=bb,blee=duh"}, - {map[string]string{}, MissingValue}, + {map[string]string{}, ""}, } for _, u := range uu { assert.Equal(t, u.e, mapToStr(u.i)) diff --git a/internal/ui/config.go b/internal/ui/config.go index cc4f69e3..96080c3d 100644 --- a/internal/ui/config.go +++ b/internal/ui/config.go @@ -103,6 +103,9 @@ func (c *Configurator) RefreshStyles(context string) { func (c *Configurator) updateStyles(f string) { c.skinFile = f + if !c.HasSkins() { + c.Styles.DefaultSkins() + } c.Styles.Update() render.StdColor = config.AsColor(c.Styles.Frame().Status.NewColor) diff --git a/internal/ui/menu.go b/internal/ui/menu.go index 55184944..ef44f60a 100644 --- a/internal/ui/menu.go +++ b/internal/ui/menu.go @@ -15,7 +15,7 @@ import ( ) const ( - menuIndexFmt = " [key:bg:b]<%d> [fg:bg:d]%s " + menuIndexFmt = " [key:-:b]<%d> [fg:-:d]%s " maxRows = 7 ) @@ -195,7 +195,7 @@ func formatNSMenu(i int, name string, styles config.Frame) string { } func formatPlainMenu(h model.MenuHint, size int, styles config.Frame) string { - menuFmt := " [key:bg:b]%-" + strconv.Itoa(size+2) + "s [fg:bg:d]%s " + menuFmt := " [key:-:b]%-" + strconv.Itoa(size+2) + "s [fg:-:d]%s " fmat := strings.Replace(menuFmt, "[key", "["+styles.Menu.KeyColor, 1) fmat = strings.Replace(fmat, "[fg", "["+styles.Menu.FgColor, 1) fmat = strings.Replace(fmat, ":bg:", ":"+styles.Title.BgColor+":", -1) diff --git a/internal/ui/menu_test.go b/internal/ui/menu_test.go index ead592ca..51511448 100644 --- a/internal/ui/menu_test.go +++ b/internal/ui/menu_test.go @@ -18,9 +18,9 @@ func TestNewMenu(t *testing.T) { {Mnemonic: "0", Description: "zero", Visible: true}, }) - assert.Equal(t, " [fuchsia:black:b]<0> [white:black:d]zero ", v.GetCell(0, 0).Text) - assert.Equal(t, " [dodgerblue:black:b] [white:black:d]bleeA ", v.GetCell(0, 1).Text) - assert.Equal(t, " [dodgerblue:black:b] [white:black:d]bleeB ", v.GetCell(1, 1).Text) + assert.Equal(t, " [fuchsia:-:b]<0> [white:-:d]zero ", v.GetCell(0, 0).Text) + assert.Equal(t, " [dodgerblue:-:b] [white:-:d]bleeA ", v.GetCell(0, 1).Text) + assert.Equal(t, " [dodgerblue:-:b] [white:-:d]bleeB ", v.GetCell(1, 1).Text) } func TestActionHints(t *testing.T) { diff --git a/internal/ui/splash.go b/internal/ui/splash.go index 3c43d318..ba44f209 100644 --- a/internal/ui/splash.go +++ b/internal/ui/splash.go @@ -6,7 +6,6 @@ import ( "github.com/derailed/k9s/internal/config" "github.com/derailed/tview" - "github.com/gdamore/tcell" ) // LogoSmall K9s small log. @@ -37,16 +36,15 @@ type Splash struct { // NewSplash instantiates a new splash screen with product and company info. func NewSplash(styles *config.Styles, version string) *Splash { s := Splash{Flex: tview.NewFlex()} + s.SetBackgroundColor(styles.BgColor()) logo := tview.NewTextView() logo.SetDynamicColors(true) - logo.SetBackgroundColor(tcell.ColorDefault) logo.SetTextAlign(tview.AlignCenter) s.layoutLogo(logo, styles) vers := tview.NewTextView() vers.SetDynamicColors(true) - vers.SetBackgroundColor(tcell.ColorDefault) vers.SetTextAlign(tview.AlignCenter) s.layoutRev(vers, version, styles) diff --git a/internal/ui/table_helper.go b/internal/ui/table_helper.go index a8f271a1..c3d5b0ef 100644 --- a/internal/ui/table_helper.go +++ b/internal/ui/table_helper.go @@ -14,6 +14,9 @@ import ( ) const ( + // DefaultColorName indicator to keep term colors. + DefaultColorName = "default" + // SearchFmt represents a filter view title. SearchFmt = "<[filter:bg:r]/%s[fg:bg:-]> " @@ -81,12 +84,16 @@ func TrimLabelSelector(s string) string { // SkinTitle decorates a title. func SkinTitle(fmat string, style config.Frame) string { - fmat = strings.Replace(fmat, "[fg:bg", "["+style.Title.FgColor+":"+style.Title.BgColor, -1) + bgColor := style.Title.BgColor + if bgColor == "default" { + bgColor = "-" + } + fmat = strings.Replace(fmat, "[fg:bg", "["+style.Title.FgColor+":"+bgColor, -1) fmat = strings.Replace(fmat, "[hilite", "["+style.Title.HighlightColor, 1) fmat = strings.Replace(fmat, "[key", "["+style.Menu.NumKeyColor, 1) fmat = strings.Replace(fmat, "[filter", "["+style.Title.FilterColor, 1) fmat = strings.Replace(fmat, "[count", "["+style.Title.CounterColor, 1) - fmat = strings.Replace(fmat, ":bg:", ":"+style.Title.BgColor+":", -1) + fmat = strings.Replace(fmat, ":bg:", ":"+bgColor+":", -1) return fmat } diff --git a/internal/view/app.go b/internal/view/app.go index aded6e6f..bfff02c9 100644 --- a/internal/view/app.go +++ b/internal/view/app.go @@ -267,11 +267,11 @@ func (a *App) switchCtx(name string, loadPods bool) error { log.Error().Err(err).Msg("Config save failed!") } a.Flash().Infof("Switching context to %s", name) + a.ReloadStyles(name) if err := a.gotoResource("pods", true); loadPods && err != nil { a.Flash().Err(err) } a.clusterModel.Reset(a.factory) - a.ReloadStyles(name) } return nil diff --git a/internal/view/cluster_info.go b/internal/view/cluster_info.go index c69a94a2..dc87cfa5 100644 --- a/internal/view/cluster_info.go +++ b/internal/view/cluster_info.go @@ -32,6 +32,7 @@ func NewClusterInfo(app *App) *ClusterInfo { func (c *ClusterInfo) Init() { c.app.Styles.AddListener(c) c.layout() + c.StylesChanged(c.app.Styles) } // StylesChanged notifies skin changed. @@ -51,9 +52,14 @@ func (c *ClusterInfo) layout() { func (c *ClusterInfo) sectionCell(t string) *tview.TableCell { cell := tview.NewTableCell(t + ":") cell.SetAlign(tview.AlignLeft) - var s tcell.Style - cell.SetStyle(s.Bold(true).Foreground(config.AsColor(c.styles.K9s.Info.SectionColor))) - cell.SetBackgroundColor(c.app.Styles.BgColor()) + // var style tcell.Style + // style.Bold(true). + // Background(tcell.ColorGreen). + // Foreground(config.AsColor(c.styles.K9s.Info.SectionColor)) + // cell.SetStyle(style) + // cell.SetBackgroundColor(c.app.Styles.BgColor()) + // cell.SetBackgroundColor(tcell.ColorDefault) + cell.SetBackgroundColor(tcell.ColorGreen) return cell } diff --git a/skins/black_and_wtf.yml b/skins/black_and_wtf.yml index a31da501..73fe07d8 100644 --- a/skins/black_and_wtf.yml +++ b/skins/black_and_wtf.yml @@ -1,56 +1,70 @@ +# Styles... +fg: &fg "white" +bg: &bg "black" +mark: &mark "darkgoldenrod" +active: &active "dimgray" +text: &text "navajowhite" +white: &white "whitesmoke" +ghost: &ghost "ghostwhite" +dslate: &dslate "darkslategray" +err: &err "pink" +slate: &slate "slategray" +gray: &gray "gray" + +# Skin k9s: body: - fgColor: white - bgColor: black - logoColor: white + fgColor: *fg + bgColor: *bg + logoColor: *fg info: - fgColor: navajowhite - sectionColor: white + fgColor: *text + sectionColor: *fg frame: border: - fgColor: white - focusColor: white + fgColor: *fg + focusColor: *fg menu: - fgColor: white - keyColor: white - numKeyColor: navajowhite + fgColor: *fg + keyColor: *fg + numKeyColor: *text crumbs: - fgColor: black - bgColor: navajowhite - activeColor: whitesmoke + fgColor: *fg + bgColor: *bg + activeColor: *active status: - newColor: ghostwhite - modifyColor: navajowhite - addColor: darkslategray - errorColor: whitesmoke - highlightcolor: dimgray - killColor: slategray - completedColor: gray + newColor: *white + modifyColor: *text + addColor: *ghost + errorColor: *err + highlightcolor: *dslate + killColor: *slate + completedColor: *gray title: - fgColor: ghostwhite - highlightColor: navajowhite - counterColor: navajowhite - filterColor: slategray + fgColor: *fg + highlightColor: *active + counterColor: *text + filterColor: *slate table: - fgColor: white - bgColor: black - cursorColor: white - markColor: darkgoldenrod + fgColor: *fg + bgColor: *bg + cursorColor: *fg + markColor: *mark header: - fgColor: darkgray - bgColor: black - sorterColor: white + fgColor: *dslate + bgColor: *bg + sorterColor: *fg xray: - fgColor: white - bgColor: black - cursorColor: whitesmoke + fgColor: *fg + bgColor: *bg + cursorColor: *ghost graphicColor: gray showIcons: false views: yaml: - keyColor: ghostwhite - colorColor: slategray - valueColor: navajowhite + keyColor: *ghost + colorColor: *slate + valueColor: *text logs: - fgColor: ghostwhite - bgColor: black + fgColor: *ghost + bgColor: *bg diff --git a/skins/dracula.yml b/skins/dracula.yml index 8905eb6b..801b2250 100644 --- a/skins/dracula.yml +++ b/skins/dracula.yml @@ -1,3 +1,4 @@ +# Styles... foreground: &foreground "#f8f8f2" background: &background "#282a36" current_line: ¤t_line "#44475a" @@ -10,6 +11,8 @@ pink: &pink "#ff79c6" purple: &purple "#bd93f9" red: &red "#ff5555" yellow: &yellow "#f1fa8c" + +# Skin... k9s: # General K9s styles body: diff --git a/skins/in_the_navy.yml b/skins/in_the_navy.yml index 382a3f95..3a85f1bb 100644 --- a/skins/in_the_navy.yml +++ b/skins/in_the_navy.yml @@ -1,58 +1,78 @@ +# Styles... + +fg: &fg "dodgerblue" +bg: &bg "white" +blue: &blue "blue" +sky: &sky "lightskyblue" +steel: &steel "steelblue" +dark: &dark "darkblue" +alice: &alice "aliceblue" +corn: &corn "cornflowerblue" +err: &err "indianred" +royal: &royal "royalblue" +slate: &slate "slategray" +gray: &gray "gray" +cadet: &cadet "cadetblue" +powder: &powder "powderblue" +aqua: &aqua "aqua" +mslate: &mslate "mediumslateblue" + +# Skin... k9s: body: - fgColor: dodgerblue - bgColor: white - logoColor: blue + fgColor: *fg + bgColor: *bg + logoColor: *blue info: - fgColor: lightskyblue - sectionColor: steelblue + fgColor: *sky + sectionColor: *steel frame: border: - fgColor: dodgerblue - bgColor: darkblue - focusColor: aliceblue + fgColor: *fg + bgColor: *dark + focusColor: *alice menu: - fgColor: darkblue - keyColor: cornflowerblue - numKeyColor: cadetblue + fgColor: *dark + keyColor: *corn + numKeyColor: *cadet crumbs: - fgColor: white - bgColor: steelblue - activeColor: skyblue + fgColor: *bg + bgColor: *steel + activeColor: *sky status: - newColor: blue - modifyColor: powderblue - addColor: lightskyblue - errorColor: indianred - highlightcolor: royalblue - killColor: slategray - completedColor: gray + newColor: *blue + modifyColor: *powder + addColor: *sky + errorColor: *err + highlightcolor: *royal + killColor: *slate + completedColor: *gray title: - fgColor: aqua - bgColor: darkblue - highlightColor: skyblue - counterColor: slateblue - filterColor: slategray + fgColor: *cadet + bgColor: *bg + highlightColor: *sky + counterColor: *slate + filterColor: *slate table: - fgColor: blue - bgColor: darkblue - cursorColor: aqua - markColor: mediumslateblue + fgColor: *fg + bgColor: *bg + cursorColor: *aqua + markColor: *mslate header: - fgColor: white - bgColor: darkblue - sorterColor: orange + fgColor: *fg + bgColor: *bg + sorterColor: *cadet xray: - fgColor: blue - bgColor: darkblue - cursorColor: aqua - graphicColor: mediumslateblue + fgColor: *blue + bgColor: *dark + cursorColor: *aqua + graphicColor: *mslate showIcons: false views: yaml: - keyColor: steelblue - colorColor: blue - valueColor: royalblue + keyColor: *steel + colorColor: *blue + valueColor: *royal logs: - fgColor: white - bgColor: darkblue + fgColor: *dark + bgColor: *bg From a491f7c77ef622c0fe4f39488f426013ea6a1f8f Mon Sep 17 00:00:00 2001 From: derailed Date: Wed, 12 Feb 2020 08:33:56 -0700 Subject: [PATCH 25/58] fix race conditions --- internal/dao/table.go | 1 - internal/model/table.go | 8 ++------ internal/render/row.go | 5 ++--- internal/render/table_data.go | 10 +++++----- internal/ui/flash.go | 3 +-- internal/ui/logo.go | 5 +---- internal/view/app.go | 21 ++++++++++++--------- internal/view/xray.go | 2 ++ internal/watch/factory.go | 4 ++++ 9 files changed, 29 insertions(+), 30 deletions(-) diff --git a/internal/dao/table.go b/internal/dao/table.go index 3abdf94e..944a1ef9 100644 --- a/internal/dao/table.go +++ b/internal/dao/table.go @@ -46,7 +46,6 @@ func (t *Table) Get(ctx context.Context, path string) (runtime.Object, error) { // List all Resources in a given namespace. func (t *Table) List(ctx context.Context, ns string) ([]runtime.Object, error) { - log.Debug().Msgf("TABLE-LIST %q:%q", ns, t.gvr) a := fmt.Sprintf(gvFmt, metav1beta1.SchemeGroupVersion.Version, metav1beta1.GroupName) _, codec := t.codec() diff --git a/internal/model/table.go b/internal/model/table.go index 2fbb6376..e54decbf 100644 --- a/internal/model/table.go +++ b/internal/model/table.go @@ -2,7 +2,6 @@ package model import ( "context" - "errors" "fmt" "sync" "sync/atomic" @@ -186,7 +185,6 @@ func (t *Table) updater(ctx context.Context) { for { select { case <-ctx.Done(): - t.fireTableLoadFailed(errors.New("operation canceled")) return case <-time.After(rate): rate = t.refreshRate @@ -207,7 +205,7 @@ func (t *Table) refresh(ctx context.Context) { t.fireTableLoadFailed(err) return } - t.fireTableChanged() + t.fireTableChanged(t.Peek()) } func (t *Table) list(ctx context.Context, a dao.Accessor) ([]runtime.Object, error) { @@ -261,7 +259,6 @@ func (t *Table) reconcile(ctx context.Context) error { t.mx.Lock() defer t.mx.Unlock() - // if labelSelector in place might as well clear the model data. sel, ok := ctx.Value(internal.KeyLabels).(string) if ok && sel != "" { @@ -300,8 +297,7 @@ func (t *Table) resourceMeta() ResourceMeta { return meta } -func (t *Table) fireTableChanged() { - data := t.Peek() +func (t *Table) fireTableChanged(data render.TableData) { for _, l := range t.listeners { l.TableDataChanged(data) } diff --git a/internal/render/row.go b/internal/render/row.go index f3e4171e..4076b866 100644 --- a/internal/render/row.go +++ b/internal/render/row.go @@ -13,9 +13,8 @@ type Fields []string // Clone returns a copy of the fields. func (f Fields) Clone() Fields { cp := make(Fields, len(f)) - for i, v := range f { - cp[i] = v - } + copy(cp, f) + return cp } diff --git a/internal/render/table_data.go b/internal/render/table_data.go index d907277a..4a133a53 100644 --- a/internal/render/table_data.go +++ b/internal/render/table_data.go @@ -19,11 +19,11 @@ func (t *TableData) Clear() { // Clone returns a copy of the table func (t *TableData) Clone() TableData { - return cloneTable(*t) -} - -func cloneTable(t TableData) TableData { - return t + return TableData{ + Header: t.Header.Clone(), + RowEvents: t.RowEvents.Clone(), + Namespace: t.Namespace, + } } // SetHeader sets table header. diff --git a/internal/ui/flash.go b/internal/ui/flash.go index 855bba3c..956cb893 100644 --- a/internal/ui/flash.go +++ b/internal/ui/flash.go @@ -134,8 +134,7 @@ func (f *Flash) SetMessage(level FlashLevel, msg ...string) { } var ctx context.Context - ctx, f.cancel = context.WithCancel(context.TODO()) - ctx, f.cancel = context.WithTimeout(ctx, flashDelay) + ctx, f.cancel = context.WithTimeout(context.Background(), flashDelay) go f.refresh(ctx) } diff --git a/internal/ui/logo.go b/internal/ui/logo.go index 0935de22..e5f2ec9c 100644 --- a/internal/ui/logo.go +++ b/internal/ui/logo.go @@ -3,8 +3,6 @@ package ui import ( "fmt" - "github.com/gdamore/tcell" - "github.com/derailed/k9s/internal/config" "github.com/derailed/tview" ) @@ -29,6 +27,7 @@ func NewLogo(styles *config.Styles) *Logo { l.AddItem(l.logo, 0, 6, false) l.AddItem(l.status, 0, 1, false) l.refreshLogo(styles.Body().LogoColor) + l.SetBackgroundColor(styles.BgColor()) styles.AddListener(&l) return &l @@ -96,7 +95,6 @@ func (l *Logo) refreshLogo(c string) { func logo() *tview.TextView { v := tview.NewTextView() - v.SetBackgroundColor(tcell.ColorDefault) v.SetWordWrap(false) v.SetWrap(false) v.SetTextAlign(tview.AlignLeft) @@ -107,7 +105,6 @@ func logo() *tview.TextView { func status() *tview.TextView { v := tview.NewTextView() - v.SetBackgroundColor(tcell.ColorDefault) v.SetWordWrap(false) v.SetWrap(false) v.SetTextAlign(tview.AlignCenter) diff --git a/internal/view/app.go b/internal/view/app.go index bfff02c9..96c96e0b 100644 --- a/internal/view/app.go +++ b/internal/view/app.go @@ -169,6 +169,7 @@ func (a *App) buildHeader() tview.Primitive { func (a *App) Halt() { if a.cancelFn != nil { a.cancelFn() + a.cancelFn = nil } } @@ -311,19 +312,21 @@ func (a *App) Run() error { // Status reports a new app status for display. func (a *App) Status(l ui.FlashLevel, msg string) { - a.Flash().SetMessage(l, msg) - a.setIndicator(l, msg) - a.setLogo(l, msg) - a.Draw() + a.QueueUpdateDraw(func() { + a.Flash().SetMessage(l, msg) + a.setIndicator(l, msg) + a.setLogo(l, msg) + }) } // ClearStatus reset logo back to normal. func (a *App) ClearStatus(flash bool) { - a.Logo().Reset() - if flash { - a.Flash().Clear() - } - a.Draw() + a.QueueUpdateDraw(func() { + a.Logo().Reset() + if flash { + a.Flash().Clear() + } + }) } func (a *App) setLogo(l ui.FlashLevel, msg string) { diff --git a/internal/view/xray.go b/internal/view/xray.go index 8d0841e9..2858233a 100644 --- a/internal/view/xray.go +++ b/internal/view/xray.go @@ -160,6 +160,8 @@ func (x *Xray) refreshActions() { } switch gvr { + case "v1/namespaces": + x.Actions().Delete(tcell.KeyEnter) case "containers": x.Actions().Delete(tcell.KeyEnter) aa[ui.KeyS] = ui.NewKeyAction("Shell", x.shellCmd, true) diff --git a/internal/watch/factory.go b/internal/watch/factory.go index 8b1d9849..4a56f178 100644 --- a/internal/watch/factory.go +++ b/internal/watch/factory.go @@ -109,10 +109,14 @@ func (f *Factory) waitForCacheSync(ns string) { if f.isClusterWide() { ns = client.AllNamespaces } + + f.mx.RLock() + defer f.mx.RUnlock() fac, ok := f.factories[ns] if !ok { return } + // Hang for a sec for the cache to refresh if still not done bail out! c := make(chan struct{}) go func(c chan struct{}) { From 757479e281db4449f83ac50b702ddbad6c88e3ca Mon Sep 17 00:00:00 2001 From: derailed Date: Wed, 12 Feb 2020 09:07:20 -0700 Subject: [PATCH 26/58] add rel notes --- change_logs/release_v0.14.1.md | 41 ++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 change_logs/release_v0.14.1.md diff --git a/change_logs/release_v0.14.1.md b/change_logs/release_v0.14.1.md new file mode 100644 index 00000000..584de21f --- /dev/null +++ b/change_logs/release_v0.14.1.md @@ -0,0 +1,41 @@ + + +# Release v0.14.1 + +## Notes + +Thank you to all that contributed with flushing out issues and enhancements for K9s! I'll try to mark some of these issues as fixed. But if you don't mind grab the latest rev and see if we're happier with some of the fixes! If you've filed an issue please help me verify and close. Your support, kindness and awesome suggestions to make K9s better is as ever very much noticed and appreciated! + +Also if you dig this tool, please make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer) + +On Slack? Please join us [K9slackers](https://join.slack.com/t/k9sers/shared_invite/enQtOTA5MDEyNzI5MTU0LWQ1ZGI3MzliYzZhZWEyNzYxYzA3NjE0YTk1YmFmNzViZjIyNzhkZGI0MmJjYzhlNjdlMGJhYzE2ZGU1NjkyNTM) + +--- + +## Term Color Part Duh! + +Some folks had reported issues with skins and wanting to preserve their terminal background colors while in K9s. In this drop, we're introducing a new skin setting called `default` that should enable the skin to keep the original terminal background color. Here is a sample skin snippet that should achieve just that: + +```yaml +# .k9s/pale_rider.yml + +# Styles... +fg: &fg "#ff00ff" +bg: &bg "default" # default keeps your current terminal window background color. + +# Skin... +k9s: + body: + fgColor: *fg + bgColor: "default" +#... +``` + +## Resolved Bugs/Features/PRs + +* [Issue #539](https://github.com/derailed/k9s/issues/539) +* [Issue #538](https://github.com/derailed/k9s/issues/538) Fingers crossed! + +--- + + © 2020 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0) From e43260ed054af4512c95425bdf7b8cb526bc5583 Mon Sep 17 00:00:00 2001 From: derailed Date: Wed, 12 Feb 2020 09:32:32 -0700 Subject: [PATCH 27/58] cleaning up --- internal/config/styles.go | 4 ++-- internal/ui/config.go | 10 +++++----- internal/ui/config_test.go | 2 +- internal/ui/tree.go | 1 + internal/xray/tree_node.go | 2 ++ 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/internal/config/styles.go b/internal/config/styles.go index 854ad73b..97fe0dbd 100644 --- a/internal/config/styles.go +++ b/internal/config/styles.go @@ -292,8 +292,8 @@ func NewStyles() *Styles { } } -// LoadDefaults loads the default skin -func (s *Styles) DefaultSkins() { +// DefaultSkin loads the default skin +func (s *Styles) DefaultSkin() { s.K9s = newStyle() } diff --git a/internal/ui/config.go b/internal/ui/config.go index 96080c3d..71771745 100644 --- a/internal/ui/config.go +++ b/internal/ui/config.go @@ -26,14 +26,14 @@ type Configurator struct { Bench *config.Bench } -// HasSkins returns true if a skin file was located. -func (c *Configurator) HasSkins() bool { +// HasSkin returns true if a skin file was located. +func (c *Configurator) HasSkin() bool { return c.skinFile != "" } // StylesUpdater watches for skin file changes. func (c *Configurator) StylesUpdater(ctx context.Context, s synchronizer) error { - if !c.HasSkins() { + if !c.HasSkin() { return nil } @@ -103,8 +103,8 @@ func (c *Configurator) RefreshStyles(context string) { func (c *Configurator) updateStyles(f string) { c.skinFile = f - if !c.HasSkins() { - c.Styles.DefaultSkins() + if !c.HasSkin() { + c.Styles.DefaultSkin() } c.Styles.Update() diff --git a/internal/ui/config_test.go b/internal/ui/config_test.go index 0c409721..6436057e 100644 --- a/internal/ui/config_test.go +++ b/internal/ui/config_test.go @@ -22,7 +22,7 @@ func TestConfiguratorRefreshStyle(t *testing.T) { cfg := ui.Configurator{} cfg.RefreshStyles("") - assert.True(t, cfg.HasSkins()) + assert.True(t, cfg.HasSkin()) assert.Equal(t, tcell.ColorGhostWhite, render.StdColor) assert.Equal(t, tcell.ColorWhiteSmoke, render.ErrColor) } diff --git a/internal/ui/tree.go b/internal/ui/tree.go index 8179418c..1e0971b0 100644 --- a/internal/ui/tree.go +++ b/internal/ui/tree.go @@ -86,6 +86,7 @@ func (t *Tree) ExtraHints() map[string]string { return nil } +// BindKeys binds default mnemonics. func (t *Tree) BindKeys() { t.Actions().Add(KeyActions{ KeySpace: NewKeyAction("Expand/Collapse", t.noopCmd, true), diff --git a/internal/xray/tree_node.go b/internal/xray/tree_node.go index 8825e408..5d2d8577 100644 --- a/internal/xray/tree_node.go +++ b/internal/xray/tree_node.go @@ -55,6 +55,7 @@ type NodeSpec struct { GVRs, Paths, Statuses []string } +// ParentGVR returns the parent GVR. func (s NodeSpec) ParentGVR() *string { if len(s.GVRs) > 1 { return &s.GVRs[1] @@ -62,6 +63,7 @@ func (s NodeSpec) ParentGVR() *string { return nil } +// ParentPath returns the parent path. func (s NodeSpec) ParentPath() *string { if len(s.Paths) > 1 { return &s.Paths[1] From 7ad07b791d15e2224ad1dcbf096fc7c8d04f76b7 Mon Sep 17 00:00:00 2001 From: derailed Date: Wed, 12 Feb 2020 16:43:22 -0700 Subject: [PATCH 28/58] fix #542, #541 --- .gitignore | 5 +- README.md | 108 ++++++++++++++-------------- go.mod | 5 ++ go.sum | 14 ++++ internal/dao/container.go | 2 +- internal/dao/crd.go | 6 +- internal/dao/dp.go | 2 +- internal/dao/ds.go | 11 ++- internal/dao/generic.go | 2 +- internal/dao/job.go | 2 +- internal/dao/log_options.go | 21 ++++-- internal/dao/pod.go | 34 +++++---- internal/dao/sts.go | 2 +- internal/dao/svc.go | 2 +- internal/dao/table.go | 9 ++- internal/dao/types.go | 2 +- internal/model/cluster_info_test.go | 46 ++++++++++++ internal/model/log.go | 50 ++++++------- internal/model/log_test.go | 20 +++--- internal/render/job.go | 2 - internal/view/app.go | 3 +- internal/view/log.go | 6 +- 22 files changed, 217 insertions(+), 137 deletions(-) create mode 100644 internal/model/cluster_info_test.go diff --git a/.gitignore b/.gitignore index b8428f68..cd5193e4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ .vscode .idea -k9s.log .envrc cov.out execs @@ -10,10 +9,8 @@ dist notes vendor go.mod1 -popeye1.go gen.sh -cluster_info_test.go *.test *.log *~ -pod1.go \ No newline at end of file +faas diff --git a/README.md b/README.md index 114ff127..6a83473e 100644 --- a/README.md +++ b/README.md @@ -145,16 +145,16 @@ K9s uses aliases to navigate most K8s resources. --- -## K9s config file ($HOME/.k9s/config.yml) +## K9s Configuration - K9s keeps its configurations in a .k9s directory in your home directory. + K9s keeps its configurations in a .k9s directory in your home directory `$HOME/.k9s/config.yml`. > NOTE: This is still in flux and will change while in pre-release stage! ```yaml # config.yml k9s: - # Indicates api-server poll intervals. + # Represents ui poll intervals. refreshRate: 2 # Indicates whether modification commands like delete/kill/edit are disabled. Default is false readOnly: false @@ -189,9 +189,9 @@ K9s uses aliases to navigate most K8s resources. --- -## Aliases +## Command Aliases -In K9s, you can define your own command aliases (shortnames) to access your resources. In your `$HOME/.k9s` define a file called `alias.yml`. A K9s alias defines pairs of alias:gvr. A gvr represents a fully qualified Kubernetes resource identifier. Here is an example of an alias file: +In K9s, you can define your very own command aliases (shortnames) to access your resources. In your `$HOME/.k9s` define a file called `alias.yml`. A K9s alias defines pairs of alias:gvr. A gvr (Group/Version/Resource) represents a fully qualified Kubernetes resource identifier. Here is an example of an alias file: ```yaml # $HOME/.k9s/alias.yml @@ -204,9 +204,44 @@ Using this alias file, you can now type pp/crb to list pods or clusterrolebindin --- +## HotKey Support + +Entering the command mode and typing a resource name or alias, could be cumbersome for navigating thru often used resources. We're introducing hotkeys that allows a user to define their own hotkeys to activate their favorite resource views. In order to enable hotkeys please follow these steps: + +1. Create a file named `$HOME/.k9s/hotkey.yml` +2. Add the following to your `hotkey.yml`. You can use resource name/short name to specify a command ie same as typing it while in command mode. + + ```yaml + # $HOME/.k9s/hotkey.yml + hotKey: + # Hitting Shift-0 navigates to your pod view + shift-0: + shortCut: Shift-0 + description: Viewing pods + command: pods + # Hitting Shift-1 navigates to your deployments + shift-1: + shortCut: Shift-1 + description: View deployments + command: dp + # Hitting Shift-2 navigates to your xray deployments + shift-2: + shortCut: Shift-4 + description: Xray Deployments + command: xray deploy + ``` + + Not feeling so hot? Your custom hotkeys will be listed in the help view `?`. Also your hotkey file will be automatically reloaded so you can readily use your hotkeys as you define them. + + You can choose any keyboard shotcuts that make sense to you, provided they are not part of the standard K9s shortcuts list. + +> NOTE: This feature/configuration might change in future releases! + +--- + ## Plugins -K9s allows you to define your own cluster commands via plugins. K9s will look at `$HOME/.k9s/plugin.yml` to locate available plugins. A plugin is defined as follows: +K9s allows you to extend your command line and tooling by defining your very own cluster commands via plugins. K9s will look at `$HOME/.k9s/plugin.yml` to locate all available plugins. A plugin is defined as follows: ```yaml # $HOME/.k9s/plugin.yml @@ -217,7 +252,7 @@ plugin: description: Pod logs scopes: - po - command: /usr/local/bin/kubectl + command: kubectl background: false args: - logs @@ -237,6 +272,8 @@ K9s does provide additional environment variables for you to customize your plug * `$NAMESPACE` -- the selected resource namespace * `$NAME` -- the selected resource name +* `$CONTAINER` -- the current container if applicable +* `$FILTER` -- the current filter if any * `$KUBECONFIG` -- the KubeConfig location. * `$CLUSTER` the active cluster name * `$CONTEXT` the active context name @@ -244,13 +281,13 @@ K9s does provide additional environment variables for you to customize your plug * `$GROUPS` the active groups * `$COLX` the column at index X for the viewed resource -NOTE: This is an experimental feature! Options and layout may change in future K9s releases as this feature solidifies. +> NOTE: This is an experimental feature! Options and layout may change in future K9s releases as this feature solidifies. --- -## Benchmarking +## Benchmark Your Applications -K9s integrates [Hey](https://github.com/rakyll/hey) from the brilliant and super talented [Jaana Dogan](https://github.com/rakyll) of Google fame. Hey is a CLI tool to benchmark HTTP endpoints similar to AB bench. This preliminary feature currently supports benchmarking port-forwards and services (Read the paint on this is way fresh!). +K9s integrates [Hey](https://github.com/rakyll/hey) from the brilliant and super talented [Jaana Dogan](https://github.com/rakyll). `Hey` is a CLI tool to benchmark HTTP endpoints similar to AB bench. This preliminary feature currently supports benchmarking port-forwards and services (Read the paint on this is way fresh!). To setup a port-forward, you will need to navigate to the PodView, select a pod and a container that exposes a given port. Using `SHIFT-F` a dialog comes up to allow you to specify a local port to forward. Once acknowledged, you can navigate to the PortForward view (alias `pf`) listing out your active port-forwards. Selecting a port-forward and using `CTRL-B` will run a benchmark on that HTTP endpoint. To view the results of your benchmark runs, go to the Benchmarks view (alias `be`). You should now be able to select a benchmark and view the run stats details by pressing ``. NOTE: Port-forwards only last for the duration of the K9s session and will be terminated upon exit. @@ -272,11 +309,11 @@ benchmarks: defaults: # One concurrent connection concurrency: 1 - # 500 requests will be sent to an endpoint + # Number of requests that will be sent to an endpoint requests: 500 containers: # Containers section allows you to configure your http container's endpoints and benchmarking settings. - # NOTE: the container ID syntax uses namespace/pod_name:container_name + # NOTE: the container ID syntax uses namespace/pod-name:container-name default/nginx:nginx: # Benchmark a container named nginx using POST HTTP verb using http://localhost:port/bozo URL and headers. concurrency: 1 @@ -295,15 +332,15 @@ benchmarks: # Similary you can Benchmark an HTTP service exposed either via nodeport, loadbalancer types. # Service ID is ns/svc-name default/nginx: - # Hit the service with 5 concurrent sessions + # Set the concurrency level concurrency: 5 - # Issues a total of 500 requests + # Number of requests to be sent requests: 500 http: method: GET # This setting will depend on whether service is nodeport or loadbalancer. Nodeport may require vendor port tuneling setting. # Set this to a node if nodeport or LB if applicable. IP or dns name. - host: 10.11.13.14 + host: A.B.C.D path: /bumblebeetuna auth: user: jean-baptiste-emmanuel @@ -312,41 +349,6 @@ benchmarks: --- -## HotKeys - -Entering the command mode and typing a resource name or alias, could be cumbersome for navigating thru often used resources. We're introducing hotkeys that allows a user to define their own hotkeys to activate their favorite resource views. In order to enable hotkeys please follow these steps: - -1. In your .k9s home directory create a file named `hotkey.yml` -2. Add the following to your `hotkey.yml`. You can use short names or resource name to specify a command ie same as typing it in command mode. - - ```yaml - hotKey: - shift-0: - shortCut: Shift-0 - description: View pods - command: pods - shift-1: - shortCut: Shift-1 - description: View deployments - command: dp - shift-2: - shortCut: Shift-2 - description: View services - command: service - shift-3: - shortCut: Shift-3 - description: View statefulsets - command: sts - ``` - - Not feeling so hot? Your custom hotkeys list will be listed in the help view.``. Also your hotkey file will be automatically reloaded so you can readily use your hotkeys as you define them. - - You can choose any keyboard shotcuts that make sense to you, provided they are not part of the standard K9s shortcuts list. - -NOTE: This feature/configuration might change in future releases! - ---- - ## K9s RBAC FU On RBAC enabled clusters, you would need to give your users/groups capabilities so that they can use K9s to explore their Kubernetes cluster. K9s needs minimally read privileges at both the cluster and namespace level to display resources and metrics. @@ -459,7 +461,7 @@ Colors can be defined by name or uing an hex representation. Of recent, we've ad > NOTE: This is very much an experimental feature at this time, more will be added/modified if this feature has legs so thread accordingly! ```yaml -# InTheNavy Skin... +# Skin InTheNavy... k9s: # General K9s styles body: @@ -589,8 +591,8 @@ to make this project a reality! ## Meet The Core Team! * [Fernand Galiana](https://github.com/derailed) - * fernand@imhotep.io - * [@kitesurfer](https://twitter.com/kitesurfer?lang=en) + * fernand@imhotep.io + * [@kitesurfer](https://twitter.com/kitesurfer?lang=en) --- diff --git a/go.mod b/go.mod index a42b7e03..f440f8d9 100644 --- a/go.mod +++ b/go.mod @@ -32,6 +32,7 @@ require ( github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/atotto/clipboard v0.1.2 github.com/derailed/tview v0.3.4 + github.com/drone/envsubst v1.0.2 // indirect github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f // indirect github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f // indirect github.com/fatih/color v1.6.0 @@ -41,9 +42,13 @@ require ( github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/mattn/go-runewidth v0.0.5 + github.com/openfaas/faas v0.0.0-20200207215241-6afae214e3ec // indirect + github.com/openfaas/faas-cli v0.0.0-20200124160744-30b7cec9634c + github.com/openfaas/faas-provider v0.15.0 // indirect github.com/petergtz/pegomock v2.6.0+incompatible github.com/rakyll/hey v0.1.2 github.com/rs/zerolog v1.17.2 + github.com/ryanuber/go-glob v1.0.0 // indirect github.com/sahilm/fuzzy v0.1.0 github.com/spf13/cobra v0.0.5 github.com/stretchr/testify v1.4.0 diff --git a/go.sum b/go.sum index 847d5a31..38a835e0 100644 --- a/go.sum +++ b/go.sum @@ -177,6 +177,8 @@ github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZ github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c h1:ZfSZ3P3BedhKGUhzj7BQlPSU4OvT6tfOKe3DVHzOA7s= github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/drone/envsubst v1.0.2 h1:dpYLMAspQHW0a8dZpLRKe9jCNvIGZPhCPrycZzIHdqo= +github.com/drone/envsubst v1.0.2/go.mod h1:bkZbnc/2vh1M12Ecn7EYScpI4YGYU0etwLJICOWi8Z0= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f h1:8GDPb0tCY8LQ+OJ3dbHb5sA6YZWXFORQYZx5sdsTlMs= @@ -339,9 +341,11 @@ github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1a github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZsA= github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U= github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= @@ -450,6 +454,7 @@ github.com/mindprince/gonvml v0.0.0-20171110221305-fee913ce8fb2/go.mod h1:2eu9pR github.com/mistifyio/go-zfs v2.1.1+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= @@ -497,6 +502,12 @@ github.com/opencontainers/runc v1.0.0-rc2.0.20190611121236-6cc515888830 h1:yvQ/2 github.com/opencontainers/runc v1.0.0-rc2.0.20190611121236-6cc515888830/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runtime-spec v1.0.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.2.2/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs= +github.com/openfaas/faas v0.0.0-20200207215241-6afae214e3ec h1:S6wtb5ie7KeMcuEaESj0RoSmpyGfvOSuunmKEdX7wg8= +github.com/openfaas/faas v0.0.0-20200207215241-6afae214e3ec/go.mod h1:E0m2rLup0Vvxg53BKxGgaYAGcZa3Xl+vvL7vSi5yQ14= +github.com/openfaas/faas-cli v0.0.0-20200124160744-30b7cec9634c h1:9RGaDpUySgRscx5oiagwUtm9vBZti/4+QYq2GM4FegE= +github.com/openfaas/faas-cli v0.0.0-20200124160744-30b7cec9634c/go.mod h1:u/KO+e43wkagC0lqM1eaqNEWEBdg08Q1ugP/idj39MM= +github.com/openfaas/faas-provider v0.15.0 h1:3x5ma90FL7AqP4NOD6f03AY24y3xBeVF6xGLUx6Xrlc= +github.com/openfaas/faas-provider v0.15.0/go.mod h1:8Fagi2UeMfL+gZAqZWSMQg86i+w1+hBOKtwKRP5sLFI= github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= @@ -557,6 +568,8 @@ github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvf github.com/russross/blackfriday v0.0.0-20170610170232-067529f716f4/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI= github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= @@ -631,6 +644,7 @@ github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxt go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569 h1:nSQar3Y0E3VQF/VdZ8PTAilaXpER+d7ypdABCrpwMdg= go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/goleak v0.10.0/go.mod h1:VCZuO8V8mFPlL0F5J5GK1rtHV3DrFcQ1R8ryq7FK0aI= go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df h1:shvkWr0NAZkg4nPuE3XrKP0VuBPijjk3TfX6Y6acFNg= go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15 h1:Z2sc4+v0JHV6Mn4kX1f2a5nruNjmV+Th32sugE8zwz8= diff --git a/internal/dao/container.go b/internal/dao/container.go index 60a8ac3c..a655f505 100644 --- a/internal/dao/container.go +++ b/internal/dao/container.go @@ -62,7 +62,7 @@ func (c *Container) List(ctx context.Context, _ string) ([]runtime.Object, error } // TailLogs tails a given container logs -func (c *Container) TailLogs(ctx context.Context, logChan chan<- string, opts LogOptions) error { +func (c *Container) TailLogs(ctx context.Context, logChan chan<- []byte, opts LogOptions) error { fac, ok := ctx.Value(internal.KeyFactory).(Factory) if !ok { return errors.New("Expecting an informer") diff --git a/internal/dao/crd.go b/internal/dao/crd.go index 18ff56f6..c329560f 100644 --- a/internal/dao/crd.go +++ b/internal/dao/crd.go @@ -21,11 +21,11 @@ type CustomResourceDefinition struct { // List returns a collection of nodes. func (c *CustomResourceDefinition) List(ctx context.Context, _ string) ([]runtime.Object, error) { strLabel, ok := ctx.Value(internal.KeyLabels).(string) - lsel := labels.Everything() + labelSel := labels.Everything() if sel, e := labels.ConvertSelectorToLabelsMap(strLabel); ok && e == nil { - lsel = sel.AsSelector() + labelSel = sel.AsSelector() } const gvr = "apiextensions.k8s.io/v1beta1/customresourcedefinitions" - return c.Factory.List(gvr, "-", true, lsel) + return c.Factory.List(gvr, "-", true, labelSel) } diff --git a/internal/dao/dp.go b/internal/dao/dp.go index 43ab784a..e61b07f6 100644 --- a/internal/dao/dp.go +++ b/internal/dao/dp.go @@ -79,7 +79,7 @@ func (d *Deployment) Restart(path string) error { } // TailLogs tail logs for all pods represented by this Deployment. -func (d *Deployment) TailLogs(ctx context.Context, c chan<- string, opts LogOptions) error { +func (d *Deployment) TailLogs(ctx context.Context, c chan<- []byte, opts LogOptions) error { o, err := d.Factory.Get(d.gvr.String(), opts.Path, true, labels.Everything()) if err != nil { return err diff --git a/internal/dao/ds.go b/internal/dao/ds.go index c957766b..d42b159e 100644 --- a/internal/dao/ds.go +++ b/internal/dao/ds.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "strings" + "time" "github.com/derailed/k9s/internal" "github.com/derailed/k9s/internal/client" @@ -61,7 +62,7 @@ func (d *DaemonSet) Restart(path string) error { } // TailLogs tail logs for all pods represented by this DaemonSet. -func (d *DaemonSet) TailLogs(ctx context.Context, c chan<- string, opts LogOptions) error { +func (d *DaemonSet) TailLogs(ctx context.Context, c chan<- []byte, opts LogOptions) error { o, err := d.Factory.Get(d.gvr.String(), opts.Path, true, labels.Everything()) if err != nil { return err @@ -79,7 +80,11 @@ func (d *DaemonSet) TailLogs(ctx context.Context, c chan<- string, opts LogOptio return podLogs(ctx, c, ds.Spec.Selector.MatchLabels, opts) } -func podLogs(ctx context.Context, c chan<- string, sel map[string]string, opts LogOptions) error { +func podLogs(ctx context.Context, c chan<- []byte, sel map[string]string, opts LogOptions) error { + defer func(t time.Time) { + log.Debug().Msgf("POD LOGS %v", time.Since(t)) + }(time.Now()) + f, ok := ctx.Value(internal.KeyFactory).(*watch.Factory) if !ok { return errors.New("expecting a context factory") @@ -94,7 +99,7 @@ func podLogs(ctx context.Context, c chan<- string, sel map[string]string, opts L } ns, _ := client.Namespaced(opts.Path) - oo, err := f.List("v1/pods", ns, true, lsel) + oo, err := f.List("v1/pods", ns, false, lsel) if err != nil { return err } diff --git a/internal/dao/generic.go b/internal/dao/generic.go index 4d60762d..7963019e 100644 --- a/internal/dao/generic.go +++ b/internal/dao/generic.go @@ -28,7 +28,7 @@ type Generic struct { func (g *Generic) List(ctx context.Context, ns string) ([]runtime.Object, error) { labelSel, ok := ctx.Value(internal.KeyLabels).(string) if !ok { - log.Warn().Msgf("No label selector found in context. Listing all resources") + log.Debug().Msgf("No label selector found in context. Listing all resources") } if client.IsAllNamespace(ns) { ns = client.AllNamespaces diff --git a/internal/dao/job.go b/internal/dao/job.go index ff96a6d4..5f002804 100644 --- a/internal/dao/job.go +++ b/internal/dao/job.go @@ -23,7 +23,7 @@ type Job struct { } // TailLogs tail logs for all pods represented by this Job. -func (j *Job) TailLogs(ctx context.Context, c chan<- string, opts LogOptions) error { +func (j *Job) TailLogs(ctx context.Context, c chan<- []byte, opts LogOptions) error { o, err := j.Factory.Get(j.gvr.String(), opts.Path, true, labels.Everything()) if err != nil { return err diff --git a/internal/dao/log_options.go b/internal/dao/log_options.go index ce31c575..67e5e38c 100644 --- a/internal/dao/log_options.go +++ b/internal/dao/log_options.go @@ -47,19 +47,26 @@ func colorize(c color.Paint, txt string) string { } // DecorateLog add a log header to display po/co information along with the log message. -func (o LogOptions) DecorateLog(msg string) string { - _, n := client.Namespaced(o.Path) - if msg == "" { - return msg +func (o LogOptions) DecorateLog(bytes []byte) []byte { + if len(bytes) == 0 { + return bytes } + bytes = bytes[:len(bytes)-1] + _, n := client.Namespaced(o.Path) + + var prefix []byte if o.MultiPods { - return colorize(o.Color, n+":"+o.Container+" ") + msg + prefix = []byte(colorize(o.Color, n+":"+o.Container+" ")) } if !o.SingleContainer { - return colorize(o.Color, o.Container+" ") + msg + prefix = []byte(colorize(o.Color, o.Container+" ")) } - return msg + if len(prefix) == 0 { + return bytes + } + + return append(prefix, bytes...) } diff --git a/internal/dao/pod.go b/internal/dao/pod.go index 1258af29..faf39cb5 100644 --- a/internal/dao/pod.go +++ b/internal/dao/pod.go @@ -148,14 +148,14 @@ func (p *Pod) Containers(path string, includeInit bool) ([]string, error) { } // TailLogs tails a given container logs -func (p *Pod) TailLogs(ctx context.Context, c chan<- string, opts LogOptions) error { +func (p *Pod) TailLogs(ctx context.Context, c chan<- []byte, opts LogOptions) error { if !opts.HasContainer() { return p.logs(ctx, c, opts) } return tailLogs(ctx, p, c, opts) } -func (p *Pod) logs(ctx context.Context, c chan<- string, opts LogOptions) error { +func (p *Pod) logs(ctx context.Context, c chan<- []byte, opts LogOptions) error { fac, ok := ctx.Value(internal.KeyFactory).(*watch.Factory) if !ok { return errors.New("Expecting an informer") @@ -194,7 +194,7 @@ func (p *Pod) logs(ctx context.Context, c chan<- string, opts LogOptions) error return nil } -func tailLogs(ctx context.Context, logger Logger, c chan<- string, opts LogOptions) error { +func tailLogs(ctx context.Context, logger Logger, c chan<- []byte, opts LogOptions) error { log.Debug().Msgf("Tailing logs for %q -- %q", opts.Path, opts.Container) o := v1.PodLogOptions{ Container: opts.Container, @@ -206,11 +206,13 @@ func tailLogs(ctx context.Context, logger Logger, c chan<- string, opts LogOptio if err != nil { return err } - ctxt, cancelFunc := context.WithCancel(ctx) - req.Context(ctxt) + + var cancel context.CancelFunc + ctx, cancel = context.WithCancel(ctx) + req.Context(ctx) var blocked int32 = 1 - go logsTimeout(cancelFunc, &blocked) + go logsTimeout(cancel, &blocked) // This call will block if nothing is in the stream!! stream, err := req.Stream() @@ -219,7 +221,7 @@ func tailLogs(ctx context.Context, logger Logger, c chan<- string, opts LogOptio log.Error().Err(err).Msgf("Log stream failed for `%s", opts.Path) return fmt.Errorf("Unable to obtain log stream for %s", opts.Path) } - go readLogs(ctx, stream, c, opts) + go readLogs(stream, c, opts) return nil } @@ -232,7 +234,7 @@ func logsTimeout(cancel context.CancelFunc, blocked *int32) { } } -func readLogs(ctx context.Context, stream io.ReadCloser, c chan<- string, opts LogOptions) { +func readLogs(stream io.ReadCloser, c chan<- []byte, opts LogOptions) { defer func() { log.Debug().Msgf(">>> Closing stream `%s", opts.Path) if err := stream.Close(); err != nil { @@ -240,16 +242,18 @@ func readLogs(ctx context.Context, stream io.ReadCloser, c chan<- string, opts L } }() - scanner := bufio.NewScanner(stream) - for scanner.Scan() { - select { - case <-ctx.Done(): + r := bufio.NewReader(stream) + for { + bytes, err := r.ReadBytes('\n') + if err != nil { + log.Warn().Err(err).Msg("Read error") + if err != io.EOF { + log.Error().Err(err).Msgf("stream reader failed") + } return - default: - c <- opts.DecorateLog(scanner.Text()) } + c <- opts.DecorateLog(bytes) } - log.Error().Msgf("SCAN_ERR %#v", scanner.Err()) } // ---------------------------------------------------------------------------- diff --git a/internal/dao/sts.go b/internal/dao/sts.go index 3fe02c52..0946ff24 100644 --- a/internal/dao/sts.go +++ b/internal/dao/sts.go @@ -80,7 +80,7 @@ func (s *StatefulSet) Restart(path string) error { } // TailLogs tail logs for all pods represented by this StatefulSet. -func (s *StatefulSet) TailLogs(ctx context.Context, c chan<- string, opts LogOptions) error { +func (s *StatefulSet) TailLogs(ctx context.Context, c chan<- []byte, opts LogOptions) error { o, err := s.Factory.Get(s.gvr.String(), opts.Path, true, labels.Everything()) if err != nil { return err diff --git a/internal/dao/svc.go b/internal/dao/svc.go index 25b82e0f..9fbc3787 100644 --- a/internal/dao/svc.go +++ b/internal/dao/svc.go @@ -22,7 +22,7 @@ type Service struct { } // TailLogs tail logs for all pods represented by this Service. -func (s *Service) TailLogs(ctx context.Context, c chan<- string, opts LogOptions) error { +func (s *Service) TailLogs(ctx context.Context, c chan<- []byte, opts LogOptions) error { o, err := s.Factory.Get(s.gvr.String(), opts.Path, true, labels.Everything()) if err != nil { return err diff --git a/internal/dao/table.go b/internal/dao/table.go index 944a1ef9..290f2201 100644 --- a/internal/dao/table.go +++ b/internal/dao/table.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/derailed/k9s/internal" "github.com/derailed/k9s/internal/client" "github.com/rs/zerolog/log" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -22,7 +23,6 @@ type Table struct { func (t *Table) Get(ctx context.Context, path string) (runtime.Object, error) { ns, n := client.Namespaced(path) - log.Debug().Msgf("TABLE-GET %q:%q", ns, t.gvr) a := fmt.Sprintf(gvFmt, metav1beta1.SchemeGroupVersion.Version, metav1beta1.GroupName) _, codec := t.codec() @@ -46,6 +46,11 @@ func (t *Table) Get(ctx context.Context, path string) (runtime.Object, error) { // List all Resources in a given namespace. func (t *Table) List(ctx context.Context, ns string) ([]runtime.Object, error) { + labelSel, ok := ctx.Value(internal.KeyLabels).(string) + if !ok { + log.Debug().Msgf("No label selector found in context. Listing all resources") + } + a := fmt.Sprintf(gvFmt, metav1beta1.SchemeGroupVersion.Version, metav1beta1.GroupName) _, codec := t.codec() @@ -57,7 +62,7 @@ func (t *Table) List(ctx context.Context, ns string) ([]runtime.Object, error) { SetHeader("Accept", a). Namespace(ns). Resource(t.gvr.R()). - VersionedParams(&metav1beta1.TableOptions{}, codec). + VersionedParams(&metav1.ListOptions{LabelSelector: labelSel}, codec). Do().Get() if err != nil { return nil, err diff --git a/internal/dao/types.go b/internal/dao/types.go index c57ccb70..b93d7f76 100644 --- a/internal/dao/types.go +++ b/internal/dao/types.go @@ -73,7 +73,7 @@ type Accessor interface { // Loggable represents resources with logs. type Loggable interface { // TaiLogs streams resource logs. - TailLogs(ctx context.Context, c chan<- string, opts LogOptions) error + TailLogs(ctx context.Context, c chan<- []byte, opts LogOptions) error } // Describer describes a resource. diff --git a/internal/model/cluster_info_test.go b/internal/model/cluster_info_test.go new file mode 100644 index 00000000..7fabb932 --- /dev/null +++ b/internal/model/cluster_info_test.go @@ -0,0 +1,46 @@ +package model_test + +import ( + "testing" + + "github.com/derailed/k9s/internal/model" + "github.com/stretchr/testify/assert" +) + +func TestClusterMetaDelta(t *testing.T) { + uu := map[string]struct { + o, n model.ClusterMeta + e bool + }{ + "empty": { + o: model.NewClusterMeta(), + n: model.NewClusterMeta(), + }, + "same": { + o: makeClusterMeta("fred"), + n: makeClusterMeta("fred"), + }, + "diff": { + o: makeClusterMeta("fred"), + n: makeClusterMeta("freddie"), + e: true, + }, + } + + for k := range uu { + u := uu[k] + t.Run(k, func(t *testing.T) { + assert.Equal(t, u.e, u.o.Deltas(u.n)) + }) + } +} + +// Helpers... + +func makeClusterMeta(cluster string) model.ClusterMeta { + m := model.NewClusterMeta() + m.Cluster = cluster + m.Cpu, m.Mem = 10, 20 + + return m +} diff --git a/internal/model/log.go b/internal/model/log.go index 896f00be..07cbc4ad 100644 --- a/internal/model/log.go +++ b/internal/model/log.go @@ -31,25 +31,23 @@ type LogsListener interface { // Log represents a resource logger. type Log struct { - factory dao.Factory - lines []string - listeners []LogsListener - gvr client.GVR - logOptions dao.LogOptions - cancelFn context.CancelFunc - initialized bool - mx sync.RWMutex - filter string - lastSent int + factory dao.Factory + lines []string + listeners []LogsListener + gvr client.GVR + logOptions dao.LogOptions + cancelFn context.CancelFunc + mx sync.RWMutex + filter string + lastSent int } // NewLog returns a new model. -func NewLog(gvr client.GVR, msg string, opts dao.LogOptions, timeOut time.Duration) *Log { +func NewLog(gvr client.GVR, opts dao.LogOptions, timeOut time.Duration) *Log { return &Log{ - gvr: gvr, - logOptions: opts, - initialized: true, - lines: []string{msg}, + gvr: gvr, + logOptions: opts, + lines: nil, } } @@ -84,12 +82,11 @@ func (l *Log) Start() { // Stop terminates log tailing. func (l *Log) Stop() { - if l.cancelFn == nil { - return + defer log.Debug().Msgf("<<<< Logger STOPPED!") + if l.cancelFn != nil { + l.cancelFn() + l.cancelFn = nil } - log.Debug().Msgf("<<<< Logger STOP!") - l.cancelFn() - l.cancelFn = nil } // Set sets the log lines (for testing only!) @@ -131,7 +128,7 @@ func (l *Log) load() error { ctx = context.WithValue(context.Background(), internal.KeyFactory, l.factory) ctx, l.cancelFn = context.WithCancel(ctx) - c := make(chan string, 10) + c := make(chan []byte, 10) go l.updateLogs(ctx, c) accessor, err := dao.AccessorFor(l.factory, l.gvr) @@ -163,8 +160,7 @@ func (l *Log) Append(line string) { l.mx.Lock() defer l.mx.Unlock() - if l.initialized { - l.lines, l.initialized, l.lastSent = []string{}, false, 0 + if l.lines == nil { l.fireLogCleared() } @@ -190,20 +186,20 @@ func (l *Log) Notify(timedOut bool) { } } -func (l *Log) updateLogs(ctx context.Context, c <-chan string) { +func (l *Log) updateLogs(ctx context.Context, c <-chan []byte) { defer func() { log.Debug().Msgf("updateLogs view bailing out!") }() for { select { - case line, ok := <-c: + case bytes, ok := <-c: if !ok { log.Debug().Msgf("Closed channel detected. Bailing out...") - l.Append(line) + l.Append(string(bytes)) l.Notify(false) return } - l.Append(line) + l.Append(string(bytes)) var overflow bool l.mx.RLock() { diff --git a/internal/model/log_test.go b/internal/model/log_test.go index 6b23ea46..d6ac27d7 100644 --- a/internal/model/log_test.go +++ b/internal/model/log_test.go @@ -18,7 +18,7 @@ import ( func TestLogFullBuffer(t *testing.T) { size := 4 - m := model.NewLog(client.NewGVR("fred"), "Blee", makeLogOpts(size), 10*time.Millisecond) + m := model.NewLog(client.NewGVR("fred"), makeLogOpts(size), 10*time.Millisecond) m.Init(makeFactory()) v := newTestView() @@ -60,7 +60,7 @@ func TestLogFilter(t *testing.T) { for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { - m := model.NewLog(client.NewGVR("fred"), "Blee", makeLogOpts(size), 10*time.Millisecond) + m := model.NewLog(client.NewGVR("fred"), makeLogOpts(size), 10*time.Millisecond) m.Init(makeFactory()) v := newTestView() @@ -89,7 +89,7 @@ func TestLogFilter(t *testing.T) { } func TestLogStartStop(t *testing.T) { - m := model.NewLog(client.NewGVR("fred"), "Blee", makeLogOpts(4), 10*time.Millisecond) + m := model.NewLog(client.NewGVR("fred"), makeLogOpts(4), 10*time.Millisecond) m.Init(makeFactory()) v := newTestView() @@ -110,7 +110,7 @@ func TestLogStartStop(t *testing.T) { } func TestLogClear(t *testing.T) { - m := model.NewLog(client.NewGVR("fred"), "Blee", makeLogOpts(4), 10*time.Millisecond) + m := model.NewLog(client.NewGVR("fred"), makeLogOpts(4), 10*time.Millisecond) m.Init(makeFactory()) assert.Equal(t, "fred", m.GetPath()) assert.Equal(t, "blee", m.GetContainer()) @@ -132,7 +132,7 @@ func TestLogClear(t *testing.T) { } func TestLogBasic(t *testing.T) { - m := model.NewLog(client.NewGVR("fred"), "Blee", makeLogOpts(2), 10*time.Millisecond) + m := model.NewLog(client.NewGVR("fred"), makeLogOpts(2), 10*time.Millisecond) m.Init(makeFactory()) v := newTestView() @@ -148,7 +148,7 @@ func TestLogBasic(t *testing.T) { } func TestLogAppend(t *testing.T) { - m := model.NewLog(client.NewGVR("fred"), "blah blah", makeLogOpts(4), 5*time.Millisecond) + m := model.NewLog(client.NewGVR("fred"), makeLogOpts(4), 5*time.Millisecond) m.Init(makeFactory()) v := newTestView() @@ -161,17 +161,17 @@ func TestLogAppend(t *testing.T) { m.Append(d) } assert.Equal(t, 1, v.dataCalled) - assert.Equal(t, []string{}, v.data) + assert.Equal(t, []string{"blah blah"}, v.data) m.Notify(true) assert.Equal(t, 2, v.dataCalled) - assert.Equal(t, 1, v.clearCalled) + assert.Equal(t, 0, v.clearCalled) assert.Equal(t, 0, v.errCalled) - assert.Equal(t, data, v.data) + assert.Equal(t, append([]string{"blah blah"}, data...), v.data) } func TestLogTimedout(t *testing.T) { - m := model.NewLog(client.NewGVR("fred"), "Blee", makeLogOpts(4), 10*time.Millisecond) + m := model.NewLog(client.NewGVR("fred"), makeLogOpts(4), 10*time.Millisecond) m.Init(makeFactory()) v := newTestView() diff --git a/internal/render/job.go b/internal/render/job.go index 62048990..661c7c88 100644 --- a/internal/render/job.go +++ b/internal/render/job.go @@ -7,7 +7,6 @@ import ( "time" "github.com/derailed/k9s/internal/client" - "github.com/rs/zerolog/log" batchv1 "k8s.io/api/batch/v1" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -42,7 +41,6 @@ func (Job) Header(ns string) HeaderRow { // Render renders a K8s resource to screen. func (j Job) Render(o interface{}, ns string, r *Row) error { - log.Debug().Msgf("JOB RENDER %q", ns) raw, ok := o.(*unstructured.Unstructured) if !ok { return fmt.Errorf("Expected Job, but got %T", o) diff --git a/internal/view/app.go b/internal/view/app.go index 96c96e0b..d41814cb 100644 --- a/internal/view/app.go +++ b/internal/view/app.go @@ -134,7 +134,7 @@ func (a *App) toggleHeader(flag bool) { } if a.showHeader { flex.RemoveItemAtIndex(0) - flex.AddItemAtIndex(0, a.buildHeader(), 7, 1, false) + flex.AddItemAtIndex(0, a.buildHeader(), 8, 1, false) } else { flex.RemoveItemAtIndex(0) flex.AddItemAtIndex(0, a.statusIndicator(), 1, 1, false) @@ -144,7 +144,6 @@ func (a *App) toggleHeader(flag bool) { func (a *App) buildHeader() tview.Primitive { header := tview.NewFlex() header.SetBackgroundColor(a.Styles.BgColor()) - header.SetBorderPadding(0, 0, 1, 1) header.SetDirection(tview.FlexColumn) if !a.showHeader { return header diff --git a/internal/view/log.go b/internal/view/log.go index 5e7ede41..7e0e715b 100644 --- a/internal/view/log.go +++ b/internal/view/log.go @@ -21,7 +21,7 @@ import ( const ( logTitle = "logs" - logMessage = "Waiting for logs..." + logMessage = "[:orange:b]Waiting for logs...[::]" logCoFmt = " Logs([fg:bg:]%s:[hilite:bg:b]%s[-:bg:-]) " logFmt = " Logs([fg:bg:]%s) " @@ -49,7 +49,7 @@ func NewLog(gvr client.GVR, path, co string, prev bool) *Log { l := Log{ Flex: tview.NewFlex(), cmdBuff: ui.NewCmdBuff('/', ui.FilterBuff), - model: model.NewLog(gvr, logMessage, buildLogOpts(path, co, prev, tailLineCount), defaultTimeout), + model: model.NewLog(gvr, buildLogOpts(path, co, prev, tailLineCount), defaultTimeout), } return &l @@ -66,11 +66,13 @@ func (l *Log) Init(ctx context.Context) (err error) { l.indicator = NewLogIndicator(l.app.Config, l.app.Styles) l.AddItem(l.indicator, 1, 1, false) + l.indicator.Refresh() l.logs = NewDetails(l.app, "", "", false) if err = l.logs.Init(ctx); err != nil { return err } + l.logs.SetText(logMessage) l.logs.SetWrap(false) l.logs.SetMaxBuffer(l.app.Config.K9s.LogBufferSize) From 94e96b39a51a9ab50b07d6a08c8f51bde996aa59 Mon Sep 17 00:00:00 2001 From: Philipp Eckel Date: Thu, 13 Feb 2020 19:46:39 +0100 Subject: [PATCH 29/58] Update README.md: fix example hotkey.yml --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6a83473e..88700e05 100644 --- a/README.md +++ b/README.md @@ -226,7 +226,7 @@ Entering the command mode and typing a resource name or alias, could be cumberso command: dp # Hitting Shift-2 navigates to your xray deployments shift-2: - shortCut: Shift-4 + shortCut: Shift-2 description: Xray Deployments command: xray deploy ``` From f1ef8d216ccdc9e30fe4373fc1b66c89c2378188 Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 13 Feb 2020 12:31:30 -0700 Subject: [PATCH 30/58] enable port-forwards on pods and services --- go.mod | 8 +- go.sum | 5 + internal/dao/chart.go | 1 - internal/dao/helpers.go | 1 + internal/dao/ofaas.go | 216 ++++++++++++++++++++++++++++ internal/dao/registry.go | 17 ++- internal/model/registry.go | 4 + internal/render/chart.go | 2 +- internal/render/ofaas.go | 102 +++++++++++++ internal/render/ofaas_test.go | 34 +++++ internal/ui/dialog/port_forwards.go | 62 ++++++++ internal/view/app.go | 2 +- internal/view/container.go | 26 ++-- internal/view/help_test.go | 2 +- internal/view/ofaas.go | 46 ++++++ internal/view/pod.go | 80 ++++++++++- internal/view/pod_test.go | 2 +- internal/view/registrar.go | 3 + internal/view/svc.go | 100 ++++++++++++- internal/view/svc_test.go | 2 +- internal/watch/factory.go | 3 + plugins/README.md | 4 + plugins/job_suspend.yml | 19 +++ plugins/kubectl/kubectl-jq | 3 + plugins/log_jq.yml | 14 ++ plugins/log_stern.yml | 17 +++ 26 files changed, 745 insertions(+), 30 deletions(-) create mode 100644 internal/dao/ofaas.go create mode 100644 internal/render/ofaas.go create mode 100644 internal/render/ofaas_test.go create mode 100644 internal/ui/dialog/port_forwards.go create mode 100644 internal/view/ofaas.go create mode 100644 plugins/README.md create mode 100644 plugins/job_suspend.yml create mode 100755 plugins/kubectl/kubectl-jq create mode 100644 plugins/log_jq.yml create mode 100644 plugins/log_stern.yml diff --git a/go.mod b/go.mod index f440f8d9..599c7759 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module github.com/derailed/k9s go 1.13 +replace github.com/derailed/tview => /Users/fernand/go_wk/derailed/src/github.com/derailed/tview + replace ( github.com/docker/docker => github.com/docker/docker v1.4.2-0.20181221150755-2cb26cfe9cbf k8s.io/api => k8s.io/api v0.0.0-20190918155943-95b840bb6a1f @@ -30,6 +32,8 @@ replace ( require ( fyne.io/fyne v1.2.2 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect + github.com/alexellis/go-execute v0.0.0-20200124154445-8697e4e28c5e // indirect + github.com/alexellis/hmac v0.0.0-20180624211220-5c52ab81c0de // indirect github.com/atotto/clipboard v0.1.2 github.com/derailed/tview v0.3.4 github.com/drone/envsubst v1.0.2 // indirect @@ -42,9 +46,9 @@ require ( github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/mattn/go-runewidth v0.0.5 - github.com/openfaas/faas v0.0.0-20200207215241-6afae214e3ec // indirect + github.com/openfaas/faas v0.0.0-20200207215241-6afae214e3ec github.com/openfaas/faas-cli v0.0.0-20200124160744-30b7cec9634c - github.com/openfaas/faas-provider v0.15.0 // indirect + github.com/openfaas/faas-provider v0.15.0 github.com/petergtz/pegomock v2.6.0+incompatible github.com/rakyll/hey v0.1.2 github.com/rs/zerolog v1.17.2 diff --git a/go.sum b/go.sum index 38a835e0..07ae4013 100644 --- a/go.sum +++ b/go.sum @@ -67,6 +67,10 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alexellis/go-execute v0.0.0-20200124154445-8697e4e28c5e h1:0cv4CUENL7e67/ZlNrvExWqa6oKH/9iv0KQn0/+hYaY= +github.com/alexellis/go-execute v0.0.0-20200124154445-8697e4e28c5e/go.mod h1:zfRbgnPVxXCSpiKrg1CE72hNUWInqxExiaz2D9ppTts= +github.com/alexellis/hmac v0.0.0-20180624211220-5c52ab81c0de h1:jiPEvtW8VT0KwJxRyjW2VAAvlssjj9SfecsQ3Vgv5tk= +github.com/alexellis/hmac v0.0.0-20180624211220-5c52ab81c0de/go.mod h1:uAbpy8G7sjNB4qYdY6ymf5OIQ+TLDPApBYiR0Vc3lhk= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= @@ -470,6 +474,7 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c h1:nXxl5PrvVm2L/wCy8dQu6DMTwH4oIuGN8GJDAlqDdVE= github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mrunalp/fileutils v0.0.0-20160930181131-4ee1cc9a8058/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d h1:7PxY7LVfSZm7PEeBTyK1rj1gABdCO2mbri6GKO1cMDs= diff --git a/internal/dao/chart.go b/internal/dao/chart.go index e69aa050..a407bd0d 100644 --- a/internal/dao/chart.go +++ b/internal/dao/chart.go @@ -90,7 +90,6 @@ func (c *Chart) ToYAML(path string) (string, error) { // Delete uninstall a Chart. func (c *Chart) Delete(path string, cascade, force bool) error { - log.Debug().Msgf("CHART DELETE %q", path) ns, n := client.Namespaced(path) cfg, err := c.EnsureHelmConfig(ns) if err != nil { diff --git a/internal/dao/helpers.go b/internal/dao/helpers.go index e893e3b2..718ad677 100644 --- a/internal/dao/helpers.go +++ b/internal/dao/helpers.go @@ -29,6 +29,7 @@ func ToYAML(o runtime.Object) (string, error) { if o == nil { return "", errors.New("no object to yamlize") } + var ( buff bytes.Buffer p printers.YAMLPrinter diff --git a/internal/dao/ofaas.go b/internal/dao/ofaas.go new file mode 100644 index 00000000..7feb5402 --- /dev/null +++ b/internal/dao/ofaas.go @@ -0,0 +1,216 @@ +package dao + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "os" + "path" + "strings" + "time" + + "github.com/derailed/k9s/internal/client" + "github.com/derailed/k9s/internal/render" + "github.com/openfaas/faas-cli/proxy" + "github.com/openfaas/faas/gateway/requests" + "github.com/rs/zerolog/log" + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/yaml" +) + +const ( + oFaasGatewayEnv = "OPENFAAS_GATEWAY" + oFaasJWTTokenEnv = "OPENFAAS_JWT_TOKEN" + oFaasTLSInsecure = "OPENFAAS_TLS_INSECURE" +) + +var ( + _ Accessor = (*OpenFaas)(nil) + _ Nuker = (*OpenFaas)(nil) + _ Describer = (*OpenFaas)(nil) +) + +// OpenFaas represents a faas gateway connection. +type OpenFaas struct { + NonResource +} + +// IsOpenFaasEnabled returns true if a gateway url is set in the environment. +func IsOpenFaasEnabled() bool { + return os.Getenv(oFaasGatewayEnv) != "" +} + +func getOpenFAASFlags() (string, string, bool) { + gw, token := os.Getenv(oFaasGatewayEnv), os.Getenv(oFaasJWTTokenEnv) + tlsInsecure := false + if os.Getenv(oFaasTLSInsecure) == "true" { + tlsInsecure = true + } + + return gw, token, tlsInsecure +} + +// List returns a collection of functions +func (f *OpenFaas) Get(ctx context.Context, path string) (runtime.Object, error) { + ns, n := client.Namespaced(path) + + oo, err := f.List(ctx, ns) + if err != nil { + return nil, err + } + + var found runtime.Object + for _, o := range oo { + r, ok := o.(render.OpenFaasRes) + if !ok { + continue + } + if r.Function.Name == n { + found = o + break + } + } + + if found == nil { + return nil, fmt.Errorf("unable to locate function %q", path) + } + + return found, nil +} + +// List returns a collection of functions +func (f *OpenFaas) List(_ context.Context, ns string) ([]runtime.Object, error) { + if !IsOpenFaasEnabled() { + return nil, errors.New("OpenFAAS is not enabled on this cluster") + } + + gw, token, tls := getOpenFAASFlags() + ff, err := proxy.ListFunctionsToken(gw, tls, token, ns) + if err != nil { + return nil, err + } + + oo := make([]runtime.Object, 0, len(ff)) + for _, f := range ff { + oo = append(oo, render.OpenFaasRes{Function: f}) + } + + return oo, nil +} + +func (f *OpenFaas) Delete(path string, _, _ bool) error { + gw, token, tls := getOpenFAASFlags() + ns, n := client.Namespaced(path) + + // BOZO!! openfaas spews to stdout. Not good for us... + return deleteFunctionToken(gw, n, tls, token, ns) +} + +func (f *OpenFaas) ToYAML(path string) (string, error) { + return f.Describe(path) +} + +func (f *OpenFaas) Describe(path string) (string, error) { + o, err := f.Get(context.Background(), path) + if err != nil { + return "", err + } + + fn, ok := o.(render.OpenFaasRes) + if !ok { + return "", fmt.Errorf("expecting OpenFaasRes but got %T", o) + } + + raw, err := json.Marshal(fn) + if err != nil { + return "", err + } + + bytes, err := yaml.JSONToYAML(raw) + if err != nil { + return "", err + } + + return string(bytes), nil +} + +// BOZO!! Meow! openfaas fn prints to stdout have to dup ;( +func deleteFunctionToken(gateway string, functionName string, tlsInsecure bool, token string, namespace string) error { + defaultCommandTimeout := 60 * time.Second + + gateway = strings.TrimRight(gateway, "/") + delReq := requests.DeleteFunctionRequest{FunctionName: functionName} + reqBytes, _ := json.Marshal(&delReq) + reader := bytes.NewReader(reqBytes) + + c := proxy.MakeHTTPClient(&defaultCommandTimeout, tlsInsecure) + + deleteEndpoint, err := createSystemEndpoint(gateway, namespace) + if err != nil { + return err + } + + req, err := http.NewRequest("DELETE", deleteEndpoint, reader) + if err != nil { + fmt.Println(err) + return err + } + req.Header.Set("Content-Type", "application/json") + + if len(token) > 0 { + proxy.SetToken(req, token) + } else { + proxy.SetAuth(req, gateway) + } + + delRes, delErr := c.Do(req) + + if delErr != nil { + fmt.Printf("Error removing existing function: %s, gateway=%s, functionName=%s\n", delErr.Error(), gateway, functionName) + return delErr + } + + if delRes.Body != nil { + defer func() { + if err := delRes.Body.Close(); err != nil { + log.Error().Err(err).Msgf("closing delete-gtw body") + } + }() + } + + switch delRes.StatusCode { + case http.StatusOK, http.StatusCreated, http.StatusAccepted: + return nil + case http.StatusNotFound: + return fmt.Errorf("no function named %s found", functionName) + case http.StatusUnauthorized: + return fmt.Errorf("unauthorized access, run \"faas-cli login\" to setup authentication for this server") + default: + bytesOut, err := ioutil.ReadAll(delRes.Body) + if err != nil { + return err + } + return fmt.Errorf("server returned unexpected status code %d %s", delRes.StatusCode, string(bytesOut)) + } +} + +func createSystemEndpoint(gateway, namespace string) (string, error) { + const systemPath = "/system/functions" + + gatewayURL, err := url.Parse(gateway) + if err != nil { + return "", fmt.Errorf("invalid gateway URL: %s", err.Error()) + } + gatewayURL.Path = path.Join(gatewayURL.Path, systemPath) + if len(namespace) > 0 { + q := gatewayURL.Query() + q.Set("namespace", namespace) + gatewayURL.RawQuery = q.Encode() + } + return gatewayURL.String(), nil +} diff --git a/internal/dao/registry.go b/internal/dao/registry.go index 56799b5b..1436efd7 100644 --- a/internal/dao/registry.go +++ b/internal/dao/registry.go @@ -47,6 +47,7 @@ func AccessorFor(f Factory, gvr client.GVR) (Accessor, error) { client.NewGVR("batch/v1beta1/cronjobs"): &CronJob{}, client.NewGVR("batch/v1/jobs"): &Job{}, client.NewGVR("charts"): &Chart{}, + client.NewGVR("openfaas"): &OpenFaas{}, } r, ok := m[gvr] @@ -96,7 +97,7 @@ func (m *Meta) MetaFor(gvr client.GVR) (metav1.APIResource, error) { // IsK8sMeta checks for non resource meta. func IsK8sMeta(m metav1.APIResource) bool { for _, c := range m.Categories { - if c == "k9s" || c == "helm" { + if c == "k9s" || c == "helm" || c == "faas" { return false } } @@ -135,6 +136,9 @@ func loadNonResource(m ResourceMetas) { loadK9s(m) loadRBAC(m) loadHelm(m) + if IsOpenFaasEnabled() { + loadOpenFaas(m) + } } func loadK9s(m ResourceMetas) { @@ -203,6 +207,17 @@ func loadHelm(m ResourceMetas) { } } +func loadOpenFaas(m ResourceMetas) { + m[client.NewGVR("openfaas")] = metav1.APIResource{ + Name: "openfaas", + Kind: "OpenFaaS", + ShortNames: []string{"ofaas", "ofa"}, + Namespaced: true, + Verbs: []string{"delete"}, + Categories: []string{"faas"}, + } +} + func loadRBAC(m ResourceMetas) { m[client.NewGVR("rbac")] = metav1.APIResource{ Name: "rbacs", diff --git a/internal/model/registry.go b/internal/model/registry.go index 717f8bec..997ddfe2 100644 --- a/internal/model/registry.go +++ b/internal/model/registry.go @@ -14,6 +14,10 @@ var Registry = map[string]ResourceMeta{ DAO: &dao.Chart{}, Renderer: &render.Chart{}, }, + "openfaas": { + DAO: &dao.OpenFaas{}, + Renderer: &render.OpenFaas{}, + }, "containers": { DAO: &dao.Container{}, Renderer: &render.Container{}, diff --git a/internal/render/chart.go b/internal/render/chart.go index cb3aa0c7..f1ab5892 100644 --- a/internal/render/chart.go +++ b/internal/render/chart.go @@ -66,7 +66,7 @@ func (c Chart) Render(o interface{}, ns string, r *Row) error { // ---------------------------------------------------------------------------- // Helpers... -// ChartRes represents an alias resource. +// ChartRes represents an helm chart resource. type ChartRes struct { Release *release.Release } diff --git a/internal/render/ofaas.go b/internal/render/ofaas.go new file mode 100644 index 00000000..c51dd4c7 --- /dev/null +++ b/internal/render/ofaas.go @@ -0,0 +1,102 @@ +package render + +import ( + "fmt" + "strconv" + "time" + + "github.com/derailed/k9s/internal/client" + "github.com/derailed/tview" + "github.com/gdamore/tcell" + ofaas "github.com/openfaas/faas-provider/types" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + fnStatusReady = "Ready" + fnStatusNotReady = "Not Ready" +) + +// OpenFaas renders an openfaas function to screen. +type OpenFaas struct{} + +// ColorerFunc colors a resource row. +func (OpenFaas) ColorerFunc() ColorerFunc { + return func(ns string, re RowEvent) tcell.Color { + return tcell.ColorPaleTurquoise + } +} + +// Header returns a header row. +func (OpenFaas) Header(ns string) HeaderRow { + var h HeaderRow + if client.IsAllNamespaces(ns) { + h = append(h, Header{Name: "NAMESPACE"}) + } + + return append(h, + Header{Name: "NAME"}, + Header{Name: "STATUS"}, + Header{Name: "IMAGE"}, + Header{Name: "LABELS"}, + Header{Name: "INVOCATIONS", Align: tview.AlignRight}, + Header{Name: "REPLICAS", Align: tview.AlignRight}, + Header{Name: "AVAILABLE", Align: tview.AlignRight}, + Header{Name: "AGE", Decorator: AgeDecorator}, + ) +} + +// Render renders a chart to screen. +func (f OpenFaas) Render(o interface{}, ns string, r *Row) error { + fn, ok := o.(OpenFaasRes) + if !ok { + return fmt.Errorf("expected OpenFaasRes, but got %T", o) + } + + var labels string + if fn.Function.Labels != nil { + labels = mapToStr(*fn.Function.Labels) + } + var status = fnStatusReady + if fn.Function.AvailableReplicas == 0 { + status = fnStatusNotReady + } + + r.ID = client.FQN(fn.Function.Namespace, fn.Function.Name) + r.Fields = make(Fields, 0, len(f.Header(ns))) + if client.IsAllNamespaces(ns) { + r.Fields = append(r.Fields, fn.Function.Namespace) + } + r.Fields = append(r.Fields, + fn.Function.Name, + status, + fn.Function.Image, + labels, + strconv.Itoa(int(fn.Function.InvocationCount)), + strconv.Itoa(int(fn.Function.Replicas)), + strconv.Itoa(int(fn.Function.AvailableReplicas)), + toAge(metav1.Time{Time: time.Now()}), + ) + + return nil +} + +// ---------------------------------------------------------------------------- +// Helpers... + +// OpenFaasRes represents an openfaas function resource. +type OpenFaasRes struct { + Function ofaas.FunctionStatus `json:"function"` +} + +// GetObjectKind returns a schema object. +func (OpenFaasRes) GetObjectKind() schema.ObjectKind { + return nil +} + +// DeepCopyObject returns a container copy. +func (h OpenFaasRes) DeepCopyObject() runtime.Object { + return h +} diff --git a/internal/render/ofaas_test.go b/internal/render/ofaas_test.go new file mode 100644 index 00000000..3deda698 --- /dev/null +++ b/internal/render/ofaas_test.go @@ -0,0 +1,34 @@ +package render_test + +import ( + "testing" + + "github.com/derailed/k9s/internal/render" + ofaas "github.com/openfaas/faas-provider/types" + "github.com/stretchr/testify/assert" +) + +func TestOpenFaasRender(t *testing.T) { + c := render.OpenFaas{} + r := render.NewRow(9) + c.Render(makeFn("blee"), "", &r) + + assert.Equal(t, "default/blee", r.ID) + assert.Equal(t, render.Fields{"default", "blee", "Ready", "nginx:0", "fred=blee", "10", "1", "1"}, r.Fields[:8]) +} + +// Helpers... + +func makeFn(n string) render.OpenFaasRes { + return render.OpenFaasRes{ + Function: ofaas.FunctionStatus{ + Name: n, + Namespace: "default", + Image: "nginx:0", + InvocationCount: 10, + Replicas: 1, + AvailableReplicas: 1, + Labels: &map[string]string{"fred": "blee"}, + }, + } +} diff --git a/internal/ui/dialog/port_forwards.go b/internal/ui/dialog/port_forwards.go new file mode 100644 index 00000000..279e4524 --- /dev/null +++ b/internal/ui/dialog/port_forwards.go @@ -0,0 +1,62 @@ +package dialog + +import ( + "fmt" + + "github.com/derailed/k9s/internal/config" + "github.com/derailed/k9s/internal/ui" + "github.com/derailed/tview" +) + +type PortForwardFunc func(path, address, lport, cport string) + +// ShowPortForwards pops a port forwarding configuration dialog. +func ShowPortForwards(p *ui.Pages, s *config.Styles, path string, ports []string, okFn PortForwardFunc) { + f := tview.NewForm() + f.SetItemPadding(0) + f.SetButtonsAlign(tview.AlignCenter). + SetButtonBackgroundColor(s.BgColor()). + SetButtonTextColor(s.FgColor()). + SetLabelColor(config.AsColor(s.K9s.Info.FgColor)). + SetFieldTextColor(config.AsColor(s.K9s.Info.SectionColor)) + + p1, p2, address := ports[0], ports[0], "localhost" + f.AddDropDown("Container Ports", ports, 0, func(sel string, _ int) { + p1, p2 = sel, stripPort(sel) + }) + + dropD, ok := f.GetFormItem(0).(*tview.DropDown) + if ok { + dropD.SetFieldBackgroundColor(s.BgColor()) + list := dropD.GetList() + list.SetMainTextColor(s.FgColor()) + list.SetSelectedTextColor(s.FgColor()) + list.SetSelectedBackgroundColor(config.AsColor(s.Table().CursorColor)) + list.SetBackgroundColor(s.BgColor() + 100) + } + f.AddInputField("Local Port:", p2, 20, nil, func(p string) { + p2 = p + }) + f.AddInputField("Address:", address, 20, nil, func(h string) { + address = h + }) + + f.AddButton("OK", func() { + okFn(path, address, stripPort(p2), stripPort(p1)) + }) + f.AddButton("Cancel", func() { + DismissPortForward(p) + }) + + modal := tview.NewModalForm(fmt.Sprintf("", path), f) + modal.SetDoneFunc(func(_ int, b string) { + DismissPortForward(p) + }) + p.AddPage(portForwardKey, modal, false, false) + p.ShowPage(portForwardKey) +} + +// DismissPortForward dismiss the port forward dialog. +func DismissPortForwards(p *ui.Pages) { + p.RemovePage(portForwardKey) +} diff --git a/internal/view/app.go b/internal/view/app.go index d41814cb..d36f5745 100644 --- a/internal/view/app.go +++ b/internal/view/app.go @@ -134,7 +134,7 @@ func (a *App) toggleHeader(flag bool) { } if a.showHeader { flex.RemoveItemAtIndex(0) - flex.AddItemAtIndex(0, a.buildHeader(), 8, 1, false) + flex.AddItemAtIndex(0, a.buildHeader(), 7, 1, false) } else { flex.RemoveItemAtIndex(0) flex.AddItemAtIndex(0, a.statusIndicator(), 1, 1, false) diff --git a/internal/view/container.go b/internal/view/container.go index 9b25a00f..724801eb 100644 --- a/internal/view/container.go +++ b/internal/view/container.go @@ -159,31 +159,35 @@ func (c *Container) preparePort(pp []string) string { func (c *Container) portForward(address, lport, cport string) { co := c.GetTable().GetSelectedCell(0) pf := dao.NewPortForwarder(c.App().Conn()) + path := c.GetTable().GetSelectedItem() ports := []string{lport + ":" + cport} - fw, err := pf.Start(c.GetTable().Path, co, address, ports) + fw, err := pf.Start(path, co, address, ports) if err != nil { c.App().Flash().Err(err) return } - log.Debug().Msgf(">>> Starting port forward %q %v", c.GetTable().Path, ports) - go c.runForward(pf, fw) + log.Debug().Msgf(">>> Starting port forward %q %v", path, ports) + go runForward(c.App(), pf, fw) } -func (c *Container) runForward(pf *dao.PortForwarder, f *portforward.PortForwarder) { - c.App().QueueUpdateDraw(func() { - c.App().factory.AddForwarder(pf) - c.App().Flash().Infof("PortForward activated %s:%s", pf.Path(), pf.Ports()[0]) - dialog.DismissPortForward(c.App().Content.Pages) +// ---------------------------------------------------------------------------- +// Helpers... + +func runForward(a *App, pf *dao.PortForwarder, f *portforward.PortForwarder) { + a.QueueUpdateDraw(func() { + a.factory.AddForwarder(pf) + a.Flash().Infof("PortForward activated %s:%s", pf.Path(), pf.Ports()[0]) + dialog.DismissPortForward(a.Content.Pages) }) pf.SetActive(true) if err := f.ForwardPorts(); err != nil { - c.App().Flash().Err(err) + a.Flash().Err(err) return } - c.App().QueueUpdateDraw(func() { - c.App().factory.DeleteForwarder(pf.FQN()) + a.QueueUpdateDraw(func() { + a.factory.DeleteForwarder(pf.FQN()) pf.SetActive(false) }) } diff --git a/internal/view/help_test.go b/internal/view/help_test.go index 18c5ccd3..443633c3 100644 --- a/internal/view/help_test.go +++ b/internal/view/help_test.go @@ -21,7 +21,7 @@ func TestHelp(t *testing.T) { v := view.NewHelp() assert.Nil(t, v.Init(ctx)) - assert.Equal(t, 19, v.GetRowCount()) + assert.Equal(t, 20, v.GetRowCount()) assert.Equal(t, 8, v.GetColumnCount()) assert.Equal(t, "", strings.TrimSpace(v.GetCell(1, 0).Text)) assert.Equal(t, "Kill", strings.TrimSpace(v.GetCell(1, 1).Text)) diff --git a/internal/view/ofaas.go b/internal/view/ofaas.go new file mode 100644 index 00000000..fda3bd62 --- /dev/null +++ b/internal/view/ofaas.go @@ -0,0 +1,46 @@ +package view + +import ( + "strings" + + "github.com/derailed/k9s/internal/client" + "github.com/derailed/k9s/internal/render" + "github.com/derailed/k9s/internal/ui" +) + +// OpenFaas represents an OpenFaaS viewer. +type OpenFaas struct { + ResourceViewer +} + +// NewOpenFaas returns a new viewer. +func NewOpenFaas(gvr client.GVR) ResourceViewer { + o := OpenFaas{ResourceViewer: NewBrowser(gvr)} + o.SetBindKeysFn(o.bindKeys) + o.GetTable().SetEnterFn(o.showPods) + o.GetTable().SetColorerFn(render.OpenFaas{}.ColorerFunc()) + + return &o +} + +func (o *OpenFaas) bindKeys(aa ui.KeyActions) { + aa.Add(ui.KeyActions{ + ui.KeyShiftS: ui.NewKeyAction("Sort Status", o.GetTable().SortColCmd(2, true), false), + ui.KeyShiftT: ui.NewKeyAction("Sort Invocations", o.GetTable().SortColCmd(5, false), false), + ui.KeyShiftC: ui.NewKeyAction("Sort Replicas", o.GetTable().SortColCmd(6, false), false), + ui.KeyShiftM: ui.NewKeyAction("Sort Available", o.GetTable().SortColCmd(7, false), false), + }) +} + +func (o *OpenFaas) showPods(a *App, _ ui.Tabular, _, path string) { + labels := o.GetTable().GetSelectedCell(4) + sels := make(map[string]string) + + tokens := strings.Split(labels, ",") + for _, t := range tokens { + s := strings.Split(t, "=") + sels[s[0]] = s[1] + } + + showPodsWithLabels(a, path, sels) +} diff --git a/internal/view/pod.go b/internal/view/pod.go index 11f50ec0..0a79b7c7 100644 --- a/internal/view/pod.go +++ b/internal/view/pod.go @@ -11,6 +11,7 @@ import ( "github.com/derailed/k9s/internal/model" "github.com/derailed/k9s/internal/render" "github.com/derailed/k9s/internal/ui" + "github.com/derailed/k9s/internal/ui/dialog" "github.com/derailed/k9s/internal/watch" "github.com/fatih/color" "github.com/gdamore/tcell" @@ -49,6 +50,7 @@ func (p *Pod) bindKeys(aa ui.KeyActions) { } aa.Add(ui.KeyActions{ + ui.KeyShiftF: ui.NewKeyAction("Port-Forward", p.portFwdCmd, true), ui.KeyShiftR: ui.NewKeyAction("Sort Ready", p.GetTable().SortColCmd(1, true), false), ui.KeyShiftS: ui.NewKeyAction("Sort Status", p.GetTable().SortColCmd(2, true), false), ui.KeyShiftT: ui.NewKeyAction("Sort Restart", p.GetTable().SortColCmd(3, false), false), @@ -64,7 +66,6 @@ func (p *Pod) bindKeys(aa ui.KeyActions) { } func (p *Pod) showContainers(app *App, model ui.Tabular, gvr, path string) { - log.Debug().Msgf("SHOW CONTAINERS %q -- %q -- %q", gvr, model.GetNamespace(), path) co := NewContainer(client.NewGVR("containers")) co.SetContextFn(p.coContext) if err := app.inject(co); err != nil { @@ -128,6 +129,51 @@ func (p *Pod) shellCmd(evt *tcell.EventKey) *tcell.EventKey { return nil } +func (p *Pod) portFwdCmd(evt *tcell.EventKey) *tcell.EventKey { + path := p.GetTable().GetSelectedItem() + if path == "" { + return evt + } + + pp, err := fetchPodPorts(p.App().factory, path) + if err != nil { + p.App().Flash().Err(err) + return nil + } + ports := make([]string, 0, len(pp)) + for _, p := range pp { + if p.Protocol == v1.ProtocolTCP { + port := fmt.Sprintf("%s:%d", p.Name, p.ContainerPort) + if p.Name == "" { + port = fmt.Sprintf("%d", p.ContainerPort) + } + ports = append(ports, port) + } + } + + if len(ports) == 0 { + p.App().Flash().Err(fmt.Errorf("no tcp ports found on %s", path)) + return nil + } + + dialog.ShowPortForwards(p.App().Content.Pages, p.App().Styles, path, ports, p.portForward) + + return nil +} + +func (p *Pod) portForward(path, address, lport, cport string) { + pf := dao.NewPortForwarder(p.App().Conn()) + ports := []string{lport + ":" + cport} + fw, err := pf.Start(path, "", address, ports) + if err != nil { + p.App().Flash().Err(err) + return + } + + log.Debug().Msgf(">>> Starting port forward %q %v", path, ports) + go runForward(p.App(), pf, fw) +} + // ---------------------------------------------------------------------------- // Helpers... @@ -160,6 +206,7 @@ func containerShellin(a *App, comp model.Component, path, co string) error { func resumeShellIn(a *App, c model.Component, path, co string) { c.Stop() defer c.Start() + shellIn(a, path, co) } @@ -205,10 +252,33 @@ func fetchContainers(f *watch.Factory, path string, includeInit bool) ([]string, for _, c := range pod.Spec.Containers { nn = append(nn, c.Name) } - if includeInit { - for _, c := range pod.Spec.InitContainers { - nn = append(nn, c.Name) - } + if !includeInit { + return nn, nil } + for _, c := range pod.Spec.InitContainers { + nn = append(nn, c.Name) + } + return nn, nil } + +func fetchPodPorts(f *watch.Factory, path string) ([]v1.ContainerPort, error) { + log.Debug().Msgf("Fetching ports on pod %q", path) + o, err := f.Get("v1/pods", path, false, labels.Everything()) + if err != nil { + return nil, err + } + + var pod v1.Pod + err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &pod) + if err != nil { + return nil, err + } + + pp := make([]v1.ContainerPort, 0, len(pod.Spec.Containers)) + for _, c := range pod.Spec.Containers { + pp = append(pp, c.Ports...) + } + + return pp, nil +} diff --git a/internal/view/pod_test.go b/internal/view/pod_test.go index 00878bdb..8588155c 100644 --- a/internal/view/pod_test.go +++ b/internal/view/pod_test.go @@ -16,7 +16,7 @@ func TestPodNew(t *testing.T) { assert.Nil(t, po.Init(makeCtx())) assert.Equal(t, "Pods", po.Name()) - assert.Equal(t, 18, len(po.Hints())) + assert.Equal(t, 19, len(po.Hints())) } // Helpers... diff --git a/internal/view/registrar.go b/internal/view/registrar.go index 40d228a9..9631348d 100644 --- a/internal/view/registrar.go +++ b/internal/view/registrar.go @@ -51,6 +51,9 @@ func miscViewers(vv MetaViewers) { vv[client.NewGVR("contexts")] = MetaViewer{ viewerFn: NewContext, } + vv[client.NewGVR("openfaas")] = MetaViewer{ + viewerFn: NewOpenFaas, + } vv[client.NewGVR("containers")] = MetaViewer{ viewerFn: NewContainer, } diff --git a/internal/view/svc.go b/internal/view/svc.go index 5cd7257b..0a5aff0b 100644 --- a/internal/view/svc.go +++ b/internal/view/svc.go @@ -8,8 +8,10 @@ import ( "github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/config" + "github.com/derailed/k9s/internal/dao" "github.com/derailed/k9s/internal/perf" "github.com/derailed/k9s/internal/ui" + "github.com/derailed/k9s/internal/ui/dialog" "github.com/gdamore/tcell" "github.com/rs/zerolog/log" v1 "k8s.io/api/core/v1" @@ -40,19 +42,92 @@ func NewService(gvr client.GVR) ResourceViewer { func (s *Service) bindKeys(aa ui.KeyActions) { aa.Add(ui.KeyActions{ + ui.KeyShiftF: ui.NewKeyAction("Port-Forward", s.portFwdCmd, true), tcell.KeyCtrlB: ui.NewKeyAction("Bench Run/Stop", s.toggleBenchCmd, true), ui.KeyShiftT: ui.NewKeyAction("Sort Type", s.GetTable().SortColCmd(1, true), false), }) } -func (s *Service) showPods(app *App, _ ui.Tabular, gvr, path string) { - o, err := app.factory.Get(gvr, path, true, labels.Everything()) +func podFromSelector(f dao.Factory, ns string, sel map[string]string) (string, error) { + log.Debug().Msgf("Looking for pods %q:%v -- %v", ns, sel, labels.Set(sel).AsSelector()) + oo, err := f.List("v1/pods", ns, true, labels.Set(sel).AsSelector()) if err != nil { - app.Flash().Err(err) + return "", err + } + + if len(oo) == 0 { + return "", fmt.Errorf("no matching pods for %v", sel) + } + + var pod v1.Pod + err = runtime.DefaultUnstructuredConverter.FromUnstructured(oo[0].(*unstructured.Unstructured).Object, &pod) + if err != nil { + return "", err + } + + return client.FQN(pod.Namespace, pod.Name), nil +} + +func (s *Service) portFwdCmd(evt *tcell.EventKey) *tcell.EventKey { + path := s.GetTable().GetSelectedItem() + if path == "" { + return evt + } + + svc, err := fetchService(s.App().factory, s.GVR(), path) + if err != nil { + s.App().Flash().Err(err) + return nil + } + + ns, _ := client.Namespaced(path) + pod, err := podFromSelector(s.App().factory, ns, svc.Spec.Selector) + if err != nil { + s.App().Flash().Err(err) + return nil + } + + pp, err := fetchPodPorts(s.App().factory, pod) + if err != nil { + s.App().Flash().Err(err) + return nil + } + ports := make([]string, 0, len(pp)) + for _, p := range pp { + if p.Protocol == v1.ProtocolTCP { + port := fmt.Sprintf("%s:%d", p.Name, p.ContainerPort) + if p.Name == "" { + port = fmt.Sprintf("%d", p.ContainerPort) + } + ports = append(ports, port) + } + } + + if len(ports) == 0 { + s.App().Flash().Err(fmt.Errorf("no tcp ports found on %s", path)) + return nil + } + + dialog.ShowPortForwards(s.App().Content.Pages, s.App().Styles, pod, ports, s.portForward) + + return nil +} + +func (s *Service) portForward(path, address, lport, cport string) { + pf := dao.NewPortForwarder(s.App().Conn()) + ports := []string{lport + ":" + cport} + fw, err := pf.Start(path, "", address, ports) + if err != nil { + s.App().Flash().Err(err) return } - var svc v1.Service - err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &svc) + + log.Debug().Msgf(">>> Starting port forward %q %v", path, ports) + go runForward(s.App(), pf, fw) +} + +func (s *Service) showPods(app *App, _ ui.Tabular, gvr, path string) { + svc, err := fetchService(app.factory, gvr, path) if err != nil { app.Flash().Err(err) return @@ -170,6 +245,21 @@ func (s *Service) benchDone() { }) } +// ---------------------------------------------------------------------------- +// Helpers... + +func fetchService(f dao.Factory, gvr, path string) (*v1.Service, error) { + o, err := f.Get(gvr, path, true, labels.Everything()) + if err != nil { + return nil, err + } + + var svc v1.Service + err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &svc) + + return &svc, err +} + func benchTimedOut(app *App) { <-time.After(2 * time.Second) app.QueueUpdate(func() { diff --git a/internal/view/svc_test.go b/internal/view/svc_test.go index b09e3dfc..a9a5bd1c 100644 --- a/internal/view/svc_test.go +++ b/internal/view/svc_test.go @@ -132,5 +132,5 @@ func TestServiceNew(t *testing.T) { assert.Nil(t, s.Init(makeCtx())) assert.Equal(t, "Services", s.Name()) - assert.Equal(t, 7, len(s.Hints())) + assert.Equal(t, 8, len(s.Hints())) } diff --git a/internal/watch/factory.go b/internal/watch/factory.go index 4a56f178..3fe01958 100644 --- a/internal/watch/factory.go +++ b/internal/watch/factory.go @@ -229,6 +229,9 @@ func (f *Factory) DeleteForwarder(path string) { // Forwarders returns all portforwards. func (f *Factory) Forwarders() Forwarders { + f.mx.RLock() + defer f.mx.RUnlock() + return f.forwarders } diff --git a/plugins/README.md b/plugins/README.md new file mode 100644 index 00000000..e23d86d7 --- /dev/null +++ b/plugins/README.md @@ -0,0 +1,4 @@ +# K9s community plugins + +These plugins provide for extending the K9s cli to provide for more cluster management fu. + diff --git a/plugins/job_suspend.yml b/plugins/job_suspend.yml new file mode 100644 index 00000000..3d4b4ae7 --- /dev/null +++ b/plugins/job_suspend.yml @@ -0,0 +1,19 @@ +plugin: + # Suspends/Resumes a cronjob + suspendCronsToggle: + shortCut: Ctrl-S + scopes: + - cj + description: Suspend toggle + command: kubectl + background: true + args: + - patch + - cronjobs + - $NAME + - ns + - $NAMESPACE + - --context + - $CONTEXT + - -p + - '{"spec" : {"suspend" : $COL3 }}' diff --git a/plugins/kubectl/kubectl-jq b/plugins/kubectl/kubectl-jq new file mode 100755 index 00000000..5229a1d5 --- /dev/null +++ b/plugins/kubectl/kubectl-jq @@ -0,0 +1,3 @@ +#!/bin/bash + +/usr/local/bin/kubectl logs -f $1 -n $2 --context $3 | jq -r '.message' \ No newline at end of file diff --git a/plugins/log_jq.yml b/plugins/log_jq.yml new file mode 100644 index 00000000..4e6d6d3c --- /dev/null +++ b/plugins/log_jq.yml @@ -0,0 +1,14 @@ +plugin: + # Sends logs over to jq for processing. This leverages kubectl plugin kubectl-jq. + jqlogs: + shortCut: Ctrl-J + description: "Logs (jq)" + scopes: + - po + command: kubectl + background: false + args: + - jq + - $NAME + - $NAMESPACE + - $CONTEXT diff --git a/plugins/log_stern.yml b/plugins/log_stern.yml new file mode 100644 index 00000000..83dbe6f1 --- /dev/null +++ b/plugins/log_stern.yml @@ -0,0 +1,17 @@ +plugin: + # Leverage stern (https://github.com/wercker/stern) to output logs. + stern: + shortCut: Ctrl-L + description: "Logs " + scopes: + - pods + command: stern + background: false + args: + - --tail + - 50 + - $FILTER + - -n + - $NAMESPACE + - --context + - $CONTEXT From bda9f4e6a44323443bd7e8ef4080948598654d41 Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 13 Feb 2020 14:00:43 -0700 Subject: [PATCH 31/58] update rel notes --- change_logs/release_v0.15.0.md | 55 ++++++++++++++++++++++++++++++++++ internal/view/ofaas.go | 6 ++-- 2 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 change_logs/release_v0.15.0.md diff --git a/change_logs/release_v0.15.0.md b/change_logs/release_v0.15.0.md new file mode 100644 index 00000000..f680d8a8 --- /dev/null +++ b/change_logs/release_v0.15.0.md @@ -0,0 +1,55 @@ + + +# Release v0.15.0 + +## Notes + +Thank you to all that contributed with flushing out issues and enhancements for K9s! I'll try to mark some of these issues as fixed. But if you don't mind grab the latest rev and see if we're happier with some of the fixes! If you've filed an issue please help me verify and close. Your support, kindness and awesome suggestions to make K9s better is as ever very much noticed and appreciated! + +Also if you dig this tool, please make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer) + +On Slack? Please join us [K9slackers](https://join.slack.com/t/k9sers/shared_invite/enQtOTA5MDEyNzI5MTU0LWQ1ZGI3MzliYzZhZWEyNzYxYzA3NjE0YTk1YmFmNzViZjIyNzhkZGI0MmJjYzhlNjdlMGJhYzE2ZGU1NjkyNTM) + +--- + +## Does This FaaS Look Familiar? + +The awesome and ever so smart and creative [Alex Ellis](https://github.com/alexellis) of [OpenFaas Fame](https://www.openfaas.com) fame, had pinged me when I had launched K9s to add support for OpenFaas functions. It's been a long time coming indeed, but we now have a very (VERY!) primitive integration with this very cool framework. + +The current approach is to enable a few environment variables to tell K9s that you have an OpenFaas cluster available namely: + +```shell +OPENFAAS_GATEWAY=http://YOUR_CLUSTER_IP:31112 +OPENFAAS_TLS_INSECURE=false +OPENFAAS_JWT_TOKEN=YOUR_TOKEN +``` + +These will tell K9s that an OpenFaas gateway is available and exposed on a given nodeport. + +Next you can navigate to your OpenFaas function view by entering command mode `:openfaas` or using aliases `:ofaas` or `ofa` + +If functions are present in the given namespace they will be displayed here just like any other K8s resources. + +The following operations are currently supported: + +* Describe and YAML to view function definitions (Note: currently yields same results!) +* Enter to view all pods instances associated with the selected function +* Delete a function +* Editing, shelling, logs, etc... are all supported by navigating to the underlying pods + +Keep in mind, the paint is way fresh here and this feature could be a complete dud, but figure will give it a rinse on this drop and Alex can pipe in and helps us ironing this out. + +> NOTE! It's been a while since I've played with OpenFaas so if some of you are more versed in this space by all means please do land a hand so we can make this feature more awesome! + +## Moving Forward! + +A few folks had mentioned the eagerness to port-forward directly from a pod or a service. Well now you can! Port Forwarding is now available on both the pod view and services view. Note! at the end of the day, you are still port-fowarding to a container! So the port-forward dialog is a bit different for these views as there might be several container ports available now when looking at this from a pod perspective. So the first field in the dialog is a combo-box that allows one to pick their desired ports. The rest of the dialog works the same as the container port-forward dialog. + +## Resolved Bugs/Features/PRs + +* [Issue #541](https://github.com/derailed/k9s/issues/541) +* [Issue #227](https://github.com/derailed/k9s/issues/227) + +--- + + © 2020 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0) diff --git a/internal/view/ofaas.go b/internal/view/ofaas.go index fda3bd62..fa5799c4 100644 --- a/internal/view/ofaas.go +++ b/internal/view/ofaas.go @@ -26,9 +26,9 @@ func NewOpenFaas(gvr client.GVR) ResourceViewer { func (o *OpenFaas) bindKeys(aa ui.KeyActions) { aa.Add(ui.KeyActions{ ui.KeyShiftS: ui.NewKeyAction("Sort Status", o.GetTable().SortColCmd(2, true), false), - ui.KeyShiftT: ui.NewKeyAction("Sort Invocations", o.GetTable().SortColCmd(5, false), false), - ui.KeyShiftC: ui.NewKeyAction("Sort Replicas", o.GetTable().SortColCmd(6, false), false), - ui.KeyShiftM: ui.NewKeyAction("Sort Available", o.GetTable().SortColCmd(7, false), false), + ui.KeyShiftI: ui.NewKeyAction("Sort Invocations", o.GetTable().SortColCmd(4, false), false), + ui.KeyShiftR: ui.NewKeyAction("Sort Replicas", o.GetTable().SortColCmd(5, false), false), + ui.KeyShiftV: ui.NewKeyAction("Sort Available", o.GetTable().SortColCmd(6, false), false), }) } From 580d8ea36d12267addee3cf20d0bd663c34ae389 Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 13 Feb 2020 17:36:05 -0700 Subject: [PATCH 32/58] oops hosed the build... --- change_logs/release_v0.15.0.md | 1 + go.mod | 4 +--- go.sum | 2 ++ internal/view/app.go | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/change_logs/release_v0.15.0.md b/change_logs/release_v0.15.0.md index f680d8a8..57c823b3 100644 --- a/change_logs/release_v0.15.0.md +++ b/change_logs/release_v0.15.0.md @@ -47,6 +47,7 @@ A few folks had mentioned the eagerness to port-forward directly from a pod or a ## Resolved Bugs/Features/PRs +* [Issue #546](https://github.com/derailed/k9s/issues/546) BREAKING NEWS! Use `t` vs `ctrl-h` now to toggle the K9s header * [Issue #541](https://github.com/derailed/k9s/issues/541) * [Issue #227](https://github.com/derailed/k9s/issues/227) diff --git a/go.mod b/go.mod index 599c7759..1fb59774 100644 --- a/go.mod +++ b/go.mod @@ -2,8 +2,6 @@ module github.com/derailed/k9s go 1.13 -replace github.com/derailed/tview => /Users/fernand/go_wk/derailed/src/github.com/derailed/tview - replace ( github.com/docker/docker => github.com/docker/docker v1.4.2-0.20181221150755-2cb26cfe9cbf k8s.io/api => k8s.io/api v0.0.0-20190918155943-95b840bb6a1f @@ -35,7 +33,7 @@ require ( github.com/alexellis/go-execute v0.0.0-20200124154445-8697e4e28c5e // indirect github.com/alexellis/hmac v0.0.0-20180624211220-5c52ab81c0de // indirect github.com/atotto/clipboard v0.1.2 - github.com/derailed/tview v0.3.4 + github.com/derailed/tview v0.3.5 github.com/drone/envsubst v1.0.2 // indirect github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f // indirect github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f // indirect diff --git a/go.sum b/go.sum index 07ae4013..34dddd58 100644 --- a/go.sum +++ b/go.sum @@ -153,6 +153,8 @@ github.com/derailed/tview v0.3.3 h1:tipPwxcDhx0zRBZuc8VKIrNgWL40FL5JeF/30XVieUE= github.com/derailed/tview v0.3.3/go.mod h1:yApPszFU62FoaGkf7swy2nIdV/h7Nid3dhMSVy6+OFI= github.com/derailed/tview v0.3.4 h1:PnF64fLqm48LEjC/XwOS7JufDgFuuPYx85YVt5t3rwE= github.com/derailed/tview v0.3.4/go.mod h1:yApPszFU62FoaGkf7swy2nIdV/h7Nid3dhMSVy6+OFI= +github.com/derailed/tview v0.3.5 h1:1vKqcJIiZtLAs5moX9c38+BbBSYhPgFq0ZndnVNVNFc= +github.com/derailed/tview v0.3.5/go.mod h1:yApPszFU62FoaGkf7swy2nIdV/h7Nid3dhMSVy6+OFI= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= diff --git a/internal/view/app.go b/internal/view/app.go index d36f5745..c0ac13b8 100644 --- a/internal/view/app.go +++ b/internal/view/app.go @@ -114,7 +114,7 @@ func (a *App) Init(version string, rate int) error { func (a *App) bindKeys() { a.AddActions(ui.KeyActions{ - tcell.KeyCtrlH: ui.NewSharedKeyAction("ToggleHeader", a.toggleHeaderCmd, false), + ui.KeyT: ui.NewSharedKeyAction("ToggleHeader", a.toggleHeaderCmd, false), ui.KeyHelp: ui.NewSharedKeyAction("Help", a.helpCmd, false), tcell.KeyCtrlA: ui.NewSharedKeyAction("Aliases", a.aliasCmd, false), tcell.KeyEnter: ui.NewKeyAction("Goto", a.gotoCmd, false), From 69bf1ee1518019cca05f99f2829e0228fc07a246 Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 13 Feb 2020 17:41:00 -0700 Subject: [PATCH 33/58] add openfaas support + bugz. Just in time for OpenFezThurday ;) --- assets/k9s_fez.png | Bin 0 -> 231866 bytes change_logs/release_v0.15.0.md | 4 +++- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 assets/k9s_fez.png diff --git a/assets/k9s_fez.png b/assets/k9s_fez.png new file mode 100644 index 0000000000000000000000000000000000000000..078a33dfacddeb241ddd55febee6d93116595a8d GIT binary patch literal 231866 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 F{{h{BHY@-D literal 0 HcmV?d00001 diff --git a/change_logs/release_v0.15.0.md b/change_logs/release_v0.15.0.md index 57c823b3..c40fa60b 100644 --- a/change_logs/release_v0.15.0.md +++ b/change_logs/release_v0.15.0.md @@ -12,7 +12,9 @@ On Slack? Please join us [K9slackers](https://join.slack.com/t/k9sers/shared_inv --- -## Does This FaaS Look Familiar? + + +## Seen This Fez Before? The awesome and ever so smart and creative [Alex Ellis](https://github.com/alexellis) of [OpenFaas Fame](https://www.openfaas.com) fame, had pinged me when I had launched K9s to add support for OpenFaas functions. It's been a long time coming indeed, but we now have a very (VERY!) primitive integration with this very cool framework. From cd4e4a72ab873c0b679ee8c6ccb9098826cebd4b Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 13 Feb 2020 17:49:26 -0700 Subject: [PATCH 34/58] and missed one... --- internal/view/app_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/view/app_test.go b/internal/view/app_test.go index 4ff96086..b1f3476f 100644 --- a/internal/view/app_test.go +++ b/internal/view/app_test.go @@ -12,5 +12,5 @@ func TestAppNew(t *testing.T) { a := view.NewApp(config.NewConfig(ks{})) a.Init("blee", 10) - assert.Equal(t, 11, len(a.GetActions())) + assert.Equal(t, 12, len(a.GetActions())) } From 642303bb724257d80818cb45c7e8ca1c60cbcdf4 Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 13 Feb 2020 17:56:13 -0700 Subject: [PATCH 35/58] cleaning up --- internal/dao/ofaas.go | 7 +++++-- internal/ui/dialog/port_forwards.go | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/internal/dao/ofaas.go b/internal/dao/ofaas.go index 7feb5402..123e702c 100644 --- a/internal/dao/ofaas.go +++ b/internal/dao/ofaas.go @@ -55,7 +55,7 @@ func getOpenFAASFlags() (string, string, bool) { return gw, token, tlsInsecure } -// List returns a collection of functions +// Get returns a function by name. func (f *OpenFaas) Get(ctx context.Context, path string) (runtime.Object, error) { ns, n := client.Namespaced(path) @@ -83,7 +83,7 @@ func (f *OpenFaas) Get(ctx context.Context, path string) (runtime.Object, error) return found, nil } -// List returns a collection of functions +// List returns a collection of functions. func (f *OpenFaas) List(_ context.Context, ns string) ([]runtime.Object, error) { if !IsOpenFaasEnabled() { return nil, errors.New("OpenFAAS is not enabled on this cluster") @@ -103,6 +103,7 @@ func (f *OpenFaas) List(_ context.Context, ns string) ([]runtime.Object, error) return oo, nil } +// Delete removes a function. func (f *OpenFaas) Delete(path string, _, _ bool) error { gw, token, tls := getOpenFAASFlags() ns, n := client.Namespaced(path) @@ -111,10 +112,12 @@ func (f *OpenFaas) Delete(path string, _, _ bool) error { return deleteFunctionToken(gw, n, tls, token, ns) } +// ToYAML dumps a function to yaml. func (f *OpenFaas) ToYAML(path string) (string, error) { return f.Describe(path) } +// Describe describes a function. func (f *OpenFaas) Describe(path string) (string, error) { o, err := f.Get(context.Background(), path) if err != nil { diff --git a/internal/ui/dialog/port_forwards.go b/internal/ui/dialog/port_forwards.go index 279e4524..45871e3b 100644 --- a/internal/ui/dialog/port_forwards.go +++ b/internal/ui/dialog/port_forwards.go @@ -8,6 +8,7 @@ import ( "github.com/derailed/tview" ) +// PortForwardFunc represents a port-forward callback function. type PortForwardFunc func(path, address, lport, cport string) // ShowPortForwards pops a port forwarding configuration dialog. @@ -56,7 +57,7 @@ func ShowPortForwards(p *ui.Pages, s *config.Styles, path string, ports []string p.ShowPage(portForwardKey) } -// DismissPortForward dismiss the port forward dialog. +// DismissPortForwards dismiss the port forward dialog. func DismissPortForwards(p *ui.Pages) { p.RemovePage(portForwardKey) } From a3f19e060d7e68179112e6d988f0e14ef4afe11b Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 13 Feb 2020 19:01:28 -0700 Subject: [PATCH 36/58] and... first openfaas support bug. Meow! --- change_logs/release_v0.15.1.md | 56 ++++++++++++++++++++++++++++++++++ internal/view/ofaas.go | 2 +- 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 change_logs/release_v0.15.1.md diff --git a/change_logs/release_v0.15.1.md b/change_logs/release_v0.15.1.md new file mode 100644 index 00000000..193d9beb --- /dev/null +++ b/change_logs/release_v0.15.1.md @@ -0,0 +1,56 @@ + + +# Release v0.15.1 + +## Notes + +Thank you to all that contributed with flushing out issues and enhancements for K9s! I'll try to mark some of these issues as fixed. But if you don't mind grab the latest rev and see if we're happier with some of the fixes! If you've filed an issue please help me verify and close. Your support, kindness and awesome suggestions to make K9s better is as ever very much noticed and appreciated! + +Also if you dig this tool, please make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer) + +On Slack? Please join us [K9slackers](https://join.slack.com/t/k9sers/shared_invite/enQtOTA5MDEyNzI5MTU0LWQ1ZGI3MzliYzZhZWEyNzYxYzA3NjE0YTk1YmFmNzViZjIyNzhkZGI0MmJjYzhlNjdlMGJhYzE2ZGU1NjkyNTM) + +--- + + + +## OpenFeZ Reloaded? + +🙀With feelings and one less bugZ! + +The awesome and ever so smart and creative [Alex Ellis](https://github.com/alexellis) of [OpenFaas Fame](https://www.openfaas.com) fame, had pinged me when I had launched K9s to add support for OpenFaas functions. It's been a long time coming indeed, but we now have a very (VERY!) primitive integration with this very cool framework. + +The current approach is to enable a few environment variables to tell K9s that you have an OpenFaas cluster available namely: + +```shell +OPENFAAS_GATEWAY=http://YOUR_CLUSTER_IP:31112 +OPENFAAS_TLS_INSECURE=false +OPENFAAS_JWT_TOKEN=YOUR_TOKEN +``` + +These will tell K9s that an OpenFaas gateway is available and exposed on a given nodeport. + +Next you can navigate to your OpenFaas function view by entering command mode `:openfaas` or using aliases `:ofaas` or `ofa` + +If functions are present in the given namespace they will be displayed here just like any other K8s resources. + +The following operations are currently supported: + +* Describe and YAML to view function definitions (Note: currently yields same results!) +* Enter to view all pods instances associated with the selected function +* Delete a function +* Editing, shelling, logs, etc... are all supported by navigating to the underlying pods + +Keep in mind, the paint is way fresh here and this feature could be a complete dud, but figure will give it a rinse on this drop and Alex can pipe in and helps us ironing this out. + +> NOTE! It's been a while since I've played with OpenFaas so if some of you are more versed in this space by all means please do land a hand so we can make this feature more awesome! + +## Moving Forward! + +A few folks had mentioned the eagerness to port-forward directly from a pod or a service. Well now you can! Port Forwarding is now available on both the pod view and services view. Note! at the end of the day, you are still port-fowarding to a container! So the port-forward dialog is a bit different for these views as there might be several container ports available now when looking at this from a pod perspective. So the first field in the dialog is a combo-box that allows one to pick their desired ports. The rest of the dialog works the same as the container port-forward dialog. + +## Resolved Bugs/Features/PRs + +--- + + © 2020 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0) diff --git a/internal/view/ofaas.go b/internal/view/ofaas.go index fa5799c4..00c93a2c 100644 --- a/internal/view/ofaas.go +++ b/internal/view/ofaas.go @@ -33,7 +33,7 @@ func (o *OpenFaas) bindKeys(aa ui.KeyActions) { } func (o *OpenFaas) showPods(a *App, _ ui.Tabular, _, path string) { - labels := o.GetTable().GetSelectedCell(4) + labels := o.GetTable().GetSelectedCell(o.GetTable().NameColIndex() + 3) sels := make(map[string]string) tokens := strings.Split(labels, ",") From 1ef375e78150f2bf7254c3f05435e79a9d8035f2 Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 13 Feb 2020 19:54:15 -0700 Subject: [PATCH 37/58] update docs --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 88700e05..9b88228d 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,7 @@ K9s is available on Linux, macOS and Windows platforms. ## Demo Video +* [K9s v0.15.1](https://youtu.be/7Fx4XQ2ftpM) * [K9s v0.13.0](https://www.youtube.com/watch?v=qaeR2iK7U0o&t=15s) * [K9s v0.9.0](https://www.youtube.com/watch?v=bxKfqumjW4I) * [K9s v0.7.0 Features](https://youtu.be/83jYehwlql8) From 2822ac702ed0a213f8541ca537e436de0aa13b13 Mon Sep 17 00:00:00 2001 From: derailed Date: Fri, 14 Feb 2020 00:57:57 -0700 Subject: [PATCH 38/58] rework portforward + benchmarks --- internal/config/bench.go | 5 +- internal/config/bench_test.go | 2 +- internal/dao/port_forwarder.go | 14 +++- internal/perf/benchmark.go | 2 + internal/ui/dialog/port_forward.go | 65 ------------------- internal/ui/dialog/port_forwards.go | 45 +++++++++++-- ..._forward_test.go => port_forwards_test.go} | 15 +++-- internal/view/benchmark.go | 2 +- internal/view/container.go | 55 ++++++---------- internal/view/pod.go | 60 +++++++++-------- internal/view/port_forward.go | 30 +++++++-- internal/view/svc.go | 29 ++------- internal/watch/forwarders.go | 6 +- 13 files changed, 150 insertions(+), 180 deletions(-) delete mode 100644 internal/ui/dialog/port_forward.go rename internal/ui/dialog/{port_forward_test.go => port_forwards_test.go} (60%) diff --git a/internal/config/bench.go b/internal/config/bench.go index a224f17c..86502c96 100644 --- a/internal/config/bench.go +++ b/internal/config/bench.go @@ -49,11 +49,11 @@ type ( // BenchConfig represents a service benchmark. BenchConfig struct { + Name string C int `yaml:"concurrency"` N int `yaml:"requests"` Auth Auth `yaml:"auth"` HTTP HTTP `yaml:"http"` - Name string } ) @@ -73,7 +73,8 @@ func newBenchmark() Benchmark { } } -func (b Benchmark) empty() bool { +// Empty checks if the benchmark is set +func (b Benchmark) Empty() bool { return b.C == 0 && b.N == 0 } diff --git a/internal/config/bench_test.go b/internal/config/bench_test.go index 77df32fd..36157277 100644 --- a/internal/config/bench_test.go +++ b/internal/config/bench_test.go @@ -19,7 +19,7 @@ func TestBenchEmpty(t *testing.T) { for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { - assert.Equal(t, u.e, u.b.empty()) + assert.Equal(t, u.e, u.b.Empty()) }) } } diff --git a/internal/dao/port_forwarder.go b/internal/dao/port_forwarder.go index 0b31cf19..38d1d8f5 100644 --- a/internal/dao/port_forwarder.go +++ b/internal/dao/port_forwarder.go @@ -23,6 +23,11 @@ import ( const localhost = "localhost" +// Tunnel represents a host tunnel port mapper. +type Tunnel struct { + Address, LocalPort, ContainerPort string +} + // PortForwarder tracks a port forward stream. type PortForwarder struct { client.Connection @@ -88,8 +93,9 @@ func (p *PortForwarder) FQN() string { } // Start initiates a port forward session for a given pod and ports. -func (p *PortForwarder) Start(path, co, address string, ports []string) (*portforward.PortForwarder, error) { - p.path, p.container, p.ports, p.age = path, co, ports, time.Now() +func (p *PortForwarder) Start(path, co string, t Tunnel) (*portforward.PortForwarder, error) { + fwds := []string{t.LocalPort + ":" + t.ContainerPort} + p.path, p.container, p.ports, p.age = path, co, fwds, time.Now() ns, n := client.Namespaced(path) auth, err := p.CanI(ns, "v1/pods", []string{client.GetVerb}) @@ -99,6 +105,8 @@ func (p *PortForwarder) Start(path, co, address string, ports []string) (*portfo if !auth { return nil, fmt.Errorf("user is not authorized to get pods") } + + // BOZO!! Use the factory! pod, err := p.DialOrDie().CoreV1().Pods(ns).Get(n, metav1.GetOptions{}) if err != nil { return nil, err @@ -131,7 +139,7 @@ func (p *PortForwarder) Start(path, co, address string, ports []string) (*portfo Name(n). SubResource("portforward") - return p.forwardPorts("POST", req.URL(), address, ports) + return p.forwardPorts("POST", req.URL(), t.Address, fwds) } func (p *PortForwarder) forwardPorts(method string, url *url.URL, address string, ports []string) (*portforward.PortForwarder, error) { diff --git a/internal/perf/benchmark.go b/internal/perf/benchmark.go index 53dfff8c..cbb669b8 100644 --- a/internal/perf/benchmark.go +++ b/internal/perf/benchmark.go @@ -64,6 +64,8 @@ func (b *Benchmark) init(base, version string) error { } req.Header.Set("User-Agent", ua) + log.Debug().Msgf("Benching %d:%d", b.config.N, b.config.C) + b.worker = &requester.Work{ Request: req, RequestBody: []byte(b.config.HTTP.Body), diff --git a/internal/ui/dialog/port_forward.go b/internal/ui/dialog/port_forward.go deleted file mode 100644 index 52a6cb7d..00000000 --- a/internal/ui/dialog/port_forward.go +++ /dev/null @@ -1,65 +0,0 @@ -package dialog - -import ( - "strings" - - "github.com/derailed/k9s/internal/ui" - "github.com/derailed/tview" - "github.com/gdamore/tcell" -) - -const portForwardKey = "portforward" - -// ShowPortForward pops a port forwarding configuration dialog. -func ShowPortForward(p *ui.Pages, port string, okFn func(address, lport, cport string)) { - f := tview.NewForm() - f.SetItemPadding(0) - f.SetButtonsAlign(tview.AlignCenter). - SetButtonBackgroundColor(tview.Styles.PrimitiveBackgroundColor). - SetButtonTextColor(tview.Styles.PrimaryTextColor). - SetLabelColor(tcell.ColorAqua). - SetFieldTextColor(tcell.ColorOrange) - - p1, p2, address := port, port, "localhost" - f.AddInputField("Pod Port:", p1, 20, nil, func(p string) { - p1 = p - }) - f.AddInputField("Local Port:", p2, 20, nil, func(p string) { - p2 = p - }) - f.AddInputField("Address:", address, 20, nil, func(h string) { - address = h - }) - - f.AddButton("OK", func() { - okFn(address, stripPort(p2), stripPort(p1)) - }) - f.AddButton("Cancel", func() { - DismissPortForward(p) - }) - - modal := tview.NewModalForm("", f) - modal.SetDoneFunc(func(_ int, b string) { - DismissPortForward(p) - }) - p.AddPage(portForwardKey, modal, false, false) - p.ShowPage(portForwardKey) -} - -// DismissPortForward dismiss the port forward dialog. -func DismissPortForward(p *ui.Pages) { - p.RemovePage(portForwardKey) -} - -// ---------------------------------------------------------------------------- -// Helpers... - -// StripPort removes the named port id if present. -func stripPort(p string) string { - tokens := strings.Split(p, ":") - if len(tokens) == 2 { - return strings.Replace(tokens[1], "╱UDP", "", 1) - } - - return p -} diff --git a/internal/ui/dialog/port_forwards.go b/internal/ui/dialog/port_forwards.go index 45871e3b..fbfc6ded 100644 --- a/internal/ui/dialog/port_forwards.go +++ b/internal/ui/dialog/port_forwards.go @@ -2,14 +2,19 @@ package dialog import ( "fmt" + "strings" + "github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/config" + "github.com/derailed/k9s/internal/dao" "github.com/derailed/k9s/internal/ui" "github.com/derailed/tview" ) +const portForwardKey = "portforward" + // PortForwardFunc represents a port-forward callback function. -type PortForwardFunc func(path, address, lport, cport string) +type PortForwardFunc func(path, co string, mapper dao.Tunnel) // ShowPortForwards pops a port forwarding configuration dialog. func ShowPortForwards(p *ui.Pages, s *config.Styles, path string, ports []string, okFn PortForwardFunc) { @@ -23,7 +28,7 @@ func ShowPortForwards(p *ui.Pages, s *config.Styles, path string, ports []string p1, p2, address := ports[0], ports[0], "localhost" f.AddDropDown("Container Ports", ports, 0, func(sel string, _ int) { - p1, p2 = sel, stripPort(sel) + p1, p2 = sel, extractPort(sel) }) dropD, ok := f.GetFormItem(0).(*tview.DropDown) @@ -43,15 +48,20 @@ func ShowPortForwards(p *ui.Pages, s *config.Styles, path string, ports []string }) f.AddButton("OK", func() { - okFn(path, address, stripPort(p2), stripPort(p1)) + tunnel := dao.Tunnel{ + Address: address, + LocalPort: p2, + ContainerPort: extractPort(p1), + } + okFn(path, extractContainer(p1), tunnel) }) f.AddButton("Cancel", func() { - DismissPortForward(p) + DismissPortForwards(p) }) modal := tview.NewModalForm(fmt.Sprintf("", path), f) modal.SetDoneFunc(func(_ int, b string) { - DismissPortForward(p) + DismissPortForwards(p) }) p.AddPage(portForwardKey, modal, false, false) p.ShowPage(portForwardKey) @@ -61,3 +71,28 @@ func ShowPortForwards(p *ui.Pages, s *config.Styles, path string, ports []string func DismissPortForwards(p *ui.Pages) { p.RemovePage(portForwardKey) } + +// ---------------------------------------------------------------------------- +// Helpers... + +func extractPort(p string) string { + tokens := strings.Split(p, ":") + switch { + case len(tokens) < 2: + return tokens[0] + case len(tokens) == 2: + return strings.Replace(tokens[1], "╱UDP", "", 1) + default: + return tokens[1] + } +} + +func extractContainer(p string) string { + tokens := strings.Split(p, ":") + if len(tokens) != 2 { + return "n/a" + } + + co, _ := client.Namespaced(tokens[0]) + return co +} diff --git a/internal/ui/dialog/port_forward_test.go b/internal/ui/dialog/port_forwards_test.go similarity index 60% rename from internal/ui/dialog/port_forward_test.go rename to internal/ui/dialog/port_forwards_test.go index 1c2461e1..6ecb876f 100644 --- a/internal/ui/dialog/port_forward_test.go +++ b/internal/ui/dialog/port_forwards_test.go @@ -3,26 +3,27 @@ package dialog import ( "testing" + "github.com/derailed/k9s/internal/config" + "github.com/derailed/k9s/internal/dao" "github.com/derailed/k9s/internal/ui" "github.com/derailed/tview" "github.com/stretchr/testify/assert" ) -func TestPortForwardDialog(t *testing.T) { +func TestPortForwards(t *testing.T) { p := ui.NewPages() - okFunc := func(address, lport, cport string) { - } - ShowPortForward(p, "8080", okFunc) + cbFunc := func(path, co string, t dao.Tunnel) {} + ShowPortForwards(p, config.NewStyles(), "fred", []string{"8080"}, cbFunc) d := p.GetPrimitive(portForwardKey).(*tview.ModalForm) assert.NotNil(t, d) - DismissPortForward(p) + DismissPortForwards(p) assert.Nil(t, p.GetPrimitive(portForwardKey)) } -func TestStripPort(t *testing.T) { +func TestExtractPort(t *testing.T) { uu := map[string]struct { port, e string }{ @@ -40,7 +41,7 @@ func TestStripPort(t *testing.T) { for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { - assert.Equal(t, u.e, stripPort(u.port)) + assert.Equal(t, u.e, extractPort(u.port)) }) } } diff --git a/internal/view/benchmark.go b/internal/view/benchmark.go index 7fdc78f2..059c3703 100644 --- a/internal/view/benchmark.go +++ b/internal/view/benchmark.go @@ -46,7 +46,7 @@ func (b *Benchmark) viewBench(app *App, model ui.Tabular, gvr, path string) { return } - details := NewDetails(b.App(), "Benchmark", fileToSubject(path), false).Update(data) + details := NewDetails(b.App(), "Results", fileToSubject(path), false).Update(data) if err := app.inject(details); err != nil { app.Flash().Err(err) } diff --git a/internal/view/container.go b/internal/view/container.go index 724801eb..941b2889 100644 --- a/internal/view/container.go +++ b/internal/view/container.go @@ -103,6 +103,7 @@ func (c *Container) portFwdCmd(evt *tcell.EventKey) *tcell.EventKey { return evt } + log.Debug().Msgf("CONTAINER-SEL %q", path) if _, ok := c.App().factory.ForwarderFor(fwFQN(c.GetTable().Path, path)); ok { c.App().Flash().Err(fmt.Errorf("A PortForward already exist on container %s", c.GetTable().Path)) return nil @@ -112,12 +113,24 @@ func (c *Container) portFwdCmd(evt *tcell.EventKey) *tcell.EventKey { if !ok { return nil } - - dialog.ShowPortForward(c.App().Content.Pages, c.preparePort(ports), c.portForward) + log.Debug().Msgf("CONTAINER-PORTS %#v", ports) + dialog.ShowPortForwards(c.App().Content.Pages, c.App().Styles, c.GetTable().Path, ports, c.portForward) return nil } +func (c *Container) portForward(path, co string, t dao.Tunnel) { + pf := dao.NewPortForwarder(c.App().Conn()) + fw, err := pf.Start(path, co, t) + if err != nil { + c.App().Flash().Err(err) + return + } + + log.Debug().Msgf(">>> Starting port forward %q %#v", path, t) + go runForward(c.App(), pf, fw) +} + func (c *Container) isForwardable(path string) ([]string, bool) { state := c.GetTable().GetSelectedCell(3) if state != "Running" { @@ -132,43 +145,15 @@ func (c *Container) isForwardable(path string) ([]string, bool) { return nil, false } - return ports, true -} - -func (c *Container) preparePort(pp []string) string { - var port string - for _, p := range pp { + pp := make([]string, 0, len(ports)) + for _, p := range ports { if !isTCPPort(p) { continue } - port = strings.TrimSpace(p) - tokens := strings.Split(port, ":") - if len(tokens) == 2 { - port = tokens[1] - } - break - } - if port == "" { - c.App().Flash().Warn("No valid TCP port found on this container. User will specify...") - return "MY_TCP_PORT!" + pp = append(pp, path+"/"+p) } - return port -} - -func (c *Container) portForward(address, lport, cport string) { - co := c.GetTable().GetSelectedCell(0) - pf := dao.NewPortForwarder(c.App().Conn()) - path := c.GetTable().GetSelectedItem() - ports := []string{lport + ":" + cport} - fw, err := pf.Start(path, co, address, ports) - if err != nil { - c.App().Flash().Err(err) - return - } - - log.Debug().Msgf(">>> Starting port forward %q %v", path, ports) - go runForward(c.App(), pf, fw) + return pp, true } // ---------------------------------------------------------------------------- @@ -178,7 +163,7 @@ func runForward(a *App, pf *dao.PortForwarder, f *portforward.PortForwarder) { a.QueueUpdateDraw(func() { a.factory.AddForwarder(pf) a.Flash().Infof("PortForward activated %s:%s", pf.Path(), pf.Ports()[0]) - dialog.DismissPortForward(a.Content.Pages) + dialog.DismissPortForwards(a.Content.Pages) }) pf.SetActive(true) diff --git a/internal/view/pod.go b/internal/view/pod.go index 0a79b7c7..413c18d5 100644 --- a/internal/view/pod.go +++ b/internal/view/pod.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "strconv" "github.com/derailed/k9s/internal" "github.com/derailed/k9s/internal/client" @@ -135,48 +136,51 @@ func (p *Pod) portFwdCmd(evt *tcell.EventKey) *tcell.EventKey { return evt } - pp, err := fetchPodPorts(p.App().factory, path) - if err != nil { + if err := showFwdDialog(p.App(), path, p.portForward); err != nil { p.App().Flash().Err(err) - return nil } - ports := make([]string, 0, len(pp)) - for _, p := range pp { - if p.Protocol == v1.ProtocolTCP { - port := fmt.Sprintf("%s:%d", p.Name, p.ContainerPort) - if p.Name == "" { - port = fmt.Sprintf("%d", p.ContainerPort) - } - ports = append(ports, port) - } - } - - if len(ports) == 0 { - p.App().Flash().Err(fmt.Errorf("no tcp ports found on %s", path)) - return nil - } - - dialog.ShowPortForwards(p.App().Content.Pages, p.App().Styles, path, ports, p.portForward) return nil } -func (p *Pod) portForward(path, address, lport, cport string) { +func (p *Pod) portForward(path, co string, t dao.Tunnel) { pf := dao.NewPortForwarder(p.App().Conn()) - ports := []string{lport + ":" + cport} - fw, err := pf.Start(path, "", address, ports) + fw, err := pf.Start(path, co, t) if err != nil { p.App().Flash().Err(err) return } - log.Debug().Msgf(">>> Starting port forward %q %v", path, ports) + log.Debug().Msgf(">>> Starting port forward %q:%s %v", path, co, t) go runForward(p.App(), pf, fw) } // ---------------------------------------------------------------------------- // Helpers... +func showFwdDialog(a *App, path string, cb dialog.PortForwardFunc) error { + mm, err := fetchPodPorts(a.factory, path) + if err != nil { + return nil + } + ports := make([]string, 0, len(mm)) + for co, pp := range mm { + for _, p := range pp { + if p.Protocol != v1.ProtocolTCP { + continue + } + ports = append(ports, client.FQN(co, p.Name)+":"+strconv.Itoa(int(p.ContainerPort))) + } + } + + if len(ports) == 0 { + return fmt.Errorf("no tcp ports found on %s", path) + } + dialog.ShowPortForwards(a.Content.Pages, a.Styles, path, ports, cb) + + return nil +} + func containerShellin(a *App, comp model.Component, path, co string) error { if co != "" { resumeShellIn(a, comp, path, co) @@ -262,7 +266,7 @@ func fetchContainers(f *watch.Factory, path string, includeInit bool) ([]string, return nn, nil } -func fetchPodPorts(f *watch.Factory, path string) ([]v1.ContainerPort, error) { +func fetchPodPorts(f *watch.Factory, path string) (map[string][]v1.ContainerPort, error) { log.Debug().Msgf("Fetching ports on pod %q", path) o, err := f.Get("v1/pods", path, false, labels.Everything()) if err != nil { @@ -275,9 +279,9 @@ func fetchPodPorts(f *watch.Factory, path string) ([]v1.ContainerPort, error) { return nil, err } - pp := make([]v1.ContainerPort, 0, len(pod.Spec.Containers)) - for _, c := range pod.Spec.Containers { - pp = append(pp, c.Ports...) + pp := make(map[string][]v1.ContainerPort) + for _, co := range pod.Spec.Containers { + pp[co.Name] = co.Ports } return pp, nil diff --git a/internal/view/port_forward.go b/internal/view/port_forward.go index 551e2558..b31e7c84 100644 --- a/internal/view/port_forward.go +++ b/internal/view/port_forward.go @@ -3,6 +3,8 @@ package view import ( "context" "fmt" + "regexp" + "strings" "time" "github.com/derailed/k9s/internal" @@ -63,6 +65,8 @@ func (p *PortForward) showBenchCmd(evt *tcell.EventKey) *tcell.EventKey { return nil } +var podNameRX = regexp.MustCompile(`\A(.+)\-(\w{10})\-(\w{5})\z`) + func (p *PortForward) toggleBenchCmd(evt *tcell.EventKey) *tcell.EventKey { if p.bench != nil { p.App().Status(ui.FlashErr, "Benchmark Canceled!") @@ -71,18 +75,34 @@ func (p *PortForward) toggleBenchCmd(evt *tcell.EventKey) *tcell.EventKey { return nil } - sel := p.GetTable().GetSelectedItem() - if sel == "" { + path := p.GetTable().GetSelectedItem() + if path == "" { return nil } + tokens := strings.Split(path, ":") + ns, po := client.Namespaced(tokens[0]) + sections := podNameRX.FindStringSubmatch(po) + log.Debug().Msgf("SECTIONS %q::%q--%#v", ns, po, sections) + if len(sections) >= 1 { + po = sections[1] + } + key := client.FQN(ns, po) + ":" + tokens[1] - r, _ := p.GetTable().GetSelection() cfg := defaultConfig() - if b, ok := p.App().Bench.Benchmarks.Containers[sel]; ok { + if defaults := p.App().Bench.Benchmarks.Defaults; !defaults.Empty() { + cfg.C, cfg.N = defaults.C, defaults.N + } + + log.Debug().Msgf("CUST-CFG %q -- %#v", path, key) + if b, ok := p.App().Bench.Benchmarks.Containers[key]; ok { + log.Debug().Msgf("FOUND CUST BENCH_CFG!") cfg = b } - cfg.Name = sel + cfg.Name = path + log.Debug().Msgf("BenchCFG %q::%#v", path, cfg) + + r, _ := p.GetTable().GetSelection() base := ui.TrimCell(p.GetTable().SelectTable, r, 4) var err error if p.bench, err = perf.NewBenchmark(base, p.App().version, cfg); err != nil { diff --git a/internal/view/svc.go b/internal/view/svc.go index 0a5aff0b..b8270991 100644 --- a/internal/view/svc.go +++ b/internal/view/svc.go @@ -11,7 +11,6 @@ import ( "github.com/derailed/k9s/internal/dao" "github.com/derailed/k9s/internal/perf" "github.com/derailed/k9s/internal/ui" - "github.com/derailed/k9s/internal/ui/dialog" "github.com/gdamore/tcell" "github.com/rs/zerolog/log" v1 "k8s.io/api/core/v1" @@ -87,42 +86,22 @@ func (s *Service) portFwdCmd(evt *tcell.EventKey) *tcell.EventKey { return nil } - pp, err := fetchPodPorts(s.App().factory, pod) - if err != nil { + if err := showFwdDialog(s.App(), pod, s.portForward); err != nil { s.App().Flash().Err(err) - return nil } - ports := make([]string, 0, len(pp)) - for _, p := range pp { - if p.Protocol == v1.ProtocolTCP { - port := fmt.Sprintf("%s:%d", p.Name, p.ContainerPort) - if p.Name == "" { - port = fmt.Sprintf("%d", p.ContainerPort) - } - ports = append(ports, port) - } - } - - if len(ports) == 0 { - s.App().Flash().Err(fmt.Errorf("no tcp ports found on %s", path)) - return nil - } - - dialog.ShowPortForwards(s.App().Content.Pages, s.App().Styles, pod, ports, s.portForward) return nil } -func (s *Service) portForward(path, address, lport, cport string) { +func (s *Service) portForward(path, co string, t dao.Tunnel) { pf := dao.NewPortForwarder(s.App().Conn()) - ports := []string{lport + ":" + cport} - fw, err := pf.Start(path, "", address, ports) + fw, err := pf.Start(path, co, t) if err != nil { s.App().Flash().Err(err) return } - log.Debug().Msgf(">>> Starting port forward %q %v", path, ports) + log.Debug().Msgf(">>> Starting port forward %q %#v", path, t) go runForward(s.App(), pf, fw) } diff --git a/internal/watch/forwarders.go b/internal/watch/forwarders.go index aa53cc1b..60464f32 100644 --- a/internal/watch/forwarders.go +++ b/internal/watch/forwarders.go @@ -4,13 +4,13 @@ import ( "strings" "github.com/rs/zerolog/log" - "k8s.io/client-go/tools/portforward" ) // Forwarder represents a port forwarder. type Forwarder interface { - // Start initializes a port forward. - Start(path, co, address string, ports []string) (*portforward.PortForwarder, error) + // BOZO!! + // // Start initializes a port forward. + // Start(path, co, string, t dao.Tunnel) (*portforward.PortForwarder, error) // Stop terminates a port forward. Stop() From 7a977f31c77bdc4628eb348ade8c20084544c937 Mon Sep 17 00:00:00 2001 From: derailed Date: Fri, 14 Feb 2020 14:28:52 -0700 Subject: [PATCH 39/58] refactor pf and benchmarks --- go.mod | 1 + go.sum | 4 + internal/client/config_test.go | 30 ++-- internal/client/{assets => testdata}/config | 0 internal/client/{assets => testdata}/config.1 | 0 internal/client/tunnel.go | 11 ++ internal/config/alias_test.go | 2 +- internal/config/bench.go | 12 ++ internal/config/bench_test.go | 14 +- internal/config/config_test.go | 26 +-- internal/config/hotkey_test.go | 2 +- internal/config/k9s_test.go | 2 +- internal/config/plugin_test.go | 2 +- internal/config/styles_test.go | 8 +- .../{test_assets => testdata}/alias.yml | 0 .../b_containers.yml | 0 .../b_containers_1.yml | 0 .../{test_assets => testdata}/b_good.yml | 0 .../{test_assets => testdata}/b_toast.yml | 0 .../{test_assets => testdata}/bench-fred.yml | 0 .../black_and_wtf.yml | 0 .../{test_assets => testdata}/empty_skin.yml | 0 .../{test_assets => testdata}/hot_key.yml | 0 .../config/{test_assets => testdata}/k8s.yml | 0 .../config/{test_assets => testdata}/k9s.yml | 0 .../config/{test_assets => testdata}/k9s1.yml | 0 .../{test_assets => testdata}/k9s_old.yml | 0 .../{test_assets => testdata}/k9s_toast.yml | 0 .../kubeconfig-test.yml | 0 .../{test_assets => testdata}/plugin.yml | 0 .../skin_boarked.yml | 0 internal/dao/benchmark_test.go | 4 +- internal/dao/cruiser_test.go | 2 +- internal/dao/dp.go | 46 ++++-- internal/dao/ds.go | 52 +++--- internal/dao/pod.go | 36 ++-- internal/dao/port_forward.go | 50 ++++-- internal/dao/port_forward_test.go | 33 ++++ internal/dao/port_forwarder.go | 49 +++--- internal/dao/registry_test.go | 2 +- internal/dao/sts.go | 45 +++-- internal/dao/svc.go | 62 ++++++- .../default_fred_1577308050814961000.txt | 0 internal/dao/testdata/benchspec.yml | 19 +++ internal/dao/{assets => testdata}/config | 0 internal/dao/{assets => testdata}/config.1 | 0 .../dao/{test_assets => testdata}/crb.json | 0 internal/dao/{assets => testdata}/dr.json | 0 .../dao/{test_assets => testdata}/n1.json | 0 .../dao/{test_assets => testdata}/p1.json | 0 internal/dao/types.go | 6 + internal/model/table_int_test.go | 12 +- internal/model/table_test.go | 2 +- .../model/{test_assets => testdata}/p1.json | 0 internal/render/benchmark_int_test.go | 8 +- internal/render/render_test.go | 2 +- internal/render/{assets => testdata}/b1.txt | 0 internal/render/{assets => testdata}/b2.txt | 0 internal/render/{assets => testdata}/b3.txt | 0 internal/render/{assets => testdata}/b4.txt | 0 internal/render/{assets => testdata}/cj.json | 0 internal/render/{assets => testdata}/cm.json | 0 internal/render/{assets => testdata}/cr.json | 0 internal/render/{assets => testdata}/crb.json | 0 internal/render/{assets => testdata}/crd.json | 0 internal/render/{assets => testdata}/dp.json | 0 internal/render/{assets => testdata}/ds.json | 0 internal/render/{assets => testdata}/ep.json | 0 internal/render/{assets => testdata}/ev.json | 0 internal/render/{assets => testdata}/hpa.json | 0 internal/render/{assets => testdata}/ing.json | 0 internal/render/{assets => testdata}/job.json | 0 internal/render/{assets => testdata}/no.json | 0 internal/render/{assets => testdata}/np.json | 0 internal/render/{assets => testdata}/ns.json | 0 internal/render/{assets => testdata}/pdb.json | 0 internal/render/{assets => testdata}/po.json | 0 .../render/{assets => testdata}/po_init.json | 0 internal/render/{assets => testdata}/pv.json | 0 internal/render/{assets => testdata}/pvc.json | 0 internal/render/{assets => testdata}/rb.json | 0 internal/render/{assets => testdata}/ro.json | 0 internal/render/{assets => testdata}/rs.json | 0 internal/render/{assets => testdata}/sa.json | 0 internal/render/{assets => testdata}/sc.json | 0 internal/render/{assets => testdata}/sec.json | 0 internal/render/{assets => testdata}/sts.json | 0 internal/render/{assets => testdata}/svc.json | 0 internal/ui/config.go | 22 +-- internal/ui/config_test.go | 14 +- internal/ui/dialog/port_forwards_test.go | 47 ------ internal/ui/menu.go | 2 +- internal/view/app.go | 3 +- internal/view/browser.go | 1 - internal/view/container.go | 38 +---- internal/view/dp.go | 28 ++-- internal/view/dp_test.go | 3 +- internal/view/ds.go | 21 +-- internal/view/ds_test.go | 2 +- internal/view/help.go | 4 +- .../port_forwards.go => view/pf_dialog.go} | 42 ++--- internal/view/pf_dialog_test.go | 30 ++++ internal/view/pf_extender.go | 155 ++++++++++++++++++ internal/view/pod.go | 79 +-------- internal/view/port_forward.go | 47 +----- internal/view/sts.go | 8 +- internal/view/sts_test.go | 2 +- internal/view/svc.go | 107 ++---------- internal/view/types.go | 2 + internal/watch/factory.go | 6 + internal/watch/forwarders.go | 16 +- 111 files changed, 683 insertions(+), 540 deletions(-) rename internal/client/{assets => testdata}/config (100%) rename internal/client/{assets => testdata}/config.1 (100%) create mode 100644 internal/client/tunnel.go rename internal/config/{test_assets => testdata}/alias.yml (100%) rename internal/config/{test_assets => testdata}/b_containers.yml (100%) rename internal/config/{test_assets => testdata}/b_containers_1.yml (100%) rename internal/config/{test_assets => testdata}/b_good.yml (100%) rename internal/config/{test_assets => testdata}/b_toast.yml (100%) rename internal/config/{test_assets => testdata}/bench-fred.yml (100%) rename internal/config/{test_assets => testdata}/black_and_wtf.yml (100%) rename internal/config/{test_assets => testdata}/empty_skin.yml (100%) rename internal/config/{test_assets => testdata}/hot_key.yml (100%) rename internal/config/{test_assets => testdata}/k8s.yml (100%) rename internal/config/{test_assets => testdata}/k9s.yml (100%) rename internal/config/{test_assets => testdata}/k9s1.yml (100%) rename internal/config/{test_assets => testdata}/k9s_old.yml (100%) rename internal/config/{test_assets => testdata}/k9s_toast.yml (100%) rename internal/config/{test_assets => testdata}/kubeconfig-test.yml (100%) rename internal/config/{test_assets => testdata}/plugin.yml (100%) rename internal/config/{test_assets => testdata}/skin_boarked.yml (100%) create mode 100644 internal/dao/port_forward_test.go rename internal/dao/{test_assets => testdata}/bench/default_fred_1577308050814961000.txt (100%) create mode 100644 internal/dao/testdata/benchspec.yml rename internal/dao/{assets => testdata}/config (100%) rename internal/dao/{assets => testdata}/config.1 (100%) rename internal/dao/{test_assets => testdata}/crb.json (100%) rename internal/dao/{assets => testdata}/dr.json (100%) rename internal/dao/{test_assets => testdata}/n1.json (100%) rename internal/dao/{test_assets => testdata}/p1.json (100%) rename internal/model/{test_assets => testdata}/p1.json (100%) rename internal/render/{assets => testdata}/b1.txt (100%) rename internal/render/{assets => testdata}/b2.txt (100%) rename internal/render/{assets => testdata}/b3.txt (100%) rename internal/render/{assets => testdata}/b4.txt (100%) rename internal/render/{assets => testdata}/cj.json (100%) rename internal/render/{assets => testdata}/cm.json (100%) rename internal/render/{assets => testdata}/cr.json (100%) rename internal/render/{assets => testdata}/crb.json (100%) rename internal/render/{assets => testdata}/crd.json (100%) rename internal/render/{assets => testdata}/dp.json (100%) rename internal/render/{assets => testdata}/ds.json (100%) rename internal/render/{assets => testdata}/ep.json (100%) rename internal/render/{assets => testdata}/ev.json (100%) rename internal/render/{assets => testdata}/hpa.json (100%) rename internal/render/{assets => testdata}/ing.json (100%) rename internal/render/{assets => testdata}/job.json (100%) rename internal/render/{assets => testdata}/no.json (100%) rename internal/render/{assets => testdata}/np.json (100%) rename internal/render/{assets => testdata}/ns.json (100%) rename internal/render/{assets => testdata}/pdb.json (100%) rename internal/render/{assets => testdata}/po.json (100%) rename internal/render/{assets => testdata}/po_init.json (100%) rename internal/render/{assets => testdata}/pv.json (100%) rename internal/render/{assets => testdata}/pvc.json (100%) rename internal/render/{assets => testdata}/rb.json (100%) rename internal/render/{assets => testdata}/ro.json (100%) rename internal/render/{assets => testdata}/rs.json (100%) rename internal/render/{assets => testdata}/sa.json (100%) rename internal/render/{assets => testdata}/sc.json (100%) rename internal/render/{assets => testdata}/sec.json (100%) rename internal/render/{assets => testdata}/sts.json (100%) rename internal/render/{assets => testdata}/svc.json (100%) delete mode 100644 internal/ui/dialog/port_forwards_test.go rename internal/{ui/dialog/port_forwards.go => view/pf_dialog.go} (64%) create mode 100644 internal/view/pf_dialog_test.go create mode 100644 internal/view/pf_extender.go diff --git a/go.mod b/go.mod index 1fb59774..d6e03b95 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,7 @@ replace ( require ( fyne.io/fyne v1.2.2 // indirect + github.com/GeertJohan/gomatrix v0.0.0-20190924221747-74328b69a02f // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/alexellis/go-execute v0.0.0-20200124154445-8697e4e28c5e // indirect github.com/alexellis/hmac v0.0.0-20180624211220-5c52ab81c0de // indirect diff --git a/go.sum b/go.sum index 34dddd58..c28d347a 100644 --- a/go.sum +++ b/go.sum @@ -29,6 +29,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/GeertJohan/gomatrix v0.0.0-20190924221747-74328b69a02f h1:O4XncXE6+qNjZIvermf2/Z4esEl8K1zFVPbl3l14mjM= +github.com/GeertJohan/gomatrix v0.0.0-20190924221747-74328b69a02f/go.mod h1:HqtsgfzGADJzbZ+MbYAJ+PJnxIxBwBvYjyqd2wWw0j0= github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14= github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5hodBMJ5+l/7J4xAyMeuM2PNuepvHlGs8yilUCA= github.com/Kodeworks/golang-image-ico v0.0.0-20141118225523-73f0f4cfade9/go.mod h1:7uhhqiBaR4CpN0k9rMjOtjpcfGd6DG2m04zQxKnWQ0I= @@ -389,6 +391,8 @@ github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jackmordaunt/icns v0.0.0-20181231085925-4f16af745526/go.mod h1:UQkeMHVoNcyXYq9otUupF7/h/2tmHlhrS2zw7ZVvUqc= +github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jimstudt/http-authentication v0.0.0-20140401203705-3eca13d6893a/go.mod h1:wK6yTYYcgjHE1Z1QtXACPDjcFJyBskHEdagmnq3vsP8= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/internal/client/config_test.go b/internal/client/config_test.go index 19a95703..46137574 100644 --- a/internal/client/config_test.go +++ b/internal/client/config_test.go @@ -18,7 +18,7 @@ func init() { } func TestConfigCurrentContext(t *testing.T) { - name, kubeConfig := "blee", "./assets/config" + name, kubeConfig := "blee", "./testdata/config" uu := []struct { flags *genericclioptions.ConfigFlags context string @@ -36,7 +36,7 @@ func TestConfigCurrentContext(t *testing.T) { } func TestConfigCurrentCluster(t *testing.T) { - name, kubeConfig := "blee", "./assets/config" + name, kubeConfig := "blee", "./testdata/config" uu := []struct { flags *genericclioptions.ConfigFlags cluster string @@ -54,7 +54,7 @@ func TestConfigCurrentCluster(t *testing.T) { } func TestConfigCurrentUser(t *testing.T) { - name, kubeConfig := "blee", "./assets/config" + name, kubeConfig := "blee", "./testdata/config" uu := []struct { flags *genericclioptions.ConfigFlags user string @@ -72,7 +72,7 @@ func TestConfigCurrentUser(t *testing.T) { } func TestConfigCurrentNamespace(t *testing.T) { - name, kubeConfig := "blee", "./assets/config" + name, kubeConfig := "blee", "./testdata/config" uu := []struct { flags *genericclioptions.ConfigFlags namespace string @@ -91,7 +91,7 @@ func TestConfigCurrentNamespace(t *testing.T) { } func TestConfigGetContext(t *testing.T) { - kubeConfig := "./assets/config" + kubeConfig := "./testdata/config" uu := []struct { flags *genericclioptions.ConfigFlags cluster string @@ -114,7 +114,7 @@ func TestConfigGetContext(t *testing.T) { } func TestConfigSwitchContext(t *testing.T) { - cluster, kubeConfig := "duh", "./assets/config" + cluster, kubeConfig := "duh", "./testdata/config" flags := genericclioptions.ConfigFlags{ KubeConfig: &kubeConfig, ClusterName: &cluster, @@ -129,7 +129,7 @@ func TestConfigSwitchContext(t *testing.T) { } func TestConfigClusterNameFromContext(t *testing.T) { - cluster, kubeConfig := "duh", "./assets/config" + cluster, kubeConfig := "duh", "./testdata/config" flags := genericclioptions.ConfigFlags{ KubeConfig: &kubeConfig, ClusterName: &cluster, @@ -142,7 +142,7 @@ func TestConfigClusterNameFromContext(t *testing.T) { } func TestConfigAccess(t *testing.T) { - cluster, kubeConfig := "duh", "./assets/config" + cluster, kubeConfig := "duh", "./testdata/config" flags := genericclioptions.ConfigFlags{ KubeConfig: &kubeConfig, ClusterName: &cluster, @@ -155,7 +155,7 @@ func TestConfigAccess(t *testing.T) { } func TestConfigContexts(t *testing.T) { - cluster, kubeConfig := "duh", "./assets/config" + cluster, kubeConfig := "duh", "./testdata/config" flags := genericclioptions.ConfigFlags{ KubeConfig: &kubeConfig, ClusterName: &cluster, @@ -168,7 +168,7 @@ func TestConfigContexts(t *testing.T) { } func TestConfigContextNames(t *testing.T) { - cluster, kubeConfig := "duh", "./assets/config" + cluster, kubeConfig := "duh", "./testdata/config" flags := genericclioptions.ConfigFlags{ KubeConfig: &kubeConfig, ClusterName: &cluster, @@ -181,7 +181,7 @@ func TestConfigContextNames(t *testing.T) { } func TestConfigClusterNames(t *testing.T) { - cluster, kubeConfig := "duh", "./assets/config" + cluster, kubeConfig := "duh", "./testdata/config" flags := genericclioptions.ConfigFlags{ KubeConfig: &kubeConfig, ClusterName: &cluster, @@ -194,7 +194,7 @@ func TestConfigClusterNames(t *testing.T) { } func TestConfigDelContext(t *testing.T) { - cluster, kubeConfig := "duh", "./assets/config.1" + cluster, kubeConfig := "duh", "./testdata/config.1" flags := genericclioptions.ConfigFlags{ KubeConfig: &kubeConfig, ClusterName: &cluster, @@ -209,7 +209,7 @@ func TestConfigDelContext(t *testing.T) { } func TestConfigRestConfig(t *testing.T) { - kubeConfig := "./assets/config" + kubeConfig := "./testdata/config" flags := genericclioptions.ConfigFlags{ KubeConfig: &kubeConfig, } @@ -221,7 +221,7 @@ func TestConfigRestConfig(t *testing.T) { } func TestConfigBadConfig(t *testing.T) { - kubeConfig := "./assets/bork_config" + kubeConfig := "./testdata/bork_config" flags := genericclioptions.ConfigFlags{ KubeConfig: &kubeConfig, } @@ -232,7 +232,7 @@ func TestConfigBadConfig(t *testing.T) { } func TestNamespaceNames(t *testing.T) { - kubeConfig := "./assets/config" + kubeConfig := "./testdata/config" flags := genericclioptions.ConfigFlags{ KubeConfig: &kubeConfig, diff --git a/internal/client/assets/config b/internal/client/testdata/config similarity index 100% rename from internal/client/assets/config rename to internal/client/testdata/config diff --git a/internal/client/assets/config.1 b/internal/client/testdata/config.1 similarity index 100% rename from internal/client/assets/config.1 rename to internal/client/testdata/config.1 diff --git a/internal/client/tunnel.go b/internal/client/tunnel.go new file mode 100644 index 00000000..2eba5a37 --- /dev/null +++ b/internal/client/tunnel.go @@ -0,0 +1,11 @@ +package client + +// PortTunnel represents a host tunnel port mapper. +type PortTunnel struct { + Address, LocalPort, ContainerPort string +} + +// PortMap returns a port mapping. +func (t PortTunnel) PortMap() string { + return t.LocalPort + ":" + t.ContainerPort +} diff --git a/internal/config/alias_test.go b/internal/config/alias_test.go index 80416d70..49e3c445 100644 --- a/internal/config/alias_test.go +++ b/internal/config/alias_test.go @@ -72,7 +72,7 @@ func TestAliasDefine(t *testing.T) { func TestAliasesLoad(t *testing.T) { a := config.NewAliases() - assert.Nil(t, a.LoadAliases("test_assets/alias.yml")) + assert.Nil(t, a.LoadAliases("testdata/alias.yml")) assert.Equal(t, 2, len(a.Alias)) } diff --git a/internal/config/bench.go b/internal/config/bench.go index 86502c96..f3e0a149 100644 --- a/internal/config/bench.go +++ b/internal/config/bench.go @@ -105,3 +105,15 @@ func (s *Bench) load(path string) error { return yaml.Unmarshal(f, &s) } + +// DefaultBenchSpec returns a default bench spec. +func DefaultBenchSpec() BenchConfig { + return BenchConfig{ + C: DefaultC, + N: DefaultN, + HTTP: HTTP{ + Method: DefaultMethod, + Path: "/", + }, + } +} diff --git a/internal/config/bench_test.go b/internal/config/bench_test.go index 36157277..fd6e4d97 100644 --- a/internal/config/bench_test.go +++ b/internal/config/bench_test.go @@ -32,14 +32,14 @@ func TestBenchLoad(t *testing.T) { coCount int }{ "goodConfig": { - "test_assets/b_good.yml", + "testdata/b_good.yml", 2, 1000, 2, 0, }, "malformed": { - "test_assets/b_toast.yml", + "testdata/b_toast.yml", 1, 200, 0, @@ -100,7 +100,7 @@ func TestBenchServiceLoad(t *testing.T) { for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { - b, err := NewBench("test_assets/b_good.yml") + b, err := NewBench("testdata/b_good.yml") assert.Nil(t, err) assert.Equal(t, 2, len(b.Benchmarks.Services)) @@ -119,16 +119,16 @@ func TestBenchServiceLoad(t *testing.T) { } func TestBenchReLoad(t *testing.T) { - b, err := NewBench("test_assets/b_containers.yml") + b, err := NewBench("testdata/b_containers.yml") assert.Nil(t, err) assert.Equal(t, 2, b.Benchmarks.Defaults.C) - assert.Nil(t, b.Reload("test_assets/b_containers_1.yml")) + assert.Nil(t, b.Reload("testdata/b_containers_1.yml")) assert.Equal(t, 20, b.Benchmarks.Defaults.C) } func TestBenchLoadToast(t *testing.T) { - _, err := NewBench("test_assets/toast.yml") + _, err := NewBench("testdata/toast.yml") assert.NotNil(t, err) } @@ -171,7 +171,7 @@ func TestBenchContainerLoad(t *testing.T) { for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { - b, err := NewBench("test_assets/b_containers.yml") + b, err := NewBench("testdata/b_containers.yml") assert.Nil(t, err) assert.Equal(t, 2, len(b.Benchmarks.Services)) diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 52a6c570..0f940013 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -18,7 +18,7 @@ func init() { } func TestConfigRefine(t *testing.T) { - cfgFile, ctx, cluster, ns := "test_assets/kubeconfig-test.yml", "test", "c1", "ns1" + cfgFile, ctx, cluster, ns := "testdata/kubeconfig-test.yml", "test", "c1", "ns1" uu := map[string]struct { flags *genericclioptions.ConfigFlags issue bool @@ -85,7 +85,7 @@ func TestConfigValidate(t *testing.T) { cfg := config.NewConfig(mk) cfg.SetConnection(mc) - assert.Nil(t, cfg.Load("test_assets/k9s.yml")) + assert.Nil(t, cfg.Load("testdata/k9s.yml")) cfg.Validate() // mc.VerifyWasCalledOnce().ValidNamespaces() } @@ -93,7 +93,7 @@ func TestConfigValidate(t *testing.T) { func TestConfigLoad(t *testing.T) { mk := NewMockKubeSettings() cfg := config.NewConfig(mk) - assert.Nil(t, cfg.Load("test_assets/k9s.yml")) + assert.Nil(t, cfg.Load("testdata/k9s.yml")) assert.Equal(t, 2, cfg.K9s.RefreshRate) assert.Equal(t, 200, cfg.K9s.LogBufferSize) @@ -119,7 +119,7 @@ func TestConfigCurrentCluster(t *testing.T) { mk := NewMockKubeSettings() cfg := config.NewConfig(mk) - assert.Nil(t, cfg.Load("test_assets/k9s.yml")) + assert.Nil(t, cfg.Load("testdata/k9s.yml")) assert.NotNil(t, cfg.CurrentCluster()) assert.Equal(t, "kube-system", cfg.CurrentCluster().Namespace.Active) assert.Equal(t, "ctx", cfg.CurrentCluster().View.Active) @@ -129,7 +129,7 @@ func TestConfigActiveNamespace(t *testing.T) { mk := NewMockKubeSettings() cfg := config.NewConfig(mk) - assert.Nil(t, cfg.Load("test_assets/k9s.yml")) + assert.Nil(t, cfg.Load("testdata/k9s.yml")) assert.Equal(t, "kube-system", cfg.ActiveNamespace()) } @@ -142,7 +142,7 @@ func TestConfigSetActiveNamespace(t *testing.T) { mk := NewMockKubeSettings() cfg := config.NewConfig(mk) - assert.Nil(t, cfg.Load("test_assets/k9s.yml")) + assert.Nil(t, cfg.Load("testdata/k9s.yml")) assert.Nil(t, cfg.SetActiveNamespace("default")) assert.Equal(t, "default", cfg.ActiveNamespace()) } @@ -151,7 +151,7 @@ func TestConfigActiveView(t *testing.T) { mk := NewMockKubeSettings() cfg := config.NewConfig(mk) - assert.Nil(t, cfg.Load("test_assets/k9s.yml")) + assert.Nil(t, cfg.Load("testdata/k9s.yml")) assert.Equal(t, "ctx", cfg.ActiveView()) } @@ -164,7 +164,7 @@ func TestConfigSetActiveView(t *testing.T) { mk := NewMockKubeSettings() cfg := config.NewConfig(mk) - assert.Nil(t, cfg.Load("test_assets/k9s.yml")) + assert.Nil(t, cfg.Load("testdata/k9s.yml")) cfg.SetActiveView("po") assert.Equal(t, "po", cfg.ActiveView()) } @@ -173,7 +173,7 @@ func TestConfigFavNamespaces(t *testing.T) { mk := NewMockKubeSettings() cfg := config.NewConfig(mk) - assert.Nil(t, cfg.Load("test_assets/k9s.yml")) + assert.Nil(t, cfg.Load("testdata/k9s.yml")) expectedNS := []string{"default", "kube-public", "istio-system", "all", "kube-system"} assert.Equal(t, expectedNS, cfg.FavNamespaces()) } @@ -181,13 +181,13 @@ func TestConfigFavNamespaces(t *testing.T) { func TestConfigLoadOldCfg(t *testing.T) { mk := NewMockKubeSettings() cfg := config.NewConfig(mk) - assert.Nil(t, cfg.Load("test_assets/k9s_old.yml")) + assert.Nil(t, cfg.Load("testdata/k9s_old.yml")) } func TestConfigLoadCrap(t *testing.T) { mk := NewMockKubeSettings() cfg := config.NewConfig(mk) - assert.NotNil(t, cfg.Load("test_assets/k9s_not_there.yml")) + assert.NotNil(t, cfg.Load("testdata/k9s_not_there.yml")) } func TestConfigSaveFile(t *testing.T) { @@ -203,7 +203,7 @@ func TestConfigSaveFile(t *testing.T) { cfg := config.NewConfig(mk) cfg.SetConnection(mc) - assert.Nil(t, cfg.Load("test_assets/k9s.yml")) + assert.Nil(t, cfg.Load("testdata/k9s.yml")) cfg.K9s.RefreshRate = 100 cfg.K9s.ReadOnly = true cfg.K9s.LogBufferSize = 500 @@ -233,7 +233,7 @@ func TestConfigReset(t *testing.T) { cfg := config.NewConfig(mk) cfg.SetConnection(mc) - assert.Nil(t, cfg.Load("test_assets/k9s.yml")) + assert.Nil(t, cfg.Load("testdata/k9s.yml")) cfg.Reset() cfg.Validate() diff --git a/internal/config/hotkey_test.go b/internal/config/hotkey_test.go index 38f8242b..96515b24 100644 --- a/internal/config/hotkey_test.go +++ b/internal/config/hotkey_test.go @@ -9,7 +9,7 @@ import ( func TestHotKeyLoad(t *testing.T) { h := config.NewHotKeys() - assert.Nil(t, h.LoadHotKeys("test_assets/hot_key.yml")) + assert.Nil(t, h.LoadHotKeys("testdata/hot_key.yml")) assert.Equal(t, 1, len(h.HotKey)) diff --git a/internal/config/k9s_test.go b/internal/config/k9s_test.go index 65f45a27..4b061de6 100644 --- a/internal/config/k9s_test.go +++ b/internal/config/k9s_test.go @@ -72,7 +72,7 @@ func TestK9sActiveClusterBlank(t *testing.T) { func TestK9sActiveCluster(t *testing.T) { mk := NewMockKubeSettings() cfg := config.NewConfig(mk) - assert.Nil(t, cfg.Load("test_assets/k9s.yml")) + assert.Nil(t, cfg.Load("testdata/k9s.yml")) cl := cfg.K9s.ActiveCluster() assert.NotNil(t, cl) diff --git a/internal/config/plugin_test.go b/internal/config/plugin_test.go index 7a81412b..43f8e278 100644 --- a/internal/config/plugin_test.go +++ b/internal/config/plugin_test.go @@ -9,7 +9,7 @@ import ( func TestPluginLoad(t *testing.T) { p := config.NewPlugins() - assert.Nil(t, p.LoadPlugins("test_assets/plugin.yml")) + assert.Nil(t, p.LoadPlugins("testdata/plugin.yml")) assert.Equal(t, 1, len(p.Plugin)) k, ok := p.Plugin["blah"] diff --git a/internal/config/styles_test.go b/internal/config/styles_test.go index ee9fe85a..bdb0d7ee 100644 --- a/internal/config/styles_test.go +++ b/internal/config/styles_test.go @@ -27,7 +27,7 @@ func TestAsColor(t *testing.T) { func TestSkinNone(t *testing.T) { s := config.NewStyles() - assert.Nil(t, s.Load("test_assets/empty_skin.yml")) + assert.Nil(t, s.Load("testdata/empty_skin.yml")) s.Update() assert.Equal(t, "cadetblue", s.Body().FgColor) @@ -40,7 +40,7 @@ func TestSkinNone(t *testing.T) { func TestSkin(t *testing.T) { s := config.NewStyles() - assert.Nil(t, s.Load("test_assets/black_and_wtf.yml")) + assert.Nil(t, s.Load("testdata/black_and_wtf.yml")) s.Update() assert.Equal(t, "white", s.Body().FgColor) @@ -53,10 +53,10 @@ func TestSkin(t *testing.T) { func TestSkinNotExits(t *testing.T) { s := config.NewStyles() - assert.NotNil(t, s.Load("test_assets/blee.yml")) + assert.NotNil(t, s.Load("testdata/blee.yml")) } func TestSkinBoarked(t *testing.T) { s := config.NewStyles() - assert.NotNil(t, s.Load("test_assets/skin_boarked.yml")) + assert.NotNil(t, s.Load("testdata/skin_boarked.yml")) } diff --git a/internal/config/test_assets/alias.yml b/internal/config/testdata/alias.yml similarity index 100% rename from internal/config/test_assets/alias.yml rename to internal/config/testdata/alias.yml diff --git a/internal/config/test_assets/b_containers.yml b/internal/config/testdata/b_containers.yml similarity index 100% rename from internal/config/test_assets/b_containers.yml rename to internal/config/testdata/b_containers.yml diff --git a/internal/config/test_assets/b_containers_1.yml b/internal/config/testdata/b_containers_1.yml similarity index 100% rename from internal/config/test_assets/b_containers_1.yml rename to internal/config/testdata/b_containers_1.yml diff --git a/internal/config/test_assets/b_good.yml b/internal/config/testdata/b_good.yml similarity index 100% rename from internal/config/test_assets/b_good.yml rename to internal/config/testdata/b_good.yml diff --git a/internal/config/test_assets/b_toast.yml b/internal/config/testdata/b_toast.yml similarity index 100% rename from internal/config/test_assets/b_toast.yml rename to internal/config/testdata/b_toast.yml diff --git a/internal/config/test_assets/bench-fred.yml b/internal/config/testdata/bench-fred.yml similarity index 100% rename from internal/config/test_assets/bench-fred.yml rename to internal/config/testdata/bench-fred.yml diff --git a/internal/config/test_assets/black_and_wtf.yml b/internal/config/testdata/black_and_wtf.yml similarity index 100% rename from internal/config/test_assets/black_and_wtf.yml rename to internal/config/testdata/black_and_wtf.yml diff --git a/internal/config/test_assets/empty_skin.yml b/internal/config/testdata/empty_skin.yml similarity index 100% rename from internal/config/test_assets/empty_skin.yml rename to internal/config/testdata/empty_skin.yml diff --git a/internal/config/test_assets/hot_key.yml b/internal/config/testdata/hot_key.yml similarity index 100% rename from internal/config/test_assets/hot_key.yml rename to internal/config/testdata/hot_key.yml diff --git a/internal/config/test_assets/k8s.yml b/internal/config/testdata/k8s.yml similarity index 100% rename from internal/config/test_assets/k8s.yml rename to internal/config/testdata/k8s.yml diff --git a/internal/config/test_assets/k9s.yml b/internal/config/testdata/k9s.yml similarity index 100% rename from internal/config/test_assets/k9s.yml rename to internal/config/testdata/k9s.yml diff --git a/internal/config/test_assets/k9s1.yml b/internal/config/testdata/k9s1.yml similarity index 100% rename from internal/config/test_assets/k9s1.yml rename to internal/config/testdata/k9s1.yml diff --git a/internal/config/test_assets/k9s_old.yml b/internal/config/testdata/k9s_old.yml similarity index 100% rename from internal/config/test_assets/k9s_old.yml rename to internal/config/testdata/k9s_old.yml diff --git a/internal/config/test_assets/k9s_toast.yml b/internal/config/testdata/k9s_toast.yml similarity index 100% rename from internal/config/test_assets/k9s_toast.yml rename to internal/config/testdata/k9s_toast.yml diff --git a/internal/config/test_assets/kubeconfig-test.yml b/internal/config/testdata/kubeconfig-test.yml similarity index 100% rename from internal/config/test_assets/kubeconfig-test.yml rename to internal/config/testdata/kubeconfig-test.yml diff --git a/internal/config/test_assets/plugin.yml b/internal/config/testdata/plugin.yml similarity index 100% rename from internal/config/test_assets/plugin.yml rename to internal/config/testdata/plugin.yml diff --git a/internal/config/test_assets/skin_boarked.yml b/internal/config/testdata/skin_boarked.yml similarity index 100% rename from internal/config/test_assets/skin_boarked.yml rename to internal/config/testdata/skin_boarked.yml diff --git a/internal/dao/benchmark_test.go b/internal/dao/benchmark_test.go index 767abef1..b3e52f21 100644 --- a/internal/dao/benchmark_test.go +++ b/internal/dao/benchmark_test.go @@ -15,10 +15,10 @@ func TestBenchmarkList(t *testing.T) { a := dao.Benchmark{} a.Init(makeFactory(), client.NewGVR("benchmarks")) - ctx := context.WithValue(context.Background(), internal.KeyDir, "test_assets/bench") + ctx := context.WithValue(context.Background(), internal.KeyDir, "testdata/bench") oo, err := a.List(ctx, "-") assert.Nil(t, err) assert.Equal(t, 1, len(oo)) - assert.Equal(t, "test_assets/bench/default_fred_1577308050814961000.txt", oo[0].(render.BenchInfo).Path) + assert.Equal(t, "testdata/bench/default_fred_1577308050814961000.txt", oo[0].(render.BenchInfo).Path) } diff --git a/internal/dao/cruiser_test.go b/internal/dao/cruiser_test.go index 33981345..8574d8a4 100644 --- a/internal/dao/cruiser_test.go +++ b/internal/dao/cruiser_test.go @@ -29,7 +29,7 @@ func TestCruiserSlice(t *testing.T) { // Helpers... func loadJSON(t assert.TestingT, n string) *unstructured.Unstructured { - raw, err := ioutil.ReadFile(fmt.Sprintf("test_assets/%s.json", n)) + raw, err := ioutil.ReadFile(fmt.Sprintf("testdata/%s.json", n)) assert.Nil(t, err) var o unstructured.Unstructured diff --git a/internal/dao/dp.go b/internal/dao/dp.go index e61b07f6..6f937b25 100644 --- a/internal/dao/dp.go +++ b/internal/dao/dp.go @@ -21,6 +21,7 @@ var ( _ Loggable = (*Deployment)(nil) _ Restartable = (*Deployment)(nil) _ Scalable = (*Deployment)(nil) + _ Controller = (*Deployment)(nil) ) // Deployment represents a deployment K8s resource. @@ -51,12 +52,7 @@ func (d *Deployment) Scale(path string, replicas int32) error { // Restart a Deployment rollout. func (d *Deployment) Restart(path string) error { - o, err := d.Factory.Get(d.gvr.String(), path, true, labels.Everything()) - if err != nil { - return err - } - var ds appsv1.Deployment - err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &ds) + dp, err := d.GetInstance(path) if err != nil { return err } @@ -69,30 +65,50 @@ func (d *Deployment) Restart(path string) error { if !auth { return fmt.Errorf("user is not authorized to restart a deployment") } - update, err := polymorphichelpers.ObjectRestarterFn(&ds) + update, err := polymorphichelpers.ObjectRestarterFn(dp) if err != nil { return err } - _, err = d.Client().DialOrDie().AppsV1().Deployments(ds.Namespace).Patch(ds.Name, types.StrategicMergePatchType, update) + _, err = d.Client().DialOrDie().AppsV1().Deployments(dp.Namespace).Patch(dp.Name, types.StrategicMergePatchType, update) return err } // TailLogs tail logs for all pods represented by this Deployment. func (d *Deployment) TailLogs(ctx context.Context, c chan<- []byte, opts LogOptions) error { - o, err := d.Factory.Get(d.gvr.String(), opts.Path, true, labels.Everything()) + dp, err := d.GetInstance(opts.Path) if err != nil { return err } - - var dp appsv1.Deployment - err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &dp) - if err != nil { - return errors.New("expecting Deployment resource") - } if dp.Spec.Selector == nil || len(dp.Spec.Selector.MatchLabels) == 0 { return fmt.Errorf("No valid selector found on Deployment %s", opts.Path) } return podLogs(ctx, c, dp.Spec.Selector.MatchLabels, opts) } + +// Pod returns a pod victim by name. +func (d *Deployment) Pod(fqn string) (string, error) { + dp, err := d.GetInstance(fqn) + if err != nil { + return "", err + } + + return podFromSelector(d.Factory, dp.Namespace, dp.Spec.Selector.MatchLabels) +} + +// GetInstance returns a deployment instance. +func (d *Deployment) GetInstance(fqn string) (*appsv1.Deployment, error) { + o, err := d.Factory.Get(d.gvr.String(), fqn, false, labels.Everything()) + if err != nil { + return nil, err + } + + var dp appsv1.Deployment + err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &dp) + if err != nil { + return nil, errors.New("expecting Deployment resource") + } + + return &dp, nil +} diff --git a/internal/dao/ds.go b/internal/dao/ds.go index d42b159e..89a0877d 100644 --- a/internal/dao/ds.go +++ b/internal/dao/ds.go @@ -5,12 +5,10 @@ import ( "errors" "fmt" "strings" - "time" "github.com/derailed/k9s/internal" "github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/watch" - "github.com/rs/zerolog/log" appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -26,6 +24,7 @@ var ( _ Nuker = (*DaemonSet)(nil) _ Loggable = (*DaemonSet)(nil) _ Restartable = (*DaemonSet)(nil) + _ Controller = (*DaemonSet)(nil) ) // DaemonSet represents a K8s daemonset. @@ -35,12 +34,7 @@ type DaemonSet struct { // Restart a DaemonSet rollout. func (d *DaemonSet) Restart(path string) error { - o, err := d.Factory.Get(d.gvr.String(), path, true, labels.Everything()) - if err != nil { - return err - } - var ds appsv1.DaemonSet - err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &ds) + ds, err := d.GetInstance(path) if err != nil { return err } @@ -52,26 +46,21 @@ func (d *DaemonSet) Restart(path string) error { if !auth { return fmt.Errorf("user is not authorized to restart a daemonset") } - update, err := polymorphichelpers.ObjectRestarterFn(&ds) + update, err := polymorphichelpers.ObjectRestarterFn(ds) if err != nil { return err } - _, err = d.Client().DialOrDie().AppsV1().DaemonSets(ds.Namespace).Patch(ds.Name, types.StrategicMergePatchType, update) + _, err = d.Client().DialOrDie().AppsV1().DaemonSets(ds.Namespace).Patch(ds.Name, types.StrategicMergePatchType, update) return err } // TailLogs tail logs for all pods represented by this DaemonSet. func (d *DaemonSet) TailLogs(ctx context.Context, c chan<- []byte, opts LogOptions) error { - o, err := d.Factory.Get(d.gvr.String(), opts.Path, true, labels.Everything()) + ds, err := d.GetInstance(opts.Path) if err != nil { return err } - var ds appsv1.DaemonSet - err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &ds) - if err != nil { - return errors.New("expecting daemonset resource") - } if ds.Spec.Selector == nil || len(ds.Spec.Selector.MatchLabels) == 0 { return fmt.Errorf("no valid selector found on daemonset %q", opts.Path) @@ -81,10 +70,6 @@ func (d *DaemonSet) TailLogs(ctx context.Context, c chan<- []byte, opts LogOptio } func podLogs(ctx context.Context, c chan<- []byte, sel map[string]string, opts LogOptions) error { - defer func(t time.Time) { - log.Debug().Msgf("POD LOGS %v", time.Since(t)) - }(time.Now()) - f, ok := ctx.Value(internal.KeyFactory).(*watch.Factory) if !ok { return errors.New("expecting a context factory") @@ -116,7 +101,6 @@ func podLogs(ctx context.Context, c chan<- []byte, sel map[string]string, opts L if err != nil { return err } - log.Debug().Msgf("TAILING logs on pod %q", pod.Name) opts.Path = client.FQN(pod.Namespace, pod.Name) if err := po.TailLogs(ctx, c, opts); err != nil { return err @@ -125,6 +109,32 @@ func podLogs(ctx context.Context, c chan<- []byte, sel map[string]string, opts L return nil } +// Pod returns a pod victim by name. +func (d *DaemonSet) Pod(fqn string) (string, error) { + ds, err := d.GetInstance(fqn) + if err != nil { + return "", err + } + + return podFromSelector(d.Factory, ds.Namespace, ds.Spec.Selector.MatchLabels) +} + +// GetInstance returns a daemonset instance. +func (d *DaemonSet) GetInstance(fqn string) (*appsv1.DaemonSet, error) { + o, err := d.Factory.Get(d.gvr.String(), fqn, false, labels.Everything()) + if err != nil { + return nil, err + } + + var ds appsv1.DaemonSet + err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &ds) + if err != nil { + return nil, errors.New("expecting DaemonSet resource") + } + + return &ds, nil +} + // ---------------------------------------------------------------------------- // Helpers... diff --git a/internal/dao/pod.go b/internal/dao/pod.go index faf39cb5..1fddf20b 100644 --- a/internal/dao/pod.go +++ b/internal/dao/pod.go @@ -27,9 +27,10 @@ import ( const defaultTimeout = 1 * time.Second var ( - _ Accessor = (*Pod)(nil) - _ Nuker = (*Pod)(nil) - _ Loggable = (*Pod)(nil) + _ Accessor = (*Pod)(nil) + _ Nuker = (*Pod)(nil) + _ Loggable = (*Pod)(nil) + _ Controller = (*Pod)(nil) ) // Pod represents a pod resource. @@ -122,13 +123,7 @@ func (p *Pod) Logs(path string, opts *v1.PodLogOptions) (*restclient.Request, er // Containers returns all container names on pod func (p *Pod) Containers(path string, includeInit bool) ([]string, error) { - o, err := p.Factory.Get(p.gvr.String(), path, true, labels.Everything()) - if err != nil { - return nil, err - } - - var pod v1.Pod - err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &pod) + pod, err := p.GetInstance(path) if err != nil { return nil, err } @@ -147,6 +142,27 @@ func (p *Pod) Containers(path string, includeInit bool) ([]string, error) { return cc, nil } +// Pod returns a pod victim by name. +func (p *Pod) Pod(fqn string) (string, error) { + return fqn, nil +} + +// GetInstance returns a pod instance. +func (p *Pod) GetInstance(fqn string) (*v1.Pod, error) { + o, err := p.Factory.Get(p.gvr.String(), fqn, false, labels.Everything()) + if err != nil { + return nil, err + } + + var pod v1.Pod + err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &pod) + if err != nil { + return nil, err + } + + return &pod, nil +} + // TailLogs tails a given container logs func (p *Pod) TailLogs(ctx context.Context, c chan<- []byte, opts LogOptions) error { if !opts.HasContainer() { diff --git a/internal/dao/port_forward.go b/internal/dao/port_forward.go index 02852886..e88f7969 100644 --- a/internal/dao/port_forward.go +++ b/internal/dao/port_forward.go @@ -3,12 +3,14 @@ package dao import ( "context" "fmt" + "regexp" "strings" "github.com/derailed/k9s/internal" "github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/config" "github.com/derailed/k9s/internal/render" + "github.com/rs/zerolog/log" "k8s.io/apimachinery/pkg/runtime" ) @@ -40,21 +42,26 @@ func (p *PortForward) Delete(path string, cascade, force bool) error { // List returns a collection of screen dumps. func (p *PortForward) List(ctx context.Context, _ string) ([]runtime.Object, error) { - config, ok := ctx.Value(internal.KeyBenchCfg).(*config.Bench) + benchFile, ok := ctx.Value(internal.KeyBenchCfg).(string) if !ok { - return nil, fmt.Errorf("no benchconfig found in context") + return nil, fmt.Errorf("no bench file found in context") + } + + config, err := config.NewBench(benchFile) + if err != nil { + log.Debug().Msgf("No custom benchmark config file found") } cc := config.Benchmarks.Containers oo := make([]runtime.Object, 0, len(p.Factory.Forwarders())) - for _, f := range p.Factory.Forwarders() { + for k, f := range p.Factory.Forwarders() { cfg := render.BenchCfg{ C: config.Benchmarks.Defaults.C, N: config.Benchmarks.Defaults.N, } - if config, ok := cc[containerID(f.Path(), f.Container())]; ok { - cfg.C, cfg.N = config.C, config.N - cfg.Host, cfg.Path = config.HTTP.Host, config.HTTP.Path + if cust, ok := cc[PodToKey(k)]; ok { + cfg.C, cfg.N = cust.C, cust.N + cfg.Host, cfg.Path = cust.HTTP.Host, cust.HTTP.Path } oo = append(oo, render.ForwardRes{ Forwarder: f, @@ -68,10 +75,31 @@ func (p *PortForward) List(ctx context.Context, _ string) ([]runtime.Object, err // ---------------------------------------------------------------------------- // Helpers... -// ContainerID computes container ID based on ns/po/co. -func containerID(path, co string) string { - ns, n := client.Namespaced(path) - po := strings.Split(n, "-")[0] +var podNameRX = regexp.MustCompile(`\A(.+)\-(\w{10})\-(\w{5})\z`) - return ns + "/" + po + ":" + co +// PodToKey converts a pod path to a generic bench config key +func PodToKey(path string) string { + tokens := strings.Split(path, ":") + ns, po := client.Namespaced(tokens[0]) + sections := podNameRX.FindStringSubmatch(po) + if len(sections) >= 1 { + po = sections[1] + } + return client.FQN(ns, po) + ":" + tokens[1] +} + +// BenchConfigFor returns a custom bench spec if defined otherwise returns the default one. +func BenchConfigFor(benchFile, path string) config.BenchConfig { + def := config.DefaultBenchSpec() + cust, err := config.NewBench(benchFile) + if err != nil { + log.Debug().Msgf("No custom benchmark config file found") + return def + } + if b, ok := cust.Benchmarks.Containers[PodToKey(path)]; ok { + return b + } + + def.C, def.N = cust.Benchmarks.Defaults.C, cust.Benchmarks.Defaults.N + return def } diff --git a/internal/dao/port_forward_test.go b/internal/dao/port_forward_test.go new file mode 100644 index 00000000..691eee7f --- /dev/null +++ b/internal/dao/port_forward_test.go @@ -0,0 +1,33 @@ +package dao_test + +import ( + "testing" + + "github.com/derailed/k9s/internal/config" + "github.com/derailed/k9s/internal/dao" + "github.com/stretchr/testify/assert" +) + +func TestBenchForConfig(t *testing.T) { + uu := map[string]struct { + file, key string + spec config.BenchConfig + }{ + "no_file": {file: "", key: "", spec: config.DefaultBenchSpec()}, + "spec": {file: "testdata/benchspec.yml", key: "default/nginx-123-456:nginx", spec: config.BenchConfig{ + C: 2, + N: 3000, + HTTP: config.HTTP{ + Method: "GET", + Path: "/", + }, + }}, + } + + for k := range uu { + u := uu[k] + t.Run(k, func(t *testing.T) { + assert.NotNil(t, u.spec, dao.BenchConfigFor(u.file, u.key)) + }) + } +} diff --git a/internal/dao/port_forwarder.go b/internal/dao/port_forwarder.go index 38d1d8f5..f91175df 100644 --- a/internal/dao/port_forwarder.go +++ b/internal/dao/port_forwarder.go @@ -23,14 +23,9 @@ import ( const localhost = "localhost" -// Tunnel represents a host tunnel port mapper. -type Tunnel struct { - Address, LocalPort, ContainerPort string -} - // PortForwarder tracks a port forward stream. type PortForwarder struct { - client.Connection + Factory genericclioptions.IOStreams stopChan, readyChan chan struct{} @@ -42,11 +37,11 @@ type PortForwarder struct { } // NewPortForwarder returns a new port forward streamer. -func NewPortForwarder(c client.Connection) *PortForwarder { +func NewPortForwarder(f Factory) *PortForwarder { return &PortForwarder{ - Connection: c, - stopChan: make(chan struct{}), - readyChan: make(chan struct{}), + Factory: f, + stopChan: make(chan struct{}), + readyChan: make(chan struct{}), } } @@ -72,7 +67,12 @@ func (p *PortForwarder) Ports() []string { // Path returns the pod resource path. func (p *PortForwarder) Path() string { - return p.path + ":" + p.container + return PortForwardID(p.path, p.container) +} + +// PortForwardID computes port-forward identifier. +func PortForwardID(path, co string) string { + return path + ":" + co } // Container returns the targetes container. @@ -92,13 +92,23 @@ func (p *PortForwarder) FQN() string { return p.path + ":" + p.container } +// HasPortMapping checks if port mapping is defined for this fwd. +func (p *PortForwarder) HasPortMapping(m string) bool { + for _, mapping := range p.ports { + if mapping == m { + return true + } + } + return false +} + // Start initiates a port forward session for a given pod and ports. -func (p *PortForwarder) Start(path, co string, t Tunnel) (*portforward.PortForwarder, error) { - fwds := []string{t.LocalPort + ":" + t.ContainerPort} +func (p *PortForwarder) Start(path, co string, t client.PortTunnel) (*portforward.PortForwarder, error) { + fwds := []string{t.PortMap()} p.path, p.container, p.ports, p.age = path, co, fwds, time.Now() ns, n := client.Namespaced(path) - auth, err := p.CanI(ns, "v1/pods", []string{client.GetVerb}) + auth, err := p.Client().CanI(ns, "v1/pods", []string{client.GetVerb}) if err != nil { return nil, err } @@ -106,8 +116,9 @@ func (p *PortForwarder) Start(path, co string, t Tunnel) (*portforward.PortForwa return nil, fmt.Errorf("user is not authorized to get pods") } - // BOZO!! Use the factory! - pod, err := p.DialOrDie().CoreV1().Pods(ns).Get(n, metav1.GetOptions{}) + var res Pod + res.Init(p, client.NewGVR("v1/pods")) + pod, err := res.GetInstance(path) if err != nil { return nil, err } @@ -115,7 +126,7 @@ func (p *PortForwarder) Start(path, co string, t Tunnel) (*portforward.PortForwa return nil, fmt.Errorf("unable to forward port because pod is not running. Current status=%v", pod.Status.Phase) } - auth, err = p.CanI(ns, "v1/pods:portforward", []string{client.UpdateVerb}) + auth, err = p.Client().CanI(ns, "v1/pods:portforward", []string{client.UpdateVerb}) if err != nil { return nil, err } @@ -123,7 +134,7 @@ func (p *PortForwarder) Start(path, co string, t Tunnel) (*portforward.PortForwa return nil, fmt.Errorf("user is not authorized to update portforward") } - rcfg := p.RestConfigOrDie() + rcfg := p.Client().RestConfigOrDie() rcfg.GroupVersion = &schema.GroupVersion{Group: "", Version: "v1"} rcfg.APIPath = "/api" codec, _ := codec() @@ -143,7 +154,7 @@ func (p *PortForwarder) Start(path, co string, t Tunnel) (*portforward.PortForwa } func (p *PortForwarder) forwardPorts(method string, url *url.URL, address string, ports []string) (*portforward.PortForwarder, error) { - cfg, err := p.Config().RESTConfig() + cfg, err := p.Client().Config().RESTConfig() if err != nil { return nil, err } diff --git a/internal/dao/registry_test.go b/internal/dao/registry_test.go index 241869b8..28ff4ef8 100644 --- a/internal/dao/registry_test.go +++ b/internal/dao/registry_test.go @@ -89,7 +89,7 @@ func TestExtractString(t *testing.T) { // Helpers... func load(t *testing.T, n string) *unstructured.Unstructured { - raw, err := ioutil.ReadFile(fmt.Sprintf("assets/%s.json", n)) + raw, err := ioutil.ReadFile(fmt.Sprintf("testdata/%s.json", n)) assert.Nil(t, err) var o unstructured.Unstructured diff --git a/internal/dao/sts.go b/internal/dao/sts.go index 0946ff24..e00d849b 100644 --- a/internal/dao/sts.go +++ b/internal/dao/sts.go @@ -21,6 +21,7 @@ var ( _ Loggable = (*StatefulSet)(nil) _ Restartable = (*StatefulSet)(nil) _ Scalable = (*StatefulSet)(nil) + _ Controller = (*StatefulSet)(nil) ) // StatefulSet represents a K8s sts. @@ -51,12 +52,7 @@ func (s *StatefulSet) Scale(path string, replicas int32) error { // Restart a StatefulSet rollout. func (s *StatefulSet) Restart(path string) error { - o, err := s.Factory.Get(s.gvr.String(), path, true, labels.Everything()) - if err != nil { - return err - } - var ds appsv1.StatefulSet - err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &ds) + sts, err := s.getStatefulSet(path) if err != nil { return err } @@ -70,24 +66,18 @@ func (s *StatefulSet) Restart(path string) error { return fmt.Errorf("user is not authorized to update statefulsets") } - update, err := polymorphichelpers.ObjectRestarterFn(&ds) + update, err := polymorphichelpers.ObjectRestarterFn(sts) if err != nil { return err } - _, err = s.Client().DialOrDie().AppsV1().StatefulSets(ds.Namespace).Patch(ds.Name, types.StrategicMergePatchType, update) + _, err = s.Client().DialOrDie().AppsV1().StatefulSets(sts.Namespace).Patch(sts.Name, types.StrategicMergePatchType, update) return err } // TailLogs tail logs for all pods represented by this StatefulSet. func (s *StatefulSet) TailLogs(ctx context.Context, c chan<- []byte, opts LogOptions) error { - o, err := s.Factory.Get(s.gvr.String(), opts.Path, true, labels.Everything()) - if err != nil { - return err - } - - var sts appsv1.StatefulSet - err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &sts) + sts, err := s.getStatefulSet(opts.Path) if err != nil { return errors.New("expecting StatefulSet resource") } @@ -97,3 +87,28 @@ func (s *StatefulSet) TailLogs(ctx context.Context, c chan<- []byte, opts LogOpt return podLogs(ctx, c, sts.Spec.Selector.MatchLabels, opts) } + +// Pod returns a pod victim by name. +func (s *StatefulSet) Pod(fqn string) (string, error) { + sts, err := s.getStatefulSet(fqn) + if err != nil { + return "", err + } + + return podFromSelector(s.Factory, sts.Namespace, sts.Spec.Selector.MatchLabels) +} + +func (s *StatefulSet) getStatefulSet(fqn string) (*appsv1.StatefulSet, error) { + o, err := s.Factory.Get(s.gvr.String(), fqn, false, labels.Everything()) + if err != nil { + return nil, err + } + + var sts appsv1.StatefulSet + err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &sts) + if err != nil { + return nil, errors.New("expecting Service resource") + } + + return &sts, nil +} diff --git a/internal/dao/svc.go b/internal/dao/svc.go index 9fbc3787..2369870b 100644 --- a/internal/dao/svc.go +++ b/internal/dao/svc.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" + "github.com/derailed/k9s/internal/client" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/labels" @@ -12,8 +13,9 @@ import ( ) var ( - _ Accessor = (*Service)(nil) - _ Loggable = (*Service)(nil) + _ Accessor = (*Service)(nil) + _ Loggable = (*Service)(nil) + _ Controller = (*Service)(nil) ) // Service represents a k8s service. @@ -23,19 +25,61 @@ type Service struct { // TailLogs tail logs for all pods represented by this Service. func (s *Service) TailLogs(ctx context.Context, c chan<- []byte, opts LogOptions) error { - o, err := s.Factory.Get(s.gvr.String(), opts.Path, true, labels.Everything()) + svc, err := s.GetInstance(opts.Path) if err != nil { return err } - var svc v1.Service - err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &svc) - if err != nil { - return errors.New("expecting Service resource") - } - if svc.Spec.Selector == nil || len(svc.Spec.Selector) == 0 { return fmt.Errorf("no valid selector found on Service %s", opts.Path) } return podLogs(ctx, c, svc.Spec.Selector, opts) } + +// Pod returns a pod victim by name. +func (s *Service) Pod(fqn string) (string, error) { + svc, err := s.GetInstance(fqn) + if err != nil { + return "", err + } + + return podFromSelector(s.Factory, svc.Namespace, svc.Spec.Selector) +} + +// GetInstance returns a service instance. +func (s *Service) GetInstance(fqn string) (*v1.Service, error) { + o, err := s.Factory.Get(s.gvr.String(), fqn, false, labels.Everything()) + if err != nil { + return nil, err + } + + var svc v1.Service + err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &svc) + if err != nil { + return nil, errors.New("expecting Service resource") + } + + return &svc, nil +} + +// ---------------------------------------------------------------------------- +// Helpers... + +func podFromSelector(f Factory, ns string, sel map[string]string) (string, error) { + oo, err := f.List("v1/pods", ns, true, labels.Set(sel).AsSelector()) + if err != nil { + return "", err + } + + if len(oo) == 0 { + return "", fmt.Errorf("no matching pods for %v", sel) + } + + var pod v1.Pod + err = runtime.DefaultUnstructuredConverter.FromUnstructured(oo[0].(*unstructured.Unstructured).Object, &pod) + if err != nil { + return "", err + } + + return client.FQN(pod.Namespace, pod.Name), nil +} diff --git a/internal/dao/test_assets/bench/default_fred_1577308050814961000.txt b/internal/dao/testdata/bench/default_fred_1577308050814961000.txt similarity index 100% rename from internal/dao/test_assets/bench/default_fred_1577308050814961000.txt rename to internal/dao/testdata/bench/default_fred_1577308050814961000.txt diff --git a/internal/dao/testdata/benchspec.yml b/internal/dao/testdata/benchspec.yml new file mode 100644 index 00000000..e308b288 --- /dev/null +++ b/internal/dao/testdata/benchspec.yml @@ -0,0 +1,19 @@ +benchmarks: + defaults: + concurrency: 2 + requests: 500 + containers: + default/nginx:nginx: + concurrency: 2 + requests: 3000 + http: + method: GET + path: / + services: + default/nginx: + concurrency: 1 + requests: 666 + http: + method: GET + host: 192.168.64.1 + path: / diff --git a/internal/dao/assets/config b/internal/dao/testdata/config similarity index 100% rename from internal/dao/assets/config rename to internal/dao/testdata/config diff --git a/internal/dao/assets/config.1 b/internal/dao/testdata/config.1 similarity index 100% rename from internal/dao/assets/config.1 rename to internal/dao/testdata/config.1 diff --git a/internal/dao/test_assets/crb.json b/internal/dao/testdata/crb.json similarity index 100% rename from internal/dao/test_assets/crb.json rename to internal/dao/testdata/crb.json diff --git a/internal/dao/assets/dr.json b/internal/dao/testdata/dr.json similarity index 100% rename from internal/dao/assets/dr.json rename to internal/dao/testdata/dr.json diff --git a/internal/dao/test_assets/n1.json b/internal/dao/testdata/n1.json similarity index 100% rename from internal/dao/test_assets/n1.json rename to internal/dao/testdata/n1.json diff --git a/internal/dao/test_assets/p1.json b/internal/dao/testdata/p1.json similarity index 100% rename from internal/dao/test_assets/p1.json rename to internal/dao/testdata/p1.json diff --git a/internal/dao/types.go b/internal/dao/types.go index b93d7f76..ccddbb8e 100644 --- a/internal/dao/types.go +++ b/internal/dao/types.go @@ -91,6 +91,12 @@ type Scalable interface { Scale(path string, replicas int32) error } +// Controller represents a pod controller. +type Controller interface { + // Pod returns a pod instance matching the selector. + Pod(path string) (string, error) +} + // Nuker represents a resource deleter. type Nuker interface { // Delete removes a resource from the api server. diff --git a/internal/model/table_int_test.go b/internal/model/table_int_test.go index 3ba5405d..123da35c 100644 --- a/internal/model/table_int_test.go +++ b/internal/model/table_int_test.go @@ -69,12 +69,6 @@ func TestTableMeta(t *testing.T) { accessor dao.Accessor renderer Renderer }{ - // BOZO!! - // "full": { - // gvr: "v1/pods", - // accessor: &pd, - // renderer: &render.Pod{}, - // }, "generic": { gvr: "containers", accessor: &dao.Container{}, @@ -144,7 +138,7 @@ func TestTableGenericHydrate(t *testing.T) { // Helpers... func mustLoad(n string) *unstructured.Unstructured { - raw, err := ioutil.ReadFile(fmt.Sprintf("test_assets/%s.json", n)) + raw, err := ioutil.ReadFile(fmt.Sprintf("testdata/%s.json", n)) if err != nil { panic(err) } @@ -156,7 +150,7 @@ func mustLoad(n string) *unstructured.Unstructured { } func load(t *testing.T, n string) *unstructured.Unstructured { - raw, err := ioutil.ReadFile(fmt.Sprintf("test_assets/%s.json", n)) + raw, err := ioutil.ReadFile(fmt.Sprintf("testdata/%s.json", n)) assert.Nil(t, err) var o unstructured.Unstructured err = json.Unmarshal(raw, &o) @@ -165,7 +159,7 @@ func load(t *testing.T, n string) *unstructured.Unstructured { } func raw(t *testing.T, n string) []byte { - raw, err := ioutil.ReadFile(fmt.Sprintf("test_assets/%s.json", n)) + raw, err := ioutil.ReadFile(fmt.Sprintf("testdata/%s.json", n)) assert.Nil(t, err) return raw } diff --git a/internal/model/table_test.go b/internal/model/table_test.go index b72878ca..0ae6da2d 100644 --- a/internal/model/table_test.go +++ b/internal/model/table_test.go @@ -116,7 +116,7 @@ func makeTableFactory() tableFactory { } func mustLoad(n string) *unstructured.Unstructured { - raw, err := ioutil.ReadFile(fmt.Sprintf("test_assets/%s.json", n)) + raw, err := ioutil.ReadFile(fmt.Sprintf("testdata/%s.json", n)) if err != nil { panic(err) } diff --git a/internal/model/test_assets/p1.json b/internal/model/testdata/p1.json similarity index 100% rename from internal/model/test_assets/p1.json rename to internal/model/testdata/p1.json diff --git a/internal/render/benchmark_int_test.go b/internal/render/benchmark_int_test.go index 7489b914..6c7c5384 100644 --- a/internal/render/benchmark_int_test.go +++ b/internal/render/benchmark_int_test.go @@ -18,19 +18,19 @@ func TestAugmentRow(t *testing.T) { e Fields }{ "cool": { - "assets/b1.txt", + "testdata/b1.txt", Fields{"pass", "3.3544", "29.8116", "100", "0"}, }, "2XX": { - "assets/b4.txt", + "testdata/b4.txt", Fields{"pass", "3.3544", "29.8116", "160", "0"}, }, "4XX/5XX": { - "assets/b2.txt", + "testdata/b2.txt", Fields{"pass", "3.3544", "29.8116", "100", "12"}, }, "toast": { - "assets/b3.txt", + "testdata/b3.txt", Fields{"fail", "2.3688", "35.4606", "0", "0"}, }, } diff --git a/internal/render/render_test.go b/internal/render/render_test.go index dd758af1..f526ed70 100644 --- a/internal/render/render_test.go +++ b/internal/render/render_test.go @@ -12,7 +12,7 @@ import ( // Helpers... func load(t assert.TestingT, n string) *unstructured.Unstructured { - raw, err := ioutil.ReadFile(fmt.Sprintf("assets/%s.json", n)) + raw, err := ioutil.ReadFile(fmt.Sprintf("testdata/%s.json", n)) assert.Nil(t, err) var o unstructured.Unstructured diff --git a/internal/render/assets/b1.txt b/internal/render/testdata/b1.txt similarity index 100% rename from internal/render/assets/b1.txt rename to internal/render/testdata/b1.txt diff --git a/internal/render/assets/b2.txt b/internal/render/testdata/b2.txt similarity index 100% rename from internal/render/assets/b2.txt rename to internal/render/testdata/b2.txt diff --git a/internal/render/assets/b3.txt b/internal/render/testdata/b3.txt similarity index 100% rename from internal/render/assets/b3.txt rename to internal/render/testdata/b3.txt diff --git a/internal/render/assets/b4.txt b/internal/render/testdata/b4.txt similarity index 100% rename from internal/render/assets/b4.txt rename to internal/render/testdata/b4.txt diff --git a/internal/render/assets/cj.json b/internal/render/testdata/cj.json similarity index 100% rename from internal/render/assets/cj.json rename to internal/render/testdata/cj.json diff --git a/internal/render/assets/cm.json b/internal/render/testdata/cm.json similarity index 100% rename from internal/render/assets/cm.json rename to internal/render/testdata/cm.json diff --git a/internal/render/assets/cr.json b/internal/render/testdata/cr.json similarity index 100% rename from internal/render/assets/cr.json rename to internal/render/testdata/cr.json diff --git a/internal/render/assets/crb.json b/internal/render/testdata/crb.json similarity index 100% rename from internal/render/assets/crb.json rename to internal/render/testdata/crb.json diff --git a/internal/render/assets/crd.json b/internal/render/testdata/crd.json similarity index 100% rename from internal/render/assets/crd.json rename to internal/render/testdata/crd.json diff --git a/internal/render/assets/dp.json b/internal/render/testdata/dp.json similarity index 100% rename from internal/render/assets/dp.json rename to internal/render/testdata/dp.json diff --git a/internal/render/assets/ds.json b/internal/render/testdata/ds.json similarity index 100% rename from internal/render/assets/ds.json rename to internal/render/testdata/ds.json diff --git a/internal/render/assets/ep.json b/internal/render/testdata/ep.json similarity index 100% rename from internal/render/assets/ep.json rename to internal/render/testdata/ep.json diff --git a/internal/render/assets/ev.json b/internal/render/testdata/ev.json similarity index 100% rename from internal/render/assets/ev.json rename to internal/render/testdata/ev.json diff --git a/internal/render/assets/hpa.json b/internal/render/testdata/hpa.json similarity index 100% rename from internal/render/assets/hpa.json rename to internal/render/testdata/hpa.json diff --git a/internal/render/assets/ing.json b/internal/render/testdata/ing.json similarity index 100% rename from internal/render/assets/ing.json rename to internal/render/testdata/ing.json diff --git a/internal/render/assets/job.json b/internal/render/testdata/job.json similarity index 100% rename from internal/render/assets/job.json rename to internal/render/testdata/job.json diff --git a/internal/render/assets/no.json b/internal/render/testdata/no.json similarity index 100% rename from internal/render/assets/no.json rename to internal/render/testdata/no.json diff --git a/internal/render/assets/np.json b/internal/render/testdata/np.json similarity index 100% rename from internal/render/assets/np.json rename to internal/render/testdata/np.json diff --git a/internal/render/assets/ns.json b/internal/render/testdata/ns.json similarity index 100% rename from internal/render/assets/ns.json rename to internal/render/testdata/ns.json diff --git a/internal/render/assets/pdb.json b/internal/render/testdata/pdb.json similarity index 100% rename from internal/render/assets/pdb.json rename to internal/render/testdata/pdb.json diff --git a/internal/render/assets/po.json b/internal/render/testdata/po.json similarity index 100% rename from internal/render/assets/po.json rename to internal/render/testdata/po.json diff --git a/internal/render/assets/po_init.json b/internal/render/testdata/po_init.json similarity index 100% rename from internal/render/assets/po_init.json rename to internal/render/testdata/po_init.json diff --git a/internal/render/assets/pv.json b/internal/render/testdata/pv.json similarity index 100% rename from internal/render/assets/pv.json rename to internal/render/testdata/pv.json diff --git a/internal/render/assets/pvc.json b/internal/render/testdata/pvc.json similarity index 100% rename from internal/render/assets/pvc.json rename to internal/render/testdata/pvc.json diff --git a/internal/render/assets/rb.json b/internal/render/testdata/rb.json similarity index 100% rename from internal/render/assets/rb.json rename to internal/render/testdata/rb.json diff --git a/internal/render/assets/ro.json b/internal/render/testdata/ro.json similarity index 100% rename from internal/render/assets/ro.json rename to internal/render/testdata/ro.json diff --git a/internal/render/assets/rs.json b/internal/render/testdata/rs.json similarity index 100% rename from internal/render/assets/rs.json rename to internal/render/testdata/rs.json diff --git a/internal/render/assets/sa.json b/internal/render/testdata/sa.json similarity index 100% rename from internal/render/assets/sa.json rename to internal/render/testdata/sa.json diff --git a/internal/render/assets/sc.json b/internal/render/testdata/sc.json similarity index 100% rename from internal/render/assets/sc.json rename to internal/render/testdata/sc.json diff --git a/internal/render/assets/sec.json b/internal/render/testdata/sec.json similarity index 100% rename from internal/render/assets/sec.json rename to internal/render/testdata/sec.json diff --git a/internal/render/assets/sts.json b/internal/render/testdata/sts.json similarity index 100% rename from internal/render/assets/sts.json rename to internal/render/testdata/sts.json diff --git a/internal/render/assets/svc.json b/internal/render/testdata/svc.json similarity index 100% rename from internal/render/assets/svc.json rename to internal/render/testdata/svc.json diff --git a/internal/ui/config.go b/internal/ui/config.go index 71771745..857179db 100644 --- a/internal/ui/config.go +++ b/internal/ui/config.go @@ -20,10 +20,10 @@ type synchronizer interface { // Configurator represents an application configurationa. type Configurator struct { - skinFile string - Config *config.Config - Styles *config.Styles - Bench *config.Bench + skinFile string + Config *config.Config + Styles *config.Styles + BenchFile string } // HasSkin returns true if a skin file was located. @@ -67,21 +67,15 @@ func (c *Configurator) StylesUpdater(ctx context.Context, s synchronizer) error return w.Add(c.skinFile) } -// InitBench load benchmark configuration if any. -func (c *Configurator) InitBench(cluster string) { - var err error - if c.Bench, err = config.NewBench(BenchConfig(cluster)); err != nil { - log.Info().Msg("No benchmark config file found, using defaults.") - } -} - // BenchConfig location of the benchmarks configuration file. -func BenchConfig(cluster string) string { - return filepath.Join(config.K9sHome, config.K9sBench+"-"+cluster+".yml") +func BenchConfig(context string) string { + return filepath.Join(config.K9sHome, config.K9sBench+"-"+context+".yml") } // RefreshStyles load for skin configuration changes. func (c *Configurator) RefreshStyles(context string) { + c.BenchFile = BenchConfig(context) + clusterSkins := filepath.Join(config.K9sHome, fmt.Sprintf("%s_skin.yml", context)) if c.Styles == nil { c.Styles = config.NewStyles() diff --git a/internal/ui/config_test.go b/internal/ui/config_test.go index 6436057e..2eb9006f 100644 --- a/internal/ui/config_test.go +++ b/internal/ui/config_test.go @@ -17,7 +17,7 @@ func TestBenchConfig(t *testing.T) { } func TestConfiguratorRefreshStyle(t *testing.T) { - config.K9sStylesFile = filepath.Join("..", "config", "test_assets", "black_and_wtf.yml") + config.K9sStylesFile = filepath.Join("..", "config", "testdata", "black_and_wtf.yml") cfg := ui.Configurator{} cfg.RefreshStyles("") @@ -26,15 +26,3 @@ func TestConfiguratorRefreshStyle(t *testing.T) { assert.Equal(t, tcell.ColorGhostWhite, render.StdColor) assert.Equal(t, tcell.ColorWhiteSmoke, render.ErrColor) } - -func TestInitBench(t *testing.T) { - config.K9sHome = filepath.Join("..", "config", "test_assets") - - cfg := ui.Configurator{} - cfg.InitBench("fred") - - assert.NotNil(t, cfg.Bench) - assert.Equal(t, 2, cfg.Bench.Benchmarks.Defaults.C) - assert.Equal(t, 1000, cfg.Bench.Benchmarks.Defaults.N) - assert.Equal(t, 2, len(cfg.Bench.Benchmarks.Services)) -} diff --git a/internal/ui/dialog/port_forwards_test.go b/internal/ui/dialog/port_forwards_test.go deleted file mode 100644 index 6ecb876f..00000000 --- a/internal/ui/dialog/port_forwards_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package dialog - -import ( - "testing" - - "github.com/derailed/k9s/internal/config" - "github.com/derailed/k9s/internal/dao" - "github.com/derailed/k9s/internal/ui" - "github.com/derailed/tview" - "github.com/stretchr/testify/assert" -) - -func TestPortForwards(t *testing.T) { - p := ui.NewPages() - - cbFunc := func(path, co string, t dao.Tunnel) {} - ShowPortForwards(p, config.NewStyles(), "fred", []string{"8080"}, cbFunc) - - d := p.GetPrimitive(portForwardKey).(*tview.ModalForm) - assert.NotNil(t, d) - - DismissPortForwards(p) - assert.Nil(t, p.GetPrimitive(portForwardKey)) -} - -func TestExtractPort(t *testing.T) { - uu := map[string]struct { - port, e string - }{ - "full": { - "fred:8000", "8000", - }, - "port": { - "8000", "8000", - }, - "protocol": { - "dns:53╱UDP", "53", - }, - } - - for k := range uu { - u := uu[k] - t.Run(k, func(t *testing.T) { - assert.Equal(t, u.e, extractPort(u.port)) - }) - } -} diff --git a/internal/ui/menu.go b/internal/ui/menu.go index ef44f60a..958cf5d9 100644 --- a/internal/ui/menu.go +++ b/internal/ui/menu.go @@ -16,7 +16,7 @@ import ( const ( menuIndexFmt = " [key:-:b]<%d> [fg:-:d]%s " - maxRows = 7 + maxRows = 6 ) var menuRX = regexp.MustCompile(`\d`) diff --git a/internal/view/app.go b/internal/view/app.go index c0ac13b8..903917a1 100644 --- a/internal/view/app.go +++ b/internal/view/app.go @@ -18,7 +18,7 @@ import ( "github.com/rs/zerolog/log" ) -// ExitStatus indicates UI exit conditions. +// // ExitStatus indicates UI exit conditions. var ExitStatus = "" const ( @@ -50,7 +50,6 @@ func NewApp(cfg *config.Config) *App { Content: NewPageStack(), } a.Config = cfg - a.InitBench(cfg.K9s.CurrentCluster) a.Views()["statusIndicator"] = ui.NewStatusIndicator(a.App, a.Styles) a.Views()["clusterInfo"] = NewClusterInfo(&a) diff --git a/internal/view/browser.go b/internal/view/browser.go index 8dc6d351..80c65281 100644 --- a/internal/view/browser.go +++ b/internal/view/browser.go @@ -145,7 +145,6 @@ func (b *Browser) TableDataChanged(data render.TableData) { b.app.QueueUpdateDraw(func() { b.refreshActions() b.Update(data) - b.App().ClearStatus(false) }) } diff --git a/internal/view/container.go b/internal/view/container.go index 941b2889..e128ccac 100644 --- a/internal/view/container.go +++ b/internal/view/container.go @@ -6,13 +6,10 @@ import ( "strings" "github.com/derailed/k9s/internal/client" - "github.com/derailed/k9s/internal/dao" "github.com/derailed/k9s/internal/render" "github.com/derailed/k9s/internal/ui" - "github.com/derailed/k9s/internal/ui/dialog" "github.com/gdamore/tcell" "github.com/rs/zerolog/log" - "k8s.io/client-go/tools/portforward" ) const ( @@ -114,23 +111,11 @@ func (c *Container) portFwdCmd(evt *tcell.EventKey) *tcell.EventKey { return nil } log.Debug().Msgf("CONTAINER-PORTS %#v", ports) - dialog.ShowPortForwards(c.App().Content.Pages, c.App().Styles, c.GetTable().Path, ports, c.portForward) + ShowPortForwards(c, c.GetTable().Path, ports, startFwdCB) return nil } -func (c *Container) portForward(path, co string, t dao.Tunnel) { - pf := dao.NewPortForwarder(c.App().Conn()) - fw, err := pf.Start(path, co, t) - if err != nil { - c.App().Flash().Err(err) - return - } - - log.Debug().Msgf(">>> Starting port forward %q %#v", path, t) - go runForward(c.App(), pf, fw) -} - func (c *Container) isForwardable(path string) ([]string, bool) { state := c.GetTable().GetSelectedCell(3) if state != "Running" { @@ -155,24 +140,3 @@ func (c *Container) isForwardable(path string) ([]string, bool) { return pp, true } - -// ---------------------------------------------------------------------------- -// Helpers... - -func runForward(a *App, pf *dao.PortForwarder, f *portforward.PortForwarder) { - a.QueueUpdateDraw(func() { - a.factory.AddForwarder(pf) - a.Flash().Infof("PortForward activated %s:%s", pf.Path(), pf.Ports()[0]) - dialog.DismissPortForwards(a.Content.Pages) - }) - - pf.SetActive(true) - if err := f.ForwardPorts(); err != nil { - a.Flash().Err(err) - return - } - a.QueueUpdateDraw(func() { - a.factory.DeleteForwarder(pf.FQN()) - pf.SetActive(false) - }) -} diff --git a/internal/view/dp.go b/internal/view/dp.go index aa9bb793..d88464a8 100644 --- a/internal/view/dp.go +++ b/internal/view/dp.go @@ -2,13 +2,10 @@ package view import ( "github.com/derailed/k9s/internal/client" + "github.com/derailed/k9s/internal/dao" "github.com/derailed/k9s/internal/render" "github.com/derailed/k9s/internal/ui" - appsv1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime" ) const scaleDialogKey = "scale" @@ -21,8 +18,15 @@ type Deploy struct { // NewDeploy returns a new deployment view. func NewDeploy(gvr client.GVR) ResourceViewer { d := Deploy{ - ResourceViewer: NewRestartExtender( - NewScaleExtender(NewLogsExtender(NewBrowser(gvr), nil)), + ResourceViewer: NewPortForwardExtender( + NewRestartExtender( + NewScaleExtender( + NewLogsExtender( + NewBrowser(gvr), + nil, + ), + ), + ), ), } d.SetBindKeysFn(d.bindKeys) @@ -41,21 +45,19 @@ func (d *Deploy) bindKeys(aa ui.KeyActions) { } func (d *Deploy) showPods(app *App, model ui.Tabular, gvr, path string) { - o, err := app.factory.Get(d.GVR(), path, true, labels.Everything()) + var res dao.Deployment + res.Init(app.factory, client.NewGVR(d.GVR())) + + dp, err := res.GetInstance(path) if err != nil { app.Flash().Err(err) return } - var dp appsv1.Deployment - err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &dp) - if err != nil { - app.Flash().Err(err) - } - showPodsFromSelector(app, path, dp.Spec.Selector) } +// ---------------------------------------------------------------------------- // Helpers... func showPodsFromSelector(app *App, path string, sel *metav1.LabelSelector) { diff --git a/internal/view/dp_test.go b/internal/view/dp_test.go index 6adde7f7..18e94546 100644 --- a/internal/view/dp_test.go +++ b/internal/view/dp_test.go @@ -13,6 +13,5 @@ func TestDeploy(t *testing.T) { assert.Nil(t, v.Init(makeCtx())) assert.Equal(t, "Deployments", v.Name()) - assert.Equal(t, 10, len(v.Hints())) - + assert.Equal(t, 11, len(v.Hints())) } diff --git a/internal/view/ds.go b/internal/view/ds.go index c18028f2..77c24414 100644 --- a/internal/view/ds.go +++ b/internal/view/ds.go @@ -2,12 +2,9 @@ package view import ( "github.com/derailed/k9s/internal/client" + "github.com/derailed/k9s/internal/dao" "github.com/derailed/k9s/internal/render" "github.com/derailed/k9s/internal/ui" - appsv1 "k8s.io/api/apps/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime" ) // DaemonSet represents a daemon set custom viewer. @@ -18,8 +15,10 @@ type DaemonSet struct { // NewDaemonSet returns a new viewer. func NewDaemonSet(gvr client.GVR) ResourceViewer { d := DaemonSet{ - ResourceViewer: NewRestartExtender( - NewLogsExtender(NewBrowser(gvr), nil), + ResourceViewer: NewPortForwardExtender( + NewRestartExtender( + NewLogsExtender(NewBrowser(gvr), nil), + ), ), } d.SetBindKeysFn(d.bindKeys) @@ -40,14 +39,10 @@ func (d *DaemonSet) bindKeys(aa ui.KeyActions) { } func (d *DaemonSet) showPods(app *App, model ui.Tabular, _, path string) { - o, err := app.factory.Get(d.GVR(), path, true, labels.Everything()) - if err != nil { - d.App().Flash().Err(err) - return - } + var res dao.DaemonSet + res.Init(app.factory, client.NewGVR(d.GVR())) - var ds appsv1.DaemonSet - err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &ds) + ds, err := res.GetInstance(path) if err != nil { d.App().Flash().Err(err) } diff --git a/internal/view/ds_test.go b/internal/view/ds_test.go index 762ad2b1..34cfe258 100644 --- a/internal/view/ds_test.go +++ b/internal/view/ds_test.go @@ -13,5 +13,5 @@ func TestDaemonSet(t *testing.T) { assert.Nil(t, v.Init(makeCtx())) assert.Equal(t, "DaemonSets", v.Name()) - assert.Equal(t, 11, len(v.Hints())) + assert.Equal(t, 12, len(v.Hints())) } diff --git a/internal/view/help.go b/internal/view/help.go index ca257204..0758d4ca 100644 --- a/internal/view/help.go +++ b/internal/view/help.go @@ -235,11 +235,11 @@ func (h *Help) showGeneral() model.MenuHints { Description: "Clear command", }, { - Mnemonic: "Ctrl-h", + Mnemonic: "t", Description: "Toggle Header", }, { - Mnemonic: ":q", + Mnemonic: "q", Description: "Quit", }, { diff --git a/internal/ui/dialog/port_forwards.go b/internal/view/pf_dialog.go similarity index 64% rename from internal/ui/dialog/port_forwards.go rename to internal/view/pf_dialog.go index fbfc6ded..6b7e3b15 100644 --- a/internal/ui/dialog/port_forwards.go +++ b/internal/view/pf_dialog.go @@ -1,4 +1,4 @@ -package dialog +package view import ( "fmt" @@ -6,7 +6,6 @@ import ( "github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/config" - "github.com/derailed/k9s/internal/dao" "github.com/derailed/k9s/internal/ui" "github.com/derailed/tview" ) @@ -14,17 +13,19 @@ import ( const portForwardKey = "portforward" // PortForwardFunc represents a port-forward callback function. -type PortForwardFunc func(path, co string, mapper dao.Tunnel) +type PortForwardFunc func(v ResourceViewer, path, co string, mapper client.PortTunnel) // ShowPortForwards pops a port forwarding configuration dialog. -func ShowPortForwards(p *ui.Pages, s *config.Styles, path string, ports []string, okFn PortForwardFunc) { +func ShowPortForwards(v ResourceViewer, path string, ports []string, okFn PortForwardFunc) { + styles := v.App().Styles + f := tview.NewForm() f.SetItemPadding(0) f.SetButtonsAlign(tview.AlignCenter). - SetButtonBackgroundColor(s.BgColor()). - SetButtonTextColor(s.FgColor()). - SetLabelColor(config.AsColor(s.K9s.Info.FgColor)). - SetFieldTextColor(config.AsColor(s.K9s.Info.SectionColor)) + SetButtonBackgroundColor(styles.BgColor()). + SetButtonTextColor(styles.FgColor()). + SetLabelColor(config.AsColor(styles.K9s.Info.FgColor)). + SetFieldTextColor(config.AsColor(styles.K9s.Info.SectionColor)) p1, p2, address := ports[0], ports[0], "localhost" f.AddDropDown("Container Ports", ports, 0, func(sel string, _ int) { @@ -33,12 +34,12 @@ func ShowPortForwards(p *ui.Pages, s *config.Styles, path string, ports []string dropD, ok := f.GetFormItem(0).(*tview.DropDown) if ok { - dropD.SetFieldBackgroundColor(s.BgColor()) + dropD.SetFieldBackgroundColor(styles.BgColor()) list := dropD.GetList() - list.SetMainTextColor(s.FgColor()) - list.SetSelectedTextColor(s.FgColor()) - list.SetSelectedBackgroundColor(config.AsColor(s.Table().CursorColor)) - list.SetBackgroundColor(s.BgColor() + 100) + list.SetMainTextColor(styles.FgColor()) + list.SetSelectedTextColor(styles.FgColor()) + list.SetSelectedBackgroundColor(config.AsColor(styles.Table().CursorColor)) + list.SetBackgroundColor(styles.BgColor() + 100) } f.AddInputField("Local Port:", p2, 20, nil, func(p string) { p2 = p @@ -47,24 +48,27 @@ func ShowPortForwards(p *ui.Pages, s *config.Styles, path string, ports []string address = h }) + pages := v.App().Content.Pages + f.AddButton("OK", func() { - tunnel := dao.Tunnel{ + tunnel := client.PortTunnel{ Address: address, LocalPort: p2, ContainerPort: extractPort(p1), } - okFn(path, extractContainer(p1), tunnel) + okFn(v, path, extractContainer(p1), tunnel) }) f.AddButton("Cancel", func() { - DismissPortForwards(p) + DismissPortForwards(pages) }) modal := tview.NewModalForm(fmt.Sprintf("", path), f) modal.SetDoneFunc(func(_ int, b string) { - DismissPortForwards(p) + DismissPortForwards(pages) }) - p.AddPage(portForwardKey, modal, false, false) - p.ShowPage(portForwardKey) + + pages.AddPage(portForwardKey, modal, false, false) + pages.ShowPage(portForwardKey) } // DismissPortForwards dismiss the port forward dialog. diff --git a/internal/view/pf_dialog_test.go b/internal/view/pf_dialog_test.go new file mode 100644 index 00000000..f4154494 --- /dev/null +++ b/internal/view/pf_dialog_test.go @@ -0,0 +1,30 @@ +package view + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestExtractPort(t *testing.T) { + uu := map[string]struct { + port, e string + }{ + "full": { + "fred:8000", "8000", + }, + "port": { + "8000", "8000", + }, + "protocol": { + "dns:53╱UDP", "53", + }, + } + + for k := range uu { + u := uu[k] + t.Run(k, func(t *testing.T) { + assert.Equal(t, u.e, extractPort(u.port)) + }) + } +} diff --git a/internal/view/pf_extender.go b/internal/view/pf_extender.go new file mode 100644 index 00000000..1393d37a --- /dev/null +++ b/internal/view/pf_extender.go @@ -0,0 +1,155 @@ +package view + +import ( + "errors" + "fmt" + "strconv" + + "github.com/derailed/k9s/internal/client" + "github.com/derailed/k9s/internal/dao" + "github.com/derailed/k9s/internal/ui" + "github.com/derailed/k9s/internal/watch" + "github.com/gdamore/tcell" + "github.com/rs/zerolog/log" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/portforward" +) + +// PortForwardExtender adds port-forward extensions. +type PortForwardExtender struct { + ResourceViewer +} + +// NewPortForwardExtender returns a new extender. +func NewPortForwardExtender(r ResourceViewer) ResourceViewer { + s := PortForwardExtender{ResourceViewer: r} + s.bindKeys(s.Actions()) + + return &s +} + +func (p *PortForwardExtender) bindKeys(aa ui.KeyActions) { + aa.Add(ui.KeyActions{ + ui.KeyShiftF: ui.NewKeyAction("Port-Forward", p.portFwdCmd, true), + }) +} + +func (p *PortForwardExtender) portFwdCmd(evt *tcell.EventKey) *tcell.EventKey { + path := p.GetTable().GetSelectedItem() + if path == "" { + return evt + } + + pod, err := p.fetchPodName(path) + if err != nil { + p.App().Flash().Err(err) + return nil + } + if err := showFwdDialog(p, pod, startFwdCB); err != nil { + p.App().Flash().Err(err) + } + + return nil +} + +func (p *PortForwardExtender) fetchPodName(path string) (string, error) { + res, err := dao.AccessorFor(p.App().factory, client.NewGVR(p.GVR())) + if err != nil { + return "", nil + } + ctrl, ok := res.(dao.Controller) + if !ok { + return "", fmt.Errorf("expecting a controller resource for %q", p.GVR()) + } + + return ctrl.Pod(path) +} + +// ---------------------------------------------------------------------------- +// Helpers... + +func runForward(v ResourceViewer, pf watch.Forwarder, f *portforward.PortForwarder) { + v.App().factory.AddForwarder(pf) + + v.App().QueueUpdateDraw(func() { + v.App().Flash().Infof("PortForward activated %s:%s", pf.Path(), pf.Ports()[0]) + DismissPortForwards(v.App().Content.Pages) + }) + + pf.SetActive(true) + if err := f.ForwardPorts(); err != nil { + v.App().Flash().Err(err) + return + } + + v.App().QueueUpdateDraw(func() { + v.App().factory.DeleteForwarder(pf.FQN()) + pf.SetActive(false) + }) +} + +func startFwdCB(v ResourceViewer, path, co string, t client.PortTunnel) { + log.Debug().Msgf("CURRENT-FWD %#v", v.App().factory.Forwarders()) + + if _, ok := v.App().factory.ForwarderFor(dao.PortForwardID(path, co)); ok { + v.App().Flash().Err(errors.New("A port-forward is already active on this pod")) + return + } + + pf := dao.NewPortForwarder(v.App().factory) + fwd, err := pf.Start(path, co, t) + if err != nil { + v.App().Flash().Err(err) + return + } + + log.Debug().Msgf(">>> Starting port forward %q %#v", path, t) + go runForward(v, pf, fwd) +} + +func showFwdDialog(v ResourceViewer, path string, cb PortForwardFunc) error { + mm, err := fetchPodPorts(v.App().factory, path) + if err != nil { + return nil + } + ports := make([]string, 0, len(mm)) + for co, pp := range mm { + for _, p := range pp { + if p.Protocol != v1.ProtocolTCP { + continue + } + ports = append(ports, client.FQN(co, p.Name)+":"+strconv.Itoa(int(p.ContainerPort))) + } + } + + if len(ports) == 0 { + return fmt.Errorf("no tcp ports found on %s", path) + } + ShowPortForwards(v, path, ports, cb) + + return nil +} + +func fetchPodPorts(f *watch.Factory, path string) (map[string][]v1.ContainerPort, error) { + log.Debug().Msgf("Fetching ports on pod %q", path) + o, err := f.Get("v1/pods", path, false, labels.Everything()) + if err != nil { + return nil, err + } + + var pod v1.Pod + err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &pod) + if err != nil { + return nil, err + } + + pp := make(map[string][]v1.ContainerPort) + for _, co := range pod.Spec.Containers { + pp[co.Name] = co.Ports + } + + return pp, nil +} diff --git a/internal/view/pod.go b/internal/view/pod.go index 413c18d5..dd90fcaf 100644 --- a/internal/view/pod.go +++ b/internal/view/pod.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "strconv" "github.com/derailed/k9s/internal" "github.com/derailed/k9s/internal/client" @@ -12,11 +11,9 @@ import ( "github.com/derailed/k9s/internal/model" "github.com/derailed/k9s/internal/render" "github.com/derailed/k9s/internal/ui" - "github.com/derailed/k9s/internal/ui/dialog" "github.com/derailed/k9s/internal/watch" "github.com/fatih/color" "github.com/gdamore/tcell" - "github.com/rs/zerolog/log" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/labels" @@ -30,7 +27,11 @@ type Pod struct { // NewPod returns a new viewer. func NewPod(gvr client.GVR) ResourceViewer { - p := Pod{ResourceViewer: NewLogsExtender(NewBrowser(gvr), nil)} + p := Pod{ + ResourceViewer: NewPortForwardExtender( + NewLogsExtender(NewBrowser(gvr), nil), + ), + } p.SetBindKeysFn(p.bindKeys) p.GetTable().SetEnterFn(p.showContainers) p.GetTable().SetColorerFn(render.Pod{}.ColorerFunc()) @@ -51,7 +52,6 @@ func (p *Pod) bindKeys(aa ui.KeyActions) { } aa.Add(ui.KeyActions{ - ui.KeyShiftF: ui.NewKeyAction("Port-Forward", p.portFwdCmd, true), ui.KeyShiftR: ui.NewKeyAction("Sort Ready", p.GetTable().SortColCmd(1, true), false), ui.KeyShiftS: ui.NewKeyAction("Sort Status", p.GetTable().SortColCmd(2, true), false), ui.KeyShiftT: ui.NewKeyAction("Sort Restart", p.GetTable().SortColCmd(3, false), false), @@ -130,57 +130,9 @@ func (p *Pod) shellCmd(evt *tcell.EventKey) *tcell.EventKey { return nil } -func (p *Pod) portFwdCmd(evt *tcell.EventKey) *tcell.EventKey { - path := p.GetTable().GetSelectedItem() - if path == "" { - return evt - } - - if err := showFwdDialog(p.App(), path, p.portForward); err != nil { - p.App().Flash().Err(err) - } - - return nil -} - -func (p *Pod) portForward(path, co string, t dao.Tunnel) { - pf := dao.NewPortForwarder(p.App().Conn()) - fw, err := pf.Start(path, co, t) - if err != nil { - p.App().Flash().Err(err) - return - } - - log.Debug().Msgf(">>> Starting port forward %q:%s %v", path, co, t) - go runForward(p.App(), pf, fw) -} - // ---------------------------------------------------------------------------- // Helpers... -func showFwdDialog(a *App, path string, cb dialog.PortForwardFunc) error { - mm, err := fetchPodPorts(a.factory, path) - if err != nil { - return nil - } - ports := make([]string, 0, len(mm)) - for co, pp := range mm { - for _, p := range pp { - if p.Protocol != v1.ProtocolTCP { - continue - } - ports = append(ports, client.FQN(co, p.Name)+":"+strconv.Itoa(int(p.ContainerPort))) - } - } - - if len(ports) == 0 { - return fmt.Errorf("no tcp ports found on %s", path) - } - dialog.ShowPortForwards(a.Content.Pages, a.Styles, path, ports, cb) - - return nil -} - func containerShellin(a *App, comp model.Component, path, co string) error { if co != "" { resumeShellIn(a, comp, path, co) @@ -265,24 +217,3 @@ func fetchContainers(f *watch.Factory, path string, includeInit bool) ([]string, return nn, nil } - -func fetchPodPorts(f *watch.Factory, path string) (map[string][]v1.ContainerPort, error) { - log.Debug().Msgf("Fetching ports on pod %q", path) - o, err := f.Get("v1/pods", path, false, labels.Everything()) - if err != nil { - return nil, err - } - - var pod v1.Pod - err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &pod) - if err != nil { - return nil, err - } - - pp := make(map[string][]v1.ContainerPort) - for _, co := range pod.Spec.Containers { - pp[co.Name] = co.Ports - } - - return pp, nil -} diff --git a/internal/view/port_forward.go b/internal/view/port_forward.go index b31e7c84..3901ef75 100644 --- a/internal/view/port_forward.go +++ b/internal/view/port_forward.go @@ -3,13 +3,10 @@ package view import ( "context" "fmt" - "regexp" - "strings" "time" "github.com/derailed/k9s/internal" "github.com/derailed/k9s/internal/client" - "github.com/derailed/k9s/internal/config" "github.com/derailed/k9s/internal/dao" "github.com/derailed/k9s/internal/perf" "github.com/derailed/k9s/internal/render" @@ -44,7 +41,7 @@ func NewPortForward(gvr client.GVR) ResourceViewer { } func (p *PortForward) portForwardContext(ctx context.Context) context.Context { - return context.WithValue(ctx, internal.KeyBenchCfg, p.App().Bench) + return context.WithValue(ctx, internal.KeyBenchCfg, p.App().BenchFile) } func (p *PortForward) bindKeys(aa ui.KeyActions) { @@ -65,8 +62,6 @@ func (p *PortForward) showBenchCmd(evt *tcell.EventKey) *tcell.EventKey { return nil } -var podNameRX = regexp.MustCompile(`\A(.+)\-(\w{10})\-(\w{5})\z`) - func (p *PortForward) toggleBenchCmd(evt *tcell.EventKey) *tcell.EventKey { if p.bench != nil { p.App().Status(ui.FlashErr, "Benchmark Canceled!") @@ -79,46 +74,28 @@ func (p *PortForward) toggleBenchCmd(evt *tcell.EventKey) *tcell.EventKey { if path == "" { return nil } - tokens := strings.Split(path, ":") - ns, po := client.Namespaced(tokens[0]) - sections := podNameRX.FindStringSubmatch(po) - log.Debug().Msgf("SECTIONS %q::%q--%#v", ns, po, sections) - if len(sections) >= 1 { - po = sections[1] - } - key := client.FQN(ns, po) + ":" + tokens[1] - - cfg := defaultConfig() - if defaults := p.App().Bench.Benchmarks.Defaults; !defaults.Empty() { - cfg.C, cfg.N = defaults.C, defaults.N - } - - log.Debug().Msgf("CUST-CFG %q -- %#v", path, key) - if b, ok := p.App().Bench.Benchmarks.Containers[key]; ok { - log.Debug().Msgf("FOUND CUST BENCH_CFG!") - cfg = b - } + cfg := dao.BenchConfigFor(p.App().BenchFile, path) cfg.Name = path - log.Debug().Msgf("BenchCFG %q::%#v", path, cfg) - r, _ := p.GetTable().GetSelection() base := ui.TrimCell(p.GetTable().SelectTable, r, 4) var err error - if p.bench, err = perf.NewBenchmark(base, p.App().version, cfg); err != nil { + p.bench, err = perf.NewBenchmark(base, p.App().version, cfg) + if err != nil { p.App().Flash().Errf("Bench failed %v", err) p.App().ClearStatus(false) return nil } p.App().Status(ui.FlashWarn, "Benchmark in progress...") - log.Debug().Msg("Bench starting...") go p.runBenchmark() return nil } func (p *PortForward) runBenchmark() { + log.Debug().Msg("Bench starting...") + p.bench.Run(p.App().Config.K9s.CurrentCluster, func() { log.Debug().Msg("Bench Completed!") p.App().QueueUpdate(func() { @@ -147,7 +124,6 @@ func (p *PortForward) deleteCmd(evt *tcell.EventKey) *tcell.EventKey { if path == "" { return nil } - log.Debug().Msgf("PF DELETE %q", path) showModal(p.App().Content.Pages, fmt.Sprintf("Delete PortForward `%s?", path), func() { var pf dao.PortForward @@ -166,17 +142,6 @@ func (p *PortForward) deleteCmd(evt *tcell.EventKey) *tcell.EventKey { // ---------------------------------------------------------------------------- // Helpers... -func defaultConfig() config.BenchConfig { - return config.BenchConfig{ - C: config.DefaultC, - N: config.DefaultN, - HTTP: config.HTTP{ - Method: config.DefaultMethod, - Path: "/", - }, - } -} - func showModal(p *ui.Pages, msg string, ok func()) { m := tview.NewModal(). AddButtons([]string{"Cancel", "OK"}). diff --git a/internal/view/sts.go b/internal/view/sts.go index 01930512..23cf7d97 100644 --- a/internal/view/sts.go +++ b/internal/view/sts.go @@ -18,9 +18,11 @@ type StatefulSet struct { // NewStatefulSet returns a new viewer. func NewStatefulSet(gvr client.GVR) ResourceViewer { s := StatefulSet{ - ResourceViewer: NewRestartExtender( - NewScaleExtender( - NewLogsExtender(NewBrowser(gvr), nil), + ResourceViewer: NewPortForwardExtender( + NewRestartExtender( + NewScaleExtender( + NewLogsExtender(NewBrowser(gvr), nil), + ), ), ), } diff --git a/internal/view/sts_test.go b/internal/view/sts_test.go index bf32d2d7..57deed3f 100644 --- a/internal/view/sts_test.go +++ b/internal/view/sts_test.go @@ -13,5 +13,5 @@ func TestStatefulSetNew(t *testing.T) { assert.Nil(t, s.Init(makeCtx())) assert.Equal(t, "StatefulSets", s.Name()) - assert.Equal(t, 8, len(s.Hints())) + assert.Equal(t, 9, len(s.Hints())) } diff --git a/internal/view/svc.go b/internal/view/svc.go index b8270991..51711e63 100644 --- a/internal/view/svc.go +++ b/internal/view/svc.go @@ -13,10 +13,6 @@ import ( "github.com/derailed/k9s/internal/ui" "github.com/gdamore/tcell" "github.com/rs/zerolog/log" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime" ) // Service represents a service viewer. @@ -29,7 +25,9 @@ type Service struct { // NewService returns a new viewer. func NewService(gvr client.GVR) ResourceViewer { s := Service{ - ResourceViewer: NewLogsExtender(NewBrowser(gvr), nil), + ResourceViewer: NewPortForwardExtender( + NewLogsExtender(NewBrowser(gvr), nil), + ), } s.SetBindKeysFn(s.bindKeys) s.GetTable().SetEnterFn(s.showPods) @@ -41,78 +39,22 @@ func NewService(gvr client.GVR) ResourceViewer { func (s *Service) bindKeys(aa ui.KeyActions) { aa.Add(ui.KeyActions{ - ui.KeyShiftF: ui.NewKeyAction("Port-Forward", s.portFwdCmd, true), tcell.KeyCtrlB: ui.NewKeyAction("Bench Run/Stop", s.toggleBenchCmd, true), ui.KeyShiftT: ui.NewKeyAction("Sort Type", s.GetTable().SortColCmd(1, true), false), }) } -func podFromSelector(f dao.Factory, ns string, sel map[string]string) (string, error) { - log.Debug().Msgf("Looking for pods %q:%v -- %v", ns, sel, labels.Set(sel).AsSelector()) - oo, err := f.List("v1/pods", ns, true, labels.Set(sel).AsSelector()) +func (s *Service) showPods(a *App, _ ui.Tabular, gvr, path string) { + var res dao.Service + res.Init(a.factory, client.NewGVR(s.GVR())) + + svc, err := res.GetInstance(path) if err != nil { - return "", err - } - - if len(oo) == 0 { - return "", fmt.Errorf("no matching pods for %v", sel) - } - - var pod v1.Pod - err = runtime.DefaultUnstructuredConverter.FromUnstructured(oo[0].(*unstructured.Unstructured).Object, &pod) - if err != nil { - return "", err - } - - return client.FQN(pod.Namespace, pod.Name), nil -} - -func (s *Service) portFwdCmd(evt *tcell.EventKey) *tcell.EventKey { - path := s.GetTable().GetSelectedItem() - if path == "" { - return evt - } - - svc, err := fetchService(s.App().factory, s.GVR(), path) - if err != nil { - s.App().Flash().Err(err) - return nil - } - - ns, _ := client.Namespaced(path) - pod, err := podFromSelector(s.App().factory, ns, svc.Spec.Selector) - if err != nil { - s.App().Flash().Err(err) - return nil - } - - if err := showFwdDialog(s.App(), pod, s.portForward); err != nil { - s.App().Flash().Err(err) - } - - return nil -} - -func (s *Service) portForward(path, co string, t dao.Tunnel) { - pf := dao.NewPortForwarder(s.App().Conn()) - fw, err := pf.Start(path, co, t) - if err != nil { - s.App().Flash().Err(err) + a.Flash().Err(err) return } - log.Debug().Msgf(">>> Starting port forward %q %#v", path, t) - go runForward(s.App(), pf, fw) -} - -func (s *Service) showPods(app *App, _ ui.Tabular, gvr, path string) { - svc, err := fetchService(app.factory, gvr, path) - if err != nil { - app.Flash().Err(err) - return - } - - showPodsWithLabels(app, path, svc.Spec.Selector) + showPodsWithLabels(a, path, svc.Spec.Selector) } func (s *Service) checkSvc(row int) error { @@ -140,11 +82,6 @@ func (s *Service) getExternalPort(row int) (string, error) { return tokens[1], nil } -func (s *Service) reloadBenchCfg() error { - path := ui.BenchConfig(s.App().Config.K9s.CurrentCluster) - return s.App().Bench.Reload(path) -} - func (s *Service) toggleBenchCmd(evt *tcell.EventKey) *tcell.EventKey { if s.bench != nil { log.Debug().Msg(">>> Benchmark canceled!!") @@ -159,12 +96,12 @@ func (s *Service) toggleBenchCmd(evt *tcell.EventKey) *tcell.EventKey { return evt } - if err := s.reloadBenchCfg(); err != nil { - s.App().Flash().Err(err) - return nil + cust, err := config.NewBench(s.App().BenchFile) + if err != nil { + log.Debug().Msgf("No custom benchmark config file found") } - cfg, ok := s.App().Bench.Benchmarks.Services[sel] + cfg, ok := cust.Benchmarks.Services[sel] if !ok { s.App().Flash().Errf("No bench config found for service %s", sel) return nil @@ -173,8 +110,8 @@ func (s *Service) toggleBenchCmd(evt *tcell.EventKey) *tcell.EventKey { log.Debug().Msgf("Benchmark config %#v", cfg) row := s.GetTable().GetSelectedRowIndex() - if err := s.checkSvc(row); err != nil { - s.App().Flash().Err(err) + if e := s.checkSvc(row); e != nil { + s.App().Flash().Err(e) return nil } port, err := s.getExternalPort(row) @@ -227,18 +164,6 @@ func (s *Service) benchDone() { // ---------------------------------------------------------------------------- // Helpers... -func fetchService(f dao.Factory, gvr, path string) (*v1.Service, error) { - o, err := f.Get(gvr, path, true, labels.Everything()) - if err != nil { - return nil, err - } - - var svc v1.Service - err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &svc) - - return &svc, err -} - func benchTimedOut(app *App) { <-time.After(2 * time.Second) app.QueueUpdate(func() { diff --git a/internal/view/types.go b/internal/view/types.go index e55f9490..8b8020c1 100644 --- a/internal/view/types.go +++ b/internal/view/types.go @@ -77,6 +77,8 @@ type ResourceViewer interface { // SetBindKeys provision additional key bindings. SetBindKeysFn(BindKeysFunc) + + // SetInstance sets a parent FQN SetInstance(string) } diff --git a/internal/watch/factory.go b/internal/watch/factory.go index 3fe01958..32d86ae6 100644 --- a/internal/watch/factory.go +++ b/internal/watch/factory.go @@ -218,6 +218,9 @@ func (f *Factory) ensureFactory(ns string) di.DynamicSharedInformerFactory { // AddForwarder registers a new portforward for a given container. func (f *Factory) AddForwarder(pf Forwarder) { + f.mx.Lock() + defer f.mx.Unlock() + f.forwarders[pf.Path()] = pf } @@ -237,6 +240,9 @@ func (f *Factory) Forwarders() Forwarders { // ForwarderFor returns a portforward for a given container or nil if none exists. func (f *Factory) ForwarderFor(path string) (Forwarder, bool) { + f.mx.RLock() + defer f.mx.RUnlock() + fwd, ok := f.forwarders[path] return fwd, ok } diff --git a/internal/watch/forwarders.go b/internal/watch/forwarders.go index 60464f32..4ec6dd33 100644 --- a/internal/watch/forwarders.go +++ b/internal/watch/forwarders.go @@ -3,14 +3,15 @@ package watch import ( "strings" + "github.com/derailed/k9s/internal/client" "github.com/rs/zerolog/log" + "k8s.io/client-go/tools/portforward" ) // Forwarder represents a port forwarder. type Forwarder interface { - // BOZO!! - // // Start initializes a port forward. - // Start(path, co, string, t dao.Tunnel) (*portforward.PortForwarder, error) + // Start starts a port-forward. + Start(path, co string, t client.PortTunnel) (*portforward.PortForwarder, error) // Stop terminates a port forward. Stop() @@ -24,11 +25,20 @@ type Forwarder interface { // Ports returns container exposed ports. Ports() []string + // FQN returns the full port-forward name. + FQN() string + // Active returns forwarder current state. Active() bool + // SetActive sets port-forward state. + SetActive(bool) + // Age returns forwarder age. Age() string + + // HasPortMapping returns true if port mapping exists. + HasPortMapping(string) bool } // Forwarders tracks active port forwards. From fc115c5476ba66852a918612c6e681a395f44c97 Mon Sep 17 00:00:00 2001 From: Anthony Cruz Date: Fri, 14 Feb 2020 13:43:17 -0800 Subject: [PATCH 40/58] Update help mnemonic for Toggle Header This change complements what had already been started for #546. --- internal/view/help.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/view/help.go b/internal/view/help.go index ca257204..4c33128b 100644 --- a/internal/view/help.go +++ b/internal/view/help.go @@ -235,7 +235,7 @@ func (h *Help) showGeneral() model.MenuHints { Description: "Clear command", }, { - Mnemonic: "Ctrl-h", + Mnemonic: "t", Description: "Toggle Header", }, { From a76d5809b8223278261da33504e15a323fb89015 Mon Sep 17 00:00:00 2001 From: derailed Date: Fri, 14 Feb 2020 16:31:52 -0700 Subject: [PATCH 41/58] checkpoint --- internal/dao/healthz.go | 45 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 internal/dao/healthz.go diff --git a/internal/dao/healthz.go b/internal/dao/healthz.go new file mode 100644 index 00000000..75e18971 --- /dev/null +++ b/internal/dao/healthz.go @@ -0,0 +1,45 @@ +package dao + +import ( + "context" + + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" +) + +type Healthz struct { + Resource string + Count int64 + Errors int64 +} + +type Pulse interface{} +type Pulses []Pulse + + +func ClusterHealth(ctx context.Context, gvr string) (Pulses, error) { + var h Healthz + + oo, err := p.List(ctx, "") + if err != nil { + return nil, err + } + + h.Count = len(oo) + for _, o := range oo { + var pod v1.Pod + err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &pod) + if err != nil { + return nil, err + } + + if !happy(pod) { + h.Errors++ + } + } +} + +func happy(p v1.Pod) bool { + +} From 889e5131cf9558056690b375f1702fb1a03479b4 Mon Sep 17 00:00:00 2001 From: derailed Date: Fri, 14 Feb 2020 16:43:41 -0700 Subject: [PATCH 42/58] add rel notes --- change_logs/release_v0.15.2.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 change_logs/release_v0.15.2.md diff --git a/change_logs/release_v0.15.2.md b/change_logs/release_v0.15.2.md new file mode 100644 index 00000000..6c29b88b --- /dev/null +++ b/change_logs/release_v0.15.2.md @@ -0,0 +1,23 @@ + + +# Release v0.15.2 + +## Notes + +Thank you to all that contributed with flushing out issues and enhancements for K9s! I'll try to mark some of these issues as fixed. But if you don't mind grab the latest rev and see if we're happier with some of the fixes! If you've filed an issue please help me verify and close. Your support, kindness and awesome suggestions to make K9s better is as ever very much noticed and appreciated! + +Also if you dig this tool, please make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer) + +On Slack? Please join us [K9slackers](https://join.slack.com/t/k9sers/shared_invite/enQtOTA5MDEyNzI5MTU0LWQ1ZGI3MzliYzZhZWEyNzYxYzA3NjE0YTk1YmFmNzViZjIyNzhkZGI0MmJjYzhlNjdlMGJhYzE2ZGU1NjkyNTM) + +--- + +## Mo PortForwards... + +While putting together the [OpenFeeZ video](https://youtu.be/7Fx4XQ2ftpM), I've noticed a few issues with port-forwards and benchmarks. While I was doing surgery on that carp, figured why not go pull a full monty on port-forwards and enable for other controller like resources such as deployments, statefulsets and daemonsets. So now you can set up port-forwards on any of these using `shift-f`. This exhibits the same mechanics as service based port-forwards ie pick a container port from pods matching the controller selector. + +## Resolved Bugs/Features/PRs + +--- + + © 2020 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0) From 355f4ce39605f3d8cd83cb2a85064b0b6064ea92 Mon Sep 17 00:00:00 2001 From: derailed Date: Wed, 19 Feb 2020 18:25:36 -0700 Subject: [PATCH 43/58] checkpoint --- .goreleaser.yml | 1 + assets/k9s_health.png | Bin 0 -> 748240 bytes go.mod | 4 +- go.sum | 4 + internal/client/metrics.go | 155 ++++++++---- internal/client/types.go | 3 + internal/config/alias.go | 126 +++++----- internal/config/alias_test.go | 4 +- internal/config/styles.go | 215 ++++++++++------ internal/config/styles_test.go | 16 +- internal/dao/container.go | 24 +- internal/dao/dp.go | 5 + internal/dao/ds.go | 5 + internal/dao/healthz.go | 45 ---- internal/dao/node.go | 12 +- internal/dao/pod.go | 31 ++- internal/dao/pulse.go | 16 ++ internal/dao/registry.go | 7 + internal/dao/rs.go | 23 ++ internal/dao/sts.go | 5 + internal/health/check.go | 54 ++++ internal/health/check_test.go | 26 ++ internal/health/types.go | 44 ++++ internal/keys.go | 2 + internal/model/cluster.go | 2 +- internal/model/flash.go | 153 +++++++++++ internal/model/flash_test.go | 105 ++++++++ internal/model/health_one.go | 118 +++++++++ internal/model/pulse.go | 156 ++++++++++++ internal/model/registry.go | 3 + internal/model/stack.go | 10 +- internal/model/table.go | 2 + internal/model/table_int_test.go | 6 +- internal/model/table_test.go | 3 +- internal/model/tree.go | 4 +- internal/render/benchmark.go | 30 ++- internal/render/chart.go | 14 ++ internal/render/container.go | 35 ++- internal/render/container_test.go | 1 + internal/render/cr.go | 2 + internal/render/crb.go | 4 +- internal/render/crb_test.go | 2 +- internal/render/crd.go | 2 + internal/render/cronjob.go | 64 +++++ internal/render/dp.go | 26 +- internal/render/ds.go | 21 +- internal/render/ev.go | 30 ++- internal/render/ev_test.go | 14 +- internal/render/generic.go | 5 + internal/render/helpers.go | 50 +++- internal/render/helpers_test.go | 11 +- internal/render/hpa.go | 4 + internal/render/ing.go | 2 + internal/render/job.go | 23 +- internal/render/job_test.go | 2 +- internal/render/node.go | 59 ++++- internal/render/np.go | 8 +- internal/render/ns.go | 21 +- internal/render/ofaas.go | 17 +- internal/render/pdb.go | 27 +- internal/render/pod.go | 54 ++-- internal/render/pod_test.go | 16 +- internal/render/policy.go | 17 +- internal/render/policy_test.go | 1 + internal/render/port_forward_test.go | 1 + internal/render/portforward.go | 2 + internal/render/pv.go | 39 ++- internal/render/pvc.go | 29 ++- internal/render/rbac.go | 11 +- internal/render/ro.go | 4 + internal/render/rob.go | 10 +- internal/render/rob_test.go | 2 +- internal/render/row.go | 5 + internal/render/row_event.go | 2 +- internal/render/row_header.go | 25 +- internal/render/rs.go | 31 ++- internal/render/sa.go | 4 + internal/render/sc.go | 4 + internal/render/screen_dump.go | 4 + internal/render/screen_dump_test.go | 2 + internal/render/sts.go | 37 +-- internal/render/sts_test.go | 2 +- internal/render/subject.go | 7 + internal/render/svc.go | 23 +- internal/render/svc_test.go | 2 +- internal/tchart/component.go | 128 ++++++++++ internal/tchart/dot_matrix.go | 106 ++++++++ internal/tchart/dot_matrix_test.go | 126 ++++++++++ internal/tchart/gauge.go | 149 +++++++++++ internal/tchart/sparkline.go | 161 ++++++++++++ internal/ui/app.go | 14 +- internal/ui/app_test.go | 3 +- internal/ui/config.go | 14 +- internal/ui/flash.go | 144 +++-------- internal/ui/flash_test.go | 63 +++-- internal/ui/logo.go | 14 +- internal/ui/menu.go | 12 +- internal/ui/table.go | 107 +++++--- internal/ui/table_helper.go | 35 ++- internal/ui/table_test.go | 1 + internal/view/alias.go | 8 + internal/view/alias_test.go | 3 +- internal/view/app.go | 30 ++- internal/view/browser.go | 19 +- internal/view/cluster_info.go | 6 +- internal/view/container.go | 2 +- internal/view/container_test.go | 2 +- internal/view/context_test.go | 2 +- internal/view/details.go | 2 +- internal/view/dp.go | 2 +- internal/view/dp_test.go | 2 +- internal/view/ds.go | 2 +- internal/view/ds_test.go | 2 +- internal/view/env.go | 15 +- internal/view/event.go | 7 + internal/view/exec.go | 34 ++- internal/view/help.go | 2 +- internal/view/help_test.go | 2 +- internal/view/log.go | 8 +- internal/view/log_indicator.go | 2 +- internal/view/ns.go | 5 +- internal/view/ns_test.go | 2 +- internal/view/ofaas.go | 2 +- internal/view/pf_dialog.go | 22 +- internal/view/pf_dialog_test.go | 26 ++ internal/view/pod.go | 6 +- internal/view/pod_test.go | 2 +- internal/view/port_forward.go | 9 +- internal/view/port_forward_test.go | 2 +- internal/view/pulse.go | 362 +++++++++++++++++++++++++++ internal/view/rbac_test.go | 2 +- internal/view/registrar.go | 3 + internal/view/screen_dump_test.go | 2 +- internal/view/secret_test.go | 2 +- internal/view/sts_test.go | 2 +- internal/view/svc.go | 9 +- internal/view/svc_test.go | 2 +- internal/view/table.go | 14 ++ internal/view/table_int_test.go | 1 + internal/view/xray.go | 18 +- internal/view/yaml.go | 12 +- plugins/job_suspend.yml | 4 +- 142 files changed, 3150 insertions(+), 785 deletions(-) create mode 100644 assets/k9s_health.png delete mode 100644 internal/dao/healthz.go create mode 100644 internal/dao/pulse.go create mode 100644 internal/dao/rs.go create mode 100644 internal/health/check.go create mode 100644 internal/health/check_test.go create mode 100644 internal/health/types.go create mode 100644 internal/model/flash.go create mode 100644 internal/model/flash_test.go create mode 100644 internal/model/health_one.go create mode 100644 internal/model/pulse.go create mode 100644 internal/tchart/component.go create mode 100644 internal/tchart/dot_matrix.go create mode 100644 internal/tchart/dot_matrix_test.go create mode 100644 internal/tchart/gauge.go create mode 100644 internal/tchart/sparkline.go create mode 100644 internal/view/pulse.go diff --git a/.goreleaser.yml b/.goreleaser.yml index 2643bb05..dbc015af 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -16,6 +16,7 @@ builds: - 386 - amd64 - arm64 + - armhf goarm: - 6 - 7 diff --git a/assets/k9s_health.png b/assets/k9s_health.png new file mode 100644 index 0000000000000000000000000000000000000000..e653dcfdf76148f8d9a23bb5e076cb42f82acc79 GIT binary patch literal 748240 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�iTKY)mScICwlF!5;!%onC?1I&e?AyCO{ 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%0D`=puHNh1hMV&8kZzwM5Q=&wmv6pDg5 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Ξ>=N!8V#Wi-Bo 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 z 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

3Vux>RlY@vf^5)dSTd1x}0w z>uRspW@sql$E%lJimhJelT+&9gz)#J+E$Zr_a52=hlQT-sRHN zKzDALKk-$`!NMw4JpyapmA!{5jzz1@be(k7#%+o5a`-V+{W8^LG0UH?M$bt;jP^$W zKB3l1q{Wrp;XN2# z0+)~zC=YWd-@4R`#|GBPt9=e9(L8v17&?7beF`kg1GMvi%#_Q1wl}u>->WOh>A{uF zfCK0TY!JYS;H2#&$e~W1?hL)Dgv%i_h5EhV_{YKb=y8j0ua+J)T`vE4H(ffA${V*- z>psruO)o3Y%QdJl^;JBPS&qcolxmF7jx%3+)m-5r9l}mH>>#bBJ**5og*dy!gY z6ZHhvMx&~^_p!V|5>qgqE^LdBJyd@^nQiG@#) z>%r4L_ZNiLnN?N}3$rzRxp;}HXUX7WFP=SJ+x{Z(c}K%J}@w~!DB`Ok|DU80bckRSF$|k zl2(KvsUhHZon6T1bge5Em-l=WeA$|FyEoPqgHI{U5^sxL{x;~le|ufF_Sem0(8$kU z)6V->9Y8ja8paXW#^62E;2>~@FzFdkB2RZVXG6F}O;poLja8}L%p#Qw8GuDdP@R8pNxW=2iQa0coKTqQ~pNI$3@KCwH1eF1c2IrD@ zf66rrl&%k_s!n2<8wh%r6&U36!hXY~u`N4zZ!QyodO9u*N3#M*0e`Nxgv2HM(tt-o zFfQu_Wƍ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%0A@cm! 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 m{*`p|ucVv*M= 0 { + p.listeners = append(p.listeners[:victim], p.listeners[victim+1:]...) + } +} + +func (p *Pulse) firePulseChanged(check *health.Check) { + for _, l := range p.listeners { + l.PulseChanged(check) + } +} + +func (p *Pulse) firePulseFailed(err error) { + for _, l := range p.listeners { + l.PulseFailed(err) + } +} diff --git a/internal/model/registry.go b/internal/model/registry.go index 997ddfe2..0dde91f1 100644 --- a/internal/model/registry.go +++ b/internal/model/registry.go @@ -14,6 +14,9 @@ var Registry = map[string]ResourceMeta{ DAO: &dao.Chart{}, Renderer: &render.Chart{}, }, + "pulses": { + DAO: &dao.Pulse{}, + }, "openfaas": { DAO: &dao.OpenFaas{}, Renderer: &render.OpenFaas{}, diff --git a/internal/model/stack.go b/internal/model/stack.go index b2ffb3cb..53cd0fea 100644 --- a/internal/model/stack.go +++ b/internal/model/stack.go @@ -108,8 +108,8 @@ func (s *Stack) Pop() (Component, bool) { var c Component s.mx.Lock() { - c = s.components[s.size()] - s.components = s.components[:s.size()] + c = s.components[len(s.components)-1] + s.components = s.components[:len(s.components)-1] } s.mx.Unlock() s.notify(StackPop, c) @@ -163,11 +163,7 @@ func (s *Stack) Top() Component { return nil } - return s.components[s.size()] -} - -func (s *Stack) size() int { - return len(s.components) - 1 + return s.components[len(s.components)-1] } func (s *Stack) notify(a StackAction, c Component) { diff --git a/internal/model/table.go b/internal/model/table.go index e54decbf..75bba3f5 100644 --- a/internal/model/table.go +++ b/internal/model/table.go @@ -162,6 +162,7 @@ func (t *Table) SetRefreshRate(d time.Duration) { // ClusterWide checks if resource is scope for all namespaces. func (t *Table) ClusterWide() bool { + log.Debug().Msgf("CLUSTER-WIDE %q", t.namespace) return client.IsClusterWide(t.namespace) } @@ -219,6 +220,7 @@ func (t *Table) list(ctx context.Context, a dao.Accessor) ([]runtime.Object, err if client.IsClusterScoped(t.namespace) { ns = client.AllNamespaces } + return a.List(ctx, ns) } diff --git a/internal/model/table_int_test.go b/internal/model/table_int_test.go index 123da35c..9033d021 100644 --- a/internal/model/table_int_test.go +++ b/internal/model/table_int_test.go @@ -29,10 +29,11 @@ func TestTableReconcile(t *testing.T) { f.rows = []runtime.Object{load(t, "p1")} ctx := context.WithValue(context.Background(), internal.KeyFactory, f) ctx = context.WithValue(ctx, internal.KeyFields, "") + ctx = context.WithValue(ctx, internal.KeyWithMetrics, false) err := ta.reconcile(ctx) assert.Nil(t, err) data := ta.Peek() - assert.Equal(t, 15, len(data.Header)) + assert.Equal(t, 17, len(data.Header)) assert.Equal(t, 1, len(data.RowEvents)) assert.Equal(t, client.NamespaceAll, data.Namespace) } @@ -55,6 +56,7 @@ func TestTableGet(t *testing.T) { f := makeFactory() f.rows = []runtime.Object{load(t, "p1")} ctx := context.WithValue(context.Background(), internal.KeyFactory, f) + ctx = context.WithValue(ctx, internal.KeyWithMetrics, false) row, err := ta.Get(ctx, "fred") assert.Nil(t, err) assert.NotNil(t, row) @@ -104,7 +106,7 @@ func TestTableHydrate(t *testing.T) { assert.Nil(t, hydrate("blee", oo, rr, render.Pod{})) assert.Equal(t, 1, len(rr)) - assert.Equal(t, 14, len(rr[0].Fields)) + assert.Equal(t, 16, len(rr[0].Fields)) } func TestTableGenericHydrate(t *testing.T) { diff --git a/internal/model/table_test.go b/internal/model/table_test.go index 0ae6da2d..f58187ae 100644 --- a/internal/model/table_test.go +++ b/internal/model/table_test.go @@ -30,9 +30,10 @@ func TestTableRefresh(t *testing.T) { f.rows = []runtime.Object{mustLoad("p1")} ctx := context.WithValue(context.Background(), internal.KeyFactory, f) ctx = context.WithValue(ctx, internal.KeyFields, "") + ctx = context.WithValue(ctx, internal.KeyWithMetrics, false) ta.Refresh(ctx) data := ta.Peek() - assert.Equal(t, 15, len(data.Header)) + assert.Equal(t, 17, len(data.Header)) assert.Equal(t, 1, len(data.RowEvents)) assert.Equal(t, client.NamespaceAll, data.Namespace) assert.Equal(t, 1, l.count) diff --git a/internal/model/tree.go b/internal/model/tree.go index 55dc4284..400944e1 100644 --- a/internal/model/tree.go +++ b/internal/model/tree.go @@ -229,7 +229,7 @@ func (t *Tree) reconcile(ctx context.Context) error { } if t.root == nil || t.root.Diff(root) { t.root = root - t.fireTreeTreeChanged(t.root) + t.fireTreeChanged(t.root) } return nil @@ -251,7 +251,7 @@ func (t *Tree) resourceMeta() ResourceMeta { return meta } -func (t *Tree) fireTreeTreeChanged(root *xray.TreeNode) { +func (t *Tree) fireTreeChanged(root *xray.TreeNode) { for _, l := range t.listeners { l.TreeChanged(root) } diff --git a/internal/render/benchmark.go b/internal/render/benchmark.go index 68da849a..2f137de9 100644 --- a/internal/render/benchmark.go +++ b/internal/render/benchmark.go @@ -1,6 +1,7 @@ package render import ( + "errors" "fmt" "io/ioutil" "os" @@ -8,6 +9,7 @@ import ( "strconv" "strings" + "github.com/derailed/k9s/internal/client" "github.com/derailed/tview" "github.com/gdamore/tcell" "golang.org/x/text/language" @@ -28,11 +30,10 @@ var ( type Benchmark struct{} // ColorerFunc colors a resource row. -func (Benchmark) ColorerFunc() ColorerFunc { +func (b Benchmark) ColorerFunc() ColorerFunc { return func(ns string, re RowEvent) tcell.Color { c := tcell.ColorPaleGreen - statusCol := 2 - if strings.TrimSpace(re.Row.Fields[statusCol]) != "pass" { + if !Happy(ns, re.Row) { c = ErrColor } return c @@ -50,6 +51,7 @@ func (Benchmark) Header(ns string) HeaderRow { Header{Name: "2XX", Align: tview.AlignRight}, Header{Name: "4XX/5XX", Align: tview.AlignRight}, Header{Name: "REPORT"}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, } } @@ -72,6 +74,24 @@ func (b Benchmark) Render(o interface{}, ns string, r *Row) error { return err } b.augmentRow(r.Fields, data) + r.Fields[8] = asStatus(b.diagnose(ns, r.Fields)) + + return nil +} + +// Happy returns true if resoure is happy, false otherwise +func (Benchmark) diagnose(ns string, ff Fields) error { + statusCol := 3 + if !client.IsAllNamespaces(ns) { + statusCol-- + } + + if len(ff) < statusCol { + return nil + } + if ff[statusCol] != "pass" { + return errors.New("failed benchmark") + } return nil } @@ -87,7 +107,7 @@ func (Benchmark) readFile(file string) (string, error) { return string(data), nil } -func (Benchmark) initRow(row Fields, f os.FileInfo) error { +func (b Benchmark) initRow(row Fields, f os.FileInfo) error { tokens := strings.Split(f.Name(), "_") if len(tokens) < 2 { return fmt.Errorf("Invalid file name %s", f.Name()) @@ -95,7 +115,7 @@ func (Benchmark) initRow(row Fields, f os.FileInfo) error { row[0] = tokens[0] row[1] = tokens[1] row[7] = f.Name() - row[8] = timeToAge(f.ModTime()) + row[9] = timeToAge(f.ModTime()) return nil } diff --git a/internal/render/chart.go b/internal/render/chart.go index f1ab5892..0cfbdfb0 100644 --- a/internal/render/chart.go +++ b/internal/render/chart.go @@ -18,6 +18,10 @@ type Chart struct{} // ColorerFunc colors a resource row. func (Chart) ColorerFunc() ColorerFunc { return func(ns string, re RowEvent) tcell.Color { + if !Happy(ns, re.Row) { + return ErrColor + } + return tcell.ColorMediumSpringGreen } } @@ -35,6 +39,7 @@ func (Chart) Header(ns string) HeaderRow { Header{Name: "STATUS"}, Header{Name: "CHART"}, Header{Name: "APP VERSION"}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, ) } @@ -57,12 +62,21 @@ func (c Chart) Render(o interface{}, ns string, r *Row) error { h.Release.Info.Status.String(), h.Release.Chart.Metadata.Name+"-"+h.Release.Chart.Metadata.Version, h.Release.Chart.Metadata.AppVersion, + asStatus(c.diagnose(h.Release.Info.Status.String())), toAge(metav1.Time{Time: h.Release.Info.LastDeployed.Time}), ) return nil } +func (c Chart) diagnose(s string) error { + if s != "deployed" { + return fmt.Errorf("chart is in an invalid state") + } + + return nil +} + // ---------------------------------------------------------------------------- // Helpers... diff --git a/internal/render/container.go b/internal/render/container.go index 0e74e04f..410c55c4 100644 --- a/internal/render/container.go +++ b/internal/render/container.go @@ -1,6 +1,7 @@ package render import ( + "errors" "fmt" "strconv" "strings" @@ -36,18 +37,18 @@ type ContainerWithMetrics interface { // Container renders a K8s Container to screen. type Container struct{} +const readyCol = 2 + // ColorerFunc colors a resource row. -func (Container) ColorerFunc() ColorerFunc { - return func(ns string, r RowEvent) tcell.Color { - c := DefaultColorer(ns, r) +func (c Container) ColorerFunc() ColorerFunc { + return func(ns string, re RowEvent) tcell.Color { + color := DefaultColorer(ns, re) - readyCol := 2 - if strings.TrimSpace(r.Row.Fields[readyCol]) == "false" { - c = ErrColor + if !Happy(ns, re.Row) { + color = ErrColor } - stateCol := readyCol + 1 - switch strings.TrimSpace(r.Row.Fields[stateCol]) { + switch strings.TrimSpace(re.Row.Fields[stateCol]) { case ContainerCreating, PodInitializing: return AddColor case Terminating, Initialized: @@ -56,10 +57,10 @@ func (Container) ColorerFunc() ColorerFunc { return CompletedColor case Running: default: - c = ErrColor + color = ErrColor } - return c + return color } } @@ -80,6 +81,7 @@ func (Container) Header(ns string) HeaderRow { Header{Name: "%CPU/L", Align: tview.AlignRight}, Header{Name: "%MEM/L", Align: tview.AlignRight}, Header{Name: "PORTS"}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, } } @@ -114,12 +116,25 @@ func (c Container) Render(o interface{}, name string, r *Row) error { limit.cpu, limit.mem, toStrPorts(co.Container.Ports), + asStatus(c.diagnose(state, ready)), toAge(co.Age), ) return nil } +// Happy returns true if resoure is happy, false otherwise +func (Container) diagnose(state, ready string) error { + if state == "Completed" { + return nil + } + + if ready == "false" { + return errors.New("container is not ready") + } + return nil +} + // ---------------------------------------------------------------------------- // Helpers... diff --git a/internal/render/container_test.go b/internal/render/container_test.go index 051cb2fb..1d14321a 100644 --- a/internal/render/container_test.go +++ b/internal/render/container_test.go @@ -41,6 +41,7 @@ func TestContainer(t *testing.T) { "50", "20", "", + "container is not ready", }, r.Fields[:len(r.Fields)-1], ) diff --git a/internal/render/cr.go b/internal/render/cr.go index aed5710c..5b7c5734 100644 --- a/internal/render/cr.go +++ b/internal/render/cr.go @@ -21,6 +21,7 @@ func (ClusterRole) ColorerFunc() ColorerFunc { func (ClusterRole) Header(string) HeaderRow { return HeaderRow{ Header{Name: "NAME"}, + Header{Name: "LABELS", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, } } @@ -40,6 +41,7 @@ func (ClusterRole) Render(o interface{}, ns string, r *Row) error { r.ID = client.FQN("-", cr.ObjectMeta.Name) r.Fields = Fields{ cr.Name, + mapToStr(cr.Labels), toAge(cr.ObjectMeta.CreationTimestamp), } diff --git a/internal/render/crb.go b/internal/render/crb.go index 74c4ee37..2543cfb1 100644 --- a/internal/render/crb.go +++ b/internal/render/crb.go @@ -22,8 +22,9 @@ func (ClusterRoleBinding) Header(string) HeaderRow { return HeaderRow{ Header{Name: "NAME"}, Header{Name: "CLUSTERROLE"}, - Header{Name: "KIND"}, + Header{Name: "SUBJECT-KIND"}, Header{Name: "SUBJECTS"}, + Header{Name: "LABELS", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, } } @@ -48,6 +49,7 @@ func (ClusterRoleBinding) Render(o interface{}, ns string, r *Row) error { crb.RoleRef.Name, kind, ss, + mapToStr(crb.Labels), toAge(crb.ObjectMeta.CreationTimestamp), } diff --git a/internal/render/crb_test.go b/internal/render/crb_test.go index 08f41b35..cbed129e 100644 --- a/internal/render/crb_test.go +++ b/internal/render/crb_test.go @@ -13,5 +13,5 @@ func TestClusterRoleBindingRender(t *testing.T) { c.Render(load(t, "crb"), "-", &r) assert.Equal(t, "-/blee", r.ID) - assert.Equal(t, render.Fields{"blee", "blee", "USR", "fernand"}, r.Fields[:4]) + assert.Equal(t, render.Fields{"blee", "blee", "User", "fernand"}, r.Fields[:4]) } diff --git a/internal/render/crd.go b/internal/render/crd.go index 120ebdc8..a29faf01 100644 --- a/internal/render/crd.go +++ b/internal/render/crd.go @@ -22,6 +22,7 @@ func (CustomResourceDefinition) ColorerFunc() ColorerFunc { func (CustomResourceDefinition) Header(string) HeaderRow { return HeaderRow{ Header{Name: "NAME"}, + Header{Name: "LABELS", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, } } @@ -45,6 +46,7 @@ func (CustomResourceDefinition) Render(o interface{}, ns string, r *Row) error { r.ID = client.FQN(client.ClusterScope, extractMetaField(meta, "name")) r.Fields = Fields{ extractMetaField(meta, "name"), + mapToIfc(meta["labels"]), toAge(metav1.Time{Time: t}), } diff --git a/internal/render/cronjob.go b/internal/render/cronjob.go index d389fc1c..5b182bbd 100644 --- a/internal/render/cronjob.go +++ b/internal/render/cronjob.go @@ -3,9 +3,12 @@ package render import ( "fmt" "strconv" + "strings" "github.com/derailed/k9s/internal/client" + batchv1 "k8s.io/api/batch/v1" batchv1beta1 "k8s.io/api/batch/v1beta1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" ) @@ -31,6 +34,11 @@ func (CronJob) Header(ns string) HeaderRow { Header{Name: "SUSPEND"}, Header{Name: "ACTIVE"}, Header{Name: "LAST_SCHEDULE"}, + Header{Name: "SELECTOR", Wide: true}, + Header{Name: "CONTAINERS", Wide: true}, + Header{Name: "IMAGES", Wide: true}, + Header{Name: "LABELS", Wide: true}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, ) } @@ -63,8 +71,64 @@ func (c CronJob) Render(o interface{}, ns string, r *Row) error { boolPtrToStr(cj.Spec.Suspend), strconv.Itoa(len(cj.Status.Active)), lastScheduled, + jobSelector(cj.Spec.JobTemplate.Spec), + podContainerNames(cj.Spec.JobTemplate.Spec.Template.Spec, true), + podImageNames(cj.Spec.JobTemplate.Spec.Template.Spec, true), + mapToStr(cj.Labels), + "", toAge(cj.ObjectMeta.CreationTimestamp), ) return nil } + +// Helpers + +func jobSelector(spec batchv1.JobSpec) string { + if spec.Selector == nil { + return MissingValue + } + if len(spec.Selector.MatchLabels) > 0 { + return mapToStr(spec.Selector.MatchLabels) + } + if len(spec.Selector.MatchExpressions) == 0 { + return "" + } + + ss := make([]string, 0, len(spec.Selector.MatchExpressions)) + for _, e := range spec.Selector.MatchExpressions { + ss = append(ss, e.String()) + } + + return strings.Join(ss, " ") +} + +func podContainerNames(spec v1.PodSpec, includeInit bool) string { + cc := make([]string, 0, len(spec.Containers)+len(spec.InitContainers)) + + if includeInit { + for _, c := range spec.InitContainers { + cc = append(cc, c.Name) + } + } + for _, c := range spec.Containers { + cc = append(cc, c.Name) + } + + return strings.Join(cc, ",") +} + +func podImageNames(spec v1.PodSpec, includeInit bool) string { + cc := make([]string, 0, len(spec.Containers)+len(spec.InitContainers)) + + if includeInit { + for _, c := range spec.InitContainers { + cc = append(cc, c.Image) + } + } + for _, c := range spec.Containers { + cc = append(cc, c.Image) + } + + return strings.Join(cc, ",") +} diff --git a/internal/render/dp.go b/internal/render/dp.go index 8e636f72..88424063 100644 --- a/internal/render/dp.go +++ b/internal/render/dp.go @@ -3,7 +3,6 @@ package render import ( "fmt" "strconv" - "strings" "github.com/derailed/k9s/internal/client" "github.com/derailed/tview" @@ -17,19 +16,13 @@ import ( type Deployment struct{} // ColorerFunc colors a resource row. -func (Deployment) ColorerFunc() ColorerFunc { +func (d Deployment) ColorerFunc() ColorerFunc { return func(ns string, r RowEvent) tcell.Color { c := DefaultColorer(ns, r) if r.Kind == EventAdd || r.Kind == EventUpdate { return c } - - readyCol := 2 - if !client.IsAllNamespaces(ns) { - readyCol-- - } - tokens := strings.Split(r.Row.Fields[readyCol], "/") - if tokens[0] != tokens[1] { + if !Happy(ns, r.Row) { return ErrColor } @@ -49,6 +42,9 @@ func (Deployment) Header(ns string) HeaderRow { Header{Name: "READY"}, Header{Name: "UP-TO-DATE", Align: tview.AlignRight}, Header{Name: "AVAILABLE", Align: tview.AlignRight}, + Header{Name: "READY", Align: tview.AlignRight}, + Header{Name: "LABELS", Wide: true}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, ) } @@ -73,11 +69,21 @@ func (d Deployment) Render(o interface{}, ns string, r *Row) error { } r.Fields = append(r.Fields, dp.Name, - strconv.Itoa(int(dp.Status.AvailableReplicas))+"/"+strconv.Itoa(int(*dp.Spec.Replicas)), + strconv.Itoa(int(dp.Status.AvailableReplicas))+"/"+strconv.Itoa(int(dp.Status.Replicas)), strconv.Itoa(int(dp.Status.UpdatedReplicas)), strconv.Itoa(int(dp.Status.AvailableReplicas)), + strconv.Itoa(int(dp.Status.ReadyReplicas)), + mapToStr(dp.Labels), + asStatus(d.diagnose(dp.Status.Replicas, dp.Status.AvailableReplicas)), toAge(dp.ObjectMeta.CreationTimestamp), ) return nil } + +func (Deployment) diagnose(d, r int32) error { + if d != r { + return fmt.Errorf("desiring %d replicas got %d available", d, r) + } + return nil +} diff --git a/internal/render/ds.go b/internal/render/ds.go index b70f957c..191c59a5 100644 --- a/internal/render/ds.go +++ b/internal/render/ds.go @@ -3,7 +3,6 @@ package render import ( "fmt" "strconv" - "strings" "github.com/derailed/k9s/internal/client" "github.com/derailed/tview" @@ -17,18 +16,14 @@ import ( type DaemonSet struct{} // ColorerFunc colors a resource row. -func (DaemonSet) ColorerFunc() ColorerFunc { +func (d DaemonSet) ColorerFunc() ColorerFunc { return func(ns string, r RowEvent) tcell.Color { c := DefaultColorer(ns, r) if r.Kind == EventAdd || r.Kind == EventUpdate { return c } - desiredCol := 2 - if !client.IsAllNamespaces(ns) { - desiredCol = 1 - } - if strings.TrimSpace(r.Row.Fields[desiredCol]) != strings.TrimSpace(r.Row.Fields[desiredCol+2]) { + if !Happy(ns, r.Row) { return ErrColor } @@ -50,6 +45,8 @@ func (DaemonSet) Header(ns string) HeaderRow { Header{Name: "READY", Align: tview.AlignRight}, Header{Name: "UP-TO-DATE", Align: tview.AlignRight}, Header{Name: "AVAILABLE", Align: tview.AlignRight}, + Header{Name: "LABELS", Wide: true}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, ) } @@ -78,8 +75,18 @@ func (d DaemonSet) Render(o interface{}, ns string, r *Row) error { strconv.Itoa(int(ds.Status.NumberReady)), strconv.Itoa(int(ds.Status.UpdatedNumberScheduled)), strconv.Itoa(int(ds.Status.NumberAvailable)), + mapToStr(ds.Labels), + asStatus(d.diagnose(ds.Status.DesiredNumberScheduled, ds.Status.NumberReady)), toAge(ds.ObjectMeta.CreationTimestamp), ) return nil } + +// Happy returns true if resoure is happy, false otherwise +func (DaemonSet) diagnose(d, r int32) error { + if d != r { + return fmt.Errorf("desiring %d replicas but %d ready", d, r) + } + return nil +} diff --git a/internal/render/ev.go b/internal/render/ev.go index 67494d2a..ef4b6813 100644 --- a/internal/render/ev.go +++ b/internal/render/ev.go @@ -1,6 +1,7 @@ package render import ( + "errors" "fmt" "strconv" "strings" @@ -17,19 +18,20 @@ import ( type Event struct{} // ColorerFunc colors a resource row. -func (Event) ColorerFunc() ColorerFunc { +func (e Event) ColorerFunc() ColorerFunc { return func(ns string, r RowEvent) tcell.Color { c := DefaultColorer(ns, r) + if !Happy(ns, r.Row) { + return ErrColor + } + markCol := 3 if !client.IsAllNamespaces(ns) { markCol = 2 } - switch strings.TrimSpace(r.Row.Fields[markCol]) { - case "Failed": - c = ErrColor - case "Killing": - c = KillColor + if strings.TrimSpace(r.Row.Fields[markCol]) == "Killing" { + return KillColor } return c @@ -45,10 +47,12 @@ func (Event) Header(ns string) HeaderRow { return append(h, Header{Name: "NAME"}, + Header{Name: "TYPE"}, Header{Name: "REASON"}, Header{Name: "SOURCE"}, Header{Name: "COUNT", Align: tview.AlignRight}, - Header{Name: "MESSAGE"}, + Header{Name: "MESSAGE", Wide: true}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, ) } @@ -72,15 +76,27 @@ func (e Event) Render(o interface{}, ns string, r *Row) error { } r.Fields = append(r.Fields, asRef(ev.InvolvedObject), + ev.Type, ev.Reason, ev.Source.Component, strconv.Itoa(int(ev.Count)), ev.Message, + asStatus(e.diagnose(ev.Type)), toAge(ev.LastTimestamp)) return nil } +// Happy returns true if resoure is happy, false otherwise +func (Event) diagnose(kind string) error { + if kind != "Normal" { + return errors.New("failed event") + } + return nil +} + +// Helpers... + func asRef(r v1.ObjectReference) string { return strings.ToLower(r.Kind) + ":" + r.Name } diff --git a/internal/render/ev_test.go b/internal/render/ev_test.go index 766e5c7a..9388969e 100644 --- a/internal/render/ev_test.go +++ b/internal/render/ev_test.go @@ -13,5 +13,17 @@ func TestEventRender(t *testing.T) { c.Render(load(t, "ev"), "", &r) assert.Equal(t, "default/hello-1567197780-mn4mv.15bfce150bd764dd", r.ID) - assert.Equal(t, render.Fields{"default", "pod:hello-1567197780-mn4mv", "Pulled", "kubelet", "1", `Successfully pulled image "blang/busybox-bash"`}, r.Fields[:6]) + assert.Equal(t, render.Fields{"default", "pod:hello-1567197780-mn4mv", "Normal", "Pulled", "kubelet", "1", `Successfully pulled image "blang/busybox-bash"`}, r.Fields[:7]) +} + +func BenchmarkEventRender(b *testing.B) { + ev := load(b, "ev") + var re render.Event + r := render.NewRow(7) + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = re.Render(&ev, "", &r) + } } diff --git a/internal/render/generic.go b/internal/render/generic.go index d1e70bd9..46950ea7 100644 --- a/internal/render/generic.go +++ b/internal/render/generic.go @@ -19,6 +19,11 @@ type Generic struct { ageIndex int } +// Happy returns true if resoure is happy, false otherwise +func (Generic) Happy(ns string, r Row) bool { + return true +} + // SetTable sets the tabular resource. func (g *Generic) SetTable(t *metav1beta1.Table) { g.table = t diff --git a/internal/render/helpers.go b/internal/render/helpers.go index a598065d..1a26f447 100644 --- a/internal/render/helpers.go +++ b/internal/render/helpers.go @@ -13,6 +13,12 @@ import ( "k8s.io/apimachinery/pkg/util/duration" ) +// Happy returns true if resoure is happy, false otherwise +func Happy(ns string, r Row) bool { + validCol := r.Len() - 2 + return strings.TrimSpace(r.Fields[validCol]) == "" +} + const megaByte = 1024 * 1024 // ToMB converts bytes to megabytes. @@ -20,6 +26,13 @@ func ToMB(v int64) float64 { return float64(v) / megaByte } +func asStatus(err error) string { + if err == nil { + return "" + } + return err.Error() +} + func asSelector(s *metav1.LabelSelector) string { sel, err := metav1.LabelSelectorAsSelector(s) if err != nil { @@ -84,7 +97,7 @@ func join(a []string, sep string) string { var buff strings.Builder buff.Grow(n) - buff.WriteString(a[0]) + buff.WriteString(b[0]) for _, s := range b[1:] { buff.WriteString(sep) buff.WriteString(s) @@ -163,7 +176,40 @@ func mapToStr(m map[string]string) (s string) { for i, k := range kk { s += k + "=" + m[k] if i < len(kk)-1 { - s += "," + s += " " + } + } + + return +} + +func mapToIfc(m interface{}) (s string) { + if m == nil { + return "" + } + + mm, ok := m.(map[string]interface{}) + if !ok { + return "" + } + if len(mm) == 0 { + return "" + } + + kk := make([]string, 0, len(mm)) + for k := range mm { + kk = append(kk, k) + } + sort.Strings(kk) + + for i, k := range kk { + str, ok := mm[k].(string) + if !ok { + continue + } + s += k + "=" + str + if i < len(kk)-1 { + s += " " } } diff --git a/internal/render/helpers_test.go b/internal/render/helpers_test.go index ed366a46..51b93339 100644 --- a/internal/render/helpers_test.go +++ b/internal/render/helpers_test.go @@ -82,10 +82,11 @@ func TestJoin(t *testing.T) { i []string e string }{ - "zero": {[]string{}, ""}, - "std": {[]string{"a", "b", "c"}, "a,b,c"}, - "blank": {[]string{"", "", ""}, ""}, - "sparse": {[]string{"a", "", "c"}, "a,c"}, + "zero": {[]string{}, ""}, + "std": {[]string{"a", "b", "c"}, "a,b,c"}, + "blank": {[]string{"", "", ""}, ""}, + "sparse": {[]string{"a", "", "c"}, "a,c"}, + "withBlank": {[]string{"", "a", "c"}, "a,c"}, } for k := range uu { @@ -304,7 +305,7 @@ func TestMapToStr(t *testing.T) { i map[string]string e string }{ - {map[string]string{"blee": "duh", "aa": "bb"}, "aa=bb,blee=duh"}, + {map[string]string{"blee": "duh", "aa": "bb"}, "aa=bb blee=duh"}, {map[string]string{}, ""}, } for _, u := range uu { diff --git a/internal/render/hpa.go b/internal/render/hpa.go index 6042b49f..08bba6a4 100644 --- a/internal/render/hpa.go +++ b/internal/render/hpa.go @@ -36,6 +36,7 @@ func (HorizontalPodAutoscaler) Header(ns string) HeaderRow { Header{Name: "MINPODS", Align: tview.AlignRight}, Header{Name: "MAXPODS", Align: tview.AlignRight}, Header{Name: "REPLICAS", Align: tview.AlignRight}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, ) } @@ -80,6 +81,7 @@ func (h HorizontalPodAutoscaler) renderV1(raw *unstructured.Unstructured, ns str strconv.Itoa(int(*hpa.Spec.MinReplicas)), strconv.Itoa(int(hpa.Spec.MaxReplicas)), strconv.Itoa(int(hpa.Status.CurrentReplicas)), + "", toAge(hpa.ObjectMeta.CreationTimestamp), ) @@ -106,6 +108,7 @@ func (h HorizontalPodAutoscaler) renderV2b1(raw *unstructured.Unstructured, ns s strconv.Itoa(int(*hpa.Spec.MinReplicas)), strconv.Itoa(int(hpa.Spec.MaxReplicas)), strconv.Itoa(int(hpa.Status.CurrentReplicas)), + "", toAge(hpa.ObjectMeta.CreationTimestamp), ) @@ -132,6 +135,7 @@ func (h HorizontalPodAutoscaler) renderV2b2(raw *unstructured.Unstructured, ns s strconv.Itoa(int(*hpa.Spec.MinReplicas)), strconv.Itoa(int(hpa.Spec.MaxReplicas)), strconv.Itoa(int(hpa.Status.CurrentReplicas)), + "", toAge(hpa.ObjectMeta.CreationTimestamp), ) diff --git a/internal/render/ing.go b/internal/render/ing.go index 9f90ba74..2ba806fa 100644 --- a/internal/render/ing.go +++ b/internal/render/ing.go @@ -31,6 +31,7 @@ func (Ingress) Header(ns string) HeaderRow { Header{Name: "HOSTS"}, Header{Name: "ADDRESS"}, Header{Name: "PORT"}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, ) } @@ -57,6 +58,7 @@ func (i Ingress) Render(o interface{}, ns string, r *Row) error { toHosts(ing.Spec.Rules), toAddress(ing.Status.LoadBalancer), toTLSPorts(ing.Spec.TLS), + "", toAge(ing.ObjectMeta.CreationTimestamp), ) diff --git a/internal/render/job.go b/internal/render/job.go index 661c7c88..22d32f1a 100644 --- a/internal/render/job.go +++ b/internal/render/job.go @@ -9,6 +9,7 @@ import ( "github.com/derailed/k9s/internal/client" batchv1 "k8s.io/api/batch/v1" v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/duration" @@ -33,8 +34,10 @@ func (Job) Header(ns string) HeaderRow { Header{Name: "NAME"}, Header{Name: "COMPLETIONS"}, Header{Name: "DURATION"}, - Header{Name: "CONTAINERS"}, - Header{Name: "IMAGES"}, + Header{Name: "SELECTOR", Wide: true}, + Header{Name: "CONTAINERS", Wide: true}, + Header{Name: "IMAGES", Wide: true}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, ) } @@ -50,6 +53,7 @@ func (j Job) Render(o interface{}, ns string, r *Row) error { if err != nil { return err } + ready := toCompletion(job.Spec, job.Status) r.ID = client.MetaFQN(job.ObjectMeta) r.Fields = make(Fields, 0, len(j.Header(ns))) @@ -59,16 +63,29 @@ func (j Job) Render(o interface{}, ns string, r *Row) error { cc, ii := toContainers(job.Spec.Template.Spec) r.Fields = append(r.Fields, job.Name, - toCompletion(job.Spec, job.Status), + ready, toDuration(job.Status), + jobSelector(job.Spec), cc, ii, + asStatus(j.diagnose(ready, job.Status.CompletionTime)), toAge(job.ObjectMeta.CreationTimestamp), ) return nil } +func (Job) diagnose(ready string, completed *metav1.Time) error { + if completed == nil { + return nil + } + tokens := strings.Split(ready, "/") + if tokens[0] != tokens[1] { + return fmt.Errorf("expecting %s completion got %s", tokens[1], tokens[0]) + } + return nil +} + // ---------------------------------------------------------------------------- // Helpers... diff --git a/internal/render/job_test.go b/internal/render/job_test.go index 7d375d57..63ff6fb7 100644 --- a/internal/render/job_test.go +++ b/internal/render/job_test.go @@ -13,5 +13,5 @@ func TestJobRender(t *testing.T) { c.Render(load(t, "job"), "", &r) assert.Equal(t, "default/hello-1567179180", r.ID) - assert.Equal(t, render.Fields{"default", "hello-1567179180", "1/1", "8s", "c1", "blang/busybox-bash"}, r.Fields[:6]) + assert.Equal(t, render.Fields{"default", "hello-1567179180", "1/1", "8s", "controller-uid=7473e6d0-cb3b-11e9-990f-42010a800218", "c1", "blang/busybox-bash"}, r.Fields[:7]) } diff --git a/internal/render/node.go b/internal/render/node.go index f64038a7..14dd41cc 100644 --- a/internal/render/node.go +++ b/internal/render/node.go @@ -1,11 +1,14 @@ package render import ( + "errors" "fmt" + "sort" "strings" "github.com/derailed/k9s/internal/client" "github.com/derailed/tview" + "github.com/gdamore/tcell" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -22,8 +25,16 @@ const ( type Node struct{} // ColorerFunc colors a resource row. -func (Node) ColorerFunc() ColorerFunc { - return DefaultColorer +func (n Node) ColorerFunc() ColorerFunc { + return func(ns string, r RowEvent) tcell.Color { + c := DefaultColorer(ns, r) + if !Happy(ns, r.Row) { + return ErrColor + } + + return c + } + } // Header returns a header row. @@ -31,17 +42,19 @@ func (Node) Header(_ string) HeaderRow { return HeaderRow{ Header{Name: "NAME"}, Header{Name: "STATUS"}, - Header{Name: "ROLE"}, - Header{Name: "VERSION"}, - Header{Name: "KERNEL"}, - Header{Name: "INTERNAL-IP"}, - Header{Name: "EXTERNAL-IP"}, + Header{Name: "ROLE", Wide: true}, + Header{Name: "VERSION", Wide: true}, + Header{Name: "KERNEL", Wide: true}, + Header{Name: "INTERNAL-IP", Wide: true}, + Header{Name: "EXTERNAL-IP", Wide: true}, Header{Name: "CPU", Align: tview.AlignRight}, Header{Name: "MEM", Align: tview.AlignRight}, Header{Name: "%CPU", Align: tview.AlignRight}, Header{Name: "%MEM", Align: tview.AlignRight}, Header{Name: "ACPU", Align: tview.AlignRight}, Header{Name: "AMEM", Align: tview.AlignRight}, + Header{Name: "LABELS", Wide: true}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, } } @@ -69,17 +82,19 @@ func (n Node) Render(o interface{}, ns string, r *Row) error { c, a, p := gatherNodeMX(&no, oo.MX) - sta := make([]string, 10) - status(no.Status, no.Spec.Unschedulable, sta) - ro := make([]string, 10) - nodeRoles(&no, ro) + statuses := make(sort.StringSlice, 10) + status(no.Status, no.Spec.Unschedulable, statuses) + sort.Sort(statuses) + roles := make(sort.StringSlice, 10) + nodeRoles(&no, roles) + sort.Sort(roles) r.ID = client.FQN("", na) r.Fields = make(Fields, 0, len(n.Header(ns))) r.Fields = append(r.Fields, no.Name, - join(sta, ","), - join(ro, ","), + join(statuses, ","), + join(roles, ","), no.Status.NodeInfo.KubeletVersion, no.Status.NodeInfo.KernelVersion, iIP, @@ -90,12 +105,27 @@ func (n Node) Render(o interface{}, ns string, r *Row) error { p.mem, a.cpu, a.mem, + mapToStr(no.Labels), + asStatus(n.diagnose(statuses)), toAge(no.ObjectMeta.CreationTimestamp), ) return nil } +func (Node) diagnose(ss []string) error { + if len(ss) == 0 { + return nil + } + for _, s := range ss { + if s == "Ready" { + return nil + } + } + + return errors.New("node is not ready") +} + // ---------------------------------------------------------------------------- // Helpers... @@ -156,6 +186,9 @@ func nodeRoles(node *v1.Node, res []string) { res[index] = v index++ } + if index >= len(res) { + break + } } if empty(res) { diff --git a/internal/render/np.go b/internal/render/np.go index bdedf401..05062971 100644 --- a/internal/render/np.go +++ b/internal/render/np.go @@ -28,12 +28,14 @@ func (NetworkPolicy) Header(ns string) HeaderRow { return append(h, Header{Name: "NAME"}, - Header{Name: "ING-SELECTOR"}, + Header{Name: "ING-SELECTOR", Wide: true}, Header{Name: "ING-PORTS"}, Header{Name: "ING-BLOCK"}, - Header{Name: "EGR-SELECTOR"}, + Header{Name: "EGR-SELECTOR", Wide: true}, Header{Name: "EGR-PORTS"}, Header{Name: "EGR-BLOCK"}, + Header{Name: "LABELS", Wide: true}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, ) } @@ -66,6 +68,8 @@ func (n NetworkPolicy) Render(o interface{}, ns string, r *Row) error { es, ep, eb, + mapToStr(np.Labels), + "", toAge(np.ObjectMeta.CreationTimestamp), ) diff --git a/internal/render/ns.go b/internal/render/ns.go index b8547b31..0dc1bb07 100644 --- a/internal/render/ns.go +++ b/internal/render/ns.go @@ -1,6 +1,7 @@ package render import ( + "errors" "fmt" "strings" @@ -15,7 +16,7 @@ import ( type Namespace struct{} // ColorerFunc colors a resource row. -func (Namespace) ColorerFunc() ColorerFunc { +func (n Namespace) ColorerFunc() ColorerFunc { return func(ns string, r RowEvent) tcell.Color { c := DefaultColorer(ns, r) if r.Kind == EventAdd { @@ -25,9 +26,8 @@ func (Namespace) ColorerFunc() ColorerFunc { if r.Kind == EventUpdate { c = StdColor } - switch strings.TrimSpace(r.Row.Fields[1]) { - case "Inactive", Terminating: - c = ErrColor + if !Happy(ns, r.Row) { + return ErrColor } if strings.Contains(strings.TrimSpace(r.Row.Fields[0]), "*") { c = HighlightColor @@ -42,12 +42,14 @@ func (Namespace) Header(string) HeaderRow { return HeaderRow{ Header{Name: "NAME"}, Header{Name: "STATUS"}, + Header{Name: "LABELS", Wide: true}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, } } // Render renders a K8s resource to screen. -func (Namespace) Render(o interface{}, _ string, r *Row) error { +func (n Namespace) Render(o interface{}, _ string, r *Row) error { raw, ok := o.(*unstructured.Unstructured) if !ok { return fmt.Errorf("Expected Namespace, but got %T", o) @@ -62,8 +64,17 @@ func (Namespace) Render(o interface{}, _ string, r *Row) error { r.Fields = Fields{ ns.Name, string(ns.Status.Phase), + mapToStr(ns.Labels), + asStatus(n.diagnose(ns.Status.Phase)), toAge(ns.ObjectMeta.CreationTimestamp), } return nil } + +func (Namespace) diagnose(phase v1.NamespacePhase) error { + if phase != v1.NamespaceActive && phase != v1.NamespaceTerminating { + return errors.New("namespace not ready") + } + return nil +} diff --git a/internal/render/ofaas.go b/internal/render/ofaas.go index c51dd4c7..4d285197 100644 --- a/internal/render/ofaas.go +++ b/internal/render/ofaas.go @@ -1,6 +1,7 @@ package render import ( + "errors" "fmt" "strconv" "time" @@ -23,8 +24,12 @@ const ( type OpenFaas struct{} // ColorerFunc colors a resource row. -func (OpenFaas) ColorerFunc() ColorerFunc { +func (o OpenFaas) ColorerFunc() ColorerFunc { return func(ns string, re RowEvent) tcell.Color { + if !Happy(ns, re.Row) { + return ErrColor + } + return tcell.ColorPaleTurquoise } } @@ -44,6 +49,7 @@ func (OpenFaas) Header(ns string) HeaderRow { Header{Name: "INVOCATIONS", Align: tview.AlignRight}, Header{Name: "REPLICAS", Align: tview.AlignRight}, Header{Name: "AVAILABLE", Align: tview.AlignRight}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, ) } @@ -77,12 +83,21 @@ func (f OpenFaas) Render(o interface{}, ns string, r *Row) error { strconv.Itoa(int(fn.Function.InvocationCount)), strconv.Itoa(int(fn.Function.Replicas)), strconv.Itoa(int(fn.Function.AvailableReplicas)), + asStatus(f.diagnose(status)), toAge(metav1.Time{Time: time.Now()}), ) return nil } +func (OpenFaas) diagnose(status string) error { + if status != "Ready" { + return errors.New("function not ready") + } + + return nil +} + // ---------------------------------------------------------------------------- // Helpers... diff --git a/internal/render/pdb.go b/internal/render/pdb.go index 9103b336..fb94eed4 100644 --- a/internal/render/pdb.go +++ b/internal/render/pdb.go @@ -3,7 +3,6 @@ package render import ( "fmt" "strconv" - "strings" "github.com/derailed/k9s/internal/client" "github.com/derailed/tview" @@ -18,24 +17,19 @@ import ( type PodDisruptionBudget struct{} // ColorerFunc colors a resource row. -func (PodDisruptionBudget) ColorerFunc() ColorerFunc { - return func(ns string, r RowEvent) tcell.Color { - c := DefaultColorer(ns, r) - if r.Kind == EventAdd || r.Kind == EventUpdate { +func (p PodDisruptionBudget) ColorerFunc() ColorerFunc { + return func(ns string, re RowEvent) tcell.Color { + c := DefaultColorer(ns, re) + if re.Kind == EventAdd || re.Kind == EventUpdate { return c } - markCol := 5 - if !client.IsAllNamespaces(ns) { - markCol-- - } - if strings.TrimSpace(r.Row.Fields[markCol]) != strings.TrimSpace(r.Row.Fields[markCol+1]) { + if !Happy(ns, re.Row) { return ErrColor } return StdColor } - } // Header returns a header row. @@ -53,6 +47,8 @@ func (PodDisruptionBudget) Header(ns string) HeaderRow { Header{Name: "CURRENT", Align: tview.AlignRight}, Header{Name: "DESIRED", Align: tview.AlignRight}, Header{Name: "EXPECTED", Align: tview.AlignRight}, + Header{Name: "LABELS", Wide: true}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, ) } @@ -82,12 +78,21 @@ func (p PodDisruptionBudget) Render(o interface{}, ns string, r *Row) error { strconv.Itoa(int(pdb.Status.CurrentHealthy)), strconv.Itoa(int(pdb.Status.DesiredHealthy)), strconv.Itoa(int(pdb.Status.ExpectedPods)), + mapToStr(pdb.Labels), + asStatus(p.diagnose(pdb.Spec.MinAvailable.IntVal, pdb.Status.CurrentHealthy)), toAge(pdb.ObjectMeta.CreationTimestamp), ) return nil } +func (PodDisruptionBudget) diagnose(min, healthy int32) error { + if min > healthy { + return fmt.Errorf("expected %d but got %d", min, healthy) + } + return nil +} + // Helpers... func numbToStr(n *intstr.IntOrString) string { diff --git a/internal/render/pod.go b/internal/render/pod.go index ded5b483..011fb064 100644 --- a/internal/render/pod.go +++ b/internal/render/pod.go @@ -25,15 +25,11 @@ func (p Pod) ColorerFunc() ColorerFunc { return func(ns string, re RowEvent) tcell.Color { c := DefaultColorer(ns, re) - readyCol := 2 + statusCol := 4 if !client.IsAllNamespaces(ns) { - readyCol-- + statusCol-- } - statusCol := readyCol + 1 - - ready, status := strings.TrimSpace(re.Row.Fields[readyCol]), strings.TrimSpace(re.Row.Fields[statusCol]) - c = p.checkReadyCol(ready, status, c) - + status := strings.TrimSpace(re.Row.Fields[statusCol]) switch status { case ContainerCreating, PodInitializing: c = AddColor @@ -42,28 +38,19 @@ func (p Pod) ColorerFunc() ColorerFunc { case Completed: c = CompletedColor case Running: + c = StdColor case Terminating: c = KillColor default: - c = ErrColor + if !Happy(ns, re.Row) { + c = ErrColor + } } return c } } -func (Pod) checkReadyCol(readyCol, statusCol string, c tcell.Color) tcell.Color { - if statusCol == "Completed" { - return c - } - - tokens := strings.Split(readyCol, "/") - if len(tokens) == 2 && (tokens[0] == "0" || tokens[0] != tokens[1]) { - return ErrColor - } - return c -} - // Header returns a header row. func (Pod) Header(ns string) HeaderRow { var h HeaderRow @@ -74,17 +61,19 @@ func (Pod) Header(ns string) HeaderRow { return append(h, Header{Name: "NAME"}, Header{Name: "READY"}, - Header{Name: "STATUS"}, Header{Name: "RS", Align: tview.AlignRight}, + Header{Name: "STATUS"}, Header{Name: "CPU", Align: tview.AlignRight}, Header{Name: "MEM", Align: tview.AlignRight}, Header{Name: "%CPU/R", Align: tview.AlignRight}, Header{Name: "%MEM/R", Align: tview.AlignRight}, Header{Name: "%CPU/L", Align: tview.AlignRight}, Header{Name: "%MEM/L", Align: tview.AlignRight}, - Header{Name: "IP"}, - Header{Name: "NODE"}, - Header{Name: "QOS"}, + Header{Name: "IP", Wide: true}, + Header{Name: "NODE", Wide: true}, + Header{Name: "QOS", Wide: true}, + Header{Name: "LABELS", Wide: true}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, ) } @@ -105,7 +94,7 @@ func (p Pod) Render(o interface{}, ns string, r *Row) error { ss := po.Status.ContainerStatuses cr, _, rc := p.Statuses(ss) c, perc := p.gatherPodMX(&po, pwm.MX) - + phase := p.Phase(&po) r.ID = client.MetaFQN(po.ObjectMeta) r.Fields = make(Fields, 0, len(p.Header(ns))) if client.IsAllNamespaces(ns) { @@ -114,8 +103,8 @@ func (p Pod) Render(o interface{}, ns string, r *Row) error { r.Fields = append(r.Fields, po.ObjectMeta.Name, strconv.Itoa(cr)+"/"+strconv.Itoa(len(ss)), - p.Phase(&po), strconv.Itoa(rc), + phase, c.cpu, c.mem, perc.cpu, @@ -125,12 +114,25 @@ func (p Pod) Render(o interface{}, ns string, r *Row) error { na(po.Status.PodIP), na(po.Spec.NodeName), p.mapQOS(po.Status.QOSClass), + mapToStr(po.Labels), + asStatus(p.diagnose(phase, cr, len(ss))), toAge(po.ObjectMeta.CreationTimestamp), ) return nil } +func (p Pod) diagnose(phase string, cr, ct int) error { + if phase == "Completed" { + return nil + } + if cr != ct { + return fmt.Errorf("container ready check failed: %d of %d", cr, ct) + } + + return nil +} + // ---------------------------------------------------------------------------- // Helpers... diff --git a/internal/render/pod_test.go b/internal/render/pod_test.go index 6b0df397..0f746fce 100644 --- a/internal/render/pod_test.go +++ b/internal/render/pod_test.go @@ -24,12 +24,12 @@ type ( func TestPodColorer(t *testing.T) { var ( - nsRow = render.Row{Fields: render.Fields{"blee", "fred", "1/1", "Running"}} - toastNS = render.Row{Fields: render.Fields{"blee", "fred", "1/1", "Boom"}} - notReadyNS = render.Row{Fields: render.Fields{"blee", "fred", "0/1", "Boom"}} - row = render.Row{Fields: render.Fields{"fred", "1/1", "Running"}} - toast = render.Row{Fields: render.Fields{"fred", "1/1", "Boom"}} - notReady = render.Row{Fields: render.Fields{"fred", "0/1", "Boom"}} + nsRow = render.Row{Fields: render.Fields{"blee", "fred", "1/1", "0", "Running"}} + toastNS = render.Row{Fields: render.Fields{"blee", "fred", "1/1", "0", "Boom"}} + notReadyNS = render.Row{Fields: render.Fields{"blee", "fred", "0/1", "0", "Boom"}} + row = render.Row{Fields: render.Fields{"fred", "1/1", "0", "Running"}} + toast = render.Row{Fields: render.Fields{"fred", "1/1", "0", "Boom"}} + notReady = render.Row{Fields: render.Fields{"fred", "0/1", "0", "Boom"}} ) uu := colorerUCs{ @@ -70,7 +70,7 @@ func TestPodRender(t *testing.T) { assert.Nil(t, err) assert.Equal(t, "default/nginx", r.ID) - e := render.Fields{"default", "nginx", "1/1", "Running", "0", "10", "10", "10", "14", "0", "5", "172.17.0.6", "minikube", "BE"} + e := render.Fields{"default", "nginx", "1/1", "0", "Running", "10", "10", "10", "14", "0", "5", "172.17.0.6", "minikube", "BE"} assert.Equal(t, e, r.Fields[:14]) } @@ -101,7 +101,7 @@ func TestPodInitRender(t *testing.T) { assert.Nil(t, err) assert.Equal(t, "default/nginx", r.ID) - e := render.Fields{"default", "nginx", "1/1", "Init:0/1", "0", "10", "10", "10", "14", "0", "5", "172.17.0.6", "minikube", "BE"} + e := render.Fields{"default", "nginx", "1/1", "0", "Init:0/1", "10", "10", "10", "14", "0", "5", "172.17.0.6", "minikube", "BE"} assert.Equal(t, e, r.Fields[:14]) } diff --git a/internal/render/policy.go b/internal/render/policy.go index e29ab3ce..da279118 100644 --- a/internal/render/policy.go +++ b/internal/render/policy.go @@ -18,8 +18,8 @@ func rbacVerbHeader() HeaderRow { Header{Name: "PATCH "}, Header{Name: "UPDATE"}, Header{Name: "DELETE"}, - Header{Name: "DLIST "}, - Header{Name: "EXTRAS"}, + Header{Name: "DEL-LIST "}, + Header{Name: "EXTRAS", Wide: true}, } } @@ -41,7 +41,10 @@ func (Policy) Header(ns string) HeaderRow { Header{Name: "API GROUP"}, Header{Name: "BINDING"}, } - return append(h, rbacVerbHeader()...) + h = append(h, rbacVerbHeader()...) + h = append(h, Header{Name: "VALID", Wide: true}) + + return h } // Render renders a K8s resource to screen. @@ -52,8 +55,14 @@ func (Policy) Render(o interface{}, gvr string, r *Row) error { } r.ID = client.FQN(p.Namespace, p.Resource) - r.Fields = append(r.Fields, p.Namespace, cleanseResource(p.Resource), p.Group, p.Binding) + r.Fields = append(r.Fields, + p.Namespace, + cleanseResource(p.Resource), + p.Group, + p.Binding, + ) r.Fields = append(r.Fields, asVerbs(p.Verbs)...) + r.Fields = append(r.Fields, "") return nil } diff --git a/internal/render/policy_test.go b/internal/render/policy_test.go index 61a30ddf..24408821 100644 --- a/internal/render/policy_test.go +++ b/internal/render/policy_test.go @@ -37,5 +37,6 @@ func TestPolicyRender(t *testing.T) { "[orangered::b] 𐄂 [::]", "[orangered::b] 𐄂 [::]", "", + "", }, r.Fields) } diff --git a/internal/render/port_forward_test.go b/internal/render/port_forward_test.go index 3ce102f1..81c9d7cf 100644 --- a/internal/render/port_forward_test.go +++ b/internal/render/port_forward_test.go @@ -30,6 +30,7 @@ func TestPortForwardRender(t *testing.T) { "http://0.0.0.0:p1/", "1", "1", + "", "2m", }, r.Fields) } diff --git a/internal/render/portforward.go b/internal/render/portforward.go index 450188d2..89dcf258 100644 --- a/internal/render/portforward.go +++ b/internal/render/portforward.go @@ -48,6 +48,7 @@ func (PortForward) Header(ns string) HeaderRow { Header{Name: "URL"}, Header{Name: "C"}, Header{Name: "N"}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, } } @@ -71,6 +72,7 @@ func (f PortForward) Render(o interface{}, gvr string, r *Row) error { UrlFor(pf.Config.Host, pf.Config.Path, ports[0]), asNum(pf.Config.C), asNum(pf.Config.N), + "", pf.Age(), } diff --git a/internal/render/pv.go b/internal/render/pv.go index ef0ae627..67742ff6 100644 --- a/internal/render/pv.go +++ b/internal/render/pv.go @@ -16,26 +16,26 @@ import ( type PersistentVolume struct{} // ColorerFunc colors a resource row. -func (PersistentVolume) ColorerFunc() ColorerFunc { - return func(ns string, r RowEvent) tcell.Color { - c := DefaultColorer(ns, r) - if r.Kind == EventAdd || r.Kind == EventUpdate { +func (p PersistentVolume) ColorerFunc() ColorerFunc { + return func(ns string, re RowEvent) tcell.Color { + c := DefaultColorer(ns, re) + if re.Kind == EventAdd || re.Kind == EventUpdate { return c } - status := strings.TrimSpace(r.Row.Fields[4]) - switch status { + if !Happy(ns, re.Row) { + return ErrColor + } + + switch strings.TrimSpace(re.Row.Fields[4]) { case "Bound": c = StdColor case "Available": c = tcell.ColorYellow - default: - c = ErrColor } return c } - } // Header returns a header rbw. @@ -49,6 +49,9 @@ func (PersistentVolume) Header(string) HeaderRow { Header{Name: "CLAIM"}, Header{Name: "STORAGECLASS"}, Header{Name: "REASON"}, + Header{Name: "VOLUMEMODE", Wide: true}, + Header{Name: "LABELS", Wide: true}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, } } @@ -90,12 +93,30 @@ func (p PersistentVolume) Render(o interface{}, ns string, r *Row) error { claim, class, pv.Status.Reason, + p.volumeMode(pv.Spec.VolumeMode), + mapToStr(pv.Labels), + asStatus(p.diagnose(string(phase))), toAge(pv.ObjectMeta.CreationTimestamp), } return nil } +func (PersistentVolume) diagnose(r string) error { + if r != "Bound" && r != "Available" { + return fmt.Errorf("unexpected status %s", r) + } + return nil +} + +func (PersistentVolume) volumeMode(m *v1.PersistentVolumeMode) string { + if m == nil { + return MissingValue + } + + return string(*m) +} + // ---------------------------------------------------------------------------- // Helpers... diff --git a/internal/render/pvc.go b/internal/render/pvc.go index c6ce1484..2b10a867 100644 --- a/internal/render/pvc.go +++ b/internal/render/pvc.go @@ -2,7 +2,6 @@ package render import ( "fmt" - "strings" "github.com/derailed/k9s/internal/client" "github.com/gdamore/tcell" @@ -15,19 +14,14 @@ import ( type PersistentVolumeClaim struct{} // ColorerFunc colors a resource row. -func (PersistentVolumeClaim) ColorerFunc() ColorerFunc { - return func(ns string, r RowEvent) tcell.Color { - c := DefaultColorer(ns, r) - if r.Kind == EventAdd || r.Kind == EventUpdate { +func (p PersistentVolumeClaim) ColorerFunc() ColorerFunc { + return func(ns string, re RowEvent) tcell.Color { + c := DefaultColorer(ns, re) + if re.Kind == EventAdd || re.Kind == EventUpdate { return c } - - markCol := 2 - if !client.IsAllNamespaces(ns) { - markCol-- - } - if strings.TrimSpace(r.Row.Fields[markCol]) != "Bound" { - c = ErrColor + if !Happy(ns, re.Row) { + return ErrColor } return c @@ -49,6 +43,8 @@ func (PersistentVolumeClaim) Header(ns string) HeaderRow { Header{Name: "CAPACITY"}, Header{Name: "ACCESS MODES"}, Header{Name: "STORAGECLASS"}, + Header{Name: "LABELS", Wide: true}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, ) } @@ -96,8 +92,17 @@ func (p PersistentVolumeClaim) Render(o interface{}, ns string, r *Row) error { capacity, accessModes, class, + mapToStr(pvc.Labels), + asStatus(p.diagnose(string(phase))), toAge(pvc.ObjectMeta.CreationTimestamp), ) return nil } + +func (PersistentVolumeClaim) diagnose(r string) error { + if r != "Bound" && r != "Available" { + return fmt.Errorf("unexpected status %s", r) + } + return nil +} diff --git a/internal/render/rbac.go b/internal/render/rbac.go index 438ef473..93b6fd85 100644 --- a/internal/render/rbac.go +++ b/internal/render/rbac.go @@ -46,7 +46,10 @@ func (Rbac) Header(ns string) HeaderRow { Header{Name: "API GROUP"}, } - return append(h, rbacVerbHeader()...) + h = append(h, rbacVerbHeader()...) + h = append(h, Header{Name: "VALID", Wide: true}) + + return h } // Render renders a K8s resource to screen. @@ -57,8 +60,12 @@ func (Rbac) Render(o interface{}, gvr string, r *Row) error { } r.ID = p.Resource - r.Fields = append(r.Fields, cleanseResource(p.Resource), p.Group) + r.Fields = append(r.Fields, + cleanseResource(p.Resource), + p.Group, + ) r.Fields = append(r.Fields, asVerbs(p.Verbs)...) + r.Fields = append(r.Fields, "") return nil } diff --git a/internal/render/ro.go b/internal/render/ro.go index c388889e..1e54bb81 100644 --- a/internal/render/ro.go +++ b/internal/render/ro.go @@ -26,6 +26,8 @@ func (Role) Header(ns string) HeaderRow { return append(h, Header{Name: "NAME"}, + Header{Name: "LABELS", Wide: true}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, ) } @@ -49,6 +51,8 @@ func (r Role) Render(o interface{}, ns string, row *Row) error { } row.Fields = append(row.Fields, ro.Name, + mapToStr(ro.Labels), + "", toAge(ro.ObjectMeta.CreationTimestamp), ) diff --git a/internal/render/rob.go b/internal/render/rob.go index 6777c090..e55b01df 100644 --- a/internal/render/rob.go +++ b/internal/render/rob.go @@ -30,6 +30,8 @@ func (RoleBinding) Header(ns string) HeaderRow { Header{Name: "ROLE"}, Header{Name: "KIND"}, Header{Name: "SUBJECTS"}, + Header{Name: "LABELS", Wide: true}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, ) } @@ -58,6 +60,8 @@ func (r RoleBinding) Render(o interface{}, ns string, row *Row) error { rb.RoleRef.Name, kind, ss, + mapToStr(rb.Labels), + "", toAge(rb.ObjectMeta.CreationTimestamp), ) @@ -87,11 +91,11 @@ func toSubjectAlias(s string) string { switch s { case rbacv1.UserKind: - return "USR" + return "User" case rbacv1.GroupKind: - return "GRP" + return "Group" case rbacv1.ServiceAccountKind: - return "SA" + return "SvcAcct" default: return strings.ToUpper(s) } diff --git a/internal/render/rob_test.go b/internal/render/rob_test.go index 66afcf6a..26a5c138 100644 --- a/internal/render/rob_test.go +++ b/internal/render/rob_test.go @@ -13,5 +13,5 @@ func TestRoleBindingRender(t *testing.T) { c.Render(load(t, "rb"), "", &r) assert.Equal(t, "default/blee", r.ID) - assert.Equal(t, render.Fields{"default", "blee", "blee", "SA", "fernand"}, r.Fields[:5]) + assert.Equal(t, render.Fields{"default", "blee", "blee", "SvcAcct", "fernand"}, r.Fields[:5]) } diff --git a/internal/render/row.go b/internal/render/row.go index 4076b866..dde5cbe1 100644 --- a/internal/render/row.go +++ b/internal/render/row.go @@ -39,6 +39,11 @@ func (r Row) Clone() Row { } } +// Len returns the length of the row. +func (r Row) Len() int { + return len(r.Fields) +} + // ---------------------------------------------------------------------------- // Rows represents a collection of rows. diff --git a/internal/render/row_event.go b/internal/render/row_event.go index 5b607c69..c2daae04 100644 --- a/internal/render/row_event.go +++ b/internal/render/row_event.go @@ -181,7 +181,7 @@ func (rr RowEvents) Sort(ns string, col int, asc bool) { func toAgeDuration(dur string) string { d, err := time.ParseDuration(dur) if err != nil { - return "n/a" + return dur } return duration.HumanDuration(d) } diff --git a/internal/render/row_header.go b/internal/render/row_header.go index 4b34ea1a..343fff3f 100644 --- a/internal/render/row_header.go +++ b/internal/render/row_header.go @@ -9,6 +9,8 @@ type Header struct { Name string Align int Decorator DecoratorFunc + Hide bool + Wide bool } // Clone copies a header. @@ -56,13 +58,7 @@ func (hh HeaderRow) Columns() []string { // HasAge returns true if table has an age column. func (hh HeaderRow) HasAge() bool { - for _, r := range hh { - if r.Name == ageCol { - return true - } - } - - return false + return hh.IndexOf(ageCol) != -1 } // AgeCol checks if given column index is the age column. @@ -72,3 +68,18 @@ func (hh HeaderRow) AgeCol(col int) bool { } return col == len(hh)-1 } + +// ValidColIndex returns the valid col index or -1 if none. +func (hh HeaderRow) ValidColIndex() int { + return hh.IndexOf("VALID") +} + +// IndeOf returns the col index or -1 if none. +func (hh HeaderRow) IndexOf(c string) int { + for i, h := range hh { + if h.Name == c { + return i + } + } + return -1 +} diff --git a/internal/render/rs.go b/internal/render/rs.go index 5b38fcf1..f0412d56 100644 --- a/internal/render/rs.go +++ b/internal/render/rs.go @@ -3,7 +3,6 @@ package render import ( "fmt" "strconv" - "strings" "github.com/derailed/k9s/internal/client" "github.com/derailed/tview" @@ -17,24 +16,19 @@ import ( type ReplicaSet struct{} // ColorerFunc colors a resource row. -func (ReplicaSet) ColorerFunc() ColorerFunc { - return func(ns string, r RowEvent) tcell.Color { - c := DefaultColorer(ns, r) - if r.Kind == EventAdd || r.Kind == EventUpdate { +func (r ReplicaSet) ColorerFunc() ColorerFunc { + return func(ns string, re RowEvent) tcell.Color { + c := DefaultColorer(ns, re) + if re.Kind == EventAdd || re.Kind == EventUpdate { return c } - markCol := 2 - if !client.IsAllNamespaces(ns) { - markCol-- - } - if strings.TrimSpace(r.Row.Fields[markCol]) != strings.TrimSpace(r.Row.Fields[markCol+1]) { + if !Happy(ns, re.Row) { return ErrColor } return StdColor } - } // Header returns a header row. @@ -49,6 +43,8 @@ func (ReplicaSet) Header(ns string) HeaderRow { Header{Name: "DESIRED", Align: tview.AlignRight}, Header{Name: "CURRENT", Align: tview.AlignRight}, Header{Name: "READY", Align: tview.AlignRight}, + Header{Name: "LABELS", Wide: true}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, ) } @@ -75,8 +71,21 @@ func (s ReplicaSet) Render(o interface{}, ns string, r *Row) error { strconv.Itoa(int(*rs.Spec.Replicas)), strconv.Itoa(int(rs.Status.Replicas)), strconv.Itoa(int(rs.Status.ReadyReplicas)), + mapToStr(rs.Labels), + asStatus(s.diagnose(rs)), toAge(rs.ObjectMeta.CreationTimestamp), ) return nil } + +func (s ReplicaSet) diagnose(rs appsv1.ReplicaSet) error { + if rs.Status.Replicas != rs.Status.ReadyReplicas { + if rs.Status.Replicas == 0 { + return fmt.Errorf("did not phase down correctly expecting 0 replicas but got %d", rs.Status.ReadyReplicas) + } + return fmt.Errorf("mismatch desired(%d) vs ready(%d)", rs.Status.Replicas, rs.Status.ReadyReplicas) + } + + return nil +} diff --git a/internal/render/sa.go b/internal/render/sa.go index eafffe7a..d0900374 100644 --- a/internal/render/sa.go +++ b/internal/render/sa.go @@ -28,6 +28,8 @@ func (ServiceAccount) Header(ns string) HeaderRow { return append(h, Header{Name: "NAME"}, Header{Name: "SECRET"}, + Header{Name: "LABELS", Wide: true}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, ) } @@ -52,6 +54,8 @@ func (s ServiceAccount) Render(o interface{}, ns string, r *Row) error { r.Fields = append(r.Fields, sa.Name, strconv.Itoa(len(sa.Secrets)), + mapToStr(sa.Labels), + "", toAge(sa.ObjectMeta.CreationTimestamp), ) diff --git a/internal/render/sc.go b/internal/render/sc.go index 4c43fbc0..00ab82e0 100644 --- a/internal/render/sc.go +++ b/internal/render/sc.go @@ -22,6 +22,8 @@ func (StorageClass) Header(ns string) HeaderRow { return HeaderRow{ Header{Name: "NAME"}, Header{Name: "PROVISIONER"}, + Header{Name: "LABELS", Wide: true}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, } } @@ -42,6 +44,8 @@ func (StorageClass) Render(o interface{}, ns string, r *Row) error { r.Fields = Fields{ sc.Name, string(sc.Provisioner), + mapToStr(sc.Labels), + "", toAge(sc.ObjectMeta.CreationTimestamp), } diff --git a/internal/render/screen_dump.go b/internal/render/screen_dump.go index ce1d4a69..5d81b068 100644 --- a/internal/render/screen_dump.go +++ b/internal/render/screen_dump.go @@ -33,6 +33,8 @@ var AgeDecorator = func(a string) string { func (ScreenDump) Header(ns string) HeaderRow { return HeaderRow{ Header{Name: "NAME"}, + Header{Name: "DIR"}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, } } @@ -47,6 +49,8 @@ func (b ScreenDump) Render(o interface{}, ns string, r *Row) error { r.ID = filepath.Join(f.Dir, f.File.Name()) r.Fields = Fields{ f.File.Name(), + f.Dir, + "", timeToAge(f.File.ModTime()), } diff --git a/internal/render/screen_dump_test.go b/internal/render/screen_dump_test.go index ce6413ab..7dfad7f5 100644 --- a/internal/render/screen_dump_test.go +++ b/internal/render/screen_dump_test.go @@ -21,6 +21,8 @@ func TestScreenDumpRender(t *testing.T) { assert.Equal(t, "fred/blee/bob", r.ID) assert.Equal(t, render.Fields{ "bob", + "fred/blee", + "", }, r.Fields[:len(r.Fields)-1]) } diff --git a/internal/render/sts.go b/internal/render/sts.go index 30038c83..02dcc8c9 100644 --- a/internal/render/sts.go +++ b/internal/render/sts.go @@ -3,7 +3,6 @@ package render import ( "fmt" "strconv" - "strings" "github.com/derailed/k9s/internal/client" "github.com/gdamore/tcell" @@ -16,20 +15,13 @@ import ( type StatefulSet struct{} // ColorerFunc colors a resource row. -func (StatefulSet) ColorerFunc() ColorerFunc { - return func(ns string, r RowEvent) tcell.Color { - c := DefaultColorer(ns, r) - if r.Kind == EventAdd || r.Kind == EventUpdate { +func (s StatefulSet) ColorerFunc() ColorerFunc { + return func(ns string, re RowEvent) tcell.Color { + c := DefaultColorer(ns, re) + if re.Kind == EventAdd || re.Kind == EventUpdate { return c } - - readyCol := 2 - if !client.IsAllNamespaces(ns) { - readyCol-- - } - tokens := strings.Split(strings.TrimSpace(r.Row.Fields[readyCol]), "/") - curr, des := tokens[0], tokens[1] - if curr != des { + if !Happy(ns, re.Row) { return ErrColor } @@ -47,8 +39,12 @@ func (StatefulSet) Header(ns string) HeaderRow { return append(h, Header{Name: "NAME"}, Header{Name: "READY"}, - Header{Name: "SELECTOR"}, + Header{Name: "SELECTOR", Wide: true}, Header{Name: "SERVICE"}, + Header{Name: "CONTAINERS", Wide: true}, + Header{Name: "IMAGES", Wide: true}, + Header{Name: "LABELS", Wide: true}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, ) } @@ -72,11 +68,22 @@ func (s StatefulSet) Render(o interface{}, ns string, r *Row) error { } r.Fields = append(r.Fields, sts.Name, - strconv.Itoa(int(sts.Status.Replicas))+"/"+strconv.Itoa(int(*sts.Spec.Replicas)), + strconv.Itoa(int(sts.Status.ReadyReplicas))+"/"+strconv.Itoa(int(sts.Status.Replicas)), asSelector(sts.Spec.Selector), na(sts.Spec.ServiceName), + podContainerNames(sts.Spec.Template.Spec, true), + podImageNames(sts.Spec.Template.Spec, true), + mapToStr(sts.Labels), + asStatus(s.diagnose(sts.Status.Replicas, sts.Status.ReadyReplicas)), toAge(sts.ObjectMeta.CreationTimestamp), ) return nil } + +func (StatefulSet) diagnose(d, r int32) error { + if d != r { + return fmt.Errorf("desiring %d replicas got %d available", d, r) + } + return nil +} diff --git a/internal/render/sts_test.go b/internal/render/sts_test.go index 6fe8e4ae..600daa93 100644 --- a/internal/render/sts_test.go +++ b/internal/render/sts_test.go @@ -13,5 +13,5 @@ func TestStatefulSetRender(t *testing.T) { assert.Nil(t, c.Render(load(t, "sts"), "", &r)) assert.Equal(t, "default/nginx-sts", r.ID) - assert.Equal(t, render.Fields{"default", "nginx-sts", "4/4", "app=nginx-sts", "nginx-sts"}, r.Fields[:len(r.Fields)-1]) + assert.Equal(t, render.Fields{"default", "nginx-sts", "4/4", "app=nginx-sts", "nginx-sts", "nginx", "k8s.gcr.io/nginx-slim:0.8", "app=nginx-sts", ""}, r.Fields[:len(r.Fields)-1]) } diff --git a/internal/render/subject.go b/internal/render/subject.go index 5c1e0f83..dae66c77 100644 --- a/internal/render/subject.go +++ b/internal/render/subject.go @@ -11,6 +11,11 @@ import ( // Subject renders a rbac to screen. type Subject struct{} +// Happy returns true if resoure is happy, false otherwise +func (Subject) Happy(_ string, _ Row) bool { + return true +} + // ColorerFunc colors a resource row. func (Subject) ColorerFunc() ColorerFunc { return func(ns string, re RowEvent) tcell.Color { @@ -24,6 +29,7 @@ func (Subject) Header(ns string) HeaderRow { Header{Name: "NAME"}, Header{Name: "KIND"}, Header{Name: "FIRST LOCATION"}, + Header{Name: "VALID", Wide: true}, } } @@ -40,6 +46,7 @@ func (s Subject) Render(o interface{}, ns string, r *Row) error { res.Name, res.Kind, res.FirstLocation, + "", ) return nil diff --git a/internal/render/svc.go b/internal/render/svc.go index 008f2d8d..f8411f55 100644 --- a/internal/render/svc.go +++ b/internal/render/svc.go @@ -32,8 +32,10 @@ func (Service) Header(ns string) HeaderRow { Header{Name: "TYPE"}, Header{Name: "CLUSTER-IP"}, Header{Name: "EXTERNAL-IP"}, - Header{Name: "SELECTOR"}, - Header{Name: "PORTS"}, + Header{Name: "SELECTOR", Wide: true}, + Header{Name: "PORTS", Wide: true}, + Header{Name: "LABELS", Wide: true}, + Header{Name: "VALID", Wide: true}, Header{Name: "AGE", Decorator: AgeDecorator}, ) } @@ -58,19 +60,32 @@ func (s Service) Render(o interface{}, ns string, r *Row) error { r.Fields = append(r.Fields, svc.ObjectMeta.Name, string(svc.Spec.Type), - svc.Spec.ClusterIP, + toIP(svc.Spec.ClusterIP), toIPs(svc.Spec.Type, getSvcExtIPS(&svc)), mapToStr(svc.Spec.Selector), toPorts(svc.Spec.Ports), + mapToStr(svc.Labels), + asStatus(s.diagnose()), toAge(svc.ObjectMeta.CreationTimestamp), ) return nil } +func (Service) diagnose() error { + return nil +} + // ---------------------------------------------------------------------------- // Helpers... +func toIP(ip string) string { + if ip == "" || ip == "None" { + return "" + } + return ip +} + func getSvcExtIPS(svc *v1.Service) []string { results := []string{} @@ -116,7 +131,7 @@ func toIPs(svcType v1.ServiceType, ips []string) string { if svcType == v1.ServiceTypeLoadBalancer { return "" } - return MissingValue + return "" } sort.Strings(ips) diff --git a/internal/render/svc_test.go b/internal/render/svc_test.go index b74bdf64..63c1c433 100644 --- a/internal/render/svc_test.go +++ b/internal/render/svc_test.go @@ -13,5 +13,5 @@ func TestServiceRender(t *testing.T) { c.Render(load(t, "svc"), "", &r) assert.Equal(t, "default/dictionary1", r.ID) - assert.Equal(t, render.Fields{"default", "dictionary1", "ClusterIP", "10.47.248.116", "", "app=dictionary1", "http:4001►0"}, r.Fields[:7]) + assert.Equal(t, render.Fields{"default", "dictionary1", "ClusterIP", "10.47.248.116", "", "app=dictionary1", "http:4001►0"}, r.Fields[:7]) } diff --git a/internal/tchart/component.go b/internal/tchart/component.go new file mode 100644 index 00000000..64e45757 --- /dev/null +++ b/internal/tchart/component.go @@ -0,0 +1,128 @@ +package tchart + +import ( + "image" + "sync" + + "github.com/derailed/tview" + "github.com/gdamore/tcell" + "github.com/rs/zerolog/log" +) + +const ( + okColor, faultColor = tcell.ColorPaleGreen, tcell.ColorOrangeRed + okColorName, faultColorName = "palegreen", "orangered" +) + +// Component represents a graphic component. +type Component struct { + *tview.Box + + bgColor, noColor tcell.Color + seriesColors []tcell.Color + dimmed tcell.Style + id, legend string + blur func(tcell.Key) + mx sync.RWMutex +} + +// NewComponent returns a new component. +func NewComponent(id string) *Component { + return &Component{ + Box: tview.NewBox(), + id: id, + noColor: tcell.ColorBlack, + seriesColors: []tcell.Color{tview.Styles.PrimaryTextColor, tview.Styles.FocusColor}, + dimmed: tcell.StyleDefault.Background(tview.Styles.PrimitiveBackgroundColor).Foreground(tcell.ColorGray).Dim(true), + } +} + +// SetBackgroundColor sets the graph bg color. +func (c *Component) SetBackgroundColor(color tcell.Color) { + c.Box.SetBackgroundColor(color) + c.bgColor = color + c.dimmed = c.dimmed.Background(color) +} + +// ID returns the component ID. +func (c *Component) ID() string { + return c.id +} + +// SetLegend sets the component legend. +func (c *Component) SetLegend(l string) { + c.mx.Lock() + defer c.mx.Unlock() + c.legend = l +} + +// InputHandler returns the handler for this primitive. +func (c *Component) InputHandler() func(event *tcell.EventKey, setFocus func(p tview.Primitive)) { + return c.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p tview.Primitive)) { + switch key := event.Key(); key { + case tcell.KeyEnter: + log.Debug().Msgf("YO %s ENTER!!", c.id) + case tcell.KeyBacktab, tcell.KeyTab: + log.Debug().Msgf("YO %s TAB!!", c.id) + if c.blur != nil { + c.blur(key) + } + setFocus(c) + } + }) +} + +// IsDial returns true if chart is a dial +func (c *Component) IsDial() bool { + return false +} + +// SetBlurFunc sets a callback fn when component gets out of focus. +func (c *Component) SetBlurFunc(handler func(key tcell.Key)) *Component { + c.blur = handler + return c +} + +// SetSeriesColors sets the component series colors. +func (c *Component) SetSeriesColors(cc ...tcell.Color) { + c.mx.Lock() + defer c.mx.Unlock() + c.seriesColors = cc +} + +// GetSeriesColorNames returns series colors by name. +func (c *Component) GetSeriesColorNames() []string { + c.mx.RLock() + defer c.mx.RUnlock() + + var nn []string + for _, color := range c.seriesColors { + for name, co := range tcell.ColorNames { + if co == color { + nn = append(nn, name) + } + } + } + if len(nn) < 2 { + nn = append(nn, okColorName, faultColorName) + } + + return nn +} + +func (c *Component) colorForSeries() (tcell.Color, tcell.Color) { + c.mx.RLock() + defer c.mx.RUnlock() + if len(c.seriesColors) > 1 { + return c.seriesColors[0], c.seriesColors[1] + } + return okColor, faultColor +} + +func (c *Component) asRect() image.Rectangle { + x, y, width, height := c.GetInnerRect() + return image.Rectangle{ + Min: image.Point{X: x, Y: y}, + Max: image.Point{X: x + width, Y: y + height}, + } +} diff --git a/internal/tchart/dot_matrix.go b/internal/tchart/dot_matrix.go new file mode 100644 index 00000000..8115a314 --- /dev/null +++ b/internal/tchart/dot_matrix.go @@ -0,0 +1,106 @@ +package tchart + +import ( + "fmt" +) + +// var dots = []rune{' ', '⠂', '⠶', '⠿'} +var dots = []rune{' ', '⠂', '▤', '▥'} + +// var dots = []rune{' ', '⠂', '▤', '▇'} + +type Segment []int + +type Segments []Segment + +type Matrix [][]rune + +type Orientation int + +type DotMatrix struct { + row, col int +} + +func NewDotMatrix(row, col int) DotMatrix { + return DotMatrix{ + row: row, + col: col, + } +} + +func (d DotMatrix) Print(n int) Matrix { + m := make(Matrix, d.row) + segs := asSegments(n) + for row := 0; row < d.row; row++ { + for col := 0; col < d.col; col++ { + m[row] = append(m[row], segs.CharFor(row, col)) + } + } + return m +} + +func asSegments(n int) Segment { + switch n { + case 0: + return Segment{1, 1, 1, 0, 1, 1, 1} + case 1: + return Segment{0, 0, 1, 0, 0, 1, 0} + case 2: + return Segment{1, 0, 1, 1, 1, 0, 1} + case 3: + return Segment{1, 0, 1, 1, 0, 1, 1} + case 4: + return Segment{0, 1, 0, 1, 0, 1, 0} + case 5: + return Segment{1, 1, 0, 1, 0, 1, 1} + case 6: + return Segment{0, 1, 0, 1, 1, 1, 1} + case 7: + return Segment{1, 0, 1, 0, 0, 1, 0} + case 8: + return Segment{1, 1, 1, 1, 1, 1, 1} + case 9: + return Segment{1, 1, 1, 1, 0, 1, 0} + + default: + panic(fmt.Sprintf("NYI %d", n)) + } +} + +func (s Segment) CharFor(row, col int) rune { + c := ' ' + segs := ToSegments(row, col) + if segs == nil { + return c + } + for _, seg := range segs { + if s[seg] == 1 { + c = charForSeg(seg, row, col) + } + } + return c +} + +func charForSeg(seg, row, col int) rune { + switch seg { + case 0, 3, 6: + return dots[2] + } + if row == 0 && (col == 0 || col == 2) { + return dots[2] + } + + return dots[3] +} + +var segs = map[int][][]int{ + 0: [][]int{[]int{1, 0}, []int{0}, []int{2, 0}}, + 1: [][]int{[]int{1}, nil, []int{2}}, + 2: [][]int{[]int{1, 3}, []int{3}, []int{2, 3}}, + 3: [][]int{[]int{4}, nil, []int{5}}, + 4: [][]int{[]int{4, 6}, []int{6}, []int{5, 6}}, +} + +func ToSegments(row, col int) []int { + return segs[row][col] +} diff --git a/internal/tchart/dot_matrix_test.go b/internal/tchart/dot_matrix_test.go new file mode 100644 index 00000000..8f032e7d --- /dev/null +++ b/internal/tchart/dot_matrix_test.go @@ -0,0 +1,126 @@ +package tchart_test + +import ( + "strconv" + "testing" + + "github.com/derailed/k9s/internal/tchart" + "github.com/stretchr/testify/assert" +) + +func TestSegmentFor(t *testing.T) { + uu := map[string]struct { + r, c int + e []int + }{ + "0x0": {r: 0, c: 0, e: []int{1, 0}}, + "0x1": {r: 0, c: 1, e: []int{0}}, + "0x2": {r: 0, c: 2, e: []int{2, 0}}, + "1x0": {r: 1, c: 0, e: []int{1}}, + "1x1": {r: 1, c: 1, e: nil}, + "1x2": {r: 1, c: 2, e: []int{2}}, + "2x0": {r: 2, c: 0, e: []int{1, 3}}, + "2x1": {r: 2, c: 1, e: []int{3}}, + "2x2": {r: 2, c: 2, e: []int{2, 3}}, + "3x0": {r: 3, c: 0, e: []int{4}}, + "3x1": {r: 3, c: 1, e: nil}, + "3x2": {r: 3, c: 2, e: []int{5}}, + "4x0": {r: 4, c: 0, e: []int{4, 6}}, + "4x1": {r: 4, c: 1, e: []int{6}}, + "4x2": {r: 4, c: 2, e: []int{5, 6}}, + } + + for k := range uu { + u := uu[k] + t.Run(k, func(t *testing.T) { + assert.Equal(t, u.e, tchart.ToSegments(u.r, u.c)) + }) + } +} + +func TestDial(t *testing.T) { + d := tchart.NewDotMatrix(5, 3) + for n := 0; n <= 9; n++ { + i := n + t.Run(strconv.Itoa(n), func(t *testing.T) { + assert.Equal(t, numbers[i], d.Print(i)) + }) + } +} + +// Helpers... + +const hChar, vChar = '⠶', '⠿' + +var numbers = []tchart.Matrix{ + [][]rune{ + {hChar, hChar, hChar}, + {vChar, ' ', vChar}, + {vChar, ' ', vChar}, + {vChar, ' ', vChar}, + {hChar, hChar, hChar}, + }, + [][]rune{ + {' ', ' ', hChar}, + {' ', ' ', vChar}, + {' ', ' ', vChar}, + {' ', ' ', vChar}, + {' ', ' ', vChar}, + }, + [][]rune{ + {hChar, hChar, hChar}, + {' ', ' ', vChar}, + {hChar, hChar, hChar}, + {vChar, ' ', ' '}, + {hChar, hChar, hChar}, + }, + [][]rune{ + {hChar, hChar, hChar}, + {' ', ' ', vChar}, + {hChar, hChar, hChar}, + {' ', ' ', vChar}, + {hChar, hChar, hChar}, + }, + [][]rune{ + {hChar, ' ', ' '}, + {vChar, ' ', ' '}, + {hChar, hChar, hChar}, + {' ', ' ', vChar}, + {' ', ' ', vChar}, + }, + [][]rune{ + {hChar, hChar, hChar}, + {vChar, ' ', ' '}, + {hChar, hChar, hChar}, + {' ', ' ', vChar}, + {hChar, hChar, hChar}, + }, + [][]rune{ + {hChar, ' ', ' '}, + {vChar, ' ', ' '}, + {hChar, hChar, hChar}, + {vChar, ' ', vChar}, + {hChar, hChar, hChar}, + }, + [][]rune{ + {hChar, hChar, hChar}, + {' ', ' ', vChar}, + {' ', ' ', vChar}, + {' ', ' ', vChar}, + {' ', ' ', vChar}, + }, + [][]rune{ + {hChar, hChar, hChar}, + {vChar, ' ', vChar}, + {hChar, hChar, hChar}, + {vChar, ' ', vChar}, + {hChar, hChar, hChar}, + }, + [][]rune{ + {hChar, hChar, hChar}, + {vChar, ' ', vChar}, + {hChar, hChar, hChar}, + {' ', ' ', vChar}, + {' ', ' ', vChar}, + }, +} diff --git a/internal/tchart/gauge.go b/internal/tchart/gauge.go new file mode 100644 index 00000000..87fa9ce4 --- /dev/null +++ b/internal/tchart/gauge.go @@ -0,0 +1,149 @@ +package tchart + +import ( + "fmt" + "image" + + "github.com/derailed/tview" + "github.com/gdamore/tcell" +) + +const ( + DeltaSame delta = iota + DeltaMore + DeltaLess + + gaugeFmt = "0%dd" +) + +type delta int + +// Gauge represents a gauge component. +type Gauge struct { + *Component + + data Metric + deltaOk, deltaFault delta +} + +// NewGauge returns a new gauge. +func NewGauge(id string) *Gauge { + return &Gauge{ + Component: NewComponent(id), + } +} + +// IsDial returns true if chart is a dial +func (g *Gauge) IsDial() bool { + return true +} + +func (g *Gauge) Add(m Metric) { + g.mx.Lock() + defer g.mx.Unlock() + + g.deltaOk, g.deltaFault = computeDelta(g.data.OK, m.OK), computeDelta(g.data.Fault, m.Fault) + g.data = m +} + +func (g *Gauge) drawNum(sc tcell.Screen, ok bool, o image.Point, n int, dn delta, ns string, style tcell.Style) { + c1, _ := g.colorForSeries() + if ok { + o.X -= 1 + style = style.Foreground(c1) + printDelta(sc, dn, o, style) + o.X += 1 + } + + dm, sig := NewDotMatrix(5, 3), n == 0 + for i := 0; i < len(ns); i++ { + if ns[i] == '0' && !sig { + g.drawDial(sc, dm.Print(int(ns[i]-48)), o, g.dimmed) + } else { + sig = true + g.drawDial(sc, dm.Print(int(ns[i]-48)), o, style) + } + o.X += 5 + } + if !ok { + printDelta(sc, dn, o, style) + } +} + +func (g *Gauge) Draw(sc tcell.Screen) { + g.Component.Draw(sc) + + g.mx.RLock() + defer g.mx.RUnlock() + + rect := g.asRect() + mid := image.Point{X: rect.Min.X + rect.Dx()/2 - 2, Y: rect.Min.Y + rect.Dy()/2 - 2} + + style := tcell.StyleDefault.Background(g.bgColor) + style = style.Foreground(tcell.ColorYellow) + sc.SetContent(mid.X+1, mid.Y+2, '⠔', nil, style) + + var ( + max = g.data.MaxDigits() + fmat = "%" + fmt.Sprintf(gaugeFmt, max) + o = image.Point{X: mid.X - 3, Y: mid.Y} + ) + + s1C, s2C := g.colorForSeries() + d1, d2 := fmt.Sprintf(fmat, g.data.OK), fmt.Sprintf(fmat, g.data.Fault) + o.X -= (len(d1) - 1) * 5 + g.drawNum(sc, true, o, g.data.OK, g.deltaOk, d1, style.Foreground(s1C).Dim(false)) + + o.X = mid.X + 3 + g.drawNum(sc, false, o, g.data.Fault, g.deltaFault, d2, style.Foreground(s2C).Dim(false)) + + if rect.Dx() > 0 && rect.Dy() > 0 && g.legend != "" { + legend := g.legend + if g.HasFocus() { + legend = "[:aqua]" + g.legend + "[::]" + } + tview.Print(sc, legend, rect.Min.X, rect.Max.Y-1, rect.Dx(), tview.AlignCenter, tcell.ColorWhite) + } +} + +func (g *Gauge) drawDial(sc tcell.Screen, m Matrix, o image.Point, style tcell.Style) { + for r := 0; r < len(m); r++ { + for c := 0; c < len(m[r]); c++ { + dot := m[r][c] + if dot == dots[0] { + sc.SetContent(o.X+c, o.Y+r, dots[1], nil, g.dimmed) + } else { + sc.SetContent(o.X+c, o.Y+r, dot, nil, style) + } + } + } +} + +// ---------------------------------------------------------------------------- +// Helpers... + +func computeDelta(d1, d2 int) delta { + if d2 == 0 { + return DeltaSame + } + + d := d2 - d1 + switch { + case d > 0: + return DeltaMore + case d < 0: + return DeltaLess + default: + return DeltaSame + } +} + +func printDelta(sc tcell.Screen, d delta, o image.Point, s tcell.Style) { + s = s.Dim(false) + switch d { + case DeltaLess: + sc.SetContent(o.X-1, o.Y+2, '↓', nil, s) + case DeltaMore: + sc.SetContent(o.X-1, o.Y+2, '↑', nil, s) + } +} diff --git a/internal/tchart/sparkline.go b/internal/tchart/sparkline.go new file mode 100644 index 00000000..e4031892 --- /dev/null +++ b/internal/tchart/sparkline.go @@ -0,0 +1,161 @@ +package tchart + +import ( + "fmt" + "math" + + "github.com/derailed/tview" + "github.com/gdamore/tcell" +) + +var sparks = []rune{'▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'} + +type block struct { + full int + partial rune +} + +type blocks struct { + oks, errs block +} + +// Metric tracks a good and error rates. +type Metric struct { + OK, Fault int +} + +// Max returns the max of the metric. +func (m Metric) MaxDigits() int { + max := int(math.Max(float64(m.OK), float64(m.Fault))) + s := fmt.Sprintf("%d", max) + return len(s) +} + +// Sum returns the sum of the metrics. +func (m Metric) Sum() int { + return m.OK + m.Fault +} + +// Sparkline represents a sparkline component. +type SparkLine struct { + *Component + + data []Metric + lastWidth int +} + +// NewSparkLine returns a new graph. +func NewSparkLine(id string) *SparkLine { + return &SparkLine{ + Component: NewComponent(id), + } +} + +// Add adds a metric. +func (s *SparkLine) Add(m Metric) { + s.mx.Lock() + defer s.mx.Unlock() + s.data = append(s.data, m) +} + +// Draw draws the graph. +func (s *SparkLine) Draw(screen tcell.Screen) { + s.Component.Draw(screen) + + s.mx.RLock() + defer s.mx.RUnlock() + + if len(s.data) == 0 { + return + } + + pad := 1 + if s.legend != "" { + pad++ + } + + rect := s.asRect() + s.lastWidth = rect.Dx() + s.cutSet(rect.Dx()) + max := s.computeMax() + + cX := rect.Min.X + 1 + if len(s.data) < rect.Dx() { + cX = rect.Max.X - len(s.data) + } + + scale := float64(len(sparks)) * float64((rect.Dy() - pad)) / float64(max) + + c1, c2 := s.colorForSeries() + for _, d := range s.data { + b := toBlocks(d, scale) + cY := rect.Max.Y - pad + cY = s.drawBlock(screen, cX, cY, b.oks, c1) + s.drawBlock(screen, cX, cY, b.errs, c2) + cX++ + } + + if rect.Dx() > 0 && rect.Dy() > 0 && s.legend != "" { + legend := s.legend + if s.HasFocus() { + legend = "[:aqua:]" + s.legend + "[::]" + } + tview.Print(screen, legend, rect.Min.X, rect.Max.Y-1, rect.Dx(), tview.AlignCenter, tcell.ColorWhite) + } +} + +func (s *SparkLine) drawBlock(screen tcell.Screen, x, y int, b block, c tcell.Color) int { + style := tcell.StyleDefault.Foreground(c).Background(s.bgColor) + + for i := 0; i < b.full; i++ { + screen.SetContent(x, y, sparks[len(sparks)-1], nil, style) + y-- + } + if b.partial != 0 { + screen.SetContent(x, y, b.partial, nil, style) + } + + return y +} + +func (s *SparkLine) cutSet(w int) { + if w <= 0 || len(s.data) == 0 { + return + } + + if w < len(s.data) { + s.data = s.data[len(s.data)-w:] + } +} + +func (s *SparkLine) computeMax() int { + var max int + for _, d := range s.data { + sum := d.Sum() + if sum > max { + max = sum + } + } + + return max +} + +func toBlocks(value Metric, scale float64) blocks { + if value.Sum() <= 0 { + return blocks{} + } + + oks := int(math.Floor(float64(value.OK) * scale)) + part, okB := oks%len(sparks), block{full: oks / len(sparks)} + if part > 0 { + okB.partial = sparks[part-1] + } + + errs := int(math.Round(float64(value.Fault) * scale)) + part, errB := errs%len(sparks), block{full: errs / len(sparks)} + if part > 0 { + errB.partial = sparks[part-1] + } + + return blocks{oks: okB, errs: errB} +} diff --git a/internal/ui/app.go b/internal/ui/app.go index 54f2a833..efe187a7 100644 --- a/internal/ui/app.go +++ b/internal/ui/app.go @@ -3,6 +3,7 @@ package ui import ( "github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/config" + "github.com/derailed/k9s/internal/model" "github.com/derailed/tview" "github.com/gdamore/tcell" "github.com/rs/zerolog/log" @@ -14,6 +15,7 @@ type App struct { Configurator Main *Pages + flash *model.Flash actions KeyActions views map[string]tview.Primitive cmdBuff *CmdBuff @@ -25,6 +27,7 @@ func NewApp(context string) *App { Application: tview.NewApplication(), actions: make(KeyActions), Main: NewPages(), + flash: model.NewFlash(model.DefaultFlashDelay), cmdBuff: NewCmdBuff(':', CommandBuff), } a.ReloadStyles(context) @@ -33,7 +36,6 @@ func NewApp(context string) *App { "menu": NewMenu(a.Styles), "logo": NewLogo(a.Styles), "cmd": NewCommand(a.Styles), - "flash": NewFlash(&a, "Initializing..."), "crumbs": NewCrumbs(a.Styles), } @@ -239,11 +241,6 @@ func (a *App) Logo() *Logo { return a.views["logo"].(*Logo) } -// Flash returns app flash. -func (a *App) Flash() *Flash { - return a.views["flash"].(*Flash) -} - // Cmd returns app cmd. func (a *App) Cmd() *Command { return a.views["cmd"].(*Command) @@ -254,6 +251,11 @@ func (a *App) Menu() *Menu { return a.views["menu"].(*Menu) } +// Flash returns a flash model. +func (a *App) Flash() *model.Flash { + return a.flash +} + // ---------------------------------------------------------------------------- // Helpers... diff --git a/internal/ui/app_test.go b/internal/ui/app_test.go index 4e189c59..2fdde772 100644 --- a/internal/ui/app_test.go +++ b/internal/ui/app_test.go @@ -59,7 +59,7 @@ func TestAppViews(t *testing.T) { a := ui.NewApp("") a.Init() - vv := []string{"crumbs", "logo", "cmd", "flash", "menu"} + vv := []string{"crumbs", "logo", "cmd", "menu"} for i := range vv { v := vv[i] t.Run(v, func(t *testing.T) { @@ -68,7 +68,6 @@ func TestAppViews(t *testing.T) { } assert.NotNil(t, a.Crumbs()) - assert.NotNil(t, a.Flash()) assert.NotNil(t, a.Logo()) assert.NotNil(t, a.Cmd()) assert.NotNil(t, a.Menu()) diff --git a/internal/ui/config.go b/internal/ui/config.go index 857179db..2620aea2 100644 --- a/internal/ui/config.go +++ b/internal/ui/config.go @@ -79,6 +79,8 @@ func (c *Configurator) RefreshStyles(context string) { clusterSkins := filepath.Join(config.K9sHome, fmt.Sprintf("%s_skin.yml", context)) if c.Styles == nil { c.Styles = config.NewStyles() + } else { + c.Styles.Reset() } if err := c.Styles.Load(clusterSkins); err != nil { log.Info().Msgf("No context specific skin file found -- %s", clusterSkins) @@ -102,10 +104,10 @@ func (c *Configurator) updateStyles(f string) { } c.Styles.Update() - render.StdColor = config.AsColor(c.Styles.Frame().Status.NewColor) - render.AddColor = config.AsColor(c.Styles.Frame().Status.AddColor) - render.ModColor = config.AsColor(c.Styles.Frame().Status.ModifyColor) - render.ErrColor = config.AsColor(c.Styles.Frame().Status.ErrorColor) - render.HighlightColor = config.AsColor(c.Styles.Frame().Status.HighlightColor) - render.CompletedColor = config.AsColor(c.Styles.Frame().Status.CompletedColor) + render.StdColor = c.Styles.Frame().Status.NewColor.Color() + render.AddColor = c.Styles.Frame().Status.AddColor.Color() + render.ModColor = c.Styles.Frame().Status.ModifyColor.Color() + render.ErrColor = c.Styles.Frame().Status.ErrorColor.Color() + render.HighlightColor = c.Styles.Frame().Status.HighlightColor.Color() + render.CompletedColor = c.Styles.Frame().Status.CompletedColor.Color() } diff --git a/internal/ui/flash.go b/internal/ui/flash.go index 956cb893..acd6d588 100644 --- a/internal/ui/flash.go +++ b/internal/ui/flash.go @@ -2,51 +2,30 @@ package ui import ( "context" - "fmt" - "strings" - "time" "github.com/derailed/k9s/internal/config" - "github.com/derailed/k9s/internal/render" + "github.com/derailed/k9s/internal/model" "github.com/derailed/tview" "github.com/gdamore/tcell" "github.com/rs/zerolog/log" ) const ( - // FlashInfo represents an info message. - FlashInfo FlashLevel = iota - // FlashWarn represents an warning message. - FlashWarn - // FlashErr represents an error message. - FlashErr - // FlashFatal represents an fatal message. - FlashFatal - - flashDelay = 3 * time.Second - + emoHappy = "😎" emoDoh = "😗" emoRed = "😡" - emoDead = "💀" - emoHappy = "😎" ) -type ( - // FlashLevel represents flash message severity. - FlashLevel int +// Flash represents a flash message indicator. +type Flash struct { + *tview.TextView - // Flash represents a flash message indicator. - Flash struct { - *tview.TextView - - cancel context.CancelFunc - app *App - flushNow bool - } -) + app *App + testMode bool +} // NewFlash returns a new flash view. -func NewFlash(app *App, m string) *Flash { +func NewFlash(app *App) *Flash { f := Flash{ app: app, TextView: tview.NewTextView(), @@ -54,15 +33,14 @@ func NewFlash(app *App, m string) *Flash { f.SetTextColor(tcell.ColorAqua) f.SetTextAlign(tview.AlignLeft) f.SetBorderPadding(0, 0, 1, 1) - f.SetText(m) f.app.Styles.AddListener(&f) return &f } -// TestMode for testing... -func (f *Flash) TestMode() { - f.flushNow = true +// SetTestMode for testing ONLY! +func (f *Flash) SetTestMode(b bool) { + f.testMode = b } // StylesChanged notifies listener the skin changed. @@ -71,101 +49,53 @@ func (f *Flash) StylesChanged(s *config.Styles) { f.SetTextColor(s.FgColor()) } -// Info displays an info flash message. -func (f *Flash) Info(msg string) { - log.Info().Msg(msg) - f.SetMessage(FlashInfo, msg) -} - -// Infof displays a formatted info flash message. -func (f *Flash) Infof(fmat string, args ...interface{}) { - f.Info(fmt.Sprintf(fmat, args...)) -} - -// Warn displays a warning flash message. -func (f *Flash) Warn(msg string) { - log.Warn().Msg(msg) - f.SetMessage(FlashWarn, msg) -} - -// Warnf displays a formatted warning flash message. -func (f *Flash) Warnf(fmat string, args ...interface{}) { - f.Warn(fmt.Sprintf(fmat, args...)) -} - -// Err displays an error flash message. -func (f *Flash) Err(err error) { - log.Error().Msg(err.Error()) - f.SetMessage(FlashErr, err.Error()) -} - -// Errf displays a formatted error flash message. -func (f *Flash) Errf(fmat string, args ...interface{}) { - var err error - for _, a := range args { - switch e := a.(type) { - case error: - err = e +func (f *Flash) Watch(ctx context.Context, c model.FlashChan) { + defer log.Debug().Msgf("Flash Canceled!") + for { + select { + case <-ctx.Done(): + return + case msg := <-c: + f.SetMessage(msg) } } - log.Error().Err(err).Msgf(fmat, args...) - f.SetMessage(FlashErr, fmt.Sprintf(fmat, args...)) } // SetMessage sets flash message and level. -func (f *Flash) SetMessage(level FlashLevel, msg ...string) { - if f.cancel != nil { - f.cancel() +func (f *Flash) SetMessage(m model.LevelMessage) { + fn := func() { + if m.Text == "" { + f.Clear() + return + } + f.SetTextColor(flashColor(m.Level)) + f.SetText(flashEmoji(m.Level) + " " + m.Text) } - _, _, width, _ := f.GetRect() - if width <= 15 { - width = 100 - } - m := strings.Join(msg, " ") - if f.flushNow { - f.SetTextColor(flashColor(level)) - f.SetText(render.Truncate(flashEmoji(level)+" "+m, width-3)) + if f.testMode { + fn() } else { - f.app.QueueUpdateDraw(func() { - f.SetTextColor(flashColor(level)) - f.SetText(render.Truncate(flashEmoji(level)+" "+m, width-3)) - }) + f.app.QueueUpdateDraw(fn) } - - var ctx context.Context - ctx, f.cancel = context.WithTimeout(context.Background(), flashDelay) - go f.refresh(ctx) } -func (f *Flash) refresh(ctx context.Context) { - <-ctx.Done() - f.app.QueueUpdateDraw(func() { - f.Clear() - }) -} - -func flashEmoji(l FlashLevel) string { +func flashEmoji(l model.FlashLevel) string { switch l { - case FlashWarn: + case model.FlashWarn: return emoDoh - case FlashErr: + case model.FlashErr: return emoRed - case FlashFatal: - return emoDead default: return emoHappy } } -func flashColor(l FlashLevel) tcell.Color { +func flashColor(l model.FlashLevel) tcell.Color { switch l { - case FlashWarn: + case model.FlashWarn: return tcell.ColorOrange - case FlashErr: + case model.FlashErr: return tcell.ColorOrangeRed - case FlashFatal: - return tcell.ColorFuchsia default: return tcell.ColorNavajoWhite } diff --git a/internal/ui/flash_test.go b/internal/ui/flash_test.go index c158f166..e46c591d 100644 --- a/internal/ui/flash_test.go +++ b/internal/ui/flash_test.go @@ -1,45 +1,40 @@ package ui_test import ( - "errors" + "context" "testing" + "time" + "github.com/derailed/k9s/internal/model" "github.com/derailed/k9s/internal/ui" "github.com/stretchr/testify/assert" ) -func TestFlashInfo(t *testing.T) { - f := newFlash() - f.Info("Blee") +func TestFlash(t *testing.T) { + const delay = 1 * time.Millisecond + uu := map[string]struct { + l model.FlashLevel + i, e string + }{ + "info": {l: model.FlashInfo, i: "hello", e: "😎 hello\n"}, + "warn": {l: model.FlashWarn, i: "hello", e: "😗 hello\n"}, + "err": {l: model.FlashErr, i: "hello", e: "😡 hello\n"}, + } - assert.Equal(t, "😎 Blee\n", f.GetText(false)) - f.Infof("Blee %s", "duh") - assert.Equal(t, "😎 Blee duh\n", f.GetText(false)) -} - -func TestFlashWarn(t *testing.T) { - f := newFlash() - f.Warn("Blee") - - assert.Equal(t, "😗 Blee\n", f.GetText(false)) - f.Warnf("Blee %s", "duh") - assert.Equal(t, "😗 Blee duh\n", f.GetText(false)) -} - -func TestFlashErr(t *testing.T) { - f := newFlash() - - f.Err(errors.New("Blee")) - assert.Equal(t, "😡 Blee\n", f.GetText(false)) - f.Errf("Blee %s", "duh") - assert.Equal(t, "😡 Blee duh\n", f.GetText(false)) -} - -// ---------------------------------------------------------------------------- -// Helpers... - -func newFlash() *ui.Flash { - f := ui.NewFlash(ui.NewApp(""), "YO!") - f.TestMode() - return f + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + a := ui.NewApp("test") + f := ui.NewFlash(a) + f.SetTestMode(true) + go f.Watch(ctx, a.Flash().Channel()) + + for k := range uu { + u := uu[k] + t.Run(k, func(t *testing.T) { + a.Flash().SetMessage(u.l, u.i) + time.Sleep(delay) + assert.Equal(t, u.e, f.GetText(false)) + }) + } } diff --git a/internal/ui/logo.go b/internal/ui/logo.go index e5f2ec9c..500b8840 100644 --- a/internal/ui/logo.go +++ b/internal/ui/logo.go @@ -60,30 +60,30 @@ func (l *Logo) Reset() { // Err displays a log error state. func (l *Logo) Err(msg string) { - l.update(msg, "red") + l.update(msg, config.NewColor("red")) } // Warn displays a log warning state. func (l *Logo) Warn(msg string) { - l.update(msg, "mediumvioletred") + l.update(msg, config.NewColor("mediumvioletred")) } // Info displays a log info state. func (l *Logo) Info(msg string) { - l.update(msg, "green") + l.update(msg, config.NewColor("green")) } -func (l *Logo) update(msg, c string) { +func (l *Logo) update(msg string, c config.Color) { l.refreshStatus(msg, c) l.refreshLogo(c) } -func (l *Logo) refreshStatus(msg, c string) { - l.status.SetBackgroundColor(config.AsColor(c)) +func (l *Logo) refreshStatus(msg string, c config.Color) { + l.status.SetBackgroundColor(c.Color()) l.status.SetText(fmt.Sprintf("[white::b]%s", msg)) } -func (l *Logo) refreshLogo(c string) { +func (l *Logo) refreshLogo(c config.Color) { l.logo.Clear() for i, s := range LogoSmall { fmt.Fprintf(l.logo, "[%s::b]%s", c, s) diff --git a/internal/ui/menu.go b/internal/ui/menu.go index 958cf5d9..cc1ea1d6 100644 --- a/internal/ui/menu.go +++ b/internal/ui/menu.go @@ -188,16 +188,16 @@ func toMnemonic(s string) string { } func formatNSMenu(i int, name string, styles config.Frame) string { - fmat := strings.Replace(menuIndexFmt, "[key", "["+styles.Menu.NumKeyColor, 1) - fmat = strings.Replace(fmat, ":bg:", ":"+styles.Title.BgColor+":", -1) - fmat = strings.Replace(fmat, "[fg", "["+styles.Menu.FgColor, 1) + fmat := strings.Replace(menuIndexFmt, "[key", "["+styles.Menu.NumKeyColor.String(), 1) + fmat = strings.Replace(fmat, ":bg:", ":"+styles.Title.BgColor.String()+":", -1) + fmat = strings.Replace(fmat, "[fg", "["+styles.Menu.FgColor.String(), 1) return fmt.Sprintf(fmat, i, name) } func formatPlainMenu(h model.MenuHint, size int, styles config.Frame) string { menuFmt := " [key:-:b]%-" + strconv.Itoa(size+2) + "s [fg:-:d]%s " - fmat := strings.Replace(menuFmt, "[key", "["+styles.Menu.KeyColor, 1) - fmat = strings.Replace(fmat, "[fg", "["+styles.Menu.FgColor, 1) - fmat = strings.Replace(fmat, ":bg:", ":"+styles.Title.BgColor+":", -1) + fmat := strings.Replace(menuFmt, "[key", "["+styles.Menu.KeyColor.String(), 1) + fmat = strings.Replace(fmat, "[fg", "["+styles.Menu.FgColor.String(), 1) + fmat = strings.Replace(fmat, ":bg:", ":"+styles.Title.BgColor.String()+":", -1) return fmt.Sprintf(fmat, toMnemonic(h.Mnemonic), h.Description) } diff --git a/internal/ui/table.go b/internal/ui/table.go index a9c8c9e5..bcb2e224 100644 --- a/internal/ui/table.go +++ b/internal/ui/table.go @@ -38,6 +38,8 @@ type Table struct { sortCol SortColumn colorerFn render.ColorerFunc decorateFn DecorateFunc + wide bool + toast bool } // NewTable returns a new table view. @@ -65,6 +67,7 @@ func (t *Table) Init(ctx context.Context) { t.SetSelectable(true, false) t.SetSelectionChangedFunc(t.selectionChanged) t.SetInputCapture(t.keyboard) + t.SetBackgroundColor(tcell.ColorDefault) t.styles = mustExtractSyles(ctx) t.StylesChanged(t.styles) @@ -72,17 +75,35 @@ func (t *Table) Init(ctx context.Context) { // StylesChanged notifies the skin changed. func (t *Table) StylesChanged(s *config.Styles) { - t.SetBackgroundColor(config.AsColor(s.Table().BgColor)) - t.SetBorderColor(config.AsColor(s.Table().FgColor)) - t.SetBorderFocusColor(config.AsColor(s.Frame().Border.FocusColor)) + t.SetBackgroundColor(s.Table().BgColor.Color()) + t.SetBorderColor(s.Table().FgColor.Color()) + t.SetBorderFocusColor(s.Frame().Border.FocusColor.Color()) t.SetSelectedStyle( tcell.ColorBlack, - config.AsColor(t.styles.Table().CursorColor), + t.styles.Table().CursorColor.Color(), tcell.AttrBold, ) t.Refresh() } +// ResetToast resets toast flag. +func (t *Table) ResetToast() { + t.toast = false + t.Refresh() +} + +// ToggleToast toggles to show toast resources. +func (t *Table) ToggleToast() { + t.toast = !t.toast + t.Refresh() +} + +// ToggleWide toggles wide col display. +func (t *Table) ToggleWide() { + t.wide = !t.wide + t.Refresh() +} + // Actions returns active menu bindings. func (t *Table) Actions() KeyActions { return t.actions @@ -166,10 +187,7 @@ func (t *Table) Update(data render.TableData) { if t.decorateFn != nil { data = t.decorateFn(data) } - if !t.cmdBuff.Empty() { - data = t.filtered(data) - } - t.doUpdate(data) + t.doUpdate(t.filtered(data)) t.UpdateTitle() } @@ -182,13 +200,18 @@ func (t *Table) doUpdate(data render.TableData) { t.Clear() t.adjustSorter(data) - fg := config.AsColor(t.styles.Table().Header.FgColor) - bg := config.AsColor(t.styles.Table().Header.BgColor) - for col, h := range data.Header { + fg := t.styles.Table().Header.FgColor.Color() + bg := t.styles.Table().Header.BgColor.Color() + var col int + for _, h := range data.Header { + if h.Wide && !t.wide { + continue + } t.AddHeaderCell(col, h) c := t.GetCell(0, col) c.SetBackgroundColor(bg) c.SetTextColor(fg) + col++ } data.RowEvents.Sort(data.Namespace, t.sortCol.index, t.sortCol.asc) @@ -209,6 +232,8 @@ func (t *Table) SortColCmd(col int, asc bool) func(evt *tcell.EventKey) *tcell.E index = 0 case -1: index = t.GetColumnCount() - 1 + case -3: + index = t.GetColumnCount() - 2 default: index = t.NameColIndex() + col } @@ -251,29 +276,33 @@ func (t *Table) buildRow(ns string, r int, re render.RowEvent, header render.Hea color = t.colorerFn } marked := t.IsMarked(re.Row.ID) - for col, field := range re.Row.Fields { - if !re.Deltas.IsBlank() && !header.AgeCol(col) { - field += Deltas(re.Deltas[col], field) + var col int + for c, field := range re.Row.Fields { + if header[c].Wide && !t.wide { + continue + } + if !re.Deltas.IsBlank() && !header.AgeCol(c) { + field += Deltas(re.Deltas[c], field) + } + if header[c].Decorator != nil { + field = header[c].Decorator(field) + } + if header[c].Align == tview.AlignLeft { + field = formatCell(field, pads[c]) } - if header[col].Decorator != nil { - field = header[col].Decorator(field) - } - - if header[col].Align == tview.AlignLeft { - field = formatCell(field, pads[col]) - } - c := tview.NewTableCell(field) - c.SetExpansion(1) - c.SetAlign(header[col].Align) - c.SetTextColor(color(ns, re)) + cell := tview.NewTableCell(field) + cell.SetExpansion(1) + cell.SetAlign(header[c].Align) + cell.SetTextColor(color(ns, re)) if marked { - c.SetTextColor(config.AsColor(t.styles.Table().MarkColor)) + cell.SetTextColor(t.styles.Table().MarkColor.Color()) } if col == 0 { - c.SetReference(re.Row.ID) + cell.SetReference(re.Row.ID) } - t.SetCell(r, col, c) + t.SetCell(r, col, cell) + col++ } } @@ -298,6 +327,9 @@ func (t *Table) GetSelectedRow() render.Row { // NameColIndex returns the index of the resource name column. func (t *Table) NameColIndex() int { col := 0 + if client.IsClusterScoped(t.GetModel().GetNamespace()) { + return col + } if t.GetModel().ClusterWide() { col++ } @@ -313,20 +345,25 @@ func (t *Table) AddHeaderCell(col int, h render.Header) { } func (t *Table) filtered(data render.TableData) render.TableData { - if t.cmdBuff.Empty() || IsLabelSelector(t.cmdBuff.String()) { - return data + filtered := data + if t.toast { + filtered = filterToast(data) } - q := t.cmdBuff.String() - if IsFuzzySelector(q) { - return fuzzyFilter(q[2:], t.NameColIndex(), data) + if t.cmdBuff.Empty() || IsLabelSelector(t.cmdBuff.String()) { + return filtered } - filtered, err := rxFilter(t.cmdBuff.String(), data) + q := t.cmdBuff.String() + if IsFuzzySelector(q) { + return fuzzyFilter(q[2:], t.NameColIndex(), filtered) + } + + filtered, err := rxFilter(t.cmdBuff.String(), filtered) if err != nil { log.Error().Err(errors.New("Invalid filter expression")).Msg("Regexp") t.cmdBuff.Clear() - return data } + return filtered } diff --git a/internal/ui/table_helper.go b/internal/ui/table_helper.go index c3d5b0ef..3f02d7d6 100644 --- a/internal/ui/table_helper.go +++ b/internal/ui/table_helper.go @@ -85,15 +85,15 @@ func TrimLabelSelector(s string) string { // SkinTitle decorates a title. func SkinTitle(fmat string, style config.Frame) string { bgColor := style.Title.BgColor - if bgColor == "default" { - bgColor = "-" + if bgColor == config.DefaultColor { + bgColor = config.TransparentColor } - fmat = strings.Replace(fmat, "[fg:bg", "["+style.Title.FgColor+":"+bgColor, -1) - fmat = strings.Replace(fmat, "[hilite", "["+style.Title.HighlightColor, 1) - fmat = strings.Replace(fmat, "[key", "["+style.Menu.NumKeyColor, 1) - fmat = strings.Replace(fmat, "[filter", "["+style.Title.FilterColor, 1) - fmat = strings.Replace(fmat, "[count", "["+style.Title.CounterColor, 1) - fmat = strings.Replace(fmat, ":bg:", ":"+bgColor+":", -1) + fmat = strings.Replace(fmat, "[fg:bg", "["+style.Title.FgColor.String()+":"+bgColor.String(), -1) + fmat = strings.Replace(fmat, "[hilite", "["+style.Title.HighlightColor.String(), 1) + fmat = strings.Replace(fmat, "[key", "["+style.Menu.NumKeyColor.String(), 1) + fmat = strings.Replace(fmat, "[filter", "["+style.Title.FilterColor.String(), 1) + fmat = strings.Replace(fmat, "[count", "["+style.Title.CounterColor.String(), 1) + fmat = strings.Replace(fmat, ":bg:", ":"+bgColor.String()+":", -1) return fmat } @@ -118,6 +118,25 @@ func formatCell(field string, padding int) string { return field } +func filterToast(data render.TableData) render.TableData { + validX := data.Header.IndexOf("VALID") + if validX == -1 { + return data + } + + toast := render.TableData{ + Header: data.Header, + RowEvents: make(render.RowEvents, 0, len(data.RowEvents)), + Namespace: data.Namespace, + } + for _, re := range data.RowEvents { + if re.Row.Fields[validX] != "" { + toast.RowEvents = append(toast.RowEvents, re) + } + } + return toast +} + func rxFilter(q string, data render.TableData) (render.TableData, error) { rx, err := regexp.Compile(`(?i)` + q) if err != nil { diff --git a/internal/ui/table_test.go b/internal/ui/table_test.go index 9f63fc8e..bc32a21d 100644 --- a/internal/ui/table_test.go +++ b/internal/ui/table_test.go @@ -66,6 +66,7 @@ func (t *testModel) Peek() render.TableData { return makeTableData() } func (t *testModel) ClusterWide() bool { return false } func (t *testModel) GetNamespace() string { return "blee" } func (t *testModel) SetNamespace(string) {} +func (t *testModel) ToggleToast() {} func (t *testModel) AddListener(model.TableListener) {} func (t *testModel) Watch(context.Context) {} func (t *testModel) Get(ctx context.Context, path string) (runtime.Object, error) { diff --git a/internal/view/alias.go b/internal/view/alias.go index 6b6b7b43..4e822f2f 100644 --- a/internal/view/alias.go +++ b/internal/view/alias.go @@ -32,6 +32,14 @@ func NewAlias(gvr client.GVR) ResourceViewer { return &a } +func (a *Alias) Init(ctx context.Context) error { + if err := a.ResourceViewer.Init(ctx); err != nil { + return err + } + a.GetTable().GetModel().SetNamespace("*") + return nil +} + func (a *Alias) aliasContext(ctx context.Context) context.Context { return context.WithValue(ctx, internal.KeyAliases, a.App().command.alias) } diff --git a/internal/view/alias_test.go b/internal/view/alias_test.go index ecc4c8d0..24199528 100644 --- a/internal/view/alias_test.go +++ b/internal/view/alias_test.go @@ -23,7 +23,7 @@ func TestAliasNew(t *testing.T) { assert.Nil(t, v.Init(makeContext())) assert.Equal(t, "Aliases", v.Name()) - assert.Equal(t, 5, len(v.Hints())) + assert.Equal(t, 7, len(v.Hints())) } func TestAliasSearch(t *testing.T) { @@ -105,6 +105,7 @@ func (t *testModel) Peek() render.TableData { return makeTableData() } func (t *testModel) ClusterWide() bool { return false } func (t *testModel) GetNamespace() string { return "blee" } func (t *testModel) SetNamespace(string) {} +func (t *testModel) ToggleToast() {} func (t *testModel) AddListener(model.TableListener) {} func (t *testModel) Watch(context.Context) {} func (t *testModel) Get(context.Context, string) (runtime.Object, error) { diff --git a/internal/view/app.go b/internal/view/app.go index 903917a1..98997efe 100644 --- a/internal/view/app.go +++ b/internal/view/app.go @@ -98,11 +98,14 @@ func (a *App) Init(version string, rate int) error { a.clusterInfo().Init() + flash := ui.NewFlash(a.App) + go flash.Watch(ctx, a.Flash().Channel()) + main := tview.NewFlex().SetDirection(tview.FlexRow) main.AddItem(a.statusIndicator(), 1, 1, false) main.AddItem(a.Content, 0, 10, true) main.AddItem(a.Crumbs(), 2, 1, false) - main.AddItem(a.Flash(), 2, 1, false) + main.AddItem(flash, 2, 1, false) a.Main.AddPage("main", main, true, false) a.Main.AddPage("splash", ui.NewSplash(a.Styles, version), true, true) @@ -113,7 +116,7 @@ func (a *App) Init(version string, rate int) error { func (a *App) bindKeys() { a.AddActions(ui.KeyActions{ - ui.KeyT: ui.NewSharedKeyAction("ToggleHeader", a.toggleHeaderCmd, false), + tcell.KeyCtrlE: ui.NewSharedKeyAction("ToggleHeader", a.toggleHeaderCmd, false), ui.KeyHelp: ui.NewSharedKeyAction("Help", a.helpCmd, false), tcell.KeyCtrlA: ui.NewSharedKeyAction("Aliases", a.aliasCmd, false), tcell.KeyEnter: ui.NewKeyAction("Goto", a.gotoCmd, false), @@ -198,7 +201,7 @@ func (a *App) refreshCluster() { if ok := a.Conn().CheckConnectivity(); ok { if atomic.LoadInt32(&a.conRetry) > 0 { atomic.StoreInt32(&a.conRetry, 0) - a.Status(ui.FlashInfo, "K8s connectivity OK") + a.Status(model.FlashInfo, "K8s connectivity OK") if c != nil { c.Start() } @@ -210,7 +213,7 @@ func (a *App) refreshCluster() { } count := atomic.LoadInt32(&a.conRetry) log.Warn().Msgf("Conn check failed (%d/%d)", count, maxConRetry) - a.Status(ui.FlashWarn, fmt.Sprintf("Dial K8s failed (%d)", count)) + a.Status(model.FlashWarn, fmt.Sprintf("Dial K8s failed (%d)", count)) } count := atomic.LoadInt32(&a.conRetry) @@ -258,6 +261,7 @@ func (a *App) switchCtx(name string, loadPods bool) error { } a.initFactory(ns) + client.ResetMetrics() if err := a.command.Reset(true); err != nil { return err } @@ -309,7 +313,7 @@ func (a *App) Run() error { } // Status reports a new app status for display. -func (a *App) Status(l ui.FlashLevel, msg string) { +func (a *App) Status(l model.FlashLevel, msg string) { a.QueueUpdateDraw(func() { a.Flash().SetMessage(l, msg) a.setIndicator(l, msg) @@ -327,13 +331,13 @@ func (a *App) ClearStatus(flash bool) { }) } -func (a *App) setLogo(l ui.FlashLevel, msg string) { +func (a *App) setLogo(l model.FlashLevel, msg string) { switch l { - case ui.FlashErr: + case model.FlashErr: a.Logo().Err(msg) - case ui.FlashWarn: + case model.FlashWarn: a.Logo().Warn(msg) - case ui.FlashInfo: + case model.FlashInfo: a.Logo().Info(msg) default: a.Logo().Reset() @@ -341,13 +345,13 @@ func (a *App) setLogo(l ui.FlashLevel, msg string) { a.Draw() } -func (a *App) setIndicator(l ui.FlashLevel, msg string) { +func (a *App) setIndicator(l model.FlashLevel, msg string) { switch l { - case ui.FlashErr: + case model.FlashErr: a.statusIndicator().Err(msg) - case ui.FlashWarn: + case model.FlashWarn: a.statusIndicator().Warn(msg) - case ui.FlashInfo: + case model.FlashInfo: a.statusIndicator().Info(msg) default: a.statusIndicator().Reset() diff --git a/internal/view/browser.go b/internal/view/browser.go index 80c65281..9d561876 100644 --- a/internal/view/browser.go +++ b/internal/view/browser.go @@ -94,6 +94,10 @@ func (b *Browser) Start() { b.Stop() b.Table.Start() + b.GetModel().Watch(b.prepareContext()) +} + +func (b *Browser) prepareContext() context.Context { ctx := b.defaultContext() ctx, b.cancelFn = context.WithCancel(ctx) if b.contextFn != nil { @@ -102,7 +106,8 @@ func (b *Browser) Start() { if path, ok := ctx.Value(internal.KeyPath).(string); ok && path != "" { b.Path = path } - b.GetModel().Watch(ctx) + + return ctx } // Stop terminates browser updates. @@ -275,20 +280,22 @@ func (b *Browser) editCmd(evt *tcell.EventKey) *tcell.EventKey { path := b.GetSelectedItem() if path == "" { return evt + + } + ns, n := client.Namespaced(path) + + if ok, err := b.app.Conn().CanI(ns, b.GVR(), []string{"edit"}); !ok || err != nil { + b.App().Flash().Err(fmt.Errorf("Current user can't edit resource %s", b.GVR())) + return nil } b.Stop() defer b.Start() { - ns, n := client.Namespaced(path) args := make([]string, 0, 10) args = append(args, "edit") args = append(args, b.meta.SingularName) args = append(args, "-n", ns) - args = append(args, "--context", b.app.Config.K9s.CurrentContext) - if cfg := b.app.Conn().Config().Flags().KubeConfig; cfg != nil && *cfg != "" { - args = append(args, "--kubeconfig", *cfg) - } if !runK(b.app, shellOpts{clear: true, args: append(args, n)}) { b.app.Flash().Err(errors.New("Edit exec failed")) } diff --git a/internal/view/cluster_info.go b/internal/view/cluster_info.go index dc87cfa5..df75851e 100644 --- a/internal/view/cluster_info.go +++ b/internal/view/cluster_info.go @@ -67,7 +67,7 @@ func (c *ClusterInfo) sectionCell(t string) *tview.TableCell { func (c *ClusterInfo) infoCell(t string) *tview.TableCell { cell := tview.NewTableCell(t) cell.SetExpansion(2) - cell.SetTextColor(config.AsColor(c.styles.K9s.Info.FgColor)) + cell.SetTextColor(c.styles.K9s.Info.FgColor.Color()) cell.SetBackgroundColor(c.app.Styles.BgColor()) return cell @@ -119,9 +119,9 @@ func (c *ClusterInfo) ClusterInfoChanged(prev, curr model.ClusterMeta) { func (c *ClusterInfo) updateStyle() { for row := 0; row < c.GetRowCount(); row++ { - c.GetCell(row, 0).SetTextColor(config.AsColor(c.styles.K9s.Info.FgColor)) + c.GetCell(row, 0).SetTextColor(c.styles.K9s.Info.FgColor.Color()) c.GetCell(row, 0).SetBackgroundColor(c.styles.BgColor()) var s tcell.Style - c.GetCell(row, 1).SetStyle(s.Bold(true).Foreground(config.AsColor(c.styles.K9s.Info.SectionColor))) + c.GetCell(row, 1).SetStyle(s.Bold(true).Foreground(c.styles.K9s.Info.SectionColor.Color())) } } diff --git a/internal/view/container.go b/internal/view/container.go index e128ccac..5d126494 100644 --- a/internal/view/container.go +++ b/internal/view/container.go @@ -57,7 +57,7 @@ func (c *Container) bindKeys(aa ui.KeyActions) { ui.KeyShiftX: ui.NewKeyAction("Sort %CPU (REQ)", c.GetTable().SortColCmd(8, false), false), ui.KeyShiftZ: ui.NewKeyAction("Sort %MEM (REQ)", c.GetTable().SortColCmd(9, false), false), tcell.KeyCtrlX: ui.NewKeyAction("Sort %CPU (LIM)", c.GetTable().SortColCmd(8, false), false), - tcell.KeyCtrlZ: ui.NewKeyAction("Sort %MEM (LIM)", c.GetTable().SortColCmd(9, false), false), + tcell.KeyCtrlQ: ui.NewKeyAction("Sort %MEM (LIM)", c.GetTable().SortColCmd(9, false), false), }) } diff --git a/internal/view/container_test.go b/internal/view/container_test.go index 7e8497fa..732c35e9 100644 --- a/internal/view/container_test.go +++ b/internal/view/container_test.go @@ -13,5 +13,5 @@ func TestContainerNew(t *testing.T) { assert.Nil(t, c.Init(makeCtx())) assert.Equal(t, "Containers", c.Name()) - assert.Equal(t, 13, len(c.Hints())) + assert.Equal(t, 15, len(c.Hints())) } diff --git a/internal/view/context_test.go b/internal/view/context_test.go index ebefd197..dc0f693e 100644 --- a/internal/view/context_test.go +++ b/internal/view/context_test.go @@ -13,5 +13,5 @@ func TestContext(t *testing.T) { assert.Nil(t, ctx.Init(makeCtx())) assert.Equal(t, "Contexts", ctx.Name()) - assert.Equal(t, 2, len(ctx.Hints())) + assert.Equal(t, 4, len(ctx.Hints())) } diff --git a/internal/view/details.go b/internal/view/details.go index 66d64624..a468fa1b 100644 --- a/internal/view/details.go +++ b/internal/view/details.go @@ -161,7 +161,7 @@ func (d *Details) filterInput(r rune) bool { func (d *Details) StylesChanged(s *config.Styles) { d.SetBackgroundColor(d.app.Styles.BgColor()) d.SetTextColor(d.app.Styles.FgColor()) - d.SetBorderFocusColor(config.AsColor(d.app.Styles.Frame().Border.FocusColor)) + d.SetBorderFocusColor(d.app.Styles.Frame().Border.FocusColor.Color()) d.TextChanged(d.model.Peek()) } diff --git a/internal/view/dp.go b/internal/view/dp.go index d88464a8..aa92c575 100644 --- a/internal/view/dp.go +++ b/internal/view/dp.go @@ -40,7 +40,7 @@ func (d *Deploy) bindKeys(aa ui.KeyActions) { aa.Add(ui.KeyActions{ ui.KeyShiftR: ui.NewKeyAction("Sort Ready", d.GetTable().SortColCmd(1, true), false), ui.KeyShiftU: ui.NewKeyAction("Sort UpToDate", d.GetTable().SortColCmd(2, true), false), - ui.KeyShiftV: ui.NewKeyAction("Sort Available", d.GetTable().SortColCmd(3, true), false), + ui.KeyShiftL: ui.NewKeyAction("Sort Available", d.GetTable().SortColCmd(3, true), false), }) } diff --git a/internal/view/dp_test.go b/internal/view/dp_test.go index 18e94546..d69fa571 100644 --- a/internal/view/dp_test.go +++ b/internal/view/dp_test.go @@ -13,5 +13,5 @@ func TestDeploy(t *testing.T) { assert.Nil(t, v.Init(makeCtx())) assert.Equal(t, "Deployments", v.Name()) - assert.Equal(t, 11, len(v.Hints())) + assert.Equal(t, 12, len(v.Hints())) } diff --git a/internal/view/ds.go b/internal/view/ds.go index 77c24414..d9f317d3 100644 --- a/internal/view/ds.go +++ b/internal/view/ds.go @@ -34,7 +34,7 @@ func (d *DaemonSet) bindKeys(aa ui.KeyActions) { ui.KeyShiftC: ui.NewKeyAction("Sort Current", d.GetTable().SortColCmd(2, true), false), ui.KeyShiftR: ui.NewKeyAction("Sort Ready", d.GetTable().SortColCmd(3, true), false), ui.KeyShiftU: ui.NewKeyAction("Sort UpToDate", d.GetTable().SortColCmd(4, true), false), - ui.KeyShiftV: ui.NewKeyAction("Sort Available", d.GetTable().SortColCmd(5, true), false), + ui.KeyShiftL: ui.NewKeyAction("Sort Available", d.GetTable().SortColCmd(5, true), false), }) } diff --git a/internal/view/ds_test.go b/internal/view/ds_test.go index 34cfe258..43d45f8b 100644 --- a/internal/view/ds_test.go +++ b/internal/view/ds_test.go @@ -13,5 +13,5 @@ func TestDaemonSet(t *testing.T) { assert.Nil(t, v.Init(makeCtx())) assert.Equal(t, "DaemonSets", v.Name()) - assert.Equal(t, 12, len(v.Hints())) + assert.Equal(t, 13, len(v.Hints())) } diff --git a/internal/view/env.go b/internal/view/env.go index 7ddcb4ba..a2bb9f75 100644 --- a/internal/view/env.go +++ b/internal/view/env.go @@ -13,7 +13,7 @@ import ( type K9sEnv map[string]string // EnvRX match $XXX custom arg. -var envRX = regexp.MustCompile(`\$([\w]+)(\d*)`) +var envRX = regexp.MustCompile(`\$(\!?[\w]+)(\d*)`) func (e K9sEnv) envFor(ns, args string) (string, error) { envs := envRX.FindStringSubmatch(args) @@ -41,10 +41,23 @@ func (e K9sEnv) envFor(ns, args string) (string, error) { } func (e K9sEnv) subOut(args, q string) (string, error) { + var reverse bool + if q[0] == '!' { + reverse = true + q = q[1:] + } env, ok := e[strings.ToUpper(q)] if !ok { return "", fmt.Errorf("no env vars exists for argument %q using key %q", args, q) } + if b, err := strconv.ParseBool(env); err == nil { + if reverse { + env = fmt.Sprintf("%t", !b) + } else { + env = fmt.Sprintf("%t", b) + } + } + return envRX.ReplaceAllString(args, env), nil } diff --git a/internal/view/event.go b/internal/view/event.go index 58ffa82b..a0f6f8f5 100644 --- a/internal/view/event.go +++ b/internal/view/event.go @@ -19,10 +19,17 @@ func NewEvent(gvr client.GVR) ResourceViewer { } e.GetTable().SetColorerFn(render.Event{}.ColorerFunc()) e.SetBindKeysFn(e.bindKeys) + e.GetTable().SetSortCol(7, 0, true) return &e } func (e *Event) bindKeys(aa ui.KeyActions) { aa.Delete(tcell.KeyCtrlD, ui.KeyE) + aa.Add(ui.KeyActions{ + ui.KeyShiftY: ui.NewKeyAction("Sort Type", e.GetTable().SortColCmd(1, true), false), + ui.KeyShiftR: ui.NewKeyAction("Sort Reason", e.GetTable().SortColCmd(2, true), false), + ui.KeyShiftE: ui.NewKeyAction("Sort Source", e.GetTable().SortColCmd(3, true), false), + ui.KeyShiftC: ui.NewKeyAction("Sort Count", e.GetTable().SortColCmd(4, true), false), + }) } diff --git a/internal/view/exec.go b/internal/view/exec.go index ff905ca7..e302231a 100644 --- a/internal/view/exec.go +++ b/internal/view/exec.go @@ -25,29 +25,44 @@ type shellOpts struct { args []string } -func runK(app *App, opts shellOpts) bool { +func runK(a *App, opts shellOpts) bool { bin, err := exec.LookPath("kubectl") if err != nil { log.Error().Msgf("Unable to find kubectl command in path %v", err) return false } + var args []string + if u, err := a.Conn().Config().CurrentUserName(); err == nil { + args = append(args, "--as", u) + } + if g, err := a.Conn().Config().CurrentGroupNames(); err == nil { + args = append(args, "--as-group", strings.Join(g, ",")) + } + args = append(args, "--context", a.Config.K9s.CurrentContext) + if cfg := a.Conn().Config().Flags().KubeConfig; cfg != nil && *cfg != "" { + args = append(args, "--kubeconfig", *cfg) + } + if len(args) > 0 { + opts.args = append(opts.args, args...) + } + opts.binary, opts.background = bin, false - return run(app, opts) + return run(a, opts) } -func run(app *App, opts shellOpts) bool { - app.Halt() - defer app.Resume() +func run(a *App, opts shellOpts) bool { + a.Halt() + defer a.Resume() - return app.Suspend(func() { + return a.Suspend(func() { if err := execute(opts); err != nil { - app.Flash().Errf("Command exited: %v", err) + a.Flash().Errf("Command exited: %v", err) } }) } -func edit(app *App, opts shellOpts) bool { +func edit(a *App, opts shellOpts) bool { bin, err := exec.LookPath(os.Getenv("EDITOR")) if err != nil { log.Error().Msgf("Unable to find editor command in path %v", err) @@ -55,7 +70,7 @@ func edit(app *App, opts shellOpts) bool { } opts.binary, opts.background = bin, false - return run(app, opts) + return run(a, opts) } func execute(opts shellOpts) error { @@ -85,7 +100,6 @@ func execute(opts shellOpts) error { err = cmd.Start() } else { cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr - _, _ = cmd.Stdout.Write([]byte(opts.banner)) err = cmd.Run() } diff --git a/internal/view/help.go b/internal/view/help.go index 0758d4ca..959f4580 100644 --- a/internal/view/help.go +++ b/internal/view/help.go @@ -235,7 +235,7 @@ func (h *Help) showGeneral() model.MenuHints { Description: "Clear command", }, { - Mnemonic: "t", + Mnemonic: "Ctrl-e", Description: "Toggle Header", }, { diff --git a/internal/view/help_test.go b/internal/view/help_test.go index 443633c3..5f538ad2 100644 --- a/internal/view/help_test.go +++ b/internal/view/help_test.go @@ -21,7 +21,7 @@ func TestHelp(t *testing.T) { v := view.NewHelp() assert.Nil(t, v.Init(ctx)) - assert.Equal(t, 20, v.GetRowCount()) + assert.Equal(t, 22, v.GetRowCount()) assert.Equal(t, 8, v.GetColumnCount()) assert.Equal(t, "", strings.TrimSpace(v.GetCell(1, 0).Text)) assert.Equal(t, "Kill", strings.TrimSpace(v.GetCell(1, 1).Text)) diff --git a/internal/view/log.go b/internal/view/log.go index 7e0e715b..701f8502 100644 --- a/internal/view/log.go +++ b/internal/view/log.go @@ -76,7 +76,7 @@ func (l *Log) Init(ctx context.Context) (err error) { l.logs.SetWrap(false) l.logs.SetMaxBuffer(l.app.Config.K9s.LogBufferSize) - l.ansiWriter = tview.ANSIWriter(l.logs, l.app.Styles.Views().Log.FgColor, l.app.Styles.Views().Log.BgColor) + l.ansiWriter = tview.ANSIWriter(l.logs, l.app.Styles.Views().Log.FgColor.String(), l.app.Styles.Views().Log.BgColor.String()) l.AddItem(l.logs, 0, 1, true) l.bindKeys() l.logs.SetInputCapture(l.keyboard) @@ -127,9 +127,9 @@ func (l *Log) BufferActive(state bool, k ui.BufferKind) { // StylesChanged reports skin changes. func (l *Log) StylesChanged(s *config.Styles) { - l.SetBackgroundColor(config.AsColor(s.Views().Log.BgColor)) - l.logs.SetTextColor(config.AsColor(s.Views().Log.FgColor)) - l.logs.SetBackgroundColor(config.AsColor(s.Views().Log.BgColor)) + l.SetBackgroundColor(s.Views().Log.BgColor.Color()) + l.logs.SetTextColor(s.Views().Log.FgColor.Color()) + l.logs.SetBackgroundColor(s.Views().Log.BgColor.Color()) } // GetModel returns the log model. diff --git a/internal/view/log_indicator.go b/internal/view/log_indicator.go index 11634ad9..31a20ec6 100644 --- a/internal/view/log_indicator.go +++ b/internal/view/log_indicator.go @@ -26,7 +26,7 @@ func NewLogIndicator(cfg *config.Config, styles *config.Styles) *LogIndicator { scrollStatus: 1, fullScreen: cfg.K9s.FullScreenLogs, } - l.SetBackgroundColor(config.AsColor(styles.Views().Log.BgColor)) + l.SetBackgroundColor(styles.Views().Log.BgColor.Color()) l.SetTextAlign(tview.AlignRight) l.SetDynamicColors(true) diff --git a/internal/view/ns.go b/internal/view/ns.go index adf567c0..1ad2a585 100644 --- a/internal/view/ns.go +++ b/internal/view/ns.go @@ -1,6 +1,8 @@ package view import ( + "time" + "github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/config" "github.com/derailed/k9s/internal/render" @@ -76,12 +78,13 @@ func (n *Namespace) decorate(data render.TableData) render.TableData { // checks if all ns is in the list if not add it. if _, ok := data.RowEvents.FindIndex(client.NamespaceAll); !ok { + log.Debug().Msg("YO!!") data.RowEvents = append(data.RowEvents, render.RowEvent{ Kind: render.EventUnchanged, Row: render.Row{ ID: client.NamespaceAll, - Fields: render.Fields{client.NamespaceAll, "Active", "0"}, + Fields: render.Fields{client.NamespaceAll, "Active", "", "", time.Now().String()}, }, }, ) diff --git a/internal/view/ns_test.go b/internal/view/ns_test.go index 6a98ac0a..a78b829a 100644 --- a/internal/view/ns_test.go +++ b/internal/view/ns_test.go @@ -13,5 +13,5 @@ func TestNSCleanser(t *testing.T) { assert.Nil(t, ns.Init(makeCtx())) assert.Equal(t, "Namespaces", ns.Name()) - assert.Equal(t, 4, len(ns.Hints())) + assert.Equal(t, 6, len(ns.Hints())) } diff --git a/internal/view/ofaas.go b/internal/view/ofaas.go index 00c93a2c..f2fa81a8 100644 --- a/internal/view/ofaas.go +++ b/internal/view/ofaas.go @@ -28,7 +28,7 @@ func (o *OpenFaas) bindKeys(aa ui.KeyActions) { ui.KeyShiftS: ui.NewKeyAction("Sort Status", o.GetTable().SortColCmd(2, true), false), ui.KeyShiftI: ui.NewKeyAction("Sort Invocations", o.GetTable().SortColCmd(4, false), false), ui.KeyShiftR: ui.NewKeyAction("Sort Replicas", o.GetTable().SortColCmd(5, false), false), - ui.KeyShiftV: ui.NewKeyAction("Sort Available", o.GetTable().SortColCmd(6, false), false), + ui.KeyShiftL: ui.NewKeyAction("Sort Available", o.GetTable().SortColCmd(6, false), false), }) } diff --git a/internal/view/pf_dialog.go b/internal/view/pf_dialog.go index 6b7e3b15..a7b0e4b8 100644 --- a/internal/view/pf_dialog.go +++ b/internal/view/pf_dialog.go @@ -5,7 +5,6 @@ import ( "strings" "github.com/derailed/k9s/internal/client" - "github.com/derailed/k9s/internal/config" "github.com/derailed/k9s/internal/ui" "github.com/derailed/tview" ) @@ -24,23 +23,13 @@ func ShowPortForwards(v ResourceViewer, path string, ports []string, okFn PortFo f.SetButtonsAlign(tview.AlignCenter). SetButtonBackgroundColor(styles.BgColor()). SetButtonTextColor(styles.FgColor()). - SetLabelColor(config.AsColor(styles.K9s.Info.FgColor)). - SetFieldTextColor(config.AsColor(styles.K9s.Info.SectionColor)) + SetLabelColor(styles.K9s.Info.FgColor.Color()). + SetFieldTextColor(styles.K9s.Info.SectionColor.Color()) - p1, p2, address := ports[0], ports[0], "localhost" - f.AddDropDown("Container Ports", ports, 0, func(sel string, _ int) { - p1, p2 = sel, extractPort(sel) + p1, p2, address := ports[0], extractPort(ports[0]), "localhost" + f.AddInputField("Container Port:", p1, 20, nil, func(p string) { + p1 = p }) - - dropD, ok := f.GetFormItem(0).(*tview.DropDown) - if ok { - dropD.SetFieldBackgroundColor(styles.BgColor()) - list := dropD.GetList() - list.SetMainTextColor(styles.FgColor()) - list.SetSelectedTextColor(styles.FgColor()) - list.SetSelectedBackgroundColor(config.AsColor(styles.Table().CursorColor)) - list.SetBackgroundColor(styles.BgColor() + 100) - } f.AddInputField("Local Port:", p2, 20, nil, func(p string) { p2 = p }) @@ -63,6 +52,7 @@ func ShowPortForwards(v ResourceViewer, path string, ports []string, okFn PortFo }) modal := tview.NewModalForm(fmt.Sprintf("", path), f) + modal.SetText("Exposed Ports: " + strings.Join(ports, ",")) modal.SetDoneFunc(func(_ int, b string) { DismissPortForwards(pages) }) diff --git a/internal/view/pf_dialog_test.go b/internal/view/pf_dialog_test.go index f4154494..6b654c55 100644 --- a/internal/view/pf_dialog_test.go +++ b/internal/view/pf_dialog_test.go @@ -11,6 +11,9 @@ func TestExtractPort(t *testing.T) { port, e string }{ "full": { + "co/fred:8000", "8000", + }, + "named": { "fred:8000", "8000", }, "port": { @@ -28,3 +31,26 @@ func TestExtractPort(t *testing.T) { }) } } + +func TestExtractContainer(t *testing.T) { + uu := map[string]struct { + port, e string + }{ + "full": { + "co/port:8000", "co", + }, + "unamed": { + "co/:8000", "co", + }, + "protocol": { + "co/dns:53╱UDP", "co", + }, + } + + for k := range uu { + u := uu[k] + t.Run(k, func(t *testing.T) { + assert.Equal(t, u.e, extractContainer(u.port)) + }) + } +} diff --git a/internal/view/pod.go b/internal/view/pod.go index dd90fcaf..0ba9937a 100644 --- a/internal/view/pod.go +++ b/internal/view/pod.go @@ -53,14 +53,14 @@ func (p *Pod) bindKeys(aa ui.KeyActions) { aa.Add(ui.KeyActions{ ui.KeyShiftR: ui.NewKeyAction("Sort Ready", p.GetTable().SortColCmd(1, true), false), - ui.KeyShiftS: ui.NewKeyAction("Sort Status", p.GetTable().SortColCmd(2, true), false), - ui.KeyShiftT: ui.NewKeyAction("Sort Restart", p.GetTable().SortColCmd(3, false), false), + ui.KeyShiftT: ui.NewKeyAction("Sort Restart", p.GetTable().SortColCmd(2, false), false), + ui.KeyShiftS: ui.NewKeyAction("Sort Status", p.GetTable().SortColCmd(3, true), false), ui.KeyShiftC: ui.NewKeyAction("Sort CPU", p.GetTable().SortColCmd(4, false), false), ui.KeyShiftM: ui.NewKeyAction("Sort MEM", p.GetTable().SortColCmd(5, false), false), ui.KeyShiftX: ui.NewKeyAction("Sort %CPU (REQ)", p.GetTable().SortColCmd(6, false), false), ui.KeyShiftZ: ui.NewKeyAction("Sort %MEM (REQ)", p.GetTable().SortColCmd(7, false), false), tcell.KeyCtrlX: ui.NewKeyAction("Sort %CPU (LIM)", p.GetTable().SortColCmd(8, false), false), - tcell.KeyCtrlZ: ui.NewKeyAction("Sort %MEM (LIM)", p.GetTable().SortColCmd(9, false), false), + tcell.KeyCtrlQ: ui.NewKeyAction("Sort %MEM (LIM)", p.GetTable().SortColCmd(9, false), false), ui.KeyShiftI: ui.NewKeyAction("Sort IP", p.GetTable().SortColCmd(10, true), false), ui.KeyShiftO: ui.NewKeyAction("Sort Node", p.GetTable().SortColCmd(11, true), false), }) diff --git a/internal/view/pod_test.go b/internal/view/pod_test.go index 8588155c..dd5c43bb 100644 --- a/internal/view/pod_test.go +++ b/internal/view/pod_test.go @@ -16,7 +16,7 @@ func TestPodNew(t *testing.T) { assert.Nil(t, po.Init(makeCtx())) assert.Equal(t, "Pods", po.Name()) - assert.Equal(t, 19, len(po.Hints())) + assert.Equal(t, 21, len(po.Hints())) } // Helpers... diff --git a/internal/view/port_forward.go b/internal/view/port_forward.go index 3901ef75..89ecc88a 100644 --- a/internal/view/port_forward.go +++ b/internal/view/port_forward.go @@ -8,6 +8,7 @@ import ( "github.com/derailed/k9s/internal" "github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/dao" + "github.com/derailed/k9s/internal/model" "github.com/derailed/k9s/internal/perf" "github.com/derailed/k9s/internal/render" "github.com/derailed/k9s/internal/ui" @@ -64,7 +65,7 @@ func (p *PortForward) showBenchCmd(evt *tcell.EventKey) *tcell.EventKey { func (p *PortForward) toggleBenchCmd(evt *tcell.EventKey) *tcell.EventKey { if p.bench != nil { - p.App().Status(ui.FlashErr, "Benchmark Canceled!") + p.App().Status(model.FlashErr, "Benchmark Canceled!") p.bench.Cancel() p.App().ClearStatus(true) return nil @@ -87,7 +88,7 @@ func (p *PortForward) toggleBenchCmd(evt *tcell.EventKey) *tcell.EventKey { return nil } - p.App().Status(ui.FlashWarn, "Benchmark in progress...") + p.App().Status(model.FlashWarn, "Benchmark in progress...") go p.runBenchmark() return nil @@ -100,9 +101,9 @@ func (p *PortForward) runBenchmark() { log.Debug().Msg("Bench Completed!") p.App().QueueUpdate(func() { if p.bench.Canceled() { - p.App().Status(ui.FlashInfo, "Benchmark canceled") + p.App().Status(model.FlashInfo, "Benchmark canceled") } else { - p.App().Status(ui.FlashInfo, "Benchmark Completed!") + p.App().Status(model.FlashInfo, "Benchmark Completed!") p.bench.Cancel() } p.bench = nil diff --git a/internal/view/port_forward_test.go b/internal/view/port_forward_test.go index fabe07b8..eb21f9f4 100644 --- a/internal/view/port_forward_test.go +++ b/internal/view/port_forward_test.go @@ -13,5 +13,5 @@ func TestPortForwardNew(t *testing.T) { assert.Nil(t, pf.Init(makeCtx())) assert.Equal(t, "PortForwards", pf.Name()) - assert.Equal(t, 7, len(pf.Hints())) + assert.Equal(t, 9, len(pf.Hints())) } diff --git a/internal/view/pulse.go b/internal/view/pulse.go new file mode 100644 index 00000000..fcebef6a --- /dev/null +++ b/internal/view/pulse.go @@ -0,0 +1,362 @@ +package view + +import ( + "context" + "fmt" + "image" + "strings" + + "github.com/derailed/k9s/internal" + "github.com/derailed/k9s/internal/client" + "github.com/derailed/k9s/internal/config" + "github.com/derailed/k9s/internal/health" + "github.com/derailed/k9s/internal/model" + "github.com/derailed/k9s/internal/tchart" + "github.com/derailed/k9s/internal/ui" + "github.com/derailed/tview" + "github.com/gdamore/tcell" + "github.com/rs/zerolog/log" +) + +// Grapheable represents a graphic component. +type Grapheable interface { + tview.Primitive + + // ID returns the graph id. + ID() string + + // Add adds a metric + Add(tchart.Metric) + + // SetLegend sets the graph legend + SetLegend(string) + + // SetSeriesColors sets charts series colors. + SetSeriesColors(...tcell.Color) + + // GetSeriesColorNames returns the series color names. + GetSeriesColorNames() []string + + // SetBackgroundColor sets chart bg color. + SetBackgroundColor(tcell.Color) + + // IsDial returns true if chart is a dial + IsDial() bool +} + +const pulseTitle = "Pulses" + +var _ ResourceViewer = (*Pulse)(nil) + +// Pulse represents a command health view. +type Pulse struct { + *tview.Grid + + app *App + gvr client.GVR + model *model.Pulse + cancelFn context.CancelFunc + actions ui.KeyActions + charts []Grapheable +} + +// NewPulse returns a new alias view. +func NewPulse(gvr client.GVR) ResourceViewer { + return &Pulse{ + Grid: tview.NewGrid(), + model: model.NewPulse(gvr.String()), + actions: make(ui.KeyActions), + } +} + +// Init initializes the view. +func (p *Pulse) Init(ctx context.Context) error { + p.SetBorder(true) + p.SetTitle(fmt.Sprintf(" %s ", pulseTitle)) + p.SetGap(1, 1) + p.SetBorderPadding(0, 0, 1, 1) + var err error + if p.app, err = extractApp(ctx); err != nil { + return err + } + + p.charts = []Grapheable{ + p.makeGA(image.Point{X: 0, Y: 0}, image.Point{X: 4, Y: 2}, "apps/v1/deployments"), + p.makeGA(image.Point{X: 0, Y: 2}, image.Point{X: 4, Y: 2}, "apps/v1/replicasets"), + p.makeGA(image.Point{X: 0, Y: 4}, image.Point{X: 4, Y: 2}, "apps/v1/statefulsets"), + p.makeGA(image.Point{X: 0, Y: 6}, image.Point{X: 4, Y: 2}, "apps/v1/daemonsets"), + p.makeSP(image.Point{X: 4, Y: 0}, image.Point{X: 3, Y: 4}, "v1/pods"), + p.makeSP(image.Point{X: 4, Y: 4}, image.Point{X: 3, Y: 4}, "v1/events"), + p.makeSP(image.Point{X: 7, Y: 0}, image.Point{X: 3, Y: 4}, "batch/v1/jobs"), + p.makeSP(image.Point{X: 7, Y: 4}, image.Point{X: 3, Y: 4}, "v1/persistentvolumes"), + } + if p.app.Conn().HasMetrics() { + p.charts = append(p.charts, + p.makeSP(image.Point{X: 10, Y: 0}, image.Point{X: 2, Y: 4}, "cpu"), + p.makeSP(image.Point{X: 10, Y: 4}, image.Point{X: 2, Y: 4}, "mem"), + ) + } + p.bindKeys() + p.model.AddListener(p) + p.app.SetFocus(p.charts[0]) + p.app.Styles.AddListener(p) + + return nil +} + +// StylesChanged notifies the skin changed. +func (p *Pulse) StylesChanged(s *config.Styles) { + p.SetBackgroundColor(s.Charts().BgColor.Color()) + for _, c := range p.charts { + if c.IsDial() { + c.SetBackgroundColor(s.Charts().DialBgColor.Color()) + c.SetSeriesColors(s.Charts().DefaultDialColors.Colors()...) + } else { + c.SetBackgroundColor(s.Charts().ChartBgColor.Color()) + c.SetSeriesColors(s.Charts().DefaultChartColors.Colors()...) + } + if ss, ok := s.Charts().ResourceColors[c.ID()]; ok { + c.SetSeriesColors(ss.Colors()...) + } + } + p.app.Draw() +} + +// PulseChanged notifies the model data changed. +func (p *Pulse) PulseChanged(c *health.Check) { + index, ok := findIndexGVR(p.charts, c.GVR) + if !ok { + return + } + + v, ok := p.GetItem(index).Item.(Grapheable) + if !ok { + return + } + gvr := client.NewGVR(c.GVR) + switch c.GVR { + case "cpu": + v.SetLegend(fmt.Sprintf(" %s - %dm", strings.Title(gvr.R()), c.Tally(health.OK))) + case "mem": + v.SetLegend(fmt.Sprintf(" %s - %dMi", strings.Title(gvr.R()), c.Tally(health.OK))) + default: + nn := v.GetSeriesColorNames() + v.SetLegend(fmt.Sprintf(" %s(%d:[%s::]%d:[%s::b]%d[-::])", + strings.Title(gvr.R()), + c.Tally(health.Corpus), + nn[0], + c.Tally(health.OK), + nn[1], + c.Tally(health.Toast), + ), + ) + } + v.Add(tchart.Metric{OK: c.Tally(health.OK), Fault: c.Tally(health.Toast)}) +} + +// PulseLoadFailed notifies the load failed. +func (p *Pulse) PulseFailed(err error) { + p.app.Flash().Err(err) +} + +func (p *Pulse) bindKeys() { + p.actions.Add(ui.KeyActions{ + tcell.KeyEnter: ui.NewKeyAction("Goto", p.enterCmd, true), + tcell.KeyTab: ui.NewKeyAction("Next", p.nextFocusCmd(1), true), + tcell.KeyBacktab: ui.NewKeyAction("Prev", p.nextFocusCmd(-1), true), + }) + + for i, v := range p.charts { + t := strings.Title(client.NewGVR(v.(Grapheable).ID()).R()) + p.actions[tcell.Key(ui.NumKeys[i])] = ui.NewKeyAction(t, p.sparkFocusCmd(i), true) + } +} + +func (p *Pulse) keyboard(evt *tcell.EventKey) *tcell.EventKey { + log.Debug().Msgf("Pulse GOT EVENT %#v", evt) + key := evt.Key() + if key == tcell.KeyRune { + key = tcell.Key(evt.Rune()) + } + + if a, ok := p.actions[key]; ok { + return a.Action(evt) + } + + return evt +} + +func (p *Pulse) defaultContext() context.Context { + return context.WithValue(context.Background(), internal.KeyFactory, p.app.factory) +} + +// Start initializes resource watch loop. +func (p *Pulse) Start() { + p.Stop() + + ctx := p.defaultContext() + ctx, p.cancelFn = context.WithCancel(ctx) + p.model.Watch(ctx) +} + +// Stop terminates watch loop. +func (p *Pulse) Stop() { + if p.cancelFn == nil { + return + } + p.cancelFn() + p.cancelFn = nil +} + +// Refresh updates the view +func (p *Pulse) Refresh() { + // p.update(p.model.Peek()) +} + +// GVR returns a resource descriptor. +func (p *Pulse) GVR() string { + return p.gvr.String() +} + +// Name returns the component name. +func (p *Pulse) Name() string { + return pulseTitle +} + +// App returns the current app handle. +func (p *Pulse) App() *App { + return p.app +} + +// SetInstance sets specific resource instance. +func (p *Pulse) SetInstance(string) {} + +// SetEnvFn sets the custom environment function. +func (p *Pulse) SetEnvFn(EnvFunc) {} + +// SetBindKeysFn sets up extra key bindings. +func (p *Pulse) SetBindKeysFn(BindKeysFunc) {} + +// SetContextFn sets custom context. +func (p *Pulse) SetContextFn(ContextFunc) {} + +// GetTable return the view table if any. +func (p *Pulse) GetTable() *Table { + return nil +} + +// Actions returns active menu bindings. +func (p *Pulse) Actions() ui.KeyActions { + return p.actions +} + +// Hints returns the view hints. +func (p *Pulse) Hints() model.MenuHints { + return p.actions.Hints() +} + +// ExtraHints returns additional hints. +func (p *Pulse) ExtraHints() map[string]string { + return nil +} + +func (p *Pulse) sparkFocusCmd(i int) func(evt *tcell.EventKey) *tcell.EventKey { + return func(evt *tcell.EventKey) *tcell.EventKey { + p.app.SetFocus(p.charts[i]) + return nil + } +} + +func (p *Pulse) enterCmd(evt *tcell.EventKey) *tcell.EventKey { + v := p.App().GetFocus() + s, ok := v.(Grapheable) + if !ok { + return nil + } + log.Debug().Msgf("Selected %s", s.ID()) + gvr := client.NewGVR(s.ID()) + if err := p.App().gotoResource(gvr.R(), false); err != nil { + p.App().Flash().Err(err) + } + + return nil +} + +func (p *Pulse) nextFocusCmd(direction int) func(evt *tcell.EventKey) *tcell.EventKey { + return func(evt *tcell.EventKey) *tcell.EventKey { + v := p.app.GetFocus() + index := findIndex(p.charts, v) + p.GetItem(index).Focus = false + p.GetItem(index).Item.Blur() + i, v := nextFocus(p.charts, index+direction) + p.GetItem(i).Focus = true + p.app.SetFocus(v) + + return nil + } +} + +func (p *Pulse) makeSP(loc image.Point, span image.Point, gvr string) *tchart.SparkLine { + s := tchart.NewSparkLine(gvr) + s.SetBackgroundColor(p.app.Styles.Charts().BgColor.Color()) + s.SetBorderPadding(0, 1, 0, 1) + if cc, ok := p.app.Styles.Charts().ResourceColors[gvr]; ok { + s.SetSeriesColors(cc.Colors()...) + } else { + s.SetSeriesColors(p.app.Styles.Charts().DefaultChartColors.Colors()...) + } + s.SetLegend(fmt.Sprintf(" %s ", strings.Title(client.NewGVR(gvr).R()))) + s.SetInputCapture(p.keyboard) + p.AddItem(s, loc.X, loc.Y, span.X, span.Y, 0, 0, true) + + return s +} + +func (p *Pulse) makeGA(loc image.Point, span image.Point, gvr string) *tchart.Gauge { + g := tchart.NewGauge(gvr) + g.SetBackgroundColor(p.app.Styles.Charts().BgColor.Color()) + g.SetBorderPadding(0, 1, 0, 1) + if cc, ok := p.app.Styles.Charts().ResourceColors[gvr]; ok { + g.SetSeriesColors(cc.Colors()...) + } else { + g.SetSeriesColors(p.app.Styles.Charts().DefaultDialColors.Colors()...) + } + g.SetLegend(fmt.Sprintf(" %s ", strings.Title(client.NewGVR(gvr).R()))) + g.SetInputCapture(p.keyboard) + p.AddItem(g, loc.X, loc.Y, span.X, span.Y, 0, 0, true) + + return g +} + +// ---------------------------------------------------------------------------- +// Helpers + +func nextFocus(pp []Grapheable, index int) (int, tview.Primitive) { + if index >= len(pp) { + return 0, pp[0] + } + + if index < 0 { + return len(pp) - 1, pp[len(pp)-1] + } + + return index, pp[index] +} + +func findIndex(pp []Grapheable, p tview.Primitive) int { + for i, v := range pp { + if v == p { + return i + } + } + return 0 +} + +func findIndexGVR(pp []Grapheable, gvr string) (int, bool) { + for i, v := range pp { + if v.(Grapheable).ID() == gvr { + return i, true + } + } + return 0, false +} diff --git a/internal/view/rbac_test.go b/internal/view/rbac_test.go index 63cfad8b..2c0972c8 100644 --- a/internal/view/rbac_test.go +++ b/internal/view/rbac_test.go @@ -13,5 +13,5 @@ func TestRbacNew(t *testing.T) { assert.Nil(t, v.Init(makeCtx())) assert.Equal(t, "Rbac", v.Name()) - assert.Equal(t, 3, len(v.Hints())) + assert.Equal(t, 5, len(v.Hints())) } diff --git a/internal/view/registrar.go b/internal/view/registrar.go index 9631348d..417f79e8 100644 --- a/internal/view/registrar.go +++ b/internal/view/registrar.go @@ -69,6 +69,9 @@ func miscViewers(vv MetaViewers) { vv[client.NewGVR("aliases")] = MetaViewer{ viewerFn: NewAlias, } + vv[client.NewGVR("pulses")] = MetaViewer{ + viewerFn: NewPulse, + } } func appsViewers(vv MetaViewers) { diff --git a/internal/view/screen_dump_test.go b/internal/view/screen_dump_test.go index 59b1756f..0e191f1b 100644 --- a/internal/view/screen_dump_test.go +++ b/internal/view/screen_dump_test.go @@ -13,5 +13,5 @@ func TestScreenDumpNew(t *testing.T) { assert.Nil(t, po.Init(makeCtx())) assert.Equal(t, "ScreenDumps", po.Name()) - assert.Equal(t, 3, len(po.Hints())) + assert.Equal(t, 5, len(po.Hints())) } diff --git a/internal/view/secret_test.go b/internal/view/secret_test.go index 8823ab3c..d75cd10f 100644 --- a/internal/view/secret_test.go +++ b/internal/view/secret_test.go @@ -13,5 +13,5 @@ func TestSecretNew(t *testing.T) { assert.Nil(t, s.Init(makeCtx())) assert.Equal(t, "Secrets", s.Name()) - assert.Equal(t, 4, len(s.Hints())) + assert.Equal(t, 6, len(s.Hints())) } diff --git a/internal/view/sts_test.go b/internal/view/sts_test.go index 57deed3f..30a5de22 100644 --- a/internal/view/sts_test.go +++ b/internal/view/sts_test.go @@ -13,5 +13,5 @@ func TestStatefulSetNew(t *testing.T) { assert.Nil(t, s.Init(makeCtx())) assert.Equal(t, "StatefulSets", s.Name()) - assert.Equal(t, 9, len(s.Hints())) + assert.Equal(t, 11, len(s.Hints())) } diff --git a/internal/view/svc.go b/internal/view/svc.go index 51711e63..30f95a90 100644 --- a/internal/view/svc.go +++ b/internal/view/svc.go @@ -9,6 +9,7 @@ import ( "github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/config" "github.com/derailed/k9s/internal/dao" + "github.com/derailed/k9s/internal/model" "github.com/derailed/k9s/internal/perf" "github.com/derailed/k9s/internal/ui" "github.com/gdamore/tcell" @@ -85,7 +86,7 @@ func (s *Service) getExternalPort(row int) (string, error) { func (s *Service) toggleBenchCmd(evt *tcell.EventKey) *tcell.EventKey { if s.bench != nil { log.Debug().Msg(">>> Benchmark canceled!!") - s.App().Status(ui.FlashErr, "Benchmark Canceled!") + s.App().Status(model.FlashErr, "Benchmark Canceled!") s.bench.Cancel() s.App().ClearStatus(true) return nil @@ -140,7 +141,7 @@ func (s *Service) runBenchmark(port string, cfg config.BenchConfig) error { return err } - s.App().Status(ui.FlashWarn, "Benchmark in progress...") + s.App().Status(model.FlashWarn, "Benchmark in progress...") log.Debug().Msg("Bench starting...") go s.bench.Run(s.App().Config.K9s.CurrentCluster, s.benchDone) @@ -151,9 +152,9 @@ func (s *Service) benchDone() { log.Debug().Msg("Bench Completed!") s.App().QueueUpdate(func() { if s.bench.Canceled() { - s.App().Status(ui.FlashInfo, "Benchmark canceled") + s.App().Status(model.FlashInfo, "Benchmark canceled") } else { - s.App().Status(ui.FlashInfo, "Benchmark Completed!") + s.App().Status(model.FlashInfo, "Benchmark Completed!") s.bench.Cancel() } s.bench = nil diff --git a/internal/view/svc_test.go b/internal/view/svc_test.go index a9a5bd1c..9bf3756d 100644 --- a/internal/view/svc_test.go +++ b/internal/view/svc_test.go @@ -132,5 +132,5 @@ func TestServiceNew(t *testing.T) { assert.Nil(t, s.Init(makeCtx())) assert.Equal(t, "Services", s.Name()) - assert.Equal(t, 8, len(s.Hints())) + assert.Equal(t, 10, len(s.Hints())) } diff --git a/internal/view/table.go b/internal/view/table.go index faa62541..56641086 100644 --- a/internal/view/table.go +++ b/internal/view/table.go @@ -132,10 +132,24 @@ func (t *Table) bindKeys() { tcell.KeyBackspace: ui.NewSharedKeyAction("Erase", t.eraseCmd, false), tcell.KeyDelete: ui.NewSharedKeyAction("Erase", t.eraseCmd, false), ui.KeyShiftN: ui.NewKeyAction("Sort Name", t.SortColCmd(0, true), false), + tcell.KeyCtrlZ: ui.NewKeyAction("Toggle Faults", t.toggleFaultCmd, false), ui.KeyShiftA: ui.NewKeyAction("Sort Age", t.SortColCmd(-1, true), false), + tcell.KeyCtrlW: ui.NewKeyAction("Show Wide", t.toggleWideCmd, false), }) } +func (t *Table) toggleFaultCmd(evt *tcell.EventKey) *tcell.EventKey { + t.ToggleToast() + + return nil +} + +func (t *Table) toggleWideCmd(evt *tcell.EventKey) *tcell.EventKey { + t.ToggleWide() + + return nil +} + func (t *Table) cpCmd(evt *tcell.EventKey) *tcell.EventKey { path := t.GetSelectedItem() if path == "" { diff --git a/internal/view/table_int_test.go b/internal/view/table_int_test.go index f98700c4..336acadc 100644 --- a/internal/view/table_int_test.go +++ b/internal/view/table_int_test.go @@ -97,6 +97,7 @@ func (t *testTableModel) Peek() render.TableData { return makeTableData func (t *testTableModel) ClusterWide() bool { return false } func (t *testTableModel) GetNamespace() string { return "blee" } func (t *testTableModel) SetNamespace(string) {} +func (t *testTableModel) ToggleToast() {} func (t *testTableModel) AddListener(model.TableListener) {} func (t *testTableModel) Watch(context.Context) {} func (t *testTableModel) Get(context.Context, string) (runtime.Object, error) { diff --git a/internal/view/xray.go b/internal/view/xray.go index 2858233a..38a3c86d 100644 --- a/internal/view/xray.go +++ b/internal/view/xray.go @@ -25,6 +25,8 @@ import ( const xrayTitle = "Xray" +var _ ResourceViewer = (*Xray)(nil) + // Xray represents an xray tree view. type Xray struct { *ui.Tree @@ -37,8 +39,6 @@ type Xray struct { envFn EnvFunc } -var _ ResourceViewer = (*Xray)(nil) - // NewXray returns a new view. func NewXray(gvr client.GVR) ResourceViewer { return &Xray{ @@ -68,10 +68,10 @@ func (x *Xray) Init(ctx context.Context) error { } x.bindKeys() - x.SetBackgroundColor(config.AsColor(x.app.Styles.Xray().BgColor)) - x.SetBorderColor(config.AsColor(x.app.Styles.Xray().FgColor)) - x.SetBorderFocusColor(config.AsColor(x.app.Styles.Frame().Border.FocusColor)) - x.SetGraphicsColor(config.AsColor(x.app.Styles.Xray().GraphicColor)) + x.SetBackgroundColor(x.app.Styles.Xray().BgColor.Color()) + x.SetBorderColor(x.app.Styles.Xray().FgColor.Color()) + x.SetBorderFocusColor(x.app.Styles.Frame().Border.FocusColor.Color()) + x.SetGraphicsColor(x.app.Styles.Xray().GraphicColor.Color()) x.SetTitle(fmt.Sprintf(" %s-%s ", xrayTitle, strings.Title(x.gvr.R()))) x.model.SetRefreshRate(time.Duration(x.app.Config.K9s.GetRefreshRate()) * time.Second) @@ -479,7 +479,7 @@ func (x *Xray) TreeNodeSelected() { x.app.QueueUpdateDraw(func() { n := x.GetCurrentNode() if n != nil { - n.SetColor(config.AsColor(x.app.Styles.Xray().CursorColor)) + n.SetColor(x.app.Styles.Xray().CursorColor.Color()) } }) } @@ -548,7 +548,7 @@ func (x *Xray) hydrate(parent *tview.TreeNode, n *xray.TreeNode) { // SetEnvFn sets the custom environment function. func (x *Xray) SetEnvFn(EnvFunc) {} -// Refresh refresh the view +// Refresh updates the view func (x *Xray) Refresh() { } @@ -704,7 +704,7 @@ func makeTreeNode(node *xray.TreeNode, expanded bool, styles *config.Styles) *tv } n.SetSelectable(true) n.SetExpanded(expanded) - n.SetColor(config.AsColor(styles.Xray().CursorColor)) + n.SetColor(styles.Xray().CursorColor.Color()) n.SetSelectedFunc(func() { n.SetExpanded(!n.IsExpanded()) }) diff --git a/internal/view/yaml.go b/internal/view/yaml.go index 9ab389e9..356568dc 100644 --- a/internal/view/yaml.go +++ b/internal/view/yaml.go @@ -28,14 +28,14 @@ func colorizeYAML(style config.Yaml, raw string) string { // lines := strings.Split(raw, "\n") lines := strings.Split(tview.Escape(raw), "\n") - fullFmt := strings.Replace(yamlFullFmt, "[key", "["+style.KeyColor, 1) - fullFmt = strings.Replace(fullFmt, "[colon", "["+style.ColonColor, 1) - fullFmt = strings.Replace(fullFmt, "[val", "["+style.ValueColor, 1) + fullFmt := strings.Replace(yamlFullFmt, "[key", "["+style.KeyColor.String(), 1) + fullFmt = strings.Replace(fullFmt, "[colon", "["+style.ColonColor.String(), 1) + fullFmt = strings.Replace(fullFmt, "[val", "["+style.ValueColor.String(), 1) - keyFmt := strings.Replace(yamlKeyFmt, "[key", "["+style.KeyColor, 1) - keyFmt = strings.Replace(keyFmt, "[colon", "["+style.ColonColor, 1) + keyFmt := strings.Replace(yamlKeyFmt, "[key", "["+style.KeyColor.String(), 1) + keyFmt = strings.Replace(keyFmt, "[colon", "["+style.ColonColor.String(), 1) - valFmt := strings.Replace(yamlValueFmt, "[val", "["+style.ValueColor, 1) + valFmt := strings.Replace(yamlValueFmt, "[val", "["+style.ValueColor.String(), 1) buff := make([]string, 0, len(lines)) for _, l := range lines { diff --git a/plugins/job_suspend.yml b/plugins/job_suspend.yml index 3d4b4ae7..06f0de45 100644 --- a/plugins/job_suspend.yml +++ b/plugins/job_suspend.yml @@ -11,9 +11,9 @@ plugin: - patch - cronjobs - $NAME - - ns + - -n - $NAMESPACE - --context - $CONTEXT - -p - - '{"spec" : {"suspend" : $COL3 }}' + - '{"spec" : {"suspend" : $!COL3 }}' From 98b07e69614303074329660383725cff055e3080 Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 20 Feb 2020 00:03:32 -0700 Subject: [PATCH 44/58] checkpoint --- .gitignore | 1 + internal/config/styles.go | 6 +- internal/model/pulse.go | 10 +-- .../model/{health_one.go => pulse_health.go} | 18 ++--- internal/tchart/component.go | 2 +- internal/tchart/dot_matrix_test.go | 2 +- internal/tchart/gauge.go | 5 +- internal/tchart/sparkline.go | 71 +++++++++---------- internal/ui/flash.go | 2 +- internal/ui/logo.go | 2 +- internal/view/actions.go | 6 +- internal/view/alias.go | 2 +- internal/view/app.go | 14 ++-- internal/view/cluster_info.go | 1 + internal/view/ns.go | 2 +- internal/view/pf_dialog.go | 16 +++-- internal/view/pf_extender.go | 3 +- internal/view/pulse.go | 16 +++-- internal/view/registrar.go | 2 +- 19 files changed, 92 insertions(+), 89 deletions(-) rename internal/model/{health_one.go => pulse_health.go} (81%) diff --git a/.gitignore b/.gitignore index cd5193e4..81b09721 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ gen.sh *.log *~ faas +demos \ No newline at end of file diff --git a/internal/config/styles.go b/internal/config/styles.go index b45c17a0..e14ecdf4 100644 --- a/internal/config/styles.go +++ b/internal/config/styles.go @@ -210,9 +210,9 @@ func newStyle() Style { func newCharts() Charts { return Charts{ - BgColor: "#111111", - DialBgColor: "#111111", - ChartBgColor: "#111111", + BgColor: "default", + DialBgColor: "default", + ChartBgColor: "default", DefaultDialColors: Colors{Color("palegreen"), Color("orangered")}, DefaultChartColors: Colors{Color("palegreen"), Color("orangered")}, } diff --git a/internal/model/pulse.go b/internal/model/pulse.go index c19c79c4..9db88a0b 100644 --- a/internal/model/pulse.go +++ b/internal/model/pulse.go @@ -13,6 +13,8 @@ import ( "k8s.io/apimachinery/pkg/runtime" ) +const defaultRefreshRate = 5 * time.Second + // PulseListener represents a health model listener. type PulseListener interface { // PulseChanged notifies the model data changed. @@ -29,14 +31,14 @@ type Pulse struct { inUpdate int32 listeners []PulseListener refreshRate time.Duration - health *Health + health *PulseHealth data health.Checks } func NewPulse(gvr string) *Pulse { return &Pulse{ gvr: gvr, - refreshRate: 2 * time.Second, + refreshRate: defaultRefreshRate, } } @@ -48,7 +50,7 @@ func (p *Pulse) Watch(ctx context.Context) { func (p *Pulse) updater(ctx context.Context) { defer log.Debug().Msgf("Pulse canceled -- %q", p.gvr) - rate := initTreeRefreshRate + rate := initRefreshRate for { select { case <-ctx.Done(): @@ -88,7 +90,7 @@ func (p *Pulse) list(ctx context.Context) ([]runtime.Object, error) { return nil, fmt.Errorf("expected Factory in context but got %T", ctx.Value(internal.KeyFactory)) } if p.health == nil { - p.health = NewHealth(f) + p.health = NewPulseHealth(f) } ctx = context.WithValue(ctx, internal.KeyFields, "") ctx = context.WithValue(ctx, internal.KeyWithMetrics, false) diff --git a/internal/model/health_one.go b/internal/model/pulse_health.go similarity index 81% rename from internal/model/health_one.go rename to internal/model/pulse_health.go index 99372c36..12de902d 100644 --- a/internal/model/health_one.go +++ b/internal/model/pulse_health.go @@ -14,19 +14,19 @@ import ( "k8s.io/apimachinery/pkg/runtime" ) -type Health struct { +type PulseHealth struct { factory dao.Factory } -func NewHealth(f dao.Factory) *Health { - return &Health{ +func NewPulseHealth(f dao.Factory) *PulseHealth { + return &PulseHealth{ factory: f, } } -func (h *Health) List(ctx context.Context, ns string) ([]runtime.Object, error) { +func (h *PulseHealth) List(ctx context.Context, ns string) ([]runtime.Object, error) { defer func(t time.Time) { - log.Debug().Msgf("HealthCheck %v", time.Since(t)) + log.Debug().Msgf("PulseHealthCheck %v", time.Since(t)) }(time.Now()) gvrs := []string{ @@ -60,7 +60,7 @@ func (h *Health) List(ctx context.Context, ns string) ([]runtime.Object, error) return hh, nil } -func (h *Health) checkMetrics() (health.Checks, error) { +func (h *PulseHealth) checkMetrics() (health.Checks, error) { dial := client.DialMetrics(h.factory.Client()) nmx, err := dial.FetchNodesMetrics() if err != nil { @@ -81,11 +81,7 @@ func (h *Health) checkMetrics() (health.Checks, error) { return health.Checks{c1, c2}, nil } -func (h *Health) check(ctx context.Context, ns, gvr string) (*health.Check, error) { - defer func(t time.Time) { - log.Debug().Msgf(" CHECK %s - %v", gvr, time.Since(t)) - }(time.Now()) - +func (h *PulseHealth) check(ctx context.Context, ns, gvr string) (*health.Check, error) { meta, ok := Registry[gvr] if !ok { return nil, fmt.Errorf("No meta for %q", gvr) diff --git a/internal/tchart/component.go b/internal/tchart/component.go index 64e45757..42733082 100644 --- a/internal/tchart/component.go +++ b/internal/tchart/component.go @@ -31,7 +31,7 @@ func NewComponent(id string) *Component { return &Component{ Box: tview.NewBox(), id: id, - noColor: tcell.ColorBlack, + noColor: tcell.ColorDefault, seriesColors: []tcell.Color{tview.Styles.PrimaryTextColor, tview.Styles.FocusColor}, dimmed: tcell.StyleDefault.Background(tview.Styles.PrimitiveBackgroundColor).Foreground(tcell.ColorGray).Dim(true), } diff --git a/internal/tchart/dot_matrix_test.go b/internal/tchart/dot_matrix_test.go index 8f032e7d..e3e8e122 100644 --- a/internal/tchart/dot_matrix_test.go +++ b/internal/tchart/dot_matrix_test.go @@ -50,7 +50,7 @@ func TestDial(t *testing.T) { // Helpers... -const hChar, vChar = '⠶', '⠿' +const hChar, vChar = '▤', '▥' var numbers = []tchart.Matrix{ [][]rune{ diff --git a/internal/tchart/gauge.go b/internal/tchart/gauge.go index 87fa9ce4..b40fa546 100644 --- a/internal/tchart/gauge.go +++ b/internal/tchart/gauge.go @@ -56,6 +56,9 @@ func (g *Gauge) drawNum(sc tcell.Screen, ok bool, o image.Point, n int, dn delta } dm, sig := NewDotMatrix(5, 3), n == 0 + if n == 0 { + style = g.dimmed + } for i := 0; i < len(ns); i++ { if ns[i] == '0' && !sig { g.drawDial(sc, dm.Print(int(ns[i]-48)), o, g.dimmed) @@ -102,7 +105,7 @@ func (g *Gauge) Draw(sc tcell.Screen) { if g.HasFocus() { legend = "[:aqua]" + g.legend + "[::]" } - tview.Print(sc, legend, rect.Min.X, rect.Max.Y-1, rect.Dx(), tview.AlignCenter, tcell.ColorWhite) + tview.Print(sc, legend, rect.Min.X, rect.Max.Y, rect.Dx(), tview.AlignCenter, tcell.ColorWhite) } } diff --git a/internal/tchart/sparkline.go b/internal/tchart/sparkline.go index e4031892..690578a0 100644 --- a/internal/tchart/sparkline.go +++ b/internal/tchart/sparkline.go @@ -40,8 +40,7 @@ func (m Metric) Sum() int { type SparkLine struct { *Component - data []Metric - lastWidth int + data []Metric } // NewSparkLine returns a new graph. @@ -75,24 +74,24 @@ func (s *SparkLine) Draw(screen tcell.Screen) { } rect := s.asRect() - s.lastWidth = rect.Dx() s.cutSet(rect.Dx()) max := s.computeMax() - cX := rect.Min.X + 1 - if len(s.data) < rect.Dx() { - cX = rect.Max.X - len(s.data) + cX, idx := rect.Min.X+1, 0 + if len(s.data)*2 < rect.Dx() { + cX = rect.Max.X - len(s.data)*2 + } else { + idx = len(s.data) - rect.Dx()/2 } scale := float64(len(sparks)) * float64((rect.Dy() - pad)) / float64(max) - c1, c2 := s.colorForSeries() - for _, d := range s.data { + for _, d := range s.data[idx:] { b := toBlocks(d, scale) cY := rect.Max.Y - pad - cY = s.drawBlock(screen, cX, cY, b.oks, c1) + s.drawBlock(screen, cX, cY, b.oks, c1) s.drawBlock(screen, cX, cY, b.errs, c2) - cX++ + cX += 2 } if rect.Dx() > 0 && rect.Dy() > 0 && s.legend != "" { @@ -100,11 +99,11 @@ func (s *SparkLine) Draw(screen tcell.Screen) { if s.HasFocus() { legend = "[:aqua:]" + s.legend + "[::]" } - tview.Print(screen, legend, rect.Min.X, rect.Max.Y-1, rect.Dx(), tview.AlignCenter, tcell.ColorWhite) + tview.Print(screen, legend, rect.Min.X, rect.Max.Y, rect.Dx(), tview.AlignCenter, tcell.ColorWhite) } } -func (s *SparkLine) drawBlock(screen tcell.Screen, x, y int, b block, c tcell.Color) int { +func (s *SparkLine) drawBlock(screen tcell.Screen, x, y int, b block, c tcell.Color) { style := tcell.StyleDefault.Foreground(c).Background(s.bgColor) for i := 0; i < b.full; i++ { @@ -114,48 +113,46 @@ func (s *SparkLine) drawBlock(screen tcell.Screen, x, y int, b block, c tcell.Co if b.partial != 0 { screen.SetContent(x, y, b.partial, nil, style) } - - return y } -func (s *SparkLine) cutSet(w int) { - if w <= 0 || len(s.data) == 0 { +func (s *SparkLine) cutSet(width int) { + if width <= 0 || len(s.data) == 0 { return } - if w < len(s.data) { - s.data = s.data[len(s.data)-w:] + if len(s.data) >= width*2 { + s.data = s.data[len(s.data)-width:] } } func (s *SparkLine) computeMax() int { var max int for _, d := range s.data { - sum := d.Sum() - if sum > max { - max = sum + if max < d.OK { + max = d.OK } } return max } -func toBlocks(value Metric, scale float64) blocks { - if value.Sum() <= 0 { +func toBlocks(m Metric, scale float64) blocks { + if m.Sum() <= 0 { return blocks{} } - - oks := int(math.Floor(float64(value.OK) * scale)) - part, okB := oks%len(sparks), block{full: oks / len(sparks)} - if part > 0 { - okB.partial = sparks[part-1] - } - - errs := int(math.Round(float64(value.Fault) * scale)) - part, errB := errs%len(sparks), block{full: errs / len(sparks)} - if part > 0 { - errB.partial = sparks[part-1] - } - - return blocks{oks: okB, errs: errB} + return blocks{oks: makeBlocks(m.OK, false, scale), errs: makeBlocks(m.Fault, true, scale)} +} + +func makeBlocks(v int, isErr bool, scale float64) block { + scaled := int(math.Round(float64(v) * scale)) + part, b := scaled%len(sparks), block{full: scaled / len(sparks)} + // Err might get scaled way down if so nudge. + if v > 0 && isErr && scaled == 0 { + part = 1 + } + if part > 0 { + b.partial = sparks[part-1] + } + + return b } diff --git a/internal/ui/flash.go b/internal/ui/flash.go index acd6d588..5faa123d 100644 --- a/internal/ui/flash.go +++ b/internal/ui/flash.go @@ -31,7 +31,7 @@ func NewFlash(app *App) *Flash { TextView: tview.NewTextView(), } f.SetTextColor(tcell.ColorAqua) - f.SetTextAlign(tview.AlignLeft) + f.SetTextAlign(tview.AlignCenter) f.SetBorderPadding(0, 0, 1, 1) f.app.Styles.AddListener(&f) diff --git a/internal/ui/logo.go b/internal/ui/logo.go index 500b8840..3bc0a83b 100644 --- a/internal/ui/logo.go +++ b/internal/ui/logo.go @@ -25,7 +25,7 @@ func NewLogo(styles *config.Styles) *Logo { } l.SetDirection(tview.FlexRow) l.AddItem(l.logo, 0, 6, false) - l.AddItem(l.status, 0, 1, false) + l.AddItem(l.status, 1, 0, false) l.refreshLogo(styles.Body().LogoColor) l.SetBackgroundColor(styles.BgColor()) styles.AddListener(&l) diff --git a/internal/view/actions.go b/internal/view/actions.go index f0ec5529..9bd173b1 100644 --- a/internal/view/actions.go +++ b/internal/view/actions.go @@ -68,14 +68,14 @@ func hotKeyActions(r Runner, aa ui.KeyActions) { } aa[key] = ui.NewSharedKeyAction( hk.Description, - gotoCmd(r, hk.Command), + gotoCmd(r, "", hk.Command), false) } } -func gotoCmd(r Runner, cmd string) ui.ActionHandler { +func gotoCmd(r Runner, cmd, path string) ui.ActionHandler { return func(evt *tcell.EventKey) *tcell.EventKey { - if err := r.App().gotoResource(cmd, true); err != nil { + if err := r.App().gotoResource(cmd, path, true); err != nil { r.App().Flash().Err(err) } return nil diff --git a/internal/view/alias.go b/internal/view/alias.go index 4e822f2f..430c9635 100644 --- a/internal/view/alias.go +++ b/internal/view/alias.go @@ -59,7 +59,7 @@ func (a *Alias) gotoCmd(evt *tcell.EventKey) *tcell.EventKey { if r != 0 { s := ui.TrimCell(a.GetTable().SelectTable, r, 1) tokens := strings.Split(s, ",") - if err := a.App().gotoResource(tokens[0], true); err != nil { + if err := a.App().gotoResource(tokens[0], "", true); err != nil { a.App().Flash().Err(err) } return nil diff --git a/internal/view/app.go b/internal/view/app.go index 98997efe..8a68ffb0 100644 --- a/internal/view/app.go +++ b/internal/view/app.go @@ -104,8 +104,8 @@ func (a *App) Init(version string, rate int) error { main := tview.NewFlex().SetDirection(tview.FlexRow) main.AddItem(a.statusIndicator(), 1, 1, false) main.AddItem(a.Content, 0, 10, true) - main.AddItem(a.Crumbs(), 2, 1, false) - main.AddItem(flash, 2, 1, false) + main.AddItem(a.Crumbs(), 1, 1, false) + main.AddItem(flash, 1, 1, false) a.Main.AddPage("main", main, true, false) a.Main.AddPage("splash", ui.NewSplash(a.Styles, version), true, true) @@ -136,7 +136,7 @@ func (a *App) toggleHeader(flag bool) { } if a.showHeader { flex.RemoveItemAtIndex(0) - flex.AddItemAtIndex(0, a.buildHeader(), 7, 1, false) + flex.AddItemAtIndex(0, a.buildHeader(), 8, 1, false) } else { flex.RemoveItemAtIndex(0) flex.AddItemAtIndex(0, a.statusIndicator(), 1, 1, false) @@ -271,7 +271,7 @@ func (a *App) switchCtx(name string, loadPods bool) error { } a.Flash().Infof("Switching context to %s", name) a.ReloadStyles(name) - if err := a.gotoResource("pods", true); loadPods && err != nil { + if err := a.gotoResource("pods", "", true); loadPods && err != nil { a.Flash().Err(err) } a.clusterModel.Reset(a.factory) @@ -382,7 +382,7 @@ func (a *App) toggleHeaderCmd(evt *tcell.EventKey) *tcell.EventKey { func (a *App) gotoCmd(evt *tcell.EventKey) *tcell.EventKey { if a.CmdBuff().IsActive() && !a.CmdBuff().Empty() { - if err := a.gotoResource(a.GetCmd(), true); err != nil { + if err := a.gotoResource(a.GetCmd(), "", true); err != nil { log.Error().Err(err).Msgf("Goto resource for %q failed", a.GetCmd()) a.Flash().Err(err) } @@ -431,8 +431,8 @@ func (a *App) viewResource(gvr, path string, clearStack bool) error { return a.command.run(gvr, path, clearStack) } -func (a *App) gotoResource(cmd string, clearStack bool) error { - return a.command.run(cmd, "", clearStack) +func (a *App) gotoResource(cmd, path string, clearStack bool) error { + return a.command.run(cmd, path, clearStack) } func (a *App) inject(c model.Component) error { diff --git a/internal/view/cluster_info.go b/internal/view/cluster_info.go index df75851e..b315441e 100644 --- a/internal/view/cluster_info.go +++ b/internal/view/cluster_info.go @@ -30,6 +30,7 @@ func NewClusterInfo(app *App) *ClusterInfo { // Init initializes the view. func (c *ClusterInfo) Init() { + c.SetBorderPadding(0, 0, 1, 0) c.app.Styles.AddListener(c) c.layout() c.StylesChanged(c.app.Styles) diff --git a/internal/view/ns.go b/internal/view/ns.go index 1ad2a585..1a79fb94 100644 --- a/internal/view/ns.go +++ b/internal/view/ns.go @@ -42,7 +42,7 @@ func (n *Namespace) bindKeys(aa ui.KeyActions) { func (n *Namespace) switchNs(app *App, model ui.Tabular, gvr, path string) { n.useNamespace(path) - if err := app.gotoResource("pods", true); err != nil { + if err := app.gotoResource("pods", "", true); err != nil { app.Flash().Err(err) } } diff --git a/internal/view/pf_dialog.go b/internal/view/pf_dialog.go index a7b0e4b8..973644df 100644 --- a/internal/view/pf_dialog.go +++ b/internal/view/pf_dialog.go @@ -27,13 +27,13 @@ func ShowPortForwards(v ResourceViewer, path string, ports []string, okFn PortFo SetFieldTextColor(styles.K9s.Info.SectionColor.Color()) p1, p2, address := ports[0], extractPort(ports[0]), "localhost" - f.AddInputField("Container Port:", p1, 20, nil, func(p string) { + f.AddInputField("Container Port:", p1, 30, nil, func(p string) { p1 = p }) - f.AddInputField("Local Port:", p2, 20, nil, func(p string) { + f.AddInputField("Local Port:", p2, 30, nil, func(p string) { p2 = p }) - f.AddInputField("Address:", address, 20, nil, func(h string) { + f.AddInputField("Address:", address, 30, nil, func(h string) { address = h }) @@ -48,22 +48,24 @@ func ShowPortForwards(v ResourceViewer, path string, ports []string, okFn PortFo okFn(v, path, extractContainer(p1), tunnel) }) f.AddButton("Cancel", func() { - DismissPortForwards(pages) + DismissPortForwards(v.App(), pages) }) modal := tview.NewModalForm(fmt.Sprintf("", path), f) modal.SetText("Exposed Ports: " + strings.Join(ports, ",")) modal.SetDoneFunc(func(_ int, b string) { - DismissPortForwards(pages) + DismissPortForwards(v.App(), pages) }) - pages.AddPage(portForwardKey, modal, false, false) + pages.AddPage(portForwardKey, modal, false, true) pages.ShowPage(portForwardKey) + v.App().SetFocus(pages.GetPrimitive(portForwardKey)) } // DismissPortForwards dismiss the port forward dialog. -func DismissPortForwards(p *ui.Pages) { +func DismissPortForwards(app *App, p *ui.Pages) { p.RemovePage(portForwardKey) + app.SetFocus(p.CurrentPage().Item) } // ---------------------------------------------------------------------------- diff --git a/internal/view/pf_extender.go b/internal/view/pf_extender.go index 1393d37a..2907f2a8 100644 --- a/internal/view/pf_extender.go +++ b/internal/view/pf_extender.go @@ -76,7 +76,7 @@ func runForward(v ResourceViewer, pf watch.Forwarder, f *portforward.PortForward v.App().QueueUpdateDraw(func() { v.App().Flash().Infof("PortForward activated %s:%s", pf.Path(), pf.Ports()[0]) - DismissPortForwards(v.App().Content.Pages) + DismissPortForwards(v.App(), v.App().Content.Pages) }) pf.SetActive(true) @@ -124,7 +124,6 @@ func showFwdDialog(v ResourceViewer, path string, cb PortForwardFunc) error { ports = append(ports, client.FQN(co, p.Name)+":"+strconv.Itoa(int(p.ContainerPort))) } } - if len(ports) == 0 { return fmt.Errorf("no tcp ports found on %s", path) } diff --git a/internal/view/pulse.go b/internal/view/pulse.go index fcebef6a..21db7bce 100644 --- a/internal/view/pulse.go +++ b/internal/view/pulse.go @@ -141,15 +141,19 @@ func (p *Pulse) PulseChanged(c *health.Check) { v.SetLegend(fmt.Sprintf(" %s - %dMi", strings.Title(gvr.R()), c.Tally(health.OK))) default: nn := v.GetSeriesColorNames() - v.SetLegend(fmt.Sprintf(" %s(%d:[%s::]%d:[%s::b]%d[-::])", + if c.Tally(health.OK) == 0 { + nn[0] = "gray" + } + if c.Tally(health.Toast) == 0 { + nn[1] = "gray" + } + v.SetLegend(fmt.Sprintf(" %s - [%s::]%d/[%s::b]%d[-::]", strings.Title(gvr.R()), - c.Tally(health.Corpus), nn[0], c.Tally(health.OK), nn[1], c.Tally(health.Toast), - ), - ) + )) } v.Add(tchart.Metric{OK: c.Tally(health.OK), Fault: c.Tally(health.Toast)}) } @@ -173,12 +177,10 @@ func (p *Pulse) bindKeys() { } func (p *Pulse) keyboard(evt *tcell.EventKey) *tcell.EventKey { - log.Debug().Msgf("Pulse GOT EVENT %#v", evt) key := evt.Key() if key == tcell.KeyRune { key = tcell.Key(evt.Rune()) } - if a, ok := p.actions[key]; ok { return a.Action(evt) } @@ -275,7 +277,7 @@ func (p *Pulse) enterCmd(evt *tcell.EventKey) *tcell.EventKey { } log.Debug().Msgf("Selected %s", s.ID()) gvr := client.NewGVR(s.ID()) - if err := p.App().gotoResource(gvr.R(), false); err != nil { + if err := p.App().gotoResource(gvr.R(), "", false); err != nil { p.App().Flash().Err(err) } diff --git a/internal/view/registrar.go b/internal/view/registrar.go index 417f79e8..9adf1eb4 100644 --- a/internal/view/registrar.go +++ b/internal/view/registrar.go @@ -137,7 +137,7 @@ func extViewers(vv MetaViewers) { func showCRD(app *App, _ ui.Tabular, _, path string) { _, crdGVR := client.Namespaced(path) tokens := strings.Split(crdGVR, ".") - if err := app.gotoResource(tokens[0], false); err != nil { + if err := app.gotoResource(tokens[0], "", false); err != nil { app.Flash().Err(err) } } From bcbb24093b9194a72cba7145e40ec076db74beae Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 20 Feb 2020 00:13:29 -0700 Subject: [PATCH 45/58] add pulse view --- internal/view/pulse.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/view/pulse.go b/internal/view/pulse.go index 21db7bce..92314ffb 100644 --- a/internal/view/pulse.go +++ b/internal/view/pulse.go @@ -15,7 +15,6 @@ import ( "github.com/derailed/k9s/internal/ui" "github.com/derailed/tview" "github.com/gdamore/tcell" - "github.com/rs/zerolog/log" ) // Grapheable represents a graphic component. @@ -275,9 +274,8 @@ func (p *Pulse) enterCmd(evt *tcell.EventKey) *tcell.EventKey { if !ok { return nil } - log.Debug().Msgf("Selected %s", s.ID()) gvr := client.NewGVR(s.ID()) - if err := p.App().gotoResource(gvr.R(), "", false); err != nil { + if err := p.App().gotoResource(gvr.R()+" all", "", false); err != nil { p.App().Flash().Err(err) } From 3614b3122b0eb9f24f25dfe1802ff0415e9c43cb Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 20 Feb 2020 09:24:16 -0700 Subject: [PATCH 46/58] added rel notes + cleanup --- assets/k9s_doc.png | Bin 0 -> 177058 bytes change_logs/release_v0.16.0.md | 184 +++++++++++++++++++++++++++++++++ internal/client/config.go | 25 ++++- internal/view/exec.go | 6 +- skins/black_and_wtf.yml | 38 ++++--- skins/dracula.yml | 41 +++++--- skins/in_the_navy.yml | 36 ++++--- skins/snazzy.yml | 39 ++++--- skins/stock.yml | 39 ++++--- 9 files changed, 329 insertions(+), 79 deletions(-) create mode 100644 assets/k9s_doc.png create mode 100644 change_logs/release_v0.16.0.md diff --git a/assets/k9s_doc.png b/assets/k9s_doc.png new file mode 100644 index 0000000000000000000000000000000000000000..8627cb219ce7948009c3bf1828f80136e33ac0a6 GIT binary patch literal 177058 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

MZUTbuY^BM%Q`(&mvhd`f7W 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 SZS5rdv%|>DFx|lJ!v6u|YB{3- literal 0 HcmV?d00001 diff --git a/change_logs/release_v0.16.0.md b/change_logs/release_v0.16.0.md new file mode 100644 index 00000000..185a4529 --- /dev/null +++ b/change_logs/release_v0.16.0.md @@ -0,0 +1,184 @@ + + +# Release v0.16.0 + +## Notes + +Thank you to all that contributed with flushing out issues and enhancements for K9s! I'll try to mark some of these issues as fixed. But if you don't mind grab the latest rev and see if we're happier with some of the fixes! If you've filed an issue please help me verify and close. Your support, kindness and awesome suggestions to make K9s better is as ever very much noticed and appreciated! + +Also if you dig this tool, please make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer) + +On Slack? Please join us [K9slackers](https://join.slack.com/t/k9sers/shared_invite/enQtOTA5MDEyNzI5MTU0LWQ1ZGI3MzliYzZhZWEyNzYxYzA3NjE0YTk1YmFmNzViZjIyNzhkZGI0MmJjYzhlNjdlMGJhYzE2ZGU1NjkyNTM) + +--- + + + +This is one of these drops that may make you wonder if you'll go from zero to hero or likely the reverse?? Will see how this goes... Please proceed with caution on this one as there could very well be much distrubances in the force... + +Lots of code churns so could have totally hose some stuff, but like my GranPappy used to say `can't cook without making a mess!` + +## Going Wide? + +In this drop, we've enabled a new shortcut namely `wide` as `Ctrl-w`. On table views, you will be able to see more information about the resources such as labels or others depending on the viewed resource. This mnemonic works as a toggle so you can `narrow` the view by hitting it again. + +## Zoom, Zoom, Zoom! + +While viewing some resources that may contain errors, sorting on columns may not achieve the results you're seeking ie `show me all resources in an error state`. We've added a new option to achieve just that aka `zoom errors` as `ctrl-z`. This works as a toggle and will unveil resources that are need of some TLC on your part ;) + +## Does Your Cluster Have A Pulse? + +In this drop, we're introducing a brand new view aka `K9s Pulses`. This is a summary view listing the most sailient resources in your clusters and their current states. This view tracks two main metrics ie Ok and Toast on a 5sec beat. This view affords cluster activity and failure rates. BTW this is the zero to hero deal 🙀 Hopefully you'll dig it as this was much work to put together and I personally think it's the `ducks nuts`... If you like, please give me some luving on social or via GH sponsors as batteries are running low... + +To navigate thru the various pulses, you can use `tab`/`backtab` or use the menu index (just like namespaces selectors). Once on a pulse view, you can press `enter` to see the resource table view. Pressing `esc` will nav you back. + +As I've may have mentioned before, my front-end/UX FU is weak, so I've also added a way for you to skin the charts via skins yaml to your own liking. Please see the skin section below for an example on how to skin the pulses dials. BONUS you should be able to skin K9s live! How cool is that? + +NOTE: Pulses are very much experimental and could totally bomb on your clusters! So please thread carefully and please do report (kindly!) back. + +## BReaking Bad! + +In this drop I've broken a few things (that I know off...), here is the list as I can recall... + +1. Toggle header aka `my red headed step child`. Key moved (again!) now `Ctrl-e` +2. Skin yaml layout CHANGED! Moved table and xray sections under views and added charts section. + +## Skins Updates! + +The skin file format CHANGE! If you are running skins with K9s, please make sure to update your skin file. If not K9s could bomb coming up! + +NOTE: I don't think I'll get around to update all the contributed skins in this repo `skins` dir. If you're looking for a way to help out and are UI inclined, please take a peek and make them cool! + +```yaml +# my_cluster_skin.yml +# Styles... +foreground: &foreground "#f8f8f2" +background: &background "#282a36" +current_line: ¤t_line "#44475a" +selection: &selection "#44475a" +comment: &comment "#6272a4" +cyan: &cyan "#8be9fd" +green: &green "#50fa7b" +orange: &orange "#ffb86c" +pink: &pink "#ff79c6" +purple: &purple "#bd93f9" +red: &red "#ff5555" +yellow: &yellow "#f1fa8c" + +# Skin... +k9s: + # General K9s styles + body: + fgColor: *foreground + bgColor: *background + logoColor: *purple + # ClusterInfoView styles. + info: + fgColor: *pink + sectionColor: *foreground + frame: + # Borders styles. + border: + fgColor: *selection + focusColor: *current_line + menu: + fgColor: *foreground + keyColor: *pink + # Used for favorite namespaces + numKeyColor: *purple + # CrumbView attributes for history navigation. + crumbs: + fgColor: *foreground + bgColor: *current_line + activeColor: *current_line + # Resource status and update styles + status: + newColor: *cyan + modifyColor: *purple + addColor: *green + errorColor: *red + highlightcolor: *orange + killColor: *comment + completedColor: *comment + # Border title styles. + title: + fgColor: *foreground + bgColor: *current_line + highlightColor: *orange + counterColor: *purple + filterColor: *pink + views: + charts: + bgColor: *background + dialBgColor: "#0A2239" + chartBgColor: "#0A2239" + defaultDialColors: + - "#1E3888" + - "#820101" + defaultChartColors: + - "#1E3888" + - "#820101" + resourceColors: + batch/v1/jobs: + - "#5D737E" + - "#820101" + v1/persistentvolumes: + - "#3E554A" + - "#820101" + cpu: + - "#6EA4BF" + - "#820101" + mem: + - "#17505B" + - "#820101" + v1/events: + - "#073B3A" + - "#820101" + v1/pods: + - "#487FFF" + - "#820101" + # TableView attributes. + table: + fgColor: *foreground + bgColor: *background + cursorColor: *current_line + # Header row styles. + header: + fgColor: *foreground + bgColor: *background + sorterColor: *cyan + # Xray view attributes. + xray: + fgColor: *foreground + bgColor: *background + cursorColor: *current_line + graphicColor: *purple + showIcons: true + # YAML info styles. + yaml: + keyColor: *pink + colonColor: *purple + valueColor: *foreground + # Logs styles. + logs: + fgColor: *foreground + bgColor: *background +``` + +## Resolved Bugs/Features/PRs + +- [Issue #557](https://github.com/derailed/k9s/issues/557) +- [Issue #555](https://github.com/derailed/k9s/issues/555) +- [Issue #554](https://github.com/derailed/k9s/issues/554) +- [Issue #553](https://github.com/derailed/k9s/issues/553) +- [Issue #552](https://github.com/derailed/k9s/issues/552) +- [Issue #551](https://github.com/derailed/k9s/issues/551) +- [Issue #549](https://github.com/derailed/k9s/issues/549) A start with pulses... +- [Issue #540](https://github.com/derailed/k9s/issues/540) +- [Issue #421](https://github.com/derailed/k9s/issues/421) +- [Issue #351](https://github.com/derailed/k9s/issues/351) Solved by Pulses? +- [Issue #25](https://github.com/derailed/k9s/issues/25) Pulses? Oldie but goodie! + +--- + + © 2020 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0) diff --git a/internal/client/config.go b/internal/client/config.go index 58f9d74d..0be32021 100644 --- a/internal/client/config.go +++ b/internal/client/config.go @@ -3,6 +3,7 @@ package client import ( "errors" "fmt" + "strings" "sync" "github.com/rs/zerolog/log" @@ -177,13 +178,31 @@ func (c *Config) ClusterNames() ([]string, error) { // CurrentGroupNames retrieves the active group names. func (c *Config) CurrentGroupNames() ([]string, error) { - if c.flags.ImpersonateGroup != nil && len(*c.flags.ImpersonateGroup) != 0 { + if areSet(c.flags.ImpersonateGroup) { return *c.flags.ImpersonateGroup, nil } return []string{}, errors.New("unable to locate current group") } +// ImpersonateGroups retrieves the active groupsif set on the CLI. +func (c *Config) ImpersonateGroups() (string, error) { + if areSet(c.flags.ImpersonateGroup) { + return strings.Join(*c.flags.ImpersonateGroup, ","), nil + } + + return "", errors.New("no groups set") +} + +// ImpersonateUser retrieves the active user name if set on the CLI. +func (c *Config) ImpersonateUser() (string, error) { + if isSet(c.flags.Impersonate) { + return *c.flags.Impersonate, nil + } + + return "", errors.New("no user set") +} + // CurrentUserName retrieves the active user name. func (c *Config) CurrentUserName() (string, error) { if isSet(c.flags.Impersonate) { @@ -311,3 +330,7 @@ func (c *Config) ensureConfig() { func isSet(s *string) bool { return s != nil && len(*s) != 0 } + +func areSet(s *[]string) bool { + return s != nil && len(*s) != 0 +} diff --git a/internal/view/exec.go b/internal/view/exec.go index e302231a..2250b4aa 100644 --- a/internal/view/exec.go +++ b/internal/view/exec.go @@ -32,11 +32,11 @@ func runK(a *App, opts shellOpts) bool { return false } var args []string - if u, err := a.Conn().Config().CurrentUserName(); err == nil { + if u, err := a.Conn().Config().ImpersonateUser(); err == nil { args = append(args, "--as", u) } - if g, err := a.Conn().Config().CurrentGroupNames(); err == nil { - args = append(args, "--as-group", strings.Join(g, ",")) + if g, err := a.Conn().Config().ImpersonateGroups(); err == nil { + args = append(args, "--as-group", g) } args = append(args, "--context", a.Config.K9s.CurrentContext) if cfg := a.Conn().Config().Flags().KubeConfig; cfg != nil && *cfg != "" { diff --git a/skins/black_and_wtf.yml b/skins/black_and_wtf.yml index 73fe07d8..07009922 100644 --- a/skins/black_and_wtf.yml +++ b/skins/black_and_wtf.yml @@ -45,22 +45,22 @@ k9s: highlightColor: *active counterColor: *text filterColor: *slate - table: - fgColor: *fg - bgColor: *bg - cursorColor: *fg - markColor: *mark - header: - fgColor: *dslate - bgColor: *bg - sorterColor: *fg - xray: - fgColor: *fg - bgColor: *bg - cursorColor: *ghost - graphicColor: gray - showIcons: false views: + table: + fgColor: *fg + bgColor: *bg + cursorColor: *fg + markColor: *mark + header: + fgColor: *dslate + bgColor: *bg + sorterColor: *fg + xray: + fgColor: *fg + bgColor: *bg + cursorColor: *ghost + graphicColor: gray + showIcons: false yaml: keyColor: *ghost colorColor: *slate @@ -68,3 +68,11 @@ k9s: logs: fgColor: *ghost bgColor: *bg + charts: + bgColor: default + defaultDialColors: + - *white + - *err + defaultChartColors: + - *white + - *err diff --git a/skins/dracula.yml b/skins/dracula.yml index 801b2250..4ba08cd8 100644 --- a/skins/dracula.yml +++ b/skins/dracula.yml @@ -54,24 +54,33 @@ k9s: highlightColor: *orange counterColor: *purple filterColor: *pink - # TableView attributes. - table: - fgColor: *foreground - bgColor: *background - cursorColor: *current_line - # Header row styles. - header: + views: + # Charts skins... + charts: + bgColor: default + defaultDialColors: + - *purple + - *red + defaultChartColors: + - *purple + - *red + # TableView attributes. + table: fgColor: *foreground bgColor: *background - sorterColor: *cyan - # Xray view attributes. - xray: - fgColor: *foreground - bgColor: *background - cursorColor: *current_line - graphicColor: *purple - showIcons: false - views: + cursorColor: *current_line + # Header row styles. + header: + fgColor: *foreground + bgColor: *background + sorterColor: *cyan + # Xray view attributes. + xray: + fgColor: *foreground + bgColor: *background + cursorColor: *current_line + graphicColor: *purple + showIcons: false # YAML info styles. yaml: keyColor: *pink diff --git a/skins/in_the_navy.yml b/skins/in_the_navy.yml index 3a85f1bb..ed101190 100644 --- a/skins/in_the_navy.yml +++ b/skins/in_the_navy.yml @@ -53,22 +53,30 @@ k9s: highlightColor: *sky counterColor: *slate filterColor: *slate - table: - fgColor: *fg - bgColor: *bg - cursorColor: *aqua - markColor: *mslate - header: + views: + table: fgColor: *fg bgColor: *bg - sorterColor: *cadet - xray: - fgColor: *blue - bgColor: *dark - cursorColor: *aqua - graphicColor: *mslate - showIcons: false - views: + cursorColor: *aqua + markColor: *mslate + header: + fgColor: *fg + bgColor: *bg + sorterColor: *cadet + xray: + fgColor: *blue + bgColor: *dark + cursorColor: *aqua + graphicColor: *mslate + showIcons: false + charts: + bgColor: *bg + defaultDialColors: + - *aqua + - *err + defaultChartColors: + - *aqua + - *err yaml: keyColor: *steel colorColor: *blue diff --git a/skins/snazzy.yml b/skins/snazzy.yml index 55a022ea..11cf5240 100644 --- a/skins/snazzy.yml +++ b/skins/snazzy.yml @@ -32,22 +32,31 @@ k9s: highlightColor: white counterColor: white filterColor: "#57c7ff" - table: - fgColor: "#57c7ff" - bgColor: "#282a36" - cursorColor: "#5af78e" - markColor: darkgoldenrod - header: - fgColor: white - bgColor: "#282a36" - sorterColor: orange - xray: - fgColor: "#57c7ff" - bgColor: "#282a36" - cursorColor: "#5af78e" - graphicColor: darkgoldenrod - showIcons: false views: + # Charts skins... + charts: + bgColor: default + defaultDialColors: + - "#57c7ff" + - "#ff5c57" + defaultChartColors: + - "#57c7ff" + - "#ff5c57" + table: + fgColor: "#57c7ff" + bgColor: "#282a36" + cursorColor: "#5af78e" + markColor: darkgoldenrod + header: + fgColor: white + bgColor: "#282a36" + sorterColor: orange + xray: + fgColor: "#57c7ff" + bgColor: "#282a36" + cursorColor: "#5af78e" + graphicColor: darkgoldenrod + showIcons: false yaml: keyColor: "#ff5c57" colonColor: white diff --git a/skins/stock.yml b/skins/stock.yml index acbf7dc0..33c9538c 100644 --- a/skins/stock.yml +++ b/skins/stock.yml @@ -31,22 +31,31 @@ k9s: highlightColor: fuchsia counterColor: papayawhip filterColor: steelblue - table: - fgColor: blue - bgColor: black - cursorColor: aqua - markColor: darkgoldenrod - header: - fgColor: white - bgColor: black - sorterColor: orange - xray: - fgColor: blue - bgColor: black - cursorColor: aqua - graphicColor: darkgoldenrod - showIcons: false views: + # Charts skins... + charts: + bgColor: black + defaultDialColors: + - linegreen + - orangered + defaultChartColors: + - linegreen + - orangered + table: + fgColor: blue + bgColor: black + cursorColor: aqua + markColor: darkgoldenrod + header: + fgColor: white + bgColor: black + sorterColor: orange + xray: + fgColor: blue + bgColor: black + cursorColor: aqua + graphicColor: darkgoldenrod + showIcons: false yaml: keyColor: steelblue colonColor: white From 706911215260bd59aa579a66d08afdc2ab7c74a2 Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 20 Feb 2020 09:38:59 -0700 Subject: [PATCH 47/58] update rel notes --- change_logs/release_v0.16.0.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/change_logs/release_v0.16.0.md b/change_logs/release_v0.16.0.md index 185a4529..53c52754 100644 --- a/change_logs/release_v0.16.0.md +++ b/change_logs/release_v0.16.0.md @@ -26,13 +26,14 @@ In this drop, we've enabled a new shortcut namely `wide` as `Ctrl-w`. On table v While viewing some resources that may contain errors, sorting on columns may not achieve the results you're seeking ie `show me all resources in an error state`. We've added a new option to achieve just that aka `zoom errors` as `ctrl-z`. This works as a toggle and will unveil resources that are need of some TLC on your part ;) -## Does Your Cluster Have A Pulse? +## Does Your Cluster Have A Pulse 💓? -In this drop, we're introducing a brand new view aka `K9s Pulses`. This is a summary view listing the most sailient resources in your clusters and their current states. This view tracks two main metrics ie Ok and Toast on a 5sec beat. This view affords cluster activity and failure rates. BTW this is the zero to hero deal 🙀 Hopefully you'll dig it as this was much work to put together and I personally think it's the `ducks nuts`... If you like, please give me some luving on social or via GH sponsors as batteries are running low... +In this drop, we're introducing a brand new view aka `K9s Pulses` 💓. This is a summary view listing the most sailient resources in your clusters and their current states. This view tracks two main metrics ie Ok and Toast on a 5sec beat. This view affords cluster activity and failure rates. BTW this is the zero to hero deal 🙀 Hopefully you'll dig it as this was much work to put together and I personally think it's the `ducks nuts`... If you like, please give me some luving on social or via GH sponsors as batteries are running low... -To navigate thru the various pulses, you can use `tab`/`backtab` or use the menu index (just like namespaces selectors). Once on a pulse view, you can press `enter` to see the resource table view. Pressing `esc` will nav you back. +To active, enter command mode by typing in `:pulse` aliases are `pu`, `pulses` or `hz` +To navigate thru the various pulses, you can use `tab`/`backtab` or use the menu index (just like namespaces selectors). Once on a pulse view, you can press `enter` to see the associated resource table view. Pressing `esc` will nav you back. -As I've may have mentioned before, my front-end/UX FU is weak, so I've also added a way for you to skin the charts via skins yaml to your own liking. Please see the skin section below for an example on how to skin the pulses dials. BONUS you should be able to skin K9s live! How cool is that? +As I've may have mentioned before, my front-end/UX FU is weak, so I've also added a way for you to skin the charts via skins yaml to your own liking. Please see the skin section below for an example on how to skin the pulses dials. BONUS you should be able to skin K9s live! How cool is that 😻? NOTE: Pulses are very much experimental and could totally bomb on your clusters! So please thread carefully and please do report (kindly!) back. From 73a90ed2aecc83ae1e7b99ca1362332c56ff9c0f Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 20 Feb 2020 10:18:01 -0700 Subject: [PATCH 48/58] cleaning up --- go.mod | 2 +- go.sum | 2 ++ internal/client/metrics.go | 3 +++ internal/config/styles.go | 6 +++--- internal/dao/pulse.go | 2 ++ internal/model/flash.go | 3 +++ internal/model/pulse.go | 2 ++ internal/model/pulse_health.go | 3 +++ internal/render/ofaas.go | 8 ++++---- internal/render/rs.go | 12 ++++++------ internal/tchart/dot_matrix.go | 12 +++++++++--- internal/tchart/gauge.go | 7 +++++++ internal/ui/flash.go | 1 + internal/view/alias.go | 1 + internal/view/app.go | 2 +- internal/view/pulse.go | 2 +- 16 files changed, 49 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index 25af63b4..4daf737e 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/alexellis/go-execute v0.0.0-20200124154445-8697e4e28c5e // indirect github.com/alexellis/hmac v0.0.0-20180624211220-5c52ab81c0de // indirect github.com/atotto/clipboard v0.1.2 - github.com/derailed/tview v0.3.5 + github.com/derailed/tview v0.3.6 github.com/drone/envsubst v1.0.2 // indirect github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f // indirect github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f // indirect diff --git a/go.sum b/go.sum index 0980b97e..ad8eaeee 100644 --- a/go.sum +++ b/go.sum @@ -157,6 +157,8 @@ github.com/derailed/tview v0.3.4 h1:PnF64fLqm48LEjC/XwOS7JufDgFuuPYx85YVt5t3rwE= github.com/derailed/tview v0.3.4/go.mod h1:yApPszFU62FoaGkf7swy2nIdV/h7Nid3dhMSVy6+OFI= github.com/derailed/tview v0.3.5 h1:1vKqcJIiZtLAs5moX9c38+BbBSYhPgFq0ZndnVNVNFc= github.com/derailed/tview v0.3.5/go.mod h1:yApPszFU62FoaGkf7swy2nIdV/h7Nid3dhMSVy6+OFI= +github.com/derailed/tview v0.3.6 h1:9PyX6Nu1vs9mCVfvV2q2fwT/dZta0dBGr4ZPjCF1KnU= +github.com/derailed/tview v0.3.6/go.mod h1:GJ3k/TIzEE+sj1L09/usk6HrkjsdadSsb03eHgPbcII= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= diff --git a/internal/client/metrics.go b/internal/client/metrics.go index 25b137f9..7f02787e 100644 --- a/internal/client/metrics.go +++ b/internal/client/metrics.go @@ -16,8 +16,10 @@ const ( mxCacheExpiry = 1 * time.Minute ) +// MetricsDial tracks global metric server handle. var MetricsDial *MetricsServer +// DialMetrics dials the metrics server. func DialMetrics(c Connection) *MetricsServer { if MetricsDial == nil { MetricsDial = NewMetricsServer(c) @@ -26,6 +28,7 @@ func DialMetrics(c Connection) *MetricsServer { return MetricsDial } +// ResetMetrics resets the metric server handle. func ResetMetrics() { MetricsDial = nil } diff --git a/internal/config/styles.go b/internal/config/styles.go index e14ecdf4..cc56482f 100644 --- a/internal/config/styles.go +++ b/internal/config/styles.go @@ -105,7 +105,7 @@ type ( FgColor Color `yaml:"fgColor"` } - // ColorBorder tracks border styles. + // Border tracks border styles. Border struct { FgColor Color `yaml:"fgColor"` FocusColor Color `yaml:"focusColor"` @@ -179,7 +179,7 @@ func (c Color) String() string { return string(c) } -// AsColor returns a view color. +// Color returns a view color. func (c Color) Color() tcell.Color { if c == DefaultColor { return tcell.ColorDefault @@ -190,7 +190,7 @@ func (c Color) Color() tcell.Color { return tcell.GetColor(c.String()) } -// AsColors converts series string colors to colors. +// Colors converts series string colors to colors. func (c Colors) Colors() []tcell.Color { cc := make([]tcell.Color, 0, len(c)) for _, color := range c { diff --git a/internal/dao/pulse.go b/internal/dao/pulse.go index 6b323021..4c93ad38 100644 --- a/internal/dao/pulse.go +++ b/internal/dao/pulse.go @@ -7,10 +7,12 @@ import ( "k8s.io/apimachinery/pkg/runtime" ) +// Pulse tracks pulses. type Pulse struct { NonResource } +// List lists out pulses. func (h *Pulse) List(ctx context.Context, ns string) ([]runtime.Object, error) { return nil, fmt.Errorf("NYI") } diff --git a/internal/model/flash.go b/internal/model/flash.go index 284985b8..d7fe8300 100644 --- a/internal/model/flash.go +++ b/internal/model/flash.go @@ -20,6 +20,7 @@ const ( FlashErr ) +// LevelMessage tracks an message and severity. type LevelMessage struct { Level FlashLevel Text string @@ -29,6 +30,7 @@ func newClearMessage() LevelMessage { return LevelMessage{} } +// IsClear returns true if message is empty. func (l LevelMessage) IsClear() bool { return l.Text == "" } @@ -56,6 +58,7 @@ type Flash struct { msgChan chan LevelMessage } +// NewFlash returns a new instance. func NewFlash(dur time.Duration) *Flash { return &Flash{ delay: dur, diff --git a/internal/model/pulse.go b/internal/model/pulse.go index 9db88a0b..d26ecc83 100644 --- a/internal/model/pulse.go +++ b/internal/model/pulse.go @@ -35,6 +35,7 @@ type Pulse struct { data health.Checks } +// NewPulse returns a new pulse. func NewPulse(gvr string) *Pulse { return &Pulse{ gvr: gvr, @@ -42,6 +43,7 @@ func NewPulse(gvr string) *Pulse { } } +// Watch monitors pulses. func (p *Pulse) Watch(ctx context.Context) { p.Refresh(ctx) go p.updater(ctx) diff --git a/internal/model/pulse_health.go b/internal/model/pulse_health.go index 12de902d..d0a1c5c0 100644 --- a/internal/model/pulse_health.go +++ b/internal/model/pulse_health.go @@ -14,16 +14,19 @@ import ( "k8s.io/apimachinery/pkg/runtime" ) +// PulseHealth tracks resources health. type PulseHealth struct { factory dao.Factory } +// NewPulseHealth returns a new instance. func NewPulseHealth(f dao.Factory) *PulseHealth { return &PulseHealth{ factory: f, } } +// List returns a canned collection of resources health. func (h *PulseHealth) List(ctx context.Context, ns string) ([]runtime.Object, error) { defer func(t time.Time) { log.Debug().Msgf("PulseHealthCheck %v", time.Since(t)) diff --git a/internal/render/ofaas.go b/internal/render/ofaas.go index 4d285197..1edb3439 100644 --- a/internal/render/ofaas.go +++ b/internal/render/ofaas.go @@ -55,8 +55,8 @@ func (OpenFaas) Header(ns string) HeaderRow { } // Render renders a chart to screen. -func (f OpenFaas) Render(o interface{}, ns string, r *Row) error { - fn, ok := o.(OpenFaasRes) +func (o OpenFaas) Render(i interface{}, ns string, r *Row) error { + fn, ok := i.(OpenFaasRes) if !ok { return fmt.Errorf("expected OpenFaasRes, but got %T", o) } @@ -71,7 +71,7 @@ func (f OpenFaas) Render(o interface{}, ns string, r *Row) error { } r.ID = client.FQN(fn.Function.Namespace, fn.Function.Name) - r.Fields = make(Fields, 0, len(f.Header(ns))) + r.Fields = make(Fields, 0, len(o.Header(ns))) if client.IsAllNamespaces(ns) { r.Fields = append(r.Fields, fn.Function.Namespace) } @@ -83,7 +83,7 @@ func (f OpenFaas) Render(o interface{}, ns string, r *Row) error { strconv.Itoa(int(fn.Function.InvocationCount)), strconv.Itoa(int(fn.Function.Replicas)), strconv.Itoa(int(fn.Function.AvailableReplicas)), - asStatus(f.diagnose(status)), + asStatus(o.diagnose(status)), toAge(metav1.Time{Time: time.Now()}), ) diff --git a/internal/render/rs.go b/internal/render/rs.go index f0412d56..63f4885b 100644 --- a/internal/render/rs.go +++ b/internal/render/rs.go @@ -50,7 +50,7 @@ func (ReplicaSet) Header(ns string) HeaderRow { } // Render renders a K8s resource to screen. -func (s ReplicaSet) Render(o interface{}, ns string, r *Row) error { +func (r ReplicaSet) Render(o interface{}, ns string, row *Row) error { raw, ok := o.(*unstructured.Unstructured) if !ok { return fmt.Errorf("Expected ReplicaSet, but got %T", o) @@ -61,18 +61,18 @@ func (s ReplicaSet) Render(o interface{}, ns string, r *Row) error { return err } - r.ID = client.MetaFQN(rs.ObjectMeta) - r.Fields = make(Fields, 0, len(s.Header(ns))) + row.ID = client.MetaFQN(rs.ObjectMeta) + row.Fields = make(Fields, 0, len(r.Header(ns))) if client.IsAllNamespaces(ns) { - r.Fields = append(r.Fields, rs.Namespace) + row.Fields = append(row.Fields, rs.Namespace) } - r.Fields = append(r.Fields, + row.Fields = append(row.Fields, rs.Name, strconv.Itoa(int(*rs.Spec.Replicas)), strconv.Itoa(int(rs.Status.Replicas)), strconv.Itoa(int(rs.Status.ReadyReplicas)), mapToStr(rs.Labels), - asStatus(s.diagnose(rs)), + asStatus(r.diagnose(rs)), toAge(rs.ObjectMeta.CreationTimestamp), ) diff --git a/internal/tchart/dot_matrix.go b/internal/tchart/dot_matrix.go index 8115a314..6eaf596a 100644 --- a/internal/tchart/dot_matrix.go +++ b/internal/tchart/dot_matrix.go @@ -4,23 +4,26 @@ import ( "fmt" ) -// var dots = []rune{' ', '⠂', '⠶', '⠿'} var dots = []rune{' ', '⠂', '▤', '▥'} -// var dots = []rune{' ', '⠂', '▤', '▇'} - +// Segment represents a dial segment. type Segment []int +// Segments represents a collection of segments. type Segments []Segment +// Matrics represents a number dial. type Matrix [][]rune +// Orientation tracks char orientations. type Orientation int +// DotMatrix tracks a char matrix. type DotMatrix struct { row, col int } +// NewDotMatrix returns a new matrix. func NewDotMatrix(row, col int) DotMatrix { return DotMatrix{ row: row, @@ -28,6 +31,7 @@ func NewDotMatrix(row, col int) DotMatrix { } } +// Print prints the matrix. func (d DotMatrix) Print(n int) Matrix { m := make(Matrix, d.row) segs := asSegments(n) @@ -67,6 +71,7 @@ func asSegments(n int) Segment { } } +// CharFor return a char based on row/col. func (s Segment) CharFor(row, col int) rune { c := ' ' segs := ToSegments(row, col) @@ -101,6 +106,7 @@ var segs = map[int][][]int{ 4: [][]int{[]int{4, 6}, []int{6}, []int{5, 6}}, } +// ToSegments return path segments. func ToSegments(row, col int) []int { return segs[row][col] } diff --git a/internal/tchart/gauge.go b/internal/tchart/gauge.go index b40fa546..f019b4d2 100644 --- a/internal/tchart/gauge.go +++ b/internal/tchart/gauge.go @@ -9,8 +9,13 @@ import ( ) const ( + // DeltaSame represents no difference. DeltaSame delta = iota + + // DeltaMore represents a higher value. DeltaMore + + // DeltaLess represents a lower value. DeltaLess gaugeFmt = "0%dd" @@ -38,6 +43,7 @@ func (g *Gauge) IsDial() bool { return true } +// Add adds a new metric. func (g *Gauge) Add(m Metric) { g.mx.Lock() defer g.mx.Unlock() @@ -73,6 +79,7 @@ func (g *Gauge) drawNum(sc tcell.Screen, ok bool, o image.Point, n int, dn delta } } +// Draw draws the primitive. func (g *Gauge) Draw(sc tcell.Screen) { g.Component.Draw(sc) diff --git a/internal/ui/flash.go b/internal/ui/flash.go index 5faa123d..d401fe7e 100644 --- a/internal/ui/flash.go +++ b/internal/ui/flash.go @@ -49,6 +49,7 @@ func (f *Flash) StylesChanged(s *config.Styles) { f.SetTextColor(s.FgColor()) } +// Watch watches for flash changes. func (f *Flash) Watch(ctx context.Context, c model.FlashChan) { defer log.Debug().Msgf("Flash Canceled!") for { diff --git a/internal/view/alias.go b/internal/view/alias.go index 430c9635..ac582262 100644 --- a/internal/view/alias.go +++ b/internal/view/alias.go @@ -32,6 +32,7 @@ func NewAlias(gvr client.GVR) ResourceViewer { return &a } +// Init initialiazes the view. func (a *Alias) Init(ctx context.Context) error { if err := a.ResourceViewer.Init(ctx); err != nil { return err diff --git a/internal/view/app.go b/internal/view/app.go index 8a68ffb0..55e0fb01 100644 --- a/internal/view/app.go +++ b/internal/view/app.go @@ -18,7 +18,7 @@ import ( "github.com/rs/zerolog/log" ) -// // ExitStatus indicates UI exit conditions. +// ExitStatus indicates UI exit conditions. var ExitStatus = "" const ( diff --git a/internal/view/pulse.go b/internal/view/pulse.go index 92314ffb..b936f42b 100644 --- a/internal/view/pulse.go +++ b/internal/view/pulse.go @@ -157,7 +157,7 @@ func (p *Pulse) PulseChanged(c *health.Check) { v.Add(tchart.Metric{OK: c.Tally(health.OK), Fault: c.Tally(health.Toast)}) } -// PulseLoadFailed notifies the load failed. +// PulseFailed notifies the load failed. func (p *Pulse) PulseFailed(err error) { p.app.Flash().Err(err) } From 134c394b6ecc23c71715393d54c0ca5c5a801975 Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 20 Feb 2020 10:26:45 -0700 Subject: [PATCH 49/58] cleaning up --- internal/model/flash_test.go | 1 - internal/render/row_header.go | 2 +- internal/render/rs.go | 2 +- internal/tchart/dot_matrix.go | 12 ++++++------ internal/tchart/sparkline.go | 4 ++-- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/internal/model/flash_test.go b/internal/model/flash_test.go index f191b444..438eda73 100644 --- a/internal/model/flash_test.go +++ b/internal/model/flash_test.go @@ -69,7 +69,6 @@ func TestFlashBurst(t *testing.T) { assert.Equal(t, count, s) assert.Equal(t, model.FlashInfo, l) assert.Equal(t, fmt.Sprintf("test-%d", count), m) - assert.Equal(t, 1, c) } type flash struct { diff --git a/internal/render/row_header.go b/internal/render/row_header.go index 343fff3f..4bdd87d6 100644 --- a/internal/render/row_header.go +++ b/internal/render/row_header.go @@ -74,7 +74,7 @@ func (hh HeaderRow) ValidColIndex() int { return hh.IndexOf("VALID") } -// IndeOf returns the col index or -1 if none. +// IndexOf returns the col index or -1 if none. func (hh HeaderRow) IndexOf(c string) int { for i, h := range hh { if h.Name == c { diff --git a/internal/render/rs.go b/internal/render/rs.go index 63f4885b..df0ed8c7 100644 --- a/internal/render/rs.go +++ b/internal/render/rs.go @@ -79,7 +79,7 @@ func (r ReplicaSet) Render(o interface{}, ns string, row *Row) error { return nil } -func (s ReplicaSet) diagnose(rs appsv1.ReplicaSet) error { +func (ReplicaSet) diagnose(rs appsv1.ReplicaSet) error { if rs.Status.Replicas != rs.Status.ReadyReplicas { if rs.Status.Replicas == 0 { return fmt.Errorf("did not phase down correctly expecting 0 replicas but got %d", rs.Status.ReadyReplicas) diff --git a/internal/tchart/dot_matrix.go b/internal/tchart/dot_matrix.go index 6eaf596a..7e9399fb 100644 --- a/internal/tchart/dot_matrix.go +++ b/internal/tchart/dot_matrix.go @@ -12,7 +12,7 @@ type Segment []int // Segments represents a collection of segments. type Segments []Segment -// Matrics represents a number dial. +// Matrix represents a number dial. type Matrix [][]rune // Orientation tracks char orientations. @@ -99,11 +99,11 @@ func charForSeg(seg, row, col int) rune { } var segs = map[int][][]int{ - 0: [][]int{[]int{1, 0}, []int{0}, []int{2, 0}}, - 1: [][]int{[]int{1}, nil, []int{2}}, - 2: [][]int{[]int{1, 3}, []int{3}, []int{2, 3}}, - 3: [][]int{[]int{4}, nil, []int{5}}, - 4: [][]int{[]int{4, 6}, []int{6}, []int{5, 6}}, + 0: {{1, 0}, {0}, {2, 0}}, + 1: {{1}, nil, {2}}, + 2: {{1, 3}, {3}, {2, 3}}, + 3: {{4}, nil, {5}}, + 4: {{4, 6}, {6}, {5, 6}}, } // ToSegments return path segments. diff --git a/internal/tchart/sparkline.go b/internal/tchart/sparkline.go index 690578a0..5b157bc1 100644 --- a/internal/tchart/sparkline.go +++ b/internal/tchart/sparkline.go @@ -24,7 +24,7 @@ type Metric struct { OK, Fault int } -// Max returns the max of the metric. +// MaxDigits returns the max of the metric. func (m Metric) MaxDigits() int { max := int(math.Max(float64(m.OK), float64(m.Fault))) s := fmt.Sprintf("%d", max) @@ -36,7 +36,7 @@ func (m Metric) Sum() int { return m.OK + m.Fault } -// Sparkline represents a sparkline component. +// SparkLine represents a sparkline component. type SparkLine struct { *Component From bd4ab0cf2bf667d6d2a5e79e74d1691466615d90 Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 20 Feb 2020 10:28:06 -0700 Subject: [PATCH 50/58] fix tests --- internal/model/flash_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/model/flash_test.go b/internal/model/flash_test.go index 438eda73..a12dfe01 100644 --- a/internal/model/flash_test.go +++ b/internal/model/flash_test.go @@ -65,7 +65,7 @@ func TestFlashBurst(t *testing.T) { } time.Sleep(2 * delay) - s, c, l, m := v.getMetrics() + s, _, l, m := v.getMetrics() assert.Equal(t, count, s) assert.Equal(t, model.FlashInfo, l) assert.Equal(t, fmt.Sprintf("test-%d", count), m) From 7ae43eaf5e071a4cba6f3177f2dd83d6c48e0f5c Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 20 Feb 2020 10:39:58 -0700 Subject: [PATCH 51/58] update docs --- README.md | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 9b88228d..47710d12 100644 --- a/README.md +++ b/README.md @@ -99,8 +99,9 @@ K9s is available on Linux, macOS and Windows platforms. --- -## Demo Video +## Demo Videos/Recordings +* [K9s Pulses](https://asciinema.org/a/UbXKPal6IWpTaVAjBBFmizcGN) * [K9s v0.15.1](https://youtu.be/7Fx4XQ2ftpM) * [K9s v0.13.0](https://www.youtube.com/watch?v=qaeR2iK7U0o&t=15s) * [K9s v0.9.0](https://www.youtube.com/watch?v=bxKfqumjW4I) @@ -141,7 +142,7 @@ K9s uses aliases to navigate most K8s resources. | `:`ns`` | To view and switch to another Kubernetes namespace | `:`+`ns`+`` | | `:screendump`, `:sd` | To view all saved resources | | | `Ctrl-d` | To delete a resource (TAB and ENTER to confirm) | | -| `Ctrl-k` | To delete a resource (no confirmation dialog) | | +| `Ctrl-k` | To kill a resource (no confirmation dialog!) | | | `:q`, `Ctrl-c` | To bail out of K9s | | --- @@ -505,17 +506,17 @@ k9s: highlightColor: skyblue counterColor: slateblue filterColor: slategray - # TableView attributes. - table: - fgColor: blue - bgColor: darkblue - cursorColor: aqua - # Header row styles. - header: - fgColor: white - bgColor: darkblue - sorterColor: orange views: + # TableView attributes. + table: + fgColor: blue + bgColor: darkblue + cursorColor: aqua + # Header row styles. + header: + fgColor: white + bgColor: darkblue + sorterColor: orange # YAML info styles. yaml: keyColor: steelblue From 0e948340368ec6320bfd097bad61403dd37528f9 Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 20 Feb 2020 10:51:01 -0700 Subject: [PATCH 52/58] update test --- internal/model/flash_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/model/flash_test.go b/internal/model/flash_test.go index a12dfe01..b3e5b86c 100644 --- a/internal/model/flash_test.go +++ b/internal/model/flash_test.go @@ -40,7 +40,7 @@ func TestFlash(t *testing.T) { f.Err(errors.New(u.e)) } - time.Sleep(2 * delay) + time.Sleep(5 * delay) s, c, l, m := v.getMetrics() assert.Equal(t, 1, s) assert.Equal(t, u.level, l) From fa14ecc4daed028572e5ab6a3a1a211706496f1f Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 20 Feb 2020 11:03:47 -0700 Subject: [PATCH 53/58] fix test --- internal/model/flash_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/model/flash_test.go b/internal/model/flash_test.go index b3e5b86c..c33d706e 100644 --- a/internal/model/flash_test.go +++ b/internal/model/flash_test.go @@ -41,11 +41,10 @@ func TestFlash(t *testing.T) { } time.Sleep(5 * delay) - s, c, l, m := v.getMetrics() + s, _, l, m := v.getMetrics() assert.Equal(t, 1, s) assert.Equal(t, u.level, l) assert.Equal(t, u.e, m) - assert.Equal(t, 1, c) close(f.Channel()) }) From 237ef23bf7f9e616dd00894bd6312cfef9fa16bd Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 20 Feb 2020 11:57:55 -0700 Subject: [PATCH 54/58] fix #561 --- .goreleaser.yml | 2 +- change_logs/release_v0.16.1.md | 23 +++++++++++++++++++++++ internal/view/pod.go | 2 +- 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 change_logs/release_v0.16.1.md diff --git a/.goreleaser.yml b/.goreleaser.yml index dbc015af..3ea1f36b 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -16,7 +16,7 @@ builds: - 386 - amd64 - arm64 - - armhf + - arm goarm: - 6 - 7 diff --git a/change_logs/release_v0.16.1.md b/change_logs/release_v0.16.1.md new file mode 100644 index 00000000..29cc927f --- /dev/null +++ b/change_logs/release_v0.16.1.md @@ -0,0 +1,23 @@ + + +# Release v0.16.1 + +## Notes + +Thank you to all that contributed with flushing out issues and enhancements for K9s! I'll try to mark some of these issues as fixed. But if you don't mind grab the latest rev and see if we're happier with some of the fixes! If you've filed an issue please help me verify and close. Your support, kindness and awesome suggestions to make K9s better is as ever very much noticed and appreciated! + +Also if you dig this tool, please make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer) + +On Slack? Please join us [K9slackers](https://join.slack.com/t/k9sers/shared_invite/enQtOTA5MDEyNzI5MTU0LWQ1ZGI3MzliYzZhZWEyNzYxYzA3NjE0YTk1YmFmNzViZjIyNzhkZGI0MmJjYzhlNjdlMGJhYzE2ZGU1NjkyNTM) + +--- + +Maintenance Release! + +## Resolved Bugs/Features/PRs + +- [Issue #561](https://github.com/derailed/k9s/issues/561) + +--- + + © 2020 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0) diff --git a/internal/view/pod.go b/internal/view/pod.go index 0ba9937a..08facd08 100644 --- a/internal/view/pod.go +++ b/internal/view/pod.go @@ -117,7 +117,7 @@ func (p *Pod) shellCmd(evt *tcell.EventKey) *tcell.EventKey { } row := p.GetTable().GetSelectedRowIndex() - status := ui.TrimCell(p.GetTable().SelectTable, row, p.GetTable().NameColIndex()+2) + status := ui.TrimCell(p.GetTable().SelectTable, row, p.GetTable().NameColIndex()+3) if status != render.Running { p.App().Flash().Errf("%s is not in a running state", path) return nil From 7758b255b7b97c7121eceeaf4211f10b4f873a9a Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 20 Feb 2020 12:07:01 -0700 Subject: [PATCH 55/58] update releases --- .goreleaser.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.goreleaser.yml b/.goreleaser.yml index 3ea1f36b..f8e5f3dc 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -12,6 +12,7 @@ builds: - linux - darwin - windows + - debian goarch: - 386 - amd64 From 9f24abc1419e6e8b7e39c748b33e35e7ce96805e Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 20 Feb 2020 12:12:46 -0700 Subject: [PATCH 56/58] update release --- .goreleaser.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index f8e5f3dc..3ea1f36b 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -12,7 +12,6 @@ builds: - linux - darwin - windows - - debian goarch: - 386 - amd64 From edf7c5388de0ad8af941e798709a458c5c52adb8 Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 20 Feb 2020 12:17:29 -0700 Subject: [PATCH 57/58] udpate release --- .goreleaser.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 3ea1f36b..f5511c2c 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -18,7 +18,6 @@ builds: - arm64 - arm goarm: - - 6 - 7 ldflags: - -s -w -X github.com/derailed/k9s/cmd.version={{.Version}} -X github.com/derailed/k9s/cmd.commit={{.Commit}} -X github.com/derailed/k9s/cmd.date={{.Date}} From bb9b31b103d825fe3f77aef39a71592a79e800db Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 20 Feb 2020 12:26:43 -0700 Subject: [PATCH 58/58] fix tests --- internal/model/flash_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/internal/model/flash_test.go b/internal/model/flash_test.go index c33d706e..2c0561ed 100644 --- a/internal/model/flash_test.go +++ b/internal/model/flash_test.go @@ -45,8 +45,6 @@ func TestFlash(t *testing.T) { assert.Equal(t, 1, s) assert.Equal(t, u.level, l) assert.Equal(t, u.e, m) - - close(f.Channel()) }) } }