diff --git a/cmd/apply.go b/cmd/apply.go index aa3cb48d..0431fc8b 100644 --- a/cmd/apply.go +++ b/cmd/apply.go @@ -59,7 +59,6 @@ func NewApplyCmd(globalCfg *config.GlobalImpl) *cobra.Command { f.BoolVar(&applyOptions.ShowSecrets, "show-secrets", false, "do not redact secret values in the diff output. should be used for debug purpose only") f.BoolVar(&applyOptions.NoHooks, "no-hooks", false, "do not diff changes made by hooks.") f.BoolVar(&applyOptions.SuppressDiff, "suppress-diff", false, "suppress diff in the output. Usable in new installs") - f.BoolVar(&applyOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`) f.BoolVar(&applyOptions.Wait, "wait", false, `Override helmDefaults.wait setting "helm upgrade --install --wait"`) f.BoolVar(&applyOptions.WaitForJobs, "wait-for-jobs", false, `Override helmDefaults.waitForJobs setting "helm upgrade --install --wait-for-jobs"`) f.BoolVar(&applyOptions.ReuseValues, "reuse-values", false, `Override helmDefaults.reuseValues "helm upgrade --install --reuse-values"`) diff --git a/cmd/delete.go b/cmd/delete.go index 441337c6..69f9b61d 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -35,7 +35,6 @@ func NewDeleteCmd(globalCfg *config.GlobalImpl) *cobra.Command { f.StringVar(&globalCfg.GlobalOptions.Args, "args", "", "pass args to helm exec") f.IntVar(&deleteOptions.Concurrency, "concurrency", 0, "maximum number of concurrent helm processes to run, 0 is unlimited") f.BoolVar(&deleteOptions.Purge, "purge", false, "purge releases i.e. free release names and histories") - f.BoolVar(&deleteOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`) f.BoolVar(&deleteOptions.SkipCharts, "skip-charts", false, "don't prepare charts when deleting releases") return cmd diff --git a/cmd/destroy.go b/cmd/destroy.go index e53ea072..bf36b03e 100644 --- a/cmd/destroy.go +++ b/cmd/destroy.go @@ -33,7 +33,6 @@ func NewDestroyCmd(globalCfg *config.GlobalImpl) *cobra.Command { f := cmd.Flags() f.StringVar(&globalCfg.GlobalOptions.Args, "args", "", "pass args to helm exec") f.IntVar(&destroyOptions.Concurrency, "concurrency", 0, "maximum number of concurrent helm processes to run, 0 is unlimited") - f.BoolVar(&destroyOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`) f.BoolVar(&destroyOptions.SkipCharts, "skip-charts", false, "don't prepare charts when destroying releases") return cmd diff --git a/cmd/diff.go b/cmd/diff.go index 3269f8cf..00bad84c 100644 --- a/cmd/diff.go +++ b/cmd/diff.go @@ -40,7 +40,6 @@ func NewDiffCmd(globalCfg *config.GlobalImpl) *cobra.Command { f.BoolVar(&diffOptions.IncludeTests, "include-tests", false, "enable the diffing of the helm test hooks") f.BoolVar(&diffOptions.IncludeNeeds, "include-needs", false, `automatically include releases from the target release's "needs" when --selector/-l flag is provided. Does nothing when --selector/-l flag is not provided`) f.BoolVar(&diffOptions.IncludeTransitiveNeeds, "include-transitive-needs", false, `like --include-needs, but also includes transitive needs (needs of needs). Does nothing when --selector/-l flag is not provided. Overrides exclusions of other selectors and conditions.`) - f.BoolVar(&diffOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`) f.BoolVar(&diffOptions.SkipDiffOnInstall, "skip-diff-on-install", false, "Skips running helm-diff on releases being newly installed on this apply. Useful when the release manifests are too huge to be reviewed, or it's too time-consuming to diff at all") f.BoolVar(&diffOptions.ShowSecrets, "show-secrets", false, "do not redact secret values in the output. should be used for debug purpose only") f.BoolVar(&diffOptions.NoHooks, "no-hooks", false, "do not diff changes made by hooks.") diff --git a/cmd/fetch.go b/cmd/fetch.go index 728abca9..d4c5591a 100644 --- a/cmd/fetch.go +++ b/cmd/fetch.go @@ -33,7 +33,6 @@ func NewFetchCmd(globalCfg *config.GlobalImpl) *cobra.Command { f := cmd.Flags() f.IntVar(&fetchOptions.Concurrency, "concurrency", 0, "maximum number of concurrent helm processes to run, 0 is unlimited") - f.BoolVar(&fetchOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`) f.StringVar(&fetchOptions.OutputDir, "output-dir", "", "directory to store charts (default: temporary directory which is deleted when the command terminates)") f.StringVar(&fetchOptions.OutputDirTemplate, "output-dir-template", state.DefaultFetchOutputDirTemplate, "go text template for generating the output directory") diff --git a/cmd/lint.go b/cmd/lint.go index 4b9339bc..636c3e2f 100644 --- a/cmd/lint.go +++ b/cmd/lint.go @@ -32,7 +32,6 @@ func NewLintCmd(globalCfg *config.GlobalImpl) *cobra.Command { f := cmd.Flags() f.IntVar(&lintOptions.Concurrency, "concurrency", 0, "maximum number of concurrent helm processes to run, 0 is unlimited") - f.BoolVar(&lintOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`) f.StringVar(&globalCfg.GlobalOptions.Args, "args", "", "pass args to helm exec") f.StringArrayVar(&lintOptions.Set, "set", nil, "additional values to be merged into the helm command --set flag") f.StringArrayVar(&lintOptions.Values, "values", nil, "additional value files to be merged into the helm command --values flag") diff --git a/cmd/root.go b/cmd/root.go index afdefc77..86d2e7e1 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -119,6 +119,8 @@ func setGlobalOptionsForRootCmd(fs *pflag.FlagSet, globalOptions *config.GlobalO fs.StringVarP(&globalOptions.Environment, "environment", "e", "", `specify the environment name. defaults to "default"`) fs.StringArrayVar(&globalOptions.StateValuesSet, "state-values-set", nil, "set state values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2). Used to override .Values within the helmfile template (not values template).") fs.StringArrayVar(&globalOptions.StateValuesFile, "state-values-file", nil, "specify state values in a YAML file. Used to override .Values within the helmfile template (not values template).") + fs.BoolVar(&globalOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`) + fs.BoolVar(&globalOptions.DisableForceUpdate, "disable-force-update", false, `do not force helm repos to update when executing "helm repo add"`) fs.BoolVarP(&globalOptions.Quiet, "quiet", "q", false, "Silence output. Equivalent to log-level warn") fs.StringVar(&globalOptions.KubeContext, "kube-context", "", "Set kubectl context. Uses current context by default") fs.BoolVar(&globalOptions.Debug, "debug", false, "Enable verbose output for Helm and set log-level to debug, this disables --quiet/-q effect") diff --git a/cmd/sync.go b/cmd/sync.go index 037f58f1..5f0a46f6 100644 --- a/cmd/sync.go +++ b/cmd/sync.go @@ -40,7 +40,6 @@ func NewSyncCmd(globalCfg *config.GlobalImpl) *cobra.Command { f.BoolVar(&syncOptions.SkipCRDs, "skip-crds", false, "if set, no CRDs will be installed on sync. By default, CRDs are installed if not already present") f.BoolVar(&syncOptions.IncludeNeeds, "include-needs", false, `automatically include releases from the target release's "needs" when --selector/-l flag is provided. Does nothing when --selector/-l flag is not provided`) f.BoolVar(&syncOptions.IncludeTransitiveNeeds, "include-transitive-needs", false, `like --include-needs, but also includes transitive needs (needs of needs). Does nothing when --selector/-l flag is not provided. Overrides exclusions of other selectors and conditions.`) - f.BoolVar(&syncOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`) f.BoolVar(&syncOptions.Wait, "wait", false, `Override helmDefaults.wait setting "helm upgrade --install --wait"`) f.BoolVar(&syncOptions.WaitForJobs, "wait-for-jobs", false, `Override helmDefaults.waitForJobs setting "helm upgrade --install --wait-for-jobs"`) f.BoolVar(&syncOptions.ReuseValues, "reuse-values", false, `Override helmDefaults.reuseValues "helm upgrade --install --reuse-values"`) diff --git a/cmd/template.go b/cmd/template.go index f9e5bea4..8cf8d178 100644 --- a/cmd/template.go +++ b/cmd/template.go @@ -43,7 +43,6 @@ func NewTemplateCmd(globalCfg *config.GlobalImpl) *cobra.Command { f.BoolVar(&templateOptions.SkipNeeds, "skip-needs", true, `do not automatically include releases from the target release's "needs" when --selector/-l flag is provided. Does nothing when --selector/-l flag is not provided. Defaults to true when --include-needs or --include-transitive-needs is not provided`) f.BoolVar(&templateOptions.IncludeNeeds, "include-needs", false, `automatically include releases from the target release's "needs" when --selector/-l flag is provided. Does nothing when --selector/-l flag is not provided`) f.BoolVar(&templateOptions.IncludeTransitiveNeeds, "include-transitive-needs", false, `like --include-needs, but also includes transitive needs (needs of needs). Does nothing when --selector/-l flag is not provided. Overrides exclusions of other selectors and conditions.`) - f.BoolVar(&templateOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`) f.BoolVar(&templateOptions.SkipCleanup, "skip-cleanup", false, "Stop cleaning up temporary values generated by helmfile and helm-secrets. Useful for debugging. Don't use in production for security") f.StringVar(&templateOptions.PostRenderer, "post-renderer", "", `pass --post-renderer to "helm template" or "helm upgrade --install"`) diff --git a/cmd/test.go b/cmd/test.go index a3188e23..30f6ef3e 100644 --- a/cmd/test.go +++ b/cmd/test.go @@ -33,7 +33,6 @@ func NewTestCmd(globalCfg *config.GlobalImpl) *cobra.Command { f := cmd.Flags() f.IntVar(&testOptions.Concurrency, "concurrency", 0, "maximum number of concurrent helm processes to run, 0 is unlimited") - f.BoolVar(&testOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`) f.BoolVar(&testOptions.Cleanup, "cleanup", false, "delete test pods upon completion") f.BoolVar(&testOptions.Logs, "logs", false, "Dump the logs from test pods (this runs after all tests are complete, but before any cleanup)") f.StringVar(&globalCfg.GlobalOptions.Args, "args", "", "pass args to helm exec") diff --git a/cmd/write-values.go b/cmd/write-values.go index 974ad882..5861d4c1 100644 --- a/cmd/write-values.go +++ b/cmd/write-values.go @@ -32,7 +32,6 @@ func NewWriteValuesCmd(globalCfg *config.GlobalImpl) *cobra.Command { f := cmd.Flags() f.IntVar(&writeValuesOptions.Concurrency, "concurrency", 0, "maximum number of concurrent helm processes to run, 0 is unlimited") - f.BoolVar(&writeValuesOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`) f.StringArrayVar(&writeValuesOptions.Set, "set", nil, "additional values to be merged into the helm command --set flag") f.StringArrayVar(&writeValuesOptions.Values, "values", nil, "additional value files to be merged into the helm command --values flag") f.StringVar(&writeValuesOptions.OutputFileTemplate, "output-file-template", "", "go text template for generating the output file. Default: {{ .State.BaseName }}-{{ .State.AbsPathSHA1 }}/{{ .Release.Name}}.yaml") diff --git a/docs/index.md b/docs/index.md index 4c87efd3..6193930f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -537,6 +537,7 @@ Flags: -c, --chart string Set chart. Uses the chart set in release by default, and is available in template as {{ .Chart }} --color Output with color --debug Enable verbose output for Helm and set log-level to debug, this disables --quiet/-q effect + --disable-force-update do not force helm repos to update when executing "helm repo add" --enable-live-output Show live output from the Helm binary Stdout/Stderr into Helmfile own Stdout/Stderr. It only applies for the Helm CLI commands, Stdout/Stderr for Hooks are still displayed only when it's execution finishes. -e, --environment string specify the environment name. defaults to "default" @@ -553,6 +554,7 @@ Flags: A release must match all labels in a group in order to be used. Multiple groups can be specified at once. "--selector tier=frontend,tier!=proxy --selector tier=backend" will match all frontend, non-proxy releases AND all backend releases. The name of a release can be used as a label: "--selector name=myrelease" + --skip-deps skip running "helm repo update" and "helm dependency build" --state-values-file stringArray specify state values in a YAML file. Used to override .Values within the helmfile template (not values template). --state-values-set stringArray set state values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2). Used to override .Values within the helmfile template (not values template). -v, --version version for helmfile diff --git a/pkg/app/app.go b/pkg/app/app.go index b7e5a06a..d9557e28 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -29,6 +29,7 @@ type App struct { OverrideKubeContext string OverrideHelmBinary string EnableLiveOutput bool + DisableForceUpdate bool Logger *zap.SugaredLogger Env string @@ -66,6 +67,7 @@ func New(conf ConfigProvider) *App { OverrideKubeContext: conf.KubeContext(), OverrideHelmBinary: conf.HelmBinary(), EnableLiveOutput: conf.EnableLiveOutput(), + DisableForceUpdate: conf.DisableForceUpdate(), Logger: conf.Logger(), Env: conf.Env(), Namespace: conf.Namespace(), @@ -784,7 +786,7 @@ func (a *App) getHelm(st *state.HelmState) helmexec.Interface { key := createHelmKey(bin, kubectx) if _, ok := a.helms[key]; !ok { - a.helms[key] = helmexec.New(bin, a.EnableLiveOutput, a.Logger, kubectx, &helmexec.ShellRunner{ + a.helms[key] = helmexec.New(bin, helmexec.HelmExecOptions{EnableLiveOutput: a.EnableLiveOutput, DisableForceUpdate: a.DisableForceUpdate}, a.Logger, kubectx, &helmexec.ShellRunner{ Logger: a.Logger, }) } diff --git a/pkg/app/app_test.go b/pkg/app/app_test.go index cb376f6c..5c2b2897 100644 --- a/pkg/app/app_test.go +++ b/pkg/app/app_test.go @@ -2396,7 +2396,7 @@ func (mock *mockRunner) Execute(cmd string, args []string, env map[string]string } func MockExecer(logger *zap.SugaredLogger, kubeContext string) helmexec.Interface { - execer := helmexec.New("helm", false, logger, kubeContext, &mockRunner{}) + execer := helmexec.New("helm", helmexec.HelmExecOptions{}, logger, kubeContext, &mockRunner{}) return execer } @@ -2446,6 +2446,9 @@ func (helm *mockHelmExec) SetHelmBinary(bin string) { func (helm *mockHelmExec) SetEnableLiveOutput(enableLiveOutput bool) { } +func (helm *mockHelmExec) SetDisableForceUpdate(forceUpdate bool) { +} + func (helm *mockHelmExec) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error { helm.repos = append(helm.repos, mockRepo{Name: name}) return nil diff --git a/pkg/app/config.go b/pkg/app/config.go index 26cc2151..18cde3e7 100644 --- a/pkg/app/config.go +++ b/pkg/app/config.go @@ -6,6 +6,8 @@ type ConfigProvider interface { Args() string HelmBinary() string EnableLiveOutput() bool + DisableForceUpdate() bool + SkipDeps() bool FileOrDir() string KubeContext() string diff --git a/pkg/app/init.go b/pkg/app/init.go index df653490..fff25113 100644 --- a/pkg/app/init.go +++ b/pkg/app/init.go @@ -163,7 +163,7 @@ func (h *HelmfileInit) WhetherContinue(ask string) error { func (h *HelmfileInit) CheckHelmPlugins() error { settings := cli.New() - helm := helmexec.New(h.helmBinary, false, h.logger, "", h.runner) + helm := helmexec.New(h.helmBinary, helmexec.HelmExecOptions{}, h.logger, "", h.runner) for _, p := range helmPlugins { pluginVersion, err := helmexec.GetPluginVersion(p.name, settings.PluginsDirectory) if err != nil { diff --git a/pkg/app/mocks_test.go b/pkg/app/mocks_test.go index 0c26cd13..685b0b5e 100644 --- a/pkg/app/mocks_test.go +++ b/pkg/app/mocks_test.go @@ -53,6 +53,9 @@ func (helm *noCallHelmExec) SetHelmBinary(bin string) { func (helm *noCallHelmExec) SetEnableLiveOutput(enableLiveOutput bool) { helm.doPanic() } +func (helm *noCallHelmExec) SetDisableForceUpdate(forceUpdate bool) { + helm.doPanic() +} func (helm *noCallHelmExec) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error { helm.doPanic() diff --git a/pkg/config/apply.go b/pkg/config/apply.go index 8670892d..770c1be7 100644 --- a/pkg/config/apply.go +++ b/pkg/config/apply.go @@ -39,14 +39,12 @@ type ApplyOptions struct { Suppress []string // SuppressSecrets is true if the secrets should be suppressed SuppressSecrets bool - // SuppressDiff is true if the diff should be suppressed + // ShowSecrets is true if the secrets should be shown ShowSecrets bool // NoHooks skips checking for hooks NoHooks bool - // SkipDeps is true if the running "helm repo update" and "helm dependency build" should be skipped + // SuppressDiff is true if the diff should be suppressed SuppressDiff bool - // ShowSecrets is true if the secrets should be shown - SkipDeps bool // Wait is true if the helm command should wait for the release to be deployed Wait bool // WaitForJobs is true if the helm command should wait for the jobs to be completed @@ -144,11 +142,6 @@ func (a *ApplyImpl) SkipCleanup() bool { return a.ApplyOptions.SkipCleanup } -// SkipDeps returns the skip deps. -func (a *ApplyImpl) SkipDeps() bool { - return a.ApplyOptions.SkipDeps -} - // SkipDiffOnInstall returns the skip diff on install. func (a *ApplyImpl) SkipDiffOnInstall() bool { return a.ApplyOptions.SkipDiffOnInstall diff --git a/pkg/config/delete.go b/pkg/config/delete.go index 41fe177b..31fd0768 100644 --- a/pkg/config/delete.go +++ b/pkg/config/delete.go @@ -7,8 +7,6 @@ type DeleteOptions struct { Concurrency int // Purge is the purge flag Purge bool - // SkipDeps is the skip deps flag - SkipDeps bool // SkipCharts makes Delete skip `withPreparedCharts` SkipCharts bool } @@ -42,11 +40,6 @@ func (c *DeleteImpl) Purge() bool { return c.DeleteOptions.Purge } -// SkipDeps returns the skip deps -func (c *DeleteImpl) SkipDeps() bool { - return c.DeleteOptions.SkipDeps -} - // SkipCharts returns skipCharts flag func (c *DeleteImpl) SkipCharts() bool { return c.DeleteOptions.SkipCharts diff --git a/pkg/config/destroy.go b/pkg/config/destroy.go index 71e9f3b4..0d3b36b7 100644 --- a/pkg/config/destroy.go +++ b/pkg/config/destroy.go @@ -4,8 +4,6 @@ package config type DestroyOptions struct { // Concurrency is the maximum number of concurrent helm processes to run, 0 is unlimited Concurrency int - // SkipDeps is the skip deps flag - SkipDeps bool // SkipCharts makes Destroy skip `withPreparedCharts` SkipCharts bool } @@ -34,11 +32,6 @@ func (c *DestroyImpl) Concurrency() int { return c.DestroyOptions.Concurrency } -// SkipDeps returns the skip deps -func (c *DestroyImpl) SkipDeps() bool { - return c.DestroyOptions.SkipDeps -} - // SkipCharts returns skipCharts flag func (c *DestroyImpl) SkipCharts() bool { return c.DestroyOptions.SkipCharts diff --git a/pkg/config/diff.go b/pkg/config/diff.go index 625c581b..f488d5a1 100644 --- a/pkg/config/diff.go +++ b/pkg/config/diff.go @@ -6,8 +6,6 @@ type DiffOptions struct { Set []string // Values is the values flag Values []string - // SkipDeps is the skip deps flag - SkipDeps bool // DetailedExitcode is the detailed exit code DetailedExitcode bool // IncludeTests is the include tests flag @@ -83,11 +81,6 @@ func (t *DiffImpl) Set() []string { return t.DiffOptions.Set } -// SkipDeps returns the skip deps -func (t *DiffImpl) SkipDeps() bool { - return t.DiffOptions.SkipDeps -} - // SkipNeeds returns the skip needs func (t *DiffImpl) SkipNeeds() bool { if !t.IncludeNeeds() { diff --git a/pkg/config/fetch.go b/pkg/config/fetch.go index b2b6038c..462ecdf4 100644 --- a/pkg/config/fetch.go +++ b/pkg/config/fetch.go @@ -4,8 +4,6 @@ package config type FetchOptions struct { // Concurrency is the maximum number of concurrent helm processes to run, 0 is unlimited Concurrency int - // SkipDeps is the skip deps flag - SkipDeps bool // OutputDir is the output directory OutputDir string // OutputDirTemplate is the go template to generate the path of output directory @@ -36,11 +34,6 @@ func (c *FetchImpl) Concurrency() int { return c.FetchOptions.Concurrency } -// SkipDeps returns the skip deps -func (c *FetchImpl) SkipDeps() bool { - return c.FetchOptions.SkipDeps -} - // OutputDir returns the args func (c *FetchImpl) OutputDir() string { return c.FetchOptions.OutputDir diff --git a/pkg/config/global.go b/pkg/config/global.go index 94a897dd..ebca3c03 100644 --- a/pkg/config/global.go +++ b/pkg/config/global.go @@ -23,6 +23,10 @@ type GlobalOptions struct { StateValuesSet []string // StateValuesFiles is a list of state values files to use. StateValuesFile []string + // SkipDeps is true if the running "helm repo update" and "helm dependency build" should be skipped + SkipDeps bool + // DisableForceUpdate is true if force updating repos is not desirable when executing "helm repo add" + DisableForceUpdate bool // Quiet is true if the output should be quiet. Quiet bool // KubeContext is the name of the kubectl context to use. @@ -132,6 +136,16 @@ func (g *GlobalImpl) EnableLiveOutput() bool { return g.GlobalOptions.EnableLiveOutput } +// SkipDeps return if running "helm repo update" and "helm dependency build" should be skipped +func (g *GlobalImpl) SkipDeps() bool { + return g.GlobalOptions.SkipDeps +} + +// DisableForceUpdate return when to disable forcing updates to repos upon adding +func (g *GlobalImpl) DisableForceUpdate() bool { + return g.GlobalOptions.DisableForceUpdate +} + // Logger returns the logger func (g *GlobalImpl) Logger() *zap.SugaredLogger { return g.GlobalOptions.logger diff --git a/pkg/config/lint.go b/pkg/config/lint.go index 7123ded4..46cf02f8 100644 --- a/pkg/config/lint.go +++ b/pkg/config/lint.go @@ -4,8 +4,6 @@ package config type LintOptions struct { // Concurrency is the maximum number of concurrent helm processes to run, 0 is unlimited Concurrency int - // SkipDeps is the skip deps flag - SkipDeps bool // Set is the set flags to pass to helm lint Set []string // Values is the values flags to pass to helm lint @@ -43,11 +41,6 @@ func (l *LintImpl) Concurrency() int { return l.LintOptions.Concurrency } -// SkipDeps returns the skip deps -func (l *LintImpl) SkipDeps() bool { - return l.LintOptions.SkipDeps -} - // Set returns the Set func (l *LintImpl) Set() []string { return l.LintOptions.Set diff --git a/pkg/config/sync.go b/pkg/config/sync.go index 486a8df7..d4073f58 100644 --- a/pkg/config/sync.go +++ b/pkg/config/sync.go @@ -16,8 +16,6 @@ type SyncOptions struct { IncludeNeeds bool // IncludeTransitiveNeeds is the include transitive needs flag IncludeTransitiveNeeds bool - // SkipDeps is the skip deps flag - SkipDeps bool // SkipCrds is the skip crds flag SkipCRDs bool // Wait is the wait flag @@ -71,11 +69,6 @@ func (t *SyncImpl) Set() []string { return t.SyncOptions.Set } -// SkipDeps returns the skip deps -func (t *SyncImpl) SkipDeps() bool { - return t.SyncOptions.SkipDeps -} - // SkipNeeds returns the skip needs func (t *SyncImpl) SkipNeeds() bool { if !t.IncludeNeeds() { diff --git a/pkg/config/template.go b/pkg/config/template.go index 9509e7ad..95fbe855 100644 --- a/pkg/config/template.go +++ b/pkg/config/template.go @@ -30,8 +30,6 @@ type TemplateOptions struct { IncludeNeeds bool // IncludeTransitiveNeeds is the include transitive needs flag IncludeTransitiveNeeds bool - // SkipDeps is the skip deps flag - SkipDeps bool // SkipCleanup is the skip cleanup flag SkipCleanup bool // Propagate '--post-renderer' to helmv3 template and helm install @@ -97,11 +95,6 @@ func (t *TemplateImpl) SkipCleanup() bool { return t.TemplateOptions.SkipCleanup } -// SkipDeps returns the skip deps -func (t *TemplateImpl) SkipDeps() bool { - return t.TemplateOptions.SkipDeps -} - // SkipNeeds returns the skip needs func (t *TemplateImpl) SkipNeeds() bool { if !t.IncludeNeeds() { diff --git a/pkg/config/test.go b/pkg/config/test.go index e2e205cd..74a9a97a 100644 --- a/pkg/config/test.go +++ b/pkg/config/test.go @@ -10,8 +10,6 @@ import ( type TestOptions struct { // Concurrency is the maximum number of concurrent helm processes to run, 0 is unlimited Concurrency int - // SkipDeps is the skip deps flag - SkipDeps bool // Cleanup is the cleanup flag Cleanup bool // Logs is the logs flagj @@ -45,11 +43,6 @@ func (t *TestImpl) Concurrency() int { return t.TestOptions.Concurrency } -// SkipDeps returns the skip deps -func (t *TestImpl) SkipDeps() bool { - return t.TestOptions.SkipDeps -} - // Cleanup returns the cleanup func (t *TestImpl) Cleanup() bool { return t.TestOptions.Cleanup diff --git a/pkg/config/write-values.go b/pkg/config/write-values.go index 92e2b691..5e5c2ffe 100644 --- a/pkg/config/write-values.go +++ b/pkg/config/write-values.go @@ -4,8 +4,6 @@ package config type WriteValuesOptions struct { // Concurrency is the maximum number of concurrent helm processes to run, 0 is unlimited Concurrency int - // SkipDeps is the skip deps flag - SkipDeps bool // Set is the set flags to pass to helm write values Set []string // Values is the values flags to pass to helm write values @@ -38,11 +36,6 @@ func (c *WriteValuesImpl) Concurrency() int { return c.WriteValuesOptions.Concurrency } -// SkipDeps returns the skip deps -func (c *WriteValuesImpl) SkipDeps() bool { - return c.WriteValuesOptions.SkipDeps -} - // Set returns the Set func (c *WriteValuesImpl) Set() []string { return c.WriteValuesOptions.Set diff --git a/pkg/exectest/helm.go b/pkg/exectest/helm.go index 54c8a8a5..e8a4801c 100644 --- a/pkg/exectest/helm.go +++ b/pkg/exectest/helm.go @@ -92,6 +92,8 @@ func (helm *Helm) SetHelmBinary(bin string) { } func (helm *Helm) SetEnableLiveOutput(enableLiveOutput bool) { } +func (helm *Helm) SetDisableForceUpdate(forceUpdate bool) { +} func (helm *Helm) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error { helm.Repo = []string{name, repository, cafile, certfile, keyfile, username, password, managed, passCredentials, skipTLSVerify} return nil diff --git a/pkg/helmexec/exec.go b/pkg/helmexec/exec.go index 77b3d96a..119d69a7 100644 --- a/pkg/helmexec/exec.go +++ b/pkg/helmexec/exec.go @@ -28,9 +28,14 @@ type decryptedSecret struct { err error } +type HelmExecOptions struct { + EnableLiveOutput bool + DisableForceUpdate bool +} + type execer struct { helmBinary string - enableLiveOutput bool + options HelmExecOptions version *semver.Version runner Runner logger *zap.SugaredLogger @@ -110,7 +115,7 @@ func redactedURL(chart string) string { } // New for running helm commands -func New(helmBinary string, enableLiveOutput bool, logger *zap.SugaredLogger, kubeContext string, runner Runner) *execer { +func New(helmBinary string, options HelmExecOptions, logger *zap.SugaredLogger, kubeContext string, runner Runner) *execer { // TODO: proper error handling version, err := GetHelmVersion(helmBinary, runner) if err != nil { @@ -118,7 +123,7 @@ func New(helmBinary string, enableLiveOutput bool, logger *zap.SugaredLogger, ku } return &execer{ helmBinary: helmBinary, - enableLiveOutput: enableLiveOutput, + options: options, version: version, logger: logger, kubeContext: kubeContext, @@ -136,7 +141,11 @@ func (helm *execer) SetHelmBinary(bin string) { } func (helm *execer) SetEnableLiveOutput(enableLiveOutput bool) { - helm.enableLiveOutput = enableLiveOutput + helm.options.EnableLiveOutput = enableLiveOutput +} + +func (helm *execer) SetDisableForceUpdate(forceUpdate bool) { + helm.options.DisableForceUpdate = forceUpdate } func (helm *execer) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error { @@ -156,7 +165,7 @@ func (helm *execer) AddRepo(name, repository, cafile, certfile, keyfile, usernam // See https://github.com/helm/helm/pull/8777 if cons, err := semver.NewConstraint(">= 3.3.2"); err == nil { - if cons.Check(helm.version) { + if !helm.options.DisableForceUpdate && cons.Check(helm.version) { args = append(args, "--force-update") } } else { @@ -525,7 +534,7 @@ func (helm *execer) exec(args []string, env map[string]string, overrideEnableLiv } cmd := fmt.Sprintf("exec: %s %s", helm.helmBinary, strings.Join(cmdargs, " ")) helm.logger.Debug(cmd) - enableLiveOutput := helm.enableLiveOutput + enableLiveOutput := helm.options.EnableLiveOutput if overrideEnableLiveOutput != nil { enableLiveOutput = *overrideEnableLiveOutput } diff --git a/pkg/helmexec/exec_test.go b/pkg/helmexec/exec_test.go index 050038bd..04a55b07 100644 --- a/pkg/helmexec/exec_test.go +++ b/pkg/helmexec/exec_test.go @@ -36,7 +36,7 @@ func (mock *mockRunner) Execute(cmd string, args []string, env map[string]string } func MockExecer(logger *zap.SugaredLogger, kubeContext string) *execer { - execer := New("helm", false, logger, kubeContext, &mockRunner{}) + execer := New("helm", HelmExecOptions{}, logger, kubeContext, &mockRunner{}) return execer } @@ -85,12 +85,23 @@ func Test_SetHelmBinary(t *testing.T) { func Test_SetEnableLiveOutput(t *testing.T) { helm := MockExecer(NewLogger(os.Stdout, "info"), "dev") - if helm.enableLiveOutput { - t.Error("helmexec.enableLiveOutput should not be enabled by default") + if helm.options.EnableLiveOutput { + t.Error("helmexec.options.EnableLiveOutput should not be enabled by default") } helm.SetEnableLiveOutput(true) - if !helm.enableLiveOutput { - t.Errorf("helmexec.SetEnableLiveOutput() - actual = %t expect = true", helm.enableLiveOutput) + if !helm.options.EnableLiveOutput { + t.Errorf("helmexec.SetEnableLiveOutput() - actual = %t expect = true", helm.options.EnableLiveOutput) + } +} + +func Test_SetDisableForceUpdate(t *testing.T) { + helm := MockExecer(NewLogger(os.Stdout, "info"), "dev") + if helm.options.DisableForceUpdate { + t.Error("helmexec.options.ForceUpdate should not be enabled by default") + } + helm.SetDisableForceUpdate(true) + if !helm.options.DisableForceUpdate { + t.Errorf("helmexec.SetDisableForceUpdate() - actual = %t expect = true", helm.options.DisableForceUpdate) } } @@ -117,6 +128,30 @@ exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --force- } } +func Test_AddRepo_Helm_3_3_2_NoForceUpdate(t *testing.T) { + var buffer bytes.Buffer + logger := NewLogger(&buffer, "debug") + helm := &execer{ + helmBinary: "helm", + options: HelmExecOptions{DisableForceUpdate: true}, + version: semver.MustParse("3.3.2"), + logger: logger, + kubeContext: "dev", + runner: &mockRunner{}, + } + err := helm.AddRepo("myRepo", "https://repo.example.com/", "", "cert.pem", "key.pem", "", "", "", "", "") + expected := `Adding repo myRepo https://repo.example.com/ +exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --cert-file cert.pem --key-file key.pem +` + if err != nil { + t.Errorf("unexpected error: %v", err) + } + + if buffer.String() != expected { + t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected) + } +} + func Test_AddRepo(t *testing.T) { var buffer bytes.Buffer logger := NewLogger(&buffer, "debug") @@ -322,7 +357,7 @@ func Test_BuildDeps(t *testing.T) { var buffer bytes.Buffer logger := NewLogger(&buffer, "debug") helm3Runner := mockRunner{output: []byte("v3.2.4+ge29ce2a")} - helm := New("helm", false, logger, "dev", &helm3Runner) + helm := New("helm", HelmExecOptions{}, logger, "dev", &helm3Runner) err := helm.BuildDeps("foo", "./chart/foo", []string{"--skip-refresh"}...) expected := `Building dependency release=foo, chart=./chart/foo exec: helm --kube-context dev dependency build ./chart/foo --skip-refresh @@ -364,7 +399,7 @@ v3.2.4+ge29ce2a buffer.Reset() helm2Runner := mockRunner{output: []byte("Client: v2.16.1+ge13bc94")} - helm = New("helm", false, logger, "dev", &helm2Runner) + helm = New("helm", HelmExecOptions{}, logger, "dev", &helm2Runner) err = helm.BuildDeps("foo", "./chart/foo") expected = `Building dependency release=foo, chart=./chart/foo exec: helm --kube-context dev dependency build ./chart/foo @@ -870,13 +905,13 @@ exec: helm --kube-context dev template release https://example_user:example_pass func Test_IsHelm3(t *testing.T) { helm2Runner := mockRunner{output: []byte("Client: v2.16.0+ge13bc94\n")} - helm := New("helm", false, NewLogger(os.Stdout, "info"), "dev", &helm2Runner) + helm := New("helm", HelmExecOptions{}, NewLogger(os.Stdout, "info"), "dev", &helm2Runner) if helm.IsHelm3() { t.Error("helmexec.IsHelm3() - Detected Helm 3 with Helm 2 version") } helm3Runner := mockRunner{output: []byte("v3.0.0+ge29ce2a\n")} - helm = New("helm", false, NewLogger(os.Stdout, "info"), "dev", &helm3Runner) + helm = New("helm", HelmExecOptions{}, NewLogger(os.Stdout, "info"), "dev", &helm3Runner) if !helm.IsHelm3() { t.Error("helmexec.IsHelm3() - Failed to detect Helm 3") } @@ -907,14 +942,14 @@ func Test_GetPluginVersion(t *testing.T) { func Test_GetVersion(t *testing.T) { helm2Runner := mockRunner{output: []byte("Client: v2.16.1+ge13bc94\n")} - helm := New("helm", false, NewLogger(os.Stdout, "info"), "dev", &helm2Runner) + helm := New("helm", HelmExecOptions{}, NewLogger(os.Stdout, "info"), "dev", &helm2Runner) ver := helm.GetVersion() if ver.Major != 2 || ver.Minor != 16 || ver.Patch != 1 { t.Errorf("helmexec.GetVersion - did not detect correct Helm2 version; it was: %+v", ver) } helm3Runner := mockRunner{output: []byte("v3.2.4+ge29ce2a\n")} - helm = New("helm", false, NewLogger(os.Stdout, "info"), "dev", &helm3Runner) + helm = New("helm", HelmExecOptions{}, NewLogger(os.Stdout, "info"), "dev", &helm3Runner) ver = helm.GetVersion() if ver.Major != 3 || ver.Minor != 2 || ver.Patch != 4 { t.Errorf("helmexec.GetVersion - did not detect correct Helm3 version; it was: %+v", ver) @@ -923,7 +958,7 @@ func Test_GetVersion(t *testing.T) { func Test_IsVersionAtLeast(t *testing.T) { helm2Runner := mockRunner{output: []byte("Client: v2.16.1+ge13bc94\n")} - helm := New("helm", false, NewLogger(os.Stdout, "info"), "dev", &helm2Runner) + helm := New("helm", HelmExecOptions{}, NewLogger(os.Stdout, "info"), "dev", &helm2Runner) if !helm.IsVersionAtLeast("2.1.0") { t.Error("helmexec.IsVersionAtLeast - 2.16.1 not atleast 2.1") } diff --git a/pkg/helmexec/helmexec.go b/pkg/helmexec/helmexec.go index 84938317..0f8b807f 100644 --- a/pkg/helmexec/helmexec.go +++ b/pkg/helmexec/helmexec.go @@ -14,6 +14,7 @@ type Interface interface { SetExtraArgs(args ...string) SetHelmBinary(bin string) SetEnableLiveOutput(enableLiveOutput bool) + SetDisableForceUpdate(forceUpdate bool) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error UpdateRepo() error