make kubectl config behave more expectedly

This commit is contained in:
deads2k 2015-04-08 10:32:32 -04:00
parent 2215a64567
commit b2e3f2185e
30 changed files with 688 additions and 305 deletions

View File

@ -1,11 +1,11 @@
## kubectl config set-cluster
Sets a cluster entry in .kubeconfig
Sets a cluster entry in kubeconfig
### Synopsis
Sets a cluster entry in .kubeconfig.
Sets a cluster entry in kubeconfig.
Specifying a name that already exists will merge new fields on top of existing values for those fields.
```
@ -28,12 +28,12 @@ $ kubectl config set-cluster e2e --insecure-skip-tls-verify=true
### Options
```
--api-version=: api-version for the cluster entry in .kubeconfig
--certificate-authority=: path to certificate-authority for the cluster entry in .kubeconfig
--embed-certs=false: embed-certs for the cluster entry in .kubeconfig
--api-version=: api-version for the cluster entry in kubeconfig
--certificate-authority=: path to certificate-authority for the cluster entry in kubeconfig
--embed-certs=false: embed-certs for the cluster entry in kubeconfig
-h, --help=false: help for set-cluster
--insecure-skip-tls-verify=false: insecure-skip-tls-verify for the cluster entry in .kubeconfig
--server=: server for the cluster entry in .kubeconfig
--insecure-skip-tls-verify=false: insecure-skip-tls-verify for the cluster entry in kubeconfig
--server=: server for the cluster entry in kubeconfig
```
### Options inherrited from parent commands
@ -45,10 +45,10 @@ $ kubectl config set-cluster e2e --insecure-skip-tls-verify=true
--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
--kubeconfig="": use a particular .kubeconfig file
--local=false: use the .kubeconfig in the current directory
--envvar=false: use the kubeconfig from $KUBECONFIG
--global=false: use the kubeconfig from /home/username/.kube/.kubeconfig
--kubeconfig="": use a particular kubeconfig file
--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

View File

@ -1,11 +1,11 @@
## kubectl config set-context
Sets a context entry in .kubeconfig
Sets a context entry in kubeconfig
### Synopsis
Sets a context entry in .kubeconfig
Sets a context entry in kubeconfig
Specifying a name that already exists will merge new fields on top of existing values for those fields.
```
@ -22,10 +22,10 @@ $ kubectl config set-context gce --user=cluster-admin
### Options
```
--cluster=: cluster for the context entry in .kubeconfig
--cluster=: cluster for the context entry in kubeconfig
-h, --help=false: help for set-context
--namespace=: namespace for the context entry in .kubeconfig
--user=: user for the context entry in .kubeconfig
--namespace=: namespace for the context entry in kubeconfig
--user=: user for the context entry in kubeconfig
```
### Options inherrited from parent commands
@ -38,11 +38,11 @@ $ kubectl config set-context gce --user=cluster-admin
--client-certificate="": Path to a client key file for TLS.
--client-key="": Path to a client key file for TLS.
--context="": The name of the kubeconfig context to use
--envvar=false: use the .kubeconfig from $KUBECONFIG
--global=false: use the .kubeconfig from /home/username
--envvar=false: use the kubeconfig from $KUBECONFIG
--global=false: use the kubeconfig from /home/username/.kube/.kubeconfig
--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=false: use the .kubeconfig in the current directory
--kubeconfig="": use a particular kubeconfig file
--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

View File

@ -1,11 +1,11 @@
## kubectl config set-credentials
Sets a user entry in .kubeconfig
Sets a user entry in kubeconfig
### Synopsis
Sets a user entry in .kubeconfig
Sets a user entry in kubeconfig
Specifying a name that already exists will merge new fields on top of existing values.
Client-certificate flags:
@ -41,14 +41,14 @@ $ kubectl set-credentials cluster-admin --client-certificate=~/.kube/admin.crt -
### Options
```
--auth-path=: auth-path for the user entry in .kubeconfig
--client-certificate=: path to client-certificate for the user entry in .kubeconfig
--client-key=: path to client-key for the user entry in .kubeconfig
--embed-certs=false: embed client cert/key for the user entry in .kubeconfig
--auth-path=: auth-path for the user entry in kubeconfig
--client-certificate=: path to client-certificate for the user entry in kubeconfig
--client-key=: path to client-key for the user entry in kubeconfig
--embed-certs=false: embed client cert/key for the user entry in kubeconfig
-h, --help=false: help for set-credentials
--password=: password for the user entry in .kubeconfig
--token=: token for the user entry in .kubeconfig
--username=: username for the user entry in .kubeconfig
--password=: password for the user entry in kubeconfig
--token=: token for the user entry in kubeconfig
--username=: username for the user entry in kubeconfig
```
### Options inherrited from parent commands
@ -59,11 +59,11 @@ $ kubectl set-credentials cluster-admin --client-certificate=~/.kube/admin.crt -
--certificate-authority="": Path to a cert. file for the certificate authority.
--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
--envvar=false: use the kubeconfig from $KUBECONFIG
--global=false: use the kubeconfig from /home/username/.kube/.kubeconfig
--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=false: use the .kubeconfig in the current directory
--kubeconfig="": use a particular kubeconfig file
--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

View File

@ -1,11 +1,11 @@
## kubectl config set
Sets an individual value in a .kubeconfig file
Sets an individual value in a kubeconfig file
### Synopsis
Sets an individual value in a .kubeconfig file
Sets an individual value in a kubeconfig file
PROPERTY_NAME is a dot delimited name where each token represents either a attribute name or a map key. Map keys may not contain dots.
PROPERTY_VALUE is the new value you wish to set.
@ -30,11 +30,11 @@ kubectl config set PROPERTY_NAME PROPERTY_VALUE
--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
--envvar=false: use the kubeconfig from $KUBECONFIG
--global=false: use the kubeconfig from /home/username/.kube/.kubeconfig
--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=false: use the .kubeconfig in the current directory
--kubeconfig="": use a particular kubeconfig file
--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

View File

@ -1,11 +1,11 @@
## kubectl config unset
Unsets an individual value in a .kubeconfig file
Unsets an individual value in a kubeconfig file
### Synopsis
Unsets an individual value in a .kubeconfig file
Unsets an individual value in a kubeconfig file
PROPERTY_NAME is a dot delimited name where each token represents either a attribute name or a map key. Map keys may not contain dots.
```
@ -29,11 +29,11 @@ kubectl config unset PROPERTY_NAME
--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
--envvar=false: use the kubeconfig from $KUBECONFIG
--global=false: use the kubeconfig from /home/username/.kube/.kubeconfig
--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=false: use the .kubeconfig in the current directory
--kubeconfig="": use a particular kubeconfig file
--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

View File

@ -1,11 +1,11 @@
## kubectl config use-context
Sets the current-context in a .kubeconfig file
Sets the current-context in a kubeconfig file
### Synopsis
Sets the current-context in a .kubeconfig file
Sets the current-context in a kubeconfig file
```
kubectl config use-context CONTEXT_NAME
@ -28,11 +28,11 @@ kubectl config use-context CONTEXT_NAME
--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
--envvar=false: use the kubeconfig from $KUBECONFIG
--global=false: use the kubeconfig from /home/username/.kube/.kubeconfig
--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=false: use the .kubeconfig in the current directory
--kubeconfig="": use a particular kubeconfig file
--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

View File

@ -1,11 +1,11 @@
## kubectl config view
displays merged .kubeconfig settings or a specified .kubeconfig file.
displays merged kubeconfig settings or a specified kubeconfig file.
### Synopsis
displays merged .kubeconfig settings or a specified .kubeconfig file.
displays merged kubeconfig settings or a specified kubeconfig file.
You can use --output=template --template=TEMPLATE to extract specific values.
@ -16,10 +16,10 @@ kubectl config view
### Examples
```
// Show merged .kubeconfig settings.
// Show merged kubeconfig settings.
$ kubectl config view
// Show only local ./.kubeconfig settings
// Show only local kubeconfig settings
$ kubectl config view --local
// Get the password for the e2e user
@ -30,7 +30,7 @@ $ kubectl config view -o template --template='{{range .users}}{{ if eq .name "e2
```
-h, --help=false: help for view
--merge=true: merge together the full hierarchy of .kubeconfig files
--merge=true: merge together the full hierarchy of kubeconfig files
--no-headers=false: When using the default output, don't print headers.
-o, --output="": Output format. One of: json|yaml|template|templatefile.
--output-version="": Output the formatted object with the given version (default api-version).
@ -48,11 +48,11 @@ $ kubectl config view -o template --template='{{range .users}}{{ if eq .name "e2
--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
--envvar=false: use the kubeconfig from $KUBECONFIG
--global=false: use the kubeconfig from /home/username/.kube/.kubeconfig
--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=false: use the .kubeconfig in the current directory
--kubeconfig="": use a particular kubeconfig file
--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

