Merge pull request #7304 from hashicorp/b-module-var-from-multi-var
core: Fix bug with interpolation of unknown multi-variables
This commit is contained in:
commit
4b1b185220
|
@ -667,6 +667,9 @@ func interpolationFuncElement() ast.Function {
|
||||||
ReturnType: ast.TypeString,
|
ReturnType: ast.TypeString,
|
||||||
Callback: func(args []interface{}) (interface{}, error) {
|
Callback: func(args []interface{}) (interface{}, error) {
|
||||||
list := args[0].([]ast.Variable)
|
list := args[0].([]ast.Variable)
|
||||||
|
if len(list) == 0 {
|
||||||
|
return nil, fmt.Errorf("element() may not be used with an empty list")
|
||||||
|
}
|
||||||
|
|
||||||
index, err := strconv.Atoi(args[1].(string))
|
index, err := strconv.Atoi(args[1].(string))
|
||||||
if err != nil || index < 0 {
|
if err != nil || index < 0 {
|
||||||
|
|
|
@ -952,6 +952,7 @@ func TestInterpolateFuncElement(t *testing.T) {
|
||||||
Vars: map[string]ast.Variable{
|
Vars: map[string]ast.Variable{
|
||||||
"var.a_list": interfaceToVariableSwallowError([]string{"foo", "baz"}),
|
"var.a_list": interfaceToVariableSwallowError([]string{"foo", "baz"}),
|
||||||
"var.a_short_list": interfaceToVariableSwallowError([]string{"foo"}),
|
"var.a_short_list": interfaceToVariableSwallowError([]string{"foo"}),
|
||||||
|
"var.empty_list": interfaceToVariableSwallowError([]interface{}{}),
|
||||||
},
|
},
|
||||||
Cases: []testFunctionCase{
|
Cases: []testFunctionCase{
|
||||||
{
|
{
|
||||||
|
@ -980,6 +981,13 @@ func TestInterpolateFuncElement(t *testing.T) {
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Empty list should fail
|
||||||
|
{
|
||||||
|
`${element(var.empty_list, 0)}`,
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
|
||||||
// Too many args
|
// Too many args
|
||||||
{
|
{
|
||||||
`${element(var.a_list, "0", "2")}`,
|
`${element(var.a_list, "0", "2")}`,
|
||||||
|
|
|
@ -49,6 +49,27 @@ func TestContext2Input(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestContext2Input_moduleComputedOutputElement(t *testing.T) {
|
||||||
|
m := testModule(t, "input-module-computed-output-element")
|
||||||
|
p := testProvider("aws")
|
||||||
|
p.ApplyFn = testApplyFn
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Module: m,
|
||||||
|
Providers: map[string]ResourceProviderFactory{
|
||||||
|
"aws": testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) {
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ctx.Input(InputModeStd); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestContext2Input_badVarDefault(t *testing.T) {
|
func TestContext2Input_badVarDefault(t *testing.T) {
|
||||||
m := testModule(t, "input-bad-var-default")
|
m := testModule(t, "input-bad-var-default")
|
||||||
p := testProvider("aws")
|
p := testProvider("aws")
|
||||||
|
|
|
@ -162,7 +162,6 @@ func (i *Interpolater) valueModuleVar(
|
||||||
} else {
|
} else {
|
||||||
// Same reasons as the comment above.
|
// Same reasons as the comment above.
|
||||||
result[n] = unknownVariable()
|
result[n] = unknownVariable()
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -485,11 +484,15 @@ func (i *Interpolater) computeResourceMultiVariable(
|
||||||
err)
|
err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have no module in the state yet or count, return empty
|
// If count is zero, we return an empty list
|
||||||
if module == nil || len(module.Resources) == 0 || count == 0 {
|
if count == 0 {
|
||||||
return &ast.Variable{Type: ast.TypeList, Value: []ast.Variable{}}, nil
|
return &ast.Variable{Type: ast.TypeList, Value: []ast.Variable{}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we have no module in the state yet or count, return unknown
|
||||||
|
if module == nil || len(module.Resources) == 0 {
|
||||||
|
return &unknownVariable, nil
|
||||||
|
}
|
||||||
var values []string
|
var values []string
|
||||||
for j := 0; j < count; j++ {
|
for j := 0; j < count; j++ {
|
||||||
id := fmt.Sprintf("%s.%d", v.ResourceId(), j)
|
id := fmt.Sprintf("%s.%d", v.ResourceId(), j)
|
||||||
|
|
|
@ -635,8 +635,7 @@ type OutputState struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *OutputState) String() string {
|
func (s *OutputState) String() string {
|
||||||
// This is a v0.6.x implementation only
|
return fmt.Sprintf("%#v", s.Value)
|
||||||
return fmt.Sprintf("%s", s.Value.(string))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Equal compares two OutputState structures for equality. nil values are
|
// Equal compares two OutputState structures for equality. nil values are
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
module "b" {
|
||||||
|
source = "./modb"
|
||||||
|
}
|
||||||
|
|
||||||
|
module "a" {
|
||||||
|
source = "./moda"
|
||||||
|
|
||||||
|
single_element = "${element(module.b.computed_list, 0)}"
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
variable "single_element" {
|
||||||
|
type = "string"
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
resource "aws_instance" "test" {
|
||||||
|
count = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
output "computed_list" {
|
||||||
|
value = ["${aws_instance.test.*.id}"]
|
||||||
|
}
|
Loading…
Reference in New Issue