feat: Adding filebase64 function

Adding support for filebase64 function.
pull/13308/merge
Karthik P 10 months ago committed by GitHub
commit 8c228ab969
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,40 @@
package function
import (
"encoding/base64"
"fmt"
"os"
"strings"
"github.com/zclconf/go-cty/cty"
"github.com/zclconf/go-cty/cty/function"
)
var Filebase64 = function.New(&function.Spec{
Params: []function.Parameter{
function.Parameter{
Name: "path",
Description: "Read a file and encode it as a base64 string",
Type: cty.String,
},
},
Type: function.StaticReturnType(cty.String),
RefineResult: refineNotNull,
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
path := args[0].AsString()
content, err := os.ReadFile(path)
if err != nil {
return cty.NullVal(cty.String), fmt.Errorf("failed to read file %q: %s", path, err)
}
out := &strings.Builder{}
enc := base64.NewEncoder(base64.StdEncoding, out)
_, err = enc.Write(content)
if err != nil {
return cty.NullVal(cty.String), fmt.Errorf("failed to write file %q as base64: %s", path, err)
}
_ = enc.Close()
return cty.StringVal(out.String()), nil
},
})

@ -0,0 +1,62 @@
package function
import (
"testing"
"github.com/google/go-cmp/cmp"
"github.com/zclconf/go-cty/cty"
)
func TestFilebase64(t *testing.T) {
tests := []struct {
name string
file string
expectedOutput string
expectError bool
}{
{
"file exists, return base64'd contents, no error",
"./testdata/list.tmpl",
"JXsgZm9yIHggaW4gbGlzdCB+fQotICR7eH0KJXsgZW5kZm9yIH59Cg==",
false,
},
{
"file doesn't exist, return nilval and an error",
"./testdata/no_file",
"",
true,
},
{
"directory passed as arg, should error",
"./testdata",
"",
true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
res, err := Filebase64.Call([]cty.Value{
cty.StringVal(tt.file),
})
if tt.expectError && err == nil {
t.Fatal("succeeded; want error")
}
if !tt.expectError && err != nil {
t.Fatalf("unexpected error: %s", err)
}
if err != nil {
return
}
retVal := res.AsString()
diff := cmp.Diff(retVal, tt.expectedOutput)
if diff != "" {
t.Errorf("expected output and returned are different: %s", diff)
}
})
}
}

@ -64,6 +64,7 @@ func Functions(basedir string) map[string]function.Function {
"element": stdlib.ElementFunc,
"endswith": pkrfunction.EndsWithFunc,
"file": filesystem.MakeFileFunc(basedir, false),
"filebase64": pkrfunction.Filebase64,
"fileexists": filesystem.MakeFileExistsFunc(basedir),
"fileset": filesystem.MakeFileSetFunc(basedir),
"flatten": stdlib.FlattenFunc,

@ -0,0 +1,46 @@
---
page_title: filebase64 - Functions - Configuration Language
description: |-
The filebase64 function reads the contents of the file at the given path and
returns them as a base64-encoded string.
---
# `filebase64` Function
`filebase64` reads the contents of a file at the given path and returns them as
a base64-encoded string.
```hcl
filebase64(path)
```
The result is a Base64 representation of the raw bytes in the given file.
Strings in the Packer language are sequences of Unicode characters, so
Base64 is the standard way to represent raw binary data that cannot be
interpreted as Unicode characters. Resource types that operate on binary
data will accept this data encoded in Base64, thus avoiding the need to
decode the result of this function.
Packer uses the "standard" Base64 alphabet as defined in
[RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4).
This function can be used only with functions that already exist as static
files on disk at the beginning of a Packer run. Language functions do not
participate in the dependency graph, so this function cannot be used with
files that are generated dynamically during a Packer operation.
## Examples
```
> filebase64("${path.module}/hello.txt")
SGVsbG8gV29ybGQ=
```
## Related Functions
* [`file`](/packer/docs/templates/hcl_templates/functions/file/file) also reads the contents of a given file,
but interprets the data as UTF-8 text and returns the result directly
as a string, without any further encoding.
* [`base64decode`](/packer/docs/templates/hcl_templates/functions/encoding/base64decode) can decode a Base64 string representing
bytes in UTF-8, but in practice `base64decode(filebase64(...))` is equivalent
to the shorter expression `file(...)`.

@ -508,6 +508,10 @@
"title": "file",
"path": "templates/hcl_templates/functions/file/file"
},
{
"title": "filebase64",
"path": "templates/hcl_templates/functions/file/filebase64"
},
{
"title": "fileexists",
"path": "templates/hcl_templates/functions/file/fileexists"

Loading…
Cancel
Save