From a303817e03bc048c5656f4648e91fa3384c981f3 Mon Sep 17 00:00:00 2001 From: Gorka Lerchundi Osa Date: Wed, 11 Nov 2015 09:51:30 +0100 Subject: [PATCH] config: base64gzip interpolation function Since Terraform's internals are not 8-bit clean (it assumes UTF-8 strings), we can't implement raw gzip directly. We're going to add support where it makes sense for passing data to attributes as base64 so that the result of this function can be used. --- config/interpolate_funcs.go | 29 +++++++++++++++++++ config/interpolate_funcs_test.go | 12 ++++++++ .../docs/configuration/interpolation.html.md | 5 ++++ 3 files changed, 46 insertions(+) diff --git a/config/interpolate_funcs.go b/config/interpolate_funcs.go index 2c5e660a6..0160bef05 100644 --- a/config/interpolate_funcs.go +++ b/config/interpolate_funcs.go @@ -1,6 +1,8 @@ package config import ( + "bytes" + "compress/gzip" "crypto/md5" "crypto/sha1" "crypto/sha256" @@ -58,6 +60,7 @@ func Funcs() map[string]ast.Function { "basename": interpolationFuncBasename(), "base64decode": interpolationFuncBase64Decode(), "base64encode": interpolationFuncBase64Encode(), + "base64gzip": interpolationFuncBase64Gzip(), "base64sha256": interpolationFuncBase64Sha256(), "base64sha512": interpolationFuncBase64Sha512(), "bcrypt": interpolationFuncBcrypt(), @@ -1205,6 +1208,32 @@ func interpolationFuncBase64Decode() ast.Function { } } +// interpolationFuncBase64Gzip implements the "gzip" function that allows gzip +// compression encoding the result using base64 +func interpolationFuncBase64Gzip() ast.Function { + return ast.Function{ + ArgTypes: []ast.Type{ast.TypeString}, + ReturnType: ast.TypeString, + Callback: func(args []interface{}) (interface{}, error) { + s := args[0].(string) + + var b bytes.Buffer + gz := gzip.NewWriter(&b) + if _, err := gz.Write([]byte(s)); err != nil { + return "", fmt.Errorf("failed to write gzip raw data: '%s'", s) + } + if err := gz.Flush(); err != nil { + return "", fmt.Errorf("failed to flush gzip writer: '%s'", s) + } + if err := gz.Close(); err != nil { + return "", fmt.Errorf("failed to close gzip writer: '%s'", s) + } + + return base64.StdEncoding.EncodeToString(b.Bytes()), nil + }, + } +} + // interpolationFuncLower implements the "lower" function that does // string lower casing. func interpolationFuncLower() ast.Function { diff --git a/config/interpolate_funcs_test.go b/config/interpolate_funcs_test.go index 8ed0734a6..2719f3fca 100644 --- a/config/interpolate_funcs_test.go +++ b/config/interpolate_funcs_test.go @@ -2249,6 +2249,18 @@ func TestInterpolateFuncTrimSpace(t *testing.T) { }) } +func TestInterpolateFuncBase64Gzip(t *testing.T) { + testFunction(t, testFunctionConfig{ + Cases: []testFunctionCase{ + { + `${base64gzip("test")}`, + "H4sIAAAAAAAA/ypJLS4BAAAA//8BAAD//wx+f9gEAAAA", + false, + }, + }, + }) +} + func TestInterpolateFuncBase64Sha256(t *testing.T) { testFunction(t, testFunctionConfig{ Cases: []testFunctionCase{ diff --git a/website/docs/configuration/interpolation.html.md b/website/docs/configuration/interpolation.html.md index aea83516c..12700b2d8 100644 --- a/website/docs/configuration/interpolation.html.md +++ b/website/docs/configuration/interpolation.html.md @@ -153,6 +153,11 @@ The supported built-in functions are: * `base64encode(string)` - Returns a base64-encoded representation of the given string. + * `base64gzip(string)` - Compresses the given string with gzip and then + encodes the result to base64. This can be used with certain resource + arguments that allow binary data to be passed with base64 encoding, since + Terraform strings are required to be valid UTF-8. + * `base64sha256(string)` - Returns a base64-encoded representation of raw SHA-256 sum of the given string. **This is not equivalent** of `base64encode(sha256(string))`