...

Source file src/k8s.io/kubectl/pkg/cmd/config/set_context.go

Documentation: k8s.io/kubectl/pkg/cmd/config

     1  /*
     2  Copyright 2014 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package config
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"io"
    23  
    24  	"github.com/spf13/cobra"
    25  
    26  	"k8s.io/client-go/tools/clientcmd"
    27  	clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
    28  	cliflag "k8s.io/component-base/cli/flag"
    29  	cmdutil "k8s.io/kubectl/pkg/cmd/util"
    30  	"k8s.io/kubectl/pkg/util/completion"
    31  	"k8s.io/kubectl/pkg/util/i18n"
    32  	"k8s.io/kubectl/pkg/util/templates"
    33  )
    34  
    35  type setContextOptions struct {
    36  	configAccess clientcmd.ConfigAccess
    37  	name         string
    38  	currContext  bool
    39  	cluster      cliflag.StringFlag
    40  	authInfo     cliflag.StringFlag
    41  	namespace    cliflag.StringFlag
    42  }
    43  
    44  var (
    45  	setContextLong = templates.LongDesc(i18n.T(`
    46  		Set a context entry in kubeconfig.
    47  
    48  		Specifying a name that already exists will merge new fields on top of existing values for those fields.`))
    49  
    50  	setContextExample = templates.Examples(`
    51  		# Set the user field on the gce context entry without touching other values
    52  		kubectl config set-context gce --user=cluster-admin`)
    53  )
    54  
    55  // NewCmdConfigSetContext returns a Command instance for 'config set-context' sub command
    56  func NewCmdConfigSetContext(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
    57  	options := &setContextOptions{configAccess: configAccess}
    58  
    59  	cmd := &cobra.Command{
    60  		Use:                   fmt.Sprintf("set-context [NAME | --current] [--%v=cluster_nickname] [--%v=user_nickname] [--%v=namespace]", clientcmd.FlagClusterName, clientcmd.FlagAuthInfoName, clientcmd.FlagNamespace),
    61  		DisableFlagsInUseLine: true,
    62  		Short:                 i18n.T("Set a context entry in kubeconfig"),
    63  		Long:                  setContextLong,
    64  		Example:               setContextExample,
    65  		ValidArgsFunction:     completion.ContextCompletionFunc,
    66  		Run: func(cmd *cobra.Command, args []string) {
    67  			cmdutil.CheckErr(options.complete(cmd))
    68  			name, exists, err := options.run()
    69  			cmdutil.CheckErr(err)
    70  			if exists {
    71  				fmt.Fprintf(out, "Context %q modified.\n", name)
    72  			} else {
    73  				fmt.Fprintf(out, "Context %q created.\n", name)
    74  			}
    75  		},
    76  	}
    77  
    78  	cmd.Flags().BoolVar(&options.currContext, "current", options.currContext, "Modify the current context")
    79  	cmd.Flags().Var(&options.cluster, clientcmd.FlagClusterName, clientcmd.FlagClusterName+" for the context entry in kubeconfig")
    80  	cmd.Flags().Var(&options.authInfo, clientcmd.FlagAuthInfoName, clientcmd.FlagAuthInfoName+" for the context entry in kubeconfig")
    81  	cmd.Flags().Var(&options.namespace, clientcmd.FlagNamespace, clientcmd.FlagNamespace+" for the context entry in kubeconfig")
    82  
    83  	return cmd
    84  }
    85  
    86  func (o setContextOptions) run() (string, bool, error) {
    87  	err := o.validate()
    88  	if err != nil {
    89  		return "", false, err
    90  	}
    91  
    92  	config, err := o.configAccess.GetStartingConfig()
    93  	if err != nil {
    94  		return "", false, err
    95  	}
    96  
    97  	name := o.name
    98  	if o.currContext {
    99  		if len(config.CurrentContext) == 0 {
   100  			return "", false, errors.New("no current context is set")
   101  		}
   102  		name = config.CurrentContext
   103  	}
   104  
   105  	startingStanza, exists := config.Contexts[name]
   106  	if !exists {
   107  		startingStanza = clientcmdapi.NewContext()
   108  	}
   109  	context := o.modifyContext(*startingStanza)
   110  	config.Contexts[name] = &context
   111  
   112  	if err := clientcmd.ModifyConfig(o.configAccess, *config, true); err != nil {
   113  		return name, exists, err
   114  	}
   115  
   116  	return name, exists, nil
   117  }
   118  
   119  func (o *setContextOptions) modifyContext(existingContext clientcmdapi.Context) clientcmdapi.Context {
   120  	modifiedContext := existingContext
   121  
   122  	if o.cluster.Provided() {
   123  		modifiedContext.Cluster = o.cluster.Value()
   124  	}
   125  	if o.authInfo.Provided() {
   126  		modifiedContext.AuthInfo = o.authInfo.Value()
   127  	}
   128  	if o.namespace.Provided() {
   129  		modifiedContext.Namespace = o.namespace.Value()
   130  	}
   131  
   132  	return modifiedContext
   133  }
   134  
   135  func (o *setContextOptions) complete(cmd *cobra.Command) error {
   136  	args := cmd.Flags().Args()
   137  	if len(args) > 1 {
   138  		return helpErrorf(cmd, "Unexpected args: %v", args)
   139  	}
   140  	if len(args) == 1 {
   141  		o.name = args[0]
   142  	}
   143  	return nil
   144  }
   145  
   146  func (o setContextOptions) validate() error {
   147  	if len(o.name) == 0 && !o.currContext {
   148  		return errors.New("you must specify a non-empty context name or --current")
   149  	}
   150  	if len(o.name) > 0 && o.currContext {
   151  		return errors.New("you cannot specify both a context name and --current")
   152  	}
   153  
   154  	return nil
   155  }
   156  

View as plain text