Skip to content

Commit

Permalink
Add none/all matches to DNS RRset validation
Browse files Browse the repository at this point in the history
Signed-off-by: Paul Wood <pauwood@ebay.com>
  • Loading branch information
wodity committed Nov 21, 2019
1 parent 991f898 commit e0d07ea
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 5 deletions.
18 changes: 18 additions & 0 deletions CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,25 +165,43 @@ validate_answer_rrs:
fail_if_matches_regexp:
[ - <regex>, ... ]

fail_if_all_match_regexp:
[ - <regex>, ... ]

fail_if_not_matches_regexp:
[ - <regex>, ... ]

fail_if_none_matches_regexp:
[ - <regex>, ... ]

validate_authority_rrs:

fail_if_matches_regexp:
[ - <regex>, ... ]

fail_if_all_match_regexp:
[ - <regex>, ... ]

fail_if_not_matches_regexp:
[ - <regex>, ... ]

fail_if_none_matches_regexp:
[ - <regex>, ... ]

validate_additional_rrs:

fail_if_matches_regexp:
[ - <regex>, ... ]

fail_if_all_match_regexp:
[ - <regex>, ... ]

fail_if_not_matches_regexp:
[ - <regex>, ... ]

fail_if_none_matches_regexp:
[ - <regex>, ... ]

```

### <icmp_probe>
Expand Down
6 changes: 4 additions & 2 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,10 @@ type DNSProbe struct {
}

type DNSRRValidator struct {
FailIfMatchesRegexp []string `yaml:"fail_if_matches_regexp,omitempty"`
FailIfNotMatchesRegexp []string `yaml:"fail_if_not_matches_regexp,omitempty"`
FailIfMatchesRegexp []string `yaml:"fail_if_matches_regexp,omitempty"`
FailIfAllMatchRegexp []string `yaml:"fail_if_all_match_regexp,omitempty"`
FailIfNotMatchesRegexp []string `yaml:"fail_if_not_matches_regexp,omitempty"`
FailIfNoneMatchesRegexp []string `yaml:"fail_if_none_matches_regexp,omitempty"`
}

// UnmarshalYAML implements the yaml.Unmarshaler interface.
Expand Down
4 changes: 4 additions & 0 deletions example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,12 @@ modules:
validate_answer_rrs:
fail_if_matches_regexp:
- ".*127.0.0.1"
fail_if_all_match_regexp:
- ".*127.0.0.1"
fail_if_not_matches_regexp:
- "www.prometheus.io.\t300\tIN\tA\t127.0.0.1"
fail_if_none_matches_regexp:
- "127.0.0.1"
validate_authority_rrs:
fail_if_matches_regexp:
- ".*127.0.0.1"
Expand Down
40 changes: 37 additions & 3 deletions prober/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,18 @@ import (

// validRRs checks a slice of RRs received from the server against a DNSRRValidator.
func validRRs(rrs *[]dns.RR, v *config.DNSRRValidator, logger log.Logger) bool {
var anyMatch bool = false
var allMatch bool = true
// Fail the probe if there are no RRs of a given type, but a regexp match is required
// (i.e. FailIfNotMatchesRegexp is set).
// (i.e. FailIfNotMatchesRegexp or FailIfNoneMatchesRegexp is set).
if len(*rrs) == 0 && len(v.FailIfNotMatchesRegexp) > 0 {
level.Error(logger).Log("msg", "fail_if_not_matches_regexp specified but no RRs returned")
return false
}
if len(*rrs) == 0 && len(v.FailIfNoneMatchesRegexp) > 0 {
level.Error(logger).Log("msg", "fail_if_none_matches_regexp specified but no RRs returned")
return false
}
for _, rr := range *rrs {
level.Info(logger).Log("msg", "Validating RR", "rr", rr)
for _, re := range v.FailIfMatchesRegexp {
Expand All @@ -44,22 +50,50 @@ func validRRs(rrs *[]dns.RR, v *config.DNSRRValidator, logger log.Logger) bool {
return false
}
if match {
level.Error(logger).Log("msg", "RR matched regexp", "regexp", re, "rr", rr)
level.Error(logger).Log("msg", "At least one RR matched regexp", "regexp", re, "rr", rr)
return false
}
}
for _, re := range v.FailIfAllMatchRegexp {
match, err := regexp.MatchString(re, rr.String())
if err != nil {
level.Error(logger).Log("msg", "Error matching regexp", "regexp", re, "err", err)
return false
}
if !match {
allMatch = false
}
}
for _, re := range v.FailIfNotMatchesRegexp {
match, err := regexp.MatchString(re, rr.String())
if err != nil {
level.Error(logger).Log("msg", "Error matching regexp", "regexp", re, "err", err)
return false
}
if !match {
level.Error(logger).Log("msg", "RR did not match regexp", "regexp", re, "rr", rr)
level.Error(logger).Log("msg", "At least one RR did not match regexp", "regexp", re, "rr", rr)
return false
}
}
for _, re := range v.FailIfNoneMatchesRegexp {
match, err := regexp.MatchString(re, rr.String())
if err != nil {
level.Error(logger).Log("msg", "Error matching regexp", "regexp", re, "err", err)
return false
}
if match {
anyMatch = true
}
}
}
if len(v.FailIfAllMatchRegexp) > 0 && !allMatch {
level.Error(logger).Log("msg", "Not all RRs matched regexp")
return false
}
if len(v.FailIfNoneMatchesRegexp) > 0 && !anyMatch {
level.Error(logger).Log("msg", "None of the RRs did matched any regexp")
return false
}
return true
}

Expand Down
20 changes: 20 additions & 0 deletions prober/dns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,26 @@ func TestAuthoritativeDNSResponse(t *testing.T) {
},
}, false,
},
{
config.DNSProbe{
IPProtocol: "ip4",
IPProtocolFallback: true,
QueryName: "example.com",
ValidateAdditional: config.DNSRRValidator{
FailIfAllMatchRegexp: []string{".*127.0.0.*"},
},
}, false,
},
{
config.DNSProbe{
IPProtocol: "ip4",
IPProtocolFallback: true,
QueryName: "example.com",
ValidateAdditional: config.DNSRRValidator{
FailIfNoneMatchesRegexp: []string{".*127.0.0.3.*"},
},
}, false,
},
}

for _, protocol := range PROTOCOLS {
Expand Down

0 comments on commit e0d07ea

Please sign in to comment.