mirror of
https://github.com/ahmetb/kubectx.git
synced 2025-07-19 01:27:45 +00:00
Add filtering contexts
This commit is contained in:
parent
561793c356
commit
c44c9306fd
@ -40,6 +40,16 @@ func parseArgs(argv []string) Op {
|
||||
return ListOp{}
|
||||
}
|
||||
|
||||
if argv[0] == "--list" || argv[0] == "-l" {
|
||||
if len(argv) == 1 {
|
||||
return ListOp{}
|
||||
}
|
||||
if filters, ok := parseFilterSyntax(argv[1:]); ok {
|
||||
return ListOp{Filters: filters}
|
||||
}
|
||||
return UnsupportedOp{Err: fmt.Errorf("'-l' filters must use A=B format")}
|
||||
}
|
||||
|
||||
if argv[0] == "-d" {
|
||||
if len(argv) == 1 {
|
||||
if cmdutil.IsInteractiveMode(os.Stdout) {
|
||||
|
@ -39,6 +39,21 @@ func Test_parseArgs_new(t *testing.T) {
|
||||
{name: "help long form",
|
||||
args: []string{"--help"},
|
||||
want: HelpOp{}},
|
||||
{name: "list shorthand",
|
||||
args: []string{"-l"},
|
||||
want: ListOp{}},
|
||||
{name: "list long form",
|
||||
args: []string{"--list"},
|
||||
want: ListOp{}},
|
||||
{name: "list long form filters",
|
||||
args: []string{"--list", "cluster=cl"},
|
||||
want: ListOp{Filters: map[string]string{"cluster": "cl"}}},
|
||||
{name: "list long form filters - wrong syntax",
|
||||
args: []string{"--list", "cluster-cl"},
|
||||
want: UnsupportedOp{fmt.Errorf("'-l' filters must use A=B format")}},
|
||||
{name: "current long form",
|
||||
args: []string{"--current"},
|
||||
want: CurrentOp{}},
|
||||
{name: "current shorthand",
|
||||
args: []string{"-c"},
|
||||
want: CurrentOp{}},
|
||||
|
@ -88,7 +88,7 @@ func (op InteractiveDeleteOp) Run(_, stderr io.Writer) error {
|
||||
}
|
||||
kc.Close()
|
||||
|
||||
if len(kc.ContextNames()) == 0 {
|
||||
if len(kc.ContextNames(nil)) == 0 {
|
||||
return errors.New("no contexts found in config")
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"facette.io/natsort"
|
||||
"github.com/pkg/errors"
|
||||
@ -27,9 +28,29 @@ import (
|
||||
)
|
||||
|
||||
// ListOp describes listing contexts.
|
||||
type ListOp struct{}
|
||||
type ListOp struct {
|
||||
Filters map[string]string
|
||||
}
|
||||
|
||||
func (_ ListOp) Run(stdout, stderr io.Writer) error {
|
||||
// parseFilterSyntax parses multiple A=B form into a map[A]=B and returns
|
||||
// whether it is parsed correctly.
|
||||
func parseFilterSyntax(v []string) (map[string]string, bool) {
|
||||
m := make(map[string]string)
|
||||
for _, vv := range v {
|
||||
s := strings.Split(vv, "=")
|
||||
if len(s) != 2 {
|
||||
return nil, false
|
||||
}
|
||||
key, value := s[0], s[1]
|
||||
if key == "" || value == "" {
|
||||
return nil, false
|
||||
}
|
||||
m[key] = value
|
||||
}
|
||||
return m, true
|
||||
}
|
||||
|
||||
func (op ListOp) Run(stdout, stderr io.Writer) error {
|
||||
kc := new(kubeconfig.Kubeconfig).WithLoader(kubeconfig.DefaultLoader)
|
||||
defer kc.Close()
|
||||
if err := kc.Parse(); err != nil {
|
||||
@ -40,7 +61,7 @@ func (_ ListOp) Run(stdout, stderr io.Writer) error {
|
||||
return errors.Wrap(err, "kubeconfig error")
|
||||
}
|
||||
|
||||
ctxs := kc.ContextNames()
|
||||
ctxs := kc.ContextNames(op.Filters)
|
||||
natsort.Sort(ctxs)
|
||||
|
||||
cur := kc.GetCurrentContext()
|
||||
|
@ -44,7 +44,7 @@ func (k *Kubeconfig) contextNode(name string) (*yaml.Node, error) {
|
||||
return nil, errors.Errorf("context with name \"%s\" not found", name)
|
||||
}
|
||||
|
||||
func (k *Kubeconfig) ContextNames() []string {
|
||||
func (k *Kubeconfig) ContextNames(filters map[string]string) []string {
|
||||
contexts := valueOf(k.rootNode, "contexts")
|
||||
if contexts == nil {
|
||||
return nil
|
||||
@ -54,8 +54,19 @@ func (k *Kubeconfig) ContextNames() []string {
|
||||
}
|
||||
|
||||
var ctxNames []string
|
||||
ctxLoop:
|
||||
for _, ctx := range contexts.Content {
|
||||
nameVal := valueOf(ctx, "name")
|
||||
for k, v := range filters {
|
||||
ctxVal := valueOf(ctx, "context")
|
||||
if ctxVal == nil {
|
||||
continue ctxLoop
|
||||
}
|
||||
vVal := valueOf(ctxVal, k)
|
||||
if vVal == nil || vVal.Value != v {
|
||||
continue ctxLoop
|
||||
}
|
||||
}
|
||||
if nameVal != nil {
|
||||
ctxNames = append(ctxNames, nameVal.Value)
|
||||
}
|
||||
@ -64,7 +75,7 @@ func (k *Kubeconfig) ContextNames() []string {
|
||||
}
|
||||
|
||||
func (k *Kubeconfig) ContextExists(name string) bool {
|
||||
ctxNames := k.ContextNames()
|
||||
ctxNames := k.ContextNames(nil)
|
||||
for _, v := range ctxNames {
|
||||
if v == name {
|
||||
return true
|
||||
|
@ -33,20 +33,39 @@ func TestKubeconfig_ContextNames(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ctx := kc.ContextNames()
|
||||
ctx := kc.ContextNames(nil)
|
||||
expected := []string{"abc", "def", "ghi"}
|
||||
if diff := cmp.Diff(expected, ctx); diff != "" {
|
||||
t.Fatalf("%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKubeconfig_ContextNames_Filtered(t *testing.T) {
|
||||
tl := WithMockKubeconfigLoader(
|
||||
testutil.KC().WithCtxs(
|
||||
testutil.Ctx("abc").Ns("ns1"),
|
||||
testutil.Ctx("def"),
|
||||
testutil.Ctx("ghi").Ns("ns2"),
|
||||
).Set("field1", map[string]string{"bar": "zoo"}).ToYAML(t))
|
||||
kc := new(Kubeconfig).WithLoader(tl)
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ctx := kc.ContextNames(map[string]string{"namespace": "ns2"})
|
||||
expected := []string{"ghi"}
|
||||
if diff := cmp.Diff(expected, ctx); diff != "" {
|
||||
t.Fatalf("%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKubeconfig_ContextNames_noContextsEntry(t *testing.T) {
|
||||
tl := WithMockKubeconfigLoader(`a: b`)
|
||||
kc := new(Kubeconfig).WithLoader(tl)
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ctx := kc.ContextNames()
|
||||
ctx := kc.ContextNames(nil)
|
||||
var expected []string = nil
|
||||
if diff := cmp.Diff(expected, ctx); diff != "" {
|
||||
t.Fatalf("%s", diff)
|
||||
@ -59,7 +78,7 @@ func TestKubeconfig_ContextNames_nonArrayContextsEntry(t *testing.T) {
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ctx := kc.ContextNames()
|
||||
ctx := kc.ContextNames(nil)
|
||||
var expected []string = nil
|
||||
if diff := cmp.Diff(expected, ctx); diff != "" {
|
||||
t.Fatalf("%s", diff)
|
||||
|
Loading…
Reference in New Issue
Block a user