github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/cmd/context.go (about) 1 package cmd 2 3 import ( 4 "fmt" 5 "sort" 6 "strings" 7 8 "github.com/olli-ai/jx/v2/pkg/cmd/helper" 9 10 "github.com/olli-ai/jx/v2/pkg/kube" 11 12 "github.com/spf13/cobra" 13 14 "github.com/olli-ai/jx/v2/pkg/cmd/opts" 15 "github.com/olli-ai/jx/v2/pkg/cmd/templates" 16 "github.com/olli-ai/jx/v2/pkg/util" 17 "gopkg.in/AlecAivazis/survey.v1" 18 "k8s.io/client-go/tools/clientcmd" 19 ) 20 21 type ContextOptions struct { 22 *opts.CommonOptions 23 24 Filter string 25 } 26 27 var ( 28 context_long = templates.LongDesc(` 29 Displays or changes the current Kubernetes context (cluster).`) 30 context_example = templates.Examples(` 31 # to select the context to switch to 32 jx context 33 34 # or the more concise alias 35 jx ctx 36 37 # view the current context 38 jx ctx -b`) 39 ) 40 41 func NewCmdContext(commonOpts *opts.CommonOptions) *cobra.Command { 42 options := &ContextOptions{ 43 CommonOptions: commonOpts, 44 } 45 cmd := &cobra.Command{ 46 Use: "context", 47 Aliases: []string{"ctx"}, 48 Short: "View or change the current Kubernetes context (Kubernetes cluster)", 49 Long: context_long, 50 Example: context_example, 51 Run: func(cmd *cobra.Command, args []string) { 52 options.Cmd = cmd 53 options.Args = args 54 err := options.Run() 55 helper.CheckErr(err) 56 }, 57 } 58 cmd.Flags().StringVarP(&options.Filter, "filter", "f", "", "Filter the list of contexts to switch between using the given text") 59 return cmd 60 } 61 62 func (o *ContextOptions) Run() error { 63 config, po, err := o.Kube().LoadConfig() 64 if err != nil { 65 return err 66 } 67 68 if config == nil || config.Contexts == nil || len(config.Contexts) == 0 { 69 return fmt.Errorf("No Kubernetes contexts available! Try create or connect to cluster?") 70 } 71 72 contextNames := []string{} 73 for k, v := range config.Contexts { 74 if k != "" && v != nil { 75 if o.Filter == "" || strings.Index(k, o.Filter) >= 0 { 76 contextNames = append(contextNames, k) 77 } 78 } 79 } 80 sort.Strings(contextNames) 81 82 ctxName := "" 83 args := o.Args 84 if len(args) > 0 { 85 ctxName = args[0] 86 if util.StringArrayIndex(contextNames, ctxName) < 0 { 87 return util.InvalidArg(ctxName, contextNames) 88 } 89 } 90 91 if ctxName == "" && !o.BatchMode { 92 defaultCtxName := config.CurrentContext 93 pick, err := o.PickContext(contextNames, defaultCtxName) 94 if err != nil { 95 return err 96 } 97 ctxName = pick 98 } 99 info := util.ColorInfo 100 if ctxName != "" && ctxName != config.CurrentContext { 101 ctx := config.Contexts[ctxName] 102 if ctx == nil { 103 return fmt.Errorf("Could not find Kubernetes context %s", ctxName) 104 } 105 newConfig := *config 106 newConfig.CurrentContext = ctxName 107 err = clientcmd.ModifyConfig(po, newConfig, false) 108 if err != nil { 109 return fmt.Errorf("Failed to update the kube config %s", err) 110 } 111 fmt.Fprintf(o.Out, "Now using namespace '%s' from context named '%s' on server '%s'.\n", 112 info(ctx.Namespace), info(newConfig.CurrentContext), info(kube.Server(config, ctx))) 113 } else { 114 ns := kube.CurrentNamespace(config) 115 server := kube.CurrentServer(config) 116 fmt.Fprintf(o.Out, "Using namespace '%s' from context named '%s' on server '%s'.\n", 117 info(ns), info(config.CurrentContext), info(server)) 118 } 119 return nil 120 } 121 122 func (o *ContextOptions) PickContext(names []string, defaultValue string) (string, error) { 123 surveyOpts := survey.WithStdio(o.In, o.Out, o.Err) 124 if len(names) == 0 { 125 return "", nil 126 } 127 if len(names) == 1 { 128 return names[0], nil 129 } 130 name := "" 131 prompt := &survey.Select{ 132 Message: "Change Kubernetes context:", 133 Options: names, 134 Default: defaultValue, 135 } 136 err := survey.AskOne(prompt, &name, nil, surveyOpts) 137 return name, err 138 }