From 7df60d6b640c263996e60286ff5497a2a0b3d33b Mon Sep 17 00:00:00 2001 From: juanvallejo Date: Wed, 29 Jun 2016 18:02:08 -0400 Subject: [PATCH] display resource type as part of its name --- hack/verify-flags/known-flags.txt | 1 + pkg/kubectl/cmd/get.go | 33 ++++- pkg/kubectl/kubectl.go | 13 ++ pkg/kubectl/resource_printer.go | 189 ++++++++++++++++++++++++--- pkg/kubectl/resource_printer_test.go | 44 +++++-- 5 files changed, 250 insertions(+), 30 deletions(-) diff --git a/hack/verify-flags/known-flags.txt b/hack/verify-flags/known-flags.txt index 2bc21c823bf..0a9ce63dd27 100644 --- a/hack/verify-flags/known-flags.txt +++ b/hack/verify-flags/known-flags.txt @@ -423,6 +423,7 @@ session-affinity setup-node show-all show-events +show-kind show-labels shutdown-fd shutdown-fifo diff --git a/pkg/kubectl/cmd/get.go b/pkg/kubectl/cmd/get.go index 3aab52515f1..18d38e89d97 100644 --- a/pkg/kubectl/cmd/get.go +++ b/pkg/kubectl/cmd/get.go @@ -103,6 +103,7 @@ func NewCmdGet(f *cmdutil.Factory, out io.Writer) *cobra.Command { cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on") cmd.Flags().BoolP("watch", "w", false, "After listing/getting the requested object, watch for changes.") cmd.Flags().Bool("watch-only", false, "Watch for changes to the requested object(s), without listing/getting first.") + cmd.Flags().Bool("show-kind", false, "If present, list the resource type for the requested object(s).") cmd.Flags().Bool("all-namespaces", false, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.") cmd.Flags().StringSliceP("label-columns", "L", []string{}, "Accepts a comma separated list of labels that are going to be presented as columns. Names are case-sensitive. You can also use multiple flag statements like -L label1 -L label2...") cmd.Flags().Bool("export", false, "If true, use 'export' for the resources. Exported resources are stripped of cluster-specific information.") @@ -118,6 +119,7 @@ func NewCmdGet(f *cmdutil.Factory, out io.Writer) *cobra.Command { func RunGet(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, options *GetOptions) error { selector := cmdutil.GetFlagString(cmd, "selector") allNamespaces := cmdutil.GetFlagBool(cmd, "all-namespaces") + allKinds := cmdutil.GetFlagBool(cmd, "show-kind") mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd)) cmdNamespace, enforceNamespace, err := f.DefaultNamespace() @@ -294,9 +296,29 @@ func RunGet(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string // use the default printer for each object printer = nil var lastMapping *meta.RESTMapping + var withKind bool = allKinds w := kubectl.GetNewTabWriter(out) defer w.Flush() + // determine if printing multiple kinds of + // objects and enforce "show-kinds" flag if so + for ix := range objs { + var mapping *meta.RESTMapping + if sorter != nil { + mapping = infos[sorter.OriginalPosition(ix)].Mapping + } else { + mapping = infos[ix].Mapping + } + + // display "kind" column only if we have mixed resources + if lastMapping != nil && mapping.Resource != lastMapping.Resource { + withKind = true + } + lastMapping = mapping + } + + lastMapping = nil + for ix := range objs { var mapping *meta.RESTMapping var original runtime.Object @@ -315,7 +337,16 @@ func RunGet(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string } lastMapping = mapping } - if _, found := printer.(*kubectl.HumanReadablePrinter); found { + if resourcePrinter, found := printer.(*kubectl.HumanReadablePrinter); found { + resourceName := mapping.Resource + if alias, ok := kubectl.ResourceShortFormFor(mapping.Resource); ok { + resourceName = alias + } else if resourceName == "" { + resourceName = "none" + } + + resourcePrinter.Options.WithKind = withKind + resourcePrinter.Options.KindName = resourceName if err := printer.PrintObj(original, w); err != nil { allErrs = append(allErrs, err) } diff --git a/pkg/kubectl/kubectl.go b/pkg/kubectl/kubectl.go index 5b9726d5bba..a42bf288411 100644 --- a/pkg/kubectl/kubectl.go +++ b/pkg/kubectl/kubectl.go @@ -164,6 +164,19 @@ var shortForms = map[string]string{ "svc": "services", } +// Look-up for resource short forms by value +func ResourceShortFormFor(resource string) (string, bool) { + var alias string + exists := false + for k, val := range shortForms { + if val == resource { + alias = k + exists = true + } + } + return alias, exists +} + // expandResourceShortcut will return the expanded version of resource // (something that a pkg/api/meta.RESTMapper can understand), if it is // indeed a shortcut. Otherwise, will return resource unmodified. diff --git a/pkg/kubectl/resource_printer.go b/pkg/kubectl/resource_printer.go index f4da0941e1e..811d5b289b6 100644 --- a/pkg/kubectl/resource_printer.go +++ b/pkg/kubectl/resource_printer.go @@ -322,10 +322,12 @@ type handlerEntry struct { type PrintOptions struct { NoHeaders bool WithNamespace bool + WithKind bool Wide bool ShowAll bool ShowLabels bool AbsoluteTimestamps bool + KindName string ColumnLabels []string } @@ -335,7 +337,7 @@ type PrintOptions struct { // received from watches. type HumanReadablePrinter struct { handlerMap map[reflect.Type]*handlerEntry - options PrintOptions + Options PrintOptions lastType reflect.Type } @@ -343,9 +345,11 @@ type HumanReadablePrinter struct { func NewHumanReadablePrinter(noHeaders, withNamespace bool, wide bool, showAll bool, showLabels bool, absoluteTimestamps bool, columnLabels []string) *HumanReadablePrinter { printer := &HumanReadablePrinter{ handlerMap: make(map[reflect.Type]*handlerEntry), - options: PrintOptions{ + Options: PrintOptions{ NoHeaders: noHeaders, WithNamespace: withNamespace, + WithKind: false, + KindName: "", Wide: wide, ShowAll: showAll, ShowLabels: showLabels, @@ -599,6 +603,11 @@ func printPod(pod *api.Pod, w io.Writer, options PrintOptions) error { func printPodBase(pod *api.Pod, w io.Writer, options PrintOptions) error { name := pod.Name namespace := pod.Namespace + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } restarts := 0 totalContainers := len(pod.Spec.Containers) @@ -718,6 +727,11 @@ func printPodList(podList *api.PodList, w io.Writer, options PrintOptions) error func printPodTemplate(pod *api.PodTemplate, w io.Writer, options PrintOptions) error { name := pod.Name namespace := pod.Namespace + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } containers := pod.Template.Spec.Containers @@ -759,6 +773,11 @@ func printReplicationController(controller *api.ReplicationController, w io.Writ name := controller.Name namespace := controller.Namespace containers := controller.Spec.Template.Spec.Containers + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } if options.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { @@ -808,6 +827,11 @@ func printReplicaSet(rs *extensions.ReplicaSet, w io.Writer, options PrintOption name := rs.Name namespace := rs.Namespace containers := rs.Spec.Template.Spec.Containers + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } if options.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { @@ -853,6 +877,11 @@ func printReplicaSetList(list *extensions.ReplicaSetList, w io.Writer, options P } func printCluster(c *federation.Cluster, w io.Writer, options PrintOptions) error { + name := c.Name + kind := options.KindName + if options.WithKind { + name = kind + "/" + name + } var statuses []string for _, condition := range c.Status.Conditions { if condition.Status == api.ConditionTrue { @@ -866,7 +895,7 @@ func printCluster(c *federation.Cluster, w io.Writer, options PrintOptions) erro } if _, err := fmt.Fprintf(w, "%s\t%s\t%s\n", - c.Name, + name, strings.Join(statuses, ","), translateTimestamp(c.CreationTimestamp), ); err != nil { @@ -887,6 +916,11 @@ func printJob(job *batch.Job, w io.Writer, options PrintOptions) error { name := job.Name namespace := job.Namespace containers := job.Spec.Template.Spec.Containers + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } if options.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { @@ -1005,6 +1039,11 @@ func printService(svc *api.Service, w io.Writer, options PrintOptions) error { internalIP := svc.Spec.ClusterIP externalIP := getServiceExternalIP(svc, options.Wide) + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } if options.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { @@ -1081,6 +1120,11 @@ func formatPorts(tls []extensions.IngressTLS) string { func printIngress(ingress *extensions.Ingress, w io.Writer, options PrintOptions) error { name := ingress.Name namespace := ingress.Namespace + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } if options.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { @@ -1120,6 +1164,11 @@ func printPetSet(ps *apps.PetSet, w io.Writer, options PrintOptions) error { name := ps.Name namespace := ps.Namespace containers := ps.Spec.Template.Spec.Containers + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } if options.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { @@ -1166,6 +1215,11 @@ func printPetSetList(petSetList *apps.PetSetList, w io.Writer, options PrintOpti func printDaemonSet(ds *extensions.DaemonSet, w io.Writer, options PrintOptions) error { name := ds.Name namespace := ds.Namespace + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } containers := ds.Spec.Template.Spec.Containers @@ -1221,6 +1275,11 @@ func printDaemonSetList(list *extensions.DaemonSetList, w io.Writer, options Pri func printEndpoints(endpoints *api.Endpoints, w io.Writer, options PrintOptions) error { name := endpoints.Name namespace := endpoints.Namespace + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } if options.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { @@ -1247,11 +1306,17 @@ func printEndpointsList(list *api.EndpointsList, w io.Writer, options PrintOptio } func printNamespace(item *api.Namespace, w io.Writer, options PrintOptions) error { + name := item.Name + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } if options.WithNamespace { return fmt.Errorf("namespace is not namespaced") } - if _, err := fmt.Fprintf(w, "%s\t%s\t%s", item.Name, item.Status.Phase, translateTimestamp(item.CreationTimestamp)); err != nil { + if _, err := fmt.Fprintf(w, "%s\t%s\t%s", name, item.Status.Phase, translateTimestamp(item.CreationTimestamp)); err != nil { return err } if _, err := fmt.Fprint(w, AppendLabels(item.Labels, options.ColumnLabels)); err != nil { @@ -1273,6 +1338,11 @@ func printNamespaceList(list *api.NamespaceList, w io.Writer, options PrintOptio func printSecret(item *api.Secret, w io.Writer, options PrintOptions) error { name := item.Name namespace := item.Namespace + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } if options.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { @@ -1302,6 +1372,11 @@ func printSecretList(list *api.SecretList, w io.Writer, options PrintOptions) er func printServiceAccount(item *api.ServiceAccount, w io.Writer, options PrintOptions) error { name := item.Name namespace := item.Namespace + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } if options.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { @@ -1329,6 +1404,12 @@ func printServiceAccountList(list *api.ServiceAccountList, w io.Writer, options } func printNode(node *api.Node, w io.Writer, options PrintOptions) error { + name := node.Name + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } if options.WithNamespace { return fmt.Errorf("node is not namespaced") } @@ -1355,7 +1436,7 @@ func printNode(node *api.Node, w io.Writer, options PrintOptions) error { status = append(status, "SchedulingDisabled") } - if _, err := fmt.Fprintf(w, "%s\t%s\t%s", node.Name, strings.Join(status, ","), translateTimestamp(node.CreationTimestamp)); err != nil { + if _, err := fmt.Fprintf(w, "%s\t%s\t%s", name, strings.Join(status, ","), translateTimestamp(node.CreationTimestamp)); err != nil { return err } // Display caller specify column labels first. @@ -1376,10 +1457,15 @@ func printNodeList(list *api.NodeList, w io.Writer, options PrintOptions) error } func printPersistentVolume(pv *api.PersistentVolume, w io.Writer, options PrintOptions) error { + name := pv.Name + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } if options.WithNamespace { return fmt.Errorf("persistentVolume is not namespaced") } - name := pv.Name claimRefUID := "" if pv.Spec.ClaimRef != nil { @@ -1422,6 +1508,11 @@ func printPersistentVolumeList(list *api.PersistentVolumeList, w io.Writer, opti func printPersistentVolumeClaim(pvc *api.PersistentVolumeClaim, w io.Writer, options PrintOptions) error { name := pvc.Name namespace := pvc.Namespace + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } if options.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { @@ -1459,7 +1550,13 @@ func printPersistentVolumeClaimList(list *api.PersistentVolumeClaimList, w io.Wr } func printEvent(event *api.Event, w io.Writer, options PrintOptions) error { + name := event.InvolvedObject.Name namespace := event.Namespace + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } if options.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { return err @@ -1481,7 +1578,7 @@ func printEvent(event *api.Event, w io.Writer, options PrintOptions) error { LastTimestamp, FirstTimestamp, event.Count, - event.InvolvedObject.Name, + name, event.InvolvedObject.Kind, event.InvolvedObject.FieldPath, event.Type, @@ -1525,6 +1622,12 @@ func printLimitRangeList(list *api.LimitRangeList, w io.Writer, options PrintOpt // printObjectMeta prints the object metadata of a given resource. func printObjectMeta(meta api.ObjectMeta, w io.Writer, options PrintOptions, namespaced bool) error { + name := meta.Name + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } if namespaced && options.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", meta.Namespace); err != nil { return err @@ -1533,7 +1636,7 @@ func printObjectMeta(meta api.ObjectMeta, w io.Writer, options PrintOptions, nam if _, err := fmt.Fprintf( w, "%s\t%s", - meta.Name, + name, translateTimestamp(meta.CreationTimestamp), ); err != nil { return err @@ -1616,6 +1719,12 @@ func printClusterRoleBindingList(list *rbac.ClusterRoleBindingList, w io.Writer, } func printComponentStatus(item *api.ComponentStatus, w io.Writer, options PrintOptions) error { + name := item.Name + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } if options.WithNamespace { return fmt.Errorf("componentStatus is not namespaced") } @@ -1635,7 +1744,7 @@ func printComponentStatus(item *api.ComponentStatus, w io.Writer, options PrintO } } - if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s", item.Name, status, message, error); err != nil { + if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s", name, status, message, error); err != nil { return err } if _, err := fmt.Fprint(w, AppendLabels(item.Labels, options.ColumnLabels)); err != nil { @@ -1656,13 +1765,20 @@ func printComponentStatusList(list *api.ComponentStatusList, w io.Writer, option } func printThirdPartyResource(rsrc *extensions.ThirdPartyResource, w io.Writer, options PrintOptions) error { + name := rsrc.Name + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } + versions := make([]string, len(rsrc.Versions)) for ix := range rsrc.Versions { version := &rsrc.Versions[ix] versions[ix] = fmt.Sprintf("%s", version.Name) } versionsString := strings.Join(versions, ",") - if _, err := fmt.Fprintf(w, "%s\t%s\t%s\n", rsrc.Name, rsrc.Description, versionsString); err != nil { + if _, err := fmt.Fprintf(w, "%s\t%s\t%s\n", name, rsrc.Description, versionsString); err != nil { return err } return nil @@ -1686,12 +1802,19 @@ func truncate(str string, maxLen int) string { } func printThirdPartyResourceData(rsrc *extensions.ThirdPartyResourceData, w io.Writer, options PrintOptions) error { + name := rsrc.Name + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } + l := labels.FormatLabels(rsrc.Labels) truncateCols := 50 if options.Wide { truncateCols = 100 } - if _, err := fmt.Fprintf(w, "%s\t%s\t%s\n", rsrc.Name, l, truncate(string(rsrc.Data), truncateCols)); err != nil { + if _, err := fmt.Fprintf(w, "%s\t%s\t%s\n", name, l, truncate(string(rsrc.Data), truncateCols)); err != nil { return err } return nil @@ -1708,6 +1831,12 @@ func printThirdPartyResourceDataList(list *extensions.ThirdPartyResourceDataList } func printDeployment(deployment *extensions.Deployment, w io.Writer, options PrintOptions) error { + name := deployment.Name + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } if options.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", deployment.Namespace); err != nil { return err @@ -1719,7 +1848,7 @@ func printDeployment(deployment *extensions.Deployment, w io.Writer, options Pri updatedReplicas := deployment.Status.UpdatedReplicas availableReplicas := deployment.Status.AvailableReplicas age := translateTimestamp(deployment.CreationTimestamp) - if _, err := fmt.Fprintf(w, "%s\t%d\t%d\t%d\t%d\t%s", deployment.Name, desiredReplicas, currentReplicas, updatedReplicas, availableReplicas, age); err != nil { + if _, err := fmt.Fprintf(w, "%s\t%d\t%d\t%d\t%d\t%s", name, desiredReplicas, currentReplicas, updatedReplicas, availableReplicas, age); err != nil { return err } if _, err := fmt.Fprint(w, AppendLabels(deployment.Labels, options.ColumnLabels)); err != nil { @@ -1741,6 +1870,11 @@ func printDeploymentList(list *extensions.DeploymentList, w io.Writer, options P func printHorizontalPodAutoscaler(hpa *autoscaling.HorizontalPodAutoscaler, w io.Writer, options PrintOptions) error { namespace := hpa.Namespace name := hpa.Name + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } reference := fmt.Sprintf("%s/%s", hpa.Spec.ScaleTargetRef.Kind, hpa.Spec.ScaleTargetRef.Name) @@ -1757,6 +1891,7 @@ func printHorizontalPodAutoscaler(hpa *autoscaling.HorizontalPodAutoscaler, w io minPods = fmt.Sprintf("%d", *hpa.Spec.MinReplicas) } maxPods := hpa.Spec.MaxReplicas + if options.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { return err @@ -1793,6 +1928,11 @@ func printHorizontalPodAutoscalerList(list *autoscaling.HorizontalPodAutoscalerL func printConfigMap(configMap *api.ConfigMap, w io.Writer, options PrintOptions) error { name := configMap.Name namespace := configMap.Namespace + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } if options.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { @@ -1819,7 +1959,13 @@ func printConfigMapList(list *api.ConfigMapList, w io.Writer, options PrintOptio } func printPodSecurityPolicy(item *extensions.PodSecurityPolicy, w io.Writer, options PrintOptions) error { - _, err := fmt.Fprintf(w, "%s\t%t\t%v\t%s\t%s\t%s\t%s\t%t\t%v\n", item.Name, item.Spec.Privileged, + name := item.Name + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } + _, err := fmt.Fprintf(w, "%s\t%t\t%v\t%s\t%s\t%s\t%s\t%t\t%v\n", name, item.Spec.Privileged, item.Spec.AllowedCapabilities, item.Spec.SELinux.Rule, item.Spec.RunAsUser.Rule, item.Spec.FSGroup.Rule, item.Spec.SupplementalGroups.Rule, item.Spec.ReadOnlyRootFilesystem, item.Spec.Volumes) return err @@ -1838,6 +1984,11 @@ func printPodSecurityPolicyList(list *extensions.PodSecurityPolicyList, w io.Wri func printNetworkPolicy(networkPolicy *extensions.NetworkPolicy, w io.Writer, options PrintOptions) error { name := networkPolicy.Name namespace := networkPolicy.Namespace + kind := options.KindName + + if options.WithKind { + name = kind + "/" + name + } if options.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { @@ -1984,18 +2135,18 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er } t := reflect.TypeOf(obj) if handler := h.handlerMap[t]; handler != nil { - if !h.options.NoHeaders && t != h.lastType { - headers := append(handler.columns, formatWideHeaders(h.options.Wide, t)...) - headers = append(headers, formatLabelHeaders(h.options.ColumnLabels)...) + if !h.Options.NoHeaders && t != h.lastType { + headers := append(handler.columns, formatWideHeaders(h.Options.Wide, t)...) + headers = append(headers, formatLabelHeaders(h.Options.ColumnLabels)...) // LABELS is always the last column. - headers = append(headers, formatShowLabelsHeader(h.options.ShowLabels, t)...) - if h.options.WithNamespace { + headers = append(headers, formatShowLabelsHeader(h.Options.ShowLabels, t)...) + if h.Options.WithNamespace { headers = append(withNamespacePrefixColumns, headers...) } h.printHeader(headers, w) h.lastType = t } - args := []reflect.Value{reflect.ValueOf(obj), reflect.ValueOf(w), reflect.ValueOf(h.options)} + args := []reflect.Value{reflect.ValueOf(obj), reflect.ValueOf(w), reflect.ValueOf(h.Options)} resultValue := handler.printFunc.Call(args)[0] if resultValue.IsNil() { return nil diff --git a/pkg/kubectl/resource_printer_test.go b/pkg/kubectl/resource_printer_test.go index c4e49409769..5e1f558acfa 100644 --- a/pkg/kubectl/resource_printer_test.go +++ b/pkg/kubectl/resource_printer_test.go @@ -216,7 +216,12 @@ func TestJSONPrinter(t *testing.T) { } func PrintCustomType(obj *TestPrintType, w io.Writer, options PrintOptions) error { - _, err := fmt.Fprintf(w, "%s", obj.Data) + data := obj.Data + kind := options.KindName + if options.WithKind { + data = kind + "/" + data + } + _, err := fmt.Fprintf(w, "%s", data) return err } @@ -241,6 +246,25 @@ func TestCustomTypePrinting(t *testing.T) { } } +func TestCustomTypePrintingWithKind(t *testing.T) { + columns := []string{"Data"} + printer := NewHumanReadablePrinter(false, false, false, false, false, false, []string{}) + printer.Handler(columns, PrintCustomType) + printer.Options.WithKind = true + printer.Options.KindName = "test" + + obj := TestPrintType{"test object"} + buffer := &bytes.Buffer{} + err := printer.PrintObj(&obj, buffer) + if err != nil { + t.Fatalf("An error occurred printing the custom type: %#v", err) + } + expectedOutput := "Data\ntest/test object" + if buffer.String() != expectedOutput { + t.Errorf("The data was not printed as expected. Expected:\n%s\nGot:\n%s", expectedOutput, buffer.String()) + } +} + func TestPrintHandlerError(t *testing.T) { columns := []string{"Data"} printer := NewHumanReadablePrinter(false, false, false, false, false, false, []string{}) @@ -670,7 +694,7 @@ func TestPrintHunmanReadableIngressWithColumnLabels(t *testing.T) { }, } buff := bytes.Buffer{} - printIngress(&ingress, &buff, PrintOptions{false, false, false, false, false, false, []string{"app_name"}}) + printIngress(&ingress, &buff, PrintOptions{false, false, false, false, false, false, false, "", []string{"app_name"}}) output := string(buff.Bytes()) appName := ingress.ObjectMeta.Labels["app_name"] if !strings.Contains(output, appName) { @@ -793,7 +817,7 @@ func TestPrintHumanReadableService(t *testing.T) { for _, svc := range tests { for _, wide := range []bool{false, true} { buff := bytes.Buffer{} - printService(&svc, &buff, PrintOptions{false, false, wide, false, false, false, []string{}}) + printService(&svc, &buff, PrintOptions{false, false, false, wide, false, false, false, "", []string{}}) output := string(buff.Bytes()) ip := svc.Spec.ClusterIP if !strings.Contains(output, ip) { @@ -1084,7 +1108,7 @@ func TestPrintPod(t *testing.T) { buf := bytes.NewBuffer([]byte{}) for _, test := range tests { - printPod(&test.pod, buf, PrintOptions{false, false, false, true, false, false, []string{}}) + printPod(&test.pod, buf, PrintOptions{false, false, false, false, true, false, false, "", []string{}}) // We ignore time if !strings.HasPrefix(buf.String(), test.expect) { t.Fatalf("Expected: %s, got: %s", test.expect, buf.String()) @@ -1177,7 +1201,7 @@ func TestPrintNonTerminatedPod(t *testing.T) { buf := bytes.NewBuffer([]byte{}) for _, test := range tests { - printPod(&test.pod, buf, PrintOptions{false, false, false, false, false, false, []string{}}) + printPod(&test.pod, buf, PrintOptions{false, false, false, false, false, false, false, "", []string{}}) // We ignore time if !strings.HasPrefix(buf.String(), test.expect) { t.Fatalf("Expected: %s, got: %s", test.expect, buf.String()) @@ -1237,7 +1261,7 @@ func TestPrintPodWithLabels(t *testing.T) { buf := bytes.NewBuffer([]byte{}) for _, test := range tests { - printPod(&test.pod, buf, PrintOptions{false, false, false, false, false, false, test.labelColumns}) + printPod(&test.pod, buf, PrintOptions{false, false, false, false, false, false, false, "", test.labelColumns}) // We ignore time if !strings.HasPrefix(buf.String(), test.startsWith) || !strings.HasSuffix(buf.String(), test.endsWith) { t.Fatalf("Expected to start with: %s and end with: %s, but got: %s", test.startsWith, test.endsWith, buf.String()) @@ -1301,7 +1325,7 @@ func TestPrintDeployment(t *testing.T) { buf := bytes.NewBuffer([]byte{}) for _, test := range tests { - printDeployment(&test.deployment, buf, PrintOptions{false, false, false, true, false, false, []string{}}) + printDeployment(&test.deployment, buf, PrintOptions{false, false, false, false, true, false, false, "", []string{}}) if buf.String() != test.expect { t.Fatalf("Expected: %s, got: %s", test.expect, buf.String()) } @@ -1336,7 +1360,7 @@ func TestPrintDaemonSet(t *testing.T) { buf := bytes.NewBuffer([]byte{}) for _, test := range tests { - printDaemonSet(&test.ds, buf, PrintOptions{false, false, false, false, false, false, []string{}}) + printDaemonSet(&test.ds, buf, PrintOptions{false, false, false, false, false, false, false, "", []string{}}) if !strings.HasPrefix(buf.String(), test.startsWith) { t.Fatalf("Expected to start with %s but got %s", test.startsWith, buf.String()) } @@ -1384,7 +1408,7 @@ func TestPrintJob(t *testing.T) { buf := bytes.NewBuffer([]byte{}) for _, test := range tests { - printJob(&test.job, buf, PrintOptions{false, false, false, true, false, false, []string{}}) + printJob(&test.job, buf, PrintOptions{false, false, false, false, true, false, false, "", []string{}}) if buf.String() != test.expect { t.Fatalf("Expected: %s, got: %s", test.expect, buf.String()) } @@ -1443,7 +1467,7 @@ func TestPrintPodShowLabels(t *testing.T) { buf := bytes.NewBuffer([]byte{}) for _, test := range tests { - printPod(&test.pod, buf, PrintOptions{false, false, false, false, test.showLabels, false, []string{}}) + printPod(&test.pod, buf, PrintOptions{false, false, false, false, false, test.showLabels, false, "", []string{}}) // We ignore time if !strings.HasPrefix(buf.String(), test.startsWith) || !strings.HasSuffix(buf.String(), test.endsWith) { t.Fatalf("Expected to start with: %s and end with: %s, but got: %s", test.startsWith, test.endsWith, buf.String())