diff --git a/README.md b/README.md index 0255a17..3ce8079 100644 --- a/README.md +++ b/README.md @@ -42,8 +42,6 @@ of asking systemd to list all services on a node. :) kubectl d get -N <nodename> ``` -NOTE: `-o` is not yet implemented for `get`. - Or you can delete the pod from a daemonset on a specific node ```bash diff --git a/cmd/get.go b/cmd/get.go index fb10038..fa0f218 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -1,20 +1,26 @@ package cmd import ( + "encoding/json" + "gopkg.in/yaml.v3" "fmt" "github.com/spf13/cobra" "io" "os" + "strings" + "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/cli-runtime/pkg/printers" - + v1 "k8s.io/api/core/v1" ) func newDshGetCommand( out io.Writer, namespace *string, nodeName *string, ) *cobra.Command { + var output string + dshGet := &dshCmd{ out: out, } @@ -28,15 +34,19 @@ func newDshGetCommand( if len(args) == 1 { ds = args[0] } - return dshGet.getPods(*namespace, ds, *nodeName) + return dshGet.getPods(*namespace, ds, *nodeName, output) }, } + cmd.Flags().StringVarP( + &output, "output", "o", "", "Output format. One of wide, json, yaml.", + ) + return cmd } func (sv *dshCmd) getPods( - namespace string, ds string, nodeName string, + namespace string, ds string, nodeName string, output string, ) error { clientset, err := getClientSet() if err != nil { @@ -53,32 +63,112 @@ func (sv *dshCmd) getPods( return nil } - printer := printers.NewTablePrinter(printers.PrintOptions{}) - table := metav1.Table{ - ColumnDefinitions: []metav1.TableColumnDefinition{ - {Name: "NAME"}, - {Name: "READY"}, - {Name: "STATUS"}, - {Name: "RESTARTS"}, - {Name: "AGE"}, - }, + var table metav1.Table + var printer printers.ResourcePrinter + if output == "" || output == "wide" { + printer = printers.NewTablePrinter(printers.PrintOptions{}) + if output == "" { + table = metav1.Table{ + ColumnDefinitions: []metav1.TableColumnDefinition{ + {Name: "NAME"}, + {Name: "READY"}, + {Name: "STATUS"}, + {Name: "RESTARTS"}, + {Name: "AGE"}, + }, + } + } else if output == "wide" { + // when I append(table.ColumnDefinitions, ...) I get + // syntax errors. No idea why. + table = metav1.Table{ + ColumnDefinitions: []metav1.TableColumnDefinition{ + {Name: "NAME"}, + {Name: "READY"}, + {Name: "STATUS"}, + {Name: "RESTARTS"}, + {Name: "AGE"}, + {Name: "IP"}, + {Name: "NODE"}, + {Name: "NOMINATED NODE"}, + {Name: "READINESS GATES"}, + }, + } + } } for _, pod := range pods { - readyCount, totalCount := - countReadyContainers(pod.Status.ContainerStatuses) - row := metav1.TableRow{ - Cells: []interface{}{ - pod.Name, - fmt.Sprintf("%d/%d", readyCount, totalCount), - string(pod.Status.Phase), - fmt.Sprintf("%d", pod.Status.ContainerStatuses[0].RestartCount), - pod.ObjectMeta.CreationTimestamp.Time.String(), - }, + switch output { + case "json": + jsonData, err := json.MarshalIndent(pod, "", " ") + if err != nil { + return err + } + fmt.Println(string(jsonData)) + case "yaml": + yamlData, err := yaml.Marshal(pod) + if err != nil { + return err + } + fmt.Println(string(yamlData)) + case "", "wide": + readyCount, totalCount := + countReadyContainers(pod.Status.ContainerStatuses) + age := time.Since(pod.ObjectMeta.CreationTimestamp.Time).Round( + time.Second, + ) + row := metav1.TableRow{ + Cells: []interface{}{ + pod.Name, + fmt.Sprintf("%d/%d", readyCount, totalCount), + string(pod.Status.Phase), + fmt.Sprintf( + "%d", + pod.Status.ContainerStatuses[0].RestartCount, + ), + age, + }, + } + if (output == "wide") { + nominatedNode := "<none>" + if pod.Status.NominatedNodeName != "" { + nominatedNode = pod.Status.NominatedNodeName + } + var readinessGates []string + ready := false + for _, condition := range pod.Status.Conditions { + if condition.Type == v1.PodReady && + condition.Status == v1.ConditionTrue { + ready = true + break + } + readinessGates = append( + readinessGates, + string(condition.Type), + ) + } + var readinessGatesStr string + if ready || len(readinessGates) == 0 { + readinessGatesStr = "<none>" + } else { + readinessGatesStr = strings.Join(readinessGates, ", ") + } + + row.Cells = append( + row.Cells, + pod.Status.PodIP, + pod.Spec.NodeName, + nominatedNode, + readinessGatesStr, + ) + } + + table.Rows = append(table.Rows, row) } - table.Rows = append(table.Rows, row) } - err = printer.PrintObj(&table, os.Stdout) - return err + if output == "" || output == "wide" { + err = printer.PrintObj(&table, os.Stdout) + return err + } + return nil } diff --git a/go.mod b/go.mod index a5923fa..b3b046c 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.21.4 require ( github.com/spf13/cobra v1.8.0 golang.org/x/text v0.14.0 + gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.29.2 k8s.io/apimachinery v0.29.2 k8s.io/cli-runtime v0.29.2 @@ -55,7 +56,6 @@ require ( google.golang.org/protobuf v1.31.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.110.1 // indirect k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect