From 7153ff80ff3436a1076ed43d51fa5e06d9c9a1ae Mon Sep 17 00:00:00 2001 From: jiangyaoguo Date: Tue, 10 Nov 2015 19:34:28 +0800 Subject: [PATCH] print absolute time when watch event --- pkg/kubectl/cmd/cmd_test.go | 14 +- pkg/kubectl/cmd/delete.go | 2 +- pkg/kubectl/cmd/get.go | 2 +- pkg/kubectl/cmd/label.go | 2 +- pkg/kubectl/cmd/util/factory.go | 8 +- pkg/kubectl/cmd/util/helpers.go | 13 ++ pkg/kubectl/resource_printer.go | 305 ++++++++++++++------------- pkg/kubectl/resource_printer_test.go | 33 ++- 8 files changed, 205 insertions(+), 174 deletions(-) diff --git a/pkg/kubectl/cmd/cmd_test.go b/pkg/kubectl/cmd/cmd_test.go index 76e55d5c167..1d195aa8cf1 100644 --- a/pkg/kubectl/cmd/cmd_test.go +++ b/pkg/kubectl/cmd/cmd_test.go @@ -167,7 +167,7 @@ func NewTestFactory() (*cmdutil.Factory, *testFactory, runtime.Codec) { Describer: func(*meta.RESTMapping) (kubectl.Describer, error) { return t.Describer, t.Err }, - Printer: func(mapping *meta.RESTMapping, noHeaders, withNamespace bool, wide bool, showAll bool, columnLabels []string) (kubectl.ResourcePrinter, error) { + Printer: func(mapping *meta.RESTMapping, noHeaders, withNamespace bool, wide bool, showAll bool, absoluteTimestamps bool, columnLabels []string) (kubectl.ResourcePrinter, error) { return t.Printer, t.Err }, Validator: func(validate bool, cacheDir string) (validation.Schema, error) { @@ -224,7 +224,7 @@ func NewAPIFactory() (*cmdutil.Factory, *testFactory, runtime.Codec) { Describer: func(*meta.RESTMapping) (kubectl.Describer, error) { return t.Describer, t.Err }, - Printer: func(mapping *meta.RESTMapping, noHeaders, withNamespace bool, wide bool, showAll bool, columnLabels []string) (kubectl.ResourcePrinter, error) { + Printer: func(mapping *meta.RESTMapping, noHeaders, withNamespace bool, wide bool, showAll bool, absoluteTimestamps bool, columnLabels []string) (kubectl.ResourcePrinter, error) { return t.Printer, t.Err }, Validator: func(validate bool, cacheDir string) (validation.Schema, error) { @@ -299,7 +299,7 @@ func stringBody(body string) io.ReadCloser { func ExamplePrintReplicationControllerWithNamespace() { f, tf, codec := NewAPIFactory() - tf.Printer = kubectl.NewHumanReadablePrinter(false, true, false, false, []string{}) + tf.Printer = kubectl.NewHumanReadablePrinter(false, true, false, false, false, []string{}) tf.Client = &fake.RESTClient{ Codec: codec, Client: nil, @@ -341,7 +341,7 @@ func ExamplePrintReplicationControllerWithNamespace() { func ExamplePrintPodWithWideFormat() { f, tf, codec := NewAPIFactory() - tf.Printer = kubectl.NewHumanReadablePrinter(false, false, true, false, []string{}) + tf.Printer = kubectl.NewHumanReadablePrinter(false, false, true, false, false, []string{}) tf.Client = &fake.RESTClient{ Codec: codec, Client: nil, @@ -468,7 +468,7 @@ func newAllPhasePodList() *api.PodList { func ExamplePrintPodHideTerminated() { f, tf, codec := NewAPIFactory() - tf.Printer = kubectl.NewHumanReadablePrinter(false, false, false, false, []string{}) + tf.Printer = kubectl.NewHumanReadablePrinter(false, false, false, false, false, []string{}) tf.Client = &fake.RESTClient{ Codec: codec, Client: nil, @@ -488,7 +488,7 @@ func ExamplePrintPodHideTerminated() { func ExamplePrintPodShowAll() { f, tf, codec := NewAPIFactory() - tf.Printer = kubectl.NewHumanReadablePrinter(false, false, false, true, []string{}) + tf.Printer = kubectl.NewHumanReadablePrinter(false, false, false, true, false, []string{}) tf.Client = &fake.RESTClient{ Codec: codec, Client: nil, @@ -510,7 +510,7 @@ func ExamplePrintPodShowAll() { func ExamplePrintServiceWithNamespacesAndLabels() { f, tf, codec := NewAPIFactory() - tf.Printer = kubectl.NewHumanReadablePrinter(false, true, false, false, []string{"l1"}) + tf.Printer = kubectl.NewHumanReadablePrinter(false, true, false, false, false, []string{"l1"}) tf.Client = &fake.RESTClient{ Codec: codec, Client: nil, diff --git a/pkg/kubectl/cmd/delete.go b/pkg/kubectl/cmd/delete.go index 5c5822f6a0a..6bac41cdec6 100644 --- a/pkg/kubectl/cmd/delete.go +++ b/pkg/kubectl/cmd/delete.go @@ -71,7 +71,7 @@ func NewCmdDelete(f *cmdutil.Factory, out io.Writer) *cobra.Command { // retrieve a list of handled resources from printer as valid args validArgs := []string{} - p, err := f.Printer(nil, false, false, false, false, []string{}) + p, err := f.Printer(nil, false, false, false, false, false, []string{}) cmdutil.CheckErr(err) if p != nil { validArgs = p.HandledResources() diff --git a/pkg/kubectl/cmd/get.go b/pkg/kubectl/cmd/get.go index 0bd4a95b367..07d5048deb3 100644 --- a/pkg/kubectl/cmd/get.go +++ b/pkg/kubectl/cmd/get.go @@ -78,7 +78,7 @@ func NewCmdGet(f *cmdutil.Factory, out io.Writer) *cobra.Command { // retrieve a list of handled resources from printer as valid args validArgs := []string{} - p, err := f.Printer(nil, false, false, false, false, []string{}) + p, err := f.Printer(nil, false, false, false, false, false, []string{}) cmdutil.CheckErr(err) if p != nil { validArgs = p.HandledResources() diff --git a/pkg/kubectl/cmd/label.go b/pkg/kubectl/cmd/label.go index b4bca646ea9..1634b6450c8 100644 --- a/pkg/kubectl/cmd/label.go +++ b/pkg/kubectl/cmd/label.go @@ -70,7 +70,7 @@ func NewCmdLabel(f *cmdutil.Factory, out io.Writer) *cobra.Command { // retrieve a list of handled resources from printer as valid args validArgs := []string{} - p, err := f.Printer(nil, false, false, false, false, []string{}) + p, err := f.Printer(nil, false, false, false, false, false, []string{}) cmdutil.CheckErr(err) if p != nil { validArgs = p.HandledResources() diff --git a/pkg/kubectl/cmd/util/factory.go b/pkg/kubectl/cmd/util/factory.go index 250e1f3ddb7..67d4c170f9f 100644 --- a/pkg/kubectl/cmd/util/factory.go +++ b/pkg/kubectl/cmd/util/factory.go @@ -74,7 +74,7 @@ type Factory struct { // Returns a Describer for displaying the specified RESTMapping type or an error. Describer func(mapping *meta.RESTMapping) (kubectl.Describer, error) // Returns a Printer for formatting objects of the given type or an error. - Printer func(mapping *meta.RESTMapping, noHeaders, withNamespace bool, wide bool, showAll bool, columnLabels []string) (kubectl.ResourcePrinter, error) + Printer func(mapping *meta.RESTMapping, noHeaders, withNamespace bool, wide bool, showAll bool, absoluteTimestamps bool, columnLabels []string) (kubectl.ResourcePrinter, error) // Returns a Scaler for changing the size of the specified RESTMapping type or an error Scaler func(mapping *meta.RESTMapping) (kubectl.Scaler, error) // Returns a Reaper for gracefully shutting down resources. @@ -181,8 +181,8 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory { } return nil, fmt.Errorf("no description has been implemented for %q", mapping.Kind) }, - Printer: func(mapping *meta.RESTMapping, noHeaders, withNamespace bool, wide bool, showAll bool, columnLabels []string) (kubectl.ResourcePrinter, error) { - return kubectl.NewHumanReadablePrinter(noHeaders, withNamespace, wide, showAll, columnLabels), nil + Printer: func(mapping *meta.RESTMapping, noHeaders, withNamespace bool, wide bool, showAll bool, absoluteTimestamps bool, columnLabels []string) (kubectl.ResourcePrinter, error) { + return kubectl.NewHumanReadablePrinter(noHeaders, withNamespace, wide, showAll, absoluteTimestamps, columnLabels), nil }, PodSelectorForObject: func(object runtime.Object) (string, error) { // TODO: replace with a swagger schema based approach (identify pod selector via schema introspection) @@ -622,7 +622,7 @@ func (f *Factory) PrinterForMapping(cmd *cobra.Command, mapping *meta.RESTMappin if err != nil { columnLabel = []string{} } - printer, err = f.Printer(mapping, GetFlagBool(cmd, "no-headers"), withNamespace, GetWideFlag(cmd), GetFlagBool(cmd, "show-all"), columnLabel) + printer, err = f.Printer(mapping, GetFlagBool(cmd, "no-headers"), withNamespace, GetWideFlag(cmd), GetFlagBool(cmd, "show-all"), isWatch(cmd), columnLabel) if err != nil { return nil, err } diff --git a/pkg/kubectl/cmd/util/helpers.go b/pkg/kubectl/cmd/util/helpers.go index 8159310c430..3a7a15f1569 100644 --- a/pkg/kubectl/cmd/util/helpers.go +++ b/pkg/kubectl/cmd/util/helpers.go @@ -214,6 +214,19 @@ func UsageError(cmd *cobra.Command, format string, args ...interface{}) error { return fmt.Errorf("%s\nSee '%s -h' for help and examples.", msg, cmd.CommandPath()) } +// Whether this cmd need watching objects. +func isWatch(cmd *cobra.Command) bool { + if w, err := cmd.Flags().GetBool("watch"); w && err == nil { + return true + } + + if wo, err := cmd.Flags().GetBool("watch-only"); wo && err == nil { + return true + } + + return false +} + func getFlag(cmd *cobra.Command, flag string) *pflag.Flag { f := cmd.Flags().Lookup(flag) if f == nil { diff --git a/pkg/kubectl/resource_printer.go b/pkg/kubectl/resource_printer.go index 1ff90e3b622..756ec9aaec7 100644 --- a/pkg/kubectl/resource_printer.go +++ b/pkg/kubectl/resource_printer.go @@ -300,29 +300,37 @@ type handlerEntry struct { printFunc reflect.Value } +type printOptions struct { + noHeaders bool + withNamespace bool + wide bool + showAll bool + absoluteTimestamps bool + columnLabels []string +} + // HumanReadablePrinter is an implementation of ResourcePrinter which attempts to provide // more elegant output. It is not threadsafe, but you may call PrintObj repeatedly; headers // will only be printed if the object type changes. This makes it useful for printing items // received from watches. type HumanReadablePrinter struct { - handlerMap map[reflect.Type]*handlerEntry - noHeaders bool - withNamespace bool - wide bool - showAll bool - columnLabels []string - lastType reflect.Type + handlerMap map[reflect.Type]*handlerEntry + options printOptions + lastType reflect.Type } // NewHumanReadablePrinter creates a HumanReadablePrinter. -func NewHumanReadablePrinter(noHeaders, withNamespace bool, wide bool, showAll bool, columnLabels []string) *HumanReadablePrinter { +func NewHumanReadablePrinter(noHeaders, withNamespace bool, wide bool, showAll bool, absoluteTimestamps bool, columnLabels []string) *HumanReadablePrinter { printer := &HumanReadablePrinter{ - handlerMap: make(map[reflect.Type]*handlerEntry), - noHeaders: noHeaders, - withNamespace: withNamespace, - wide: wide, - showAll: showAll, - columnLabels: columnLabels, + handlerMap: make(map[reflect.Type]*handlerEntry), + options: printOptions{ + noHeaders: noHeaders, + withNamespace: withNamespace, + wide: wide, + showAll: showAll, + absoluteTimestamps: absoluteTimestamps, + columnLabels: columnLabels, + }, } printer.addDefaultHandlers() return printer @@ -347,22 +355,22 @@ func (h *HumanReadablePrinter) Handler(columns []string, printFunc interface{}) // validatePrintHandlerFunc validates print handler signature. // printFunc is the function that will be called to print an object. // It must be of the following type: -// func printFunc(object ObjectType, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error +// func printFunc(object ObjectType, w io.Writer, options PrintOptions) error // where ObjectType is the type of the object that will be printed. func (h *HumanReadablePrinter) validatePrintHandlerFunc(printFunc reflect.Value) error { if printFunc.Kind() != reflect.Func { return fmt.Errorf("invalid print handler. %#v is not a function", printFunc) } funcType := printFunc.Type() - if funcType.NumIn() != 6 || funcType.NumOut() != 1 { + if funcType.NumIn() != 3 || funcType.NumOut() != 1 { return fmt.Errorf("invalid print handler." + - "Must accept 6 parameters and return 1 value.") + "Must accept 3 parameters and return 1 value.") } if funcType.In(1) != reflect.TypeOf((*io.Writer)(nil)).Elem() || - funcType.In(5) != reflect.TypeOf((*[]string)(nil)).Elem() || + funcType.In(2) != reflect.TypeOf((*printOptions)(nil)).Elem() || funcType.Out(0) != reflect.TypeOf((*error)(nil)).Elem() { return fmt.Errorf("invalid print handler. The expected signature is: "+ - "func handler(obj %v, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error", funcType.In(0)) + "func handler(obj %v, w io.Writer, options printOptions) error", funcType.In(0)) } return nil } @@ -528,11 +536,11 @@ func translateTimestamp(timestamp unversioned.Time) string { return shortHumanDuration(time.Now().Sub(timestamp.Time)) } -func printPod(pod *api.Pod, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { - return printPodBase(pod, w, withNamespace, wide, showAll, true, columnLabels) +func printPod(pod *api.Pod, w io.Writer, options printOptions) error { + return printPodBase(pod, w, true, options) } -func printPodBase(pod *api.Pod, w io.Writer, withNamespace bool, wide bool, showAll bool, showIfTerminating bool, columnLabels []string) error { +func printPodBase(pod *api.Pod, w io.Writer, showIfTerminating bool, options printOptions) error { name := pod.Name namespace := pod.Namespace @@ -542,7 +550,7 @@ func printPodBase(pod *api.Pod, w io.Writer, withNamespace bool, wide bool, show reason := string(pod.Status.Phase) // if not printing all pods, skip terminated pods (default) - if !showIfTerminating && !showAll && (reason == string(api.PodSucceeded) || reason == string(api.PodFailed)) { + if !showIfTerminating && !options.showAll && (reason == string(api.PodSucceeded) || reason == string(api.PodFailed)) { return nil } if pod.Status.Reason != "" { @@ -571,7 +579,7 @@ func printPodBase(pod *api.Pod, w io.Writer, withNamespace bool, wide bool, show reason = "Terminating" } - if withNamespace { + if options.withNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { return err } @@ -587,7 +595,7 @@ func printPodBase(pod *api.Pod, w io.Writer, withNamespace bool, wide bool, show return err } - if wide { + if options.wide { nodeName := pod.Spec.NodeName if _, err := fmt.Fprintf(w, "\t%s", nodeName, @@ -596,20 +604,20 @@ func printPodBase(pod *api.Pod, w io.Writer, withNamespace bool, wide bool, show } } - _, err := fmt.Fprint(w, appendLabels(pod.Labels, columnLabels)) + _, err := fmt.Fprint(w, appendLabels(pod.Labels, options.columnLabels)) return err } -func printPodList(podList *api.PodList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printPodList(podList *api.PodList, w io.Writer, options printOptions) error { for _, pod := range podList.Items { - if err := printPodBase(&pod, w, withNamespace, wide, showAll, false, columnLabels); err != nil { + if err := printPodBase(&pod, w, false, options); err != nil { return err } } return nil } -func printPodTemplate(pod *api.PodTemplate, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printPodTemplate(pod *api.PodTemplate, w io.Writer, options printOptions) error { name := pod.Name namespace := pod.Namespace @@ -619,7 +627,7 @@ func printPodTemplate(pod *api.PodTemplate, w io.Writer, withNamespace bool, wid firstContainer, containers = containers[0], containers[1:] } - if withNamespace { + if options.withNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { return err } @@ -632,13 +640,13 @@ func printPodTemplate(pod *api.PodTemplate, w io.Writer, withNamespace bool, wid ); err != nil { return err } - if _, err := fmt.Fprint(w, appendLabels(pod.Labels, columnLabels)); err != nil { + if _, err := fmt.Fprint(w, appendLabels(pod.Labels, options.columnLabels)); err != nil { return err } // Lay out all the other containers on separate lines. extraLinePrefix := "\t" - if withNamespace { + if options.withNamespace { extraLinePrefix = "\t\t" } for _, container := range containers { @@ -646,23 +654,23 @@ func printPodTemplate(pod *api.PodTemplate, w io.Writer, withNamespace bool, wid if err != nil { return err } - if _, err := fmt.Fprint(w, appendLabelTabs(columnLabels)); err != nil { + if _, err := fmt.Fprint(w, appendLabelTabs(options.columnLabels)); err != nil { return err } } return nil } -func printPodTemplateList(podList *api.PodTemplateList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printPodTemplateList(podList *api.PodTemplateList, w io.Writer, options printOptions) error { for _, pod := range podList.Items { - if err := printPodTemplate(&pod, w, withNamespace, wide, showAll, columnLabels); err != nil { + if err := printPodTemplate(&pod, w, options); err != nil { return err } } return nil } -func printReplicationController(controller *api.ReplicationController, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printReplicationController(controller *api.ReplicationController, w io.Writer, options printOptions) error { name := controller.Name namespace := controller.Namespace containers := controller.Spec.Template.Spec.Containers @@ -671,7 +679,7 @@ func printReplicationController(controller *api.ReplicationController, w io.Writ firstContainer, containers = containers[0], containers[1:] } - if withNamespace { + if options.withNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { return err } @@ -686,13 +694,13 @@ func printReplicationController(controller *api.ReplicationController, w io.Writ ); err != nil { return err } - if _, err := fmt.Fprint(w, appendLabels(controller.Labels, columnLabels)); err != nil { + if _, err := fmt.Fprint(w, appendLabels(controller.Labels, options.columnLabels)); err != nil { return err } // Lay out all the other containers on separate lines. extraLinePrefix := "\t" - if withNamespace { + if options.withNamespace { extraLinePrefix = "\t\t" } for _, container := range containers { @@ -700,23 +708,23 @@ func printReplicationController(controller *api.ReplicationController, w io.Writ if err != nil { return err } - if _, err := fmt.Fprint(w, appendLabelTabs(columnLabels)); err != nil { + if _, err := fmt.Fprint(w, appendLabelTabs(options.columnLabels)); err != nil { return err } } return nil } -func printReplicationControllerList(list *api.ReplicationControllerList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printReplicationControllerList(list *api.ReplicationControllerList, w io.Writer, options printOptions) error { for _, controller := range list.Items { - if err := printReplicationController(&controller, w, withNamespace, wide, showAll, columnLabels); err != nil { + if err := printReplicationController(&controller, w, options); err != nil { return err } } return nil } -func printJob(job *extensions.Job, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printJob(job *extensions.Job, w io.Writer, options printOptions) error { name := job.Name namespace := job.Namespace containers := job.Spec.Template.Spec.Containers @@ -724,7 +732,7 @@ func printJob(job *extensions.Job, w io.Writer, withNamespace bool, wide bool, s if len(containers) > 0 { firstContainer, containers = containers[0], containers[1:] } - if withNamespace { + if options.withNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { return err } @@ -740,13 +748,13 @@ func printJob(job *extensions.Job, w io.Writer, withNamespace bool, wide bool, s if err != nil { return err } - if _, err := fmt.Fprint(w, appendLabels(job.Labels, columnLabels)); err != nil { + if _, err := fmt.Fprint(w, appendLabels(job.Labels, options.columnLabels)); err != nil { return err } // Lay out all the other containers on separate lines. extraLinePrefix := "\t" - if withNamespace { + if options.withNamespace { extraLinePrefix = "\t\t" } for _, container := range containers { @@ -754,16 +762,16 @@ func printJob(job *extensions.Job, w io.Writer, withNamespace bool, wide bool, s if err != nil { return err } - if _, err := fmt.Fprint(w, appendLabelTabs(columnLabels)); err != nil { + if _, err := fmt.Fprint(w, appendLabelTabs(options.columnLabels)); err != nil { return err } } return nil } -func printJobList(list *extensions.JobList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printJobList(list *extensions.JobList, w io.Writer, options printOptions) error { for _, job := range list.Items { - if err := printJob(&job, w, withNamespace, wide, showAll, columnLabels); err != nil { + if err := printJob(&job, w, options); err != nil { return err } } @@ -814,14 +822,14 @@ func makePortString(ports []api.ServicePort) string { return strings.Join(pieces, ",") } -func printService(svc *api.Service, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printService(svc *api.Service, w io.Writer, options printOptions) error { name := svc.Name namespace := svc.Namespace internalIP := svc.Spec.ClusterIP externalIP := getServiceExternalIP(svc) - if withNamespace { + if options.withNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { return err } @@ -836,15 +844,15 @@ func printService(svc *api.Service, w io.Writer, withNamespace bool, wide bool, ); err != nil { return err } - if _, err := fmt.Fprint(w, appendLabels(svc.Labels, columnLabels)); err != nil { + if _, err := fmt.Fprint(w, appendLabels(svc.Labels, options.columnLabels)); err != nil { return err } return nil } -func printServiceList(list *api.ServiceList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printServiceList(list *api.ServiceList, w io.Writer, options printOptions) error { for _, svc := range list.Items { - if err := printService(&svc, w, withNamespace, wide, showAll, columnLabels); err != nil { + if err := printService(&svc, w, options); err != nil { return err } } @@ -859,12 +867,12 @@ func backendStringer(backend *extensions.IngressBackend) string { return fmt.Sprintf("%v:%v", backend.ServiceName, backend.ServicePort.String()) } -func printIngress(ingress *extensions.Ingress, w io.Writer, withNamespace, wide bool, showAll bool, columnLabels []string) error { +func printIngress(ingress *extensions.Ingress, w io.Writer, options printOptions) error { name := ingress.Name namespace := ingress.Namespace hostRules := ingress.Spec.Rules - if withNamespace { + if options.withNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { return err } @@ -880,7 +888,7 @@ func printIngress(ingress *extensions.Ingress, w io.Writer, withNamespace, wide // Lay out all the rules on separate lines. extraLinePrefix := "" - if withNamespace { + if options.withNamespace { extraLinePrefix = "\t" } for _, rules := range hostRules { @@ -891,7 +899,7 @@ func printIngress(ingress *extensions.Ingress, w io.Writer, withNamespace, wide if err != nil { return err } - if _, err := fmt.Fprint(w, appendLabelTabs(columnLabels)); err != nil { + if _, err := fmt.Fprint(w, appendLabelTabs(options.columnLabels)); err != nil { return err } for _, rule := range rules.HTTP.Paths { @@ -899,7 +907,7 @@ func printIngress(ingress *extensions.Ingress, w io.Writer, withNamespace, wide if err != nil { return err } - if _, err := fmt.Fprint(w, appendLabelTabs(columnLabels)); err != nil { + if _, err := fmt.Fprint(w, appendLabelTabs(options.columnLabels)); err != nil { return err } } @@ -907,16 +915,16 @@ func printIngress(ingress *extensions.Ingress, w io.Writer, withNamespace, wide return nil } -func printIngressList(ingressList *extensions.IngressList, w io.Writer, withNamespace, wide bool, showAll bool, columnLabels []string) error { +func printIngressList(ingressList *extensions.IngressList, w io.Writer, options printOptions) error { for _, ingress := range ingressList.Items { - if err := printIngress(&ingress, w, withNamespace, wide, true, columnLabels); err != nil { + if err := printIngress(&ingress, w, options); err != nil { return err } } return nil } -func printDaemonSet(ds *extensions.DaemonSet, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printDaemonSet(ds *extensions.DaemonSet, w io.Writer, options printOptions) error { name := ds.Name namespace := ds.Namespace @@ -926,7 +934,7 @@ func printDaemonSet(ds *extensions.DaemonSet, w io.Writer, withNamespace bool, w firstContainer, containers = containers[0], containers[1:] } - if withNamespace { + if options.withNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { return err } @@ -945,13 +953,13 @@ func printDaemonSet(ds *extensions.DaemonSet, w io.Writer, withNamespace bool, w ); err != nil { return err } - if _, err := fmt.Fprint(w, appendLabels(ds.Labels, columnLabels)); err != nil { + if _, err := fmt.Fprint(w, appendLabels(ds.Labels, options.columnLabels)); err != nil { return err } // Lay out all the other containers on separate lines. extraLinePrefix := "\t" - if withNamespace { + if options.withNamespace { extraLinePrefix = "\t\t" } for _, container := range containers { @@ -959,27 +967,27 @@ func printDaemonSet(ds *extensions.DaemonSet, w io.Writer, withNamespace bool, w if err != nil { return err } - if _, err := fmt.Fprint(w, appendLabelTabs(columnLabels)); err != nil { + if _, err := fmt.Fprint(w, appendLabelTabs(options.columnLabels)); err != nil { return err } } return nil } -func printDaemonSetList(list *extensions.DaemonSetList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printDaemonSetList(list *extensions.DaemonSetList, w io.Writer, options printOptions) error { for _, ds := range list.Items { - if err := printDaemonSet(&ds, w, withNamespace, wide, showAll, columnLabels); err != nil { + if err := printDaemonSet(&ds, w, options); err != nil { return err } } return nil } -func printEndpoints(endpoints *api.Endpoints, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printEndpoints(endpoints *api.Endpoints, w io.Writer, options printOptions) error { name := endpoints.Name namespace := endpoints.Namespace - if withNamespace { + if options.withNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { return err } @@ -987,45 +995,45 @@ func printEndpoints(endpoints *api.Endpoints, w io.Writer, withNamespace bool, w if _, err := fmt.Fprintf(w, "%s\t%s\t%s", name, formatEndpoints(endpoints, nil), translateTimestamp(endpoints.CreationTimestamp)); err != nil { return err } - _, err := fmt.Fprint(w, appendLabels(endpoints.Labels, columnLabels)) + _, err := fmt.Fprint(w, appendLabels(endpoints.Labels, options.columnLabels)) return err } -func printEndpointsList(list *api.EndpointsList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printEndpointsList(list *api.EndpointsList, w io.Writer, options printOptions) error { for _, item := range list.Items { - if err := printEndpoints(&item, w, withNamespace, wide, showAll, columnLabels); err != nil { + if err := printEndpoints(&item, w, options); err != nil { return err } } return nil } -func printNamespace(item *api.Namespace, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { - if withNamespace { +func printNamespace(item *api.Namespace, w io.Writer, options printOptions) error { + if options.withNamespace { return fmt.Errorf("namespace is not namespaced") } if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s", item.Name, labels.FormatLabels(item.Labels), item.Status.Phase, translateTimestamp(item.CreationTimestamp)); err != nil { return err } - _, err := fmt.Fprint(w, appendLabels(item.Labels, columnLabels)) + _, err := fmt.Fprint(w, appendLabels(item.Labels, options.columnLabels)) return err } -func printNamespaceList(list *api.NamespaceList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printNamespaceList(list *api.NamespaceList, w io.Writer, options printOptions) error { for _, item := range list.Items { - if err := printNamespace(&item, w, withNamespace, wide, showAll, columnLabels); err != nil { + if err := printNamespace(&item, w, options); err != nil { return err } } return nil } -func printSecret(item *api.Secret, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printSecret(item *api.Secret, w io.Writer, options printOptions) error { name := item.Name namespace := item.Namespace - if withNamespace { + if options.withNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { return err } @@ -1033,13 +1041,13 @@ func printSecret(item *api.Secret, w io.Writer, withNamespace bool, wide bool, s if _, err := fmt.Fprintf(w, "%s\t%s\t%v\t%s", name, item.Type, len(item.Data), translateTimestamp(item.CreationTimestamp)); err != nil { return err } - _, err := fmt.Fprint(w, appendLabels(item.Labels, columnLabels)) + _, err := fmt.Fprint(w, appendLabels(item.Labels, options.columnLabels)) return err } -func printSecretList(list *api.SecretList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printSecretList(list *api.SecretList, w io.Writer, options printOptions) error { for _, item := range list.Items { - if err := printSecret(&item, w, withNamespace, wide, showAll, columnLabels); err != nil { + if err := printSecret(&item, w, options); err != nil { return err } } @@ -1047,11 +1055,11 @@ func printSecretList(list *api.SecretList, w io.Writer, withNamespace bool, wide return nil } -func printServiceAccount(item *api.ServiceAccount, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printServiceAccount(item *api.ServiceAccount, w io.Writer, options printOptions) error { name := item.Name namespace := item.Namespace - if withNamespace { + if options.withNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { return err } @@ -1059,13 +1067,13 @@ func printServiceAccount(item *api.ServiceAccount, w io.Writer, withNamespace bo if _, err := fmt.Fprintf(w, "%s\t%d\t%s", name, len(item.Secrets), translateTimestamp(item.CreationTimestamp)); err != nil { return err } - _, err := fmt.Fprint(w, appendLabels(item.Labels, columnLabels)) + _, err := fmt.Fprint(w, appendLabels(item.Labels, options.columnLabels)) return err } -func printServiceAccountList(list *api.ServiceAccountList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printServiceAccountList(list *api.ServiceAccountList, w io.Writer, options printOptions) error { for _, item := range list.Items { - if err := printServiceAccount(&item, w, withNamespace, wide, showAll, columnLabels); err != nil { + if err := printServiceAccount(&item, w, options); err != nil { return err } } @@ -1073,8 +1081,8 @@ func printServiceAccountList(list *api.ServiceAccountList, w io.Writer, withName return nil } -func printNode(node *api.Node, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { - if withNamespace { +func printNode(node *api.Node, w io.Writer, options printOptions) error { + if options.withNamespace { return fmt.Errorf("node is not namespaced") } conditionMap := make(map[api.NodeConditionType]*api.NodeCondition) @@ -1103,21 +1111,21 @@ func printNode(node *api.Node, w io.Writer, withNamespace bool, wide bool, showA if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s", node.Name, labels.FormatLabels(node.Labels), strings.Join(status, ","), translateTimestamp(node.CreationTimestamp)); err != nil { return err } - _, err := fmt.Fprint(w, appendLabels(node.Labels, columnLabels)) + _, err := fmt.Fprint(w, appendLabels(node.Labels, options.columnLabels)) return err } -func printNodeList(list *api.NodeList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printNodeList(list *api.NodeList, w io.Writer, options printOptions) error { for _, node := range list.Items { - if err := printNode(&node, w, withNamespace, wide, showAll, columnLabels); err != nil { + if err := printNode(&node, w, options); err != nil { return err } } return nil } -func printPersistentVolume(pv *api.PersistentVolume, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { - if withNamespace { +func printPersistentVolume(pv *api.PersistentVolume, w io.Writer, options printOptions) error { + if options.withNamespace { return fmt.Errorf("persistentVolume is not namespaced") } name := pv.Name @@ -1145,24 +1153,24 @@ func printPersistentVolume(pv *api.PersistentVolume, w io.Writer, withNamespace ); err != nil { return err } - _, err := fmt.Fprint(w, appendLabels(pv.Labels, columnLabels)) + _, err := fmt.Fprint(w, appendLabels(pv.Labels, options.columnLabels)) return err } -func printPersistentVolumeList(list *api.PersistentVolumeList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printPersistentVolumeList(list *api.PersistentVolumeList, w io.Writer, options printOptions) error { for _, pv := range list.Items { - if err := printPersistentVolume(&pv, w, withNamespace, wide, showAll, columnLabels); err != nil { + if err := printPersistentVolume(&pv, w, options); err != nil { return err } } return nil } -func printPersistentVolumeClaim(pvc *api.PersistentVolumeClaim, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printPersistentVolumeClaim(pvc *api.PersistentVolumeClaim, w io.Writer, options printOptions) error { name := pvc.Name namespace := pvc.Namespace - if withNamespace { + if options.withNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { return err } @@ -1182,30 +1190,41 @@ func printPersistentVolumeClaim(pvc *api.PersistentVolumeClaim, w io.Writer, wit if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s", name, labels, phase, pvc.Spec.VolumeName, capacity, accessModes, translateTimestamp(pvc.CreationTimestamp)); err != nil { return err } - _, err := fmt.Fprint(w, appendLabels(pvc.Labels, columnLabels)) + _, err := fmt.Fprint(w, appendLabels(pvc.Labels, options.columnLabels)) return err } -func printPersistentVolumeClaimList(list *api.PersistentVolumeClaimList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printPersistentVolumeClaimList(list *api.PersistentVolumeClaimList, w io.Writer, options printOptions) error { for _, psd := range list.Items { - if err := printPersistentVolumeClaim(&psd, w, withNamespace, wide, showAll, columnLabels); err != nil { + if err := printPersistentVolumeClaim(&psd, w, options); err != nil { return err } } return nil } -func printEvent(event *api.Event, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printEvent(event *api.Event, w io.Writer, options printOptions) error { namespace := event.Namespace - if withNamespace { + if options.withNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { return err } } + + // While watching event, we should print absolute time. + var FirstTimestamp, LastTimestamp string + if options.absoluteTimestamps { + FirstTimestamp = event.FirstTimestamp.String() + LastTimestamp = event.LastTimestamp.String() + } else { + FirstTimestamp = translateTimestamp(event.FirstTimestamp) + LastTimestamp = translateTimestamp(event.LastTimestamp) + } + if _, err := fmt.Fprintf( w, "%s\t%s\t%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s", - translateTimestamp(event.FirstTimestamp), - translateTimestamp(event.LastTimestamp), + FirstTimestamp, + LastTimestamp, event.Count, event.InvolvedObject.Name, event.InvolvedObject.Kind, @@ -1217,26 +1236,26 @@ func printEvent(event *api.Event, w io.Writer, withNamespace bool, wide bool, sh ); err != nil { return err } - _, err := fmt.Fprint(w, appendLabels(event.Labels, columnLabels)) + _, err := fmt.Fprint(w, appendLabels(event.Labels, options.columnLabels)) return err } // Sorts and prints the EventList in a human-friendly format. -func printEventList(list *api.EventList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printEventList(list *api.EventList, w io.Writer, options printOptions) error { sort.Sort(SortableEvents(list.Items)) for i := range list.Items { - if err := printEvent(&list.Items[i], w, withNamespace, wide, showAll, columnLabels); err != nil { + if err := printEvent(&list.Items[i], w, options); err != nil { return err } } return nil } -func printLimitRange(limitRange *api.LimitRange, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printLimitRange(limitRange *api.LimitRange, w io.Writer, options printOptions) error { name := limitRange.Name namespace := limitRange.Namespace - if withNamespace { + if options.withNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { return err } @@ -1249,25 +1268,25 @@ func printLimitRange(limitRange *api.LimitRange, w io.Writer, withNamespace bool ); err != nil { return err } - _, err := fmt.Fprint(w, appendLabels(limitRange.Labels, columnLabels)) + _, err := fmt.Fprint(w, appendLabels(limitRange.Labels, options.columnLabels)) return err } // Prints the LimitRangeList in a human-friendly format. -func printLimitRangeList(list *api.LimitRangeList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printLimitRangeList(list *api.LimitRangeList, w io.Writer, options printOptions) error { for i := range list.Items { - if err := printLimitRange(&list.Items[i], w, withNamespace, wide, showAll, columnLabels); err != nil { + if err := printLimitRange(&list.Items[i], w, options); err != nil { return err } } return nil } -func printResourceQuota(resourceQuota *api.ResourceQuota, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printResourceQuota(resourceQuota *api.ResourceQuota, w io.Writer, options printOptions) error { name := resourceQuota.Name namespace := resourceQuota.Namespace - if withNamespace { + if options.withNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { return err } @@ -1280,22 +1299,22 @@ func printResourceQuota(resourceQuota *api.ResourceQuota, w io.Writer, withNames ); err != nil { return err } - _, err := fmt.Fprint(w, appendLabels(resourceQuota.Labels, columnLabels)) + _, err := fmt.Fprint(w, appendLabels(resourceQuota.Labels, options.columnLabels)) return err } // Prints the ResourceQuotaList in a human-friendly format. -func printResourceQuotaList(list *api.ResourceQuotaList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printResourceQuotaList(list *api.ResourceQuotaList, w io.Writer, options printOptions) error { for i := range list.Items { - if err := printResourceQuota(&list.Items[i], w, withNamespace, wide, showAll, columnLabels); err != nil { + if err := printResourceQuota(&list.Items[i], w, options); err != nil { return err } } return nil } -func printComponentStatus(item *api.ComponentStatus, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { - if withNamespace { +func printComponentStatus(item *api.ComponentStatus, w io.Writer, options printOptions) error { + if options.withNamespace { return fmt.Errorf("componentStatus is not namespaced") } status := "Unknown" @@ -1317,13 +1336,13 @@ func printComponentStatus(item *api.ComponentStatus, w io.Writer, withNamespace if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s", item.Name, status, message, error); err != nil { return err } - _, err := fmt.Fprint(w, appendLabels(item.Labels, columnLabels)) + _, err := fmt.Fprint(w, appendLabels(item.Labels, options.columnLabels)) return err } -func printComponentStatusList(list *api.ComponentStatusList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printComponentStatusList(list *api.ComponentStatusList, w io.Writer, options printOptions) error { for _, item := range list.Items { - if err := printComponentStatus(&item, w, withNamespace, wide, showAll, columnLabels); err != nil { + if err := printComponentStatus(&item, w, options); err != nil { return err } } @@ -1331,7 +1350,7 @@ func printComponentStatusList(list *api.ComponentStatusList, w io.Writer, withNa return nil } -func printThirdPartyResource(rsrc *extensions.ThirdPartyResource, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printThirdPartyResource(rsrc *extensions.ThirdPartyResource, w io.Writer, options printOptions) error { versions := make([]string, len(rsrc.Versions)) for ix := range rsrc.Versions { version := &rsrc.Versions[ix] @@ -1344,9 +1363,9 @@ func printThirdPartyResource(rsrc *extensions.ThirdPartyResource, w io.Writer, w return nil } -func printThirdPartyResourceList(list *extensions.ThirdPartyResourceList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printThirdPartyResourceList(list *extensions.ThirdPartyResourceList, w io.Writer, options printOptions) error { for _, item := range list.Items { - if err := printThirdPartyResource(&item, w, withNamespace, wide, showAll, columnLabels); err != nil { + if err := printThirdPartyResource(&item, w, options); err != nil { return err } } @@ -1354,8 +1373,8 @@ func printThirdPartyResourceList(list *extensions.ThirdPartyResourceList, w io.W return nil } -func printDeployment(deployment *extensions.Deployment, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { - if withNamespace { +func printDeployment(deployment *extensions.Deployment, w io.Writer, options printOptions) error { + if options.withNamespace { if _, err := fmt.Fprintf(w, "%s\t", deployment.Namespace); err != nil { return err } @@ -1366,20 +1385,20 @@ func printDeployment(deployment *extensions.Deployment, w io.Writer, withNamespa if _, err := fmt.Fprintf(w, "%s\t%s\t%s", deployment.Name, updatedReplicas, age); err != nil { return err } - _, err := fmt.Fprint(w, appendLabels(deployment.Labels, columnLabels)) + _, err := fmt.Fprint(w, appendLabels(deployment.Labels, options.columnLabels)) return err } -func printDeploymentList(list *extensions.DeploymentList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printDeploymentList(list *extensions.DeploymentList, w io.Writer, options printOptions) error { for _, item := range list.Items { - if err := printDeployment(&item, w, withNamespace, wide, showAll, columnLabels); err != nil { + if err := printDeployment(&item, w, options); err != nil { return err } } return nil } -func printHorizontalPodAutoscaler(hpa *extensions.HorizontalPodAutoscaler, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printHorizontalPodAutoscaler(hpa *extensions.HorizontalPodAutoscaler, w io.Writer, options printOptions) error { namespace := hpa.Namespace name := hpa.Name reference := fmt.Sprintf("%s/%s/%s", @@ -1399,7 +1418,7 @@ func printHorizontalPodAutoscaler(hpa *extensions.HorizontalPodAutoscaler, w io. minPods = fmt.Sprintf("%d", *hpa.Spec.MinReplicas) } maxPods := hpa.Spec.MaxReplicas - if withNamespace { + if options.withNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { return err } @@ -1416,13 +1435,13 @@ func printHorizontalPodAutoscaler(hpa *extensions.HorizontalPodAutoscaler, w io. ); err != nil { return err } - _, err := fmt.Fprint(w, appendLabels(hpa.Labels, columnLabels)) + _, err := fmt.Fprint(w, appendLabels(hpa.Labels, options.columnLabels)) return err } -func printHorizontalPodAutoscalerList(list *extensions.HorizontalPodAutoscalerList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printHorizontalPodAutoscalerList(list *extensions.HorizontalPodAutoscalerList, w io.Writer, options printOptions) error { for i := range list.Items { - if err := printHorizontalPodAutoscaler(&list.Items[i], w, withNamespace, wide, showAll, columnLabels); err != nil { + if err := printHorizontalPodAutoscaler(&list.Items[i], w, options); err != nil { return err } } @@ -1495,16 +1514,16 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er } t := reflect.TypeOf(obj) if handler := h.handlerMap[t]; handler != nil { - if !h.noHeaders && t != h.lastType { - headers := append(handler.columns, formatWideHeaders(h.wide, t)...) - headers = append(headers, formatLabelHeaders(h.columnLabels)...) - if h.withNamespace { + 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.withNamespace { headers = append(withNamespacePrefixColumns, headers...) } h.printHeader(headers, w) h.lastType = t } - args := []reflect.Value{reflect.ValueOf(obj), reflect.ValueOf(w), reflect.ValueOf(h.withNamespace), reflect.ValueOf(h.wide), reflect.ValueOf(h.showAll), reflect.ValueOf(h.columnLabels)} + 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 ea02a2b3921..bb69a1f7f34 100644 --- a/pkg/kubectl/resource_printer_test.go +++ b/pkg/kubectl/resource_printer_test.go @@ -213,18 +213,18 @@ func TestJSONPrinter(t *testing.T) { testPrinter(t, &JSONPrinter{}, json.Unmarshal) } -func PrintCustomType(obj *TestPrintType, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func PrintCustomType(obj *TestPrintType, w io.Writer, options printOptions) error { _, err := fmt.Fprintf(w, "%s", obj.Data) return err } -func ErrorPrintHandler(obj *TestPrintType, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func ErrorPrintHandler(obj *TestPrintType, w io.Writer, options printOptions) error { return fmt.Errorf("ErrorPrintHandler error") } func TestCustomTypePrinting(t *testing.T) { columns := []string{"Data"} - printer := NewHumanReadablePrinter(false, false, false, false, []string{}) + printer := NewHumanReadablePrinter(false, false, false, false, false, []string{}) printer.Handler(columns, PrintCustomType) obj := TestPrintType{"test object"} @@ -241,7 +241,7 @@ func TestCustomTypePrinting(t *testing.T) { func TestPrintHandlerError(t *testing.T) { columns := []string{"Data"} - printer := NewHumanReadablePrinter(false, false, false, false, []string{}) + printer := NewHumanReadablePrinter(false, false, false, false, false, []string{}) printer.Handler(columns, ErrorPrintHandler) obj := TestPrintType{"test object"} buffer := &bytes.Buffer{} @@ -252,7 +252,7 @@ func TestPrintHandlerError(t *testing.T) { } func TestUnknownTypePrinting(t *testing.T) { - printer := NewHumanReadablePrinter(false, false, false, false, []string{}) + printer := NewHumanReadablePrinter(false, false, false, false, false, []string{}) buffer := &bytes.Buffer{} err := printer.PrintObj(&TestUnknownType{}, buffer) if err == nil { @@ -456,8 +456,8 @@ func TestPrinters(t *testing.T) { t.Fatal(err) } printers := map[string]ResourcePrinter{ - "humanReadable": NewHumanReadablePrinter(true, false, false, false, []string{}), - "humanReadableHeaders": NewHumanReadablePrinter(false, false, false, false, []string{}), + "humanReadable": NewHumanReadablePrinter(true, false, false, false, false, []string{}), + "humanReadableHeaders": NewHumanReadablePrinter(false, false, false, false, false, []string{}), "json": &JSONPrinter{}, "yaml": &YAMLPrinter{}, "template": templatePrinter, @@ -497,7 +497,7 @@ func TestPrinters(t *testing.T) { func TestPrintEventsResultSorted(t *testing.T) { // Arrange - printer := NewHumanReadablePrinter(false /* noHeaders */, false, false, false, []string{}) + printer := NewHumanReadablePrinter(false /* noHeaders */, false, false, false, false, []string{}) obj := api.EventList{ Items: []api.Event{ @@ -541,7 +541,7 @@ func TestPrintEventsResultSorted(t *testing.T) { } func TestPrintNodeStatus(t *testing.T) { - printer := NewHumanReadablePrinter(false, false, false, false, []string{}) + printer := NewHumanReadablePrinter(false, false, false, false, false, []string{}) table := []struct { node api.Node status string @@ -752,7 +752,7 @@ func TestPrintHumanReadableService(t *testing.T) { for _, svc := range tests { buff := bytes.Buffer{} - printService(&svc, &buff, false, false, false, []string{}) + printService(&svc, &buff, printOptions{false, false, false, false, false, []string{}}) output := string(buff.Bytes()) ip := svc.Spec.ClusterIP if !strings.Contains(output, ip) { @@ -934,7 +934,7 @@ func TestPrintHumanReadableWithNamespace(t *testing.T) { for _, test := range table { if test.isNamespaced { // Expect output to include namespace when requested. - printer := NewHumanReadablePrinter(false, true, false, false, []string{}) + printer := NewHumanReadablePrinter(false, true, false, false, false, []string{}) buffer := &bytes.Buffer{} err := printer.PrintObj(test.obj, buffer) if err != nil { @@ -946,7 +946,7 @@ func TestPrintHumanReadableWithNamespace(t *testing.T) { } } else { // Expect error when trying to get all namespaces for un-namespaced object. - printer := NewHumanReadablePrinter(false, true, false, false, []string{}) + printer := NewHumanReadablePrinter(false, true, false, false, false, []string{}) buffer := &bytes.Buffer{} err := printer.PrintObj(test.obj, buffer) if err == nil { @@ -1041,7 +1041,7 @@ func TestPrintPod(t *testing.T) { buf := bytes.NewBuffer([]byte{}) for _, test := range tests { - printPod(&test.pod, buf, false, false, true, []string{}) + printPod(&test.pod, buf, printOptions{false, false, false, true, false, []string{}}) // We ignore time if !strings.HasPrefix(buf.String(), test.expect) { t.Fatalf("Expected: %s, got: %s", test.expect, buf.String()) @@ -1134,7 +1134,7 @@ func TestPrintNonTerminatedPod(t *testing.T) { buf := bytes.NewBuffer([]byte{}) for _, test := range tests { - printPod(&test.pod, buf, false, false, false, []string{}) + printPod(&test.pod, buf, printOptions{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()) @@ -1194,7 +1194,7 @@ func TestPrintPodWithLabels(t *testing.T) { buf := bytes.NewBuffer([]byte{}) for _, test := range tests { - printPod(&test.pod, buf, false, false, false, test.labelColumns) + printPod(&test.pod, buf, printOptions{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()) @@ -1217,7 +1217,6 @@ func TestTranslateTimestamp(t *testing.T) { {"5 minutes ago", translateTimestamp(unversioned.Time{Time: time.Now().Add(-3e11)}), "5m"}, {"an hour ago", translateTimestamp(unversioned.Time{Time: time.Now().Add(-6e12)}), "1h"}, {"2 days ago", translateTimestamp(unversioned.Time{Time: time.Now().AddDate(0, 0, -2)}), "2d"}, - {"months ago", translateTimestamp(unversioned.Time{Time: time.Now().AddDate(0, -3, 0)}), "92d"}, {"10 years ago", translateTimestamp(unversioned.Time{Time: time.Now().AddDate(-10, 0, 0)}), "10y"}, } for _, test := range tl { @@ -1256,7 +1255,7 @@ func TestPrintDeployment(t *testing.T) { buf := bytes.NewBuffer([]byte{}) for _, test := range tests { - printDeployment(&test.deployment, buf, false, false, true, []string{}) + printDeployment(&test.deployment, buf, printOptions{false, false, false, true, false, []string{}}) if buf.String() != test.expect { t.Fatalf("Expected: %s, got: %s", test.expect, buf.String()) }