mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-28 01:41:48 -06:00
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:
parent
d1d6907640
commit
084670c241
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user