From f335269ab45f800ef1543606122353198386dba0 Mon Sep 17 00:00:00 2001 From: c-bata Date: Sat, 2 Nov 2019 15:36:03 +0900 Subject: [PATCH 1/4] Suggest container names from cached pods --- kube/completer.go | 8 ++++++++ kube/resource.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/kube/completer.go b/kube/completer.go index 21d4da9..35fae22 100644 --- a/kube/completer.go +++ b/kube/completer.go @@ -149,6 +149,12 @@ func (c *Completer) completeOptionArguments(d prompt.Document) ([]prompt.Suggest d.GetWordBeforeCursor(), true, ), true + case "-c", "--container": + return prompt.FilterHasPrefix( + getContainerNamesFromCachedPods(c.client, c.namespace), + d.GetWordBeforeCursor(), + true, + ), true } } return []prompt.Suggest{}, false @@ -170,6 +176,8 @@ func excludeOptions(args []string) ([]string, bool) { "--user", "--output", "-o", + "--container", + "-c", } var skipNextArg bool diff --git a/kube/resource.go b/kube/resource.go index c40829b..ecd57c1 100644 --- a/kube/resource.go +++ b/kube/resource.go @@ -242,6 +242,34 @@ func getPortsFromPodName(namespace string, podName string) []prompt.Suggest { return suggests } +func getContainerNamesFromCachedPods(client *kubernetes.Clientset, namespace string) []prompt.Suggest { + go fetchPods(client, namespace) + + x, ok := podList.Load(namespace) + if !ok { + return []prompt.Suggest{} + } + l, ok := x.(*corev1.PodList) + if !ok || len(l.Items) == 0 { + return []prompt.Suggest{} + } + // container name -> pod name + set := make(map[string]string, len(l.Items)) + for i := range l.Items { + for j := range l.Items[i].Spec.Containers { + set[l.Items[i].Spec.Containers[j].Name] = l.Items[i].Name + } + } + s := make([]prompt.Suggest, 0, len(set)) + for key := range set { + s = append(s, prompt.Suggest{ + Text: key, + Description: "Pod Name: " + set[key], + }) + } + return s +} + /* Daemon Sets */ var ( From 8c7547e0b90cd99ab782d49aaa4132962c8bd93c Mon Sep 17 00:00:00 2001 From: c-bata Date: Sat, 2 Nov 2019 22:53:13 +0900 Subject: [PATCH 2/4] Fix container support --- kube/completer.go | 4 ++-- kube/resource.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/kube/completer.go b/kube/completer.go index 35fae22..d589f00 100644 --- a/kube/completer.go +++ b/kube/completer.go @@ -4,7 +4,7 @@ import ( "os" "strings" - prompt "github.com/c-bata/go-prompt" + "github.com/c-bata/go-prompt" "github.com/c-bata/go-prompt/completer" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -139,7 +139,7 @@ func (c *Completer) completeOptionArguments(d prompt.Document) ([]prompt.Suggest switch cmd { case "get", "describe", "create", "delete", "replace", "patch", "edit", "apply", "expose", "rolling-update", "rollout", - "label", "annotate", "scale", "convert", "autoscale", "top": + "label", "annotate", "scale", "convert", "autoscale", "top", "logs": switch option { case "-f", "--filename": return yamlFileCompleter.Complete(d), true diff --git a/kube/resource.go b/kube/resource.go index ecd57c1..f4881fb 100644 --- a/kube/resource.go +++ b/kube/resource.go @@ -263,7 +263,7 @@ func getContainerNamesFromCachedPods(client *kubernetes.Clientset, namespace str s := make([]prompt.Suggest, 0, len(set)) for key := range set { s = append(s, prompt.Suggest{ - Text: key, + Text: key, Description: "Pod Name: " + set[key], }) } From 04dfaecae8ca8bd579bece3d82406b5015128aa6 Mon Sep 17 00:00:00 2001 From: c-bata Date: Sat, 2 Nov 2019 23:10:33 +0900 Subject: [PATCH 3/4] Support container suggestions of selected pod --- go.mod | 2 ++ kube/completer.go | 24 +++++++++++++++++++++++- kube/resource.go | 17 +++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index b946162..bb62268 100644 --- a/go.mod +++ b/go.mod @@ -16,3 +16,5 @@ require ( k8s.io/apimachinery v0.0.0-20190612205821-1799e75a0719 k8s.io/client-go v12.0.0+incompatible ) + +go 1.13 diff --git a/kube/completer.go b/kube/completer.go index d589f00..d72e5a4 100644 --- a/kube/completer.go +++ b/kube/completer.go @@ -150,8 +150,16 @@ func (c *Completer) completeOptionArguments(d prompt.Document) ([]prompt.Suggest true, ), true case "-c", "--container": + + cmdArgs := getCommandArgs(d) + var suggestions []prompt.Suggest + if cmdArgs == nil || len(cmdArgs) < 2 { + suggestions = getContainerNamesFromCachedPods(c.client, c.namespace) + } else { + suggestions = getContainerName(c.client, c.namespace, cmdArgs[1]) + } return prompt.FilterHasPrefix( - getContainerNamesFromCachedPods(c.client, c.namespace), + suggestions, d.GetWordBeforeCursor(), true, ), true @@ -160,6 +168,20 @@ func (c *Completer) completeOptionArguments(d prompt.Document) ([]prompt.Suggest return []prompt.Suggest{}, false } +func getCommandArgs(d prompt.Document) []string { + args := strings.Split(d.TextBeforeCursor(), " ") + + // If PIPE is in text before the cursor, returns empty. + for i := range args { + if args[i] == "|" { + return nil + } + } + + commandArgs, _ := excludeOptions(args) + return commandArgs +} + func excludeOptions(args []string) ([]string, bool) { l := len(args) filtered := make([]string, 0, l) diff --git a/kube/resource.go b/kube/resource.go index f4881fb..a2d6ce2 100644 --- a/kube/resource.go +++ b/kube/resource.go @@ -270,6 +270,23 @@ func getContainerNamesFromCachedPods(client *kubernetes.Clientset, namespace str return s } +func getContainerName(client *kubernetes.Clientset, namespace string, podName string) []prompt.Suggest { + go fetchPods(client, namespace) + + pod, found := getPod(namespace, podName) + if !found { + return []prompt.Suggest{} + } + s := make([]prompt.Suggest, len(pod.Spec.Containers)) + for i := range pod.Spec.Containers { + s[i] = prompt.Suggest{ + Text: pod.Spec.Containers[i].Name, + Description: "", + } + } + return s +} + /* Daemon Sets */ var ( From 37f5b4c92c33848ceebdd9766ab126603fc877c0 Mon Sep 17 00:00:00 2001 From: c-bata Date: Sat, 2 Nov 2019 23:26:11 +0900 Subject: [PATCH 4/4] Support container suggestions on some commands --- kube/completer.go | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/kube/completer.go b/kube/completer.go index d72e5a4..50d4c82 100644 --- a/kube/completer.go +++ b/kube/completer.go @@ -136,21 +136,30 @@ func (c *Completer) completeOptionArguments(d prompt.Document) ([]prompt.Suggest if !found { return []prompt.Suggest{}, false } + + // namespace + if option == "-n" || option == "--namespace" { + return prompt.FilterHasPrefix( + getNameSpaceSuggestions(c.namespaceList), + d.GetWordBeforeCursor(), + true, + ), true + } + + // filename switch cmd { case "get", "describe", "create", "delete", "replace", "patch", "edit", "apply", "expose", "rolling-update", "rollout", - "label", "annotate", "scale", "convert", "autoscale", "top", "logs": - switch option { - case "-f", "--filename": + "label", "annotate", "scale", "convert", "autoscale", "top": + if option == "-f" || option == "--filename" { return yamlFileCompleter.Complete(d), true - case "-n", "--namespace": - return prompt.FilterHasPrefix( - getNameSpaceSuggestions(c.namespaceList), - d.GetWordBeforeCursor(), - true, - ), true - case "-c", "--container": + } + } + // container + switch cmd { + case "exec", "logs", "run", "attach", "port-forward", "cp": + if option == "-c" || option == "--container" { cmdArgs := getCommandArgs(d) var suggestions []prompt.Suggest if cmdArgs == nil || len(cmdArgs) < 2 {