config: JSON resource keys with only one item load properly GH-5140

When a resource has only a single key set, the HCL parser treats that
key as part of the overall set of object keys. This isn't valid since
we expect resources to have exactly two keys. In this scenario, we have
to "unwrap" the keys back into a set of objects.
This commit is contained in:
Mitchell Hashimoto 2016-08-25 17:18:18 -07:00
parent 8494cad8c4
commit 8a3559560d
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
3 changed files with 63 additions and 0 deletions

View File

@ -555,6 +555,37 @@ func loadManagedResourcesHcl(list *ast.ObjectList) ([]*Resource, error) {
item.Pos())
}
// HCL special case: if we're parsing JSON then directly nested
// items will show up as additional "keys". We need to unwrap them
// since we expect only two keys. Example:
//
// { "foo": { "bar": { "baz": {} } } }
//
// Will show up with Keys being: []string{"foo", "bar", "baz"}
// when we really just want the first two. To fix this we unwrap
// them into the right value.
if len(item.Keys) > 2 && item.Keys[0].Token.JSON {
for len(item.Keys) > 2 {
// Pop off the last key
n := len(item.Keys)
key := item.Keys[n-1]
item.Keys[n-1] = nil
item.Keys = item.Keys[:n-1]
// Wrap our value in a list
item.Val = &ast.ObjectType{
List: &ast.ObjectList{
Items: []*ast.ObjectItem{
&ast.ObjectItem{
Keys: []*ast.ObjectKey{key},
Val: item.Val,
},
},
},
}
}
}
if len(item.Keys) != 2 {
return nil, fmt.Errorf(
"position %s: resource must be followed by exactly two strings, a type and a name",

View File

@ -327,6 +327,22 @@ func TestLoadJSONBasic(t *testing.T) {
}
}
func TestLoadFileBasic_jsonNoName(t *testing.T) {
c, err := LoadFile(filepath.Join(fixtureDir, "resource-no-name.tf.json"))
if err != nil {
t.Fatalf("err: %s", err)
}
if c == nil {
t.Fatal("config should not be nil")
}
actual := resourcesStr(c.Resources)
if actual != strings.TrimSpace(basicJsonNoNameResourcesStr) {
t.Fatalf("bad:\n%s", actual)
}
}
func TestLoadFile_variables(t *testing.T) {
c, err := LoadFile(filepath.Join(fixtureDir, "variables.tf"))
if err != nil {
@ -837,6 +853,11 @@ foo
bar
`
const basicJsonNoNameResourcesStr = `
aws_security_group.allow_external_http_https (x1)
tags
`
const dirBasicOutputsStr = `
web_ip
vars

View File

@ -0,0 +1,11 @@
{
"resource" : {
"aws_security_group" : {
"allow_external_http_https" : {
"tags" : {
"Name" : "allow_external_http_https"
}
}
}
}
}