mirror of
https://github.com/Luzifer/korvike.git
synced 2025-01-04 18:26:05 +00:00
Compare commits
2 commits
3354a29311
...
2cc2bee14a
Author | SHA1 | Date | |
---|---|---|---|
2cc2bee14a | |||
fd2a37ca97 |
4 changed files with 71 additions and 43 deletions
18
History.md
18
History.md
|
@ -1,3 +1,19 @@
|
||||||
|
# 1.0.0 / 2024-02-29
|
||||||
|
|
||||||
|
* Breaking: Add sprig functions, replace some internal ones
|
||||||
|
* Replace old build-system
|
||||||
|
|
||||||
|
**Breaking changes:**
|
||||||
|
|
||||||
|
- Function `env` no longer takes a default, use `env "MYVAR" | default "..."`
|
||||||
|
- Function `file` no longer takes a default, use `file "[filename]" | default "..."`
|
||||||
|
- Function `now` returns `time.Time`, use `now | date "[format]"`
|
||||||
|
- Function `split` now has reversed parameters `split <sep> <str>`
|
||||||
|
- Function `vault` no longet takes a default, use `vault "key" "field" | default "..."`
|
||||||
|
- Removed function `b64decode`, use `b64dec`
|
||||||
|
- Removed function `b64encode`, use `b64enc`
|
||||||
|
- Removed function `hash`, use `sha1sum` / `sha256sum` / `sha512sum`
|
||||||
|
|
||||||
# 0.13.0 / 2022-03-30
|
# 0.13.0 / 2022-03-30
|
||||||
|
|
||||||
* Add basic string manipulation `join` and `split`
|
* Add basic string manipulation `join` and `split`
|
||||||
|
@ -79,4 +95,4 @@
|
||||||
|
|
||||||
# 0.1.0 / 2016-07-31
|
# 0.1.0 / 2016-07-31
|
||||||
|
|
||||||
* initial version
|
* initial version
|
||||||
|
|
10
README.md
10
README.md
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
# Luzifer / korvike
|
# Luzifer / korvike
|
||||||
|
|
||||||
`korvike` is the finnish translation to the word "replacer" and that is what it does: It takes a Go template and executes it.
|
`korvike` is the Finnish translation to the word "replacer" and that is what it does: It takes a Go template and executes it.
|
||||||
|
|
||||||
## Available functions
|
## Available functions
|
||||||
|
|
||||||
|
@ -16,8 +16,8 @@ Starting with `v1.0.0` Korvike is based on the [sprig functions collection](http
|
||||||
$ echo "{{ .foo }}" | korvike -v foo=bar
|
$ echo "{{ .foo }}" | korvike -v foo=bar
|
||||||
bar
|
bar
|
||||||
```
|
```
|
||||||
- `{{ file <file name> [default value] }}`
|
- `{{ file <file name> }}` / `{{ mustFile <file name> }}`
|
||||||
Read a file and place it inside the template
|
Read a file and place it inside the template, `file` returns an empty string on error, `mustFile` an error
|
||||||
```console
|
```console
|
||||||
$ echo "Hello World" > hello
|
$ echo "Hello World" > hello
|
||||||
$ echo '{{ file "hello" }}' | korvike
|
$ 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
|
$ echo '{{ urlescape "Hellö Wörld@Golang" }}' | korvike
|
||||||
Hell%C3%B6+W%C3%B6rld%40Golang
|
Hell%C3%B6+W%C3%B6rld%40Golang
|
||||||
```
|
```
|
||||||
- `{{ vault <path> <key> [default value] }}`
|
- `{{ vault <path> <key> }}` / `{{ mustVault <path> <key> }}`
|
||||||
Read a key from Vault using `VAULT_ADDR` and `VAULT_TOKEN` environment variables (or `~/.vault-token` file) for authentication.
|
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
|
```console
|
||||||
$ vault write secret/test foo=bar
|
$ vault write secret/test foo=bar
|
||||||
$ echo '{{ vault "secret/test" "foo" }}' | korvike
|
$ echo '{{ vault "secret/test" "foo" }}' | korvike
|
||||||
|
|
|
@ -1,21 +1,27 @@
|
||||||
package functions
|
package functions
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
registerFunction("file", func(name string, v ...string) string {
|
registerFunction("file", func(name string) string {
|
||||||
defaultValue := ""
|
fc, err := tplReadFile(name)
|
||||||
if len(v) > 0 {
|
if err != nil {
|
||||||
defaultValue = v[0]
|
return ""
|
||||||
}
|
}
|
||||||
if _, err := os.Stat(name); err == nil {
|
return fc
|
||||||
//#nosec:G304 // Intended to load custom file
|
|
||||||
if rawValue, err := os.ReadFile(name); err == nil {
|
|
||||||
return string(rawValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return defaultValue
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,38 +10,44 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
registerFunction("vault", func(name string, v ...string) (interface{}, error) {
|
registerFunction("mustVault", tplVaultKeyFetch)
|
||||||
if name == "" {
|
|
||||||
return nil, fmt.Errorf("path is not set")
|
|
||||||
}
|
|
||||||
if len(v) < 1 {
|
|
||||||
return nil, fmt.Errorf("key is not set")
|
|
||||||
}
|
|
||||||
|
|
||||||
client, err := vaultClientFromEnvOrFile()
|
registerFunction("vault", func(name string, key string) string {
|
||||||
|
v, err := tplVaultKeyFetch(name, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return ""
|
||||||
}
|
}
|
||||||
|
return v
|
||||||
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
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
func vaultClientFromEnvOrFile() (*api.Client, error) {
|
||||||
client, err := api.NewClient(&api.Config{
|
client, err := api.NewClient(&api.Config{
|
||||||
Address: os.Getenv(api.EnvVaultAddress),
|
Address: os.Getenv(api.EnvVaultAddress),
|
||||||
|
|
Loading…
Reference in a new issue