feat: kubectl namespace

This commit is contained in:
TravisTX 2021-02-10 19:23:00 -07:00 committed by Jan De Dobbeleer
parent bf44a446be
commit 731ebf6f9a
3 changed files with 96 additions and 37 deletions

View file

@ -6,7 +6,7 @@ sidebar_label: Kubectl
## What
Display the currently active Kubernetes context name.
Display the currently active Kubernetes context name and namespace name.
## Sample Configuration
@ -18,7 +18,27 @@ Display the currently active Kubernetes context name.
"foreground": "#000000",
"background": "#ebcc34",
"properties": {
"prefix": " \uFD31 "
"prefix": " \uFD31 ",
"template": "{{.Context}}{{if .Namespace}} :: {{.Namespace}}{{end}}"
}
}
```
## Properties
- template: `string` - A go [text/template][go-text-template] template utilizing the properties below.
Defaults to `{{.Context}}{{if .Namespace}} :: {{.Namespace}}{{end}}`
## Template Properties
- `.Context`: `string` - the current kubectl context
- `.Namespace`: `string` - the current kubectl namespace
## Tips
It is common for the Kubernetes "default" namespace to be used when no namespace is provided. If you want your prompt to
render an empty current namespace using the word "default", you can use something like this for the template:
`{{.Context}} :: {{if .Namespace}}{{.Namespace}}{{else}}default{{end}}`
[go-text-template]: https://golang.org/pkg/text/template/

View file

@ -1,13 +1,23 @@
package main
import (
"strings"
)
type kubectl struct {
props *properties
env environmentInfo
contextName string
props *properties
env environmentInfo
Context string
Namespace string
}
func (k *kubectl) string() string {
return k.contextName
segmentTemplate := k.props.getString(SegmentTemplate, "{{.Context}}{{if .Namespace}} :: {{.Namespace}}{{end}}")
template := &textTemplate{
Template: segmentTemplate,
Context: k,
}
return template.render()
}
func (k *kubectl) init(props *properties, env environmentInfo) {
@ -20,6 +30,15 @@ func (k *kubectl) enabled() bool {
if !k.env.hasCommand(cmd) {
return false
}
k.contextName, _ = k.env.runCommand(cmd, "config", "current-context")
return k.contextName != ""
result, err := k.env.runCommand(cmd, "config", "view", "--minify", "--output", "jsonpath={..current-context},{..namespace}")
if err != nil {
k.Context = "KUBECTL ERR"
k.Namespace = k.Context
return true
}
values := strings.Split(result, ",")
k.Context = values[0]
k.Namespace = values[1]
return k.Context != ""
}

View file

@ -7,45 +7,65 @@ import (
)
type kubectlArgs struct {
enabled bool
contextName string
kubectlExists bool
kubectlErr bool
template string
context string
namespace string
}
func bootStrapKubectlTest(args *kubectlArgs) *kubectl {
env := new(MockedEnvironment)
env.On("hasCommand", "kubectl").Return(args.enabled)
env.On("runCommand", "kubectl", []string{"config", "current-context"}).Return(args.contextName, nil)
env.On("hasCommand", "kubectl").Return(args.kubectlExists)
kubectlOut := args.context + "," + args.namespace
var kubectlErr error = nil
if args.kubectlErr {
kubectlErr = &commandError{
err: "oops",
exitCode: 1,
}
}
env.On("runCommand", "kubectl", []string{"config", "view", "--minify", "--output", "jsonpath={..current-context},{..namespace}"}).Return(kubectlOut, kubectlErr)
k := &kubectl{
env: env,
props: &properties{},
env: env,
props: &properties{
values: map[Property]interface{}{
SegmentTemplate: args.template,
},
},
}
return k
}
func TestKubectlWriterDisabled(t *testing.T) {
args := &kubectlArgs{
enabled: false,
func TestKubectlSegment(t *testing.T) {
standardTemplate := "{{.Context}}{{if .Namespace}} :: {{.Namespace}}{{end}}"
cases := []struct {
Case string
Template string
KubectlExists bool
Context string
Namespace string
KubectlErr bool
ExpectedEnabled bool
ExpectedString string
}{
{Case: "disabled", Template: standardTemplate, KubectlExists: false, Context: "aaa", Namespace: "bbb", ExpectedString: "", ExpectedEnabled: false},
{Case: "normal", Template: standardTemplate, KubectlExists: true, Context: "aaa", Namespace: "bbb", ExpectedString: "aaa :: bbb", ExpectedEnabled: true},
{Case: "no namespace", Template: standardTemplate, KubectlExists: true, Context: "aaa", Namespace: "", ExpectedString: "aaa", ExpectedEnabled: true},
{Case: "kubectl error", Template: standardTemplate, KubectlExists: true, Context: "aaa", Namespace: "bbb", KubectlErr: true,
ExpectedString: "KUBECTL ERR :: KUBECTL ERR", ExpectedEnabled: true},
}
kubectl := bootStrapKubectlTest(args)
assert.False(t, kubectl.enabled())
}
func TestKubectlEnabled(t *testing.T) {
expected := "context-name"
args := &kubectlArgs{
enabled: true,
contextName: expected,
for _, tc := range cases {
args := &kubectlArgs{
kubectlExists: tc.KubectlExists,
template: tc.Template,
context: tc.Context,
namespace: tc.Namespace,
kubectlErr: tc.KubectlErr,
}
kubectl := bootStrapKubectlTest(args)
assert.Equal(t, tc.ExpectedEnabled, kubectl.enabled(), tc.Case)
assert.Equal(t, tc.ExpectedString, kubectl.string(), tc.Case)
}
kubectl := bootStrapKubectlTest(args)
assert.True(t, kubectl.enabled())
assert.Equal(t, expected, kubectl.string())
}
func TestKubectlNoContext(t *testing.T) {
args := &kubectlArgs{
enabled: true,
contextName: "",
}
kubectl := bootStrapKubectlTest(args)
assert.False(t, kubectl.enabled())
}