config: replace interpolations in block keys [GH-234]

This commit is contained in:
Mitchell Hashimoto 2014-08-27 13:29:02 -07:00
parent 2fc1a47212
commit eac01c2ac8
3 changed files with 31 additions and 2 deletions

View File

@ -40,6 +40,7 @@ BUG FIXES:
* core: Fix issue where some JSON structures didn't map properly into
Terraform structures. [GH-177]
* core: Resources with only `file()` calls will interpolate. [GH-159]
* core: Variables work in block names. [GH-234]
* command/apply: "tfvars" file no longer interferes with plan apply. [GH-153]
* providers/aws: Fix issues around failing to read EIPs. [GH-122]
* providers/aws: Autoscaling groups now register and export load

View File

@ -21,6 +21,7 @@ type interpolationWalker struct {
Replace bool
key []string
lastValue reflect.Value
loc reflectwalk.Location
cs []reflect.Value
csData interface{}
@ -61,6 +62,7 @@ func (w *interpolationWalker) Map(m reflect.Value) error {
func (w *interpolationWalker) MapElem(m, k, v reflect.Value) error {
w.csData = k
w.key = append(w.key, k.String())
w.lastValue = v
return nil
}
@ -123,13 +125,26 @@ func (w *interpolationWalker) Primitive(v reflect.Value) error {
if w.Replace {
resultVal := reflect.ValueOf(result)
if w.loc == reflectwalk.MapValue {
switch w.loc {
case reflectwalk.MapKey:
m := w.cs[len(w.cs)-1]
// Delete the old value
var zero reflect.Value
m.SetMapIndex(w.csData.(reflect.Value), zero)
// Set the new key with the existing value
m.SetMapIndex(resultVal, w.lastValue)
// Set the key to be the new key
w.csData = resultVal
case reflectwalk.MapValue:
// If we're in a map, then the only way to set a map value is
// to set it directly.
m := w.cs[len(w.cs)-1]
mk := w.csData.(reflect.Value)
m.SetMapIndex(mk, resultVal)
} else {
default:
// Otherwise, we should be addressable
setV.Set(resultVal)
}

View File

@ -154,6 +154,19 @@ func TestInterpolationWalker_replace(t *testing.T) {
"foo": "hello, bar",
},
},
{
Input: map[string]interface{}{
"foo": map[string]interface{}{
"${var.foo}": "bar",
},
},
Output: map[string]interface{}{
"foo": map[string]interface{}{
"bar": "bar",
},
},
},
}
for i, tc := range cases {