diff --git a/config/config.go b/config/config.go index ee37ae1265..8b13aeecf4 100644 --- a/config/config.go +++ b/config/config.go @@ -31,6 +31,7 @@ var ( patFileSDName = regexp.MustCompile(`^[^*]*(\*[^/]*)?\.(json|yml|yaml|JSON|YML|YAML)$`) patRulePath = regexp.MustCompile(`^[^*]*(\*[^/]*)?$`) patAuthLine = regexp.MustCompile(`((?:password|bearer_token|secret_key|client_secret):\s+)(".+"|'.+'|[^\s]+)`) + relabelTarget = regexp.MustCompile(`^(?:(?:[a-zA-Z_]|\$\{?[\w]+}?)+\w*)+$`) ) // Load parses the YAML input s into a Config. @@ -355,7 +356,6 @@ func (c *GlobalConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { gc.EvaluationInterval = DefaultGlobalConfig.EvaluationInterval } *c = *gc - return nil } @@ -986,7 +986,7 @@ type RelabelConfig struct { // Modulus to take of the hash of concatenated values from the source labels. Modulus uint64 `yaml:"modulus,omitempty"` // The label to which the resulting string is written in a replacement. - TargetLabel model.LabelName `yaml:"target_label,omitempty"` + TargetLabel string `yaml:"target_label,omitempty"` // Replacement is the regex replacement pattern to be used. Replacement string `yaml:"replacement,omitempty"` // Action is the action to be performed for the relabeling. @@ -1012,6 +1012,12 @@ func (c *RelabelConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { if (c.Action == RelabelReplace || c.Action == RelabelHashMod) && c.TargetLabel == "" { return fmt.Errorf("relabel configuration for %s action requires 'target_label' value", c.Action) } + if c.Action == RelabelReplace && !relabelTarget.Match([]byte(c.TargetLabel)) { + return fmt.Errorf("%q is invalid 'target_label' for %s action", c.TargetLabel, c.Action) + } + if c.Action == RelabelHashMod && !model.LabelNameRE.Match([]byte(c.TargetLabel)) { + return fmt.Errorf("%q is invalid 'target_label' for %s action", c.TargetLabel, c.Action) + } return nil } diff --git a/config/testdata/relabel_target_label.good.yml b/config/testdata/relabel_target_label.good.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/relabel/relabel.go b/relabel/relabel.go index 6ce37296c3..ff59045965 100644 --- a/relabel/relabel.go +++ b/relabel/relabel.go @@ -61,20 +61,20 @@ func relabel(labels model.LabelSet, cfg *config.RelabelConfig) model.LabelSet { if indexes == nil { break } - target := model.LabelName(cfg.Regex.ExpandString([]byte{}, string(cfg.TargetLabel), val, indexes)) + target := model.LabelName(cfg.Regex.ExpandString([]byte{}, cfg.TargetLabel, val, indexes)) if !target.IsValid() { - delete(labels, cfg.TargetLabel) + delete(labels, model.LabelName(cfg.TargetLabel)) break } res := cfg.Regex.ExpandString([]byte{}, cfg.Replacement, val, indexes) if len(res) == 0 { - delete(labels, cfg.TargetLabel) + delete(labels, model.LabelName(cfg.TargetLabel)) break } labels[target] = model.LabelValue(res) case config.RelabelHashMod: mod := sum64(md5.Sum([]byte(val))) % cfg.Modulus - labels[cfg.TargetLabel] = model.LabelValue(fmt.Sprintf("%d", mod)) + labels[model.LabelName(cfg.TargetLabel)] = model.LabelValue(fmt.Sprintf("%d", mod)) case config.RelabelLabelMap: out := make(model.LabelSet, len(labels)) // Take a copy to avoid infinite loops. diff --git a/relabel/relabel_test.go b/relabel/relabel_test.go index 4004fa96ff..28fa6e901b 100644 --- a/relabel/relabel_test.go +++ b/relabel/relabel_test.go @@ -38,7 +38,7 @@ func TestRelabel(t *testing.T) { { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("f(.*)"), - TargetLabel: model.LabelName("d"), + TargetLabel: "d", Separator: ";", Replacement: "ch${1}-ch${1}", Action: config.RelabelReplace, @@ -61,7 +61,7 @@ func TestRelabel(t *testing.T) { { SourceLabels: model.LabelNames{"a", "b"}, Regex: config.MustNewRegexp("f(.*);(.*)r"), - TargetLabel: model.LabelName("a"), + TargetLabel: "a", Separator: ";", Replacement: "b${1}${2}m", // boobam Action: config.RelabelReplace, @@ -69,7 +69,7 @@ func TestRelabel(t *testing.T) { { SourceLabels: model.LabelNames{"c", "a"}, Regex: config.MustNewRegexp("(b).*b(.*)ba(.*)"), - TargetLabel: model.LabelName("d"), + TargetLabel: "d", Separator: ";", Replacement: "$1$2$2$3", Action: config.RelabelReplace, @@ -94,7 +94,7 @@ func TestRelabel(t *testing.T) { }, { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("f(.*)"), - TargetLabel: model.LabelName("d"), + TargetLabel: "d", Separator: ";", Replacement: "ch$1-ch$1", Action: config.RelabelReplace, @@ -124,7 +124,7 @@ func TestRelabel(t *testing.T) { { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp(".*(b).*"), - TargetLabel: model.LabelName("d"), + TargetLabel: "d", Separator: ";", Replacement: "$1", Action: config.RelabelReplace, @@ -202,7 +202,7 @@ func TestRelabel(t *testing.T) { { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("f"), - TargetLabel: model.LabelName("b"), + TargetLabel: "b", Replacement: "bar", Action: config.RelabelReplace, }, @@ -220,7 +220,7 @@ func TestRelabel(t *testing.T) { relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"c"}, - TargetLabel: model.LabelName("d"), + TargetLabel: "d", Separator: ";", Action: config.RelabelHashMod, Modulus: 1000, @@ -287,7 +287,7 @@ func TestRelabel(t *testing.T) { Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), Action: config.RelabelReplace, Replacement: "${2}", - TargetLabel: model.LabelName("${1}"), + TargetLabel: "${1}", }, }, output: model.LabelSet{ @@ -305,7 +305,7 @@ func TestRelabel(t *testing.T) { Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), Action: config.RelabelReplace, Replacement: "${3}", - TargetLabel: model.LabelName("${1}"), + TargetLabel: "${1}", }, }, output: model.LabelSet{ @@ -322,21 +322,21 @@ func TestRelabel(t *testing.T) { Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), Action: config.RelabelReplace, Replacement: "${1}", - TargetLabel: model.LabelName("${3}"), + TargetLabel: "${3}", }, { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), Action: config.RelabelReplace, Replacement: "${1}", - TargetLabel: model.LabelName("0${3}"), + TargetLabel: "0${3}", }, { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), Action: config.RelabelReplace, Replacement: "${1}", - TargetLabel: model.LabelName("-${3}"), + TargetLabel: "-${3}", }, }, output: model.LabelSet{ @@ -353,21 +353,21 @@ func TestRelabel(t *testing.T) { Regex: config.MustNewRegexp("(?:.+,|^)path:(/[^,]+).*"), Action: config.RelabelReplace, Replacement: "${1}", - TargetLabel: model.LabelName("__metrics_path__"), + TargetLabel: "__metrics_path__", }, { SourceLabels: model.LabelNames{"__meta_sd_tags"}, Regex: config.MustNewRegexp("(?:.+,|^)job:([^,]+).*"), Action: config.RelabelReplace, Replacement: "${1}", - TargetLabel: model.LabelName("job"), + TargetLabel: "job", }, { SourceLabels: model.LabelNames{"__meta_sd_tags"}, Regex: config.MustNewRegexp("(?:.+,|^)label:([^=]+)=([^,]+).*"), Action: config.RelabelReplace, Replacement: "${2}", - TargetLabel: model.LabelName("${1}"), + TargetLabel: "${1}", }, }, output: model.LabelSet{