mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-14 23:06:27 +03:00
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
This commit is contained in:
parent
3cfefeb0f7
commit
c6dec30535
2 changed files with 36 additions and 6 deletions
|
@ -60,21 +60,31 @@ func replaceEnvVars(input []byte) ([]byte, error) {
|
||||||
end += begin + len(spanOpen) // make end relative to input, not begin
|
end += begin + len(spanOpen) // make end relative to input, not begin
|
||||||
|
|
||||||
// get the name; if there is no name, skip it
|
// get the name; if there is no name, skip it
|
||||||
envVarName := input[begin+len(spanOpen) : end]
|
envString := input[begin+len(spanOpen) : end]
|
||||||
if len(envVarName) == 0 {
|
if len(envString) == 0 {
|
||||||
offset = end + len(spanClose)
|
offset = end + len(spanClose)
|
||||||
continue
|
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
|
// 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
|
// splice in the value
|
||||||
input = append(input[:begin],
|
input = append(input[:begin],
|
||||||
append(envVarValue, input[end+len(spanClose):]...)...)
|
append(envVarBytes, input[end+len(spanClose):]...)...)
|
||||||
|
|
||||||
// continue at the end of the replacement
|
// continue at the end of the replacement
|
||||||
offset = begin + len(envVarValue)
|
offset = begin + len(envVarBytes)
|
||||||
}
|
}
|
||||||
return input, nil
|
return input, nil
|
||||||
}
|
}
|
||||||
|
@ -548,4 +558,7 @@ func (s Segment) Directive() string {
|
||||||
|
|
||||||
// spanOpen and spanClose are used to bound spans that
|
// spanOpen and spanClose are used to bound spans that
|
||||||
// contain the name of an environment variable.
|
// contain the name of an environment variable.
|
||||||
var spanOpen, spanClose = []byte{'{', '$'}, []byte{'}'}
|
var (
|
||||||
|
spanOpen, spanClose = []byte{'{', '$'}, []byte{'}'}
|
||||||
|
envVarDefaultDelimiter = ":"
|
||||||
|
)
|
||||||
|
|
|
@ -478,6 +478,7 @@ func TestParseAll(t *testing.T) {
|
||||||
|
|
||||||
func TestEnvironmentReplacement(t *testing.T) {
|
func TestEnvironmentReplacement(t *testing.T) {
|
||||||
os.Setenv("FOOBAR", "foobar")
|
os.Setenv("FOOBAR", "foobar")
|
||||||
|
os.Setenv("CHAINED", "$FOOBAR")
|
||||||
|
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
input string
|
input string
|
||||||
|
@ -523,6 +524,22 @@ func TestEnvironmentReplacement(t *testing.T) {
|
||||||
input: "{$FOOBAR}{$FOOBAR}",
|
input: "{$FOOBAR}{$FOOBAR}",
|
||||||
expect: "foobarfoobar",
|
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",
|
input: "{$FOOBAR",
|
||||||
expect: "{$FOOBAR",
|
expect: "{$FOOBAR",
|
||||||
|
|
Loading…
Reference in a new issue