feat: add configuration for client-side throttling limit

Client-side throttling seems to be an issue in larger environments such as OpenShift clusters, where
it is common to have several hundreds CRDs out-of-the-box.

From this view point, it is fair that clients should be able to fine tune this accordingly should the
environment they work on evolves, which is currently not possible, and quite frustrating.

This change introduces the --default-burst-limit option to helm (and its counterpart
HELM_DEFAULT_BURST_LIMIT environment variable) to address that issue, allowing clients to properly
tune their client usage as their environment evolves.

Signed-off-by: Igor Sutton <isuttonl@redhat.com>
pull/10842/head
Igor Sutton 4 years ago
parent cba3b1eed4
commit 44db52ab5b

@ -67,6 +67,7 @@ Environment variables:
| $HELM_KUBEASUSER | set the Username to impersonate for the operation. | | $HELM_KUBEASUSER | set the Username to impersonate for the operation. |
| $HELM_KUBECONTEXT | set the name of the kubeconfig context. | | $HELM_KUBECONTEXT | set the name of the kubeconfig context. |
| $HELM_KUBETOKEN | set the Bearer KubeToken used for authentication. | | $HELM_KUBETOKEN | set the Bearer KubeToken used for authentication. |
| $HELM_DEFAULT_BURST_LIMIT | set the default burst limit in the case the server contains many CRDs |
Helm stores cache, configuration, and data based on the following configuration order: Helm stores cache, configuration, and data based on the following configuration order:

