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:
James Nugent 2016-06-24 14:31:31 +03:00 committed by GitHub
commit 4b1b185220
8 changed files with 58 additions and 5 deletions

View File

@ -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 {

View File

@ -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")}`,

View File

@ -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")

View File

@ -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)

View File

@ -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

View File

@ -0,0 +1,9 @@
module "b" {
source = "./modb"
}
module "a" {
source = "./moda"
single_element = "${element(module.b.computed_list, 0)}"
}

View File

@ -0,0 +1,3 @@
variable "single_element" {
type = "string"
}

View File

@ -0,0 +1,7 @@
resource "aws_instance" "test" {
count = 3
}
output "computed_list" {
value = ["${aws_instance.test.*.id}"]
}