packer-cn/common/template/funcs.go

64 lines
1.7 KiB
Go

package template
import (
"errors"
"fmt"
"log"
"os"
"strings"
"sync"
vaultapi "github.com/hashicorp/vault/api"
)
// DeprecatedTemplateFunc wraps a template func to warn users that it's
// deprecated. The deprecation warning is called only once.
func DeprecatedTemplateFunc(funcName, useInstead string, deprecated func(string) string) func(string) string {
once := sync.Once{}
return func(in string) string {
once.Do(func() {
log.Printf("[WARN]: the `%s` template func is deprecated, please use %s instead",
funcName, useInstead)
})
return deprecated(in)
}
}
// Vault retrieves a secret from an HC vault KV store
func Vault(path string, key string) (string, error) {
if token := os.Getenv("VAULT_TOKEN"); token == "" {
return "", errors.New("Must set VAULT_TOKEN env var in order to use vault template function")
}
vaultConfig := vaultapi.DefaultConfig()
cli, err := vaultapi.NewClient(vaultConfig)
if err != nil {
return "", fmt.Errorf("Error getting Vault client: %s", err)
}
secret, err := cli.Logical().Read(path)
if err != nil {
return "", fmt.Errorf("Error reading vault secret: %s", err)
}
if secret == nil {
return "", errors.New("Vault Secret does not exist at the given path")
}
data, ok := secret.Data["data"]
if !ok {
// maybe ths is v1, not v2 kv store
value, ok := secret.Data[key]
if ok {
return value.(string), nil
}
// neither v1 nor v2 proudced a valid value
return "", fmt.Errorf("Vault data was empty at the given path. Warnings: %s", strings.Join(secret.Warnings, "; "))
}
if val, ok := data.(map[string]interface{})[key]; ok {
return val.(string), nil
}
return "", errors.New("Vault path does not contain the requested key")
}