From affa85fab03bf4e276d0056431853cb12671533c Mon Sep 17 00:00:00 2001 From: deads2k Date: Tue, 3 Feb 2015 08:56:06 -0500 Subject: [PATCH] add flag to manage $KUBECONFIG files --- docs/kubectl.md | 24 ++++++++++----- pkg/kubectl/cmd/config/config.go | 52 +++++++++++++++++++++++++++----- pkg/kubectl/cmd/config/view.go | 3 +- 3 files changed, 63 insertions(+), 16 deletions(-) diff --git a/docs/kubectl.md b/docs/kubectl.md index dac3a5e6c91..344704db9f7 100644 --- a/docs/kubectl.md +++ b/docs/kubectl.md @@ -361,10 +361,11 @@ Available Commands: --client-key="": Path to a client key file for TLS. --cluster="": The name of the kubeconfig cluster to use --context="": The name of the kubeconfig context to use + --envvar=false: use the .kubeconfig from $KUBECONFIG --global=false: use the .kubeconfig from /home/username --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. --kubeconfig="": use a particular .kubeconfig file - --local=true: use the .kubeconfig in the current directory + --local=false: use the .kubeconfig in the current directory --log_backtrace_at=:0: when logging hits line file:N, emit a stack trace --log_dir=: If non-empty, write log files in this directory --log_flush_frequency=5s: Maximum number of seconds between log flushes @@ -415,11 +416,12 @@ Usage: --client-key="": Path to a client key file for TLS. --cluster="": The name of the kubeconfig cluster to use --context="": The name of the kubeconfig context to use + --envvar=false: use the .kubeconfig from $KUBECONFIG --global=false: use the .kubeconfig from /home/username -h, --help=false: help for view --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. --kubeconfig="": use a particular .kubeconfig file - --local=true: use the .kubeconfig in the current directory + --local=false: use the .kubeconfig in the current directory --log_backtrace_at=:0: when logging hits line file:N, emit a stack trace --log_dir=: If non-empty, write log files in this directory --log_flush_frequency=5s: Maximum number of seconds between log flushes @@ -459,11 +461,12 @@ Usage: --client-key="": Path to a client key file for TLS. --cluster="": The name of the kubeconfig cluster to use --context="": The name of the kubeconfig context to use + --envvar=false: use the .kubeconfig from $KUBECONFIG --global=false: use the .kubeconfig from /home/username -h, --help=false: help for set-cluster --insecure-skip-tls-verify=false: insecure-skip-tls-verify for the cluster entry in .kubeconfig --kubeconfig="": use a particular .kubeconfig file - --local=true: use the .kubeconfig in the current directory + --local=false: use the .kubeconfig in the current directory --log_backtrace_at=:0: when logging hits line file:N, emit a stack trace --log_dir=: If non-empty, write log files in this directory --log_flush_frequency=5s: Maximum number of seconds between log flushes @@ -502,11 +505,12 @@ Usage: --client-key=: client-key for the user entry in .kubeconfig --cluster="": The name of the kubeconfig cluster to use --context="": The name of the kubeconfig context to use + --envvar=false: use the .kubeconfig from $KUBECONFIG --global=false: use the .kubeconfig from /home/username -h, --help=false: help for set-credentials --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. --kubeconfig="": use a particular .kubeconfig file - --local=true: use the .kubeconfig in the current directory + --local=false: use the .kubeconfig in the current directory --log_backtrace_at=:0: when logging hits line file:N, emit a stack trace --log_dir=: If non-empty, write log files in this directory --log_flush_frequency=5s: Maximum number of seconds between log flushes @@ -545,11 +549,12 @@ Usage: --client-key="": Path to a client key file for TLS. --cluster=: cluster for the context entry in .kubeconfig --context="": The name of the kubeconfig context to use + --envvar=false: use the .kubeconfig from $KUBECONFIG --global=false: use the .kubeconfig from /home/username -h, --help=false: help for set-context --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. --kubeconfig="": use a particular .kubeconfig file - --local=true: use the .kubeconfig in the current directory + --local=false: use the .kubeconfig in the current directory --log_backtrace_at=:0: when logging hits line file:N, emit a stack trace --log_dir=: If non-empty, write log files in this directory --log_flush_frequency=5s: Maximum number of seconds between log flushes @@ -588,11 +593,12 @@ Usage: --client-key="": Path to a client key file for TLS. --cluster="": The name of the kubeconfig cluster to use --context="": The name of the kubeconfig context to use + --envvar=false: use the .kubeconfig from $KUBECONFIG --global=false: use the .kubeconfig from /home/username -h, --help=false: help for config --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. --kubeconfig="": use a particular .kubeconfig file - --local=true: use the .kubeconfig in the current directory + --local=false: use the .kubeconfig in the current directory --log_backtrace_at=:0: when logging hits line file:N, emit a stack trace --log_dir=: If non-empty, write log files in this directory --log_flush_frequency=5s: Maximum number of seconds between log flushes @@ -629,11 +635,12 @@ Usage: --client-key="": Path to a client key file for TLS. --cluster="": The name of the kubeconfig cluster to use --context="": The name of the kubeconfig context to use + --envvar=false: use the .kubeconfig from $KUBECONFIG --global=false: use the .kubeconfig from /home/username -h, --help=false: help for config --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. --kubeconfig="": use a particular .kubeconfig file - --local=true: use the .kubeconfig in the current directory + --local=false: use the .kubeconfig in the current directory --log_backtrace_at=:0: when logging hits line file:N, emit a stack trace --log_dir=: If non-empty, write log files in this directory --log_flush_frequency=5s: Maximum number of seconds between log flushes @@ -667,11 +674,12 @@ Usage: --client-key="": Path to a client key file for TLS. --cluster="": The name of the kubeconfig cluster to use --context="": The name of the kubeconfig context to use + --envvar=false: use the .kubeconfig from $KUBECONFIG --global=false: use the .kubeconfig from /home/username -h, --help=false: help for config --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. --kubeconfig="": use a particular .kubeconfig file - --local=true: use the .kubeconfig in the current directory + --local=false: use the .kubeconfig in the current directory --log_backtrace_at=:0: when logging hits line file:N, emit a stack trace --log_dir=: If non-empty, write log files in this directory --log_flush_frequency=5s: Maximum number of seconds between log flushes diff --git a/pkg/kubectl/cmd/config/config.go b/pkg/kubectl/cmd/config/config.go index 4c6bf23a69c..dca868c0e30 100644 --- a/pkg/kubectl/cmd/config/config.go +++ b/pkg/kubectl/cmd/config/config.go @@ -17,6 +17,7 @@ limitations under the License. package config import ( + "fmt" "io" "os" "strconv" @@ -31,6 +32,7 @@ import ( type pathOptions struct { local bool global bool + envvar bool specifiedFile string } @@ -47,8 +49,9 @@ func NewCmdConfig(out io.Writer) *cobra.Command { } // file paths are common to all sub commands - cmd.PersistentFlags().BoolVar(&pathOptions.local, "local", true, "use the .kubeconfig in the current directory") + cmd.PersistentFlags().BoolVar(&pathOptions.local, "local", false, "use the .kubeconfig in the current directory") cmd.PersistentFlags().BoolVar(&pathOptions.global, "global", false, "use the .kubeconfig from "+os.Getenv("HOME")) + cmd.PersistentFlags().BoolVar(&pathOptions.envvar, "envvar", false, "use the .kubeconfig from $KUBECONFIG") cmd.PersistentFlags().StringVar(&pathOptions.specifiedFile, "kubeconfig", "", "use a particular .kubeconfig file") cmd.AddCommand(NewCmdConfigView(out, pathOptions)) @@ -65,18 +68,53 @@ func NewCmdConfig(out io.Writer) *cobra.Command { func (o *pathOptions) getStartingConfig() (*clientcmdapi.Config, string, error) { filename := "" config := clientcmdapi.NewConfig() - switch { - case o.global: - filename = os.Getenv("HOME") + "/.kube/.kubeconfig" - config = getConfigFromFileOrDie(filename) - case len(o.specifiedFile) > 0: + if len(o.specifiedFile) > 0 { filename = o.specifiedFile config = getConfigFromFileOrDie(filename) + } + + if o.global { + if len(filename) > 0 { + return nil, "", fmt.Errorf("already loading from %v, cannot specify global as well", filename) + } + + filename = os.Getenv("HOME") + "/.kube/.kubeconfig" + config = getConfigFromFileOrDie(filename) + } + + if o.envvar { + if len(filename) > 0 { + return nil, "", fmt.Errorf("already loading from %v, cannot specify global as well", filename) + } + + filename = os.Getenv(clientcmd.RecommendedConfigPathEnvVar) + if len(filename) == 0 { + return nil, "", fmt.Errorf("environment variable %v does not have a value", clientcmd.RecommendedConfigPathEnvVar) + } + + config = getConfigFromFileOrDie(filename) + } + + if o.local { + if len(filename) > 0 { + return nil, "", fmt.Errorf("already loading from %v, cannot specify global as well", filename) + } - case o.local: filename = ".kubeconfig" config = getConfigFromFileOrDie(filename) + + } + + // no specific flag was set, first attempt to use the envvar, then use local + if len(filename) == 0 { + if len(os.Getenv(clientcmd.RecommendedConfigPathEnvVar)) > 0 { + filename = os.Getenv(clientcmd.RecommendedConfigPathEnvVar) + config = getConfigFromFileOrDie(filename) + } else { + filename = ".kubeconfig" + config = getConfigFromFileOrDie(filename) + } } return config, filename, nil diff --git a/pkg/kubectl/cmd/config/view.go b/pkg/kubectl/cmd/config/view.go index ea678d0ba41..4f8c83fc50e 100644 --- a/pkg/kubectl/cmd/config/view.go +++ b/pkg/kubectl/cmd/config/view.go @@ -19,6 +19,7 @@ package config import ( "fmt" "io" + "os" "github.com/ghodss/yaml" "github.com/spf13/cobra" @@ -82,7 +83,7 @@ func (o *viewOptions) getStartingConfig() (*clientcmdapi.Config, string, error) switch { case o.merge: loadingRules := clientcmd.NewClientConfigLoadingRules() - loadingRules.EnvVarPath = "" + loadingRules.EnvVarPath = os.Getenv("KUBECONFIG") loadingRules.CommandLinePath = o.pathOptions.specifiedFile overrides := &clientcmd.ConfigOverrides{}