View File

@ -1,11 +1,11 @@
## kubectl config
config modifies .kubeconfig files
config modifies kubeconfig files
### Synopsis
config modifies .kubeconfig files using subcommands like "kubectl config set current-context my-context"
config modifies kubeconfig files using subcommands like "kubectl config set current-context my-context"
```
kubectl config SUBCOMMAND
@ -14,11 +14,11 @@ kubectl config SUBCOMMAND
### Options
```
--envvar=false: use the .kubeconfig from $KUBECONFIG
--global=false: use the .kubeconfig from /home/username
--envvar=false: use the kubeconfig from $KUBECONFIG
--global=false: use the kubeconfig from /home/username/.kube/.kubeconfig
-h, --help=false: help for config
--kubeconfig="": use a particular .kubeconfig file
--local=false: use the .kubeconfig in the current directory
--kubeconfig="": use a particular kubeconfig file
--local=false: use the kubeconfig in the current directory
```
### Options inherrited from parent commands

View File

@ -3,7 +3,7 @@
.SH NAME
.PP
kubectl config set\-cluster \- Sets a cluster entry in .kubeconfig
kubectl config set\-cluster \- Sets a cluster entry in kubeconfig
.SH SYNOPSIS
@ -13,22 +13,22 @@ kubectl config set\-cluster \- Sets a cluster entry in .kubeconfig
.SH DESCRIPTION
.PP
Sets a cluster entry in .kubeconfig.
Sets a cluster entry in kubeconfig.
Specifying a name that already exists will merge new fields on top of existing values for those fields.
.SH OPTIONS
.PP
\fB\-\-api\-version\fP=""
api\-version for the cluster entry in .kubeconfig
api\-version for the cluster entry in kubeconfig
.PP
\fB\-\-certificate\-authority\fP=""
path to certificate\-authority for the cluster entry in .kubeconfig
path to certificate\-authority for the cluster entry in kubeconfig
.PP
\fB\-\-embed\-certs\fP=false
embed\-certs for the cluster entry in .kubeconfig
embed\-certs for the cluster entry in kubeconfig
.PP
\fB\-h\fP, \fB\-\-help\fP=false
@ -36,11 +36,11 @@ Specifying a name that already exists will merge new fields on top of existing v
.PP
\fB\-\-insecure\-skip\-tls\-verify\fP=false
insecure\-skip\-tls\-verify for the cluster entry in .kubeconfig
insecure\-skip\-tls\-verify for the cluster entry in kubeconfig
.PP
\fB\-\-server\fP=""
server for the cluster entry in .kubeconfig
server for the cluster entry in kubeconfig
.SH OPTIONS INHERITED FROM PARENT COMMANDS
@ -70,19 +70,19 @@ Specifying a name that already exists will merge new fields on top of existing v
.PP
\fB\-\-envvar\fP=false
use the .kubeconfig from $KUBECONFIG
use the kubeconfig from $KUBECONFIG
.PP
\fB\-\-global\fP=false
use the .kubeconfig from /home/username
use the kubeconfig from /home/username/.kube/.kubeconfig
.PP
\fB\-\-kubeconfig\fP=""
use a particular .kubeconfig file
use a particular kubeconfig file
.PP
\fB\-\-local\fP=false
use the .kubeconfig in the current directory
use the kubeconfig in the current directory
.PP
\fB\-\-log\_backtrace\_at\fP=:0

View File

@ -3,7 +3,7 @@
.SH NAME
.PP
kubectl config set\-context \- Sets a context entry in .kubeconfig
kubectl config set\-context \- Sets a context entry in kubeconfig
.SH SYNOPSIS
@ -13,14 +13,14 @@ kubectl config set\-context \- Sets a context entry in .kubeconfig
.SH DESCRIPTION
.PP
Sets a context entry in .kubeconfig
Sets a context entry in kubeconfig
Specifying a name that already exists will merge new fields on top of existing values for those fields.
.SH OPTIONS
.PP
\fB\-\-cluster\fP=""
cluster for the context entry in .kubeconfig
cluster for the context entry in kubeconfig
.PP
\fB\-h\fP, \fB\-\-help\fP=false
@ -28,11 +28,11 @@ Specifying a name that already exists will merge new fields on top of existing v
.PP
\fB\-\-namespace\fP=""
namespace for the context entry in .kubeconfig
namespace for the context entry in kubeconfig
.PP
\fB\-\-user\fP=""
user for the context entry in .kubeconfig
user for the context entry in kubeconfig
.SH OPTIONS INHERITED FROM PARENT COMMANDS
@ -66,11 +66,11 @@ Specifying a name that already exists will merge new fields on top of existing v
.PP
\fB\-\-envvar\fP=false
use the .kubeconfig from $KUBECONFIG
use the kubeconfig from $KUBECONFIG
.PP
\fB\-\-global\fP=false
use the .kubeconfig from /home/username
use the kubeconfig from /home/username/.kube/.kubeconfig
.PP
\fB\-\-insecure\-skip\-tls\-verify\fP=false
@ -78,11 +78,11 @@ Specifying a name that already exists will merge new fields on top of existing v
.PP
\fB\-\-kubeconfig\fP=""
use a particular .kubeconfig file
use a particular kubeconfig file
.PP
\fB\-\-local\fP=false
use the .kubeconfig in the current directory
use the kubeconfig in the current directory
.PP
\fB\-\-log\_backtrace\_at\fP=:0

View File

@ -3,7 +3,7 @@
.SH NAME
.PP
kubectl config set\-credentials \- Sets a user entry in .kubeconfig
kubectl config set\-credentials \- Sets a user entry in kubeconfig
.SH SYNOPSIS
@ -13,7 +13,7 @@ kubectl config set\-credentials \- Sets a user entry in .kubeconfig
.SH DESCRIPTION
.PP
Sets a user entry in .kubeconfig
Sets a user entry in kubeconfig
Specifying a name that already exists will merge new fields on top of existing values.
.PP
@ -35,19 +35,19 @@ Bearer token and basic auth are mutually exclusive.
.SH OPTIONS
.PP
\fB\-\-auth\-path\fP=""
auth\-path for the user entry in .kubeconfig
auth\-path for the user entry in kubeconfig
.PP
\fB\-\-client\-certificate\fP=""
path to client\-certificate for the user entry in .kubeconfig
path to client\-certificate for the user entry in kubeconfig
.PP
\fB\-\-client\-key\fP=""
path to client\-key for the user entry in .kubeconfig
path to client\-key for the user entry in kubeconfig
.PP
\fB\-\-embed\-certs\fP=false
embed client cert/key for the user entry in .kubeconfig
embed client cert/key for the user entry in kubeconfig
.PP
\fB\-h\fP, \fB\-\-help\fP=false
@ -55,15 +55,15 @@ Bearer token and basic auth are mutually exclusive.
.PP
\fB\-\-password\fP=""
password for the user entry in .kubeconfig
password for the user entry in kubeconfig
.PP
\fB\-\-token\fP=""
token for the user entry in .kubeconfig
token for the user entry in kubeconfig
.PP
\fB\-\-username\fP=""
username for the user entry in .kubeconfig
username for the user entry in kubeconfig
.SH OPTIONS INHERITED FROM PARENT COMMANDS
@ -89,11 +89,11 @@ Bearer token and basic auth are mutually exclusive.
.PP
\fB\-\-envvar\fP=false
use the .kubeconfig from $KUBECONFIG
use the kubeconfig from $KUBECONFIG
.PP
\fB\-\-global\fP=false
use the .kubeconfig from /home/username
use the kubeconfig from /home/username/.kube/.kubeconfig
.PP
\fB\-\-insecure\-skip\-tls\-verify\fP=false
@ -101,11 +101,11 @@ Bearer token and basic auth are mutually exclusive.
.PP
\fB\-\-kubeconfig\fP=""
use a particular .kubeconfig file
use a particular kubeconfig file
.PP
\fB\-\-local\fP=false
use the .kubeconfig in the current directory
use the kubeconfig in the current directory
.PP
\fB\-\-log\_backtrace\_at\fP=:0

View File

@ -3,7 +3,7 @@
.SH NAME
.PP
kubectl config set \- Sets an individual value in a .kubeconfig file
kubectl config set \- Sets an individual value in a kubeconfig file
.SH SYNOPSIS
@ -13,7 +13,7 @@ kubectl config set \- Sets an individual value in a .kubeconfig file
.SH DESCRIPTION
.PP
Sets an individual value in a .kubeconfig file
Sets an individual value in a kubeconfig file
PROPERTY\_NAME is a dot delimited name where each token represents either a attribute name or a map key. Map keys may not contain dots.
PROPERTY\_VALUE is the new value you wish to set.
@ -59,11 +59,11 @@ PROPERTY\_VALUE is the new value you wish to set.
.PP
\fB\-\-envvar\fP=false
use the .kubeconfig from $KUBECONFIG
use the kubeconfig from $KUBECONFIG
.PP
\fB\-\-global\fP=false
use the .kubeconfig from /home/username
use the kubeconfig from /home/username/.kube/.kubeconfig
.PP
\fB\-\-insecure\-skip\-tls\-verify\fP=false
@ -71,11 +71,11 @@ PROPERTY\_VALUE is the new value you wish to set.
.PP
\fB\-\-kubeconfig\fP=""
use a particular .kubeconfig file
use a particular kubeconfig file
.PP
\fB\-\-local\fP=false
use the .kubeconfig in the current directory
use the kubeconfig in the current directory
.PP
\fB\-\-log\_backtrace\_at\fP=:0

View File

@ -3,7 +3,7 @@
.SH NAME
.PP
kubectl config unset \- Unsets an individual value in a .kubeconfig file
kubectl config unset \- Unsets an individual value in a kubeconfig file
.SH SYNOPSIS
@ -13,7 +13,7 @@ kubectl config unset \- Unsets an individual value in a .kubeconfig file
.SH DESCRIPTION
.PP
Unsets an individual value in a .kubeconfig file
Unsets an individual value in a kubeconfig file
PROPERTY\_NAME is a dot delimited name where each token represents either a attribute name or a map key. Map keys may not contain dots.
@ -58,11 +58,11 @@ PROPERTY\_NAME is a dot delimited name where each token represents either a attr
.PP
\fB\-\-envvar\fP=false
use the .kubeconfig from $KUBECONFIG
use the kubeconfig from $KUBECONFIG
.PP
\fB\-\-global\fP=false
use the .kubeconfig from /home/username
use the kubeconfig from /home/username/.kube/.kubeconfig
.PP
\fB\-\-insecure\-skip\-tls\-verify\fP=false
@ -70,11 +70,11 @@ PROPERTY\_NAME is a dot delimited name where each token represents either a attr
.PP
\fB\-\-kubeconfig\fP=""
use a particular .kubeconfig file
use a particular kubeconfig file
.PP
\fB\-\-local\fP=false
use the .kubeconfig in the current directory
use the kubeconfig in the current directory
.PP
\fB\-\-log\_backtrace\_at\fP=:0

View File

@ -3,7 +3,7 @@
.SH NAME
.PP
kubectl config use\-context \- Sets the current\-context in a .kubeconfig file
kubectl config use\-context \- Sets the current\-context in a kubeconfig file
.SH SYNOPSIS
@ -13,7 +13,7 @@ kubectl config use\-context \- Sets the current\-context in a .kubeconfig file
.SH DESCRIPTION
.PP
Sets the current\-context in a .kubeconfig file
Sets the current\-context in a kubeconfig file
.SH OPTIONS
@ -57,11 +57,11 @@ Sets the current\-context in a .kubeconfig file
.PP
\fB\-\-envvar\fP=false
use the .kubeconfig from $KUBECONFIG
use the kubeconfig from $KUBECONFIG
.PP
\fB\-\-global\fP=false
use the .kubeconfig from /home/username
use the kubeconfig from /home/username/.kube/.kubeconfig
.PP
\fB\-\-insecure\-skip\-tls\-verify\fP=false
@ -69,11 +69,11 @@ Sets the current\-context in a .kubeconfig file
.PP
\fB\-\-kubeconfig\fP=""
use a particular .kubeconfig file
use a particular kubeconfig file
.PP
\fB\-\-local\fP=false
use the .kubeconfig in the current directory
use the kubeconfig in the current directory
.PP
\fB\-\-log\_backtrace\_at\fP=:0

View File

@ -3,7 +3,7 @@
.SH NAME
.PP
kubectl config view \- displays merged .kubeconfig settings or a specified .kubeconfig file.
kubectl config view \- displays merged kubeconfig settings or a specified kubeconfig file.
.SH SYNOPSIS
@ -13,7 +13,7 @@ kubectl config view \- displays merged .kubeconfig settings or a specified .kube
.SH DESCRIPTION
.PP
displays merged .kubeconfig settings or a specified .kubeconfig file.
displays merged kubeconfig settings or a specified kubeconfig file.
.PP
You can use \-\-output=template \-\-template=TEMPLATE to extract specific values.
@ -26,7 +26,7 @@ You can use \-\-output=template \-\-template=TEMPLATE to extract specific values
.PP
\fB\-\-merge\fP=true
merge together the full hierarchy of .kubeconfig files
merge together the full hierarchy of kubeconfig files
.PP
\fB\-\-no\-headers\fP=false
@ -81,11 +81,11 @@ You can use \-\-output=template \-\-template=TEMPLATE to extract specific values
.PP
\fB\-\-envvar\fP=false
use the .kubeconfig from $KUBECONFIG
use the kubeconfig from $KUBECONFIG
.PP
\fB\-\-global\fP=false
use the .kubeconfig from /home/username
use the kubeconfig from /home/username/.kube/.kubeconfig
.PP
\fB\-\-insecure\-skip\-tls\-verify\fP=false
@ -93,11 +93,11 @@ You can use \-\-output=template \-\-template=TEMPLATE to extract specific values
.PP
\fB\-\-kubeconfig\fP=""
use a particular .kubeconfig file
use a particular kubeconfig file
.PP
\fB\-\-local\fP=false
use the .kubeconfig in the current directory
use the kubeconfig in the current directory
.PP
\fB\-\-log\_backtrace\_at\fP=:0
@ -165,10 +165,10 @@ You can use \-\-output=template \-\-template=TEMPLATE to extract specific values
.RS
.nf
// Show merged .kubeconfig settings.
// Show merged kubeconfig settings.
$ kubectl config view
// Show only local ./.kubeconfig settings
// Show only local kubeconfig settings
$ kubectl config view \-\-local
// Get the password for the e2e user

View File

@ -3,7 +3,7 @@
.SH NAME
.PP
kubectl config \- config modifies .kubeconfig files
kubectl config \- config modifies kubeconfig files
.SH SYNOPSIS
@ -13,17 +13,17 @@ kubectl config \- config modifies .kubeconfig files
.SH DESCRIPTION
.PP
config modifies .kubeconfig files using subcommands like "kubectl config set current\-context my\-context"
config modifies kubeconfig files using subcommands like "kubectl config set current\-context my\-context"
.SH OPTIONS
.PP
\fB\-\-envvar\fP=false
use the .kubeconfig from $KUBECONFIG
use the kubeconfig from $KUBECONFIG
.PP
\fB\-\-global\fP=false
use the .kubeconfig from /home/username
use the kubeconfig from /home/username/.kube/.kubeconfig
.PP
\fB\-h\fP, \fB\-\-help\fP=false
@ -31,11 +31,11 @@ config modifies .kubeconfig files using subcommands like "kubectl config set cur
.PP
\fB\-\-kubeconfig\fP=""
use a particular .kubeconfig file
use a particular kubeconfig file
.PP
\fB\-\-local\fP=false
use the .kubeconfig in the current directory
use the kubeconfig in the current directory
.SH OPTIONS INHERITED FROM PARENT COMMANDS

View File

@ -49,6 +49,8 @@ type Preferences struct {
// Cluster contains information about how to communicate with a kubernetes cluster
type Cluster struct {
// LocationOfOrigin indicates where this object came from. It is used for round tripping config post-merge, but never serialized.
LocationOfOrigin string
// Server is the address of the kubernetes cluster (https://hostname:port).
Server string `json:"server"`
// APIVersion is the preferred api version for communicating with the kubernetes cluster (v1beta1, v1beta2, v1beta3, etc).
@ -65,6 +67,8 @@ type Cluster struct {
// AuthInfo contains information that describes identity information. This is use to tell the kubernetes cluster who you are.
type AuthInfo struct {
// LocationOfOrigin indicates where this object came from. It is used for round tripping config post-merge, but never serialized.
LocationOfOrigin string
// AuthPath is the path to a kubernetes auth file (~/.kubernetes_auth). If you provide an AuthPath, the other options specified are ignored
AuthPath string `json:"auth-path,omitempty"`
// ClientCertificate is the path to a client cert file for TLS.
@ -87,6 +91,8 @@ type AuthInfo struct {
// Context is a tuple of references to a cluster (how do I communicate with a kubernetes cluster), a user (how do I identify myself), and a namespace (what subset of resources do I want to work with)
type Context struct {
// LocationOfOrigin indicates where this object came from. It is used for round tripping config post-merge, but never serialized.
LocationOfOrigin string
// Cluster is the name of the cluster for this context
Cluster string `json:"cluster"`
// AuthInfo is the name of the authInfo for this context

View File

@ -88,22 +88,27 @@ func ExampleOfOptionsConfig() {
// Output:
// clusters:
// alfa:
// LocationOfOrigin: ""
// api-version: v1beta2
// certificate-authority: path/to/my/cert-ca-filename
// insecure-skip-tls-verify: true
// server: https://alfa.org:8080
// bravo:
// LocationOfOrigin: ""
// api-version: v1beta1
// server: https://bravo.org:8080
// contexts:
// alfa-as-black-mage:
// LocationOfOrigin: ""
// cluster: alfa
// namespace: zulu
// user: black-mage-via-file
// alfa-as-white-mage:
// LocationOfOrigin: ""
// cluster: alfa
// user: white-mage-via-cert
// bravo-as-black-mage:
// LocationOfOrigin: ""
// cluster: bravo
// namespace: yankee
// user: black-mage-via-file
@ -112,10 +117,13 @@ func ExampleOfOptionsConfig() {
// colors: true
// users:
// black-mage-via-file:
// LocationOfOrigin: ""
// auth-path: path/to/my/.kubernetes_auth
// red-mage-via-token:
// LocationOfOrigin: ""
// token: my-secret-token
// white-mage-via-cert:
// LocationOfOrigin: ""
// client-certificate: path/to/my/client-cert-filename
// client-key: path/to/my/client-key-filename
}

View File

@ -26,6 +26,31 @@ import (
func init() {
err := newer.Scheme.AddConversionFuncs(
func(in *Cluster, out *newer.Cluster, s conversion.Scope) error {
return s.DefaultConvert(in, out, conversion.IgnoreMissingFields)
},
func(in *newer.Cluster, out *Cluster, s conversion.Scope) error {
return s.DefaultConvert(in, out, conversion.IgnoreMissingFields)
},
func(in *Preferences, out *newer.Preferences, s conversion.Scope) error {
return s.DefaultConvert(in, out, conversion.IgnoreMissingFields)
},
func(in *newer.Preferences, out *Preferences, s conversion.Scope) error {
return s.DefaultConvert(in, out, conversion.IgnoreMissingFields)
},
func(in *AuthInfo, out *newer.AuthInfo, s conversion.Scope) error {
return s.DefaultConvert(in, out, conversion.IgnoreMissingFields)
},
func(in *newer.AuthInfo, out *AuthInfo, s conversion.Scope) error {
return s.DefaultConvert(in, out, conversion.IgnoreMissingFields)
},
func(in *Context, out *newer.Context, s conversion.Scope) error {
return s.DefaultConvert(in, out, conversion.IgnoreMissingFields)
},
func(in *newer.Context, out *Context, s conversion.Scope) error {
return s.DefaultConvert(in, out, conversion.IgnoreMissingFields)
},
func(in *Config, out *newer.Config, s conversion.Scope) error {
out.CurrentContext = in.CurrentContext
if err := s.Convert(&in.Preferences, &out.Preferences, 0); err != nil {

View File

@ -48,6 +48,10 @@ const (
type ClientConfigLoadingRules struct {
ExplicitPath string
Precedence []string
// DoNotResolvePaths indicates whether or not to resolve paths with respect to the originating files. This is phrased as a negative so
// that a default object that doesn't set this will usually get the behavior it wants.
DoNotResolvePaths bool
}
// NewDefaultClientConfigLoadingRules returns a ClientConfigLoadingRules object with default fields filled in. You are not required to
@ -71,7 +75,6 @@ func NewDefaultClientConfigLoadingRules() *ClientConfigLoadingRules {
// Relative paths inside of the .kubeconfig files are resolved against the .kubeconfig file's parent folder
// and only absolute file paths are returned.
func (rules *ClientConfigLoadingRules) Load() (*clientcmdapi.Config, error) {
errlist := []error{}
// Make sure a file we were explicitly told to use exists
@ -90,8 +93,10 @@ func (rules *ClientConfigLoadingRules) Load() (*clientcmdapi.Config, error) {
if err := mergeConfigWithFile(mapConfig, file); err != nil {
errlist = append(errlist, err)
}
if err := ResolveLocalPaths(file, mapConfig); err != nil {
errlist = append(errlist, err)
if rules.ResolvePaths() {
if err := ResolveLocalPaths(file, mapConfig); err != nil {
errlist = append(errlist, err)
}
}
}
@ -101,7 +106,9 @@ func (rules *ClientConfigLoadingRules) Load() (*clientcmdapi.Config, error) {
for i := len(kubeConfigFiles) - 1; i >= 0; i-- {
file := kubeConfigFiles[i]
mergeConfigWithFile(nonMapConfig, file)
ResolveLocalPaths(file, nonMapConfig)
if rules.ResolvePaths() {
ResolveLocalPaths(file, nonMapConfig)
}
}
// since values are overwritten, but maps values are not, we can merge the non-map config on top of the map config and
@ -182,7 +189,26 @@ func LoadFromFile(filename string) (*clientcmdapi.Config, error) {
if err != nil {
return nil, err
}
return Load(kubeconfigBytes)
config, err := Load(kubeconfigBytes)
if err != nil {
return nil, err
}
// set LocationOfOrigin on every Cluster, User, and Context
for key, obj := range config.AuthInfos {
obj.LocationOfOrigin = filename
config.AuthInfos[key] = obj
}
for key, obj := range config.Clusters {
obj.LocationOfOrigin = filename
config.Clusters[key] = obj
}
for key, obj := range config.Contexts {
obj.LocationOfOrigin = filename
config.Contexts[key] = obj
}
return config, nil
}
// Load takes a byte slice and deserializes the contents into Config object.
@ -226,3 +252,7 @@ func Write(config clientcmdapi.Config) ([]byte, error) {
}
return content, nil
}
func (rules ClientConfigLoadingRules) ResolvePaths() bool {
return !rules.DoNotResolvePaths
}

View File

@ -61,7 +61,7 @@ Find more information at https://github.com/GoogleCloudPlatform/kubernetes.`,
cmds.AddCommand(NewCmdLabel(f, out))
cmds.AddCommand(cmdconfig.NewCmdConfig(f, out))
cmds.AddCommand(cmdconfig.NewCmdConfig(cmdconfig.NewDefaultPathOptions(), out))
cmds.AddCommand(NewCmdClusterInfo(f, out))
cmds.AddCommand(NewCmdApiVersions(f, out))
cmds.AddCommand(NewCmdVersion(f, out))

