[dns] Add serial number metric for dns soa queries (#333)
authorAsk Bjørn Hansen <ask@develooper.com>
Wed, 13 Jun 2018 06:41:52 +0000 (23:41 -0700)
committerBrian Brazil <brian.brazil@robustperception.io>
Wed, 13 Jun 2018 06:41:52 +0000 (07:41 +0100)
Signed-off-by: Ask Bjørn Hansen <ask@develooper.com>
example.yml
prober/dns.go
prober/dns_test.go

index 690cb3b76e31a30baad47b0ecb46feac0477bd1c..17beee045cf684f010f8f612b12d5470fac864f7 100644 (file)
@@ -111,6 +111,11 @@ modules:
       validate_additional_rrs:
         fail_if_matches_regexp:
         - ".*127.0.0.1"
+  dns_soa:
+    prober: dns
+    dns:
+      query_name: "prometheus.io"
+      query_type: "SOA"
   dns_tcp_example:
     prober: dns
     dns:
index 94e276d32f1202b64939e1719c5fb84326fa6f34..d11aa640700cfb63d1f95b5e874a35a7c4328076 100644 (file)
@@ -107,6 +107,17 @@ func ProbeDNS(ctx context.Context, target string, module config.Module, registry
        registry.MustRegister(probeDNSAuthorityRRSGauge)
        registry.MustRegister(probeDNSAdditionalRRSGauge)
 
+       qt := dns.TypeANY
+       if module.DNS.QueryType != "" {
+               var ok bool
+               qt, ok = dns.StringToType[module.DNS.QueryType]
+               if !ok {
+                       level.Error(logger).Log("msg", "Invalid query type", "Type seen", module.DNS.QueryType, "Existing types", dns.TypeToString)
+                       return false
+               }
+       }
+       var probeDNSSOAGauge prometheus.Gauge
+
        var ip *net.IPAddr
        if module.DNS.TransportProtocol == "" {
                module.DNS.TransportProtocol = "udp"
@@ -154,15 +165,6 @@ func ProbeDNS(ctx context.Context, target string, module config.Module, registry
                }
        }
 
-       qt := dns.TypeANY
-       if module.DNS.QueryType != "" {
-               var ok bool
-               qt, ok = dns.StringToType[module.DNS.QueryType]
-               if !ok {
-                       level.Error(logger).Log("msg", "Invalid query type", "Type seen", module.DNS.QueryType, "Existing types", dns.TypeToString)
-                       return false
-               }
-       }
        msg := new(dns.Msg)
        msg.SetQuestion(dns.Fqdn(module.DNS.QueryName), qt)
 
@@ -180,6 +182,20 @@ func ProbeDNS(ctx context.Context, target string, module config.Module, registry
        probeDNSAuthorityRRSGauge.Set(float64(len(response.Ns)))
        probeDNSAdditionalRRSGauge.Set(float64(len(response.Extra)))
 
+       if qt == dns.TypeSOA {
+               probeDNSSOAGauge = prometheus.NewGauge(prometheus.GaugeOpts{
+                       Name: "probe_dns_serial",
+                       Help: "Returns the serial number of the zone",
+               })
+               registry.MustRegister(probeDNSSOAGauge)
+
+               for _, a := range response.Answer {
+                       if soa, ok := a.(*dns.SOA); ok {
+                               probeDNSSOAGauge.Set(float64(soa.Serial))
+                       }
+               }
+       }
+
        if !validRcode(response.Rcode, module.DNS.ValidRcodes, logger) {
                return false
        }
index e40f431c5f117a12dde9681a0f09093cd24cd579..f0b6f4085f2deaf3ebeb502299de2f5cc42878b5 100644 (file)
@@ -165,11 +165,20 @@ func authoritativeDNSHandler(w dns.ResponseWriter, r *dns.Msg) {
        m := new(dns.Msg)
        m.SetReply(r)
 
-       a, err := dns.NewRR("example.com. 3600 IN A 127.0.0.1")
-       if err != nil {
-               panic(err)
+       if r.Question[0].Qtype == dns.TypeSOA {
+               a, err := dns.NewRR("example.com. 3600 IN SOA ns.example.com. noc.example.com. 1000 7200 3600 1209600 3600")
+               if err != nil {
+                       panic(err)
+               }
+               m.Answer = append(m.Answer, a)
+
+       } else {
+               a, err := dns.NewRR("example.com. 3600 IN A 127.0.0.1")
+               if err != nil {
+                       panic(err)
+               }
+               m.Answer = append(m.Answer, a)
        }
-       m.Answer = append(m.Answer, a)
 
        authority := []string{
                "example.com. 7200 IN NS ns1.isp.net.",
@@ -213,6 +222,12 @@ func TestAuthoritativeDNSResponse(t *testing.T) {
                        }, true,
                },
                {
+                       config.DNSProbe{
+                               PreferredIPProtocol: "ipv4",
+                               QueryName:           "example.com",
+                               QueryType:           "SOA",
+                       }, true,
+               }, {
                        config.DNSProbe{
                                PreferredIPProtocol: "ipv4",
                                QueryName:           "example.com",
@@ -290,6 +305,10 @@ func TestAuthoritativeDNSResponse(t *testing.T) {
                                "probe_dns_authority_rrs":  2,
                                "probe_dns_additional_rrs": 3,
                        }
+                       if test.Probe.QueryType == "SOA" {
+                               expectedResults["probe_dns_serial"] = 1000
+                       }
+
                        checkRegistryResults(expectedResults, mfs, t)
                }
        }