From 5ebbda3334006ef84c3ac7ea9cab31f121d851a0 Mon Sep 17 00:00:00 2001 From: Paul Hinze Date: Tue, 28 Jul 2015 17:09:56 -0500 Subject: [PATCH] core: fix crash on provider warning When a provider validation only returns a warning, we were cutting the evaltree short by returning an error. This is fine during a `walkValidate` but was causing trouble during `walkPlan` and `walkApply`. fixes #2870 --- terraform/context_apply_test.go | 40 +++++++++++++++++++ terraform/evaltree_provider.go | 29 +++++++++++++- .../apply-provider-warning/main.tf | 1 + 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 terraform/test-fixtures/apply-provider-warning/main.tf diff --git a/terraform/context_apply_test.go b/terraform/context_apply_test.go index ac252abd2..4b2113d63 100644 --- a/terraform/context_apply_test.go +++ b/terraform/context_apply_test.go @@ -78,6 +78,46 @@ func TestContext2Apply_providerAlias(t *testing.T) { } } +// GH-2870 +func TestContext2Apply_providerWarning(t *testing.T) { + m := testModule(t, "apply-provider-warning") + p := testProvider("aws") + p.ApplyFn = testApplyFn + p.DiffFn = testDiffFn + p.ValidateFn = func(c *ResourceConfig) (ws []string, es []error) { + ws = append(ws, "Just a warning") + return + } + ctx := testContext2(t, &ContextOpts{ + Module: m, + Providers: map[string]ResourceProviderFactory{ + "aws": testProviderFuncFixed(p), + }, + }) + + if _, err := ctx.Plan(); err != nil { + t.Fatalf("err: %s", err) + } + + state, err := ctx.Apply() + if err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(state.String()) + expected := strings.TrimSpace(` +aws_instance.foo: + ID = foo + `) + if actual != expected { + t.Fatalf("got: \n%s\n\nexpected:\n%s", actual, expected) + } + + if !p.ConfigureCalled { + t.Fatalf("provider Configure() was never called!") + } +} + func TestContext2Apply_emptyModule(t *testing.T) { m := testModule(t, "apply-empty-module") p := testProvider("aws") diff --git a/terraform/evaltree_provider.go b/terraform/evaltree_provider.go index 1910bc091..99e3ccb1e 100644 --- a/terraform/evaltree_provider.go +++ b/terraform/evaltree_provider.go @@ -40,9 +40,8 @@ func ProviderEvalTree(n string, config *config.RawConfig) EvalNode { }, }) - // Apply stuff seq = append(seq, &EvalOpFilter{ - Ops: []walkOperation{walkValidate, walkRefresh, walkPlan, walkApply}, + Ops: []walkOperation{walkValidate}, Node: &EvalSequence{ Nodes: []EvalNode{ &EvalGetProvider{ @@ -70,6 +69,32 @@ func ProviderEvalTree(n string, config *config.RawConfig) EvalNode { }, }) + // Apply stuff + seq = append(seq, &EvalOpFilter{ + Ops: []walkOperation{walkRefresh, walkPlan, walkApply}, + Node: &EvalSequence{ + Nodes: []EvalNode{ + &EvalGetProvider{ + Name: n, + Output: &provider, + }, + &EvalInterpolate{ + Config: config, + Output: &resourceConfig, + }, + &EvalBuildProviderConfig{ + Provider: n, + Config: &resourceConfig, + Output: &resourceConfig, + }, + &EvalSetProviderConfig{ + Provider: n, + Config: &resourceConfig, + }, + }, + }, + }) + // We configure on everything but validate, since validate may // not have access to all the variables. seq = append(seq, &EvalOpFilter{ diff --git a/terraform/test-fixtures/apply-provider-warning/main.tf b/terraform/test-fixtures/apply-provider-warning/main.tf new file mode 100644 index 000000000..919f140bb --- /dev/null +++ b/terraform/test-fixtures/apply-provider-warning/main.tf @@ -0,0 +1 @@ +resource "aws_instance" "foo" {}