From fd2a37ca9791fdae19bdfd6ca0c76e9410e2541a Mon Sep 17 00:00:00 2001 From: Knut Ahlers Date: Thu, 29 Feb 2024 17:55:20 +0100 Subject: [PATCH] Remove default values for `file` and `vault` and add `must*` variants for them Signed-off-by: Knut Ahlers --- README.md | 8 +++--- functions/func_file.go | 28 ++++++++++++-------- functions/func_vault.go | 58 +++++++++++++++++++++++------------------ 3 files changed, 53 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 2e78dac..31b4ddb 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,8 @@ Starting with `v1.0.0` Korvike is based on the [sprig functions collection](http $ echo "{{ .foo }}" | korvike -v foo=bar bar ``` -- `{{ file [default value] }}` - Read a file and place it inside the template +- `{{ file }}` / `{{ mustFile }}` + Read a file and place it inside the template, `file` returns an empty string on error, `mustFile` an error ```console $ echo "Hello World" > hello $ echo '{{ file "hello" }}' | korvike @@ -43,8 +43,8 @@ Starting with `v1.0.0` Korvike is based on the [sprig functions collection](http $ echo '{{ urlescape "Hellö Wörld@Golang" }}' | korvike Hell%C3%B6+W%C3%B6rld%40Golang ``` -- `{{ vault [default value] }}` - Read a key from Vault using `VAULT_ADDR` and `VAULT_TOKEN` environment variables (or `~/.vault-token` file) for authentication. +- `{{ vault }}` / `{{ mustVault }}` + Read a key from Vault using `VAULT_ADDR` and `VAULT_TOKEN` environment variables (or `~/.vault-token` file) for authentication. `vault` returns an empty string on error, `mustVault` an error ```console $ vault write secret/test foo=bar $ echo '{{ vault "secret/test" "foo" }}' | korvike diff --git a/functions/func_file.go b/functions/func_file.go index 7c393b0..fb6e490 100644 --- a/functions/func_file.go +++ b/functions/func_file.go @@ -1,21 +1,27 @@ package functions import ( + "fmt" "os" ) func init() { - registerFunction("file", func(name string, v ...string) string { - defaultValue := "" - if len(v) > 0 { - defaultValue = v[0] + registerFunction("file", func(name string) string { + fc, err := tplReadFile(name) + if err != nil { + return "" } - if _, err := os.Stat(name); err == nil { - //#nosec:G304 // Intended to load custom file - if rawValue, err := os.ReadFile(name); err == nil { - return string(rawValue) - } - } - return defaultValue + return fc }) + + registerFunction("mustFile", tplReadFile) +} + +func tplReadFile(name string) (string, error) { + rawValue, err := os.ReadFile(name) //#nosec:G304 // Intended to load custom file + if err != nil { + return "", fmt.Errorf("reading file: %w", err) + } + + return string(rawValue), nil } diff --git a/functions/func_vault.go b/functions/func_vault.go index d53885c..47c6635 100644 --- a/functions/func_vault.go +++ b/functions/func_vault.go @@ -10,38 +10,44 @@ import ( ) func init() { - registerFunction("vault", func(name string, v ...string) (interface{}, error) { - if name == "" { - return nil, fmt.Errorf("path is not set") - } - if len(v) < 1 { - return nil, fmt.Errorf("key is not set") - } + registerFunction("mustVault", tplVaultKeyFetch) - client, err := vaultClientFromEnvOrFile() + registerFunction("vault", func(name string, key string) string { + v, err := tplVaultKeyFetch(name, key) if err != nil { - return nil, err + return "" } - - secret, err := client.Logical().Read(name) - if err != nil { - return nil, fmt.Errorf("reading secret: %s", err) - } - - if secret != nil && secret.Data != nil { - if val, ok := secret.Data[v[0]]; ok { - return val, nil - } - } - - if len(v) < 2 { //nolint:gomnd - return nil, fmt.Errorf("requested value %q in key %q was not found in Vault and no default was set", v[0], name) - } - - return v[1], nil + return v }) } +func tplVaultKeyFetch(name string, key string) (string, error) { + if name == "" { + return "", fmt.Errorf("path is not set") + } + if key == "" { + return "", fmt.Errorf("key is not set") + } + + client, err := vaultClientFromEnvOrFile() + if err != nil { + return "", err + } + + secret, err := client.Logical().Read(name) + if err != nil { + return "", fmt.Errorf("reading secret: %s", err) + } + + if secret != nil && secret.Data != nil { + if val, ok := secret.Data[key].(string); ok { + return val, nil + } + } + + return "", fmt.Errorf("requested value %q in key %q was not found in Vault and no default was set", key, name) +} + func vaultClientFromEnvOrFile() (*api.Client, error) { client, err := api.NewClient(&api.Config{ Address: os.Getenv(api.EnvVaultAddress),