Code refactoring for bpa operator
[icn.git] / cmd / bpa-operator / vendor / k8s.io / client-go / tools / clientcmd / overrides.go
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         ImpersonateGroups FlagInfo
57         Username          FlagInfo
58         Password          FlagInfo
59 }
60
61 // ContextOverrideFlags holds the flag names to be used for binding command line flags for Cluster objects
62 type ContextOverrideFlags struct {
63         ClusterName  FlagInfo
64         AuthInfoName FlagInfo
65         Namespace    FlagInfo
66 }
67
68 // ClusterOverride holds the flag names to be used for binding command line flags for Cluster objects
69 type ClusterOverrideFlags struct {
70         APIServer             FlagInfo
71         APIVersion            FlagInfo
72         CertificateAuthority  FlagInfo
73         InsecureSkipTLSVerify FlagInfo
74 }
75
76 // FlagInfo contains information about how to register a flag.  This struct is useful if you want to provide a way for an extender to
77 // get back a set of recommended flag names, descriptions, and defaults, but allow for customization by an extender.  This makes for
78 // coherent extension, without full prescription
79 type FlagInfo struct {
80         // LongName is the long string for a flag.  If this is empty, then the flag will not be bound
81         LongName string
82         // ShortName is the single character for a flag.  If this is empty, then there will be no short flag
83         ShortName string
84         // Default is the default value for the flag
85         Default string
86         // Description is the description for the flag
87         Description string
88 }
89
90 // AddSecretAnnotation add secret flag to Annotation.
91 func (f FlagInfo) AddSecretAnnotation(flags *pflag.FlagSet) FlagInfo {
92         flags.SetAnnotation(f.LongName, "classified", []string{"true"})
93         return f
94 }
95
96 // BindStringFlag binds the flag based on the provided info.  If LongName == "", nothing is registered
97 func (f FlagInfo) BindStringFlag(flags *pflag.FlagSet, target *string) FlagInfo {
98         // you can't register a flag without a long name
99         if len(f.LongName) > 0 {
100                 flags.StringVarP(target, f.LongName, f.ShortName, f.Default, f.Description)
101         }
102         return f
103 }
104
105 // BindTransformingStringFlag binds the flag based on the provided info.  If LongName == "", nothing is registered
106 func (f FlagInfo) BindTransformingStringFlag(flags *pflag.FlagSet, target *string, transformer func(string) (string, error)) FlagInfo {
107         // you can't register a flag without a long name
108         if len(f.LongName) > 0 {
109                 flags.VarP(newTransformingStringValue(f.Default, target, transformer), f.LongName, f.ShortName, f.Description)
110         }
111         return f
112 }
113
114 // BindStringSliceFlag binds the flag based on the provided info.  If LongName == "", nothing is registered
115 func (f FlagInfo) BindStringArrayFlag(flags *pflag.FlagSet, target *[]string) FlagInfo {
116         // you can't register a flag without a long name
117         if len(f.LongName) > 0 {
118                 sliceVal := []string{}
119                 if len(f.Default) > 0 {
120                         sliceVal = []string{f.Default}
121                 }
122                 flags.StringArrayVarP(target, f.LongName, f.ShortName, sliceVal, f.Description)
123         }
124         return f
125 }
126
127 // BindBoolFlag binds the flag based on the provided info.  If LongName == "", nothing is registered
128 func (f FlagInfo) BindBoolFlag(flags *pflag.FlagSet, target *bool) FlagInfo {
129         // you can't register a flag without a long name
130         if len(f.LongName) > 0 {
131                 // try to parse Default as a bool.  If it fails, assume false
132                 boolVal, err := strconv.ParseBool(f.Default)
133                 if err != nil {
134                         boolVal = false
135                 }
136
137                 flags.BoolVarP(target, f.LongName, f.ShortName, boolVal, f.Description)
138         }
139         return f
140 }
141
142 const (
143         FlagClusterName      = "cluster"
144         FlagAuthInfoName     = "user"
145         FlagContext          = "context"
146         FlagNamespace        = "namespace"
147         FlagAPIServer        = "server"
148         FlagInsecure         = "insecure-skip-tls-verify"
149         FlagCertFile         = "client-certificate"
150         FlagKeyFile          = "client-key"
151         FlagCAFile           = "certificate-authority"
152         FlagEmbedCerts       = "embed-certs"
153         FlagBearerToken      = "token"
154         FlagImpersonate      = "as"
155         FlagImpersonateGroup = "as-group"
156         FlagUsername         = "username"
157         FlagPassword         = "password"
158         FlagTimeout          = "request-timeout"
159 )
160
161 // RecommendedConfigOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing
162 func RecommendedConfigOverrideFlags(prefix string) ConfigOverrideFlags {
163         return ConfigOverrideFlags{
164                 AuthOverrideFlags:    RecommendedAuthOverrideFlags(prefix),
165                 ClusterOverrideFlags: RecommendedClusterOverrideFlags(prefix),
166                 ContextOverrideFlags: RecommendedContextOverrideFlags(prefix),
167
168                 CurrentContext: FlagInfo{prefix + FlagContext, "", "", "The name of the kubeconfig context to use"},
169                 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."},
170         }
171 }
172
173 // RecommendedAuthOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing
174 func RecommendedAuthOverrideFlags(prefix string) AuthOverrideFlags {
175         return AuthOverrideFlags{
176                 ClientCertificate: FlagInfo{prefix + FlagCertFile, "", "", "Path to a client certificate file for TLS"},
177                 ClientKey:         FlagInfo{prefix + FlagKeyFile, "", "", "Path to a client key file for TLS"},
178                 Token:             FlagInfo{prefix + FlagBearerToken, "", "", "Bearer token for authentication to the API server"},
179                 Impersonate:       FlagInfo{prefix + FlagImpersonate, "", "", "Username to impersonate for the operation"},
180                 ImpersonateGroups: FlagInfo{prefix + FlagImpersonateGroup, "", "", "Group to impersonate for the operation, this flag can be repeated to specify multiple groups."},
181                 Username:          FlagInfo{prefix + FlagUsername, "", "", "Username for basic authentication to the API server"},
182                 Password:          FlagInfo{prefix + FlagPassword, "", "", "Password for basic authentication to the API server"},
183         }
184 }
185
186 // RecommendedClusterOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing
187 func RecommendedClusterOverrideFlags(prefix string) ClusterOverrideFlags {
188         return ClusterOverrideFlags{
189                 APIServer:             FlagInfo{prefix + FlagAPIServer, "", "", "The address and port of the Kubernetes API server"},
190                 CertificateAuthority:  FlagInfo{prefix + FlagCAFile, "", "", "Path to a cert file for the certificate authority"},
191                 InsecureSkipTLSVerify: FlagInfo{prefix + FlagInsecure, "", "false", "If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure"},
192         }
193 }
194
195 // RecommendedContextOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing
196 func RecommendedContextOverrideFlags(prefix string) ContextOverrideFlags {
197         return ContextOverrideFlags{
198                 ClusterName:  FlagInfo{prefix + FlagClusterName, "", "", "The name of the kubeconfig cluster to use"},
199                 AuthInfoName: FlagInfo{prefix + FlagAuthInfoName, "", "", "The name of the kubeconfig user to use"},
200                 Namespace:    FlagInfo{prefix + FlagNamespace, "n", "", "If present, the namespace scope for this CLI request"},
201         }
202 }
203
204 // BindOverrideFlags is a convenience method to bind the specified flags to their associated variables
205 func BindOverrideFlags(overrides *ConfigOverrides, flags *pflag.FlagSet, flagNames ConfigOverrideFlags) {
206         BindAuthInfoFlags(&overrides.AuthInfo, flags, flagNames.AuthOverrideFlags)
207         BindClusterFlags(&overrides.ClusterInfo, flags, flagNames.ClusterOverrideFlags)
208         BindContextFlags(&overrides.Context, flags, flagNames.ContextOverrideFlags)
209         flagNames.CurrentContext.BindStringFlag(flags, &overrides.CurrentContext)
210         flagNames.Timeout.BindStringFlag(flags, &overrides.Timeout)
211 }
212
213 // BindAuthInfoFlags is a convenience method to bind the specified flags to their associated variables
214 func BindAuthInfoFlags(authInfo *clientcmdapi.AuthInfo, flags *pflag.FlagSet, flagNames AuthOverrideFlags) {
215         flagNames.ClientCertificate.BindStringFlag(flags, &authInfo.ClientCertificate).AddSecretAnnotation(flags)
216         flagNames.ClientKey.BindStringFlag(flags, &authInfo.ClientKey).AddSecretAnnotation(flags)
217         flagNames.Token.BindStringFlag(flags, &authInfo.Token).AddSecretAnnotation(flags)
218         flagNames.Impersonate.BindStringFlag(flags, &authInfo.Impersonate).AddSecretAnnotation(flags)
219         flagNames.ImpersonateGroups.BindStringArrayFlag(flags, &authInfo.ImpersonateGroups).AddSecretAnnotation(flags)
220         flagNames.Username.BindStringFlag(flags, &authInfo.Username).AddSecretAnnotation(flags)
221         flagNames.Password.BindStringFlag(flags, &authInfo.Password).AddSecretAnnotation(flags)
222 }
223
224 // BindClusterFlags is a convenience method to bind the specified flags to their associated variables
225 func BindClusterFlags(clusterInfo *clientcmdapi.Cluster, flags *pflag.FlagSet, flagNames ClusterOverrideFlags) {
226         flagNames.APIServer.BindStringFlag(flags, &clusterInfo.Server)
227         flagNames.CertificateAuthority.BindStringFlag(flags, &clusterInfo.CertificateAuthority)
228         flagNames.InsecureSkipTLSVerify.BindBoolFlag(flags, &clusterInfo.InsecureSkipTLSVerify)
229 }
230
231 // BindFlags is a convenience method to bind the specified flags to their associated variables
232 func BindContextFlags(contextInfo *clientcmdapi.Context, flags *pflag.FlagSet, flagNames ContextOverrideFlags) {
233         flagNames.ClusterName.BindStringFlag(flags, &contextInfo.Cluster)
234         flagNames.AuthInfoName.BindStringFlag(flags, &contextInfo.AuthInfo)
235         flagNames.Namespace.BindTransformingStringFlag(flags, &contextInfo.Namespace, RemoveNamespacesPrefix)
236 }
237
238 // RemoveNamespacesPrefix is a transformer that strips "ns/", "namespace/" and "namespaces/" prefixes case-insensitively
239 func RemoveNamespacesPrefix(value string) (string, error) {
240         for _, prefix := range []string{"namespaces/", "namespace/", "ns/"} {
241                 if len(value) > len(prefix) && strings.EqualFold(value[0:len(prefix)], prefix) {
242                         value = value[len(prefix):]
243                         break
244                 }
245         }
246         return value, nil
247 }