Use flatmap.Expand to extract interpolated values

Now that flatmap.Expand will properly expand nested maps, we can use
that to extract any lists and maps when interpolating.
This commit is contained in:
James Bardin 2016-12-16 10:31:02 -05:00
parent d1d6907640
commit 084670c241
2 changed files with 59 additions and 69 deletions

View File

@ -4,8 +4,6 @@ import (
"fmt"
"log"
"os"
"regexp"
"sort"
"strconv"
"strings"
"sync"
@ -620,33 +618,6 @@ func (i *Interpolater) computeResourceMultiVariable(
return &variable, err
}
type indexKeys []string
// we need to separate the index integer from the ID, and sort numerically
func (i indexKeys) Less(j, k int) bool {
jDot := strings.LastIndex(i[j], ".")
kDot := strings.LastIndex(i[j], ".")
// These should all be properly formatted, but check the indexes and return
// a safe value just in case.
if jDot < 0 || kDot < 0 {
return i[j] < i[k]
}
jIdx, _ := strconv.Atoi(i[j][jDot+1:])
kIdx, _ := strconv.Atoi(i[k][kDot+1:])
return jIdx < kIdx
}
func (i indexKeys) Swap(j, k int) {
i[j], i[k] = i[k], i[j]
}
func (i indexKeys) Len() int {
return len(i)
}
func (i *Interpolater) interpolateComplexTypeAttribute(
resourceID string,
attributes map[string]string) (ast.Variable, error) {
@ -668,23 +639,8 @@ func (i *Interpolater) interpolateComplexTypeAttribute(
return unknownVariable(), nil
}
keys := make([]string, 0)
listElementKey := regexp.MustCompile("^" + resourceID + "\\.[0-9]+$")
for id := range attributes {
if listElementKey.MatchString(id) {
keys = append(keys, id)
}
}
// sort the keys by their index number, rather than lexicographically by the key
sort.Sort(indexKeys(keys))
var members []string
for _, key := range keys {
members = append(members, attributes[key])
}
return hil.InterfaceToVariable(members)
expanded := flatmap.Expand(attributes, resourceID)
return hil.InterfaceToVariable(expanded)
}
if lengthAttr, isMap := attributes[resourceID+".%"]; isMap {
@ -699,15 +655,7 @@ func (i *Interpolater) interpolateComplexTypeAttribute(
return unknownVariable(), nil
}
resourceFlatMap := make(map[string]string)
mapElementKey := regexp.MustCompile("^" + resourceID + "\\.([^%]+)$")
for id, val := range attributes {
if mapElementKey.MatchString(id) {
resourceFlatMap[id] = val
}
}
expanded := flatmap.Expand(resourceFlatMap, resourceID)
expanded := flatmap.Expand(attributes, resourceID)
return hil.InterfaceToVariable(expanded)
}

View File

@ -4,7 +4,6 @@ import (
"fmt"
"os"
"reflect"
"sort"
"sync"
"testing"
@ -675,19 +674,6 @@ func TestInterpolater_selfVarWithoutResource(t *testing.T) {
}
}
// Verify sorting by key index number
func TestInterpolator_indexKeySort(t *testing.T) {
keys := []string{"a.1", "a.2", "a.10", "a.20", "a.3"}
sorted := []string{"a.1", "a.2", "a.3", "a.10", "a.20"}
sort.Sort(indexKeys(keys))
for i := range keys {
if keys[i] != sorted[i] {
t.Fatalf("indexes out of order\nexpected: %q\ngot: %q", sorted, keys)
}
}
}
func TestInterpolator_interpolatedListOrder(t *testing.T) {
state := &State{
Modules: []*ModuleState{
@ -796,6 +782,62 @@ func getInterpolaterFixture(t *testing.T) *Interpolater {
}
}
func TestInterpolator_nestedMapsAndLists(t *testing.T) {
state := &State{
Modules: []*ModuleState{
&ModuleState{
Path: rootModulePath,
Resources: map[string]*ResourceState{
"aws_route53_zone.yada": &ResourceState{
Type: "aws_route53_zone",
Dependencies: []string{},
Primary: &InstanceState{
ID: "null",
Attributes: map[string]string{
"list_of_map.#": "2",
"list_of_map.0.%": "1",
"list_of_map.0.a": "1",
"list_of_map.1.%": "1",
"list_of_map.1.b": "2",
"map_of_list.%": "2",
"map_of_list.list2.#": "1",
"map_of_list.list2.0": "b",
"map_of_list.list1.#": "1",
"map_of_list.list1.0": "a",
},
},
},
},
},
},
}
i := &Interpolater{
Module: testModule(t, "interpolate-multi-vars"),
StateLock: new(sync.RWMutex),
State: state,
}
scope := &InterpolationScope{
Path: rootModulePath,
}
listOfMap := []interface{}{
map[string]interface{}{"a": "1"},
map[string]interface{}{"b": "2"},
}
mapOfList := map[string]interface{}{
"list1": []interface{}{"a"},
"list2": []interface{}{"b"},
}
testInterpolate(t, i, scope, "aws_route53_zone.yada.list_of_map",
interfaceToVariableSwallowError(listOfMap))
testInterpolate(t, i, scope, `aws_route53_zone.yada.map_of_list`,
interfaceToVariableSwallowError(mapOfList))
}
func testInterpolate(
t *testing.T, i *Interpolater,
scope *InterpolationScope,