| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | package azure
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import (
 | 
					
						
							|  |  |  | 	"context"
 | 
					
						
							|  |  |  | 	"fmt"
 | 
					
						
							|  |  |  | 	"net"
 | 
					
						
							|  |  |  | 	"sync"
 | 
					
						
							|  |  |  | 	"time"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/coredns/coredns/plugin"
 | 
					
						
							|  |  |  | 	"github.com/coredns/coredns/plugin/file"
 | 
					
						
							|  |  |  | 	"github.com/coredns/coredns/plugin/pkg/fall"
 | 
					
						
							|  |  |  | 	"github.com/coredns/coredns/plugin/pkg/upstream"
 | 
					
						
							|  |  |  | 	"github.com/coredns/coredns/request"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-11 00:52:23 +05:30
										 |  |  | 	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"
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 	"github.com/miekg/dns"
 | 
					
						
							|  |  |  | )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type zone struct {
 | 
					
						
							| 
									
										
										
										
											2020-03-11 00:52:23 +05:30
										 |  |  | 	id      string
 | 
					
						
							|  |  |  | 	z       *file.Zone
 | 
					
						
							|  |  |  | 	zone    string
 | 
					
						
							|  |  |  | 	private bool
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type zones map[string][]*zone
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Azure is the core struct of the azure plugin.
 | 
					
						
							|  |  |  | type Azure struct {
 | 
					
						
							| 
									
										
										
										
											2020-03-11 00:52:23 +05:30
										 |  |  | 	zoneNames     []string
 | 
					
						
							|  |  |  | 	publicClient  publicdns.RecordSetsClient
 | 
					
						
							|  |  |  | 	privateClient privatedns.RecordSetsClient
 | 
					
						
							|  |  |  | 	upstream      *upstream.Upstream
 | 
					
						
							|  |  |  | 	zMu           sync.RWMutex
 | 
					
						
							|  |  |  | 	zones         zones
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Next plugin.Handler
 | 
					
						
							|  |  |  | 	Fall fall.F
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // New validates the input DNS zones and initializes the Azure struct.
 | 
					
						
							| 
									
										
										
										
											2020-03-11 00:52:23 +05:30
										 |  |  | func New(ctx context.Context, publicClient publicdns.RecordSetsClient, privateClient privatedns.RecordSetsClient, keys map[string][]string, accessMap map[string]string) (*Azure, error) {
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 	zones := make(map[string][]*zone, len(keys))
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 	names := make([]string, len(keys))
 | 
					
						
							| 
									
										
										
										
											2020-03-11 00:52:23 +05:30
										 |  |  | 	var private bool
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for resourceGroup, znames := range keys {
 | 
					
						
							|  |  |  | 		for _, name := range znames {
 | 
					
						
							| 
									
										
										
										
											2020-03-11 00:52:23 +05:30
										 |  |  | 			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
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 			}
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			fqdn := dns.Fqdn(name)
 | 
					
						
							|  |  |  | 			if _, ok := zones[fqdn]; !ok {
 | 
					
						
							|  |  |  | 				names = append(names, fqdn)
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 			}
 | 
					
						
							| 
									
										
										
										
											2020-03-11 00:52:23 +05:30
										 |  |  | 			zones[fqdn] = append(zones[fqdn], &zone{id: resourceGroup, zone: name, private: private, z: file.NewZone(fqdn, "")})
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 		}
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							| 
									
										
										
										
											2020-03-11 00:52:23 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 	return &Azure{
 | 
					
						
							| 
									
										
										
										
											2020-03-11 00:52:23 +05:30
										 |  |  | 		publicClient:  publicClient,
 | 
					
						
							|  |  |  | 		privateClient: privateClient,
 | 
					
						
							|  |  |  | 		zones:         zones,
 | 
					
						
							|  |  |  | 		zoneNames:     names,
 | 
					
						
							|  |  |  | 		upstream:      upstream.New(),
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 	}, nil
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Run updates the zone from azure.
 | 
					
						
							|  |  |  | func (h *Azure) Run(ctx context.Context) error {
 | 
					
						
							|  |  |  | 	if err := h.updateZones(ctx); err != nil {
 | 
					
						
							|  |  |  | 		return err
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 	go func() {
 | 
					
						
							| 
									
										
										
										
											2022-03-04 02:36:02 -05:00
										 |  |  | 		delay := 1 * time.Minute
 | 
					
						
							|  |  |  | 		timer := time.NewTimer(delay)
 | 
					
						
							|  |  |  | 		defer timer.Stop()
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 		for {
 | 
					
						
							| 
									
										
										
										
											2022-03-04 02:36:02 -05:00
										 |  |  | 			timer.Reset(delay)
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 			select {
 | 
					
						
							|  |  |  | 			case <-ctx.Done():
 | 
					
						
							| 
									
										
										
										
											2020-10-24 05:37:01 -07:00
										 |  |  | 				log.Debugf("Breaking out of Azure update loop for %v: %v", h.zoneNames, ctx.Err())
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 				return
 | 
					
						
							| 
									
										
										
										
											2022-03-04 02:36:02 -05:00
										 |  |  | 			case <-timer.C:
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 				if err := h.updateZones(ctx); err != nil && ctx.Err() == nil {
 | 
					
						
							| 
									
										
										
										
											2020-10-24 05:37:01 -07:00
										 |  |  | 					log.Errorf("Failed to update zones %v: %v", h.zoneNames, err)
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 				}
 | 
					
						
							|  |  |  | 			}
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 	}()
 | 
					
						
							|  |  |  | 	return nil
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (h *Azure) updateZones(ctx context.Context) error {
 | 
					
						
							| 
									
										
										
										
											2020-03-11 00:52:23 +05:30
										 |  |  | 	var err error
 | 
					
						
							|  |  |  | 	var publicSet publicdns.RecordSetListResultPage
 | 
					
						
							|  |  |  | 	var privateSet privatedns.RecordSetListResultPage
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 	errs := make([]string, 0)
 | 
					
						
							|  |  |  | 	for zName, z := range h.zones {
 | 
					
						
							|  |  |  | 		for i, hostedZone := range z {
 | 
					
						
							| 
									
										
										
										
											2020-12-23 11:12:47 +01:00
										 |  |  | 			newZ := file.NewZone(zName, "")
 | 
					
						
							| 
									
										
										
										
											2020-03-11 00:52:23 +05:30
										 |  |  | 			if hostedZone.private {
 | 
					
						
							| 
									
										
										
										
											2020-12-23 11:12:47 +01:00
										 |  |  | 				for privateSet, err = h.privateClient.List(ctx, hostedZone.id, hostedZone.zone, nil, ""); privateSet.NotDone(); err = privateSet.NextWithContext(ctx) {
 | 
					
						
							|  |  |  | 					updateZoneFromPrivateResourceSet(privateSet, newZ)
 | 
					
						
							|  |  |  | 				}
 | 
					
						
							| 
									
										
										
										
											2020-03-11 00:52:23 +05:30
										 |  |  | 			} else {
 | 
					
						
							| 
									
										
										
										
											2020-12-23 11:12:47 +01:00
										 |  |  | 				for publicSet, err = h.publicClient.ListByDNSZone(ctx, hostedZone.id, hostedZone.zone, nil, ""); publicSet.NotDone(); err = publicSet.NextWithContext(ctx) {
 | 
					
						
							|  |  |  | 					updateZoneFromPublicResourceSet(publicSet, newZ)
 | 
					
						
							|  |  |  | 				}
 | 
					
						
							| 
									
										
										
										
											2020-03-11 00:52:23 +05:30
										 |  |  | 			}
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 			if err != nil {
 | 
					
						
							|  |  |  | 				errs = append(errs, fmt.Sprintf("failed to list resource records for %v from azure: %v", hostedZone.zone, err))
 | 
					
						
							|  |  |  | 			}
 | 
					
						
							|  |  |  | 			newZ.Upstream = h.upstream
 | 
					
						
							|  |  |  | 			h.zMu.Lock()
 | 
					
						
							|  |  |  | 			(*z[i]).z = newZ
 | 
					
						
							|  |  |  | 			h.zMu.Unlock()
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if len(errs) != 0 {
 | 
					
						
							|  |  |  | 		return fmt.Errorf("errors updating zones: %v", errs)
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 	return nil
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-23 11:12:47 +01:00
										 |  |  | func updateZoneFromPublicResourceSet(recordSet publicdns.RecordSetListResultPage, newZ *file.Zone) {
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 	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) {
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 				a := &dns.A{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: resultTTL},
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 					A: net.ParseIP(*(A.Ipv4Address))}
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 				newZ.Insert(a)
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 			}
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if result.RecordSetProperties.AaaaRecords != nil {
 | 
					
						
							|  |  |  | 			for _, AAAA := range *(result.RecordSetProperties.AaaaRecords) {
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 				aaaa := &dns.AAAA{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: resultTTL},
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 					AAAA: net.ParseIP(*(AAAA.Ipv6Address))}
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 				newZ.Insert(aaaa)
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 			}
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if result.RecordSetProperties.MxRecords != nil {
 | 
					
						
							|  |  |  | 			for _, MX := range *(result.RecordSetProperties.MxRecords) {
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 				mx := &dns.MX{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: resultTTL},
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 					Preference: uint16(*(MX.Preference)),
 | 
					
						
							|  |  |  | 					Mx:         dns.Fqdn(*(MX.Exchange))}
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 				newZ.Insert(mx)
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 			}
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if result.RecordSetProperties.PtrRecords != nil {
 | 
					
						
							|  |  |  | 			for _, PTR := range *(result.RecordSetProperties.PtrRecords) {
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 				ptr := &dns.PTR{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypePTR, Class: dns.ClassINET, Ttl: resultTTL},
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 					Ptr: dns.Fqdn(*(PTR.Ptrdname))}
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 				newZ.Insert(ptr)
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 			}
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if result.RecordSetProperties.SrvRecords != nil {
 | 
					
						
							|  |  |  | 			for _, SRV := range *(result.RecordSetProperties.SrvRecords) {
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 				srv := &dns.SRV{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeSRV, Class: dns.ClassINET, Ttl: resultTTL},
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 					Priority: uint16(*(SRV.Priority)),
 | 
					
						
							|  |  |  | 					Weight:   uint16(*(SRV.Weight)),
 | 
					
						
							|  |  |  | 					Port:     uint16(*(SRV.Port)),
 | 
					
						
							|  |  |  | 					Target:   dns.Fqdn(*(SRV.Target))}
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 				newZ.Insert(srv)
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 			}
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if result.RecordSetProperties.TxtRecords != nil {
 | 
					
						
							|  |  |  | 			for _, TXT := range *(result.RecordSetProperties.TxtRecords) {
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 				txt := &dns.TXT{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: resultTTL},
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 					Txt: *(TXT.Value)}
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 				newZ.Insert(txt)
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 			}
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if result.RecordSetProperties.NsRecords != nil {
 | 
					
						
							|  |  |  | 			for _, NS := range *(result.RecordSetProperties.NsRecords) {
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 				ns := &dns.NS{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeNS, Class: dns.ClassINET, Ttl: resultTTL},
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 					Ns: *(NS.Nsdname)}
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 				newZ.Insert(ns)
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 			}
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if result.RecordSetProperties.SoaRecord != nil {
 | 
					
						
							|  |  |  | 			SOA := result.RecordSetProperties.SoaRecord
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 			soa := &dns.SOA{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeSOA, Class: dns.ClassINET, Ttl: resultTTL},
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 				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)}
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 			newZ.Insert(soa)
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 		}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if result.RecordSetProperties.CnameRecord != nil {
 | 
					
						
							|  |  |  | 			CNAME := result.RecordSetProperties.CnameRecord.Cname
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 			cname := &dns.CNAME{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeCNAME, Class: dns.ClassINET, Ttl: resultTTL},
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 				Target: dns.Fqdn(*CNAME)}
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 			newZ.Insert(cname)
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 		}
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-23 11:12:47 +01:00
										 |  |  | func updateZoneFromPrivateResourceSet(recordSet privatedns.RecordSetListResultPage, newZ *file.Zone) {
 | 
					
						
							| 
									
										
										
										
											2020-03-11 00:52:23 +05:30
										 |  |  | 	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)),
 | 
					
						
							| 
									
										
										
										
											2020-11-12 14:48:03 +00:00
										 |  |  | 				Ns:      dns.Fqdn(*(SOA.Host))}
 | 
					
						
							| 
									
										
										
										
											2020-03-11 00:52:23 +05:30
										 |  |  | 			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)
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | // 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}
 | 
					
						
							|  |  |  | 	qname := state.Name()
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 	zone := plugin.Zones(h.zoneNames).Matches(qname)
 | 
					
						
							|  |  |  | 	if zone == "" {
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 		return plugin.NextOrFailure(h.Name(), h.Next, ctx, w, r)
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-21 16:08:55 -04:00
										 |  |  | 	zones, ok := h.zones[zone] // ok true if we are authoritative for the zone.
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 	if !ok || zones == nil {
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 		return dns.RcodeServerFailure, nil
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m := new(dns.Msg)
 | 
					
						
							|  |  |  | 	m.SetReply(r)
 | 
					
						
							|  |  |  | 	m.Authoritative = true
 | 
					
						
							|  |  |  | 	var result file.Result
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 	for _, z := range zones {
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 		h.zMu.RLock()
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:10:26 +01:00
										 |  |  | 		m.Answer, m.Ns, m.Extra, result = z.z.Lookup(ctx, state, qname)
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:40:28 +05:30
										 |  |  | 		h.zMu.RUnlock()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// record type exists for this name (NODATA).
 | 
					
						
							|  |  |  | 		if len(m.Answer) != 0 || result == file.NoData {
 | 
					
						
							|  |  |  | 			break
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if len(m.Answer) == 0 && result != file.NoData && h.Fall.Through(qname) {
 | 
					
						
							|  |  |  | 		return plugin.NextOrFailure(h.Name(), h.Next, ctx, w, r)
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch result {
 | 
					
						
							|  |  |  | 	case file.Success:
 | 
					
						
							|  |  |  | 	case file.NoData:
 | 
					
						
							|  |  |  | 	case file.NameError:
 | 
					
						
							|  |  |  | 		m.Rcode = dns.RcodeNameError
 | 
					
						
							|  |  |  | 	case file.Delegation:
 | 
					
						
							|  |  |  | 		m.Authoritative = false
 | 
					
						
							|  |  |  | 	case file.ServerFailure:
 | 
					
						
							|  |  |  | 		return dns.RcodeServerFailure, nil
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	w.WriteMsg(m)
 | 
					
						
							|  |  |  | 	return dns.RcodeSuccess, nil
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Name implements plugin.Handler.Name.
 | 
					
						
							|  |  |  | func (h *Azure) Name() string { return "azure" }
 |