From 13ab859faf33271bd0620ad54e252feacbc3721e Mon Sep 17 00:00:00 2001 From: William Petit Date: Thu, 27 Jun 2024 14:59:28 +0200 Subject: [PATCH] fix: multiple environment variables interpolation in configuration file --- doc/README.md | 2 +- doc/fr/references/configuration.md | 34 ++++++++++++++++++++++++ internal/config/environment.go | 42 ++++++++++++++---------------- 3 files changed, 55 insertions(+), 23 deletions(-) create mode 100644 doc/fr/references/configuration.md diff --git a/doc/README.md b/doc/README.md index d52b4da..94926bf 100644 --- a/doc/README.md +++ b/doc/README.md @@ -12,7 +12,7 @@ - [(FR) - Layers](./fr/references/layers/README.md) - [(FR) - Métriques](./fr/references/metrics.md) -- [(FR) - Fichier de configuration](../misc/packaging/common/config.yml) +- [(FR) - Fichier de configuration](../fr/references/configuration.md) - [(FR) - API d'administration](./fr/references/admin_api.md) ## Tutoriels diff --git a/doc/fr/references/configuration.md b/doc/fr/references/configuration.md new file mode 100644 index 0000000..baa2094 --- /dev/null +++ b/doc/fr/references/configuration.md @@ -0,0 +1,34 @@ +# Configuration + +## Référence + +Vous trouverez ici un fichier de configuration de référence, complet et commenté: + +[`misc/packaging/common/config.yml`](../../../misc/packaging/common/config.yml) + +## Interpolation de variables + +Il est possible d'utiliser de l'interpolation de variables d'environnement dans le fichier de configuration via la syntaxe `${var}`. + +Les fonctions d'interpolation suivantes sont également disponibles: + +- `${var^}` +- `${var^^}` +- `${var,}` +- `${var,,}` +- `${var:position}` +- `${var:position:length}` +- `${var#substring}` +- `${var##substring}` +- `${var%substring}` +- `${var%%substring}` +- `${var/substring/replacement}` +- `${var//substring/replacement}` +- `${var/#substring/replacement}` +- `${var/%substring/replacement}` +- `${#var}` +- `${var=default}` +- `${var:=default}` +- `${var:-default}` + +_Voir le package [`github.com/drone/envsubst`](https://pkg.go.dev/github.com/drone/envsubst) pour plus de détails._ diff --git a/internal/config/environment.go b/internal/config/environment.go index baccdd7..0494bef 100644 --- a/internal/config/environment.go +++ b/internal/config/environment.go @@ -23,12 +23,13 @@ func (is *InterpolatedString) UnmarshalYAML(value *yaml.Node) error { return errors.WithStack(err) } - if match := reVar.FindStringSubmatch(str); len(match) > 0 { - *is = InterpolatedString(os.Getenv(match[1])) - } else { - *is = InterpolatedString(str) + str, err := envsubst.EvalEnv(str) + if err != nil { + return errors.WithStack(err) } + *is = InterpolatedString(str) + return nil } @@ -41,8 +42,9 @@ func (ii *InterpolatedInt) UnmarshalYAML(value *yaml.Node) error { return errors.Wrapf(err, "could not decode value '%v' (line '%d') into string", value.Value, value.Line) } - if match := reVar.FindStringSubmatch(str); len(match) > 0 { - str = os.Getenv(match[1]) + str, err := envsubst.EvalEnv(str) + if err != nil { + return errors.WithStack(err) } intVal, err := strconv.ParseInt(str, 10, 32) @@ -64,8 +66,9 @@ func (ifl *InterpolatedFloat) UnmarshalYAML(value *yaml.Node) error { return errors.Wrapf(err, "could not decode value '%v' (line '%d') into string", value.Value, value.Line) } - if match := reVar.FindStringSubmatch(str); len(match) > 0 { - str = os.Getenv(match[1]) + str, err := envsubst.EvalEnv(str) + if err != nil { + return errors.WithStack(err) } floatVal, err := strconv.ParseFloat(str, 10) @@ -87,8 +90,9 @@ func (ib *InterpolatedBool) UnmarshalYAML(value *yaml.Node) error { return errors.Wrapf(err, "could not decode value '%v' (line '%d') into string", value.Value, value.Line) } - if match := reVar.FindStringSubmatch(str); len(match) > 0 { - str = os.Getenv(match[1]) + str, err := envsubst.EvalEnv(str) + if err != nil { + return errors.WithStack(err) } boolVal, err := strconv.ParseBool(str) @@ -165,22 +169,15 @@ type InterpolatedStringSlice []string func (iss *InterpolatedStringSlice) UnmarshalYAML(value *yaml.Node) error { var data []string - var evErr error if err := value.Decode(&data); err != nil { return errors.Wrapf(err, "could not decode value '%v' (line '%d') into map", value.Value, value.Line) } for index, value := range data { - //match := reVar.FindStringSubmatch(value) - re := regexp.MustCompile(`\${(.*?)}`) - - res := re.FindAllStringSubmatch(value, 10) - if len(res) > 0 { - value, evErr = envsubst.EvalEnv(value) - if evErr != nil { - return evErr - } + value, err := envsubst.EvalEnv(value) + if err != nil { + return errors.WithStack(err) } data[index] = value @@ -200,8 +197,9 @@ func (id *InterpolatedDuration) UnmarshalYAML(value *yaml.Node) error { return errors.Wrapf(err, "could not decode value '%v' (line '%d') into string", value.Value, value.Line) } - if match := reVar.FindStringSubmatch(str); len(match) > 0 { - str = os.Getenv(match[1]) + str, err := envsubst.EvalEnv(str) + if err != nil { + return errors.WithStack(err) } duration, err := time.ParseDuration(str)