1
16
17 package config
18
19 import (
20 "fmt"
21 "io"
22 "sort"
23 "strings"
24
25 "github.com/liggitt/tabwriter"
26 "github.com/spf13/cobra"
27
28 utilerrors "k8s.io/apimachinery/pkg/util/errors"
29 "k8s.io/apimachinery/pkg/util/sets"
30 "k8s.io/cli-runtime/pkg/genericiooptions"
31 "k8s.io/cli-runtime/pkg/printers"
32 "k8s.io/client-go/tools/clientcmd"
33 clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
34 cmdutil "k8s.io/kubectl/pkg/cmd/util"
35 "k8s.io/kubectl/pkg/util/i18n"
36 "k8s.io/kubectl/pkg/util/templates"
37 )
38
39
40 type GetContextsOptions struct {
41 configAccess clientcmd.ConfigAccess
42 nameOnly bool
43 showHeaders bool
44 contextNames []string
45
46 outputFormat string
47 noHeaders bool
48
49 genericiooptions.IOStreams
50 }
51
52 var (
53 getContextsLong = templates.LongDesc(i18n.T(`Display one or many contexts from the kubeconfig file.`))
54
55 getContextsExample = templates.Examples(`
56 # List all the contexts in your kubeconfig file
57 kubectl config get-contexts
58
59 # Describe one context in your kubeconfig file
60 kubectl config get-contexts my-context`)
61 )
62
63
64
65 func NewCmdConfigGetContexts(streams genericiooptions.IOStreams, configAccess clientcmd.ConfigAccess) *cobra.Command {
66 options := &GetContextsOptions{
67 configAccess: configAccess,
68
69 IOStreams: streams,
70 }
71
72 cmd := &cobra.Command{
73 Use: "get-contexts [(-o|--output=)name)]",
74 DisableFlagsInUseLine: true,
75 Short: i18n.T("Describe one or many contexts"),
76 Long: getContextsLong,
77 Example: getContextsExample,
78 Run: func(cmd *cobra.Command, args []string) {
79 cmdutil.CheckErr(options.Complete(cmd, args))
80 cmdutil.CheckErr(options.Validate())
81 cmdutil.CheckErr(options.RunGetContexts())
82 },
83 }
84
85 cmd.Flags().BoolVar(&options.noHeaders, "no-headers", options.noHeaders, "When using the default or custom-column output format, don't print headers (default print headers).")
86 cmd.Flags().StringVarP(&options.outputFormat, "output", "o", options.outputFormat, `Output format. One of: (name).`)
87 return cmd
88 }
89
90
91 func (o *GetContextsOptions) Complete(cmd *cobra.Command, args []string) error {
92 supportedOutputTypes := sets.NewString("", "name")
93 if !supportedOutputTypes.Has(o.outputFormat) {
94 return fmt.Errorf("--output %v is not available in kubectl config get-contexts; resetting to default output format", o.outputFormat)
95 }
96 o.contextNames = args
97 o.nameOnly = false
98 if o.outputFormat == "name" {
99 o.nameOnly = true
100 }
101 o.showHeaders = true
102 if cmdutil.GetFlagBool(cmd, "no-headers") || o.nameOnly {
103 o.showHeaders = false
104 }
105
106 return nil
107 }
108
109
110 func (o *GetContextsOptions) Validate() error {
111 return nil
112 }
113
114
115 func (o GetContextsOptions) RunGetContexts() error {
116 config, err := o.configAccess.GetStartingConfig()
117 if err != nil {
118 return err
119 }
120
121 out, found := o.Out.(*tabwriter.Writer)
122 if !found {
123 out = printers.GetNewTabWriter(o.Out)
124 defer out.Flush()
125 }
126
127
128
129 allErrs := []error{}
130 toPrint := []string{}
131 if len(o.contextNames) == 0 {
132 for name := range config.Contexts {
133 toPrint = append(toPrint, name)
134 }
135 } else {
136 for _, name := range o.contextNames {
137 _, ok := config.Contexts[name]
138 if ok {
139 toPrint = append(toPrint, name)
140 } else {
141 allErrs = append(allErrs, fmt.Errorf("context %v not found", name))
142 }
143 }
144 }
145 if o.showHeaders {
146 err = printContextHeaders(out, o.nameOnly)
147 if err != nil {
148 allErrs = append(allErrs, err)
149 }
150 }
151
152 sort.Strings(toPrint)
153 for _, name := range toPrint {
154 err = printContext(name, config.Contexts[name], out, o.nameOnly, config.CurrentContext == name)
155 if err != nil {
156 allErrs = append(allErrs, err)
157 }
158 }
159
160 return utilerrors.NewAggregate(allErrs)
161 }
162
163 func printContextHeaders(out io.Writer, nameOnly bool) error {
164 columnNames := []string{"CURRENT", "NAME", "CLUSTER", "AUTHINFO", "NAMESPACE"}
165 if nameOnly {
166 columnNames = columnNames[:1]
167 }
168 _, err := fmt.Fprintf(out, "%s\n", strings.Join(columnNames, "\t"))
169 return err
170 }
171
172 func printContext(name string, context *clientcmdapi.Context, w io.Writer, nameOnly, current bool) error {
173 if nameOnly {
174 _, err := fmt.Fprintf(w, "%s\n", name)
175 return err
176 }
177 prefix := " "
178 if current {
179 prefix = "*"
180 }
181 _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", prefix, name, context.Cluster, context.AuthInfo, context.Namespace)
182 return err
183 }
184
View as plain text