2017-04-16 01:30:39 +08:00
/ *
2018-08-25 03:03:55 +08:00
Copyright The Helm Authors .
2017-04-16 01:30:39 +08:00
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
2022-12-22 02:47:13 +08:00
/ *
Package cli describes the operating environment for the Helm CLI .
2017-04-16 01:30:39 +08:00
2019-02-09 08:02:57 +08:00
Helm ' s environment encapsulates all of the service dependencies Helm has .
2017-04-16 01:30:39 +08:00
These dependencies are expressed as interfaces so that alternate implementations
( mocks , etc . ) can be easily generated .
* /
2019-02-09 08:02:57 +08:00
package cli
2017-04-16 01:30:39 +08:00
import (
2019-08-31 01:38:32 +08:00
"fmt"
2022-10-11 09:55:18 +08:00
"net/http"
2017-04-16 01:30:39 +08:00
"os"
2019-09-10 01:55:55 +08:00
"strconv"
2020-09-06 11:01:00 +08:00
"strings"
2017-04-16 01:30:39 +08:00
2017-07-14 07:36:39 +08:00
"github.com/spf13/pflag"
2019-10-11 02:35:46 +08:00
"k8s.io/cli-runtime/pkg/genericclioptions"
2022-05-18 02:00:57 +08:00
"k8s.io/client-go/rest"
2019-10-11 02:35:46 +08:00
2021-10-01 23:19:17 +08:00
"helm.sh/helm/v3/internal/version"
2019-10-11 02:35:54 +08:00
"helm.sh/helm/v3/pkg/helmpath"
2017-04-16 01:30:39 +08:00
)
2020-06-29 23:51:57 +08:00
// defaultMaxHistory sets the maximum number of releases to 0: unlimited
const defaultMaxHistory = 10
2022-05-18 02:00:57 +08:00
// defaultBurstLimit sets the default client-side throttling limit
const defaultBurstLimit = 100
2024-03-23 14:02:54 +08:00
// defaultQPS sets the default QPS value to 0 to use library defaults unless specified
2023-08-31 15:46:28 +08:00
const defaultQPS = float32 ( 0 )
2017-04-28 21:56:01 +08:00
// EnvSettings describes all of the environment settings.
2017-04-16 01:30:39 +08:00
type EnvSettings struct {
2020-04-24 03:20:14 +08:00
namespace string
config * genericclioptions . ConfigFlags
2019-10-15 02:14:14 +08:00
// KubeConfig is the path to the kubeconfig file
KubeConfig string
2018-04-24 03:05:45 +08:00
// KubeContext is the name of the kubeconfig context.
KubeContext string
2019-12-16 15:58:36 +08:00
// Bearer KubeToken used for authentication
KubeToken string
2020-09-06 11:01:00 +08:00
// Username to impersonate for the operation
KubeAsUser string
// Groups to impersonate for the operation, multiple groups parsed from a comma delimited list
KubeAsGroups [ ] string
2019-12-16 15:58:36 +08:00
// Kubernetes API Server Endpoint for authentication
KubeAPIServer string
2020-10-29 17:34:47 +08:00
// Custom certificate authority file.
KubeCaFile string
2022-05-10 00:29:47 +08:00
// KubeInsecureSkipTLSVerify indicates if server's certificate will not be checked for validity.
// This makes the HTTPS connections insecure
KubeInsecureSkipTLSVerify bool
// KubeTLSServerName overrides the name to use for server certificate validation.
// If it is not provided, the hostname used to contact the server is used
KubeTLSServerName string
2017-04-28 21:56:01 +08:00
// Debug indicates whether or not Helm is running in Debug mode.
Debug bool
2019-08-23 14:31:50 +08:00
// RegistryConfig is the path to the registry config file.
RegistryConfig string
// RepositoryConfig is the path to the repositories file.
RepositoryConfig string
2019-12-18 20:04:08 +08:00
// RepositoryCache is the path to the repository cache directory.
2019-08-23 14:31:50 +08:00
RepositoryCache string
// PluginsDirectory is the path to the plugins directory.
PluginsDirectory string
2020-06-29 23:51:57 +08:00
// MaxHistory is the max release history maintained.
MaxHistory int
2022-05-18 02:00:57 +08:00
// BurstLimit is the default client-side throttling limit.
BurstLimit int
2023-08-31 15:46:28 +08:00
// QPS is queries per second which may be used to avoid throttling.
QPS float32
2019-08-23 14:31:50 +08:00
}
func New ( ) * EnvSettings {
2020-04-24 03:20:14 +08:00
env := & EnvSettings {
2022-05-10 00:29:47 +08:00
namespace : os . Getenv ( "HELM_NAMESPACE" ) ,
MaxHistory : envIntOr ( "HELM_MAX_HISTORY" , defaultMaxHistory ) ,
KubeContext : os . Getenv ( "HELM_KUBECONTEXT" ) ,
KubeToken : os . Getenv ( "HELM_KUBETOKEN" ) ,
KubeAsUser : os . Getenv ( "HELM_KUBEASUSER" ) ,
KubeAsGroups : envCSV ( "HELM_KUBEASGROUPS" ) ,
KubeAPIServer : os . Getenv ( "HELM_KUBEAPISERVER" ) ,
KubeCaFile : os . Getenv ( "HELM_KUBECAFILE" ) ,
KubeTLSServerName : os . Getenv ( "HELM_KUBETLS_SERVER_NAME" ) ,
KubeInsecureSkipTLSVerify : envBoolOr ( "HELM_KUBEINSECURE_SKIP_TLS_VERIFY" , false ) ,
PluginsDirectory : envOr ( "HELM_PLUGINS" , helmpath . DataPath ( "plugins" ) ) ,
RegistryConfig : envOr ( "HELM_REGISTRY_CONFIG" , helmpath . ConfigPath ( "registry/config.json" ) ) ,
RepositoryConfig : envOr ( "HELM_REPOSITORY_CONFIG" , helmpath . ConfigPath ( "repositories.yaml" ) ) ,
RepositoryCache : envOr ( "HELM_REPOSITORY_CACHE" , helmpath . CachePath ( "repository" ) ) ,
BurstLimit : envIntOr ( "HELM_BURST_LIMIT" , defaultBurstLimit ) ,
2023-08-31 15:46:28 +08:00
QPS : envFloat32Or ( "HELM_QPS" , defaultQPS ) ,
2019-08-23 14:31:50 +08:00
}
2019-09-10 01:55:55 +08:00
env . Debug , _ = strconv . ParseBool ( os . Getenv ( "HELM_DEBUG" ) )
2020-04-24 03:20:14 +08:00
// bind to kubernetes config flags
2024-06-19 03:08:21 +08:00
config := & genericclioptions . ConfigFlags {
2020-09-06 11:01:00 +08:00
Namespace : & env . namespace ,
Context : & env . KubeContext ,
BearerToken : & env . KubeToken ,
APIServer : & env . KubeAPIServer ,
2020-10-29 17:34:47 +08:00
CAFile : & env . KubeCaFile ,
2020-09-06 11:01:00 +08:00
KubeConfig : & env . KubeConfig ,
Impersonate : & env . KubeAsUser ,
2022-05-10 00:29:47 +08:00
Insecure : & env . KubeInsecureSkipTLSVerify ,
TLSServerName : & env . KubeTLSServerName ,
2020-09-06 11:01:00 +08:00
ImpersonateGroup : & env . KubeAsGroups ,
2022-05-18 02:00:57 +08:00
WrapConfigFn : func ( config * rest . Config ) * rest . Config {
config . Burst = env . BurstLimit
2023-08-31 15:46:28 +08:00
config . QPS = env . QPS
2022-10-11 09:55:18 +08:00
config . Wrap ( func ( rt http . RoundTripper ) http . RoundTripper {
return & retryingRoundTripper { wrapped : rt }
} )
2022-12-22 02:47:13 +08:00
config . UserAgent = version . GetUserAgent ( )
2022-05-18 02:00:57 +08:00
return config
} ,
2020-04-24 03:20:14 +08:00
}
2024-06-19 03:08:21 +08:00
if env . BurstLimit != defaultBurstLimit {
config = config . WithDiscoveryBurst ( env . BurstLimit )
}
env . config = config
2020-04-24 03:20:14 +08:00
return env
2017-07-14 07:36:39 +08:00
}
// AddFlags binds flags to the given flagset.
func ( s * EnvSettings ) AddFlags ( fs * pflag . FlagSet ) {
2019-10-11 02:35:54 +08:00
fs . StringVarP ( & s . namespace , "namespace" , "n" , s . namespace , "namespace scope for this request" )
2019-10-15 02:14:14 +08:00
fs . StringVar ( & s . KubeConfig , "kubeconfig" , "" , "path to the kubeconfig file" )
2019-10-13 02:54:17 +08:00
fs . StringVar ( & s . KubeContext , "kube-context" , s . KubeContext , "name of the kubeconfig context to use" )
2019-12-16 15:58:36 +08:00
fs . StringVar ( & s . KubeToken , "kube-token" , s . KubeToken , "bearer token used for authentication" )
2020-10-30 10:26:56 +08:00
fs . StringVar ( & s . KubeAsUser , "kube-as-user" , s . KubeAsUser , "username to impersonate for the operation" )
fs . StringArrayVar ( & s . KubeAsGroups , "kube-as-group" , s . KubeAsGroups , "group to impersonate for the operation, this flag can be repeated to specify multiple groups." )
2019-12-16 15:58:36 +08:00
fs . StringVar ( & s . KubeAPIServer , "kube-apiserver" , s . KubeAPIServer , "the address and the port for the Kubernetes API server" )
2020-10-29 17:34:47 +08:00
fs . StringVar ( & s . KubeCaFile , "kube-ca-file" , s . KubeCaFile , "the certificate authority file for the Kubernetes API server connection" )
2022-05-10 00:29:47 +08:00
fs . StringVar ( & s . KubeTLSServerName , "kube-tls-server-name" , s . KubeTLSServerName , "server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used" )
fs . BoolVar ( & s . KubeInsecureSkipTLSVerify , "kube-insecure-skip-tls-verify" , s . KubeInsecureSkipTLSVerify , "if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure" )
2019-09-10 01:55:55 +08:00
fs . BoolVar ( & s . Debug , "debug" , s . Debug , "enable verbose output" )
2019-08-27 01:21:52 +08:00
fs . StringVar ( & s . RegistryConfig , "registry-config" , s . RegistryConfig , "path to the registry config file" )
2019-08-30 08:33:57 +08:00
fs . StringVar ( & s . RepositoryConfig , "repository-config" , s . RepositoryConfig , "path to the file containing repository names and URLs" )
fs . StringVar ( & s . RepositoryCache , "repository-cache" , s . RepositoryCache , "path to the file containing cached repository indexes" )
2022-05-18 02:00:57 +08:00
fs . IntVar ( & s . BurstLimit , "burst-limit" , s . BurstLimit , "client-side default throttling limit" )
2023-08-31 15:46:28 +08:00
fs . Float32Var ( & s . QPS , "qps" , s . QPS , "queries per second used when communicating with the Kubernetes API, not including bursting" )
2017-07-14 07:36:39 +08:00
}
2019-09-10 01:55:55 +08:00
func envOr ( name , def string ) string {
if v , ok := os . LookupEnv ( name ) ; ok {
return v
2017-07-14 07:36:39 +08:00
}
2019-09-10 01:55:55 +08:00
return def
2017-07-14 07:36:39 +08:00
}
2019-08-31 01:38:32 +08:00
2022-05-10 00:29:47 +08:00
func envBoolOr ( name string , def bool ) bool {
if name == "" {
return def
}
envVal := envOr ( name , strconv . FormatBool ( def ) )
ret , err := strconv . ParseBool ( envVal )
if err != nil {
return def
}
return ret
}
2020-06-29 23:51:57 +08:00
func envIntOr ( name string , def int ) int {
if name == "" {
return def
}
envVal := envOr ( name , strconv . Itoa ( def ) )
ret , err := strconv . Atoi ( envVal )
if err != nil {
return def
}
return ret
}
2023-08-31 15:46:28 +08:00
func envFloat32Or ( name string , def float32 ) float32 {
if name == "" {
return def
}
envVal := envOr ( name , strconv . FormatFloat ( float64 ( def ) , 'f' , 2 , 32 ) )
ret , err := strconv . ParseFloat ( envVal , 32 )
if err != nil {
return def
}
return float32 ( ret )
}
2020-09-06 11:01:00 +08:00
func envCSV ( name string ) ( ls [ ] string ) {
trimmed := strings . Trim ( os . Getenv ( name ) , ", " )
if trimmed != "" {
ls = strings . Split ( trimmed , "," )
}
return
}
2019-09-10 01:55:55 +08:00
func ( s * EnvSettings ) EnvVars ( ) map [ string ] string {
2019-10-10 20:32:38 +08:00
envvars := map [ string ] string {
2019-09-10 01:55:55 +08:00
"HELM_BIN" : os . Args [ 0 ] ,
2020-04-24 02:50:31 +08:00
"HELM_CACHE_HOME" : helmpath . CachePath ( "" ) ,
"HELM_CONFIG_HOME" : helmpath . ConfigPath ( "" ) ,
"HELM_DATA_HOME" : helmpath . DataPath ( "" ) ,
2019-09-05 02:15:30 +08:00
"HELM_DEBUG" : fmt . Sprint ( s . Debug ) ,
2019-09-10 01:55:55 +08:00
"HELM_PLUGINS" : s . PluginsDirectory ,
2019-09-05 02:15:30 +08:00
"HELM_REGISTRY_CONFIG" : s . RegistryConfig ,
"HELM_REPOSITORY_CACHE" : s . RepositoryCache ,
2019-09-10 01:55:55 +08:00
"HELM_REPOSITORY_CONFIG" : s . RepositoryConfig ,
2019-10-12 00:21:49 +08:00
"HELM_NAMESPACE" : s . Namespace ( ) ,
2020-06-29 23:51:57 +08:00
"HELM_MAX_HISTORY" : strconv . Itoa ( s . MaxHistory ) ,
2022-05-18 02:00:57 +08:00
"HELM_BURST_LIMIT" : strconv . Itoa ( s . BurstLimit ) ,
2023-08-31 15:46:28 +08:00
"HELM_QPS" : strconv . FormatFloat ( float64 ( s . QPS ) , 'f' , 2 , 32 ) ,
2019-10-10 20:32:38 +08:00
2020-04-24 03:20:14 +08:00
// broken, these are populated from helm flags and not kubeconfig.
2022-05-10 00:29:47 +08:00
"HELM_KUBECONTEXT" : s . KubeContext ,
"HELM_KUBETOKEN" : s . KubeToken ,
"HELM_KUBEASUSER" : s . KubeAsUser ,
"HELM_KUBEASGROUPS" : strings . Join ( s . KubeAsGroups , "," ) ,
"HELM_KUBEAPISERVER" : s . KubeAPIServer ,
"HELM_KUBECAFILE" : s . KubeCaFile ,
"HELM_KUBEINSECURE_SKIP_TLS_VERIFY" : strconv . FormatBool ( s . KubeInsecureSkipTLSVerify ) ,
"HELM_KUBETLS_SERVER_NAME" : s . KubeTLSServerName ,
2020-04-24 03:20:14 +08:00
}
2019-10-15 02:14:14 +08:00
if s . KubeConfig != "" {
envvars [ "KUBECONFIG" ] = s . KubeConfig
2019-10-10 20:32:38 +08:00
}
return envvars
2019-08-31 01:38:32 +08:00
}
2019-10-11 02:35:46 +08:00
2020-04-24 03:20:14 +08:00
// Namespace gets the namespace from the configuration
2019-10-11 02:35:46 +08:00
func ( s * EnvSettings ) Namespace ( ) string {
2020-04-24 03:20:14 +08:00
if ns , _ , err := s . config . ToRawKubeConfigLoader ( ) . Namespace ( ) ; err == nil {
2019-10-11 02:35:46 +08:00
return ns
}
2024-04-24 11:25:50 +08:00
if s . namespace != "" {
return s . namespace
}
2019-10-11 02:35:46 +08:00
return "default"
}
2021-10-08 22:40:04 +08:00
// SetNamespace sets the namespace in the configuration
func ( s * EnvSettings ) SetNamespace ( namespace string ) {
s . namespace = namespace
}
2020-04-24 03:20:14 +08:00
// RESTClientGetter gets the kubeconfig from EnvSettings
2019-10-15 00:46:06 +08:00
func ( s * EnvSettings ) RESTClientGetter ( ) genericclioptions . RESTClientGetter {
2019-10-11 05:46:58 +08:00
return s . config
2019-10-11 02:35:46 +08:00
}