Let operators manage ordered action groups on each host, run them manually or on a schedule over SSH, and inspect disk-backed JSON run logs from a node detail UI.
54 lines
1.3 KiB
Go
54 lines
1.3 KiB
Go
package auth
|
|
|
|
import (
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
var placeholderPattern = regexp.MustCompile(`\{\{\s*([a-zA-Z0-9_.]+)\s*\}\}`)
|
|
|
|
// PlaceholderContext holds values used to expand action body placeholders.
|
|
type PlaceholderContext struct {
|
|
Host string
|
|
IP string
|
|
Username string
|
|
Env map[string]string
|
|
Secrets map[string]string
|
|
}
|
|
|
|
// ExpandPlaceholders replaces {{cc.host}}, {{node.ip}}, {{env.NAME}}, etc.
|
|
// Unknown or unresolved secrets expand to empty strings.
|
|
func ExpandPlaceholders(body string, ctx PlaceholderContext) string {
|
|
return placeholderPattern.ReplaceAllStringFunc(body, func(match string) string {
|
|
submatches := placeholderPattern.FindStringSubmatch(match)
|
|
if len(submatches) < 2 {
|
|
return match
|
|
}
|
|
key := strings.TrimSpace(submatches[1])
|
|
switch key {
|
|
case "cc.host", "node.host":
|
|
return ctx.Host
|
|
case "cc.ip", "node.ip":
|
|
return ctx.IP
|
|
case "node.username":
|
|
return ctx.Username
|
|
default:
|
|
if strings.HasPrefix(key, "env.") {
|
|
name := strings.TrimPrefix(key, "env.")
|
|
if ctx.Env != nil {
|
|
return ctx.Env[name]
|
|
}
|
|
return ""
|
|
}
|
|
if strings.HasPrefix(key, "secret.") {
|
|
name := strings.TrimPrefix(key, "secret.")
|
|
if ctx.Secrets != nil {
|
|
return ctx.Secrets[name]
|
|
}
|
|
return ""
|
|
}
|
|
return ""
|
|
}
|
|
})
|
|
}
|