From 3be20a83f1d74d4fdbe9fca25606661f8bc0c24b Mon Sep 17 00:00:00 2001 From: MichaelMorris Date: Fri, 5 May 2023 12:28:14 +0100 Subject: [PATCH] Use dry-run=server to enable lookups Helm PR https://github.com/helm/helm/pull/9426 enables support for executing lookups during dry run. This PR is to make use of this new support in helm-diff. Backwards compatibility for older versions of helm is maintained by checking the helm version before setting the flag Addresses issue: https://github.com/databus23/helm-diff/issues/449 Signed-off-by: MichaelMorris --- cmd/helm3.go | 45 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/cmd/helm3.go b/cmd/helm3.go index b19b2b20..6dab4fe7 100644 --- a/cmd/helm3.go +++ b/cmd/helm3.go @@ -14,34 +14,53 @@ import ( ) var ( - helmVersionRE = regexp.MustCompile(`Version:\s*"([^"]+)"`) - minHelmVersion = semver.MustParse("v3.1.0-rc.1") + helmVersionRE = regexp.MustCompile(`Version:\s*"([^"]+)"`) + minHelmVersion = semver.MustParse("v3.1.0-rc.1") + minHelmVersionWithDryRunLookupSupport = semver.MustParse("v3.13.0") ) -func compatibleHelm3Version() error { +func getHelmVersion() (*semver.Version, error) { cmd := exec.Command(os.Getenv("HELM_BIN"), "version") debugPrint("Executing %s", strings.Join(cmd.Args, " ")) output, err := cmd.CombinedOutput() if err != nil { - return fmt.Errorf("Failed to run `%s version`: %v", os.Getenv("HELM_BIN"), err) + return nil, fmt.Errorf("Failed to run `%s version`: %v", os.Getenv("HELM_BIN"), err) } versionOutput := string(output) matches := helmVersionRE.FindStringSubmatch(versionOutput) if matches == nil { - return fmt.Errorf("Failed to find version in output %#v", versionOutput) + return nil, fmt.Errorf("Failed to find version in output %#v", versionOutput) } helmVersion, err := semver.NewVersion(matches[1]) if err != nil { - return fmt.Errorf("Failed to parse version %#v: %v", matches[1], err) + return nil, fmt.Errorf("Failed to parse version %#v: %v", matches[1], err) + } + + return helmVersion, nil +} + +func isHelmVersionAtLeast(versionToCompareTo *semver.Version) (bool, error) { + helmVersion, err := getHelmVersion() + + if err != nil { + return false, err + } + if helmVersion.LessThan(versionToCompareTo) { + return false, nil } + return true, nil +} - if minHelmVersion.GreaterThan(helmVersion) { +func compatibleHelm3Version() error { + if isCompatible, err := isHelmVersionAtLeast(minHelmVersion); err != nil { + return err + } else if !isCompatible { return fmt.Errorf("helm diff upgrade requires at least helm version %s", minHelmVersion.String()) } return nil - } + func getRelease(release, namespace string) ([]byte, error) { args := []string{"get", "manifest", release} if namespace != "" { @@ -177,7 +196,11 @@ func (d *diffCmd) template(isUpgrade bool) ([]byte, error) { flags = append(flags, "--install") } - flags = append(flags, "--dry-run") + if useDryRunService, err := isHelmVersionAtLeast(minHelmVersionWithDryRunLookupSupport); err == nil && useDryRunService { + flags = append(flags, "--dry-run=server") + } else { + flags = append(flags, "--dry-run") + } subcmd = "upgrade" filter = func(s []byte) []byte { return extractManifestFromHelmUpgradeDryRunOutput(s, d.noHooks) @@ -199,6 +222,10 @@ func (d *diffCmd) template(isUpgrade bool) ([]byte, error) { flags = append(flags, "--kube-version", d.kubeVersion) } + if useDryRunService, err := isHelmVersionAtLeast(minHelmVersionWithDryRunLookupSupport); err == nil && useDryRunService { + flags = append(flags, "--dry-run=server") + } + subcmd = "template" filter = func(s []byte) []byte {