Merge pull request #9627 from hashicorp/f-format-map
core: Add zipmap interpolation function
This commit is contained in:
commit
9eb5c69849
|
@ -84,6 +84,7 @@ func Funcs() map[string]ast.Function {
|
|||
"title": interpolationFuncTitle(),
|
||||
"trimspace": interpolationFuncTrimSpace(),
|
||||
"upper": interpolationFuncUpper(),
|
||||
"zipmap": interpolationFuncZipMap(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -386,6 +387,39 @@ func interpolationFuncFormat() ast.Function {
|
|||
}
|
||||
}
|
||||
|
||||
func interpolationFuncZipMap() ast.Function {
|
||||
return ast.Function{
|
||||
ArgTypes: []ast.Type{
|
||||
ast.TypeList, // Keys
|
||||
ast.TypeList, // Values
|
||||
},
|
||||
ReturnType: ast.TypeMap,
|
||||
Callback: func(args []interface{}) (interface{}, error) {
|
||||
keys := args[0].([]ast.Variable)
|
||||
values := args[1].([]ast.Variable)
|
||||
|
||||
if len(keys) != len(values) {
|
||||
return nil, fmt.Errorf("count of keys (%d) does not match count of values (%d)",
|
||||
len(keys), len(values))
|
||||
}
|
||||
|
||||
for i, val := range keys {
|
||||
if val.Type != ast.TypeString {
|
||||
return nil, fmt.Errorf("keys must be strings. value at position %d is %s",
|
||||
i, val.Type.Printable())
|
||||
}
|
||||
}
|
||||
|
||||
result := map[string]ast.Variable{}
|
||||
for i := 0; i < len(keys); i++ {
|
||||
result[keys[i].Value.(string)] = values[i]
|
||||
}
|
||||
|
||||
return result, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// interpolationFuncFormatList implements the "formatlist" function that does
|
||||
// string formatting on lists.
|
||||
func interpolationFuncFormatList() ast.Function {
|
||||
|
|
|
@ -11,6 +11,115 @@ import (
|
|||
"github.com/hashicorp/hil/ast"
|
||||
)
|
||||
|
||||
func TestInterpolateFuncZipMap(t *testing.T) {
|
||||
testFunction(t, testFunctionConfig{
|
||||
Cases: []testFunctionCase{
|
||||
{
|
||||
`${zipmap(var.list, var.list2)}`,
|
||||
map[string]interface{}{
|
||||
"Hello": "bar",
|
||||
"World": "baz",
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
`${zipmap(var.list, var.nonstrings)}`,
|
||||
map[string]interface{}{
|
||||
"Hello": []interface{}{"bar", "baz"},
|
||||
"World": []interface{}{"boo", "foo"},
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
`${zipmap(var.nonstrings, var.list2)}`,
|
||||
nil,
|
||||
true,
|
||||
},
|
||||
{
|
||||
`${zipmap(var.list, var.differentlengthlist)}`,
|
||||
nil,
|
||||
true,
|
||||
},
|
||||
},
|
||||
Vars: map[string]ast.Variable{
|
||||
"var.list": {
|
||||
Type: ast.TypeList,
|
||||
Value: []ast.Variable{
|
||||
{
|
||||
Type: ast.TypeString,
|
||||
Value: "Hello",
|
||||
},
|
||||
{
|
||||
Type: ast.TypeString,
|
||||
Value: "World",
|
||||
},
|
||||
},
|
||||
},
|
||||
"var.list2": {
|
||||
Type: ast.TypeList,
|
||||
Value: []ast.Variable{
|
||||
{
|
||||
Type: ast.TypeString,
|
||||
Value: "bar",
|
||||
},
|
||||
{
|
||||
Type: ast.TypeString,
|
||||
Value: "baz",
|
||||
},
|
||||
},
|
||||
},
|
||||
"var.differentlengthlist": {
|
||||
Type: ast.TypeList,
|
||||
Value: []ast.Variable{
|
||||
{
|
||||
Type: ast.TypeString,
|
||||
Value: "bar",
|
||||
},
|
||||
{
|
||||
Type: ast.TypeString,
|
||||
Value: "baz",
|
||||
},
|
||||
{
|
||||
Type: ast.TypeString,
|
||||
Value: "boo",
|
||||
},
|
||||
},
|
||||
},
|
||||
"var.nonstrings": {
|
||||
Type: ast.TypeList,
|
||||
Value: []ast.Variable{
|
||||
{
|
||||
Type: ast.TypeList,
|
||||
Value: []ast.Variable{
|
||||
{
|
||||
Type: ast.TypeString,
|
||||
Value: "bar",
|
||||
},
|
||||
{
|
||||
Type: ast.TypeString,
|
||||
Value: "baz",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: ast.TypeList,
|
||||
Value: []ast.Variable{
|
||||
{
|
||||
Type: ast.TypeString,
|
||||
Value: "boo",
|
||||
},
|
||||
{
|
||||
Type: ast.TypeString,
|
||||
Value: "foo",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestInterpolateFuncList(t *testing.T) {
|
||||
testFunction(t, testFunctionConfig{
|
||||
Cases: []testFunctionCase{
|
||||
|
|
|
@ -252,6 +252,13 @@ The supported built-in functions are:
|
|||
returned by the `keys` function. This function only works on flat maps and
|
||||
will return an error for maps that include nested lists or maps.
|
||||
|
||||
* `zipmap(list, list)` - Creates a map from a list of keys and a list of
|
||||
values. The keys must all be of type string, and the length of the lists
|
||||
must be the same.
|
||||
For example, to output a mapping of AWS IAM user names to the fingerprint
|
||||
of the key used to encrypt their initial password, you might use:
|
||||
`zipmap(aws_iam_user.users.*.name, aws_iam_user_login_profile.users.*.key_fingerprint)`.
|
||||
|
||||
<a id="templates"></a>
|
||||
## Templates
|
||||
|
||||
|
|
Loading…
Reference in New Issue