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 api 18 19 import ( 20 "fmt" 21 22 "k8s.io/apimachinery/pkg/runtime" 23 ) 24 25 // Where possible, json tags match the cli argument names. 26 // Top level config objects and all values required for proper functioning are not "omitempty". Any truly optional piece of config is allowed to be omitted. 27 28 // Config holds the information needed to build connect to remote kubernetes clusters as a given user 29 // IMPORTANT if you add fields to this struct, please update IsConfigEmpty() 30 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object 31 type Config struct { 32 // Legacy field from pkg/api/types.go TypeMeta. 33 // TODO(jlowdermilk): remove this after eliminating downstream dependencies. 34 // +k8s:conversion-gen=false 35 // +optional 36 Kind string `json:"kind,omitempty"` 37 // Legacy field from pkg/api/types.go TypeMeta. 38 // TODO(jlowdermilk): remove this after eliminating downstream dependencies. 39 // +k8s:conversion-gen=false 40 // +optional 41 APIVersion string `json:"apiVersion,omitempty"` 42 // Preferences holds general information to be use for cli interactions 43 Preferences Preferences `json:"preferences"` 44 // Clusters is a map of referencable names to cluster configs 45 Clusters map[string]*Cluster `json:"clusters"` 46 // AuthInfos is a map of referencable names to user configs 47 AuthInfos map[string]*AuthInfo `json:"users"` 48 // Contexts is a map of referencable names to context configs 49 Contexts map[string]*Context `json:"contexts"` 50 // CurrentContext is the name of the context that you would like to use by default 51 CurrentContext string `json:"current-context"` 52 // Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields 53 // +optional 54 Extensions map[string]runtime.Object `json:"extensions,omitempty"` 55 } 56 57 // IMPORTANT if you add fields to this struct, please update IsConfigEmpty() 58 type Preferences struct { 59 // +optional 60 Colors bool `json:"colors,omitempty"` 61 // Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields 62 // +optional 63 Extensions map[string]runtime.Object `json:"extensions,omitempty"` 64 } 65 66 // Cluster contains information about how to communicate with a kubernetes cluster 67 type Cluster struct { 68 // LocationOfOrigin indicates where this object came from. It is used for round tripping config post-merge, but never serialized. 69 // +k8s:conversion-gen=false 70 LocationOfOrigin string `json:"-"` 71 // Server is the address of the kubernetes cluster (https://hostname:port). 72 Server string `json:"server"` 73 // TLSServerName is used to check server certificate. If TLSServerName is empty, the hostname used to contact the server is used. 74 // +optional 75 TLSServerName string `json:"tls-server-name,omitempty"` 76 // InsecureSkipTLSVerify skips the validity check for the server's certificate. This will make your HTTPS connections insecure. 77 // +optional 78 InsecureSkipTLSVerify bool `json:"insecure-skip-tls-verify,omitempty"` 79 // CertificateAuthority is the path to a cert file for the certificate authority. 80 // +optional 81 CertificateAuthority string `json:"certificate-authority,omitempty"` 82 // CertificateAuthorityData contains PEM-encoded certificate authority certificates. Overrides CertificateAuthority 83 // +optional 84 CertificateAuthorityData []byte `json:"certificate-authority-data,omitempty"` 85 // ProxyURL is the URL to the proxy to be used for all requests made by this 86 // client. URLs with "http", "https", and "socks5" schemes are supported. If 87 // this configuration is not provided or the empty string, the client 88 // attempts to construct a proxy configuration from http_proxy and 89 // https_proxy environment variables. If these environment variables are not 90 // set, the client does not attempt to proxy requests. 91 // 92 // socks5 proxying does not currently support spdy streaming endpoints (exec, 93 // attach, port forward). 94 // +optional 95 ProxyURL string `json:"proxy-url,omitempty"` 96 // DisableCompression allows client to opt-out of response compression for all requests to the server. This is useful 97 // to speed up requests (specifically lists) when client-server network bandwidth is ample, by saving time on 98 // compression (server-side) and decompression (client-side): https://github.com/kubernetes/kubernetes/issues/112296. 99 // +optional 100 DisableCompression bool `json:"disable-compression,omitempty"` 101 // Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields 102 // +optional 103 Extensions map[string]runtime.Object `json:"extensions,omitempty"` 104 } 105 106 // AuthInfo contains information that describes identity information. This is use to tell the kubernetes cluster who you are. 107 type AuthInfo struct { 108 // LocationOfOrigin indicates where this object came from. It is used for round tripping config post-merge, but never serialized. 109 // +k8s:conversion-gen=false 110 LocationOfOrigin string `json:"-"` 111 // ClientCertificate is the path to a client cert file for TLS. 112 // +optional 113 ClientCertificate string `json:"client-certificate,omitempty"` 114 // ClientCertificateData contains PEM-encoded data from a client cert file for TLS. Overrides ClientCertificate 115 // +optional 116 ClientCertificateData []byte `json:"client-certificate-data,omitempty"` 117 // ClientKey is the path to a client key file for TLS. 118 // +optional 119 ClientKey string `json:"client-key,omitempty"` 120 // ClientKeyData contains PEM-encoded data from a client key file for TLS. Overrides ClientKey 121 // +optional 122 ClientKeyData []byte `json:"client-key-data,omitempty" datapolicy:"security-key"` 123 // Token is the bearer token for authentication to the kubernetes cluster. 124 // +optional 125 Token string `json:"token,omitempty" datapolicy:"token"` 126 // TokenFile is a pointer to a file that contains a bearer token (as described above). If both Token and TokenFile are present, Token takes precedence. 127 // +optional 128 TokenFile string `json:"tokenFile,omitempty"` 129 // Impersonate is the username to act-as. 130 // +optional 131 Impersonate string `json:"act-as,omitempty"` 132 // ImpersonateUID is the uid to impersonate. 133 // +optional 134 ImpersonateUID string `json:"act-as-uid,omitempty"` 135 // ImpersonateGroups is the groups to impersonate. 136 // +optional 137 ImpersonateGroups []string `json:"act-as-groups,omitempty"` 138 // ImpersonateUserExtra contains additional information for impersonated user. 139 // +optional 140 ImpersonateUserExtra map[string][]string `json:"act-as-user-extra,omitempty"` 141 // Username is the username for basic authentication to the kubernetes cluster. 142 // +optional 143 Username string `json:"username,omitempty"` 144 // Password is the password for basic authentication to the kubernetes cluster. 145 // +optional 146 Password string `json:"password,omitempty" datapolicy:"password"` 147 // AuthProvider specifies a custom authentication plugin for the kubernetes cluster. 148 // +optional 149 AuthProvider *AuthProviderConfig `json:"auth-provider,omitempty"` 150 // Exec specifies a custom exec-based authentication plugin for the kubernetes cluster. 151 // +optional 152 Exec *ExecConfig `json:"exec,omitempty"` 153 // Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields 154 // +optional 155 Extensions map[string]runtime.Object `json:"extensions,omitempty"` 156 } 157 158 // 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) 159 type Context struct { 160 // LocationOfOrigin indicates where this object came from. It is used for round tripping config post-merge, but never serialized. 161 // +k8s:conversion-gen=false 162 LocationOfOrigin string `json:"-"` 163 // Cluster is the name of the cluster for this context 164 Cluster string `json:"cluster"` 165 // AuthInfo is the name of the authInfo for this context 166 AuthInfo string `json:"user"` 167 // Namespace is the default namespace to use on unspecified requests 168 // +optional 169 Namespace string `json:"namespace,omitempty"` 170 // Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields 171 // +optional 172 Extensions map[string]runtime.Object `json:"extensions,omitempty"` 173 } 174 175 // AuthProviderConfig holds the configuration for a specified auth provider. 176 type AuthProviderConfig struct { 177 Name string `json:"name"` 178 // +optional 179 Config map[string]string `json:"config,omitempty"` 180 } 181 182 var _ fmt.Stringer = new(AuthProviderConfig) 183 var _ fmt.GoStringer = new(AuthProviderConfig) 184 185 // GoString implements fmt.GoStringer and sanitizes sensitive fields of 186 // AuthProviderConfig to prevent accidental leaking via logs. 187 func (c AuthProviderConfig) GoString() string { 188 return c.String() 189 } 190 191 // String implements fmt.Stringer and sanitizes sensitive fields of 192 // AuthProviderConfig to prevent accidental leaking via logs. 193 func (c AuthProviderConfig) String() string { 194 cfg := "<nil>" 195 if c.Config != nil { 196 cfg = "--- REDACTED ---" 197 } 198 return fmt.Sprintf("api.AuthProviderConfig{Name: %q, Config: map[string]string{%s}}", c.Name, cfg) 199 } 200 201 // ExecConfig specifies a command to provide client credentials. The command is exec'd 202 // and outputs structured stdout holding credentials. 203 // 204 // See the client.authentication.k8s.io API group for specifications of the exact input 205 // and output format 206 type ExecConfig struct { 207 // Command to execute. 208 Command string `json:"command"` 209 // Arguments to pass to the command when executing it. 210 // +optional 211 Args []string `json:"args"` 212 // Env defines additional environment variables to expose to the process. These 213 // are unioned with the host's environment, as well as variables client-go uses 214 // to pass argument to the plugin. 215 // +optional 216 Env []ExecEnvVar `json:"env"` 217 218 // Preferred input version of the ExecInfo. The returned ExecCredentials MUST use 219 // the same encoding version as the input. 220 APIVersion string `json:"apiVersion,omitempty"` 221 222 // This text is shown to the user when the executable doesn't seem to be 223 // present. For example, `brew install foo-cli` might be a good InstallHint for 224 // foo-cli on Mac OS systems. 225 InstallHint string `json:"installHint,omitempty"` 226 227 // ProvideClusterInfo determines whether or not to provide cluster information, 228 // which could potentially contain very large CA data, to this exec plugin as a 229 // part of the KUBERNETES_EXEC_INFO environment variable. By default, it is set 230 // to false. Package k8s.io/client-go/tools/auth/exec provides helper methods for 231 // reading this environment variable. 232 ProvideClusterInfo bool `json:"provideClusterInfo"` 233 234 // Config holds additional config data that is specific to the exec 235 // plugin with regards to the cluster being authenticated to. 236 // 237 // This data is sourced from the clientcmd Cluster object's extensions[exec] field: 238 // 239 // clusters: 240 // - name: my-cluster 241 // cluster: 242 // ... 243 // extensions: 244 // - name: client.authentication.k8s.io/exec # reserved extension name for per cluster exec config 245 // extension: 246 // audience: 06e3fbd18de8 # arbitrary config 247 // 248 // In some environments, the user config may be exactly the same across many clusters 249 // (i.e. call this exec plugin) minus some details that are specific to each cluster 250 // such as the audience. This field allows the per cluster config to be directly 251 // specified with the cluster info. Using this field to store secret data is not 252 // recommended as one of the prime benefits of exec plugins is that no secrets need 253 // to be stored directly in the kubeconfig. 254 // +k8s:conversion-gen=false 255 Config runtime.Object `json:"-"` 256 257 // InteractiveMode determines this plugin's relationship with standard input. Valid 258 // values are "Never" (this exec plugin never uses standard input), "IfAvailable" (this 259 // exec plugin wants to use standard input if it is available), or "Always" (this exec 260 // plugin requires standard input to function). See ExecInteractiveMode values for more 261 // details. 262 // 263 // If APIVersion is client.authentication.k8s.io/v1alpha1 or 264 // client.authentication.k8s.io/v1beta1, then this field is optional and defaults 265 // to "IfAvailable" when unset. Otherwise, this field is required. 266 // +optional 267 InteractiveMode ExecInteractiveMode `json:"interactiveMode,omitempty"` 268 269 // StdinUnavailable indicates whether the exec authenticator can pass standard 270 // input through to this exec plugin. For example, a higher level entity might be using 271 // standard input for something else and therefore it would not be safe for the exec 272 // plugin to use standard input. This is kept here in order to keep all of the exec configuration 273 // together, but it is never serialized. 274 // +k8s:conversion-gen=false 275 StdinUnavailable bool `json:"-"` 276 277 // StdinUnavailableMessage is an optional message to be displayed when the exec authenticator 278 // cannot successfully run this exec plugin because it needs to use standard input and 279 // StdinUnavailable is true. For example, a process that is already using standard input to 280 // read user instructions might set this to "used by my-program to read user instructions". 281 // +k8s:conversion-gen=false 282 StdinUnavailableMessage string `json:"-"` 283 } 284 285 var _ fmt.Stringer = new(ExecConfig) 286 var _ fmt.GoStringer = new(ExecConfig) 287 288 // GoString implements fmt.GoStringer and sanitizes sensitive fields of 289 // ExecConfig to prevent accidental leaking via logs. 290 func (c ExecConfig) GoString() string { 291 return c.String() 292 } 293 294 // String implements fmt.Stringer and sanitizes sensitive fields of ExecConfig 295 // to prevent accidental leaking via logs. 296 func (c ExecConfig) String() string { 297 var args []string 298 if len(c.Args) > 0 { 299 args = []string{"--- REDACTED ---"} 300 } 301 env := "[]ExecEnvVar(nil)" 302 if len(c.Env) > 0 { 303 env = "[]ExecEnvVar{--- REDACTED ---}" 304 } 305 config := "runtime.Object(nil)" 306 if c.Config != nil { 307 config = "runtime.Object(--- REDACTED ---)" 308 } 309 return fmt.Sprintf("api.ExecConfig{Command: %q, Args: %#v, Env: %s, APIVersion: %q, ProvideClusterInfo: %t, Config: %s, StdinUnavailable: %t}", c.Command, args, env, c.APIVersion, c.ProvideClusterInfo, config, c.StdinUnavailable) 310 } 311 312 // ExecEnvVar is used for setting environment variables when executing an exec-based 313 // credential plugin. 314 type ExecEnvVar struct { 315 Name string `json:"name"` 316 Value string `json:"value"` 317 } 318 319 // ExecInteractiveMode is a string that describes an exec plugin's relationship with standard input. 320 type ExecInteractiveMode string 321 322 const ( 323 // NeverExecInteractiveMode declares that this exec plugin never needs to use standard 324 // input, and therefore the exec plugin will be run regardless of whether standard input is 325 // available for user input. 326 NeverExecInteractiveMode ExecInteractiveMode = "Never" 327 // IfAvailableExecInteractiveMode declares that this exec plugin would like to use standard input 328 // if it is available, but can still operate if standard input is not available. Therefore, the 329 // exec plugin will be run regardless of whether stdin is available for user input. If standard 330 // input is available for user input, then it will be provided to this exec plugin. 331 IfAvailableExecInteractiveMode ExecInteractiveMode = "IfAvailable" 332 // AlwaysExecInteractiveMode declares that this exec plugin requires standard input in order to 333 // run, and therefore the exec plugin will only be run if standard input is available for user 334 // input. If standard input is not available for user input, then the exec plugin will not be run 335 // and an error will be returned by the exec plugin runner. 336 AlwaysExecInteractiveMode ExecInteractiveMode = "Always" 337 ) 338 339 // NewConfig is a convenience function that returns a new Config object with non-nil maps 340 func NewConfig() *Config { 341 return &Config{ 342 Preferences: *NewPreferences(), 343 Clusters: make(map[string]*Cluster), 344 AuthInfos: make(map[string]*AuthInfo), 345 Contexts: make(map[string]*Context), 346 Extensions: make(map[string]runtime.Object), 347 } 348 } 349 350 // NewContext is a convenience function that returns a new Context 351 // object with non-nil maps 352 func NewContext() *Context { 353 return &Context{Extensions: make(map[string]runtime.Object)} 354 } 355 356 // NewCluster is a convenience function that returns a new Cluster 357 // object with non-nil maps 358 func NewCluster() *Cluster { 359 return &Cluster{Extensions: make(map[string]runtime.Object)} 360 } 361 362 // NewAuthInfo is a convenience function that returns a new AuthInfo 363 // object with non-nil maps 364 func NewAuthInfo() *AuthInfo { 365 return &AuthInfo{ 366 Extensions: make(map[string]runtime.Object), 367 ImpersonateUserExtra: make(map[string][]string), 368 } 369 } 370 371 // NewPreferences is a convenience function that returns a new 372 // Preferences object with non-nil maps 373 func NewPreferences() *Preferences { 374 return &Preferences{Extensions: make(map[string]runtime.Object)} 375 } 376