mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
Merge pull request #2094 from Nomon/bug/target_label_unmarshal
Bug/target label unmarshal
This commit is contained in:
commit
8462fe9fac
|
@ -31,6 +31,7 @@ var (
|
||||||
patFileSDName = regexp.MustCompile(`^[^*]*(\*[^/]*)?\.(json|yml|yaml|JSON|YML|YAML)$`)
|
patFileSDName = regexp.MustCompile(`^[^*]*(\*[^/]*)?\.(json|yml|yaml|JSON|YML|YAML)$`)
|
||||||
patRulePath = regexp.MustCompile(`^[^*]*(\*[^/]*)?$`)
|
patRulePath = regexp.MustCompile(`^[^*]*(\*[^/]*)?$`)
|
||||||
patAuthLine = regexp.MustCompile(`((?:password|bearer_token|secret_key|client_secret):\s+)(".+"|'.+'|[^\s]+)`)
|
patAuthLine = regexp.MustCompile(`((?:password|bearer_token|secret_key|client_secret):\s+)(".+"|'.+'|[^\s]+)`)
|
||||||
|
relabelTarget = regexp.MustCompile(`^(?:(?:[a-zA-Z_]|\$(?:\{\w+\}|\w+))+\w*)+$`)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Load parses the YAML input s into a Config.
|
// 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
|
gc.EvaluationInterval = DefaultGlobalConfig.EvaluationInterval
|
||||||
}
|
}
|
||||||
*c = *gc
|
*c = *gc
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -987,8 +987,9 @@ type RelabelConfig struct {
|
||||||
Regex Regexp `yaml:"regex,omitempty"`
|
Regex Regexp `yaml:"regex,omitempty"`
|
||||||
// Modulus to take of the hash of concatenated values from the source labels.
|
// Modulus to take of the hash of concatenated values from the source labels.
|
||||||
Modulus uint64 `yaml:"modulus,omitempty"`
|
Modulus uint64 `yaml:"modulus,omitempty"`
|
||||||
// The label to which the resulting string is written in a replacement.
|
// TargetLabel is the label to which the resulting string is written in a replacement.
|
||||||
TargetLabel model.LabelName `yaml:"target_label,omitempty"`
|
// Regexp interpolation is allowed for the replace action.
|
||||||
|
TargetLabel string `yaml:"target_label,omitempty"`
|
||||||
// Replacement is the regex replacement pattern to be used.
|
// Replacement is the regex replacement pattern to be used.
|
||||||
Replacement string `yaml:"replacement,omitempty"`
|
Replacement string `yaml:"replacement,omitempty"`
|
||||||
// Action is the action to be performed for the relabeling.
|
// Action is the action to be performed for the relabeling.
|
||||||
|
@ -1014,6 +1015,12 @@ func (c *RelabelConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||||
if (c.Action == RelabelReplace || c.Action == RelabelHashMod) && c.TargetLabel == "" {
|
if (c.Action == RelabelReplace || c.Action == RelabelHashMod) && c.TargetLabel == "" {
|
||||||
return fmt.Errorf("relabel configuration for %s action requires 'target_label' value", c.Action)
|
return fmt.Errorf("relabel configuration for %s action requires 'target_label' value", c.Action)
|
||||||
}
|
}
|
||||||
|
if c.Action == RelabelReplace && !relabelTarget.MatchString(c.TargetLabel) {
|
||||||
|
return fmt.Errorf("%q is invalid 'target_label' for %s action", c.TargetLabel, c.Action)
|
||||||
|
}
|
||||||
|
if c.Action == RelabelHashMod && !model.LabelName(c.TargetLabel).IsValid() {
|
||||||
|
return fmt.Errorf("%q is invalid 'target_label' for %s action", c.TargetLabel, c.Action)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -207,6 +207,17 @@ var expectedConf = &Config{
|
||||||
Scheme: DefaultConsulSDConfig.Scheme,
|
Scheme: DefaultConsulSDConfig.Scheme,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
RelabelConfigs: []*RelabelConfig{
|
||||||
|
{
|
||||||
|
SourceLabels: model.LabelNames{"__meta_sd_consul_tags"},
|
||||||
|
Regex: MustNewRegexp("label:([^=]+)=([^,]+)"),
|
||||||
|
Separator: ",",
|
||||||
|
TargetLabel: "${1}",
|
||||||
|
Replacement: "${2}",
|
||||||
|
Action: RelabelReplace,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
JobName: "service-z",
|
JobName: "service-z",
|
||||||
|
@ -501,6 +512,34 @@ func TestEmptyGlobalBlock(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTargetLabelValidity(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
str string
|
||||||
|
valid bool
|
||||||
|
}{
|
||||||
|
{"-label", false},
|
||||||
|
{"label", true},
|
||||||
|
{"label${1}", true},
|
||||||
|
{"${1}label", true},
|
||||||
|
{"${1}", true},
|
||||||
|
{"${1}label", true},
|
||||||
|
{"${", false},
|
||||||
|
{"$", false},
|
||||||
|
{"${}", false},
|
||||||
|
{"foo${", false},
|
||||||
|
{"$1", true},
|
||||||
|
{"asd$2asd", true},
|
||||||
|
{"-foo${1}bar-", false},
|
||||||
|
{"_${1}_", true},
|
||||||
|
{"foo${bar}foo", true},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
if relabelTarget.Match([]byte(test.str)) != test.valid {
|
||||||
|
t.Fatalf("Expected %q to be %v", test.str, test.valid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func kubernetesSDHostURL() URL {
|
func kubernetesSDHostURL() URL {
|
||||||
tURL, _ := url.Parse("https://localhost:1234")
|
tURL, _ := url.Parse("https://localhost:1234")
|
||||||
return URL{URL: tURL}
|
return URL{URL: tURL}
|
||||||
|
|
7
config/testdata/conf.good.yml
vendored
7
config/testdata/conf.good.yml
vendored
|
@ -104,6 +104,13 @@ scrape_configs:
|
||||||
- server: 'localhost:1234'
|
- server: 'localhost:1234'
|
||||||
services: ['nginx', 'cache', 'mysql']
|
services: ['nginx', 'cache', 'mysql']
|
||||||
|
|
||||||
|
relabel_configs:
|
||||||
|
- source_labels: [__meta_sd_consul_tags]
|
||||||
|
separator: ','
|
||||||
|
regex: label:([^=]+)=([^,]+)
|
||||||
|
target_label: ${1}
|
||||||
|
replacement: ${2}
|
||||||
|
|
||||||
- job_name: service-z
|
- job_name: service-z
|
||||||
|
|
||||||
tls_config:
|
tls_config:
|
||||||
|
|
|
@ -61,20 +61,20 @@ func relabel(labels model.LabelSet, cfg *config.RelabelConfig) model.LabelSet {
|
||||||
if indexes == nil {
|
if indexes == nil {
|
||||||
break
|
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() {
|
if !target.IsValid() {
|
||||||
delete(labels, cfg.TargetLabel)
|
delete(labels, model.LabelName(cfg.TargetLabel))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
res := cfg.Regex.ExpandString([]byte{}, cfg.Replacement, val, indexes)
|
res := cfg.Regex.ExpandString([]byte{}, cfg.Replacement, val, indexes)
|
||||||
if len(res) == 0 {
|
if len(res) == 0 {
|
||||||
delete(labels, cfg.TargetLabel)
|
delete(labels, model.LabelName(cfg.TargetLabel))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
labels[target] = model.LabelValue(res)
|
labels[target] = model.LabelValue(res)
|
||||||
case config.RelabelHashMod:
|
case config.RelabelHashMod:
|
||||||
mod := sum64(md5.Sum([]byte(val))) % cfg.Modulus
|
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:
|
case config.RelabelLabelMap:
|
||||||
out := make(model.LabelSet, len(labels))
|
out := make(model.LabelSet, len(labels))
|
||||||
// Take a copy to avoid infinite loops.
|
// Take a copy to avoid infinite loops.
|
||||||
|
|
|
@ -38,7 +38,7 @@ func TestRelabel(t *testing.T) {
|
||||||
{
|
{
|
||||||
SourceLabels: model.LabelNames{"a"},
|
SourceLabels: model.LabelNames{"a"},
|
||||||
Regex: config.MustNewRegexp("f(.*)"),
|
Regex: config.MustNewRegexp("f(.*)"),
|
||||||
TargetLabel: model.LabelName("d"),
|
TargetLabel: "d",
|
||||||
Separator: ";",
|
Separator: ";",
|
||||||
Replacement: "ch${1}-ch${1}",
|
Replacement: "ch${1}-ch${1}",
|
||||||
Action: config.RelabelReplace,
|
Action: config.RelabelReplace,
|
||||||
|
@ -61,7 +61,7 @@ func TestRelabel(t *testing.T) {
|
||||||
{
|
{
|
||||||
SourceLabels: model.LabelNames{"a", "b"},
|
SourceLabels: model.LabelNames{"a", "b"},
|
||||||
Regex: config.MustNewRegexp("f(.*);(.*)r"),
|
Regex: config.MustNewRegexp("f(.*);(.*)r"),
|
||||||
TargetLabel: model.LabelName("a"),
|
TargetLabel: "a",
|
||||||
Separator: ";",
|
Separator: ";",
|
||||||
Replacement: "b${1}${2}m", // boobam
|
Replacement: "b${1}${2}m", // boobam
|
||||||
Action: config.RelabelReplace,
|
Action: config.RelabelReplace,
|
||||||
|
@ -69,7 +69,7 @@ func TestRelabel(t *testing.T) {
|
||||||
{
|
{
|
||||||
SourceLabels: model.LabelNames{"c", "a"},
|
SourceLabels: model.LabelNames{"c", "a"},
|
||||||
Regex: config.MustNewRegexp("(b).*b(.*)ba(.*)"),
|
Regex: config.MustNewRegexp("(b).*b(.*)ba(.*)"),
|
||||||
TargetLabel: model.LabelName("d"),
|
TargetLabel: "d",
|
||||||
Separator: ";",
|
Separator: ";",
|
||||||
Replacement: "$1$2$2$3",
|
Replacement: "$1$2$2$3",
|
||||||
Action: config.RelabelReplace,
|
Action: config.RelabelReplace,
|
||||||
|
@ -94,7 +94,7 @@ func TestRelabel(t *testing.T) {
|
||||||
}, {
|
}, {
|
||||||
SourceLabels: model.LabelNames{"a"},
|
SourceLabels: model.LabelNames{"a"},
|
||||||
Regex: config.MustNewRegexp("f(.*)"),
|
Regex: config.MustNewRegexp("f(.*)"),
|
||||||
TargetLabel: model.LabelName("d"),
|
TargetLabel: "d",
|
||||||
Separator: ";",
|
Separator: ";",
|
||||||
Replacement: "ch$1-ch$1",
|
Replacement: "ch$1-ch$1",
|
||||||
Action: config.RelabelReplace,
|
Action: config.RelabelReplace,
|
||||||
|
@ -124,7 +124,7 @@ func TestRelabel(t *testing.T) {
|
||||||
{
|
{
|
||||||
SourceLabels: model.LabelNames{"a"},
|
SourceLabels: model.LabelNames{"a"},
|
||||||
Regex: config.MustNewRegexp(".*(b).*"),
|
Regex: config.MustNewRegexp(".*(b).*"),
|
||||||
TargetLabel: model.LabelName("d"),
|
TargetLabel: "d",
|
||||||
Separator: ";",
|
Separator: ";",
|
||||||
Replacement: "$1",
|
Replacement: "$1",
|
||||||
Action: config.RelabelReplace,
|
Action: config.RelabelReplace,
|
||||||
|
@ -202,7 +202,7 @@ func TestRelabel(t *testing.T) {
|
||||||
{
|
{
|
||||||
SourceLabels: model.LabelNames{"a"},
|
SourceLabels: model.LabelNames{"a"},
|
||||||
Regex: config.MustNewRegexp("f"),
|
Regex: config.MustNewRegexp("f"),
|
||||||
TargetLabel: model.LabelName("b"),
|
TargetLabel: "b",
|
||||||
Replacement: "bar",
|
Replacement: "bar",
|
||||||
Action: config.RelabelReplace,
|
Action: config.RelabelReplace,
|
||||||
},
|
},
|
||||||
|
@ -220,7 +220,7 @@ func TestRelabel(t *testing.T) {
|
||||||
relabel: []*config.RelabelConfig{
|
relabel: []*config.RelabelConfig{
|
||||||
{
|
{
|
||||||
SourceLabels: model.LabelNames{"c"},
|
SourceLabels: model.LabelNames{"c"},
|
||||||
TargetLabel: model.LabelName("d"),
|
TargetLabel: "d",
|
||||||
Separator: ";",
|
Separator: ";",
|
||||||
Action: config.RelabelHashMod,
|
Action: config.RelabelHashMod,
|
||||||
Modulus: 1000,
|
Modulus: 1000,
|
||||||
|
@ -287,7 +287,7 @@ func TestRelabel(t *testing.T) {
|
||||||
Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"),
|
Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"),
|
||||||
Action: config.RelabelReplace,
|
Action: config.RelabelReplace,
|
||||||
Replacement: "${2}",
|
Replacement: "${2}",
|
||||||
TargetLabel: model.LabelName("${1}"),
|
TargetLabel: "${1}",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
output: model.LabelSet{
|
output: model.LabelSet{
|
||||||
|
@ -305,7 +305,7 @@ func TestRelabel(t *testing.T) {
|
||||||
Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"),
|
Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"),
|
||||||
Action: config.RelabelReplace,
|
Action: config.RelabelReplace,
|
||||||
Replacement: "${3}",
|
Replacement: "${3}",
|
||||||
TargetLabel: model.LabelName("${1}"),
|
TargetLabel: "${1}",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
output: model.LabelSet{
|
output: model.LabelSet{
|
||||||
|
@ -322,21 +322,21 @@ func TestRelabel(t *testing.T) {
|
||||||
Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"),
|
Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"),
|
||||||
Action: config.RelabelReplace,
|
Action: config.RelabelReplace,
|
||||||
Replacement: "${1}",
|
Replacement: "${1}",
|
||||||
TargetLabel: model.LabelName("${3}"),
|
TargetLabel: "${3}",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
SourceLabels: model.LabelNames{"a"},
|
SourceLabels: model.LabelNames{"a"},
|
||||||
Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"),
|
Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"),
|
||||||
Action: config.RelabelReplace,
|
Action: config.RelabelReplace,
|
||||||
Replacement: "${1}",
|
Replacement: "${1}",
|
||||||
TargetLabel: model.LabelName("0${3}"),
|
TargetLabel: "0${3}",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
SourceLabels: model.LabelNames{"a"},
|
SourceLabels: model.LabelNames{"a"},
|
||||||
Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"),
|
Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"),
|
||||||
Action: config.RelabelReplace,
|
Action: config.RelabelReplace,
|
||||||
Replacement: "${1}",
|
Replacement: "${1}",
|
||||||
TargetLabel: model.LabelName("-${3}"),
|
TargetLabel: "-${3}",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
output: model.LabelSet{
|
output: model.LabelSet{
|
||||||
|
@ -353,21 +353,21 @@ func TestRelabel(t *testing.T) {
|
||||||
Regex: config.MustNewRegexp("(?:.+,|^)path:(/[^,]+).*"),
|
Regex: config.MustNewRegexp("(?:.+,|^)path:(/[^,]+).*"),
|
||||||
Action: config.RelabelReplace,
|
Action: config.RelabelReplace,
|
||||||
Replacement: "${1}",
|
Replacement: "${1}",
|
||||||
TargetLabel: model.LabelName("__metrics_path__"),
|
TargetLabel: "__metrics_path__",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
SourceLabels: model.LabelNames{"__meta_sd_tags"},
|
SourceLabels: model.LabelNames{"__meta_sd_tags"},
|
||||||
Regex: config.MustNewRegexp("(?:.+,|^)job:([^,]+).*"),
|
Regex: config.MustNewRegexp("(?:.+,|^)job:([^,]+).*"),
|
||||||
Action: config.RelabelReplace,
|
Action: config.RelabelReplace,
|
||||||
Replacement: "${1}",
|
Replacement: "${1}",
|
||||||
TargetLabel: model.LabelName("job"),
|
TargetLabel: "job",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
SourceLabels: model.LabelNames{"__meta_sd_tags"},
|
SourceLabels: model.LabelNames{"__meta_sd_tags"},
|
||||||
Regex: config.MustNewRegexp("(?:.+,|^)label:([^=]+)=([^,]+).*"),
|
Regex: config.MustNewRegexp("(?:.+,|^)label:([^=]+)=([^,]+).*"),
|
||||||
Action: config.RelabelReplace,
|
Action: config.RelabelReplace,
|
||||||
Replacement: "${2}",
|
Replacement: "${2}",
|
||||||
TargetLabel: model.LabelName("${1}"),
|
TargetLabel: "${1}",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
output: model.LabelSet{
|
output: model.LabelSet{
|
||||||
|
|
Loading…
Reference in a new issue