From 3297a460c770a34160f300c773e34cf56d18fc7d Mon Sep 17 00:00:00 2001 From: James Bardin Date: Tue, 27 Sep 2016 13:04:40 -0400 Subject: [PATCH] Allow map variables from json A JSON object will be decoded as a list with a single map value. This will be properly coerced later, so let it through the initial config semantic checks. --- terraform/semantics.go | 21 ++++++++------------ terraform/semantics_test.go | 17 ++++++++++++++++ terraform/test-fixtures/uservars-map/main.tf | 3 +++ 3 files changed, 28 insertions(+), 13 deletions(-) create mode 100644 terraform/test-fixtures/uservars-map/main.tf diff --git a/terraform/semantics.go b/terraform/semantics.go index e8e52b7aa..80ca636a8 100644 --- a/terraform/semantics.go +++ b/terraform/semantics.go @@ -108,30 +108,25 @@ func smcUserVariables(c *config.Config, vs map[string]interface{}) []error { switch proposedValue.(type) { case string: continue - default: - errs = append(errs, fmt.Errorf("variable %s should be type %s, got %s", - name, declaredType.Printable(), hclTypeName(proposedValue))) } case config.VariableTypeMap: - switch proposedValue.(type) { + switch v := proposedValue.(type) { case map[string]interface{}: continue - default: - errs = append(errs, fmt.Errorf("variable %s should be type %s, got %s", - name, declaredType.Printable(), hclTypeName(proposedValue))) + case []map[string]interface{}: + // if we have a list of 1 map, it will get coerced later as needed + if len(v) == 1 { + continue + } } case config.VariableTypeList: switch proposedValue.(type) { case []interface{}: continue - default: - errs = append(errs, fmt.Errorf("variable %s should be type %s, got %s", - name, declaredType.Printable(), hclTypeName(proposedValue))) } - default: - errs = append(errs, fmt.Errorf("variable %s should be type %s, got %s", - name, declaredType.Printable(), hclTypeName(proposedValue))) } + errs = append(errs, fmt.Errorf("variable %s should be type %s, got %s", + name, declaredType.Printable(), hclTypeName(proposedValue))) } // TODO(mitchellh): variables that are unknown diff --git a/terraform/semantics_test.go b/terraform/semantics_test.go index 4a8d7bd48..f40f2af69 100644 --- a/terraform/semantics_test.go +++ b/terraform/semantics_test.go @@ -38,3 +38,20 @@ func TestSMCUserVariables(t *testing.T) { } } + +func TestSMCUserVariables_mapFromJSON(t *testing.T) { + c := testConfig(t, "uservars-map") + + // ensure that a single map in a list can satisfy a map variable, since it + // will be coerced later to a map + err := smcUserVariables(c, map[string]interface{}{ + "test_map": []map[string]interface{}{ + map[string]interface{}{ + "foo": "bar", + }, + }, + }) + if err != nil { + t.Fatal(err) + } +} diff --git a/terraform/test-fixtures/uservars-map/main.tf b/terraform/test-fixtures/uservars-map/main.tf new file mode 100644 index 000000000..ebe106343 --- /dev/null +++ b/terraform/test-fixtures/uservars-map/main.tf @@ -0,0 +1,3 @@ +variable "test_map" { + type = "map" +}