github.com/hashicorp/terraform-plugin-sdk@v1.17.2/internal/lang/funcs/encoding.go (about)

     1  package funcs
     2  
     3  import (
     4  	"bytes"
     5  	"compress/gzip"
     6  	"encoding/base64"
     7  	"fmt"
     8  	"log"
     9  	"net/url"
    10  	"unicode/utf8"
    11  
    12  	"github.com/zclconf/go-cty/cty"
    13  	"github.com/zclconf/go-cty/cty/function"
    14  )
    15  
    16  // Base64DecodeFunc constructs a function that decodes a string containing a base64 sequence.
    17  var Base64DecodeFunc = function.New(&function.Spec{
    18  	Params: []function.Parameter{
    19  		{
    20  			Name: "str",
    21  			Type: cty.String,
    22  		},
    23  	},
    24  	Type: function.StaticReturnType(cty.String),
    25  	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
    26  		s := args[0].AsString()
    27  		sDec, err := base64.StdEncoding.DecodeString(s)
    28  		if err != nil {
    29  			return cty.UnknownVal(cty.String), fmt.Errorf("failed to decode base64 data '%s'", s)
    30  		}
    31  		if !utf8.Valid([]byte(sDec)) {
    32  			log.Printf("[DEBUG] the result of decoding the the provided string is not valid UTF-8: %s", sDec)
    33  			return cty.UnknownVal(cty.String), fmt.Errorf("the result of decoding the the provided string is not valid UTF-8")
    34  		}
    35  		return cty.StringVal(string(sDec)), nil
    36  	},
    37  })
    38  
    39  // Base64EncodeFunc constructs a function that encodes a string to a base64 sequence.
    40  var Base64EncodeFunc = function.New(&function.Spec{
    41  	Params: []function.Parameter{
    42  		{
    43  			Name: "str",
    44  			Type: cty.String,
    45  		},
    46  	},
    47  	Type: function.StaticReturnType(cty.String),
    48  	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
    49  		return cty.StringVal(base64.StdEncoding.EncodeToString([]byte(args[0].AsString()))), nil
    50  	},
    51  })
    52  
    53  // Base64GzipFunc constructs a function that compresses a string with gzip and then encodes the result in
    54  // Base64 encoding.
    55  var Base64GzipFunc = function.New(&function.Spec{
    56  	Params: []function.Parameter{
    57  		{
    58  			Name: "str",
    59  			Type: cty.String,
    60  		},
    61  	},
    62  	Type: function.StaticReturnType(cty.String),
    63  	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
    64  		s := args[0].AsString()
    65  
    66  		var b bytes.Buffer
    67  		gz := gzip.NewWriter(&b)
    68  		if _, err := gz.Write([]byte(s)); err != nil {
    69  			return cty.UnknownVal(cty.String), fmt.Errorf("failed to write gzip raw data: '%s'", s)
    70  		}
    71  		if err := gz.Flush(); err != nil {
    72  			return cty.UnknownVal(cty.String), fmt.Errorf("failed to flush gzip writer: '%s'", s)
    73  		}
    74  		if err := gz.Close(); err != nil {
    75  			return cty.UnknownVal(cty.String), fmt.Errorf("failed to close gzip writer: '%s'", s)
    76  		}
    77  		return cty.StringVal(base64.StdEncoding.EncodeToString(b.Bytes())), nil
    78  	},
    79  })
    80  
    81  // URLEncodeFunc constructs a function that applies URL encoding to a given string.
    82  var URLEncodeFunc = function.New(&function.Spec{
    83  	Params: []function.Parameter{
    84  		{
    85  			Name: "str",
    86  			Type: cty.String,
    87  		},
    88  	},
    89  	Type: function.StaticReturnType(cty.String),
    90  	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
    91  		return cty.StringVal(url.QueryEscape(args[0].AsString())), nil
    92  	},
    93  })
    94  
    95  // Base64Decode decodes a string containing a base64 sequence.
    96  //
    97  // Terraform uses the "standard" Base64 alphabet as defined in RFC 4648 section 4.
    98  //
    99  // Strings in the Terraform language are sequences of unicode characters rather
   100  // than bytes, so this function will also interpret the resulting bytes as
   101  // UTF-8. If the bytes after Base64 decoding are _not_ valid UTF-8, this function
   102  // produces an error.
   103  func Base64Decode(str cty.Value) (cty.Value, error) {
   104  	return Base64DecodeFunc.Call([]cty.Value{str})
   105  }
   106  
   107  // Base64Encode applies Base64 encoding to a string.
   108  //
   109  // Terraform uses the "standard" Base64 alphabet as defined in RFC 4648 section 4.
   110  //
   111  // Strings in the Terraform language are sequences of unicode characters rather
   112  // than bytes, so this function will first encode the characters from the string
   113  // as UTF-8, and then apply Base64 encoding to the result.
   114  func Base64Encode(str cty.Value) (cty.Value, error) {
   115  	return Base64EncodeFunc.Call([]cty.Value{str})
   116  }
   117  
   118  // Base64Gzip compresses a string with gzip and then encodes the result in
   119  // Base64 encoding.
   120  //
   121  // Terraform uses the "standard" Base64 alphabet as defined in RFC 4648 section 4.
   122  //
   123  // Strings in the Terraform language are sequences of unicode characters rather
   124  // than bytes, so this function will first encode the characters from the string
   125  // as UTF-8, then apply gzip compression, and then finally apply Base64 encoding.
   126  func Base64Gzip(str cty.Value) (cty.Value, error) {
   127  	return Base64GzipFunc.Call([]cty.Value{str})
   128  }
   129  
   130  // URLEncode applies URL encoding to a given string.
   131  //
   132  // This function identifies characters in the given string that would have a
   133  // special meaning when included as a query string argument in a URL and
   134  // escapes them using RFC 3986 "percent encoding".
   135  //
   136  // If the given string contains non-ASCII characters, these are first encoded as
   137  // UTF-8 and then percent encoding is applied separately to each UTF-8 byte.
   138  func URLEncode(str cty.Value) (cty.Value, error) {
   139  	return URLEncodeFunc.Call([]cty.Value{str})
   140  }