Merge pull request #2443 from ajalab/fix-get-silence-filter-regex
api: check silence matching by string comparison in getSilences
This commit is contained in:
commit
a7ca7b1d29
|
@ -584,14 +584,14 @@ func (api *API) getSilencesHandler(params silence_ops.GetSilencesParams) middlew
|
|||
|
||||
sils := open_api_models.GettableSilences{}
|
||||
for _, ps := range psils {
|
||||
if !checkSilenceMatchesFilterLabels(ps, matchers) {
|
||||
continue
|
||||
}
|
||||
silence, err := gettableSilenceFromProto(ps)
|
||||
if err != nil {
|
||||
level.Error(logger).Log("msg", "Failed to unmarshal silence from proto", "err", err)
|
||||
return silence_ops.NewGetSilencesInternalServerError().WithPayload(err.Error())
|
||||
}
|
||||
if !gettableSilenceMatchesFilterLabels(silence, matchers) {
|
||||
continue
|
||||
}
|
||||
sils = append(sils, &silence)
|
||||
}
|
||||
|
||||
|
@ -638,13 +638,31 @@ func sortSilences(sils open_api_models.GettableSilences) {
|
|||
})
|
||||
}
|
||||
|
||||
func gettableSilenceMatchesFilterLabels(s open_api_models.GettableSilence, matchers []*labels.Matcher) bool {
|
||||
sms := make(map[string]string)
|
||||
// checkSilenceMatchesFilterLabels returns true if
|
||||
// a given silence matches a list of matchers.
|
||||
// A silence matches a filter (list of matchers) if
|
||||
// for all matchers in the filter, there exists a matcher in the silence
|
||||
// such that their names, types, and values are equivalent.
|
||||
func checkSilenceMatchesFilterLabels(s *silencepb.Silence, matchers []*labels.Matcher) bool {
|
||||
for _, matcher := range matchers {
|
||||
found := false
|
||||
for _, m := range s.Matchers {
|
||||
sms[*m.Name] = *m.Value
|
||||
if matcher.Name == m.Name &&
|
||||
(matcher.Type == labels.MatchEqual && m.Type == silencepb.Matcher_EQUAL ||
|
||||
matcher.Type == labels.MatchRegexp && m.Type == silencepb.Matcher_REGEXP ||
|
||||
matcher.Type == labels.MatchNotEqual && m.Type == silencepb.Matcher_NOT_EQUAL ||
|
||||
matcher.Type == labels.MatchNotRegexp && m.Type == silencepb.Matcher_NOT_REGEXP) &&
|
||||
matcher.Value == m.Pattern {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return matchFilterLabels(matchers, sms)
|
||||
return true
|
||||
}
|
||||
|
||||
func (api *API) getSilenceHandler(params silence_ops.GetSilenceParams) middleware.Responder {
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
general_ops "github.com/prometheus/alertmanager/api/v2/restapi/operations/general"
|
||||
"github.com/prometheus/alertmanager/config"
|
||||
"github.com/prometheus/alertmanager/pkg/labels"
|
||||
"github.com/prometheus/alertmanager/silence/silencepb"
|
||||
"github.com/prometheus/alertmanager/types"
|
||||
)
|
||||
|
||||
|
@ -130,6 +131,109 @@ func TestGetSilencesHandler(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func createSilenceMatcher(name string, pattern string, matcherType silencepb.Matcher_Type) *silencepb.Matcher {
|
||||
return &silencepb.Matcher{
|
||||
Name: name,
|
||||
Pattern: pattern,
|
||||
Type: matcherType,
|
||||
}
|
||||
}
|
||||
|
||||
func createLabelMatcher(name string, value string, matchType labels.MatchType) *labels.Matcher {
|
||||
matcher, _ := labels.NewMatcher(matchType, name, value)
|
||||
return matcher
|
||||
}
|
||||
|
||||
func TestCheckSilenceMatchesFilterLabels(t *testing.T) {
|
||||
type test struct {
|
||||
silenceMatchers []*silencepb.Matcher
|
||||
filterMatchers []*labels.Matcher
|
||||
expected bool
|
||||
}
|
||||
|
||||
tests := []test{
|
||||
{
|
||||
[]*silencepb.Matcher{createSilenceMatcher("label", "value", silencepb.Matcher_EQUAL)},
|
||||
[]*labels.Matcher{createLabelMatcher("label", "value", labels.MatchEqual)},
|
||||
true,
|
||||
},
|
||||
{
|
||||
[]*silencepb.Matcher{createSilenceMatcher("label", "value", silencepb.Matcher_EQUAL)},
|
||||
[]*labels.Matcher{createLabelMatcher("label", "novalue", labels.MatchEqual)},
|
||||
false,
|
||||
},
|
||||
{
|
||||
[]*silencepb.Matcher{createSilenceMatcher("label", "(foo|bar)", silencepb.Matcher_REGEXP)},
|
||||
[]*labels.Matcher{createLabelMatcher("label", "(foo|bar)", labels.MatchRegexp)},
|
||||
true,
|
||||
},
|
||||
{
|
||||
[]*silencepb.Matcher{createSilenceMatcher("label", "foo", silencepb.Matcher_REGEXP)},
|
||||
[]*labels.Matcher{createLabelMatcher("label", "(foo|bar)", labels.MatchRegexp)},
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
[]*silencepb.Matcher{createSilenceMatcher("label", "value", silencepb.Matcher_EQUAL)},
|
||||
[]*labels.Matcher{createLabelMatcher("label", "value", labels.MatchRegexp)},
|
||||
false,
|
||||
},
|
||||
{
|
||||
[]*silencepb.Matcher{createSilenceMatcher("label", "value", silencepb.Matcher_REGEXP)},
|
||||
[]*labels.Matcher{createLabelMatcher("label", "value", labels.MatchEqual)},
|
||||
false,
|
||||
},
|
||||
{
|
||||
[]*silencepb.Matcher{createSilenceMatcher("label", "value", silencepb.Matcher_NOT_EQUAL)},
|
||||
[]*labels.Matcher{createLabelMatcher("label", "value", labels.MatchNotEqual)},
|
||||
true,
|
||||
},
|
||||
{
|
||||
[]*silencepb.Matcher{createSilenceMatcher("label", "value", silencepb.Matcher_NOT_REGEXP)},
|
||||
[]*labels.Matcher{createLabelMatcher("label", "value", labels.MatchNotRegexp)},
|
||||
true,
|
||||
},
|
||||
{
|
||||
[]*silencepb.Matcher{createSilenceMatcher("label", "value", silencepb.Matcher_EQUAL)},
|
||||
[]*labels.Matcher{createLabelMatcher("label", "value", labels.MatchNotEqual)},
|
||||
false,
|
||||
},
|
||||
{
|
||||
[]*silencepb.Matcher{createSilenceMatcher("label", "value", silencepb.Matcher_REGEXP)},
|
||||
[]*labels.Matcher{createLabelMatcher("label", "value", labels.MatchNotRegexp)},
|
||||
false,
|
||||
},
|
||||
{
|
||||
[]*silencepb.Matcher{createSilenceMatcher("label", "value", silencepb.Matcher_NOT_EQUAL)},
|
||||
[]*labels.Matcher{createLabelMatcher("label", "value", labels.MatchNotRegexp)},
|
||||
false,
|
||||
},
|
||||
{
|
||||
[]*silencepb.Matcher{createSilenceMatcher("label", "value", silencepb.Matcher_NOT_REGEXP)},
|
||||
[]*labels.Matcher{createLabelMatcher("label", "value", labels.MatchNotEqual)},
|
||||
false,
|
||||
},
|
||||
{
|
||||
[]*silencepb.Matcher{
|
||||
createSilenceMatcher("label", "(foo|bar)", silencepb.Matcher_REGEXP),
|
||||
createSilenceMatcher("label", "value", silencepb.Matcher_EQUAL),
|
||||
},
|
||||
[]*labels.Matcher{createLabelMatcher("label", "(foo|bar)", labels.MatchRegexp)},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
silence := silencepb.Silence{
|
||||
Matchers: test.silenceMatchers,
|
||||
}
|
||||
actual := checkSilenceMatchesFilterLabels(&silence, test.filterMatchers)
|
||||
if test.expected != actual {
|
||||
t.Fatal("unexpected match result between silence and filter. expected:", test.expected, ", actual:", actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func convertDateTime(ts time.Time) *strfmt.DateTime {
|
||||
dt := strfmt.DateTime(ts)
|
||||
return &dt
|
||||
|
|
Loading…
Reference in New Issue