From eac01c2ac8db21d641640f73e8bc71f9cfd5058a Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 27 Aug 2014 13:29:02 -0700 Subject: [PATCH] config: replace interpolations in block keys [GH-234] --- CHANGELOG.md | 1 + config/interpolate_walk.go | 19 +++++++++++++++++-- config/interpolate_walk_test.go | 13 +++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8495ee01..103feafc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/config/interpolate_walk.go b/config/interpolate_walk.go index adc656b75..b91c48c37 100644 --- a/config/interpolate_walk.go +++ b/config/interpolate_walk.go @@ -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) } diff --git a/config/interpolate_walk_test.go b/config/interpolate_walk_test.go index 53c1659d5..5b5c98488 100644 --- a/config/interpolate_walk_test.go +++ b/config/interpolate_walk_test.go @@ -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 {