diff --git a/pkg/kubectl/resource_printer.go b/pkg/kubectl/resource_printer.go index 2e56fd77c86..79321044a55 100644 --- a/pkg/kubectl/resource_printer.go +++ b/pkg/kubectl/resource_printer.go @@ -218,7 +218,7 @@ func (h *HumanReadablePrinter) validatePrintHandlerFunc(printFunc reflect.Value) var podColumns = []string{"POD", "IP", "CONTAINER(S)", "IMAGE(S)", "HOST", "LABELS", "STATUS"} var replicationControllerColumns = []string{"CONTROLLER", "CONTAINER(S)", "IMAGE(S)", "SELECTOR", "REPLICAS"} var serviceColumns = []string{"NAME", "LABELS", "SELECTOR", "IP", "PORT"} -var minionColumns = []string{"NAME", "LABELS"} +var minionColumns = []string{"NAME", "LABELS", "STATUS"} var statusColumns = []string{"STATUS"} var eventColumns = []string{"TIME", "NAME", "KIND", "SUBOBJECT", "REASON", "SOURCE", "MESSAGE"} @@ -347,7 +347,26 @@ func printServiceList(list *api.ServiceList, w io.Writer) error { } func printMinion(minion *api.Node, w io.Writer) error { - _, err := fmt.Fprintf(w, "%s\t%s\n", minion.Name, formatLabels(minion.Labels)) + conditionMap := make(map[api.NodeConditionKind]*api.NodeCondition) + NodeAllConditions := []api.NodeConditionKind{api.NodeReady, api.NodeReachable} + for i := range minion.Status.Conditions { + cond := minion.Status.Conditions[i] + conditionMap[cond.Kind] = &cond + } + var status []string + for _, validCondition := range NodeAllConditions { + if condition, ok := conditionMap[validCondition]; ok { + if condition.Status == api.ConditionFull { + status = append(status, string(condition.Kind)) + } else { + status = append(status, "Not"+string(condition.Kind)) + } + } + } + if len(status) == 0 { + status = append(status, "Unknown") + } + _, err := fmt.Fprintf(w, "%s\t%s\t%s\n", minion.Name, formatLabels(minion.Labels), strings.Join(status, ",")) return err } diff --git a/pkg/kubectl/resource_printer_test.go b/pkg/kubectl/resource_printer_test.go index 8603cedb0c2..b33e5d60bfe 100644 --- a/pkg/kubectl/resource_printer_test.go +++ b/pkg/kubectl/resource_printer_test.go @@ -22,6 +22,7 @@ import ( "fmt" "io" "reflect" + "strings" "testing" "time" @@ -506,3 +507,78 @@ func TestPrintEventsResultSorted(t *testing.T) { out := buffer.String() VerifyDatesInOrder(out, "\n" /* rowDelimiter */, " " /* columnDelimiter */, t) } + +func TestPrintMinionStatus(t *testing.T) { + printer := NewHumanReadablePrinter(false) + table := []struct { + minion api.Node + status string + }{ + { + minion: api.Node{ + ObjectMeta: api.ObjectMeta{Name: "foo1"}, + Status: api.NodeStatus{Conditions: []api.NodeCondition{{Kind: api.NodeReady, Status: api.ConditionFull}}}, + }, + status: "Ready", + }, + { + minion: api.Node{ + ObjectMeta: api.ObjectMeta{Name: "foo2"}, + Status: api.NodeStatus{Conditions: []api.NodeCondition{ + {Kind: api.NodeReady, Status: api.ConditionFull}, + {Kind: api.NodeReachable, Status: api.ConditionFull}}}, + }, + status: "Ready,Reachable", + }, + { + minion: api.Node{ + ObjectMeta: api.ObjectMeta{Name: "foo3"}, + Status: api.NodeStatus{Conditions: []api.NodeCondition{ + {Kind: api.NodeReady, Status: api.ConditionFull}, + {Kind: api.NodeReady, Status: api.ConditionFull}}}, + }, + status: "Ready", + }, + { + minion: api.Node{ + ObjectMeta: api.ObjectMeta{Name: "foo4"}, + Status: api.NodeStatus{Conditions: []api.NodeCondition{{Kind: api.NodeReady, Status: api.ConditionNone}}}, + }, + status: "NotReady", + }, + { + minion: api.Node{ + ObjectMeta: api.ObjectMeta{Name: "foo5"}, + Status: api.NodeStatus{Conditions: []api.NodeCondition{{Kind: "InvalidValue", Status: api.ConditionFull}}}, + }, + status: "Unknown", + }, + { + minion: api.Node{ + ObjectMeta: api.ObjectMeta{Name: "foo6"}, + Status: api.NodeStatus{Conditions: []api.NodeCondition{{}}}, + }, + status: "Unknown", + }, + } + + for _, test := range table { + buffer := &bytes.Buffer{} + err := printer.PrintObj(&test.minion, buffer) + if err != nil { + t.Fatalf("An error occurred printing Minion: %#v", err) + } + if !contains(strings.Fields(buffer.String()), test.status) { + t.Fatalf("Expect printing minion %s with status %#v, got: %#v", test.minion.Name, test.status, buffer.String()) + } + } +} + +func contains(fields []string, field string) bool { + for _, v := range fields { + if v == field { + return true + } + } + return false +}