Add route53 plugin (#1390)
* Update vendor Signed-off-by: Yong Tang <yong.tang.github@outlook.com> * Add route53 plugin This fix adds route53 plugin so that it is possible to query route53 record through CoreDNS. Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
This commit is contained in:
parent
d699b89063
commit
584dd87c70
352 changed files with 81636 additions and 1798 deletions
97
plugin/route53/route53.go
Normal file
97
plugin/route53/route53.go
Normal file
|
@ -0,0 +1,97 @@
|
|||
// Package route53 implements a plugin that returns resource records
|
||||
// from AWS route53
|
||||
package route53
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/coredns/coredns/plugin"
|
||||
"github.com/coredns/coredns/request"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/route53"
|
||||
"github.com/aws/aws-sdk-go/service/route53/route53iface"
|
||||
"github.com/miekg/dns"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// Route53 is a plugin that returns RR from AWS route53
|
||||
type Route53 struct {
|
||||
Next plugin.Handler
|
||||
|
||||
zones []string
|
||||
keys map[string]string
|
||||
client route53iface.Route53API
|
||||
}
|
||||
|
||||
// ServeDNS implements the plugin.Handler interface.
|
||||
func (rr Route53) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
|
||||
state := request.Request{W: w, Req: r}
|
||||
qname := state.Name()
|
||||
|
||||
zone := plugin.Zones(rr.zones).Matches(qname)
|
||||
if zone == "" {
|
||||
return plugin.NextOrFailure(rr.Name(), rr.Next, ctx, w, r)
|
||||
}
|
||||
|
||||
output, err := rr.client.ListResourceRecordSets(&route53.ListResourceRecordSetsInput{
|
||||
HostedZoneId: aws.String(rr.keys[zone]),
|
||||
StartRecordName: aws.String(qname),
|
||||
StartRecordType: aws.String(state.Type()),
|
||||
MaxItems: aws.String("1"),
|
||||
})
|
||||
if err != nil {
|
||||
return dns.RcodeServerFailure, err
|
||||
}
|
||||
|
||||
answers := []dns.RR{}
|
||||
switch state.QType() {
|
||||
case dns.TypeA:
|
||||
answers = a(qname, output.ResourceRecordSets)
|
||||
case dns.TypeAAAA:
|
||||
answers = aaaa(qname, output.ResourceRecordSets)
|
||||
}
|
||||
|
||||
if len(answers) == 0 {
|
||||
return plugin.NextOrFailure(rr.Name(), rr.Next, ctx, w, r)
|
||||
}
|
||||
|
||||
m := new(dns.Msg)
|
||||
m.SetReply(r)
|
||||
m.Authoritative, m.RecursionAvailable, m.Compress = true, true, true
|
||||
m.Answer = answers
|
||||
|
||||
state.SizeAndDo(m)
|
||||
m, _ = state.Scrub(m)
|
||||
w.WriteMsg(m)
|
||||
return dns.RcodeSuccess, nil
|
||||
}
|
||||
|
||||
func a(zone string, rrss []*route53.ResourceRecordSet) []dns.RR {
|
||||
answers := []dns.RR{}
|
||||
for _, rrs := range rrss {
|
||||
for _, rr := range rrs.ResourceRecords {
|
||||
r := new(dns.A)
|
||||
r.Hdr = dns.RR_Header{Name: zone, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: uint32(aws.Int64Value(rrs.TTL))}
|
||||
r.A = net.ParseIP(aws.StringValue(rr.Value)).To4()
|
||||
answers = append(answers, r)
|
||||
}
|
||||
}
|
||||
return answers
|
||||
}
|
||||
|
||||
func aaaa(zone string, rrss []*route53.ResourceRecordSet) []dns.RR {
|
||||
answers := []dns.RR{}
|
||||
for _, rrs := range rrss {
|
||||
for _, rr := range rrs.ResourceRecords {
|
||||
r := new(dns.AAAA)
|
||||
r.Hdr = dns.RR_Header{Name: zone, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: uint32(aws.Int64Value(rrs.TTL))}
|
||||
r.AAAA = net.ParseIP(aws.StringValue(rr.Value)).To16()
|
||||
answers = append(answers, r)
|
||||
}
|
||||
}
|
||||
return answers
|
||||
}
|
||||
|
||||
// Name implements the Handler interface.
|
||||
func (rr Route53) Name() string { return "route53" }
|
Loading…
Add table
Add a link
Reference in a new issue