diff options
Diffstat (limited to 'plugin/azure/azure.go')
-rw-r--r-- | plugin/azure/azure.go | 145 |
1 files changed, 125 insertions, 20 deletions
diff --git a/plugin/azure/azure.go b/plugin/azure/azure.go index 8432af316..f65503947 100644 --- a/plugin/azure/azure.go +++ b/plugin/azure/azure.go @@ -13,53 +13,68 @@ import ( "github.com/coredns/coredns/plugin/pkg/upstream" "github.com/coredns/coredns/request" - azuredns "github.com/Azure/azure-sdk-for-go/profiles/latest/dns/mgmt/dns" + publicdns "github.com/Azure/azure-sdk-for-go/profiles/latest/dns/mgmt/dns" + privatedns "github.com/Azure/azure-sdk-for-go/profiles/latest/privatedns/mgmt/privatedns" "github.com/miekg/dns" ) type zone struct { - id string - z *file.Zone - zone string + id string + z *file.Zone + zone string + private bool } type zones map[string][]*zone // Azure is the core struct of the azure plugin. type Azure struct { - zoneNames []string - client azuredns.RecordSetsClient - upstream *upstream.Upstream - zMu sync.RWMutex - zones zones + zoneNames []string + publicClient publicdns.RecordSetsClient + privateClient privatedns.RecordSetsClient + upstream *upstream.Upstream + zMu sync.RWMutex + zones zones Next plugin.Handler Fall fall.F } // New validates the input DNS zones and initializes the Azure struct. -func New(ctx context.Context, dnsClient azuredns.RecordSetsClient, keys map[string][]string) (*Azure, error) { +func New(ctx context.Context, publicClient publicdns.RecordSetsClient, privateClient privatedns.RecordSetsClient, keys map[string][]string, accessMap map[string]string) (*Azure, error) { zones := make(map[string][]*zone, len(keys)) names := make([]string, len(keys)) + var private bool for resourceGroup, znames := range keys { for _, name := range znames { - if _, err := dnsClient.ListAllByDNSZone(context.Background(), resourceGroup, name, nil, ""); err != nil { - return nil, err + switch accessMap[resourceGroup+name] { + case "public": + if _, err := publicClient.ListAllByDNSZone(context.Background(), resourceGroup, name, nil, ""); err != nil { + return nil, err + } + private = false + case "private": + if _, err := privateClient.ListComplete(context.Background(), resourceGroup, name, nil, ""); err != nil { + return nil, err + } + private = true } fqdn := dns.Fqdn(name) if _, ok := zones[fqdn]; !ok { names = append(names, fqdn) } - zones[fqdn] = append(zones[fqdn], &zone{id: resourceGroup, zone: fqdn, z: file.NewZone(fqdn, "")}) + zones[fqdn] = append(zones[fqdn], &zone{id: resourceGroup, zone: name, private: private, z: file.NewZone(fqdn, "")}) } } + return &Azure{ - client: dnsClient, - zones: zones, - zoneNames: names, - upstream: upstream.New(), + publicClient: publicClient, + privateClient: privateClient, + zones: zones, + zoneNames: names, + upstream: upstream.New(), }, nil } @@ -85,14 +100,23 @@ func (h *Azure) Run(ctx context.Context) error { } func (h *Azure) updateZones(ctx context.Context) error { + var err error + var publicSet publicdns.RecordSetListResultPage + var privateSet privatedns.RecordSetListResultPage + var newZ *file.Zone errs := make([]string, 0) for zName, z := range h.zones { for i, hostedZone := range z { - recordSet, err := h.client.ListByDNSZone(ctx, hostedZone.id, hostedZone.zone, nil, "") + if hostedZone.private { + privateSet, err = h.privateClient.List(ctx, hostedZone.id, hostedZone.zone, nil, "") + newZ = updateZoneFromPrivateResourceSet(privateSet, zName) + } else { + publicSet, err = h.publicClient.ListByDNSZone(ctx, hostedZone.id, hostedZone.zone, nil, "") + newZ = updateZoneFromPublicResourceSet(publicSet, zName) + } if err != nil { errs = append(errs, fmt.Sprintf("failed to list resource records for %v from azure: %v", hostedZone.zone, err)) } - newZ := updateZoneFromResourceSet(recordSet, zName) newZ.Upstream = h.upstream h.zMu.Lock() (*z[i]).z = newZ @@ -107,7 +131,7 @@ func (h *Azure) updateZones(ctx context.Context) error { } -func updateZoneFromResourceSet(recordSet azuredns.RecordSetListResultPage, zName string) *file.Zone { +func updateZoneFromPublicResourceSet(recordSet publicdns.RecordSetListResultPage, zName string) *file.Zone { newZ := file.NewZone(zName, "") for _, result := range *(recordSet.Response().Value) { @@ -196,6 +220,87 @@ func updateZoneFromResourceSet(recordSet azuredns.RecordSetListResultPage, zName return newZ } +func updateZoneFromPrivateResourceSet(recordSet privatedns.RecordSetListResultPage, zName string) *file.Zone { + newZ := file.NewZone(zName, "") + + for _, result := range *(recordSet.Response().Value) { + resultFqdn := *(result.RecordSetProperties.Fqdn) + resultTTL := uint32(*(result.RecordSetProperties.TTL)) + if result.RecordSetProperties.ARecords != nil { + for _, A := range *(result.RecordSetProperties.ARecords) { + a := &dns.A{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: resultTTL}, + A: net.ParseIP(*(A.Ipv4Address))} + newZ.Insert(a) + } + } + if result.RecordSetProperties.AaaaRecords != nil { + for _, AAAA := range *(result.RecordSetProperties.AaaaRecords) { + aaaa := &dns.AAAA{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: resultTTL}, + AAAA: net.ParseIP(*(AAAA.Ipv6Address))} + newZ.Insert(aaaa) + } + } + + if result.RecordSetProperties.MxRecords != nil { + for _, MX := range *(result.RecordSetProperties.MxRecords) { + mx := &dns.MX{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: resultTTL}, + Preference: uint16(*(MX.Preference)), + Mx: dns.Fqdn(*(MX.Exchange))} + newZ.Insert(mx) + } + } + + if result.RecordSetProperties.PtrRecords != nil { + for _, PTR := range *(result.RecordSetProperties.PtrRecords) { + ptr := &dns.PTR{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypePTR, Class: dns.ClassINET, Ttl: resultTTL}, + Ptr: dns.Fqdn(*(PTR.Ptrdname))} + newZ.Insert(ptr) + } + } + + if result.RecordSetProperties.SrvRecords != nil { + for _, SRV := range *(result.RecordSetProperties.SrvRecords) { + srv := &dns.SRV{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeSRV, Class: dns.ClassINET, Ttl: resultTTL}, + Priority: uint16(*(SRV.Priority)), + Weight: uint16(*(SRV.Weight)), + Port: uint16(*(SRV.Port)), + Target: dns.Fqdn(*(SRV.Target))} + newZ.Insert(srv) + } + } + + if result.RecordSetProperties.TxtRecords != nil { + for _, TXT := range *(result.RecordSetProperties.TxtRecords) { + txt := &dns.TXT{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: resultTTL}, + Txt: *(TXT.Value)} + newZ.Insert(txt) + } + } + + if result.RecordSetProperties.SoaRecord != nil { + SOA := result.RecordSetProperties.SoaRecord + soa := &dns.SOA{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeSOA, Class: dns.ClassINET, Ttl: resultTTL}, + Minttl: uint32(*(SOA.MinimumTTL)), + Expire: uint32(*(SOA.ExpireTime)), + Retry: uint32(*(SOA.RetryTime)), + Refresh: uint32(*(SOA.RefreshTime)), + Serial: uint32(*(SOA.SerialNumber)), + Mbox: dns.Fqdn(*(SOA.Email)), + Ns: *(SOA.Host)} + newZ.Insert(soa) + } + + if result.RecordSetProperties.CnameRecord != nil { + CNAME := result.RecordSetProperties.CnameRecord.Cname + cname := &dns.CNAME{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeCNAME, Class: dns.ClassINET, Ttl: resultTTL}, + Target: dns.Fqdn(*CNAME)} + newZ.Insert(cname) + } + + } + return newZ +} + // ServeDNS implements the plugin.Handler interface. func (h *Azure) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { state := request.Request{W: w, Req: r} |