Add base64gzip function support to Packer template

pull/13147/head
Wenfeng Pan 2 years ago committed by GitHub
parent ded0500109
commit 1b160e5df0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,54 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package function
import (
"bytes"
"compress/gzip"
"encoding/base64"
"fmt"
"github.com/zclconf/go-cty/cty"
"github.com/zclconf/go-cty/cty/function"
)
// Base64GzipFunc constructs a function that compresses a string with gzip and then encodes the result in
// Base64 encoding.
var Base64GzipFunc = function.New(&function.Spec{
Params: []function.Parameter{
{
Name: "str",
Type: cty.String,
},
},
Type: function.StaticReturnType(cty.String),
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
s := args[0].AsString()
var b bytes.Buffer
gz := gzip.NewWriter(&b)
if _, err := gz.Write([]byte(s)); err != nil {
return cty.UnknownVal(cty.String), fmt.Errorf("failed to write gzip raw data: %w", err)
}
if err := gz.Flush(); err != nil {
return cty.UnknownVal(cty.String), fmt.Errorf("failed to flush gzip writer: %w", err)
}
if err := gz.Close(); err != nil {
return cty.UnknownVal(cty.String), fmt.Errorf("failed to close gzip writer: %w", err)
}
return cty.StringVal(base64.StdEncoding.EncodeToString(b.Bytes())), nil
},
})
// Base64Gzip compresses a string with gzip and then encodes the result in
// Base64 encoding.
//
// Packer uses the "standard" Base64 alphabet as defined in RFC 4648 section 4.
//
// Strings in the Packer language are sequences of unicode characters rather
// than bytes, so this function will first encode the characters from the string
// as UTF-8, then apply gzip compression, and then finally apply Base64 encoding.
func Base64Gzip(str cty.Value) (cty.Value, error) {
return Base64GzipFunc.Call([]cty.Value{str})
}

@ -0,0 +1,49 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package function
import (
"fmt"
"testing"
"github.com/zclconf/go-cty/cty"
)
func TestBase64Gzip(t *testing.T) {
tests := []struct {
String cty.Value
Want cty.Value
Err bool
}{
{
cty.StringVal("test"),
cty.StringVal("H4sIAAAAAAAA/ypJLS4BAAAA//8BAAD//wx+f9gEAAAA"),
false,
},
{
cty.StringVal("helloworld"),
cty.StringVal("H4sIAAAAAAAA/8pIzcnJL88vykkBAAAA//8BAAD//60g6/kKAAAA"),
false,
},
}
for _, test := range tests {
t.Run(fmt.Sprintf("base64gzip(%#v)", test.String), func(t *testing.T) {
got, err := Base64Gzip(test.String)
if test.Err {
if err == nil {
t.Fatal("succeeded; want error")
}
return
} else if err != nil {
t.Fatalf("unexpected error: %s", err)
}
if !got.RawEquals(test.Want) {
t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.Want)
}
})
}
}

@ -38,6 +38,7 @@ func Functions(basedir string) map[string]function.Function {
"basename": filesystem.BasenameFunc,
"base64decode": encoding.Base64DecodeFunc,
"base64encode": encoding.Base64EncodeFunc,
"base64gzip": pkrfunction.Base64GzipFunc,
"bcrypt": crypto.BcryptFunc,
"can": tryfunc.CanFunc,
"ceil": stdlib.CeilFunc,

@ -0,0 +1,32 @@
---
page_title: base64gzip - Functions - Configuration Language
description: The base64encode function compresses the given string with gzip and then
encodes the result in Base64.
---
# `base64gzip` Function
`base64gzip` compresses a string with gzip and then encodes the result in
Base64 encoding.
Packer uses the "standard" Base64 alphabet as defined in
[RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4).
Strings in the Packer language are sequences of unicode characters rather
than bytes, so this function will first encode the characters from the string
as UTF-8, and then apply Base64 encoding to the result.
The Packer language applies Unicode normalization to all strings, and so
passing a string through `base64decode` and then `base64encode` may not yield
the original result exactly.
While we do not recommend manipulating large, raw binary data in the Packer
language, this function can be used to compress reasonably sized text strings
generated within the Packer language. For example, the result of this
function can be used to create a compressed object in Amazon S3 as part of
an S3 website.
## Related Functions
- [`base64decode`](/packer/docs/templates/hcl_templates/functions/encoding/base64decode) performs the opposite operation,
decoding Base64 data and interpreting it as a UTF-8 string.

@ -427,6 +427,10 @@
"title": "base64encode",
"path": "templates/hcl_templates/functions/encoding/base64encode"
},
{
"title": "base64gzip",
"path": "templates/hcl_templates/functions/encoding/base64gzip"
},
{
"title": "csvdecode",
"path": "templates/hcl_templates/functions/encoding/csvdecode"

Loading…
Cancel
Save