Allow specifying a default value to lookup()

Fixes #4474, where lookup() calls fail out the entire interpolation when
the provided key value is not found in the map. This will allow using
coalesce() along with lookup() to greatly improve module flexibility.
This commit is contained in:
David Adams 2016-05-25 19:25:15 -05:00
parent a8de40090a
commit b5d1279107
2 changed files with 42 additions and 6 deletions

View File

@ -548,17 +548,32 @@ func interpolationFuncSplit() ast.Function {
// dynamic lookups of map types within a Terraform configuration. // dynamic lookups of map types within a Terraform configuration.
func interpolationFuncLookup(vs map[string]ast.Variable) ast.Function { func interpolationFuncLookup(vs map[string]ast.Variable) ast.Function {
return ast.Function{ return ast.Function{
ArgTypes: []ast.Type{ast.TypeMap, ast.TypeString}, ArgTypes: []ast.Type{ast.TypeMap, ast.TypeString},
ReturnType: ast.TypeString, ReturnType: ast.TypeString,
Variadic: true,
VariadicType: ast.TypeString,
Callback: func(args []interface{}) (interface{}, error) { Callback: func(args []interface{}) (interface{}, error) {
defaultValue := ""
defaultValueSet := false
if len(args) > 2 {
defaultValue = args[2].(string)
defaultValueSet = true
}
if len(args) > 3 {
return "", fmt.Errorf("lookup() takes no more than three arguments")
}
index := args[1].(string) index := args[1].(string)
mapVar := args[0].(map[string]ast.Variable) mapVar := args[0].(map[string]ast.Variable)
v, ok := mapVar[index] v, ok := mapVar[index]
if !ok { if !ok {
return "", fmt.Errorf( if defaultValueSet {
"lookup failed to find '%s'", return defaultValue, nil
args[1].(string)) } else {
return "", fmt.Errorf(
"lookup failed to find '%s'",
args[1].(string))
}
} }
if v.Type != ast.TypeString { if v.Type != ast.TypeString {
return "", fmt.Errorf( return "", fmt.Errorf(

View File

@ -713,12 +713,33 @@ func TestInterpolateFuncLookup(t *testing.T) {
true, true,
}, },
// Supplied default with valid key
{
`${lookup(var.foo, "bar", "")}`,
"baz",
false,
},
// Supplied default with invalid key
{
`${lookup(var.foo, "zip", "")}`,
"",
false,
},
// Too many args // Too many args
{ {
`${lookup(var.foo, "bar", "baz")}`, `${lookup(var.foo, "bar", "", "abc")}`,
nil, nil,
true, true,
}, },
// Non-empty default
{
`${lookup(var.foo, "zap", "xyz")}`,
"xyz",
false,
},
}, },
}) })
} }