Skip to content

Commit

Permalink
Handle not-found differently to errors
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewheberle committed Jan 10, 2022
1 parent e3d4d6e commit f7cca1e
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 27 deletions.
20 changes: 13 additions & 7 deletions netbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,29 +60,35 @@ func (n Netbox) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg)
ip_address string
record4 *dns.A
record6 *dns.AAAA
err error
)

qname := state.Name()

switch state.QType() {

case dns.TypeA:
ip_address = query(n.Url, n.Token, strings.TrimRight(qname, "."), n.CacheDuration, 4)
ip_address, err = query(n.Url, n.Token, strings.TrimRight(qname, "."), n.CacheDuration, 4)
// no IP is found in netbox pass processing to the next plugin
record4 = a(state, ip_address, uint32(n.TTL))
case dns.TypeAAAA:
ip_address = query(n.Url, n.Token, strings.TrimRight(qname, "."), n.CacheDuration, 6)
ip_address, err = query(n.Url, n.Token, strings.TrimRight(qname, "."), n.CacheDuration, 6)
record6 = a6(state, ip_address, uint32(n.TTL))
}

if len(ip_address) == 0 {
// check if we fallthrough
if n.Fall.Through(qname) {
return plugin.NextOrFailure(n.Name(), n.Next, ctx, w, r)
// always fallthrough if configured
if n.Fall.Through(qname) {
return plugin.NextOrFailure(n.Name(), n.Next, ctx, w, r)
}

// return failure here without fallthrough
return dnserror(dns.RcodeServerFailure, state, err)
if err != nil {
// return SERVFAIL here without fallthrough
return dnserror(dns.RcodeServerFailure, state, err)
}

// otherwise return NXDOMAIN
return dnserror(dns.RcodeNameError, state, nil)
}

writeDNSAnswer(record4, record6, w, r)
Expand Down
30 changes: 15 additions & 15 deletions query.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,10 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
logger "log"
"net/http"
"strings"
"time"

clog "github.com/coredns/coredns/plugin/pkg/log"
"github.com/imkira/go-ttlmap"
)

Expand All @@ -43,26 +41,29 @@ type RecordsList struct {

var localCache = ttlmap.New(nil)

func query(url, token, dns_name string, duration time.Duration, family int) string {
func query(url, token, dns_name string, duration time.Duration, family int) (string, error) {
item, err := localCache.Get(dns_name)
if err == nil {
clog.Debug(fmt.Sprintf("Found in local cache %s", dns_name))
logger.Printf("Found in local cache %s", dns_name)
return item.Value().(string)
log.Debugf("Found in local cache %s", dns_name)
return item.Value().(string), nil
} else {
records := RecordsList{}
client := &http.Client{}
var resp *http.Response
clog.Debug("Querying ", fmt.Sprintf("%s/?dns_name=%s", url, dns_name))
log.Debugf("Querying %s/?dns_name=%s", url, dns_name)
//logger.Printf("Querying %s ", fmt.Sprintf("%s/?dns_name=%s", url, dns_name))
req, err := http.NewRequest("GET", fmt.Sprintf("%s/?dns_name=%s", url, dns_name), nil)
if err != nil {
return "", err
}

req.Header.Set("Authorization", fmt.Sprintf("Token %s", token))

for i := 1; i <= 10; i++ {
resp, err = client.Do(req)

if err != nil {
clog.Fatalf("HTTP Error %v", err)
return "", err
}

if resp.StatusCode == http.StatusOK {
Expand All @@ -73,24 +74,23 @@ func query(url, token, dns_name string, duration time.Duration, family int) stri
}

if resp.StatusCode != http.StatusOK {
return ""
return "", fmt.Errorf("invalid HTTP resoponse code: %d", resp.StatusCode)
}

body, err := ioutil.ReadAll(resp.Body)
//logger.Printf("%s", body)
if err != nil {
clog.Fatalf("Error reading body %v", err)
return "", err
}

jsonAns := string(body)
err = json.Unmarshal([]byte(jsonAns), &records)
if err != nil {
clog.Fatalf("could not unmarshal response %v", err)
return "", err
}

if len(records.Records) == 0 {
clog.Info("Recored not found in", jsonAns)
return ""
log.Debugf("recored not found response: %s", jsonAns)
return "", nil
}

var ip_address string
Expand All @@ -113,6 +113,6 @@ func query(url, token, dns_name string, duration time.Duration, family int) stri
}

}
return ip_address
return ip_address, nil
}
}
10 changes: 5 additions & 5 deletions query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func TestQuery(t *testing.T) {
200).BodyString(anotherHostWithIPv4)

want := "10.0.0.2"
got := query("https://example.org/api/ipam/ip-addresses", "mytoken", "my_host", time.Millisecond*100, 4)
got, _ := query("https://example.org/api/ipam/ip-addresses", "mytoken", "my_host", time.Millisecond*100, 4)
if got != want {
t.Fatalf("Expected %s but got %s", want, got)
}
Expand All @@ -57,7 +57,7 @@ func TestQueryIPv6(t *testing.T) {
200).BodyString(hostWithIPv6)

want := "fe80::250:56ff:fe3d:83af"
got := query("https://example.org/api/ipam/ip-addresses", "mytoken", "mail.foo.com", time.Millisecond*100, 6)
got, _ := query("https://example.org/api/ipam/ip-addresses", "mytoken", "mail.foo.com", time.Millisecond*100, 6)
if got != want {
t.Fatalf("Expected %s but got %s", want, got)
}
Expand All @@ -70,7 +70,7 @@ func TestQueryMultipleAddresses(t *testing.T) {
map[string]string{"dns_name": "mail.foo.com"}).Reply(
200).BodyString(hostWithMultipleAddresses)
want := "fe80::250:56ff:fe3d:83af"
got := query("https://example.org/api/ipam/ip-addresses", "mytoken", "mail.foo.com", time.Millisecond*100, 6)
got, _ := query("https://example.org/api/ipam/ip-addresses", "mytoken", "mail.foo.com", time.Millisecond*100, 6)
if got != want {
t.Fatalf("Expected %s but got %s", want, got)
}
Expand All @@ -84,7 +84,7 @@ func TestNoSuchHost(t *testing.T) {
200).BodyString(`{"count":0,"next":null,"previous":null,"results":[]}`)

want := ""
got := query("https://example.org/api/ipam/ip-addresses", "mytoken", "NoSuchHost", time.Millisecond*100, 4)
got, _ := query("https://example.org/api/ipam/ip-addresses", "mytoken", "NoSuchHost", time.Millisecond*100, 4)
if got != want {
t.Fatalf("Expected empty string but got %s", got)
}
Expand All @@ -99,7 +99,7 @@ func TestLocalCache(t *testing.T) {

ip_address := ""

got := query("https://example.org/api/ipam/ip-addresses", "mytoken", "my_host", time.Millisecond*100, 4)
got, _ := query("https://example.org/api/ipam/ip-addresses", "mytoken", "my_host", time.Millisecond*100, 4)

item, err := localCache.Get("my_host")
if err == nil {
Expand Down

0 comments on commit f7cca1e

Please sign in to comment.