@ -30,6 +30,7 @@ import (
"github.com/spf13/pflag" "github.com/spf13/pflag"
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/rest"
"helm.sh/helm/v3/pkg/helmpath" "helm.sh/helm/v3/pkg/helmpath"
) )
@ -37,6 +38,9 @@ import (
// defaultMaxHistory sets the maximum number of releases to 0: unlimited // defaultMaxHistory sets the maximum number of releases to 0: unlimited
const defaultMaxHistory = 10 const defaultMaxHistory = 10
// defaultBurstLimit sets the default client-side throttling limit
const defaultBurstLimit = 250
// EnvSettings describes all of the environment settings. // EnvSettings describes all of the environment settings.
type EnvSettings struct { type EnvSettings struct {
namespace string namespace string
@ -68,22 +72,25 @@ type EnvSettings struct {
PluginsDirectory string PluginsDirectory string
// MaxHistory is the max release history maintained. // MaxHistory is the max release history maintained.
MaxHistory int MaxHistory int
// DefaultBurstLimit is the default client-side throttling limit.
DefaultBurstLimit int
} }
func New() *EnvSettings { func New() *EnvSettings {
env := &EnvSettings{ env := &EnvSettings{
namespace: os.Getenv("HELM_NAMESPACE"), namespace: os.Getenv("HELM_NAMESPACE"),
MaxHistory: envIntOr("HELM_MAX_HISTORY", defaultMaxHistory), MaxHistory: envIntOr("HELM_MAX_HISTORY", defaultMaxHistory),
KubeContext: os.Getenv("HELM_KUBECONTEXT"), KubeContext: os.Getenv("HELM_KUBECONTEXT"),
KubeToken: os.Getenv("HELM_KUBETOKEN"), KubeToken: os.Getenv("HELM_KUBETOKEN"),
KubeAsUser: os.Getenv("HELM_KUBEASUSER"), KubeAsUser: os.Getenv("HELM_KUBEASUSER"),
KubeAsGroups: envCSV("HELM_KUBEASGROUPS"), KubeAsGroups: envCSV("HELM_KUBEASGROUPS"),
KubeAPIServer: os.Getenv("HELM_KUBEAPISERVER"), KubeAPIServer: os.Getenv("HELM_KUBEAPISERVER"),
KubeCaFile: os.Getenv("HELM_KUBECAFILE"), KubeCaFile: os.Getenv("HELM_KUBECAFILE"),
PluginsDirectory: envOr("HELM_PLUGINS", helmpath.DataPath("plugins")), PluginsDirectory: envOr("HELM_PLUGINS", helmpath.DataPath("plugins")),
RegistryConfig: envOr("HELM_REGISTRY_CONFIG", helmpath.ConfigPath("registry/config.json")), RegistryConfig: envOr("HELM_REGISTRY_CONFIG", helmpath.ConfigPath("registry/config.json")),
RepositoryConfig: envOr("HELM_REPOSITORY_CONFIG", helmpath.ConfigPath("repositories.yaml")), RepositoryConfig: envOr("HELM_REPOSITORY_CONFIG", helmpath.ConfigPath("repositories.yaml")),
RepositoryCache: envOr("HELM_REPOSITORY_CACHE", helmpath.CachePath("repository")), RepositoryCache: envOr("HELM_REPOSITORY_CACHE", helmpath.CachePath("repository")),
DefaultBurstLimit: envIntOr("HELM_DEFAULT_BURST_LIMIT", defaultBurstLimit),
} }
env.Debug, _ = strconv.ParseBool(os.Getenv("HELM_DEBUG")) env.Debug, _ = strconv.ParseBool(os.Getenv("HELM_DEBUG"))
@ -97,6 +104,10 @@ func New() *EnvSettings {
KubeConfig: &env.KubeConfig, KubeConfig: &env.KubeConfig,
Impersonate: &env.KubeAsUser, Impersonate: &env.KubeAsUser,
ImpersonateGroup: &env.KubeAsGroups, ImpersonateGroup: &env.KubeAsGroups,
WrapConfigFn: func(config *rest.Config) *rest.Config {
config.Burst = env.DefaultBurstLimit
return config
},
} }
return env return env
} }
@ -115,6 +126,7 @@ func (s *EnvSettings) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.RegistryConfig, "registry-config", s.RegistryConfig, "path to the registry config file") fs.StringVar(&s.RegistryConfig, "registry-config", s.RegistryConfig, "path to the registry config file")
fs.StringVar(&s.RepositoryConfig, "repository-config", s.RepositoryConfig, "path to the file containing repository names and URLs") 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") fs.StringVar(&s.RepositoryCache, "repository-cache", s.RepositoryCache, "path to the file containing cached repository indexes")
fs.IntVar(&s.DefaultBurstLimit, "default-burst-limit", s.DefaultBurstLimit, "client-side default throttling limit")
} }
func envOr(name, def string) string { func envOr(name, def string) string {
@ -146,17 +158,18 @@ func envCSV(name string) (ls []string) {
func (s *EnvSettings) EnvVars() map[string]string { func (s *EnvSettings) EnvVars() map[string]string {
envvars := map[string]string{ envvars := map[string]string{
"HELM_BIN": os.Args[0], "HELM_BIN": os.Args[0],
"HELM_CACHE_HOME": helmpath.CachePath(""), "HELM_CACHE_HOME": helmpath.CachePath(""),
"HELM_CONFIG_HOME": helmpath.ConfigPath(""), "HELM_CONFIG_HOME": helmpath.ConfigPath(""),
"HELM_DATA_HOME": helmpath.DataPath(""), "HELM_DATA_HOME": helmpath.DataPath(""),
"HELM_DEBUG": fmt.Sprint(s.Debug), "HELM_DEBUG": fmt.Sprint(s.Debug),
"HELM_PLUGINS": s.PluginsDirectory, "HELM_PLUGINS": s.PluginsDirectory,
"HELM_REGISTRY_CONFIG": s.RegistryConfig, "HELM_REGISTRY_CONFIG": s.RegistryConfig,
"HELM_REPOSITORY_CACHE": s.RepositoryCache, "HELM_REPOSITORY_CACHE": s.RepositoryCache,
"HELM_REPOSITORY_CONFIG": s.RepositoryConfig, "HELM_REPOSITORY_CONFIG": s.RepositoryConfig,
"HELM_NAMESPACE": s.Namespace(), "HELM_NAMESPACE": s.Namespace(),
"HELM_MAX_HISTORY": strconv.Itoa(s.MaxHistory), "HELM_MAX_HISTORY": strconv.Itoa(s.MaxHistory),
"HELM_DEFAULT_BURST_LIMIT": strconv.Itoa(s.DefaultBurstLimit),
// broken, these are populated from helm flags and not kubeconfig. // broken, these are populated from helm flags and not kubeconfig.
"HELM_KUBECONTEXT": s.KubeContext, "HELM_KUBECONTEXT": s.KubeContext,

Loading…
Cancel
Save