View File

@ -17,9 +17,12 @@ limitations under the License.
package config
import (
"errors"
"fmt"
"io"
"os"
"path"
"reflect"
"strconv"
"github.com/golang/glog"
@ -27,33 +30,45 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
clientcmdapi "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api"
cmdutil "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
)
type pathOptions struct {
local bool
global bool
envvar bool
specifiedFile string
type PathOptions struct {
Local bool
Global bool
UseEnvVar bool
LocalFile string
GlobalFile string
EnvVarFile string
EnvVar string
ExplicitFileFlag string
LoadingRules *clientcmd.ClientConfigLoadingRules
}
func NewCmdConfig(f *cmdutil.Factory, out io.Writer) *cobra.Command {
pathOptions := &pathOptions{}
func NewCmdConfig(pathOptions *PathOptions, out io.Writer) *cobra.Command {
if len(pathOptions.ExplicitFileFlag) == 0 {
pathOptions.ExplicitFileFlag = clientcmd.RecommendedConfigPathFlag
}
if len(pathOptions.EnvVar) > 0 {
pathOptions.EnvVarFile = os.Getenv(pathOptions.EnvVar)
}
cmd := &cobra.Command{
Use: "config SUBCOMMAND",
Short: "config modifies .kubeconfig files",
Long: `config modifies .kubeconfig files using subcommands like "kubectl config set current-context my-context"`,
Short: "config modifies kubeconfig files",
Long: `config modifies kubeconfig files using subcommands like "kubectl config set current-context my-context"`,
Run: func(cmd *cobra.Command, args []string) {
cmd.Help()
},
}
// file paths are common to all sub commands
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.PersistentFlags().BoolVar(&pathOptions.Local, "local", pathOptions.Local, "use the kubeconfig in the current directory")
cmd.PersistentFlags().BoolVar(&pathOptions.Global, "global", pathOptions.Global, "use the kubeconfig from "+pathOptions.GlobalFile)
cmd.PersistentFlags().BoolVar(&pathOptions.UseEnvVar, "envvar", pathOptions.UseEnvVar, "use the kubeconfig from $"+pathOptions.EnvVar)
cmd.PersistentFlags().StringVar(&pathOptions.LoadingRules.ExplicitPath, pathOptions.ExplicitFileFlag, pathOptions.LoadingRules.ExplicitPath, "use a particular kubeconfig file")
cmd.AddCommand(NewCmdConfigView(out, pathOptions))
cmd.AddCommand(NewCmdConfigSetCluster(out, pathOptions))
@ -66,59 +81,367 @@ func NewCmdConfig(f *cmdutil.Factory, out io.Writer) *cobra.Command {
return cmd
}
func (o *pathOptions) getStartingConfig() (*clientcmdapi.Config, string, error) {
filename := ""
func NewDefaultPathOptions() *PathOptions {
ret := &PathOptions{
LocalFile: ".kubeconfig",
GlobalFile: path.Join(os.Getenv("HOME"), "/.kube/.kubeconfig"),
EnvVar: clientcmd.RecommendedConfigPathEnvVar,
EnvVarFile: os.Getenv(clientcmd.RecommendedConfigPathEnvVar),
ExplicitFileFlag: clientcmd.RecommendedConfigPathFlag,
LoadingRules: clientcmd.NewDefaultClientConfigLoadingRules(),
}
ret.LoadingRules.DoNotResolvePaths = true
return ret
}
func (o PathOptions) Validate() error {
if len(o.LoadingRules.ExplicitPath) > 0 {
if o.Global {
return errors.New("cannot specify both --" + o.ExplicitFileFlag + " and --global")
}
if o.Local {
return errors.New("cannot specify both --" + o.ExplicitFileFlag + " and --local")
}
if o.UseEnvVar {
return errors.New("cannot specify both --" + o.ExplicitFileFlag + " and --envvar")
}
}
if o.Global {
if o.Local {
return errors.New("cannot specify both --global and --local")
}
if o.UseEnvVar {
return errors.New("cannot specify both --global and --envvar")
}
}
if o.Local {
if o.UseEnvVar {
return errors.New("cannot specify both --local and --envvar")
}
}
if o.UseEnvVar {
if len(o.EnvVarFile) == 0 {
return fmt.Errorf("environment variable %v does not have a value", o.EnvVar)
}
}
return nil
}
func (o *PathOptions) getStartingConfig() (*clientcmdapi.Config, error) {
if err := o.Validate(); err != nil {
return nil, err
}
config := clientcmdapi.NewConfig()
if len(o.specifiedFile) > 0 {
filename = o.specifiedFile
config = getConfigFromFileOrDie(filename)
}
switch {
case o.Global:
config = getConfigFromFileOrDie(o.GlobalFile)
if o.global {
if len(filename) > 0 {
return nil, "", fmt.Errorf("already loading from %v, cannot specify global as well", filename)
case o.UseEnvVar:
config = getConfigFromFileOrDie(o.EnvVarFile)
case o.Local:
config = getConfigFromFileOrDie(o.LocalFile)
// no specific flag was set, load according to the loading rules
default:
clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(o.LoadingRules, &clientcmd.ConfigOverrides{})
rawConfig, err := clientConfig.RawConfig()
if err != nil {
return nil, err
}
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)
}
filename = ".kubeconfig"
config = getConfigFromFileOrDie(filename)
config = &rawConfig
}
// 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, nil
}
// GetDefaultFilename returns the name of the file you should write into (create if necessary), if you're trying to create
// a new stanza as opposed to updating an existing one.
func (o *PathOptions) GetDefaultFilename() string {
if o.IsExplicitFile() {
return o.GetExplicitFile()
}
if len(o.EnvVarFile) > 0 {
return o.EnvVarFile
}
if _, err := os.Stat(o.LocalFile); err == nil {
return o.LocalFile
}
return o.GlobalFile
}
func (o *PathOptions) IsExplicitFile() bool {
switch {
case len(o.LoadingRules.ExplicitPath) > 0 ||
o.Global ||
o.UseEnvVar ||
o.Local:
return true
}
return false
}
func (o *PathOptions) GetExplicitFile() string {
if !o.IsExplicitFile() {
return ""
}
switch {
case len(o.LoadingRules.ExplicitPath) > 0:
return o.LoadingRules.ExplicitPath
case o.Global:
return o.GlobalFile
case o.UseEnvVar:
return o.EnvVarFile
case o.Local:
return o.LocalFile
}
return ""
}
// ModifyConfig takes a Config object, iterates through Clusters, AuthInfos, and Contexts, uses the LocationOfOrigin if specified or
// uses the default destination file to write the results into. This results in multiple file reads, but it's very easy to follow.
// Preferences and CurrentContext should always be set in the default destination file. Since we can't distinguish between empty and missing values
// (no nil strings), we're forced have separate handling for them. In all the currently known cases, newConfig should have, at most, one difference,
// that means that this code will only write into a single file.
func (o *PathOptions) ModifyConfig(newConfig clientcmdapi.Config) error {
startingConfig, err := o.getStartingConfig()
if err != nil {
return err
}
// at this point, config and startingConfig should have, at most, one difference. We need to chase the difference until we find it
// then we'll build a partial config object to call write upon. Special case the test for current context and preferences since those
// always write to the default file.
switch {
case reflect.DeepEqual(*startingConfig, newConfig):
// nothing to do
case startingConfig.CurrentContext != newConfig.CurrentContext:
if err := o.writeCurrentContext(newConfig.CurrentContext); err != nil {
return err
}
case !reflect.DeepEqual(startingConfig.Preferences, newConfig.Preferences):
if err := o.writePreferences(newConfig.Preferences); err != nil {
return err
}
default:
// something is different. Search every cluster, authInfo, and context. First from new to old for differences, then from old to new for deletions
for key, cluster := range newConfig.Clusters {
startingCluster, exists := startingConfig.Clusters[key]
if !reflect.DeepEqual(cluster, startingCluster) || !exists {
destinationFile := cluster.LocationOfOrigin
if len(destinationFile) == 0 {
destinationFile = o.GetDefaultFilename()
}
configToWrite := getConfigFromFileOrDie(destinationFile)
configToWrite.Clusters[key] = cluster
if err := clientcmd.WriteToFile(*configToWrite, destinationFile); err != nil {
return err
}
}
}
for key, context := range newConfig.Contexts {
startingContext, exists := startingConfig.Contexts[key]
if !reflect.DeepEqual(context, startingContext) || !exists {
destinationFile := context.LocationOfOrigin
if len(destinationFile) == 0 {
destinationFile = o.GetDefaultFilename()
}
configToWrite := getConfigFromFileOrDie(destinationFile)
configToWrite.Contexts[key] = context
if err := clientcmd.WriteToFile(*configToWrite, destinationFile); err != nil {
return err
}
}
}
for key, authInfo := range newConfig.AuthInfos {
startingAuthInfo, exists := startingConfig.AuthInfos[key]
if !reflect.DeepEqual(authInfo, startingAuthInfo) || !exists {
destinationFile := authInfo.LocationOfOrigin
if len(destinationFile) == 0 {
destinationFile = o.GetDefaultFilename()
}
configToWrite := getConfigFromFileOrDie(destinationFile)
configToWrite.AuthInfos[key] = authInfo
if err := clientcmd.WriteToFile(*configToWrite, destinationFile); err != nil {
return err
}
}
}
for key, cluster := range startingConfig.Clusters {
if _, exists := newConfig.Clusters[key]; !exists {
destinationFile := cluster.LocationOfOrigin
if len(destinationFile) == 0 {
destinationFile = o.GetDefaultFilename()
}
configToWrite := getConfigFromFileOrDie(destinationFile)
delete(configToWrite.Clusters, key)
if err := clientcmd.WriteToFile(*configToWrite, destinationFile); err != nil {
return err
}
}
}
for key, context := range startingConfig.Contexts {
if _, exists := newConfig.Contexts[key]; !exists {
destinationFile := context.LocationOfOrigin
if len(destinationFile) == 0 {
destinationFile = o.GetDefaultFilename()
}
configToWrite := getConfigFromFileOrDie(destinationFile)
delete(configToWrite.Contexts, key)
if err := clientcmd.WriteToFile(*configToWrite, destinationFile); err != nil {
return err
}
}
}
for key, authInfo := range startingConfig.AuthInfos {
if _, exists := newConfig.AuthInfos[key]; !exists {
destinationFile := authInfo.LocationOfOrigin
if len(destinationFile) == 0 {
destinationFile = o.GetDefaultFilename()
}
configToWrite := getConfigFromFileOrDie(destinationFile)
delete(configToWrite.AuthInfos, key)
if err := clientcmd.WriteToFile(*configToWrite, destinationFile); err != nil {
return err
}
}
}
}
return nil
}
// writeCurrentContext takes three possible paths.
// If newCurrentContext is the same as the startingConfig's current context, then we exit.
// If newCurrentContext has a value, then that value is written into the default destination file.
// If newCurrentContext is empty, then we find the config file that is setting the CurrentContext and clear the value from that file
func (o *PathOptions) writeCurrentContext(newCurrentContext string) error {
if startingConfig, err := o.getStartingConfig(); err != nil {
return err
} else if startingConfig.CurrentContext == newCurrentContext {
return nil
}
if len(newCurrentContext) > 0 {
destinationFile := o.GetDefaultFilename()
config := getConfigFromFileOrDie(destinationFile)
config.CurrentContext = newCurrentContext
if err := clientcmd.WriteToFile(*config, destinationFile); err != nil {
return err
}
return nil
}
if o.IsExplicitFile() {
file := o.GetExplicitFile()
currConfig := getConfigFromFileOrDie(file)
currConfig.CurrentContext = newCurrentContext
if err := clientcmd.WriteToFile(*currConfig, file); err != nil {
return err
}
return nil
}
filesToCheck := make([]string, 0, len(o.LoadingRules.Precedence)+1)
filesToCheck = append(filesToCheck, o.LoadingRules.ExplicitPath)
filesToCheck = append(filesToCheck, o.LoadingRules.Precedence...)
for _, file := range filesToCheck {
currConfig := getConfigFromFileOrDie(file)
if len(currConfig.CurrentContext) > 0 {
currConfig.CurrentContext = newCurrentContext
if err := clientcmd.WriteToFile(*currConfig, file); err != nil {
return err
}
return nil
}
}
return config, filename, nil
return nil
}
func (o *PathOptions) writePreferences(newPrefs clientcmdapi.Preferences) error {
if startingConfig, err := o.getStartingConfig(); err != nil {
return err
} else if reflect.DeepEqual(startingConfig.Preferences, newPrefs) {
return nil
}
if o.IsExplicitFile() {
file := o.GetExplicitFile()
currConfig := getConfigFromFileOrDie(file)
currConfig.Preferences = newPrefs
if err := clientcmd.WriteToFile(*currConfig, file); err != nil {
return err
}
return nil
}
filesToCheck := make([]string, 0, len(o.LoadingRules.Precedence)+1)
filesToCheck = append(filesToCheck, o.LoadingRules.ExplicitPath)
filesToCheck = append(filesToCheck, o.LoadingRules.Precedence...)
for _, file := range filesToCheck {
currConfig := getConfigFromFileOrDie(file)
if !reflect.DeepEqual(currConfig.Preferences, newPrefs) {
currConfig.Preferences = newPrefs
if err := clientcmd.WriteToFile(*currConfig, file); err != nil {
return err
}
return nil
}
}
return nil
}
// getConfigFromFileOrDie tries to read a kubeconfig file and if it can't, it calls exit. One exception, missing files result in empty configs, not an exit

View File

@ -27,7 +27,6 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
clientcmdapi "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api"
cmdutil "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
@ -650,9 +649,8 @@ func testConfigCommand(args []string, startingConfig clientcmdapi.Config) (strin
argsToUse = append(argsToUse, args...)
buf := bytes.NewBuffer([]byte{})
f := cmdutil.NewFactory(nil)
cmd := NewCmdConfig(f, buf)
cmd := NewCmdConfig(NewDefaultPathOptions(), buf)
cmd.SetArgs(argsToUse)
cmd.Execute()
@ -667,6 +665,7 @@ func (test configCommandTest) run(t *testing.T) string {
testSetNilMapsToEmpties(reflect.ValueOf(&test.expectedConfig))
testSetNilMapsToEmpties(reflect.ValueOf(&actualConfig))
testClearLocationOfOrigin(&actualConfig)
if !reflect.DeepEqual(test.expectedConfig, actualConfig) {
t.Errorf("diff: %v", util.ObjectDiff(test.expectedConfig, actualConfig))
@ -681,6 +680,20 @@ func (test configCommandTest) run(t *testing.T) string {
return out
}
func testClearLocationOfOrigin(config *clientcmdapi.Config) {
for key, obj := range config.AuthInfos {
obj.LocationOfOrigin = ""
config.AuthInfos[key] = obj
}
for key, obj := range config.Clusters {
obj.LocationOfOrigin = ""
config.Clusters[key] = obj
}
for key, obj := range config.Contexts {
obj.LocationOfOrigin = ""
config.Contexts[key] = obj
}
}
func testSetNilMapsToEmpties(curr reflect.Value) {
actualCurrValue := curr
if curr.Kind() == reflect.Ptr {

View File

@ -31,7 +31,7 @@ import (
)
type createAuthInfoOptions struct {
pathOptions *pathOptions
pathOptions *PathOptions
name string
authPath util.StringFlag
clientCertificate util.StringFlag
@ -42,7 +42,7 @@ type createAuthInfoOptions struct {
embedCertData util.BoolFlag
}
var create_authinfo_long = fmt.Sprintf(`Sets a user entry in .kubeconfig
var create_authinfo_long = fmt.Sprintf(`Sets a user entry in kubeconfig
Specifying a name that already exists will merge new fields on top of existing values.
Client-certificate flags:
@ -67,12 +67,12 @@ $ kubectl set-credentials cluster-admin --username=admin --password=uXFGweU9l35q
// Embed client certificate data in the "cluster-admin" entry
$ kubectl set-credentials cluster-admin --client-certificate=~/.kube/admin.crt --embed-certs=true`
func NewCmdConfigSetAuthInfo(out io.Writer, pathOptions *pathOptions) *cobra.Command {
func NewCmdConfigSetAuthInfo(out io.Writer, pathOptions *PathOptions) *cobra.Command {
options := &createAuthInfoOptions{pathOptions: pathOptions}
cmd := &cobra.Command{
Use: fmt.Sprintf("set-credentials NAME [--%v=/path/to/authfile] [--%v=path/to/certfile] [--%v=path/to/keyfile] [--%v=bearer_token] [--%v=basic_user] [--%v=basic_password]", clientcmd.FlagAuthPath, clientcmd.FlagCertFile, clientcmd.FlagKeyFile, clientcmd.FlagBearerToken, clientcmd.FlagUsername, clientcmd.FlagPassword),
Short: "Sets a user entry in .kubeconfig",
Short: "Sets a user entry in kubeconfig",
Long: create_authinfo_long,
Example: create_authinfo_example,
Run: func(cmd *cobra.Command, args []string) {
@ -87,13 +87,13 @@ func NewCmdConfigSetAuthInfo(out io.Writer, pathOptions *pathOptions) *cobra.Com
},
}
cmd.Flags().Var(&options.authPath, clientcmd.FlagAuthPath, clientcmd.FlagAuthPath+" for the user entry in .kubeconfig")
cmd.Flags().Var(&options.clientCertificate, clientcmd.FlagCertFile, "path to "+clientcmd.FlagCertFile+" for the user entry in .kubeconfig")
cmd.Flags().Var(&options.clientKey, clientcmd.FlagKeyFile, "path to "+clientcmd.FlagKeyFile+" for the user entry in .kubeconfig")
cmd.Flags().Var(&options.token, clientcmd.FlagBearerToken, clientcmd.FlagBearerToken+" for the user entry in .kubeconfig")
cmd.Flags().Var(&options.username, clientcmd.FlagUsername, clientcmd.FlagUsername+" for the user entry in .kubeconfig")
cmd.Flags().Var(&options.password, clientcmd.FlagPassword, clientcmd.FlagPassword+" for the user entry in .kubeconfig")
cmd.Flags().Var(&options.embedCertData, clientcmd.FlagEmbedCerts, "embed client cert/key for the user entry in .kubeconfig")
cmd.Flags().Var(&options.authPath, clientcmd.FlagAuthPath, clientcmd.FlagAuthPath+" for the user entry in kubeconfig")
cmd.Flags().Var(&options.clientCertificate, clientcmd.FlagCertFile, "path to "+clientcmd.FlagCertFile+" for the user entry in kubeconfig")
cmd.Flags().Var(&options.clientKey, clientcmd.FlagKeyFile, "path to "+clientcmd.FlagKeyFile+" for the user entry in kubeconfig")
cmd.Flags().Var(&options.token, clientcmd.FlagBearerToken, clientcmd.FlagBearerToken+" for the user entry in kubeconfig")
cmd.Flags().Var(&options.username, clientcmd.FlagUsername, clientcmd.FlagUsername+" for the user entry in kubeconfig")
cmd.Flags().Var(&options.password, clientcmd.FlagPassword, clientcmd.FlagPassword+" for the user entry in kubeconfig")
cmd.Flags().Var(&options.embedCertData, clientcmd.FlagEmbedCerts, "embed client cert/key for the user entry in kubeconfig")
return cmd
}
@ -104,7 +104,7 @@ func (o createAuthInfoOptions) run() error {
return err
}
config, filename, err := o.pathOptions.getStartingConfig()
config, err := o.pathOptions.getStartingConfig()
if err != nil {
return err
}
@ -112,8 +112,7 @@ func (o createAuthInfoOptions) run() error {
authInfo := o.modifyAuthInfo(config.AuthInfos[o.name])
config.AuthInfos[o.name] = authInfo
err = clientcmd.WriteToFile(*config, filename)
if err != nil {
if err := o.pathOptions.ModifyConfig(*config); err != nil {
return err
}
@ -226,5 +225,5 @@ func (o createAuthInfoOptions) validate() error {
}
}
return nil
return o.pathOptions.Validate()
}

View File

@ -30,7 +30,7 @@ import (
)
type createClusterOptions struct {
pathOptions *pathOptions
pathOptions *PathOptions
name string
server util.StringFlag
apiVersion util.StringFlag
@ -40,7 +40,7 @@ type createClusterOptions struct {
}
const (
create_cluster_long = `Sets a cluster entry in .kubeconfig.
create_cluster_long = `Sets a cluster entry in kubeconfig.
Specifying a name that already exists will merge new fields on top of existing values for those fields.`
create_cluster_example = `// Set only the server field on the e2e cluster entry without touching other values.
$ kubectl config set-cluster e2e --server=https://1.2.3.4
@ -52,12 +52,12 @@ $ kubectl config set-cluster e2e --certificate-authority=~/.kube/e2e/kubernetes.
$ kubectl config set-cluster e2e --insecure-skip-tls-verify=true`
)
func NewCmdConfigSetCluster(out io.Writer, pathOptions *pathOptions) *cobra.Command {
func NewCmdConfigSetCluster(out io.Writer, pathOptions *PathOptions) *cobra.Command {
options := &createClusterOptions{pathOptions: pathOptions}
cmd := &cobra.Command{
Use: fmt.Sprintf("set-cluster NAME [--%v=server] [--%v=path/to/certficate/authority] [--%v=apiversion] [--%v=true]", clientcmd.FlagAPIServer, clientcmd.FlagCAFile, clientcmd.FlagAPIVersion, clientcmd.FlagInsecure),
Short: "Sets a cluster entry in .kubeconfig",
Short: "Sets a cluster entry in kubeconfig",
Long: create_cluster_long,
Example: create_cluster_example,
Run: func(cmd *cobra.Command, args []string) {
@ -74,11 +74,11 @@ func NewCmdConfigSetCluster(out io.Writer, pathOptions *pathOptions) *cobra.Comm
options.insecureSkipTLSVerify.Default(false)
cmd.Flags().Var(&options.server, clientcmd.FlagAPIServer, clientcmd.FlagAPIServer+" for the cluster entry in .kubeconfig")
cmd.Flags().Var(&options.apiVersion, clientcmd.FlagAPIVersion, clientcmd.FlagAPIVersion+" for the cluster entry in .kubeconfig")
cmd.Flags().Var(&options.insecureSkipTLSVerify, clientcmd.FlagInsecure, clientcmd.FlagInsecure+" for the cluster entry in .kubeconfig")
cmd.Flags().Var(&options.certificateAuthority, clientcmd.FlagCAFile, "path to "+clientcmd.FlagCAFile+" for the cluster entry in .kubeconfig")
cmd.Flags().Var(&options.embedCAData, clientcmd.FlagEmbedCerts, clientcmd.FlagEmbedCerts+" for the cluster entry in .kubeconfig")
cmd.Flags().Var(&options.server, clientcmd.FlagAPIServer, clientcmd.FlagAPIServer+" for the cluster entry in kubeconfig")
cmd.Flags().Var(&options.apiVersion, clientcmd.FlagAPIVersion, clientcmd.FlagAPIVersion+" for the cluster entry in kubeconfig")
cmd.Flags().Var(&options.insecureSkipTLSVerify, clientcmd.FlagInsecure, clientcmd.FlagInsecure+" for the cluster entry in kubeconfig")
cmd.Flags().Var(&options.certificateAuthority, clientcmd.FlagCAFile, "path to "+clientcmd.FlagCAFile+" for the cluster entry in kubeconfig")
cmd.Flags().Var(&options.embedCAData, clientcmd.FlagEmbedCerts, clientcmd.FlagEmbedCerts+" for the cluster entry in kubeconfig")
return cmd
}
@ -89,20 +89,15 @@ func (o createClusterOptions) run() error {
return err
}
config, filename, err := o.pathOptions.getStartingConfig()
config, err := o.pathOptions.getStartingConfig()
if err != nil {
return err
}
if config.Clusters == nil {
config.Clusters = make(map[string]clientcmdapi.Cluster)
}
cluster := o.modifyCluster(config.Clusters[o.name])
config.Clusters[o.name] = cluster
err = clientcmd.WriteToFile(*config, filename)
if err != nil {
if err := o.pathOptions.ModifyConfig(*config); err != nil {
return err
}
@ -174,5 +169,5 @@ func (o createClusterOptions) validate() error {
}
}
return nil
return o.pathOptions.Validate()
}

View File

@ -29,7 +29,7 @@ import (
)
type createContextOptions struct {
pathOptions *pathOptions
pathOptions *PathOptions
name string
cluster util.StringFlag
authInfo util.StringFlag
@ -37,18 +37,18 @@ type createContextOptions struct {
}
const (
create_context_long = `Sets a context entry in .kubeconfig
create_context_long = `Sets a context entry in kubeconfig
Specifying a name that already exists will merge new fields on top of existing values for those fields.`
create_context_example = `// Set the user field on the gce context entry without touching other values
$ kubectl config set-context gce --user=cluster-admin`
)
func NewCmdConfigSetContext(out io.Writer, pathOptions *pathOptions) *cobra.Command {
func NewCmdConfigSetContext(out io.Writer, pathOptions *PathOptions) *cobra.Command {
options := &createContextOptions{pathOptions: pathOptions}
cmd := &cobra.Command{
Use: fmt.Sprintf("set-context NAME [--%v=cluster_nickname] [--%v=user_nickname] [--%v=namespace]", clientcmd.FlagClusterName, clientcmd.FlagAuthInfoName, clientcmd.FlagNamespace),
Short: "Sets a context entry in .kubeconfig",
Short: "Sets a context entry in kubeconfig",
Long: create_context_long,
Example: create_context_example,
Run: func(cmd *cobra.Command, args []string) {
@ -63,9 +63,9 @@ func NewCmdConfigSetContext(out io.Writer, pathOptions *pathOptions) *cobra.Comm
},
}
cmd.Flags().Var(&options.cluster, clientcmd.FlagClusterName, clientcmd.FlagClusterName+" for the context entry in .kubeconfig")
cmd.Flags().Var(&options.authInfo, clientcmd.FlagAuthInfoName, clientcmd.FlagAuthInfoName+" for the context entry in .kubeconfig")
cmd.Flags().Var(&options.namespace, clientcmd.FlagNamespace, clientcmd.FlagNamespace+" for the context entry in .kubeconfig")
cmd.Flags().Var(&options.cluster, clientcmd.FlagClusterName, clientcmd.FlagClusterName+" for the context entry in kubeconfig")
cmd.Flags().Var(&options.authInfo, clientcmd.FlagAuthInfoName, clientcmd.FlagAuthInfoName+" for the context entry in kubeconfig")
cmd.Flags().Var(&options.namespace, clientcmd.FlagNamespace, clientcmd.FlagNamespace+" for the context entry in kubeconfig")
return cmd
}
@ -76,7 +76,7 @@ func (o createContextOptions) run() error {
return err
}
config, filename, err := o.pathOptions.getStartingConfig()
config, err := o.pathOptions.getStartingConfig()
if err != nil {
return err
}
@ -84,8 +84,7 @@ func (o createContextOptions) run() error {
context := o.modifyContext(config.Contexts[o.name])
config.Contexts[o.name] = context
err = clientcmd.WriteToFile(*config, filename)
if err != nil {
if err := o.pathOptions.ModifyConfig(*config); err != nil {
return err
}
@ -124,5 +123,5 @@ func (o createContextOptions) validate() error {
return errors.New("You must specify a non-empty context name")
}
return nil
return o.pathOptions.Validate()
}

View File

@ -24,8 +24,6 @@ import (
"strings"
"github.com/spf13/cobra"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
)
const (
@ -34,21 +32,21 @@ const (
)
type setOptions struct {
pathOptions *pathOptions
pathOptions *PathOptions
propertyName string
propertyValue string
}
const set_long = `Sets an individual value in a .kubeconfig file
const set_long = `Sets an individual value in a kubeconfig file
PROPERTY_NAME is a dot delimited name where each token represents either a attribute name or a map key. Map keys may not contain dots.
PROPERTY_VALUE is the new value you wish to set.`
func NewCmdConfigSet(out io.Writer, pathOptions *pathOptions) *cobra.Command {
func NewCmdConfigSet(out io.Writer, pathOptions *PathOptions) *cobra.Command {
options := &setOptions{pathOptions: pathOptions}
cmd := &cobra.Command{
Use: "set PROPERTY_NAME PROPERTY_VALUE",
Short: "Sets an individual value in a .kubeconfig file",
Short: "Sets an individual value in a kubeconfig file",
Long: set_long,
Run: func(cmd *cobra.Command, args []string) {
if !options.complete(cmd) {
@ -71,15 +69,10 @@ func (o setOptions) run() error {
return err
}
config, filename, err := o.pathOptions.getStartingConfig()
config, err := o.pathOptions.getStartingConfig()
if err != nil {
return err
}
if len(filename) == 0 {
return errors.New("cannot set property without using a specific file")
}
steps, err := newNavigationSteps(o.propertyName)
if err != nil {
return err
@ -89,8 +82,7 @@ func (o setOptions) run() error {
return err
}
err = clientcmd.WriteToFile(*config, filename)
if err != nil {
if err := o.pathOptions.ModifyConfig(*config); err != nil {
return err
}
@ -118,7 +110,7 @@ func (o setOptions) validate() error {
return errors.New("You must specify a property")
}
return nil
return o.pathOptions.Validate()
}
func modifyConfig(curr reflect.Value, steps *navigationSteps, propertyValue string, unset bool) error {

View File

@ -23,24 +23,22 @@ import (
"reflect"
"github.com/spf13/cobra"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
)
type unsetOptions struct {
pathOptions *pathOptions
pathOptions *PathOptions
propertyName string
}
const unset_long = `Unsets an individual value in a .kubeconfig file
const unset_long = `Unsets an individual value in a kubeconfig file
PROPERTY_NAME is a dot delimited name where each token represents either a attribute name or a map key. Map keys may not contain dots.`
func NewCmdConfigUnset(out io.Writer, pathOptions *pathOptions) *cobra.Command {
func NewCmdConfigUnset(out io.Writer, pathOptions *PathOptions) *cobra.Command {
options := &unsetOptions{pathOptions: pathOptions}
cmd := &cobra.Command{
Use: "unset PROPERTY_NAME",
Short: "Unsets an individual value in a .kubeconfig file",
Short: "Unsets an individual value in a kubeconfig file",
Long: unset_long,
Run: func(cmd *cobra.Command, args []string) {
if !options.complete(cmd) {
@ -63,15 +61,11 @@ func (o unsetOptions) run() error {
return err
}
config, filename, err := o.pathOptions.getStartingConfig()
config, err := o.pathOptions.getStartingConfig()
if err != nil {
return err
}
if len(filename) == 0 {
return errors.New("cannot set property without using a specific file")
}
steps, err := newNavigationSteps(o.propertyName)
if err != nil {
return err
@ -81,8 +75,7 @@ func (o unsetOptions) run() error {
return err
}
err = clientcmd.WriteToFile(*config, filename)
if err != nil {
if err := o.pathOptions.ModifyConfig(*config); err != nil {
return err
}
@ -105,5 +98,5 @@ func (o unsetOptions) validate() error {
return errors.New("You must specify a property")
}
return nil
return o.pathOptions.Validate()
}

View File

@ -22,22 +22,20 @@ import (
"io"
"github.com/spf13/cobra"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
)
type useContextOptions struct {
pathOptions *pathOptions
pathOptions *PathOptions
contextName string
}
func NewCmdConfigUseContext(out io.Writer, pathOptions *pathOptions) *cobra.Command {
func NewCmdConfigUseContext(out io.Writer, pathOptions *PathOptions) *cobra.Command {
options := &useContextOptions{pathOptions: pathOptions}
cmd := &cobra.Command{
Use: "use-context CONTEXT_NAME",
Short: "Sets the current-context in a .kubeconfig file",
Long: `Sets the current-context in a .kubeconfig file`,
Short: "Sets the current-context in a kubeconfig file",
Long: `Sets the current-context in a kubeconfig file`,
Run: func(cmd *cobra.Command, args []string) {
if !options.complete(cmd) {
return
@ -59,19 +57,14 @@ func (o useContextOptions) run() error {
return err
}
config, filename, err := o.pathOptions.getStartingConfig()
config, err := o.pathOptions.getStartingConfig()
if err != nil {
return err
}
if len(filename) == 0 {
return errors.New("cannot set current-context without using a specific file")
}
config.CurrentContext = o.contextName
err = clientcmd.WriteToFile(*config, filename)
if err != nil {
if err := o.pathOptions.ModifyConfig(*config); err != nil {
return err
}
@ -94,5 +87,5 @@ func (o useContextOptions) validate() error {
return errors.New("You must specify a current-context")
}
return nil
return o.pathOptions.Validate()
}

View File

@ -17,7 +17,7 @@ limitations under the License.
package config
import (
"fmt"
"errors"
"io"
"github.com/golang/glog"
@ -32,30 +32,30 @@ import (
)
type viewOptions struct {
pathOptions *pathOptions
pathOptions *PathOptions
merge util.BoolFlag
}
const (
view_long = `displays merged .kubeconfig settings or a specified .kubeconfig file.
view_long = `displays merged kubeconfig settings or a specified kubeconfig file.
You can use --output=template --template=TEMPLATE to extract specific values.`
view_example = `// Show merged .kubeconfig settings.
view_example = `// Show merged kubeconfig settings.
$ kubectl config view
// Show only local ./.kubeconfig settings
// Show only local kubeconfig settings
$ kubectl config view --local
// Get the password for the e2e user
$ kubectl config view -o template --template='{{range .users}}{{ if eq .name "e2e" }}{{ index .user.password }}{{end}}{{end}}'`
)
func NewCmdConfigView(out io.Writer, pathOptions *pathOptions) *cobra.Command {
func NewCmdConfigView(out io.Writer, pathOptions *PathOptions) *cobra.Command {
options := &viewOptions{pathOptions: pathOptions}
cmd := &cobra.Command{
Use: "view",
Short: "displays merged .kubeconfig settings or a specified .kubeconfig file.",
Short: "displays merged kubeconfig settings or a specified kubeconfig file.",
Long: view_long,
Example: view_example,
Run: func(cmd *cobra.Command, args []string) {
@ -85,13 +85,13 @@ func NewCmdConfigView(out io.Writer, pathOptions *pathOptions) *cobra.Command {
cmd.Flags().Set("output", "yaml")
options.merge.Default(true)
cmd.Flags().Var(&options.merge, "merge", "merge together the full hierarchy of .kubeconfig files")
cmd.Flags().Var(&options.merge, "merge", "merge together the full hierarchy of kubeconfig files")
return cmd
}
func (o *viewOptions) complete() bool {
// if --kubeconfig, --global, or --local is specified, then merging doesn't make sense since you're declaring precise intent
if (len(o.pathOptions.specifiedFile) > 0) || o.pathOptions.global || o.pathOptions.local {
if o.pathOptions.Global || o.pathOptions.Local || o.pathOptions.UseEnvVar {
if !o.merge.Provided() {
o.merge.Set("false")
}
@ -106,29 +106,36 @@ func (o viewOptions) loadConfig() (*clientcmdapi.Config, error) {
return nil, err
}
config, _, err := o.getStartingConfig()
config, err := o.getStartingConfig()
return config, err
}
func (o viewOptions) validate() error {
return nil
return o.pathOptions.Validate()
}
// getStartingConfig returns the Config object built from the sources specified by the options, the filename read (only if it was a single file), and an error if something goes wrong
func (o *viewOptions) getStartingConfig() (*clientcmdapi.Config, string, error) {
func (o *viewOptions) getStartingConfig() (*clientcmdapi.Config, error) {
switch {
case o.merge.Value():
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
loadingRules.ExplicitPath = o.pathOptions.specifiedFile
case !o.merge.Value():
switch {
case len(o.pathOptions.LoadingRules.ExplicitPath) > 0:
return clientcmd.LoadFromFile(o.pathOptions.LoadingRules.ExplicitPath)
overrides := &clientcmd.ConfigOverrides{}
clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, overrides)
case o.pathOptions.Global:
return clientcmd.LoadFromFile(o.pathOptions.GlobalFile)
case o.pathOptions.UseEnvVar:
return clientcmd.LoadFromFile(o.pathOptions.EnvVarFile)
case o.pathOptions.Local:
return clientcmd.LoadFromFile(o.pathOptions.LocalFile)
default:
return nil, errors.New("if merge==false a precise file must to specified")
config, err := clientConfig.RawConfig()
if err != nil {
return nil, "", fmt.Errorf("Error getting config: %v", err)
}
return &config, "", nil
default:
return o.pathOptions.getStartingConfig()
}