update docs + fix all ns issue #326
parent
d0156c5995
commit
87fbc9c9aa
99
README.md
99
README.md
|
|
@ -60,6 +60,26 @@ K9s is available on Linux, OSX and Windows platforms.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Screenshots
|
||||||
|
|
||||||
|
1. Pods
|
||||||
|
<img src="assets/screen_po.png"/>
|
||||||
|
1. Logs
|
||||||
|
<img src="assets/screen_logs.png"/>
|
||||||
|
1. Deployments
|
||||||
|
<img src="assets/screen_dp.png"/>
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Demo Video
|
||||||
|
|
||||||
|
* [K9s v0.9.0](https://www.youtube.com/watch?v=bxKfqumjW4I)
|
||||||
|
* [K9s v0.7.0 Features](https://youtu.be/83jYehwlql8)
|
||||||
|
* [K9s v0 Demo](https://youtu.be/k7zseUhaXeU)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## The Command Line
|
## The Command Line
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
|
|
@ -80,13 +100,13 @@ k9s --context coolCtx
|
||||||
K9s uses aliases to navigate most K8s resources.
|
K9s uses aliases to navigate most K8s resources.
|
||||||
|
|
||||||
| Command | Result | Example |
|
| Command | Result | Example |
|
||||||
|-----------------------------|----------------------------------------------------|----------------------------|
|
| --------------------------- | -------------------------------------------------- | -------------------------- |
|
||||||
| `:`alias`<ENTER>` | View a Kubernetes resource aliases | `:po<ENTER>` |
|
| `:`alias`<ENTER>` | View a Kubernetes resource aliases | `:po<ENTER>` |
|
||||||
| `?` | Show keyboard shortcuts and help | |
|
| `?` | Show keyboard shortcuts and help | |
|
||||||
| `Ctrl-a` | Show all available resource alias | select+`<ENTER>` to view |
|
| `Ctrl-a` | Show all available resource alias | select+`<ENTER>` to view |
|
||||||
| `/`filter`ENTER` | Filter out a resource view given a filter | `/bumblebeetuna` |
|
| `/`filter`ENTER` | Filter out a resource view given a filter | `/bumblebeetuna` |
|
||||||
| `/`-l label-selector`ENTER` | Filter resource view by labels | `/-l app=fred` |
|
| `/`-l label-selector`ENTER` | Filter resource view by labels | `/-l app=fred` |
|
||||||
| `<Esc>` | Bails out of command mode | |
|
| `<Esc>` | Bails out of command/filter mode | |
|
||||||
| `d`,`v`, `e`, `l`,... | Key mapping to describe, view, edit, view logs,... | `d` (describes a resource) |
|
| `d`,`v`, `e`, `l`,... | Key mapping to describe, view, edit, view logs,... | `d` (describes a resource) |
|
||||||
| `:`ctx`<ENTER>` | To view and switch to another Kubernetes context | `:`+`ctx`+`<ENTER>` |
|
| `:`ctx`<ENTER>` | To view and switch to another Kubernetes context | `:`+`ctx`+`<ENTER>` |
|
||||||
| `Ctrl-d` | To delete a resource (TAB and ENTER to confirm) | |
|
| `Ctrl-d` | To delete a resource (TAB and ENTER to confirm) | |
|
||||||
|
|
@ -95,23 +115,6 @@ K9s uses aliases to navigate most K8s resources.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Demo Video
|
|
||||||
|
|
||||||
1. [K9s v0 Demo](https://youtu.be/k7zseUhaXeU)
|
|
||||||
2. [K9s v0.7.0 Features](https://youtu.be/83jYehwlql8)
|
|
||||||
|
|
||||||
|
|
||||||
## Screenshots
|
|
||||||
|
|
||||||
1. Pods
|
|
||||||
<img src="assets/screen_po.png"/>
|
|
||||||
1. Logs
|
|
||||||
<img src="assets/screen_logs.png"/>
|
|
||||||
1. Deployments
|
|
||||||
<img src="assets/screen_dp.png"/>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## K9s config file ($HOME/.k9s/config.yml)
|
## K9s config file ($HOME/.k9s/config.yml)
|
||||||
|
|
||||||
K9s keeps its configurations in a dot file in your home directory.
|
K9s keeps its configurations in a dot file in your home directory.
|
||||||
|
|
@ -151,6 +154,62 @@ K9s uses aliases to navigate most K8s resources.
|
||||||
active: dp
|
active: dp
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
## 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:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# $HOME/.k9s/alias.yml
|
||||||
|
alias:
|
||||||
|
pp: v1/pods
|
||||||
|
crb: rbac.authorization.k8s.io/v1/clusterrolebindings
|
||||||
|
```
|
||||||
|
|
||||||
|
Using this alias file, you can now type pp/crb to list pods, clusterrolebindings respectively.
|
||||||
|
|
||||||
|
---
|
||||||
|
## 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:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# $HOME/.k9s/plugin.yml
|
||||||
|
plugin:
|
||||||
|
fred:
|
||||||
|
shortCut: Ctrl-L
|
||||||
|
description: "Pod logs"
|
||||||
|
scopes:
|
||||||
|
- po
|
||||||
|
command: /usr/local/bin/kubectl
|
||||||
|
background: false
|
||||||
|
args:
|
||||||
|
- logs
|
||||||
|
- -f
|
||||||
|
- $NAME
|
||||||
|
- -n
|
||||||
|
- $NAMESPACE
|
||||||
|
- --context
|
||||||
|
- $CONTEXT
|
||||||
|
```
|
||||||
|
|
||||||
|
This defines a plugin for viewing logs on a selected pod using `CtrlL` mnemonic.
|
||||||
|
|
||||||
|
The shortcut option represents the command a user would type to activate the plugin. The command represents adhoc commands the plugin runs upon activation. The scopes defines a collection of views shortnames for which the plugin shortcut will be made available to the user.
|
||||||
|
|
||||||
|
K9s does provide additional enviroment variables for you to customize your plugins. Currently the available environment are as follows:
|
||||||
|
|
||||||
|
* `$NAMESPACE` -- the selected resource namespace
|
||||||
|
* `$NAME` -- the selected resource name
|
||||||
|
* `$KUBECONFIG` -- the KubeConfig location.
|
||||||
|
* `$CLUSTER` the active cluster name
|
||||||
|
* `$CONTEXT` the active context name
|
||||||
|
* `$USER` the active user
|
||||||
|
* `$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.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Benchmarking
|
## Benchmarking
|
||||||
|
|
@ -391,7 +450,7 @@ k9s:
|
||||||
Available color names are defined below:
|
Available color names are defined below:
|
||||||
|
|
||||||
| Color Names | | | | |
|
| Color Names | | | | |
|
||||||
|----------------------|----------------|------------------|-------------------|-----------------|
|
| -------------------- | -------------- | ---------------- | ----------------- | --------------- |
|
||||||
| black | maroon | green | olive | navy |
|
| black | maroon | green | olive | navy |
|
||||||
| purple | teal | silver | gray | red |
|
| purple | teal | silver | gray | red |
|
||||||
| lime | yellow | blue | fuchsia | aqua |
|
| lime | yellow | blue | fuchsia | aqua |
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ func (a *appView) Init(version string, rate int) {
|
||||||
main.AddItem(a.indicator(), 1, 1, false)
|
main.AddItem(a.indicator(), 1, 1, false)
|
||||||
main.AddItem(a.Frame(), 0, 10, true)
|
main.AddItem(a.Frame(), 0, 10, true)
|
||||||
main.AddItem(a.Crumbs(), 2, 1, false)
|
main.AddItem(a.Crumbs(), 2, 1, false)
|
||||||
main.AddItem(a.Flash(), 1, 1, false)
|
main.AddItem(a.Flash(), 2, 1, false)
|
||||||
a.toggleHeader(!a.Config.K9s.GetHeadless())
|
a.toggleHeader(!a.Config.K9s.GetHeadless())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -206,6 +206,9 @@ func (a *appView) refreshIndicator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *appView) switchNS(ns string) bool {
|
func (a *appView) switchNS(ns string) bool {
|
||||||
|
if ns == resource.AllNamespace {
|
||||||
|
ns = resource.AllNamespaces
|
||||||
|
}
|
||||||
if ns == a.Config.ActiveNamespace() {
|
if ns == a.Config.ActiveNamespace() {
|
||||||
log.Debug().Msgf("Namespace did not change %s", ns)
|
log.Debug().Msgf("Namespace did not change %s", ns)
|
||||||
return true
|
return true
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
"github.com/derailed/k9s/internal/resource"
|
"github.com/derailed/k9s/internal/resource"
|
||||||
|
|
@ -52,8 +51,6 @@ func (c *command) defaultCmd() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helpers...
|
|
||||||
|
|
||||||
var authRX = regexp.MustCompile(`\Apol\s([u|g|s]):([\w-:]+)\b`)
|
var authRX = regexp.MustCompile(`\Apol\s([u|g|s]):([\w-:]+)\b`)
|
||||||
|
|
||||||
func (c *command) isK9sCmd(cmd string) bool {
|
func (c *command) isK9sCmd(cmd string) bool {
|
||||||
|
|
@ -110,11 +107,6 @@ func (c *command) viewMetaFor(cmd string) (string, *viewer) {
|
||||||
|
|
||||||
// Exec the command by showing associated display.
|
// Exec the command by showing associated display.
|
||||||
func (c *command) run(cmd string) bool {
|
func (c *command) run(cmd string) bool {
|
||||||
log.Debug().Msgf("Running command %v", cmd)
|
|
||||||
defer func(t time.Time) {
|
|
||||||
log.Debug().Msgf("RUN CMD Elapsed %v", time.Since(t))
|
|
||||||
}(time.Now())
|
|
||||||
|
|
||||||
if c.isK9sCmd(cmd) {
|
if c.isK9sCmd(cmd) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -178,7 +170,7 @@ func (c *command) exec(gvr string, ns string, v ui.Igniter) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
g := k8s.GVR(gvr)
|
g := k8s.GVR(gvr)
|
||||||
c.app.Flash().Infof("Viewing resource %s...", g.ToR())
|
c.app.Flash().Infof("Viewing %s resource...", g.ToR())
|
||||||
log.Debug().Msgf("Running command %s", gvr)
|
log.Debug().Msgf("Running command %s", gvr)
|
||||||
c.app.Config.SetActiveView(g.ToR())
|
c.app.Config.SetActiveView(g.ToR())
|
||||||
c.app.Config.Save()
|
c.app.Config.Save()
|
||||||
|
|
|
||||||
|
|
@ -172,12 +172,11 @@ func (v *resourceView) enterCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
sel := v.masterPage().GetSelectedItem()
|
f := v.defaultEnter
|
||||||
if v.enterFn != nil {
|
if v.enterFn != nil {
|
||||||
v.enterFn(v.app, v.list.GetNamespace(), v.list.GetName(), sel)
|
f = v.enterFn
|
||||||
} else {
|
|
||||||
v.defaultEnter(v.list.GetNamespace(), v.list.GetName(), sel)
|
|
||||||
}
|
}
|
||||||
|
f(v.app, v.list.GetNamespace(), v.list.GetName(), v.masterPage().GetSelectedItem())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -220,7 +219,7 @@ func deletePortForward(ff map[string]forwarder, sel string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *resourceView) defaultEnter(ns, _, selection string) {
|
func (v *resourceView) defaultEnter(app *appView, ns, _, selection string) {
|
||||||
if !v.list.Access(resource.DescribeAccess) {
|
if !v.list.Access(resource.DescribeAccess) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -245,8 +244,8 @@ func (v *resourceView) describeCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
if !v.masterPage().RowSelected() {
|
if !v.masterPage().RowSelected() {
|
||||||
return evt
|
return evt
|
||||||
}
|
}
|
||||||
|
v.defaultEnter(v.app, v.list.GetNamespace(), v.list.GetName(), v.masterPage().GetSelectedItem())
|
||||||
|
|
||||||
v.defaultEnter(v.list.GetNamespace(), v.list.GetName(), v.masterPage().GetSelectedItem())
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -277,7 +276,6 @@ func (v *resourceView) editCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
return evt
|
return evt
|
||||||
}
|
}
|
||||||
|
|
||||||
kcfg := v.app.Conn().Config().Flags().KubeConfig
|
|
||||||
v.stopUpdates()
|
v.stopUpdates()
|
||||||
{
|
{
|
||||||
ns, po := namespaced(v.masterPage().GetSelectedItem())
|
ns, po := namespaced(v.masterPage().GetSelectedItem())
|
||||||
|
|
@ -286,8 +284,8 @@ func (v *resourceView) editCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
args = append(args, v.list.GetName())
|
args = append(args, v.list.GetName())
|
||||||
args = append(args, "-n", ns)
|
args = append(args, "-n", ns)
|
||||||
args = append(args, "--context", v.app.Config.K9s.CurrentContext)
|
args = append(args, "--context", v.app.Config.K9s.CurrentContext)
|
||||||
if kcfg != nil && *kcfg != "" {
|
if cfg := v.app.Conn().Config().Flags().KubeConfig; cfg != nil && *cfg != "" {
|
||||||
args = append(args, "--kubeconfig", *kcfg)
|
args = append(args, "--kubeconfig", *cfg)
|
||||||
}
|
}
|
||||||
runK(true, v.app, append(args, po)...)
|
runK(true, v.app, append(args, po)...)
|
||||||
}
|
}
|
||||||
|
|
@ -315,7 +313,7 @@ func (v *resourceView) switchNamespaceCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
|
|
||||||
v.app.switchNS(ns)
|
v.app.switchNS(ns)
|
||||||
v.setNamespace(ns)
|
v.setNamespace(ns)
|
||||||
v.app.Flash().Infof("Viewing `%s` namespace...", ns)
|
v.app.Flash().Infof("Viewing namespace `%s`...", ns)
|
||||||
v.refresh()
|
v.refresh()
|
||||||
v.masterPage().UpdateTitle()
|
v.masterPage().UpdateTitle()
|
||||||
v.masterPage().SelectRow(1, true)
|
v.masterPage().SelectRow(1, true)
|
||||||
|
|
@ -346,10 +344,6 @@ func (v *resourceView) refresh() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *resourceView) namespaceActions(aa ui.KeyActions) {
|
func (v *resourceView) namespaceActions(aa ui.KeyActions) {
|
||||||
ns, err := v.app.Conn().Config().CurrentNamespaceName()
|
|
||||||
if err == nil && ns != resource.AllNamespace {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !v.list.Access(resource.NamespaceAccess) {
|
if !v.list.Access(resource.NamespaceAccess) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -473,14 +467,22 @@ func (v *resourceView) defaultK9sEnv() K9sEnv {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
groups = []string{"n/a"}
|
groups = []string{"n/a"}
|
||||||
}
|
}
|
||||||
env := K9sEnv{
|
var cfg string
|
||||||
"NAMESPACE": ns,
|
kcfg := v.app.Conn().Config().Flags().KubeConfig
|
||||||
"NAME": n,
|
if kcfg != nil && *kcfg != "" {
|
||||||
"CONTEXT": ctx,
|
cfg = *kcfg
|
||||||
"CLUSTER": cluster,
|
|
||||||
"USER": user,
|
|
||||||
"GROUPS": strings.Join(groups, ","),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
env := K9sEnv{
|
||||||
|
"NAMESPACE": ns,
|
||||||
|
"NAME": n,
|
||||||
|
"CONTEXT": ctx,
|
||||||
|
"CLUSTER": cluster,
|
||||||
|
"USER": user,
|
||||||
|
"GROUPS": strings.Join(groups, ","),
|
||||||
|
"KUBECONFIG": cfg,
|
||||||
|
}
|
||||||
|
|
||||||
row := v.masterPage().GetRow()
|
row := v.masterPage().GetRow()
|
||||||
for i, r := range row {
|
for i, r := range row {
|
||||||
env["COL"+strconv.Itoa(i)] = r
|
env["COL"+strconv.Itoa(i)] = r
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue