From 58ef31905dbbcfe4c460847f63e95224a94365c6 Mon Sep 17 00:00:00 2001 From: trk Date: Tue, 25 Jun 2024 01:34:01 +0600 Subject: [PATCH 1/6] Allow fetching only user-supplied existing values --- cmd/helm3.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cmd/helm3.go b/cmd/helm3.go index 8eccf723..0206856c 100644 --- a/cmd/helm3.go +++ b/cmd/helm3.go @@ -308,8 +308,12 @@ func (d *diffCmd) template(isUpgrade bool) ([]byte, error) { return filter(out), err } -func (d *diffCmd) writeExistingValues(f *os.File) error { - cmd := exec.Command(os.Getenv("HELM_BIN"), "get", "values", d.release, "--all", "--output", "yaml") +func (d *diffCmd) writeExistingValues(f *os.File, all bool) error { + args := []string{"get", "values", d.release, "--output", "yaml"} + if all { + args = append(args, "--all") + } + cmd := exec.Command(os.Getenv("HELM_BIN"), args...) debugPrint("Executing %s", strings.Join(cmd.Args, " ")) defer func() { _ = f.Close() From f476e57f70ba55df618ce921db5de1c523f7ffc5 Mon Sep 17 00:00:00 2001 From: trk Date: Tue, 25 Jun 2024 01:27:44 +0600 Subject: [PATCH 2/6] Add support for the --reset-then-reuse-values flag This flag was added in Helm v3.14.0; for details see https://github.com/helm/helm/pull/9653. --- cmd/helm3.go | 20 +++++++++++++++++--- cmd/upgrade.go | 2 ++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/cmd/helm3.go b/cmd/helm3.go index 0206856c..88b58036 100644 --- a/cmd/helm3.go +++ b/cmd/helm3.go @@ -17,7 +17,8 @@ var ( helmVersionRE = regexp.MustCompile(`Version:\s*"([^"]+)"`) minHelmVersion = semver.MustParse("v3.1.0-rc.1") // See https://github.com/helm/helm/pull/9426 - minHelmVersionWithDryRunLookupSupport = semver.MustParse("v3.13.0") + minHelmVersionWithDryRunLookupSupport = semver.MustParse("v3.13.0") + minHelmVersionWithResetThenReuseValues = semver.MustParse("v3.14.0") ) func getHelmVersion() (*semver.Version, error) { @@ -132,15 +133,28 @@ func (d *diffCmd) template(isUpgrade bool) ([]byte, error) { // Let's simulate that in helm-diff. // See https://medium.com/@kcatstack/understand-helm-upgrade-flags-reset-values-reuse-values-6e58ac8f127e shouldDefaultReusingValues := isUpgrade && len(d.values) == 0 && len(d.stringValues) == 0 && len(d.stringLiteralValues) == 0 && len(d.jsonValues) == 0 && len(d.valueFiles) == 0 && len(d.fileValues) == 0 - if (d.reuseValues || shouldDefaultReusingValues) && !d.resetValues && d.clusterAccessAllowed() { + if (d.reuseValues || d.resetThenReuseValues || shouldDefaultReusingValues) && !d.resetValues && d.clusterAccessAllowed() { tmpfile, err := os.CreateTemp("", "existing-values") if err != nil { return nil, err } + resetThenReuseValuesIsSupported, err := isHelmVersionAtLeast(minHelmVersionWithResetThenReuseValues) + if err != nil { + return nil, err + } defer func() { _ = os.Remove(tmpfile.Name()) }() - if err := d.writeExistingValues(tmpfile); err != nil { + // In the presence of --reuse-values (or --reset-values), --reset-then-reuse-values is ignored. + if d.resetThenReuseValues && !d.reuseValues { + if !resetThenReuseValuesIsSupported { + return nil, fmt.Errorf("Using --reset-then-reuse-values requires at least helm version %s", minHelmVersionWithResetThenReuseValues.String()) + } + err = d.writeExistingValues(tmpfile, false) + } else { + err = d.writeExistingValues(tmpfile, true) + } + if err != nil { return nil, err } flags = append(flags, "--values", tmpfile.Name()) diff --git a/cmd/upgrade.go b/cmd/upgrade.go index 4fe554f7..21ffd724 100644 --- a/cmd/upgrade.go +++ b/cmd/upgrade.go @@ -56,6 +56,7 @@ type diffCmd struct { fileValues []string reuseValues bool resetValues bool + resetThenReuseValues bool allowUnreleased bool noHooks bool includeTests bool @@ -242,6 +243,7 @@ func newChartCommand() *cobra.Command { f.StringArrayVar(&diff.fileValues, "set-file", []string{}, "set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)") f.BoolVar(&diff.reuseValues, "reuse-values", false, "reuse the last release's values and merge in any new values. If '--reset-values' is specified, this is ignored") f.BoolVar(&diff.resetValues, "reset-values", false, "reset the values to the ones built into the chart and merge in any new values") + f.BoolVar(&diff.resetThenReuseValues, "reset-then-reuse-values", false, "reset the values to the ones built into the chart, apply the last release's values and merge in any new values. If '--reset-values' or '--reuse-values' is specified, this is ignored") f.BoolVar(&diff.allowUnreleased, "allow-unreleased", false, "enables diffing of releases that are not yet deployed via Helm") f.BoolVar(&diff.install, "install", false, "enables diffing of releases that are not yet deployed via Helm (equivalent to --allow-unreleased, added to match \"helm upgrade --install\" command") f.BoolVar(&diff.noHooks, "no-hooks", false, "disable diffing of hooks") From c35f4135b98f8468ae4248d8158f2f2d308e86f4 Mon Sep 17 00:00:00 2001 From: trk Date: Tue, 25 Jun 2024 01:35:15 +0600 Subject: [PATCH 3/6] Document --reset-then-reuse-values in the README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 8b38a43e..1a9aa675 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,7 @@ Flags: --repo string specify the chart repository url to locate the requested chart --reset-values reset the values to the ones built into the chart and merge in any new values --reuse-values reuse the last release's values and merge in any new values. If '--reset-values' is specified, this is ignored + --reset-then-reuse-values reset the values to the ones built into the chart, apply the last release's values and merge in any new values. If '--reset-values' or '--reuse-values' is specified, this is ignored --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) @@ -198,6 +199,7 @@ Flags: --repo string specify the chart repository url to locate the requested chart --reset-values reset the values to the ones built into the chart and merge in any new values --reuse-values reuse the last release's values and merge in any new values. If '--reset-values' is specified, this is ignored + --reset-then-reuse-values reset the values to the ones built into the chart, apply the last release's values and merge in any new values. If '--reset-values' or '--reuse-values' is specified, this is ignored --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) From 875037b9a9c8dc57ce7e3fc340548626eb6072a0 Mon Sep 17 00:00:00 2001 From: trk Date: Fri, 5 Jul 2024 07:07:02 +0600 Subject: [PATCH 4/6] Add a comment referencing the new flag's origin --- cmd/helm3.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmd/helm3.go b/cmd/helm3.go index 88b58036..dcb70218 100644 --- a/cmd/helm3.go +++ b/cmd/helm3.go @@ -16,8 +16,10 @@ import ( var ( helmVersionRE = regexp.MustCompile(`Version:\s*"([^"]+)"`) minHelmVersion = semver.MustParse("v3.1.0-rc.1") - // See https://github.com/helm/helm/pull/9426 + // See https://github.com/helm/helm/pull/9426. minHelmVersionWithDryRunLookupSupport = semver.MustParse("v3.13.0") + // The --reset-then-reuse-values flag for `helm upgrade` was added in + // https://github.com/helm/helm/pull/9653 and released as part of Helm v3.14.0. minHelmVersionWithResetThenReuseValues = semver.MustParse("v3.14.0") ) From 9de76737ab4cace5168209b70c714d78358b4682 Mon Sep 17 00:00:00 2001 From: trk Date: Tue, 30 Jul 2024 15:33:10 +0600 Subject: [PATCH 5/6] Move min Helm version check to narrower scope --- cmd/helm3.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/helm3.go b/cmd/helm3.go index dcb70218..b264b607 100644 --- a/cmd/helm3.go +++ b/cmd/helm3.go @@ -17,7 +17,7 @@ var ( helmVersionRE = regexp.MustCompile(`Version:\s*"([^"]+)"`) minHelmVersion = semver.MustParse("v3.1.0-rc.1") // See https://github.com/helm/helm/pull/9426. - minHelmVersionWithDryRunLookupSupport = semver.MustParse("v3.13.0") + minHelmVersionWithDryRunLookupSupport = semver.MustParse("v3.13.0") // The --reset-then-reuse-values flag for `helm upgrade` was added in // https://github.com/helm/helm/pull/9653 and released as part of Helm v3.14.0. minHelmVersionWithResetThenReuseValues = semver.MustParse("v3.14.0") @@ -140,15 +140,15 @@ func (d *diffCmd) template(isUpgrade bool) ([]byte, error) { if err != nil { return nil, err } - resetThenReuseValuesIsSupported, err := isHelmVersionAtLeast(minHelmVersionWithResetThenReuseValues) - if err != nil { - return nil, err - } defer func() { _ = os.Remove(tmpfile.Name()) }() // In the presence of --reuse-values (or --reset-values), --reset-then-reuse-values is ignored. if d.resetThenReuseValues && !d.reuseValues { + resetThenReuseValuesIsSupported, err := isHelmVersionAtLeast(minHelmVersionWithResetThenReuseValues) + if err != nil { + return nil, err + } if !resetThenReuseValuesIsSupported { return nil, fmt.Errorf("Using --reset-then-reuse-values requires at least helm version %s", minHelmVersionWithResetThenReuseValues.String()) } From 40e8e3a515c3012cda68e63653d4c8bfe72f9c6e Mon Sep 17 00:00:00 2001 From: trk Date: Wed, 31 Jul 2024 18:01:19 +0600 Subject: [PATCH 6/6] Fix unintended name shadowing --- cmd/helm3.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmd/helm3.go b/cmd/helm3.go index b264b607..f3f7db9e 100644 --- a/cmd/helm3.go +++ b/cmd/helm3.go @@ -145,11 +145,12 @@ func (d *diffCmd) template(isUpgrade bool) ([]byte, error) { }() // In the presence of --reuse-values (or --reset-values), --reset-then-reuse-values is ignored. if d.resetThenReuseValues && !d.reuseValues { - resetThenReuseValuesIsSupported, err := isHelmVersionAtLeast(minHelmVersionWithResetThenReuseValues) + var supported bool + supported, err = isHelmVersionAtLeast(minHelmVersionWithResetThenReuseValues) if err != nil { return nil, err } - if !resetThenReuseValuesIsSupported { + if !supported { return nil, fmt.Errorf("Using --reset-then-reuse-values requires at least helm version %s", minHelmVersionWithResetThenReuseValues.String()) } err = d.writeExistingValues(tmpfile, false)