From 8bcb9e19ca73d0f5531aa24f9e3405591704fd3a Mon Sep 17 00:00:00 2001 From: James Bardin Date: Tue, 21 Mar 2017 18:04:19 -0400 Subject: [PATCH] restructure JSON terraform config block AST When configuration is read out of JSON, HCL assumes that empty levels of objects can be flattened, but this removes too much to decode into a config.Terraform struct. Reconstruct the appropriate AST to decode the config struct. --- config/loader_hcl.go | 13 ++++++++++ config/loader_test.go | 26 +++++++++++++++++++ .../test-fixtures/terraform-backend-2.tf.json | 9 +++++++ 3 files changed, 48 insertions(+) create mode 100644 config/test-fixtures/terraform-backend-2.tf.json diff --git a/config/loader_hcl.go b/config/loader_hcl.go index 8e0d62c7b..a40ad5ba7 100644 --- a/config/loader_hcl.go +++ b/config/loader_hcl.go @@ -209,6 +209,19 @@ func loadTerraformHcl(list *ast.ObjectList) (*Terraform, error) { // Get our one item item := list.Items[0] + // This block should have an empty top level ObjectItem. If there are keys + // here, it's likely because we have a flattened JSON object, and we can + // lift this into a nested ObjectList to decode properly. + if len(item.Keys) > 0 { + item = &ast.ObjectItem{ + Val: &ast.ObjectType{ + List: &ast.ObjectList{ + Items: []*ast.ObjectItem{item}, + }, + }, + } + } + // We need the item value as an ObjectList var listVal *ast.ObjectList if ot, ok := item.Val.(*ast.ObjectType); ok { diff --git a/config/loader_test.go b/config/loader_test.go index a23eba528..ace70d90e 100644 --- a/config/loader_test.go +++ b/config/loader_test.go @@ -384,6 +384,32 @@ backend (s3) } } +// test that the alternate, more obvious JSON format also decodes properly +func TestLoadFile_terraformBackendJSON2(t *testing.T) { + c, err := LoadFile(filepath.Join(fixtureDir, "terraform-backend-2.tf.json")) + if err != nil { + t.Fatalf("err: %s", err) + } + + if c == nil { + t.Fatal("config should not be nil") + } + + if c.Dir != "" { + t.Fatalf("bad: %#v", c.Dir) + } + + { + actual := terraformStr(c.Terraform) + expected := strings.TrimSpace(` +backend (s3) + foo`) + if actual != expected { + t.Fatalf("bad:\n%s", actual) + } + } +} + func TestLoadFile_terraformBackendMulti(t *testing.T) { _, err := LoadFile(filepath.Join(fixtureDir, "terraform-backend-multi.tf")) if err == nil { diff --git a/config/test-fixtures/terraform-backend-2.tf.json b/config/test-fixtures/terraform-backend-2.tf.json new file mode 100644 index 000000000..d705fe85a --- /dev/null +++ b/config/test-fixtures/terraform-backend-2.tf.json @@ -0,0 +1,9 @@ +{ + "terraform": { + "backend": { + "s3": { + "foo": "bar" + } + } + } +}