1/*
2Copyright 2018 The Kubernetes Authors.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8    http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package get
18
19import (
20	"github.com/spf13/cobra"
21	"k8s.io/cli-runtime/pkg/genericclioptions"
22
23	"k8s.io/apimachinery/pkg/runtime/schema"
24	"k8s.io/cli-runtime/pkg/printers"
25)
26
27// HumanPrintFlags provides default flags necessary for printing.
28// Given the following flag values, a printer can be requested that knows
29// how to handle printing based on these values.
30type HumanPrintFlags struct {
31	ShowKind     *bool
32	ShowLabels   *bool
33	SortBy       *string
34	ColumnLabels *[]string
35
36	// get.go-specific values
37	NoHeaders bool
38
39	Kind          schema.GroupKind
40	WithNamespace bool
41}
42
43// SetKind sets the Kind option
44func (f *HumanPrintFlags) SetKind(kind schema.GroupKind) {
45	f.Kind = kind
46}
47
48// EnsureWithKind sets the "Showkind" humanreadable option to true.
49func (f *HumanPrintFlags) EnsureWithKind() error {
50	showKind := true
51	f.ShowKind = &showKind
52	return nil
53}
54
55// EnsureWithNamespace sets the "WithNamespace" humanreadable option to true.
56func (f *HumanPrintFlags) EnsureWithNamespace() error {
57	f.WithNamespace = true
58	return nil
59}
60
61// AllowedFormats returns more customized formating options
62func (f *HumanPrintFlags) AllowedFormats() []string {
63	return []string{"wide"}
64}
65
66// ToPrinter receives an outputFormat and returns a printer capable of
67// handling human-readable output.
68func (f *HumanPrintFlags) ToPrinter(outputFormat string) (printers.ResourcePrinter, error) {
69	if len(outputFormat) > 0 && outputFormat != "wide" {
70		return nil, genericclioptions.NoCompatiblePrinterError{Options: f, AllowedFormats: f.AllowedFormats()}
71	}
72
73	showKind := false
74	if f.ShowKind != nil {
75		showKind = *f.ShowKind
76	}
77
78	showLabels := false
79	if f.ShowLabels != nil {
80		showLabels = *f.ShowLabels
81	}
82
83	columnLabels := []string{}
84	if f.ColumnLabels != nil {
85		columnLabels = *f.ColumnLabels
86	}
87
88	p := printers.NewTablePrinter(printers.PrintOptions{
89		Kind:          f.Kind,
90		WithKind:      showKind,
91		NoHeaders:     f.NoHeaders,
92		Wide:          outputFormat == "wide",
93		WithNamespace: f.WithNamespace,
94		ColumnLabels:  columnLabels,
95		ShowLabels:    showLabels,
96	})
97
98	// TODO(juanvallejo): handle sorting here
99
100	return p, nil
101}
102
103// AddFlags receives a *cobra.Command reference and binds
104// flags related to human-readable printing to it
105func (f *HumanPrintFlags) AddFlags(c *cobra.Command) {
106	if f.ShowLabels != nil {
107		c.Flags().BoolVar(f.ShowLabels, "show-labels", *f.ShowLabels, "When printing, show all labels as the last column (default hide labels column)")
108	}
109	if f.SortBy != nil {
110		c.Flags().StringVar(f.SortBy, "sort-by", *f.SortBy, "If non-empty, sort list types using this field specification.  The field specification is expressed as a JSONPath expression (e.g. '{.metadata.name}'). The field in the API resource specified by this JSONPath expression must be an integer or a string.")
111	}
112	if f.ColumnLabels != nil {
113		c.Flags().StringSliceVarP(f.ColumnLabels, "label-columns", "L", *f.ColumnLabels, "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 options like -L label1 -L label2...")
114	}
115	if f.ShowKind != nil {
116		c.Flags().BoolVar(f.ShowKind, "show-kind", *f.ShowKind, "If present, list the resource type for the requested object(s).")
117	}
118}
119
120// NewHumanPrintFlags returns flags associated with
121// human-readable printing, with default values set.
122func NewHumanPrintFlags() *HumanPrintFlags {
123	showLabels := false
124	sortBy := ""
125	showKind := false
126	columnLabels := []string{}
127
128	return &HumanPrintFlags{
129		NoHeaders:     false,
130		WithNamespace: false,
131		ColumnLabels:  &columnLabels,
132
133		Kind:       schema.GroupKind{},
134		ShowLabels: &showLabels,
135		SortBy:     &sortBy,
136		ShowKind:   &showKind,
137	}
138}
139