config: forbid nil regexp matchers (#2083)

Signed-off-by: Simon Pasquier <spasquie@redhat.com>
This commit is contained in:
Simon Pasquier 2019-10-25 11:44:45 +02:00 committed by GitHub
parent a75cd02786
commit 0630b38c4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 85 additions and 20 deletions

View File

@ -579,7 +579,7 @@ type Route struct {
GroupByAll bool `yaml:"-" json:"-"`
Match map[string]string `yaml:"match,omitempty" json:"match,omitempty"`
MatchRE map[string]Regexp `yaml:"match_re,omitempty" json:"match_re,omitempty"`
MatchRE MatchRegexps `yaml:"match_re,omitempty" json:"match_re,omitempty"`
Continue bool `yaml:"continue,omitempty" json:"continue,omitempty"`
Routes []*Route `yaml:"routes,omitempty" json:"routes,omitempty"`
@ -601,11 +601,6 @@ func (r *Route) UnmarshalYAML(unmarshal func(interface{}) error) error {
}
}
for k := range r.MatchRE {
if !model.LabelNameRE.MatchString(k) {
return fmt.Errorf("invalid label name %q", k)
}
}
for _, l := range r.GroupByStr {
if l == "..." {
r.GroupByAll = true
@ -650,13 +645,13 @@ type InhibitRule struct {
SourceMatch map[string]string `yaml:"source_match,omitempty" json:"source_match,omitempty"`
// SourceMatchRE defines pairs like SourceMatch but does regular expression
// matching.
SourceMatchRE map[string]Regexp `yaml:"source_match_re,omitempty" json:"source_match_re,omitempty"`
SourceMatchRE MatchRegexps `yaml:"source_match_re,omitempty" json:"source_match_re,omitempty"`
// TargetMatch defines a set of labels that have to equal the given
// value for target alerts.
TargetMatch map[string]string `yaml:"target_match,omitempty" json:"target_match,omitempty"`
// TargetMatchRE defines pairs like TargetMatch but does regular expression
// matching.
TargetMatchRE map[string]Regexp `yaml:"target_match_re,omitempty" json:"target_match_re,omitempty"`
TargetMatchRE MatchRegexps `yaml:"target_match_re,omitempty" json:"target_match_re,omitempty"`
// A set of labels that must be equal between the source and target alert
// for them to be a match.
Equal model.LabelNames `yaml:"equal,omitempty" json:"equal,omitempty"`
@ -675,24 +670,12 @@ func (r *InhibitRule) UnmarshalYAML(unmarshal func(interface{}) error) error {
}
}
for k := range r.SourceMatchRE {
if !model.LabelNameRE.MatchString(k) {
return fmt.Errorf("invalid label name %q", k)
}
}
for k := range r.TargetMatch {
if !model.LabelNameRE.MatchString(k) {
return fmt.Errorf("invalid label name %q", k)
}
}
for k := range r.TargetMatchRE {
if !model.LabelNameRE.MatchString(k) {
return fmt.Errorf("invalid label name %q", k)
}
}
return nil
}
@ -724,6 +707,26 @@ func (c *Receiver) UnmarshalYAML(unmarshal func(interface{}) error) error {
return nil
}
// MatchRegexps represents a map of Regexp.
type MatchRegexps map[string]Regexp
// UnmarshalYAML implements the yaml.Unmarshaler interface for MatchRegexps.
func (m *MatchRegexps) UnmarshalYAML(unmarshal func(interface{}) error) error {
type plain MatchRegexps
if err := unmarshal((*plain)(m)); err != nil {
return err
}
for k, v := range *m {
if !model.LabelNameRE.MatchString(k) {
return fmt.Errorf("invalid label name %q", k)
}
if v.Regexp == nil {
return fmt.Errorf("invalid regexp value for %q", k)
}
}
return nil
}
// Regexp encapsulates a regexp.Regexp and makes it YAML marshalable.
type Regexp struct {
*regexp.Regexp

View File

@ -16,6 +16,7 @@ package config
import (
"encoding/json"
"net/url"
"os"
"reflect"
"regexp"
"strings"
@ -776,3 +777,32 @@ func TestUnmarshalHostPort(t *testing.T) {
})
}
}
func TestNilRegexp(t *testing.T) {
for _, tc := range []struct {
file string
errMsg string
}{
{
file: "testdata/conf.nil-match_re-route.yml",
errMsg: "invalid_label",
},
{
file: "testdata/conf.nil-source_match_re-inhibitiion.yml",
errMsg: "invalid_source_label",
},
{
file: "testdata/conf.nil-target_match_re-inhibitiion.yml",
errMsg: "invalid_target_label",
},
} {
t.Run(tc.file, func(t *testing.T) {
_, err := os.Stat(tc.file)
require.NoError(t, err)
_, err = LoadFile(tc.file)
require.Error(t, err)
require.Contains(t, err.Error(), tc.errMsg)
})
}
}

View File

@ -0,0 +1,10 @@
route:
receiver: empty
routes:
- match_re:
invalid_label:
receiver: empty
receivers:
- name: empty

View File

@ -0,0 +1,11 @@
route:
receiver: empty
receivers:
- name: empty
inhibit_rules:
- source_match_re:
invalid_source_label:
target_match_re:
severity: critical

View File

@ -0,0 +1,11 @@
route:
receiver: empty
receivers:
- name: empty
inhibit_rules:
- source_match:
severity: critical
target_match_re:
invalid_target_label: