feat: add variable support

This commit is contained in:
Andrew Woodlee 2025-03-16 23:42:54 -05:00
parent cd5f7611a9
commit 5f40713e98
3 changed files with 47 additions and 5 deletions

View File

@ -103,6 +103,12 @@ func (opts *ConfigOpts) ReadConfig() *ConfigOpts {
backyKoanf := opts.koanf
if backyKoanf.Exists("variables") {
unmarshalConfig(backyKoanf, "variables", &opts.Vars, opts.Logger)
}
getConfigDir(opts)
opts.loadEnv()
if backyKoanf.Bool(getNestedConfig("logging", "cmd-std-out")) {
@ -137,6 +143,11 @@ func (opts *ConfigOpts) ReadConfig() *ConfigOpts {
resolveHostConfigs(opts)
for k, v := range opts.Vars {
v = getExternalConfigDirectiveValue(v, opts)
opts.Vars[k] = v
}
loadCommandLists(opts, backyKoanf)
validateCommandLists(opts)
@ -282,16 +293,22 @@ func resolveProxyHosts(host *Host, opts *ConfigOpts) {
}
}
func getConfigDir(opts *ConfigOpts) {
if isRemoteURL(opts.ConfigFilePath) {
p, _ := getRemoteDir(opts.ConfigFilePath)
opts.ConfigDir = p
} else {
opts.ConfigDir = path.Dir(opts.ConfigFilePath)
}
}
func loadCommandLists(opts *ConfigOpts, backyKoanf *koanf.Koanf) {
var listConfigFiles []string
var u *url.URL
var p string
// if config file is remote, use the directory of the remote file
if isRemoteURL(opts.ConfigFilePath) {
p, u = getRemoteDir(opts.ConfigFilePath)
opts.ConfigDir = p
println(p)
// // Still use local list files if a remote config file is used, but use them last
listConfigFiles = []string{u.JoinPath("lists.yml").String(), u.JoinPath("lists.yaml").String()}
} else {
opts.ConfigDir = path.Dir(opts.ConfigFilePath)
@ -479,7 +496,10 @@ func processCmds(opts *ConfigOpts) error {
// process commands
for cmdName, cmd := range opts.Cmds {
for i, v := range cmd.Args {
v = replaceVarInString(opts.Vars, v, opts.Logger)
cmd.Args[i] = v
}
if cmd.Name == "" {
cmd.Name = cmdName
}
@ -504,6 +524,10 @@ func processCmds(opts *ConfigOpts) error {
// resolve hosts
if cmd.Host != nil {
cmdHost := replaceVarInString(opts.Vars, *cmd.Host, opts.Logger)
if cmdHost != *cmd.Host {
cmd.Host = &cmdHost
}
host, hostFound := opts.Hosts[*cmd.Host]
if hostFound {
cmd.RemoteHost = host
@ -563,7 +587,7 @@ func processCmds(opts *ConfigOpts) error {
if cmd.Username == "" {
return fmt.Errorf("username is required for user command %s", cmd.Name)
}
cmd.Username = replaceVarInString(opts.Vars, cmd.Username, opts.Logger)
err := detectOSType(cmd, opts)
if err != nil {
opts.Logger.Info().Err(err).Str("command", cmdName).Send()
@ -689,3 +713,18 @@ func keyNotSupported(oldKey, newKey string, koanf *koanf.Koanf, opts *ConfigOpts
}
}
}
func replaceVarInString(vars map[string]string, str string, logger zerolog.Logger) string {
if strings.Contains(str, "%{var:") && strings.Contains(str, "}%") {
logger.Debug().Msgf("replacing vars in string %s", str)
for k, v := range vars {
if strings.Contains(str, "%{var:"+k+"}%") {
str = strings.ReplaceAll(str, "%{var:"+k+"}%", v)
}
}
if strings.Contains(str, "%{var:") && strings.Contains(str, "}%") {
logger.Warn().Msg("could not replace all vars in string")
}
}
return str
}

View File

@ -205,6 +205,8 @@ type (
List ListConfig
Vars map[string]string `yaml:"variables"`
VaultKeys []*VaultKey `yaml:"keys"`
koanf *koanf.Koanf

View File

@ -362,6 +362,7 @@ func getExternalConfigDirectiveValue(key string, opts *ConfigOpts) string {
if !(strings.HasPrefix(key, externDirectiveStart) && strings.HasSuffix(key, externDirectiveEnd)) {
return key
}
key = replaceVarInString(opts.Vars, key, opts.Logger)
opts.Logger.Debug().Str("expanding external key", key).Send()
if strings.HasPrefix(key, envExternDirectiveStart) {
key = strings.TrimPrefix(key, envExternDirectiveStart)