Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add none/all matches to DNS RRset validation #552

Merged
merged 1 commit into from
Nov 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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