From 4855a0c067e25df969debbe880448164116f625e Mon Sep 17 00:00:00 2001 From: Filip Petkovski Date: Mon, 17 Jan 2022 16:43:55 +0100 Subject: [PATCH] Allow escaping a dollar sign when expanding external labels (#10129) * Allow escaping a dollar sign when expanding external labels There is currently no mechanism to natively escape a dollar sign in the os.Expand function. As a workaround, this commit modifies the external label expansion logic to treat a double dollar ($$) as a mechanism for escaping the dollar character. Signed-off-by: fpetkovski --- config/config.go | 3 +++ config/config_test.go | 6 ++++++ config/testdata/external_labels.good.yml | 2 ++ docs/feature_flags.md | 1 + 4 files changed, 12 insertions(+) diff --git a/config/config.go b/config/config.go index 24441d2bcb..45bafeda50 100644 --- a/config/config.go +++ b/config/config.go @@ -83,6 +83,9 @@ func Load(s string, expandExternalLabels bool, logger log.Logger) (*Config, erro for i, v := range cfg.GlobalConfig.ExternalLabels { newV := os.Expand(v.Value, func(s string) string { + if s == "$" { + return "$" + } if v := os.Getenv(s); v != "" { return v } diff --git a/config/config_test.go b/config/config_test.go index 695c0188a5..bdb72dde2a 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -1480,12 +1480,16 @@ func TestExpandExternalLabels(t *testing.T) { require.Equal(t, labels.Label{Name: "bar", Value: "foo"}, c.GlobalConfig.ExternalLabels[0]) require.Equal(t, labels.Label{Name: "baz", Value: "foo${TEST}bar"}, c.GlobalConfig.ExternalLabels[1]) require.Equal(t, labels.Label{Name: "foo", Value: "${TEST}"}, c.GlobalConfig.ExternalLabels[2]) + require.Equal(t, labels.Label{Name: "qux", Value: "foo$${TEST}"}, c.GlobalConfig.ExternalLabels[3]) + require.Equal(t, labels.Label{Name: "xyz", Value: "foo$$bar"}, c.GlobalConfig.ExternalLabels[4]) c, err = LoadFile("testdata/external_labels.good.yml", false, true, log.NewNopLogger()) require.NoError(t, err) require.Equal(t, labels.Label{Name: "bar", Value: "foo"}, c.GlobalConfig.ExternalLabels[0]) require.Equal(t, labels.Label{Name: "baz", Value: "foobar"}, c.GlobalConfig.ExternalLabels[1]) require.Equal(t, labels.Label{Name: "foo", Value: ""}, c.GlobalConfig.ExternalLabels[2]) + require.Equal(t, labels.Label{Name: "qux", Value: "foo${TEST}"}, c.GlobalConfig.ExternalLabels[3]) + require.Equal(t, labels.Label{Name: "xyz", Value: "foo$bar"}, c.GlobalConfig.ExternalLabels[4]) os.Setenv("TEST", "TestValue") c, err = LoadFile("testdata/external_labels.good.yml", false, true, log.NewNopLogger()) @@ -1493,6 +1497,8 @@ func TestExpandExternalLabels(t *testing.T) { require.Equal(t, labels.Label{Name: "bar", Value: "foo"}, c.GlobalConfig.ExternalLabels[0]) require.Equal(t, labels.Label{Name: "baz", Value: "fooTestValuebar"}, c.GlobalConfig.ExternalLabels[1]) require.Equal(t, labels.Label{Name: "foo", Value: "TestValue"}, c.GlobalConfig.ExternalLabels[2]) + require.Equal(t, labels.Label{Name: "qux", Value: "foo${TEST}"}, c.GlobalConfig.ExternalLabels[3]) + require.Equal(t, labels.Label{Name: "xyz", Value: "foo$bar"}, c.GlobalConfig.ExternalLabels[4]) } func TestEmptyGlobalBlock(t *testing.T) { diff --git a/config/testdata/external_labels.good.yml b/config/testdata/external_labels.good.yml index 828312e4d8..29d28a92bd 100644 --- a/config/testdata/external_labels.good.yml +++ b/config/testdata/external_labels.good.yml @@ -3,3 +3,5 @@ global: bar: foo foo: ${TEST} baz: foo${TEST}bar + qux: foo$${TEST} + xyz: foo$$bar diff --git a/docs/feature_flags.md b/docs/feature_flags.md index cb5b6fa2f8..7715655e7a 100644 --- a/docs/feature_flags.md +++ b/docs/feature_flags.md @@ -18,6 +18,7 @@ They may be enabled by default in future versions. Replace `${var}` or `$var` in the [`external_labels`](configuration/configuration.md#configuration-file) values according to the values of the current environment variables. References to undefined variables are replaced by the empty string. +The `$` character can be escaped by using `$$`. ## Remote Write Receiver