cleanup comments for nicer godocs
This commit is contained in:
parent
9aa9b18658
commit
eb1d8b7909
|
@ -1,9 +1,15 @@
|
||||||
package funcs
|
package funcs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/sha1"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"crypto/sha512"
|
"crypto/sha512"
|
||||||
|
"crypto/x509"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/pem"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
uuid "github.com/hashicorp/go-uuid"
|
uuid "github.com/hashicorp/go-uuid"
|
||||||
|
@ -25,8 +31,8 @@ var UUIDFunc = function.New(&function.Spec{
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// Base64Sha256Func constructs a function that computes the SHA256 hash of a given string and encodes it with
|
// Base64Sha256Func constructs a function that computes the SHA256 hash of a given string
|
||||||
// Base64.
|
// and encodes it with Base64.
|
||||||
var Base64Sha256Func = function.New(&function.Spec{
|
var Base64Sha256Func = function.New(&function.Spec{
|
||||||
Params: []function.Parameter{
|
Params: []function.Parameter{
|
||||||
{
|
{
|
||||||
|
@ -44,8 +50,8 @@ var Base64Sha256Func = function.New(&function.Spec{
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// Base64Sha512Func constructs a function that computes the SHA256 hash of a given string and encodes it with
|
// Base64Sha512Func constructs a function that computes the SHA256 hash of a given string
|
||||||
// Base64.
|
// and encodes it with Base64.
|
||||||
var Base64Sha512Func = function.New(&function.Spec{
|
var Base64Sha512Func = function.New(&function.Spec{
|
||||||
Params: []function.Parameter{
|
Params: []function.Parameter{
|
||||||
{
|
{
|
||||||
|
@ -101,6 +107,89 @@ var BcryptFunc = function.New(&function.Spec{
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Md5Func constructs a function that computes the MD5 hash of a given string and encodes it with hexadecimal digits.
|
||||||
|
var Md5Func = 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) (ret cty.Value, err error) {
|
||||||
|
s := args[0].AsString()
|
||||||
|
h := md5.New()
|
||||||
|
h.Write([]byte(s))
|
||||||
|
hash := hex.EncodeToString(h.Sum(nil))
|
||||||
|
return cty.StringVal(hash), nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// RsaDecryptFunc constructs a function that decrypts an RSA-encrypted ciphertext.
|
||||||
|
var RsaDecryptFunc = function.New(&function.Spec{
|
||||||
|
Params: []function.Parameter{
|
||||||
|
{
|
||||||
|
Name: "ciphertext",
|
||||||
|
Type: cty.String,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "privatekey",
|
||||||
|
Type: cty.String,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Type: function.StaticReturnType(cty.String),
|
||||||
|
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
||||||
|
s := args[0].AsString()
|
||||||
|
key := args[1].AsString()
|
||||||
|
|
||||||
|
b, err := base64.StdEncoding.DecodeString(s)
|
||||||
|
if err != nil {
|
||||||
|
return cty.UnknownVal(cty.String), fmt.Errorf("Failed to decode input %q: cipher text must be base64-encoded", key)
|
||||||
|
}
|
||||||
|
|
||||||
|
block, _ := pem.Decode([]byte(key))
|
||||||
|
if block == nil {
|
||||||
|
return cty.UnknownVal(cty.String), fmt.Errorf("Failed to read key %q: no key found", key)
|
||||||
|
}
|
||||||
|
if block.Headers["Proc-Type"] == "4,ENCRYPTED" {
|
||||||
|
return cty.UnknownVal(cty.String), fmt.Errorf(
|
||||||
|
"Failed to read key %q: password protected keys are\n"+
|
||||||
|
"not supported. Please decrypt the key prior to use.", key)
|
||||||
|
}
|
||||||
|
|
||||||
|
x509Key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
return cty.UnknownVal(cty.String), err
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := rsa.DecryptPKCS1v15(nil, x509Key, b)
|
||||||
|
if err != nil {
|
||||||
|
return cty.UnknownVal(cty.String), err
|
||||||
|
}
|
||||||
|
|
||||||
|
return cty.StringVal(string(out)), nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Sha1Func contructs a function that computes the SHA1 hash of a given string
|
||||||
|
// and encodes it with hexadecimal digits.
|
||||||
|
var Sha1Func = 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) (ret cty.Value, err error) {
|
||||||
|
s := args[0].AsString()
|
||||||
|
h := sha1.New()
|
||||||
|
h.Write([]byte(s))
|
||||||
|
hash := hex.EncodeToString(h.Sum(nil))
|
||||||
|
return cty.StringVal(hash), nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
// UUID generates and returns a Type-4 UUID in the standard hexadecimal string
|
// UUID generates and returns a Type-4 UUID in the standard hexadecimal string
|
||||||
// format.
|
// format.
|
||||||
//
|
//
|
||||||
|
@ -111,30 +200,28 @@ func UUID() (cty.Value, error) {
|
||||||
return UUIDFunc.Call(nil)
|
return UUIDFunc.Call(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base64sha256 computes the SHA256 hash of a given string and encodes it with
|
// Base64Sha256 computes the SHA256 hash of a given string and encodes it with
|
||||||
// Base64.
|
// Base64.
|
||||||
//
|
//
|
||||||
// The given string is first encoded as UTF-8 and then the SHA256 algorithm is applied
|
// The given string is first encoded as UTF-8 and then the SHA256 algorithm is applied
|
||||||
// as defined in [RFC 4634](https://tools.ietf.org/html/rfc4634). The raw hash is
|
// as defined in RFC 4634. The raw hash is then encoded with Base64 before returning.
|
||||||
// then encoded with Base64 before returning. Terraform uses the "standard" Base64
|
// Terraform uses the "standard" Base64 alphabet as defined in RFC 4648 section 4.
|
||||||
// alphabet as defined in [RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4).
|
|
||||||
func Base64Sha256(str cty.Value) (cty.Value, error) {
|
func Base64Sha256(str cty.Value) (cty.Value, error) {
|
||||||
return Base64Sha256Func.Call([]cty.Value{str})
|
return Base64Sha256Func.Call([]cty.Value{str})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base64sha512 computes the SHA512 hash of a given string and encodes it with
|
// Base64Sha512 computes the SHA512 hash of a given string and encodes it with
|
||||||
// Base64.
|
// Base64.
|
||||||
//
|
//
|
||||||
// The given string is first encoded as UTF-8 and then the SHA256 algorithm is applied
|
// The given string is first encoded as UTF-8 and then the SHA256 algorithm is applied
|
||||||
// as defined in [RFC 4634](https://tools.ietf.org/html/rfc4634). The raw hash is
|
// as defined in RFC 4634. The raw hash is then encoded with Base64 before returning.
|
||||||
// then encoded with Base64 before returning. Terraform uses the "standard" Base64
|
// Terraform uses the "standard" Base64 alphabet as defined in RFC 4648 section 4
|
||||||
// alphabet as defined in [RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4).
|
|
||||||
func Base64Sha512(str cty.Value) (cty.Value, error) {
|
func Base64Sha512(str cty.Value) (cty.Value, error) {
|
||||||
return Base64Sha512Func.Call([]cty.Value{str})
|
return Base64Sha512Func.Call([]cty.Value{str})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bcrypt computes a hash of the given string using the Blowfish cipher,
|
// Bcrypt computes a hash of the given string using the Blowfish cipher,
|
||||||
// returning a string in the Modular Crypt Format(https://passlib.readthedocs.io/en/stable/modular_crypt_format.html)
|
// returning a string in the Modular Crypt Format
|
||||||
// usually expected in the shadow password file on many Unix systems.
|
// usually expected in the shadow password file on many Unix systems.
|
||||||
func Bcrypt(str cty.Value, cost ...cty.Value) (cty.Value, error) {
|
func Bcrypt(str cty.Value, cost ...cty.Value) (cty.Value, error) {
|
||||||
args := make([]cty.Value, len(cost)+1)
|
args := make([]cty.Value, len(cost)+1)
|
||||||
|
@ -142,3 +229,19 @@ func Bcrypt(str cty.Value, cost ...cty.Value) (cty.Value, error) {
|
||||||
copy(args[1:], cost)
|
copy(args[1:], cost)
|
||||||
return BcryptFunc.Call(args)
|
return BcryptFunc.Call(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Md5 computes the MD5 hash of a given string and encodes it with hexadecimal digits.
|
||||||
|
func Md5(str cty.Value) (cty.Value, error) {
|
||||||
|
return Md5Func.Call([]cty.Value{str})
|
||||||
|
}
|
||||||
|
|
||||||
|
// RsaDecrypt decrypts an RSA-encrypted ciphertext, returning the corresponding
|
||||||
|
// cleartext.
|
||||||
|
func RsaDecrypt(ciphertext, privatekey cty.Value) (cty.Value, error) {
|
||||||
|
return RsaDecryptFunc.Call([]cty.Value{ciphertext, privatekey})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sha1 computes the SHA1 hash of a given string and encodes it with hexadecimal digits.
|
||||||
|
func Sha1(str cty.Value) (cty.Value, error) {
|
||||||
|
return Sha1Func.Call([]cty.Value{str})
|
||||||
|
}
|
||||||
|
|
|
@ -45,10 +45,8 @@ func TestBase64Sha256(t *testing.T) {
|
||||||
t.Fatal("succeeded; want error")
|
t.Fatal("succeeded; want error")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
} else {
|
} else if err != nil {
|
||||||
if err != nil {
|
t.Fatalf("unexpected error: %s", err)
|
||||||
t.Fatalf("unexpected error: %s", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !got.RawEquals(test.Want) {
|
if !got.RawEquals(test.Want) {
|
||||||
|
@ -83,10 +81,8 @@ func TestBase64Sha512(t *testing.T) {
|
||||||
t.Fatal("succeeded; want error")
|
t.Fatal("succeeded; want error")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
} else {
|
} else if err != nil {
|
||||||
if err != nil {
|
t.Fatalf("unexpected error: %s", err)
|
||||||
t.Fatalf("unexpected error: %s", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !got.RawEquals(test.Want) {
|
if !got.RawEquals(test.Want) {
|
||||||
|
@ -125,3 +121,211 @@ func TestBcrypt(t *testing.T) {
|
||||||
t.Fatal("succeeded; want error")
|
t.Fatal("succeeded; want error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMd5(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
String cty.Value
|
||||||
|
Want cty.Value
|
||||||
|
Err bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
cty.StringVal("tada"),
|
||||||
|
cty.StringVal("ce47d07243bb6eaf5e1322c81baf9bbf"),
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{ // Confirm that we're not trimming any whitespaces
|
||||||
|
cty.StringVal(" tada "),
|
||||||
|
cty.StringVal("aadf191a583e53062de2d02c008141c4"),
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{ // We accept empty string too
|
||||||
|
cty.StringVal(""),
|
||||||
|
cty.StringVal("d41d8cd98f00b204e9800998ecf8427e"),
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(fmt.Sprintf("md5(%#v)", test.String), func(t *testing.T) {
|
||||||
|
got, err := Md5(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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRsaDecrypt(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
Ciphertext cty.Value
|
||||||
|
Privatekey cty.Value
|
||||||
|
Want cty.Value
|
||||||
|
Err bool
|
||||||
|
}{
|
||||||
|
// Base-64 encoded cipher decrypts correctly
|
||||||
|
{
|
||||||
|
cty.StringVal(CipherBase64),
|
||||||
|
cty.StringVal(PrivateKey),
|
||||||
|
cty.StringVal("message"),
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
// Wrong key
|
||||||
|
{
|
||||||
|
cty.StringVal(CipherBase64),
|
||||||
|
cty.StringVal(WrongPrivateKey),
|
||||||
|
cty.UnknownVal(cty.String),
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
// Bad key
|
||||||
|
{
|
||||||
|
cty.StringVal(CipherBase64),
|
||||||
|
cty.StringVal("bad key"),
|
||||||
|
cty.UnknownVal(cty.String),
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
// Empty key
|
||||||
|
{
|
||||||
|
cty.StringVal(CipherBase64),
|
||||||
|
cty.StringVal(""),
|
||||||
|
cty.UnknownVal(cty.String),
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
// Bad cipher
|
||||||
|
{
|
||||||
|
cty.StringVal("bad cipher"),
|
||||||
|
cty.StringVal(PrivateKey),
|
||||||
|
cty.UnknownVal(cty.String),
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
// Empty cipher
|
||||||
|
{
|
||||||
|
cty.StringVal(""),
|
||||||
|
cty.StringVal(PrivateKey),
|
||||||
|
cty.UnknownVal(cty.String),
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(fmt.Sprintf("RsaDecrypt(%#v, %#v)", test.Ciphertext, test.Privatekey), func(t *testing.T) {
|
||||||
|
got, err := RsaDecrypt(test.Ciphertext, test.Privatekey)
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSha1(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
String cty.Value
|
||||||
|
Want cty.Value
|
||||||
|
Err bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
cty.StringVal("test"),
|
||||||
|
cty.StringVal("a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"),
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(fmt.Sprintf("sha1(%#v)", test.String), func(t *testing.T) {
|
||||||
|
got, err := Sha1(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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
CipherBase64 = "eczGaDhXDbOFRZGhjx2etVzWbRqWDlmq0bvNt284JHVbwCgObiuyX9uV0LSAMY707IEgMkExJqXmsB4OWKxvB7epRB9G/3+F+pcrQpODlDuL9oDUAsa65zEpYF0Wbn7Oh7nrMQncyUPpyr9WUlALl0gRWytOA23S+y5joa4M34KFpawFgoqTu/2EEH4Xl1zo+0fy73fEto+nfkUY+meuyGZ1nUx/+DljP7ZqxHBFSlLODmtuTMdswUbHbXbWneW51D7Jm7xB8nSdiA2JQNK5+Sg5x8aNfgvFTt/m2w2+qpsyFa5Wjeu6fZmXSl840CA07aXbk9vN4I81WmJyblD/ZA=="
|
||||||
|
PrivateKey = `
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEowIBAAKCAQEAgUElV5mwqkloIrM8ZNZ72gSCcnSJt7+/Usa5G+D15YQUAdf9
|
||||||
|
c1zEekTfHgDP+04nw/uFNFaE5v1RbHaPxhZYVg5ZErNCa/hzn+x10xzcepeS3KPV
|
||||||
|
Xcxae4MR0BEegvqZqJzN9loXsNL/c3H/B+2Gle3hTxjlWFb3F5qLgR+4Mf4ruhER
|
||||||
|
1v6eHQa/nchi03MBpT4UeJ7MrL92hTJYLdpSyCqmr8yjxkKJDVC2uRrr+sTSxfh7
|
||||||
|
r6v24u/vp/QTmBIAlNPgadVAZw17iNNb7vjV7Gwl/5gHXonCUKURaV++dBNLrHIZ
|
||||||
|
pqcAM8wHRph8mD1EfL9hsz77pHewxolBATV+7QIDAQABAoIBAC1rK+kFW3vrAYm3
|
||||||
|
+8/fQnQQw5nec4o6+crng6JVQXLeH32qXShNf8kLLG/Jj0vaYcTPPDZw9JCKkTMQ
|
||||||
|
0mKj9XR/5DLbBMsV6eNXXuvJJ3x4iKW5eD9WkLD4FKlNarBRyO7j8sfPTqXW7uat
|
||||||
|
NxWdFH7YsSRvNh/9pyQHLWA5OituidMrYbc3EUx8B1GPNyJ9W8Q8znNYLfwYOjU4
|
||||||
|
Wv1SLE6qGQQH9Q0WzA2WUf8jklCYyMYTIywAjGb8kbAJlKhmj2t2Igjmqtwt1PYc
|
||||||
|
pGlqbtQBDUiWXt5S4YX/1maIQ/49yeNUajjpbJiH3DbhJbHwFTzP3pZ9P9GHOzlG
|
||||||
|
kYR+wSECgYEAw/Xida8kSv8n86V3qSY/I+fYQ5V+jDtXIE+JhRnS8xzbOzz3v0WS
|
||||||
|
Oo5H+o4nJx5eL3Ghb3Gcm0Jn46dHrxinHbm+3RjXv/X6tlbxIYjRSQfHOTSMCTvd
|
||||||
|
qcliF5vC6RCLXuc7R+IWR1Ky6eDEZGtrvt3DyeYABsp9fRUFR/6NluUCgYEAqNsw
|
||||||
|
1aSl7WJa27F0DoJdlU9LWerpXcazlJcIdOz/S9QDmSK3RDQTdqfTxRmrxiYI9LEs
|
||||||
|
mkOkvzlnnOBMpnZ3ZOU5qIRfprecRIi37KDAOHWGnlC0EWGgl46YLb7/jXiWf0AG
|
||||||
|
Y+DfJJNd9i6TbIDWu8254/erAS6bKMhW/3q7f2kCgYAZ7Id/BiKJAWRpqTRBXlvw
|
||||||
|
BhXoKvjI2HjYP21z/EyZ+PFPzur/lNaZhIUlMnUfibbwE9pFggQzzf8scM7c7Sf+
|
||||||
|
mLoVSdoQ/Rujz7CqvQzi2nKSsM7t0curUIb3lJWee5/UeEaxZcmIufoNUrzohAWH
|
||||||
|
BJOIPDM4ssUTLRq7wYM9uQKBgHCBau5OP8gE6mjKuXsZXWUoahpFLKwwwmJUp2vQ
|
||||||
|
pOFPJ/6WZOlqkTVT6QPAcPUbTohKrF80hsZqZyDdSfT3peFx4ZLocBrS56m6NmHR
|
||||||
|
UYHMvJ8rQm76T1fryHVidz85g3zRmfBeWg8yqT5oFg4LYgfLsPm1gRjOhs8LfPvI
|
||||||
|
OLlRAoGBAIZ5Uv4Z3s8O7WKXXUe/lq6j7vfiVkR1NW/Z/WLKXZpnmvJ7FgxN4e56
|
||||||
|
RXT7GwNQHIY8eDjDnsHxzrxd+raOxOZeKcMHj3XyjCX3NHfTscnsBPAGYpY/Wxzh
|
||||||
|
T8UYnFu6RzkixElTf2rseEav7rkdKkI3LAeIZy7B0HulKKsmqVQ7
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
`
|
||||||
|
WrongPrivateKey = `
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEowIBAAKCAQEAlrCgnEVgmNKCq7KPc+zUU5IrxPu1ClMNJS7RTsTPEkbwe5SB
|
||||||
|
p+6V6WtCbD/X/lDRRGbOENChh1Phulb7lViqgrdpHydgsrKoS5ah3DfSIxLFLE00
|
||||||
|
9Yo4TCYwgw6+s59j16ZAFVinaQ9l6Kmrb2ll136hMrz8QKh+qw+onOLd38WFgm+W
|
||||||
|
ZtUqSXf2LANzfzzy4OWFNyFqKaCAolSkPdTS9Nz+svtScvp002DQp8OdP1AgPO+l
|
||||||
|
o5N3M38Fftapwg0pCtJ5Zq0NRWIXEonXiTEMA6zy3gEZVOmDxoIFUWnmrqlMJLFy
|
||||||
|
5S6LDrHSdqJhCxDK6WRZj43X9j8spktk3eGhMwIDAQABAoIBAAem8ID/BOi9x+Tw
|
||||||
|
LFi2rhGQWqimH4tmrEQ3HGnjlKBY+d1MrUjZ1MMFr1nP5CgF8pqGnfA8p/c3Sz8r
|
||||||
|
K5tp5T6+EZiDZ2WrrOApxg5ox0MAsQKO6SGO40z6o3wEQ6rbbTaGOrraxaWQIpyu
|
||||||
|
AQanU4Sd6ZGqByVBaS1GnklZO+shCHqw73b7g1cpLEmFzcYnKHYHlUUIsstMe8E1
|
||||||
|
BaCY0CH7JbWBjcbiTnBVwIRZuu+EjGiQuhTilYL2OWqoMVg1WU0L2IFpR8lkf/2W
|
||||||
|
SBx5J6xhwbBGASOpM+qidiN580GdPzGhWYSqKGroHEzBm6xPSmV1tadNA26WFG4p
|
||||||
|
pthLiAECgYEA5BsPRpNYJAQLu5B0N7mj9eEp0HABVEgL/MpwiImjaKdAwp78HM64
|
||||||
|
IuPvJxs7r+xESiIz4JyjR8zrQjYOCKJsARYkmNlEuAz0SkHabCw1BdEBwUhjUGVB
|
||||||
|
efoERK6GxfAoNqmSDwsOvHFOtsmDIlbHmg7G2rUxNVpeou415BSB0B8CgYEAqR4J
|
||||||
|
YHKk2Ibr9rU+rBU33TcdTGw0aAkFNAVeqM9j0haWuFXmV3RArgoy09lH+2Ha6z/g
|
||||||
|
fTX2xSDAWV7QUlLOlBRIhurPAo2jO2yCrGHPZcWiugstrR2hTTInigaSnCmK3i7F
|
||||||
|
6sYmL3S7K01IcVNxSlWvGijtClT92Cl2WUCTfG0CgYAiEjyk4QtQTd5mxLvnOu5X
|
||||||
|
oqs5PBGmwiAwQRiv/EcRMbJFn7Oupd3xMDSflbzDmTnWDOfMy/jDl8MoH6TW+1PA
|
||||||
|
kcsjnYhbKWwvz0hN0giVdtOZSDO1ZXpzOrn6fEsbM7T9/TQY1SD9WrtUKCNTNL0Z
|
||||||
|
sM1ZC6lu+7GZCpW4HKwLJwKBgQCRT0yxQXBg1/UxwuO5ynV4rx2Oh76z0WRWIXMH
|
||||||
|
S0MyxdP1SWGkrS/SGtM3cg/GcHtA/V6vV0nUcWK0p6IJyjrTw2XZ/zGluPuTWJYi
|
||||||
|
9dvVT26Vunshrz7kbH7KuwEICy3V4IyQQHeY+QzFlR70uMS0IVFWAepCoWqHbIDT
|
||||||
|
CYhwNQKBgGPcLXmjpGtkZvggl0aZr9LsvCTckllSCFSI861kivL/rijdNoCHGxZv
|
||||||
|
dfDkLTLcz9Gk41rD9Gxn/3sqodnTAc3Z2PxFnzg1Q/u3+x6YAgBwI/g/jE2xutGW
|
||||||
|
H7CurtMwALQ/n/6LUKFmjRZjqbKX9SO2QSaC3grd6sY9Tu+bZjLe
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
`
|
||||||
|
)
|
||||||
|
|
|
@ -46,19 +46,17 @@ var TimeAddFunc = function.New(&function.Spec{
|
||||||
// Timestamp returns a string representation of the current date and time.
|
// Timestamp returns a string representation of the current date and time.
|
||||||
//
|
//
|
||||||
// In the Terraform language, timestamps are conventionally represented as
|
// In the Terraform language, timestamps are conventionally represented as
|
||||||
// strings using [RFC 3339](https://tools.ietf.org/html/rfc3339)
|
// strings using RFC 3339 "Date and Time format" syntax, and so timestamp
|
||||||
// "Date and Time format" syntax, and so `timestamp` returns a string
|
// returns a string in this format.
|
||||||
// in this format.
|
|
||||||
func Timestamp() (cty.Value, error) {
|
func Timestamp() (cty.Value, error) {
|
||||||
return TimestampFunc.Call([]cty.Value{})
|
return TimestampFunc.Call([]cty.Value{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Timeadd adds a duration to a timestamp, returning a new timestamp.
|
// TimeAdd adds a duration to a timestamp, returning a new timestamp.
|
||||||
//
|
//
|
||||||
// In the Terraform language, timestamps are conventionally represented as
|
// In the Terraform language, timestamps are conventionally represented as
|
||||||
// strings using [RFC 3339](https://tools.ietf.org/html/rfc3339)
|
// strings using RFC 3339 "Date and Time format" syntax. Timeadd requires
|
||||||
// "Date and Time format" syntax. `timeadd` requires the `timestamp` argument
|
// the timestamp argument to be a string conforming to this syntax.
|
||||||
// to be a string conforming to this syntax.
|
|
||||||
//
|
//
|
||||||
// `duration` is a string representation of a time difference, consisting of
|
// `duration` is a string representation of a time difference, consisting of
|
||||||
// sequences of number and unit pairs, like `"1.5h"` or `1h30m`. The accepted
|
// sequences of number and unit pairs, like `"1.5h"` or `1h30m`. The accepted
|
||||||
|
|
|
@ -73,10 +73,8 @@ func TestTimeadd(t *testing.T) {
|
||||||
t.Fatal("succeeded; want error")
|
t.Fatal("succeeded; want error")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
} else {
|
} else if err != nil {
|
||||||
if err != nil {
|
t.Fatalf("unexpected error: %s", err)
|
||||||
t.Fatalf("unexpected error: %s", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !got.RawEquals(test.Want) {
|
if !got.RawEquals(test.Want) {
|
||||||
|
|
|
@ -89,8 +89,7 @@ var URLEncodeFunc = function.New(&function.Spec{
|
||||||
|
|
||||||
// Base64Decode decodes a string containing a base64 sequence.
|
// Base64Decode decodes a string containing a base64 sequence.
|
||||||
//
|
//
|
||||||
// Terraform uses the "standard" Base64 alphabet as defined in
|
// Terraform uses the "standard" Base64 alphabet as defined in RFC 4648 section 4.
|
||||||
// [RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4).
|
|
||||||
//
|
//
|
||||||
// Strings in the Terraform language are sequences of unicode characters rather
|
// Strings in the Terraform language are sequences of unicode characters rather
|
||||||
// than bytes, so this function will also interpret the resulting bytes as
|
// than bytes, so this function will also interpret the resulting bytes as
|
||||||
|
@ -102,8 +101,7 @@ func Base64Decode(str cty.Value) (cty.Value, error) {
|
||||||
|
|
||||||
// Base64Encode applies Base64 encoding to a string.
|
// Base64Encode applies Base64 encoding to a string.
|
||||||
//
|
//
|
||||||
// Terraform uses the "standard" Base64 alphabet as defined in
|
// Terraform uses the "standard" Base64 alphabet as defined in RFC 4648 section 4.
|
||||||
// [RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4).
|
|
||||||
//
|
//
|
||||||
// Strings in the Terraform language are sequences of unicode characters rather
|
// Strings in the Terraform language are sequences of unicode characters rather
|
||||||
// than bytes, so this function will first encode the characters from the string
|
// than bytes, so this function will first encode the characters from the string
|
||||||
|
@ -112,11 +110,11 @@ func Base64Encode(str cty.Value) (cty.Value, error) {
|
||||||
return Base64EncodeFunc.Call([]cty.Value{str})
|
return Base64EncodeFunc.Call([]cty.Value{str})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base64gzip compresses a string with gzip and then encodes the result in
|
// Base64Gzip compresses a string with gzip and then encodes the result in
|
||||||
// Base64 encoding.
|
// Base64 encoding.
|
||||||
//
|
//
|
||||||
// Terraform uses the "standard" Base64 alphabet as defined in
|
// Terraform uses the "standard" Base64 alphabet as defined in RFC 4648 section 4.
|
||||||
// [RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4)
|
//
|
||||||
// Strings in the Terraform language are sequences of unicode characters rather
|
// Strings in the Terraform language are sequences of unicode characters rather
|
||||||
// than bytes, so this function will first encode the characters from the string
|
// 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.
|
// as UTF-8, then apply gzip compression, and then finally apply Base64 encoding.
|
||||||
|
@ -124,12 +122,11 @@ func Base64Gzip(str cty.Value) (cty.Value, error) {
|
||||||
return Base64GzipFunc.Call([]cty.Value{str})
|
return Base64GzipFunc.Call([]cty.Value{str})
|
||||||
}
|
}
|
||||||
|
|
||||||
// UrlEncode applies URL encoding to a given string.
|
// URLEncode applies URL encoding to a given string.
|
||||||
//
|
//
|
||||||
// This function identifies characters in the given string that would have a
|
// This function identifies characters in the given string that would have a
|
||||||
// special meaning when included as a query string argument in a URL and
|
// special meaning when included as a query string argument in a URL and
|
||||||
// escapes them using
|
// escapes them using RFC 3986 "percent encoding".
|
||||||
// [RFC 3986 "percent encoding"](https://tools.ietf.org/html/rfc3986#section-2.1).
|
|
||||||
//
|
//
|
||||||
// If the given string contains non-ASCII characters, these are first encoded as
|
// If the given string contains non-ASCII characters, these are first encoded as
|
||||||
// UTF-8 and then percent encoding is applied separately to each UTF-8 byte.
|
// UTF-8 and then percent encoding is applied separately to each UTF-8 byte.
|
||||||
|
|
|
@ -34,10 +34,8 @@ func TestBase64Decode(t *testing.T) {
|
||||||
t.Fatal("succeeded; want error")
|
t.Fatal("succeeded; want error")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
} else {
|
} else if err != nil {
|
||||||
if err != nil {
|
t.Fatalf("unexpected error: %s", err)
|
||||||
t.Fatalf("unexpected error: %s", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !got.RawEquals(test.Want) {
|
if !got.RawEquals(test.Want) {
|
||||||
|
@ -69,10 +67,8 @@ func TestBase64Encode(t *testing.T) {
|
||||||
t.Fatal("succeeded; want error")
|
t.Fatal("succeeded; want error")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
} else {
|
} else if err != nil {
|
||||||
if err != nil {
|
t.Fatalf("unexpected error: %s", err)
|
||||||
t.Fatalf("unexpected error: %s", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !got.RawEquals(test.Want) {
|
if !got.RawEquals(test.Want) {
|
||||||
|
@ -104,10 +100,8 @@ func TestBase64Gzip(t *testing.T) {
|
||||||
t.Fatal("succeeded; want error")
|
t.Fatal("succeeded; want error")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
} else {
|
} else if err != nil {
|
||||||
if err != nil {
|
t.Fatalf("unexpected error: %s", err)
|
||||||
t.Fatalf("unexpected error: %s", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !got.RawEquals(test.Want) {
|
if !got.RawEquals(test.Want) {
|
||||||
|
@ -154,10 +148,8 @@ func TestURLEncode(t *testing.T) {
|
||||||
t.Fatal("succeeded; want error")
|
t.Fatal("succeeded; want error")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
} else {
|
} else if err != nil {
|
||||||
if err != nil {
|
t.Fatalf("unexpected error: %s", err)
|
||||||
t.Fatalf("unexpected error: %s", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !got.RawEquals(test.Want) {
|
if !got.RawEquals(test.Want) {
|
||||||
|
|
|
@ -63,7 +63,8 @@ func MakeFileFunc(baseDir string, encBase64 bool) function.Function {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// BasenameFunc constructs a function that takes a string containing a filesystem path and removes all except the last portion from it.
|
// BasenameFunc constructs a function that takes a string containing a filesystem path
|
||||||
|
// and removes all except the last portion from it.
|
||||||
var BasenameFunc = function.New(&function.Spec{
|
var BasenameFunc = function.New(&function.Spec{
|
||||||
Params: []function.Parameter{
|
Params: []function.Parameter{
|
||||||
{
|
{
|
||||||
|
@ -77,7 +78,8 @@ var BasenameFunc = function.New(&function.Spec{
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// DirnameFunc constructs a function that takes a string containing a filesystem path and removes the last portion from it.
|
// DirnameFunc constructs a function that takes a string containing a filesystem path
|
||||||
|
// and removes the last portion from it.
|
||||||
var DirnameFunc = function.New(&function.Spec{
|
var DirnameFunc = function.New(&function.Spec{
|
||||||
Params: []function.Parameter{
|
Params: []function.Parameter{
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,10 +41,8 @@ func TestFile(t *testing.T) {
|
||||||
t.Fatal("succeeded; want error")
|
t.Fatal("succeeded; want error")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
} else {
|
} else if err != nil {
|
||||||
if err != nil {
|
t.Fatalf("unexpected error: %s", err)
|
||||||
t.Fatalf("unexpected error: %s", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !got.RawEquals(test.Want) {
|
if !got.RawEquals(test.Want) {
|
||||||
|
@ -86,10 +84,8 @@ func TestFileBase64(t *testing.T) {
|
||||||
t.Fatal("succeeded; want error")
|
t.Fatal("succeeded; want error")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
} else {
|
} else if err != nil {
|
||||||
if err != nil {
|
t.Fatalf("unexpected error: %s", err)
|
||||||
t.Fatalf("unexpected error: %s", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !got.RawEquals(test.Want) {
|
if !got.RawEquals(test.Want) {
|
||||||
|
@ -131,10 +127,8 @@ func TestBasename(t *testing.T) {
|
||||||
t.Fatal("succeeded; want error")
|
t.Fatal("succeeded; want error")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
} else {
|
} else if err != nil {
|
||||||
if err != nil {
|
t.Fatalf("unexpected error: %s", err)
|
||||||
t.Fatalf("unexpected error: %s", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !got.RawEquals(test.Want) {
|
if !got.RawEquals(test.Want) {
|
||||||
|
@ -181,10 +175,8 @@ func TestDirname(t *testing.T) {
|
||||||
t.Fatal("succeeded; want error")
|
t.Fatal("succeeded; want error")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
} else {
|
} else if err != nil {
|
||||||
if err != nil {
|
t.Fatalf("unexpected error: %s", err)
|
||||||
t.Fatalf("unexpected error: %s", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !got.RawEquals(test.Want) {
|
if !got.RawEquals(test.Want) {
|
||||||
|
@ -236,10 +228,8 @@ func TestPathExpand(t *testing.T) {
|
||||||
t.Fatal("succeeded; want error")
|
t.Fatal("succeeded; want error")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
} else {
|
} else if err != nil {
|
||||||
if err != nil {
|
t.Fatalf("unexpected error: %s", err)
|
||||||
t.Fatalf("unexpected error: %s", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !got.RawEquals(test.Want) {
|
if !got.RawEquals(test.Want) {
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var impureFunctions = []string{
|
var impureFunctions = []string{
|
||||||
|
"bcrypt",
|
||||||
"timestamp",
|
"timestamp",
|
||||||
"uuid",
|
"uuid",
|
||||||
}
|
}
|
||||||
|
@ -71,13 +72,13 @@ func (s *Scope) Functions() map[string]function.Function {
|
||||||
"lower": stdlib.LowerFunc,
|
"lower": stdlib.LowerFunc,
|
||||||
"map": unimplFunc, // TODO
|
"map": unimplFunc, // TODO
|
||||||
"max": stdlib.MaxFunc,
|
"max": stdlib.MaxFunc,
|
||||||
"md5": unimplFunc, // TODO
|
"md5": funcs.Md5Func,
|
||||||
"merge": unimplFunc, // TODO
|
"merge": unimplFunc, // TODO
|
||||||
"min": stdlib.MinFunc,
|
"min": stdlib.MinFunc,
|
||||||
"pathexpand": funcs.PathExpandFunc,
|
"pathexpand": funcs.PathExpandFunc,
|
||||||
"pow": unimplFunc, // TODO
|
"pow": unimplFunc, // TODO
|
||||||
"replace": unimplFunc, // TODO
|
"replace": unimplFunc, // TODO
|
||||||
"rsadecrypt": unimplFunc, // TODO
|
"rsadecrypt": funcs.RsaDecryptFunc,
|
||||||
"sha1": unimplFunc, // TODO
|
"sha1": unimplFunc, // TODO
|
||||||
"sha256": unimplFunc, // TODO
|
"sha256": unimplFunc, // TODO
|
||||||
"sha512": unimplFunc, // TODO
|
"sha512": unimplFunc, // TODO
|
||||||
|
@ -92,7 +93,7 @@ func (s *Scope) Functions() map[string]function.Function {
|
||||||
"transpose": unimplFunc, // TODO
|
"transpose": unimplFunc, // TODO
|
||||||
"trimspace": unimplFunc, // TODO
|
"trimspace": unimplFunc, // TODO
|
||||||
"upper": stdlib.UpperFunc,
|
"upper": stdlib.UpperFunc,
|
||||||
"urlencode": funcs.UrlEncodeFunc,
|
"urlencode": funcs.URLEncodeFunc,
|
||||||
"uuid": funcs.UUIDFunc,
|
"uuid": funcs.UUIDFunc,
|
||||||
"values": unimplFunc, // TODO
|
"values": unimplFunc, // TODO
|
||||||
"zipmap": unimplFunc, // TODO
|
"zipmap": unimplFunc, // TODO
|
||||||
|
|
Loading…
Reference in New Issue