From 2deb15beaec2aacffd28ef85c0b0e8c9d5594880 Mon Sep 17 00:00:00 2001 From: John Houston Date: Thu, 6 Oct 2022 00:17:29 -0400 Subject: [PATCH] Add regression test for unknown values bug --- helm/resource_release.go | 37 ++++++++++++--------- helm/resource_release_test.go | 61 +++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 15 deletions(-) diff --git a/helm/resource_release.go b/helm/resource_release.go index 1e23c2eaf2..0f5af66719 100644 --- a/helm/resource_release.go +++ b/helm/resource_release.go @@ -807,6 +807,17 @@ func resourceDiff(ctx context.Context, d *schema.ResourceDiff, meta interface{}) debug("%s Release validated", logID) if m.ExperimentEnabled("manifest") { + // NOTE we need to check that the values supplied to the release are + // fully known at plan time otherwise we can't supply them to the + // action to perform a dry run + if !valuesKnown(d) { + // NOTE it would be nice to surface a warning diagnostic here + // but this is not possible with the SDK + debug("not all values are known, skipping dry run to render manifest") + d.SetNewComputed("manifest") + return d.SetNewComputed("version") + } + var postRenderer postrender.PostRenderer if cmd := d.Get("postrender.0.binary_path").(string); cmd != "" { av := d.Get("postrender.0.args") @@ -846,10 +857,6 @@ func resourceDiff(ctx context.Context, d *schema.ResourceDiff, meta interface{}) install.CreateNamespace = d.Get("create_namespace").(bool) install.PostRenderer = postRenderer - // if !valuesWhollyKnown(d) { - // d.SetNewComputed("manifest") - // return d.SetNewComputed("version") - // } values, err := getValues(d) if err != nil { return fmt.Errorf("error getting values: %v", err) @@ -1374,18 +1381,18 @@ func resultToError(r *action.LintResult) error { return fmt.Errorf("malformed chart or values: \n\t%s", strings.Join(messages, "\n\t")) } -func valuesWhollyKnown(d *schema.ResourceDiff) bool { +// valuesKnown returns true if all of the values supplied to the release are known at plan time +func valuesKnown(d *schema.ResourceDiff) bool { rawPlan := d.GetRawPlan() - - if !rawPlan.GetAttr("values").IsWhollyKnown() { - return false - } - if !rawPlan.GetAttr("set").IsWhollyKnown() { - return false - } - if !rawPlan.GetAttr("set_sensitive").IsWhollyKnown() { - return false + checkAttributes := []string{ + "values", + "set", + "set_sensitive", + } + for _, attr := range checkAttributes { + if !rawPlan.GetAttr(attr).IsWhollyKnown() { + return false + } } - return true } diff --git a/helm/resource_release_test.go b/helm/resource_release_test.go index 2041d4ba15..67c09de642 100644 --- a/helm/resource_release_test.go +++ b/helm/resource_release_test.go @@ -1232,6 +1232,33 @@ func TestAccResourceRelease_manifest(t *testing.T) { }) } +func TestAccResourceRelease_manifestUnknownValues(t *testing.T) { + name := "example" + namespace := createRandomNamespace(t) + defer deleteNamespace(t, namespace) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + Providers: testAccProviders, + ExternalProviders: map[string]resource.ExternalProvider{ + "random": { + Source: "hashicorp/random", + }, + }, + CheckDestroy: testAccCheckHelmReleaseDestroy(namespace), + Steps: []resource.TestStep{ + // NOTE this is a regression test to apply a configuration which supplies + // unknown values to the release at plan time, we simply want to test here + // that applying the config doesn't produce an inconsistent final plan error + { + Config: testAccHelmReleaseConfigManifestUnknownValues(testResourceName, namespace, name, "1.2.3") + }, + }, + }) +} + func setupOCIRegistry(t *testing.T, usepassword bool) (string, func()) { dockerPath, err := exec.LookPath("docker") if err != nil { @@ -1502,6 +1529,40 @@ func testAccHelmReleaseConfigManifestExperimentEnabled(resource, ns, name, versi `, resource, name, ns, testRepositoryURL, version) } +func testAccHelmReleaseConfigManifestUnknownValues(resource, ns, name, version string) string { + return fmt.Sprintf(` + provider helm { + experiments { + manifest = true + } + } + resource "random_string" "random_label" { + length = 16 + special = false + } + resource "helm_release" "%s" { + name = %q + namespace = %q + repository = %q + version = %q + chart = "test-chart" + set { + name = "podAnnotations.random" + value = random_string.random_label.result + } + set_sensitive { + name = "podAnnotations.sensitive" + value = random_string.random_label.result + } + values = [<