diff --git a/internal/hook/hook.go b/internal/hook/hook.go index 0510095..0347f26 100644 --- a/internal/hook/hook.go +++ b/internal/hook/hook.go @@ -13,12 +13,12 @@ import ( "errors" "fmt" "hash" - "io/ioutil" "log" "math" "net" "net/textproto" "os" + "path" "reflect" "regexp" "strconv" @@ -750,14 +750,18 @@ func (h *Hooks) LoadFromFile(path string, asTemplate bool) error { } // parse hook file for hooks - file, e := ioutil.ReadFile(path) + file, e := os.ReadFile(path) if e != nil { return e } if asTemplate { - funcMap := template.FuncMap{"getenv": getenv} + funcMap := template.FuncMap{ + "cat": cat, + "credential": credential, + "getenv": getenv, + } tmpl, err := template.New("hooks").Funcs(funcMap).Parse(string(file)) if err != nil { @@ -956,3 +960,27 @@ func compare(a, b string) bool { func getenv(s string) string { return os.Getenv(s) } + +// cat provides a template function to retrieve content of files +// Similarly to getenv, if no file is found, it returns the empty string +func cat(s string) string { + data, e := os.ReadFile(s) + + if e != nil { + return "" + } + + return strings.TrimSuffix(string(data), "\n") +} + +// credential provides a template function to retreive secrets using systemd's LoadCredential mechanism +func credential(s string) string { + dir := getenv("CREDENTIALS_DIRECTORY") + + // If no credential directory is found, fallback to the env variable + if dir == "" { + return getenv(s) + } + + return cat(path.Join(dir, s)) +}