diff --git a/plugin/azure/azure.go b/plugin/azure/azure.go index e236a08b25..7e0b3a63e4 100644 --- a/plugin/azure/azure.go +++ b/plugin/azure/azure.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "net" + "strings" "sync" "time" @@ -15,47 +16,64 @@ import ( 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/Azure/go-autorest/autorest/azure/auth" "github.com/miekg/dns" ) type zone struct { - id string - z *file.Zone - zone string - private bool + id string + z *file.Zone + zone string + subscription string + publicClient publicdns.RecordSetsClient + privateClient privatedns.RecordSetsClient + private bool } type zones map[string][]*zone // Azure is the core struct of the azure plugin. type Azure struct { - zoneNames []string - publicClient publicdns.RecordSetsClient - privateClient privatedns.RecordSetsClient - upstream *upstream.Upstream - zMu sync.RWMutex - zones zones + zoneNames []string + 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, publicClient publicdns.RecordSetsClient, privateClient privatedns.RecordSetsClient, keys map[string][]string, accessMap map[string]string) (*Azure, error) { +func New(ctx context.Context, env auth.EnvironmentSettings, 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 subResourceGroup, znames := range keys { + azureIds := strings.Split(subResourceGroup, "/") + subscription := azureIds[0] + resourceGroup := azureIds[1] + var err error + for _, name := range znames { + publicDNSClient := publicdns.NewRecordSetsClient(subscription) + if publicDNSClient.Authorizer, err = env.GetAuthorizer(); err != nil { + return nil, plugin.Error("azure", err) + } + + privateDNSClient := privatedns.NewRecordSetsClient(subscription) + if privateDNSClient.Authorizer, err = env.GetAuthorizer(); err != nil { + return nil, plugin.Error("azure", err) + } + switch accessMap[resourceGroup+name] { case "public": - if _, err := publicClient.ListAllByDNSZone(context.Background(), resourceGroup, name, nil, ""); err != nil { + if _, err := publicDNSClient.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 { + if _, err := privateDNSClient.ListComplete(context.Background(), resourceGroup, name, nil, ""); err != nil { return nil, err } private = true @@ -65,16 +83,14 @@ func New(ctx context.Context, publicClient publicdns.RecordSetsClient, privateCl if _, ok := zones[fqdn]; !ok { names = append(names, fqdn) } - zones[fqdn] = append(zones[fqdn], &zone{id: resourceGroup, zone: name, private: private, z: file.NewZone(fqdn, "")}) + zones[fqdn] = append(zones[fqdn], &zone{subscription: subscription, publicClient: publicDNSClient, privateClient: privateDNSClient, id: resourceGroup, zone: name, private: private, z: file.NewZone(fqdn, "")}) } } return &Azure{ - publicClient: publicClient, - privateClient: privateClient, - zones: zones, - zoneNames: names, - upstream: upstream.New(), + zones: zones, + zoneNames: names, + upstream: upstream.New(), }, nil } @@ -112,11 +128,11 @@ func (h *Azure) updateZones(ctx context.Context) error { for i, hostedZone := range z { newZ := file.NewZone(zName, "") if hostedZone.private { - for privateSet, err = h.privateClient.List(ctx, hostedZone.id, hostedZone.zone, nil, ""); privateSet.NotDone(); err = privateSet.NextWithContext(ctx) { + for privateSet, err = hostedZone.privateClient.List(ctx, hostedZone.id, hostedZone.zone, nil, ""); privateSet.NotDone(); err = privateSet.NextWithContext(ctx) { updateZoneFromPrivateResourceSet(privateSet, newZ) } } else { - for publicSet, err = h.publicClient.ListByDNSZone(ctx, hostedZone.id, hostedZone.zone, nil, ""); publicSet.NotDone(); err = publicSet.NextWithContext(ctx) { + for publicSet, err = hostedZone.publicClient.ListByDNSZone(ctx, hostedZone.id, hostedZone.zone, nil, ""); publicSet.NotDone(); err = publicSet.NextWithContext(ctx) { updateZoneFromPublicResourceSet(publicSet, newZ) } } diff --git a/plugin/azure/setup.go b/plugin/azure/setup.go index 6cabe059f4..43939c20e0 100644 --- a/plugin/azure/setup.go +++ b/plugin/azure/setup.go @@ -10,8 +10,6 @@ import ( "github.com/coredns/coredns/plugin/pkg/fall" clog "github.com/coredns/coredns/plugin/pkg/log" - publicAzureDNS "github.com/Azure/azure-sdk-for-go/profiles/latest/dns/mgmt/dns" - privateAzureDNS "github.com/Azure/azure-sdk-for-go/profiles/latest/privatedns/mgmt/privatedns" azurerest "github.com/Azure/go-autorest/autorest/azure" "github.com/Azure/go-autorest/autorest/azure/auth" ) @@ -27,19 +25,7 @@ func setup(c *caddy.Controller) error { } ctx, cancel := context.WithCancel(context.Background()) - publicDNSClient := publicAzureDNS.NewRecordSetsClient(env.Values[auth.SubscriptionID]) - if publicDNSClient.Authorizer, err = env.GetAuthorizer(); err != nil { - cancel() - return plugin.Error("azure", err) - } - - privateDNSClient := privateAzureDNS.NewRecordSetsClient(env.Values[auth.SubscriptionID]) - if privateDNSClient.Authorizer, err = env.GetAuthorizer(); err != nil { - cancel() - return plugin.Error("azure", err) - } - - h, err := New(ctx, publicDNSClient, privateDNSClient, keys, accessMap) + h, err := New(ctx, env, keys, accessMap) if err != nil { cancel() return plugin.Error("azure", err) @@ -59,18 +45,18 @@ func setup(c *caddy.Controller) error { } func parse(c *caddy.Controller) (auth.EnvironmentSettings, map[string][]string, map[string]string, fall.F, error) { - resourceGroupMapping := map[string][]string{} accessMap := map[string]string{} resourceGroupSet := map[string]struct{}{} + subResourceGroupMapping := map[string][]string{} azureEnv := azurerest.PublicCloud env := auth.EnvironmentSettings{Values: map[string]string{}} - var fall fall.F var access string var resourceGroup string var zoneName string for c.Next() { + resourceGroupMapping := map[string][]string{} args := c.RemainingArgs() for i := 0; i < len(args); i++ { @@ -136,9 +122,12 @@ func parse(c *caddy.Controller) (auth.EnvironmentSettings, map[string][]string, return env, resourceGroupMapping, accessMap, fall, c.Errf("unknown property: %q", c.Val()) } } + for k, v := range resourceGroupMapping { + subResourceGroupMapping[env.Values[auth.SubscriptionID]+"/"+k] = v + } } env.Values[auth.Resource] = azureEnv.ResourceManagerEndpoint env.Environment = azureEnv - return env, resourceGroupMapping, accessMap, fall, nil + return env, subResourceGroupMapping, accessMap, fall, nil }