pkg/template/engine/funcs.go (114 lines of code) (raw):
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package engine
import (
"crypto/x509"
"encoding/base64"
"encoding/hex"
"encoding/json"
"net/url"
"strconv"
"strings"
"text/template"
"time"
"github.com/Masterminds/sprig/v3"
"github.com/alessio/shellescape"
"go.step.sm/crypto/pemutil"
"github.com/elastic/harp/pkg/sdk/security/crypto"
"github.com/elastic/harp/pkg/sdk/security/crypto/bech32"
"github.com/elastic/harp/pkg/sdk/security/diceware"
"github.com/elastic/harp/pkg/sdk/security/password"
"github.com/elastic/harp/pkg/template/engine/internal/codec"
)
// FuncMap returns a mapping of all of the functions that Temmplate has.
func FuncMap(secretReaders []SecretReaderFunc) template.FuncMap {
f := sprig.TxtFuncMap()
// Add some extra functionality
extra := template.FuncMap{
// Password
"customPassword": password.Generate,
"paranoidPassword": password.Paranoid,
"noSymbolPassword": password.NoSymbol,
"strongPassword": password.Strong,
// Diceware
"customDiceware": diceware.Diceware,
"basicDiceware": diceware.Basic,
"strongDiceware": diceware.Strong,
"paranoidDiceware": diceware.Paranoid,
// Encoder
"toToml": codec.ToTOML,
"toYaml": codec.ToYAML,
"fromYaml": codec.FromYAML,
"fromYamlArray": codec.FromYAMLArray,
"toJson": codec.ToJSON,
"fromJson": codec.FromJSON,
"fromJsonArray": codec.FromJSONArray,
// Crypto
"toJwk": crypto.ToJWK,
"fromJwk": crypto.FromJWK,
"toSSH": crypto.ToSSH,
"cryptoKey": crypto.Key,
"cryptoPair": crypto.Keypair,
"keyToBytes": crypto.KeyToBytes,
// Secret
"secret": SecretReaders(secretReaders),
// JWT/JWE
"encryptJwe": crypto.EncryptJWE,
"decryptJwe": crypto.DecryptJWE,
"toJws": crypto.ToJWS,
"parseJwt": crypto.ParseJWT,
"verifyJwt": crypto.VerifyJWT,
// Hex
"hexenc": hex.EncodeToString,
"hexdec": hex.DecodeString,
// Bech32
"bech32enc": bech32.Encode,
"bech32dec": crypto.Bech32Decode,
// Base64
"b64urlenc": func(in string) string {
return base64.URLEncoding.EncodeToString([]byte(in))
},
"b64urldec": func(in string) (string, error) {
out, err := base64.URLEncoding.DecodeString(in)
return string(out), err
},
// Escaping
"urlPathEscape": url.PathEscape,
"urlPathUnescape": url.PathUnescape,
"urlQueryEscape": url.QueryEscape,
"urlQueryUnescape": url.QueryUnescape,
"shellEscape": shellescape.Quote,
"jsonEscape": func(in string) (string, error) {
b, err := json.Marshal(in)
// Trim the beginning and trailing " character
return strings.Trim(string(b), `"`), err
},
"jsonUnescape": func(in string) (string, error) {
var out string
if err := json.Unmarshal([]byte(in), &out); err != nil {
return "", err
}
return out, nil
},
"unquote": strconv.Unquote,
// PEM
"toPem": crypto.ToPEM,
"encryptPem": crypto.EncryptPEM,
"parsePemCertificate": func(pemData string) (*x509.Certificate, error) {
return pemutil.ParseCertificate([]byte(pemData))
},
"parsePemCertificateBundle": func(pemData string) ([]*x509.Certificate, error) {
return pemutil.ParseCertificateBundle([]byte(pemData))
},
"parsePemCertificateRequest": func(pemData string) (*x509.CertificateRequest, error) {
return pemutil.ParseCertificateRequest([]byte(pemData))
},
"toTLSA": crypto.ToTLSA,
"isodate": func(date interface{}) string {
var t time.Time
switch date := date.(type) {
default:
t = time.Now()
case time.Time:
t = date
case *time.Time:
t = *date
case int64:
t = time.Unix(date, 0)
case int:
t = time.Unix(int64(date), 0)
case int32:
t = time.Unix(int64(date), 0)
}
return t.UTC().Format(time.RFC3339)
},
}
for k, v := range extra {
f[k] = v
}
return f
}