diff options
author | Francis Lavoie <lavofr@gmail.com> | 2020-11-23 14:51:35 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-23 12:51:35 -0700 |
commit | c6dec305357868ec9ba7fbc45e6cb70404cc23a6 (patch) | |
tree | e3b86097b0ee681aa4b1387b831e4360086f9cbb | |
parent | 3cfefeb0f71d54f1d9a76a63be7b97d0943c88ef (diff) |
caddyfile: Add support for env var defaults; add tests (#3682)
* caddyfile: Add support for env var defaults, tests
* caddyfile: Use ?? instead, fix redundant cast, remove env chaining
* caddyfile: Use : instead
-rwxr-xr-x | caddyconfig/caddyfile/parse.go | 25 | ||||
-rwxr-xr-x | caddyconfig/caddyfile/parse_test.go | 17 |
2 files changed, 36 insertions, 6 deletions
diff --git a/caddyconfig/caddyfile/parse.go b/caddyconfig/caddyfile/parse.go index 4ae98ca..50e3244 100755 --- a/caddyconfig/caddyfile/parse.go +++ b/caddyconfig/caddyfile/parse.go @@ -60,21 +60,31 @@ func replaceEnvVars(input []byte) ([]byte, error) { end += begin + len(spanOpen) // make end relative to input, not begin // get the name; if there is no name, skip it - envVarName := input[begin+len(spanOpen) : end] - if len(envVarName) == 0 { + envString := input[begin+len(spanOpen) : end] + if len(envString) == 0 { offset = end + len(spanClose) continue } + // split the string into a key and an optional default + envParts := strings.SplitN(string(envString), envVarDefaultDelimiter, 2) + + // do a lookup for the env var, replace with the default if not found + envVarValue, found := os.LookupEnv(envParts[0]) + if !found && len(envParts) == 2 { + envVarValue = envParts[1] + } + // get the value of the environment variable - envVarValue := []byte(os.ExpandEnv(os.Getenv(string(envVarName)))) + // note that this causes one-level deep chaining + envVarBytes := []byte(envVarValue) // splice in the value input = append(input[:begin], - append(envVarValue, input[end+len(spanClose):]...)...) + append(envVarBytes, input[end+len(spanClose):]...)...) // continue at the end of the replacement - offset = begin + len(envVarValue) + offset = begin + len(envVarBytes) } return input, nil } @@ -548,4 +558,7 @@ func (s Segment) Directive() string { // spanOpen and spanClose are used to bound spans that // contain the name of an environment variable. -var spanOpen, spanClose = []byte{'{', '$'}, []byte{'}'} +var ( + spanOpen, spanClose = []byte{'{', '$'}, []byte{'}'} + envVarDefaultDelimiter = ":" +) diff --git a/caddyconfig/caddyfile/parse_test.go b/caddyconfig/caddyfile/parse_test.go index 12c30c8..94a69a4 100755 --- a/caddyconfig/caddyfile/parse_test.go +++ b/caddyconfig/caddyfile/parse_test.go @@ -478,6 +478,7 @@ func TestParseAll(t *testing.T) { func TestEnvironmentReplacement(t *testing.T) { os.Setenv("FOOBAR", "foobar") + os.Setenv("CHAINED", "$FOOBAR") for i, test := range []struct { input string @@ -524,6 +525,22 @@ func TestEnvironmentReplacement(t *testing.T) { expect: "foobarfoobar", }, { + input: "{$CHAINED}", + expect: "$FOOBAR", // should not chain env expands + }, + { + input: "{$FOO:default}", + expect: "default", + }, + { + input: "foo{$BAR:bar}baz", + expect: "foobarbaz", + }, + { + input: "foo{$BAR:$FOOBAR}baz", + expect: "foo$FOOBARbaz", // should not chain env expands + }, + { input: "{$FOOBAR", expect: "{$FOOBAR", }, |