config: forbid nil regexp matchers (#2083)
Signed-off-by: Simon Pasquier <spasquie@redhat.com>
This commit is contained in:
parent
a75cd02786
commit
0630b38c4a
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
route:
|
||||
receiver: empty
|
||||
|
||||
routes:
|
||||
- match_re:
|
||||
invalid_label:
|
||||
receiver: empty
|
||||
|
||||
receivers:
|
||||
- name: empty
|
|
@ -0,0 +1,11 @@
|
|||
route:
|
||||
receiver: empty
|
||||
|
||||
receivers:
|
||||
- name: empty
|
||||
|
||||
inhibit_rules:
|
||||
- source_match_re:
|
||||
invalid_source_label:
|
||||
target_match_re:
|
||||
severity: critical
|
|
@ -0,0 +1,11 @@
|
|||
route:
|
||||
receiver: empty
|
||||
|
||||
receivers:
|
||||
- name: empty
|
||||
|
||||
inhibit_rules:
|
||||
- source_match:
|
||||
severity: critical
|
||||
target_match_re:
|
||||
invalid_target_label:
|
Loading…
Reference in New Issue