From a0fad2c6b4b3e6b24d29516549b2e751b542fb0b Mon Sep 17 00:00:00 2001 From: James Bardin Date: Wed, 24 Jun 2020 13:41:51 -0400 Subject: [PATCH 1/2] always return original workspace, even when null The returned value type needs to strictly match the proposed value type. --- .../providers/terraform/data_source_state.go | 9 ++++--- .../terraform/data_source_state_test.go | 24 ++++++++++++------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/builtin/providers/terraform/data_source_state.go b/builtin/providers/terraform/data_source_state.go index fb3349b50c..3cec518ad5 100644 --- a/builtin/providers/terraform/data_source_state.go +++ b/builtin/providers/terraform/data_source_state.go @@ -97,10 +97,13 @@ func dataSourceRemoteStateRead(d cty.Value) (cty.Value, tfdiags.Diagnostics) { newState["backend"] = d.GetAttr("backend") newState["config"] = d.GetAttr("config") - workspaceName := backend.DefaultStateName + workspaceVal := d.GetAttr("workspace") + // This attribute is not computed, so we always have to store the state + // value, even if we implicitly use a default. + newState["workspace"] = workspaceVal - if workspaceVal := d.GetAttr("workspace"); !workspaceVal.IsNull() { - newState["workspace"] = workspaceVal + workspaceName := backend.DefaultStateName + if !workspaceVal.IsNull() { workspaceName = workspaceVal.AsString() } diff --git a/builtin/providers/terraform/data_source_state_test.go b/builtin/providers/terraform/data_source_state_test.go index 8788164fc3..6dbc153286 100644 --- a/builtin/providers/terraform/data_source_state_test.go +++ b/builtin/providers/terraform/data_source_state_test.go @@ -40,7 +40,8 @@ func TestState_basic(t *testing.T) { "outputs": cty.ObjectVal(map[string]cty.Value{ "foo": cty.StringVal("bar"), }), - "defaults": cty.NullVal(cty.DynamicPseudoType), + "defaults": cty.NullVal(cty.DynamicPseudoType), + "workspace": cty.NullVal(cty.String), }), false, }, @@ -80,7 +81,8 @@ func TestState_basic(t *testing.T) { "outputs": cty.ObjectVal(map[string]cty.Value{ "foo": cty.StringVal("bar"), }), - "defaults": cty.NullVal(cty.DynamicPseudoType), + "defaults": cty.NullVal(cty.DynamicPseudoType), + "workspace": cty.NullVal(cty.String), }), false, }, @@ -113,7 +115,8 @@ func TestState_basic(t *testing.T) { cty.StringVal("test2"), }), }), - "defaults": cty.NullVal(cty.DynamicPseudoType), + "defaults": cty.NullVal(cty.DynamicPseudoType), + "workspace": cty.NullVal(cty.String), }), false, }, @@ -133,7 +136,8 @@ func TestState_basic(t *testing.T) { "map": cty.NullVal(cty.DynamicPseudoType), "list": cty.NullVal(cty.DynamicPseudoType), }), - "defaults": cty.NullVal(cty.DynamicPseudoType), + "defaults": cty.NullVal(cty.DynamicPseudoType), + "workspace": cty.NullVal(cty.String), }), false, }, @@ -158,6 +162,7 @@ func TestState_basic(t *testing.T) { "outputs": cty.ObjectVal(map[string]cty.Value{ "foo": cty.StringVal("bar"), }), + "workspace": cty.NullVal(cty.String), }), false, }, @@ -173,8 +178,9 @@ func TestState_basic(t *testing.T) { "config": cty.ObjectVal(map[string]cty.Value{ "path": cty.StringVal("./testdata/missing.tfstate"), }), - "defaults": cty.NullVal(cty.DynamicPseudoType), - "outputs": cty.EmptyObjectVal, + "defaults": cty.NullVal(cty.DynamicPseudoType), + "outputs": cty.EmptyObjectVal, + "workspace": cty.NullVal(cty.String), }), true, }, @@ -225,8 +231,9 @@ func TestState_basic(t *testing.T) { "config": cty.MapVal(map[string]cty.Value{ "path": cty.StringVal("./testdata/empty.tfstate"), }), - "defaults": cty.NullVal(cty.DynamicPseudoType), - "outputs": cty.EmptyObjectVal, + "defaults": cty.NullVal(cty.DynamicPseudoType), + "outputs": cty.EmptyObjectVal, + "workspace": cty.NullVal(cty.String), }), false, }, @@ -247,6 +254,7 @@ func TestState_basic(t *testing.T) { "outputs": cty.ObjectVal(map[string]cty.Value{ "foo": cty.StringVal("bar"), }), + "workspace": cty.NullVal(cty.String), }), false, }, From 731b19ab46d3e27f1bc1f5f682ba6e50dfcfac68 Mon Sep 17 00:00:00 2001 From: James Bardin Date: Wed, 24 Jun 2020 14:09:59 -0400 Subject: [PATCH 2/2] e2e test for remote state read --- command/e2etest/remote_state_test.go | 29 +++++++++++++++++++ .../testdata/terraform-provider/main.tf | 2 +- .../testdata/terraform-provider/test.tfstate | 13 +++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 command/e2etest/remote_state_test.go create mode 100644 command/e2etest/testdata/terraform-provider/test.tfstate diff --git a/command/e2etest/remote_state_test.go b/command/e2etest/remote_state_test.go new file mode 100644 index 0000000000..be8c032bd4 --- /dev/null +++ b/command/e2etest/remote_state_test.go @@ -0,0 +1,29 @@ +package e2etest + +import ( + "path/filepath" + "testing" + + "github.com/hashicorp/terraform/e2e" +) + +func TestTerraformProviderRead(t *testing.T) { + // Ensure the terraform provider can correctly read a remote state + + t.Parallel() + fixturePath := filepath.Join("testdata", "terraform-provider") + tf := e2e.NewBinary(terraformBin, fixturePath) + defer tf.Close() + + //// INIT + _, stderr, err := tf.Run("init") + if err != nil { + t.Fatalf("unexpected init error: %s\nstderr:\n%s", err, stderr) + } + + //// PLAN + _, stderr, err = tf.Run("plan") + if err != nil { + t.Fatalf("unexpected plan error: %s\nstderr:\n%s", err, stderr) + } +} diff --git a/command/e2etest/testdata/terraform-provider/main.tf b/command/e2etest/testdata/terraform-provider/main.tf index a8e222fca6..bd9887e99a 100644 --- a/command/e2etest/testdata/terraform-provider/main.tf +++ b/command/e2etest/testdata/terraform-provider/main.tf @@ -5,6 +5,6 @@ provider "terraform" { data "terraform_remote_state" "test" { backend = "local" config = { - path = "nothing.tfstate" + path = "test.tfstate" } } diff --git a/command/e2etest/testdata/terraform-provider/test.tfstate b/command/e2etest/testdata/terraform-provider/test.tfstate new file mode 100644 index 0000000000..fb1012d15d --- /dev/null +++ b/command/e2etest/testdata/terraform-provider/test.tfstate @@ -0,0 +1,13 @@ +{ + "version": 4, + "terraform_version": "0.13.0", + "serial": 1, + "lineage": "8fab7b5a-511c-d586-988e-250f99c8feb4", + "outputs": { + "out": { + "value": "test", + "type": "string" + } + }, + "resources": [] +}