diff --git a/command/hcl_printer.go b/command/hcl_printer.go index 7947bb815ca1..677e5c0aaaa3 100644 --- a/command/hcl_printer.go +++ b/command/hcl_printer.go @@ -94,7 +94,7 @@ func (e *encodeState) encodeMap(m map[string]interface{}) error { for i, k := range sortedKeys(m) { v := m[k] - e.WriteString(k + " = ") + e.WriteString(fmt.Sprintf("%q = ", k)) err := e.encode(v) if err != nil { return err diff --git a/command/hcl_printer_test.go b/command/hcl_printer_test.go new file mode 100644 index 000000000000..af0abec6c881 --- /dev/null +++ b/command/hcl_printer_test.go @@ -0,0 +1,52 @@ +package command + +import "testing" + +// The command package has it's own HCL encoder to encode variables to push. +// Make sure the variable we encode parse correctly +func TestHCLEncoder_parse(t *testing.T) { + cases := []struct { + Name string + Val interface{} + Error bool + }{ + { + Name: "int", + Val: 12345, + }, + { + Name: "float", + Val: 1.2345, + }, + { + Name: "string", + Val: "terraform", + }, + { + Name: "list", + Val: []interface{}{"a", "b", "c"}, + }, + { + Name: "map", + Val: map[string]interface{}{ + "a": 1, + }, + }, + // a numeric looking identifier requires quotes + { + Name: "map_with_quoted_key", + Val: map[string]interface{}{ + "0.0.0.0/24": "mask", + }, + }, + } + + for _, c := range cases { + t.Run(c.Name, func(t *testing.T) { + _, err := encodeHCL(c.Val) + if err != nil { + t.Fatal(err) + } + }) + } +} diff --git a/command/push_test.go b/command/push_test.go index 0f84611a8636..94573765fc3b 100644 --- a/command/push_test.go +++ b/command/push_test.go @@ -761,11 +761,12 @@ func testArchiveStr(t *testing.T, path string) []string { return result } +// we always quote map keys to be safe func pushTFVars() []atlas.TFVar { return []atlas.TFVar{ {Key: "bar", Value: "foo", IsHCL: false}, {Key: "baz", Value: `{ - A = "a" + "A" = "a" }`, IsHCL: true}, {Key: "fob", Value: `["a", "quotes \"in\" quotes"]`, IsHCL: true}, {Key: "foo", Value: "bar", IsHCL: false},