diff --git a/config/interpolate_funcs.go b/config/interpolate_funcs.go index 5322e46c4..1b58ac93c 100644 --- a/config/interpolate_funcs.go +++ b/config/interpolate_funcs.go @@ -29,10 +29,12 @@ func init() { "index": interpolationFuncIndex(), "join": interpolationFuncJoin(), "length": interpolationFuncLength(), + "lower": interpolationFuncLower(), "replace": interpolationFuncReplace(), "split": interpolationFuncSplit(), "base64encode": interpolationFuncBase64Encode(), "base64decode": interpolationFuncBase64Decode(), + "upper": interpolationFuncUpper(), } } @@ -442,3 +444,29 @@ func interpolationFuncBase64Decode() ast.Function { }, } } + +// interpolationFuncLower implements the "lower" function that does +// string lower casing. +func interpolationFuncLower() ast.Function { + return ast.Function{ + ArgTypes: []ast.Type{ast.TypeString}, + ReturnType: ast.TypeString, + Callback: func(args []interface{}) (interface{}, error) { + toLower := args[0].(string) + return strings.ToLower(toLower), nil + }, + } +} + +// interpolationFuncUpper implements the "upper" function that does +// string upper casing. +func interpolationFuncUpper() ast.Function { + return ast.Function{ + ArgTypes: []ast.Type{ast.TypeString}, + ReturnType: ast.TypeString, + Callback: func(args []interface{}) (interface{}, error) { + toUpper := args[0].(string) + return strings.ToUpper(toUpper), nil + }, + } +} diff --git a/config/interpolate_funcs_test.go b/config/interpolate_funcs_test.go index cafdf0564..f40f56860 100644 --- a/config/interpolate_funcs_test.go +++ b/config/interpolate_funcs_test.go @@ -644,6 +644,54 @@ func TestInterpolateFuncBase64Decode(t *testing.T) { }) } +func TestInterpolateFuncLower(t *testing.T) { + testFunction(t, testFunctionConfig{ + Cases: []testFunctionCase{ + { + `${lower("HELLO")}`, + "hello", + false, + }, + + { + `${lower("")}`, + "", + false, + }, + + { + `${lower()}`, + nil, + true, + }, + }, + }) +} + +func TestInterpolateFuncUpper(t *testing.T) { + testFunction(t, testFunctionConfig{ + Cases: []testFunctionCase{ + { + `${upper("hello")}`, + "HELLO", + false, + }, + + { + `${upper("")}`, + "", + false, + }, + + { + `${upper()}`, + nil, + true, + }, + }, + }) +} + type testFunctionConfig struct { Cases []testFunctionCase Vars map[string]ast.Variable diff --git a/website/source/docs/configuration/interpolation.html.md b/website/source/docs/configuration/interpolation.html.md index 28d03790d..940839076 100644 --- a/website/source/docs/configuration/interpolation.html.md +++ b/website/source/docs/configuration/interpolation.html.md @@ -131,6 +131,8 @@ The supported built-in functions are: variable. The `map` parameter should be another variable, such as `var.amis`. + * `lower(string)` - returns a copy of the string with all Unicode letters mapped to their lower case. + * `replace(string, search, replace)` - Does a search and replace on the given string. All instances of `search` are replaced with the value of `replace`. If `search` is wrapped in forward slashes, it is treated @@ -147,6 +149,8 @@ The supported built-in functions are: `a_resource_param = ["${split(",", var.CSV_STRING)}"]`. Example: `split(",", module.amod.server_ids)` + * `upper(string)` - returns a copy of the string with all Unicode letters mapped to their upper case. + ## Templates Long strings can be managed using templates. [Templates](/docs/providers/template/index.html) are [resources](/docs/configuration/resources.html) defined by a filename and some variables to use during interpolation. They have a computed `rendered` attribute containing the result.