From 820e641b97d9ba41bc14b2b4568706b38b973d41 Mon Sep 17 00:00:00 2001 From: James Bardin Date: Fri, 23 Oct 2020 10:39:30 -0400 Subject: [PATCH] do not return warnings as errors from eval Warnings alone cannot be returned from eval nodes, since are still treated as errors. --- terraform/context_apply_test.go | 39 +++++++++++++++++++++++++++++++++ terraform/eval_apply.go | 24 ++++++++++++++++++-- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/terraform/context_apply_test.go b/terraform/context_apply_test.go index 071c80db9..8d76edc6b 100644 --- a/terraform/context_apply_test.go +++ b/terraform/context_apply_test.go @@ -12164,3 +12164,42 @@ func TestContext2Apply_provisionerSensitive(t *testing.T) { t.Errorf("expected hook to be called with %q, but was:\n%s", want, got) } } + +func TestContext2Apply_warnings(t *testing.T) { + m := testModuleInline(t, map[string]string{ + "main.tf": ` +resource "test_resource" "foo" { +}`, + }) + + p := testProvider("test") + p.PlanResourceChangeFn = testDiffFn + + p.ApplyResourceChangeFn = func(req providers.ApplyResourceChangeRequest) providers.ApplyResourceChangeResponse { + resp := testApplyFn(req) + + resp.Diagnostics = resp.Diagnostics.Append(tfdiags.SimpleWarning("warning")) + return resp + } + + ctx := testContext2(t, &ContextOpts{ + Config: m, + Providers: map[addrs.Provider]providers.Factory{ + addrs.NewDefaultProvider("test"): testProviderFuncFixed(p), + }, + }) + + if _, diags := ctx.Plan(); diags.HasErrors() { + t.Fatalf("plan errors: %s", diags.Err()) + } + + state, diags := ctx.Apply() + if diags.HasErrors() { + t.Fatalf("diags: %s", diags.Err()) + } + + inst := state.ResourceInstance(mustResourceInstanceAddr("test_resource.foo")) + if inst == nil { + t.Fatal("missing 'test_resource.foo' in state:", state) + } +} diff --git a/terraform/eval_apply.go b/terraform/eval_apply.go index 80ba9c1f3..67e559484 100644 --- a/terraform/eval_apply.go +++ b/terraform/eval_apply.go @@ -354,7 +354,17 @@ func (n *EvalApply) Eval(ctx EvalContext) (interface{}, error) { } } - return nil, diags.ErrWithWarnings() + // we have to drop warning-only diagnostics for now + if diags.HasErrors() { + return nil, diags.ErrWithWarnings() + } + + // log any warnings since we can't return them + if e := diags.ErrWithWarnings(); e != nil { + log.Printf("[WARN] EvalApply %s: %v", n.Addr, e) + } + + return nil, nil } // EvalApplyPre is an EvalNode implementation that does the pre-Apply work @@ -738,7 +748,17 @@ func (n *EvalApplyProvisioners) apply(ctx EvalContext, provs []*configs.Provisio } } - return diags.ErrWithWarnings() + // we have to drop warning-only diagnostics for now + if diags.HasErrors() { + return diags.ErrWithWarnings() + } + + // log any warnings since we can't return them + if e := diags.ErrWithWarnings(); e != nil { + log.Printf("[WARN] EvalApplyProvisioners %s: %v", n.Addr, e) + } + + return nil } func (n *EvalApplyProvisioners) evalProvisionerConfig(ctx EvalContext, body hcl.Body, self cty.Value, schema *configschema.Block) (cty.Value, tfdiags.Diagnostics) {