...

Source file src/k8s.io/client-go/tools/clientcmd/overrides.go

Documentation: k8s.io/client-go/tools/clientcmd

     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 clientcmd
    18  
    19  import (
    20  	"strconv"
    21  	"strings"
    22  
    23  	"github.com/spf13/pflag"
    24  
    25  	clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
    26  )
    27  
    28  // ConfigOverrides holds values that should override whatever information is pulled from the actual Config object.  You can't
    29  // simply use an actual Config object, because Configs hold maps, but overrides are restricted to "at most one"
    30  type ConfigOverrides struct {
    31  	AuthInfo clientcmdapi.AuthInfo
    32  	// ClusterDefaults are applied before the configured cluster info is loaded.
    33  	ClusterDefaults clientcmdapi.Cluster
    34  	ClusterInfo     clientcmdapi.Cluster
    35  	Context         clientcmdapi.Context
    36  	CurrentContext  string
    37  	Timeout         string
    38  }
    39  
    40  // ConfigOverrideFlags holds the flag names to be used for binding command line flags. Notice that this structure tightly
    41  // corresponds to ConfigOverrides
    42  type ConfigOverrideFlags struct {
    43  	AuthOverrideFlags    AuthOverrideFlags
    44  	ClusterOverrideFlags ClusterOverrideFlags
    45  	ContextOverrideFlags ContextOverrideFlags
    46  	CurrentContext       FlagInfo
    47  	Timeout              FlagInfo
    48  }
    49  
    50  // AuthOverrideFlags holds the flag names to be used for binding command line flags for AuthInfo objects
    51  type AuthOverrideFlags struct {
    52  	ClientCertificate FlagInfo
    53  	ClientKey         FlagInfo
    54  	Token             FlagInfo
    55  	Impersonate       FlagInfo
    56  	ImpersonateUID    FlagInfo
    57  	ImpersonateGroups FlagInfo
    58  	Username          FlagInfo
    59  	Password          FlagInfo
    60  }
    61  
    62  // ContextOverrideFlags holds the flag names to be used for binding command line flags for Cluster objects
    63  type ContextOverrideFlags struct {
    64  	ClusterName  FlagInfo
    65  	AuthInfoName FlagInfo
    66  	Namespace    FlagInfo
    67  }
    68  
    69  // ClusterOverride holds the flag names to be used for binding command line flags for Cluster objects
    70  type ClusterOverrideFlags struct {
    71  	APIServer             FlagInfo
    72  	APIVersion            FlagInfo
    73  	CertificateAuthority  FlagInfo
    74  	InsecureSkipTLSVerify FlagInfo
    75  	TLSServerName         FlagInfo
    76  	ProxyURL              FlagInfo
    77  	DisableCompression    FlagInfo
    78  }
    79  
    80  // FlagInfo contains information about how to register a flag.  This struct is useful if you want to provide a way for an extender to
    81  // get back a set of recommended flag names, descriptions, and defaults, but allow for customization by an extender.  This makes for
    82  // coherent extension, without full prescription
    83  type FlagInfo struct {
    84  	// LongName is the long string for a flag.  If this is empty, then the flag will not be bound
    85  	LongName string
    86  	// ShortName is the single character for a flag.  If this is empty, then there will be no short flag
    87  	ShortName string
    88  	// Default is the default value for the flag
    89  	Default string
    90  	// Description is the description for the flag
    91  	Description string
    92  }
    93  
    94  // AddSecretAnnotation add secret flag to Annotation.
    95  func (f FlagInfo) AddSecretAnnotation(flags *pflag.FlagSet) FlagInfo {
    96  	flags.SetAnnotation(f.LongName, "classified", []string{"true"})
    97  	return f
    98  }
    99  
   100  // BindStringFlag binds the flag based on the provided info.  If LongName == "", nothing is registered
   101  func (f FlagInfo) BindStringFlag(flags *pflag.FlagSet, target *string) FlagInfo {
   102  	// you can't register a flag without a long name
   103  	if len(f.LongName) > 0 {
   104  		flags.StringVarP(target, f.LongName, f.ShortName, f.Default, f.Description)
   105  	}
   106  	return f
   107  }
   108  
   109  // BindTransformingStringFlag binds the flag based on the provided info.  If LongName == "", nothing is registered
   110  func (f FlagInfo) BindTransformingStringFlag(flags *pflag.FlagSet, target *string, transformer func(string) (string, error)) FlagInfo {
   111  	// you can't register a flag without a long name
   112  	if len(f.LongName) > 0 {
   113  		flags.VarP(newTransformingStringValue(f.Default, target, transformer), f.LongName, f.ShortName, f.Description)
   114  	}
   115  	return f
   116  }
   117  
   118  // BindStringSliceFlag binds the flag based on the provided info.  If LongName == "", nothing is registered
   119  func (f FlagInfo) BindStringArrayFlag(flags *pflag.FlagSet, target *[]string) FlagInfo {
   120  	// you can't register a flag without a long name
   121  	if len(f.LongName) > 0 {
   122  		sliceVal := []string{}
   123  		if len(f.Default) > 0 {
   124  			sliceVal = []string{f.Default}
   125  		}
   126  		flags.StringArrayVarP(target, f.LongName, f.ShortName, sliceVal, f.Description)
   127  	}
   128  	return f
   129  }
   130  
   131  // BindBoolFlag binds the flag based on the provided info.  If LongName == "", nothing is registered
   132  func (f FlagInfo) BindBoolFlag(flags *pflag.FlagSet, target *bool) FlagInfo {
   133  	// you can't register a flag without a long name
   134  	if len(f.LongName) > 0 {
   135  		// try to parse Default as a bool.  If it fails, assume false
   136  		boolVal, err := strconv.ParseBool(f.Default)
   137  		if err != nil {
   138  			boolVal = false
   139  		}
   140  
   141  		flags.BoolVarP(target, f.LongName, f.ShortName, boolVal, f.Description)
   142  	}
   143  	return f
   144  }
   145  
   146  const (
   147  	FlagClusterName        = "cluster"
   148  	FlagAuthInfoName       = "user"
   149  	FlagContext            = "context"
   150  	FlagNamespace          = "namespace"
   151  	FlagAPIServer          = "server"
   152  	FlagTLSServerName      = "tls-server-name"
   153  	FlagInsecure           = "insecure-skip-tls-verify"
   154  	FlagCertFile           = "client-certificate"
   155  	FlagKeyFile            = "client-key"
   156  	FlagCAFile             = "certificate-authority"
   157  	FlagEmbedCerts         = "embed-certs"
   158  	FlagBearerToken        = "token"
   159  	FlagImpersonate        = "as"
   160  	FlagImpersonateUID     = "as-uid"
   161  	FlagImpersonateGroup   = "as-group"
   162  	FlagUsername           = "username"
   163  	FlagPassword           = "password"
   164  	FlagTimeout            = "request-timeout"
   165  	FlagProxyURL           = "proxy-url"
   166  	FlagDisableCompression = "disable-compression"
   167  )
   168  
   169  // RecommendedConfigOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing
   170  func RecommendedConfigOverrideFlags(prefix string) ConfigOverrideFlags {
   171  	return ConfigOverrideFlags{
   172  		AuthOverrideFlags:    RecommendedAuthOverrideFlags(prefix),
   173  		ClusterOverrideFlags: RecommendedClusterOverrideFlags(prefix),
   174  		ContextOverrideFlags: RecommendedContextOverrideFlags(prefix),
   175  
   176  		CurrentContext: FlagInfo{prefix + FlagContext, "", "", "The name of the kubeconfig context to use"},
   177  		Timeout:        FlagInfo{prefix + FlagTimeout, "", "0", "The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests."},
   178  	}
   179  }
   180  
   181  // RecommendedAuthOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing
   182  func RecommendedAuthOverrideFlags(prefix string) AuthOverrideFlags {
   183  	return AuthOverrideFlags{
   184  		ClientCertificate: FlagInfo{prefix + FlagCertFile, "", "", "Path to a client certificate file for TLS"},
   185  		ClientKey:         FlagInfo{prefix + FlagKeyFile, "", "", "Path to a client key file for TLS"},
   186  		Token:             FlagInfo{prefix + FlagBearerToken, "", "", "Bearer token for authentication to the API server"},
   187  		Impersonate:       FlagInfo{prefix + FlagImpersonate, "", "", "Username to impersonate for the operation"},
   188  		ImpersonateUID:    FlagInfo{prefix + FlagImpersonateUID, "", "", "UID to impersonate for the operation"},
   189  		ImpersonateGroups: FlagInfo{prefix + FlagImpersonateGroup, "", "", "Group to impersonate for the operation, this flag can be repeated to specify multiple groups."},
   190  		Username:          FlagInfo{prefix + FlagUsername, "", "", "Username for basic authentication to the API server"},
   191  		Password:          FlagInfo{prefix + FlagPassword, "", "", "Password for basic authentication to the API server"},
   192  	}
   193  }
   194  
   195  // RecommendedClusterOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing
   196  func RecommendedClusterOverrideFlags(prefix string) ClusterOverrideFlags {
   197  	return ClusterOverrideFlags{
   198  		APIServer:             FlagInfo{prefix + FlagAPIServer, "", "", "The address and port of the Kubernetes API server"},
   199  		CertificateAuthority:  FlagInfo{prefix + FlagCAFile, "", "", "Path to a cert file for the certificate authority"},
   200  		InsecureSkipTLSVerify: FlagInfo{prefix + FlagInsecure, "", "false", "If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure"},
   201  		TLSServerName:         FlagInfo{prefix + FlagTLSServerName, "", "", "If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used."},
   202  		ProxyURL:              FlagInfo{prefix + FlagProxyURL, "", "", "If provided, this URL will be used to connect via proxy"},
   203  		DisableCompression:    FlagInfo{prefix + FlagDisableCompression, "", "", "If true, opt-out of response compression for all requests to the server"},
   204  	}
   205  }
   206  
   207  // RecommendedContextOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing
   208  func RecommendedContextOverrideFlags(prefix string) ContextOverrideFlags {
   209  	return ContextOverrideFlags{
   210  		ClusterName:  FlagInfo{prefix + FlagClusterName, "", "", "The name of the kubeconfig cluster to use"},
   211  		AuthInfoName: FlagInfo{prefix + FlagAuthInfoName, "", "", "The name of the kubeconfig user to use"},
   212  		Namespace:    FlagInfo{prefix + FlagNamespace, "n", "", "If present, the namespace scope for this CLI request"},
   213  	}
   214  }
   215  
   216  // BindOverrideFlags is a convenience method to bind the specified flags to their associated variables
   217  func BindOverrideFlags(overrides *ConfigOverrides, flags *pflag.FlagSet, flagNames ConfigOverrideFlags) {
   218  	BindAuthInfoFlags(&overrides.AuthInfo, flags, flagNames.AuthOverrideFlags)
   219  	BindClusterFlags(&overrides.ClusterInfo, flags, flagNames.ClusterOverrideFlags)
   220  	BindContextFlags(&overrides.Context, flags, flagNames.ContextOverrideFlags)
   221  	flagNames.CurrentContext.BindStringFlag(flags, &overrides.CurrentContext)
   222  	flagNames.Timeout.BindStringFlag(flags, &overrides.Timeout)
   223  }
   224  
   225  // BindAuthInfoFlags is a convenience method to bind the specified flags to their associated variables
   226  func BindAuthInfoFlags(authInfo *clientcmdapi.AuthInfo, flags *pflag.FlagSet, flagNames AuthOverrideFlags) {
   227  	flagNames.ClientCertificate.BindStringFlag(flags, &authInfo.ClientCertificate).AddSecretAnnotation(flags)
   228  	flagNames.ClientKey.BindStringFlag(flags, &authInfo.ClientKey).AddSecretAnnotation(flags)
   229  	flagNames.Token.BindStringFlag(flags, &authInfo.Token).AddSecretAnnotation(flags)
   230  	flagNames.Impersonate.BindStringFlag(flags, &authInfo.Impersonate).AddSecretAnnotation(flags)
   231  	flagNames.ImpersonateUID.BindStringFlag(flags, &authInfo.ImpersonateUID).AddSecretAnnotation(flags)
   232  	flagNames.ImpersonateGroups.BindStringArrayFlag(flags, &authInfo.ImpersonateGroups).AddSecretAnnotation(flags)
   233  	flagNames.Username.BindStringFlag(flags, &authInfo.Username).AddSecretAnnotation(flags)
   234  	flagNames.Password.BindStringFlag(flags, &authInfo.Password).AddSecretAnnotation(flags)
   235  }
   236  
   237  // BindClusterFlags is a convenience method to bind the specified flags to their associated variables
   238  func BindClusterFlags(clusterInfo *clientcmdapi.Cluster, flags *pflag.FlagSet, flagNames ClusterOverrideFlags) {
   239  	flagNames.APIServer.BindStringFlag(flags, &clusterInfo.Server)
   240  	flagNames.CertificateAuthority.BindStringFlag(flags, &clusterInfo.CertificateAuthority)
   241  	flagNames.InsecureSkipTLSVerify.BindBoolFlag(flags, &clusterInfo.InsecureSkipTLSVerify)
   242  	flagNames.TLSServerName.BindStringFlag(flags, &clusterInfo.TLSServerName)
   243  	flagNames.ProxyURL.BindStringFlag(flags, &clusterInfo.ProxyURL)
   244  	flagNames.DisableCompression.BindBoolFlag(flags, &clusterInfo.DisableCompression)
   245  }
   246  
   247  // BindFlags is a convenience method to bind the specified flags to their associated variables
   248  func BindContextFlags(contextInfo *clientcmdapi.Context, flags *pflag.FlagSet, flagNames ContextOverrideFlags) {
   249  	flagNames.ClusterName.BindStringFlag(flags, &contextInfo.Cluster)
   250  	flagNames.AuthInfoName.BindStringFlag(flags, &contextInfo.AuthInfo)
   251  	flagNames.Namespace.BindTransformingStringFlag(flags, &contextInfo.Namespace, RemoveNamespacesPrefix)
   252  }
   253  
   254  // RemoveNamespacesPrefix is a transformer that strips "ns/", "namespace/" and "namespaces/" prefixes case-insensitively
   255  func RemoveNamespacesPrefix(value string) (string, error) {
   256  	for _, prefix := range []string{"namespaces/", "namespace/", "ns/"} {
   257  		if len(value) > len(prefix) && strings.EqualFold(value[0:len(prefix)], prefix) {
   258  			value = value[len(prefix):]
   259  			break
   260  		}
   261  	}
   262  	return value, nil
   263  }
   264  

View as plain text