gatus/core/dns.go

87 lines
2.0 KiB
Go
Raw Normal View History

2020-11-18 00:55:31 +01:00
package core
import (
"errors"
"fmt"
"strings"
"github.com/miekg/dns"
)
var (
2020-11-19 13:59:03 +01:00
// ErrDNSWithNoQueryName is the error with which gatus will panic if a dns is configured without query name
2020-11-20 03:10:59 +01:00
ErrDNSWithNoQueryName = errors.New("you must specify a query name for DNS")
2020-11-30 01:03:40 +01:00
2020-11-19 13:59:03 +01:00
// ErrDNSWithInvalidQueryType is the error with which gatus will panic if a dns is configured with invalid query type
2020-11-18 00:55:31 +01:00
ErrDNSWithInvalidQueryType = errors.New("invalid query type")
)
const (
dnsPort = 53
)
// DNS is the configuration for a Endpoint of type DNS
2020-11-18 00:55:31 +01:00
type DNS struct {
// QueryType is the type for the DNS records like A, AAAA, CNAME...
2020-11-18 00:55:31 +01:00
QueryType string `yaml:"query-type"`
2020-11-30 01:03:40 +01:00
2020-11-18 00:55:31 +01:00
// QueryName is the query for DNS
QueryName string `yaml:"query-name"`
}
func (d *DNS) validateAndSetDefault() error {
2020-11-18 00:55:31 +01:00
if len(d.QueryName) == 0 {
return ErrDNSWithNoQueryName
2020-11-18 00:55:31 +01:00
}
if !strings.HasSuffix(d.QueryName, ".") {
d.QueryName += "."
}
if _, ok := dns.StringToType[d.QueryType]; !ok {
return ErrDNSWithInvalidQueryType
2020-11-18 00:55:31 +01:00
}
return nil
2020-11-18 00:55:31 +01:00
}
func (d *DNS) query(url string, result *Result) {
if !strings.Contains(url, ":") {
url = fmt.Sprintf("%s:%d", url, dnsPort)
}
queryType := dns.StringToType[d.QueryType]
c := new(dns.Client)
m := new(dns.Msg)
m.SetQuestion(d.QueryName, queryType)
r, _, err := c.Exchange(m, url)
if err != nil {
2021-06-06 00:51:51 +02:00
result.AddError(err.Error())
2020-11-18 00:55:31 +01:00
return
}
result.Connected = true
result.DNSRCode = dns.RcodeToString[r.Rcode]
for _, rr := range r.Answer {
switch rr.Header().Rrtype {
case dns.TypeA:
if a, ok := rr.(*dns.A); ok {
result.body = []byte(a.A.String())
2020-11-18 00:55:31 +01:00
}
case dns.TypeAAAA:
if aaaa, ok := rr.(*dns.AAAA); ok {
result.body = []byte(aaaa.AAAA.String())
2020-11-18 00:55:31 +01:00
}
case dns.TypeCNAME:
if cname, ok := rr.(*dns.CNAME); ok {
result.body = []byte(cname.Target)
2020-11-18 00:55:31 +01:00
}
case dns.TypeMX:
if mx, ok := rr.(*dns.MX); ok {
result.body = []byte(mx.Mx)
2020-11-18 00:55:31 +01:00
}
case dns.TypeNS:
if ns, ok := rr.(*dns.NS); ok {
result.body = []byte(ns.Ns)
2020-11-18 00:55:31 +01:00
}
default:
result.body = []byte("query type is not supported yet")
2020-11-18 00:55:31 +01:00
}
}
}