diff --git a/cmd/apply.go b/cmd/apply.go index f1c6536f..d6873076 100644 --- a/cmd/apply.go +++ b/cmd/apply.go @@ -63,6 +63,7 @@ func NewApplyCmd(globalCfg *config.GlobalImpl) *cobra.Command { 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"`) + f.BoolVar(&applyOptions.ResetValues, "reset-values", false, `Override helmDefaults.reuseValues "helm upgrade --install --reset-values"`) f.StringVar(&applyOptions.PostRenderer, "post-renderer", "", `pass --post-renderer to "helm template" or "helm upgrade --install"`) return cmd diff --git a/cmd/diff.go b/cmd/diff.go index 4796baea..44d6ba9e 100644 --- a/cmd/diff.go +++ b/cmd/diff.go @@ -50,6 +50,7 @@ func NewDiffCmd(globalCfg *config.GlobalImpl) *cobra.Command { f.BoolVar(&diffOptions.SuppressSecrets, "suppress-secrets", false, "suppress secrets in the output. highly recommended to specify on CI/CD use-cases") f.StringArrayVar(&diffOptions.Suppress, "suppress", nil, "suppress specified Kubernetes objects in the output. Can be provided multiple times. For example: --suppress KeycloakClient --suppress VaultSecret") f.BoolVar(&diffOptions.ReuseValues, "reuse-values", false, `Override helmDefaults.reuseValues "helm diff upgrade --install --reuse-values"`) + f.BoolVar(&diffOptions.ResetValues, "reset-values", false, `Override helmDefaults.reuseValues "helm diff upgrade --install --reset-values"`) return cmd } diff --git a/cmd/sync.go b/cmd/sync.go index f21bfb03..fecb941d 100644 --- a/cmd/sync.go +++ b/cmd/sync.go @@ -44,6 +44,7 @@ func NewSyncCmd(globalCfg *config.GlobalImpl) *cobra.Command { 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"`) + f.BoolVar(&syncOptions.ResetValues, "reset-values", false, `Override helmDefaults.reuseValues "helm upgrade --install --reset-values"`) f.StringVar(&syncOptions.PostRenderer, "post-renderer", "", `pass --post-renderer to "helm template" or "helm upgrade --install"`) return cmd diff --git a/docs/index.md b/docs/index.md index 66d43812..a7b9c74b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -212,7 +212,8 @@ helmDefaults: # When set to `true`, skips running `helm dep up` and `helm dep build` on this release's chart. # Useful when the chart is broken, like seen in https://github.com/roboll/helmfile/issues/1547 skipDeps: false - # if set to true, reuses the last release's values and merges them with ones provided in helmfile. + # If set to true, reuses the last release's values and merges them with ones provided in helmfile. + # This attribute, can be overriden in CLI with --reset/reuse-values flag of apply/sync/diff subcommands reuseValues: false # propagate `--post-renderer` to helmv3 template and helm install postRenderer: "path/to/postRenderer" diff --git a/pkg/app/app.go b/pkg/app/app.go index 14bebff1..b6942e96 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -1317,6 +1317,7 @@ func (a *App) apply(r *Run, c ApplyConfigProvider) (bool, bool, []error) { SkipCleanup: c.RetainValuesFiles() || c.SkipCleanup(), SkipDiffOnInstall: c.SkipDiffOnInstall(), ReuseValues: c.ReuseValues(), + ResetValues: c.ResetValues(), } infoMsg, releasesToBeUpdated, releasesToBeDeleted, errs := r.diff(false, detailedExitCode, c, diffOpts) @@ -1428,6 +1429,7 @@ Do you really want to apply? Wait: c.Wait(), WaitForJobs: c.WaitForJobs(), ReuseValues: c.ReuseValues(), + ResetValues: c.ResetValues(), } return subst.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), syncOpts) })) @@ -1549,6 +1551,7 @@ func (a *App) diff(r *Run, c DiffConfigProvider) (*string, bool, bool, []error) Set: c.Set(), SkipDiffOnInstall: c.SkipDiffOnInstall(), ReuseValues: c.ReuseValues(), + ResetValues: c.ResetValues(), } filtered := &Run{ @@ -1814,6 +1817,7 @@ Do you really want to sync? Wait: c.Wait(), WaitForJobs: c.WaitForJobs(), ReuseValues: c.ReuseValues(), + ResetValues: c.ResetValues(), } return subst.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), opts) })) diff --git a/pkg/app/app_test.go b/pkg/app/app_test.go index 36d1857c..bf7ffb8b 100644 --- a/pkg/app/app_test.go +++ b/pkg/app/app_test.go @@ -2353,6 +2353,10 @@ func (a applyConfig) ReuseValues() bool { return a.reuseValues } +func (a applyConfig) ResetValues() bool { + return !a.reuseValues +} + func (a applyConfig) PostRenderer() string { return a.postRenderer } diff --git a/pkg/app/config.go b/pkg/app/config.go index 9379d4e8..0204829d 100644 --- a/pkg/app/config.go +++ b/pkg/app/config.go @@ -259,7 +259,8 @@ type InitConfigProvider interface { Force() bool } -// when enable reuse-values, reuse the last release's values and merge in any overrides values. +// reset/reuse values helm cli flags handling for apply/sync/diff type valuesControlMode interface { ReuseValues() bool + ResetValues() bool } diff --git a/pkg/app/diff_test.go b/pkg/app/diff_test.go index 41ce7503..a9654a83 100644 --- a/pkg/app/diff_test.go +++ b/pkg/app/diff_test.go @@ -146,6 +146,10 @@ func (a diffConfig) ReuseValues() bool { return a.reuseValues } +func (a diffConfig) ResetValues() bool { + return !a.reuseValues +} + func TestDiff(t *testing.T) { type flags struct { skipNeeds bool diff --git a/pkg/config/apply.go b/pkg/config/apply.go index 4ab0296d..8670892d 100644 --- a/pkg/config/apply.go +++ b/pkg/config/apply.go @@ -53,6 +53,8 @@ type ApplyOptions struct { WaitForJobs bool // ReuseValues is true if the helm command should reuse the values ReuseValues bool + // ResetValues is true if helm command should reset values to charts' default + ResetValues bool // Propagate '--post-renderer' to helmv3 template and helm install PostRenderer string } @@ -197,7 +199,14 @@ func (a *ApplyImpl) WaitForJobs() bool { // ReuseValues returns the ReuseValues. func (a *ApplyImpl) ReuseValues() bool { - return a.ApplyOptions.ReuseValues + if !a.ResetValues() { + return a.ApplyOptions.ReuseValues + } + return false +} + +func (a *ApplyImpl) ResetValues() bool { + return a.ApplyOptions.ResetValues } // PostRenderer returns the PostRenderer. diff --git a/pkg/config/diff.go b/pkg/config/diff.go index 24cc77f5..d9eeee85 100644 --- a/pkg/config/diff.go +++ b/pkg/config/diff.go @@ -38,6 +38,8 @@ type DiffOptions struct { Output string // ReuseValues is true if the helm command should reuse the values ReuseValues bool + // ResetValues is true if helm command should reset values to charts' default + ResetValues bool } // NewDiffOptions creates a new Apply @@ -160,5 +162,12 @@ func (t *DiffImpl) SuppressSecrets() bool { // ReuseValues returns the ReuseValues. func (t *DiffImpl) ReuseValues() bool { - return t.DiffOptions.ReuseValues + if !t.ResetValues() { + return t.DiffOptions.ReuseValues + } + return false +} + +func (t *DiffImpl) ResetValues() bool { + return t.DiffOptions.ResetValues } diff --git a/pkg/config/sync.go b/pkg/config/sync.go index 1fb285ec..486a8df7 100644 --- a/pkg/config/sync.go +++ b/pkg/config/sync.go @@ -26,6 +26,8 @@ type SyncOptions struct { WaitForJobs bool // ReuseValues is true if the helm command should reuse the values ReuseValues bool + // ResetValues is true if helm command should reset values to charts' default + ResetValues bool // Propagate '--post-renderer' to helmv3 template and helm install PostRenderer string } @@ -110,7 +112,13 @@ func (t *SyncImpl) WaitForJobs() bool { // ReuseValues returns the ReuseValues. func (t *SyncImpl) ReuseValues() bool { - return t.SyncOptions.ReuseValues + if !t.ResetValues() { + return t.SyncOptions.ReuseValues + } + return false +} +func (t *SyncImpl) ResetValues() bool { + return t.SyncOptions.ResetValues } // PostRenderer returns the PostRenderer. diff --git a/pkg/state/state.go b/pkg/state/state.go index d39ad534..edee8ba8 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -613,11 +613,7 @@ func (st *HelmState) prepareSyncReleases(helm helmexec.Interface, additionalValu flags = append(flags, "--wait-for-jobs") } - if opts.ReuseValues || st.HelmDefaults.ReuseValues { - flags = append(flags, "--reuse-values") - } else { - flags = append(flags, "--reset-values") - } + flags = st.appendValuesControlModeFlag(flags, opts.ReuseValues, opts.ResetValues) if len(errs) > 0 { results <- syncPrepareResult{errors: errs, files: files} @@ -696,6 +692,7 @@ type SyncOpts struct { Wait bool WaitForJobs bool ReuseValues bool + ResetValues bool } type SyncOpt interface{ Apply(*SyncOpts) } @@ -1677,11 +1674,7 @@ func (st *HelmState) commonDiffFlags(detailedExitCode bool, includeTests bool, s flags = append(flags, "--output", opt.Output) } - if opt.ReuseValues || st.HelmDefaults.ReuseValues { - flags = append(flags, "--reuse-values") - } else { - flags = append(flags, "--reset-values") - } + flags = st.appendValuesControlModeFlag(flags, opt.ReuseValues, opt.ResetValues) if opt.Set != nil { for _, s := range opt.Set { @@ -1858,6 +1851,7 @@ type DiffOpts struct { SkipCleanup bool SkipDiffOnInstall bool ReuseValues bool + ResetValues bool } func (o *DiffOpts) Apply(opts *DiffOpts) { @@ -2563,6 +2557,16 @@ func (st *HelmState) chartVersionFlags(release *ReleaseSpec) []string { return flags } +func (st *HelmState) appendValuesControlModeFlag(flags []string, reuseValues bool, resetValues bool) []string { + if !resetValues && (st.HelmDefaults.ReuseValues || reuseValues) { + flags = append(flags, "--reuse-values") + } else { + flags = append(flags, "--reset-values") + } + + return flags +} + func (st *HelmState) appendApiVersionsFlags(flags []string, r *ReleaseSpec) []string { if len(r.ApiVersions) != 0 { for _, a := range r.ApiVersions { diff --git a/pkg/state/state_test.go b/pkg/state/state_test.go index 418cf1bf..d9c65d28 100644 --- a/pkg/state/state_test.go +++ b/pkg/state/state_test.go @@ -2604,6 +2604,36 @@ func TestDiffpareSyncReleases(t *testing.T) { ReuseValues: true, }, }, + { + name: "force-reset-values", + flags: []string{"--reset-values"}, + diffOptions: &DiffOpts{ + ResetValues: true, + }, + helmDefaults: &HelmSpec{ + ReuseValues: true, + }, + }, + { + name: "both-reset-reuse-values", + flags: []string{"--reset-values"}, + diffOptions: &DiffOpts{ + ReuseValues: true, + ResetValues: true, + }, + helmDefaults: &HelmSpec{}, + }, + { + name: "both-reset-reuse-default-reuse-values", + flags: []string{"--reset-values"}, + diffOptions: &DiffOpts{ + ReuseValues: true, + ResetValues: true, + }, + helmDefaults: &HelmSpec{ + ReuseValues: true, + }, + }, } for _, tt := range tests { @@ -2665,6 +2695,36 @@ func TestPrepareSyncReleases(t *testing.T) { ReuseValues: true, }, }, + { + name: "force-reset-values", + flags: []string{"--reset-values"}, + syncOptions: &SyncOpts{ + ResetValues: true, + }, + helmDefaults: &HelmSpec{ + ReuseValues: true, + }, + }, + { + name: "both-reset-reuse-values", + flags: []string{"--reset-values"}, + syncOptions: &SyncOpts{ + ReuseValues: true, + ResetValues: true, + }, + helmDefaults: &HelmSpec{}, + }, + { + name: "both-reset-reuse-default-reuse-values", + flags: []string{"--reset-values"}, + syncOptions: &SyncOpts{ + ReuseValues: true, + ResetValues: true, + }, + helmDefaults: &HelmSpec{ + ReuseValues: true, + }, + }, } for _, tt := range tests {