github.com/jenkins-x/jx/v2@v2.1.155/pkg/cmd/context.go (about)

     1  package cmd
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  	"strings"
     7  
     8  	"github.com/jenkins-x/jx/v2/pkg/cmd/helper"
     9  
    10  	"github.com/jenkins-x/jx/v2/pkg/kube"
    11  
    12  	"github.com/spf13/cobra"
    13  
    14  	"github.com/jenkins-x/jx/v2/pkg/cmd/opts"
    15  	"github.com/jenkins-x/jx/v2/pkg/cmd/templates"
    16  	"github.com/jenkins-x/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  }