mirror of
				https://github.com/coredns/coredns.git
				synced 2025-11-03 18:53:13 -05:00 
			
		
		
		
	This fix adds PTR record support for Route53 plugin This fix fixes 1595 Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
		
			
				
	
	
		
			113 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// 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)
 | 
						|
	case dns.TypePTR:
 | 
						|
		answers = ptr(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
 | 
						|
}
 | 
						|
 | 
						|
func ptr(zone string, rrss []*route53.ResourceRecordSet) []dns.RR {
 | 
						|
	answers := []dns.RR{}
 | 
						|
	for _, rrs := range rrss {
 | 
						|
		for _, rr := range rrs.ResourceRecords {
 | 
						|
			r := new(dns.PTR)
 | 
						|
			r.Hdr = dns.RR_Header{Name: zone, Rrtype: dns.TypePTR, Class: dns.ClassINET, Ttl: uint32(aws.Int64Value(rrs.TTL))}
 | 
						|
			r.Ptr = aws.StringValue(rr.Value)
 | 
						|
			answers = append(answers, r)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return answers
 | 
						|
}
 | 
						|
 | 
						|
// Name implements the Handler interface.
 | 
						|
func (rr Route53) Name() string { return "route53" }
 |