Skip to content

Commit

Permalink
dns/azure/client: support DNSZone type Private and PrivateDNSZone for…
Browse files Browse the repository at this point in the history
… zones

Uses the ZoneID to differentiate the type of zone, and calls the corresponding resource-type handler to PUT and DELETE the records.

* creates `recordSetClient` to manage the records for DNSZone resource type.
* creates `privateRecordSetClient` to manage the records for PrivateDNSZone resource type.
* `dnsClient` now picks one of the above based on the Zone's provider
  • Loading branch information
abhinavdahiya committed Sep 24, 2019
1 parent 68878a7 commit 0038ee3
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 22 deletions.
106 changes: 94 additions & 12 deletions pkg/dns/azure/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"

"github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-10-01/dns"
privatedns "github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -33,27 +34,63 @@ type ARecord struct {
}

type dnsClient struct {
zones dns.ZonesClient
recordSets dns.RecordSetsClient
config Config
recordSetClient, privateRecordSetClient DNSClient
}

// New returns an authenticated DNSClient
func New(config Config, userAgentExtension string) (DNSClient, error) {
rsc, err := newRecordSetClient(config, userAgentExtension)
if err != nil {
return nil, errors.Wrap(err, "failed to create newRecordSetClient")
}

prsc, err := newPrivateRecordSetClient(config, userAgentExtension)
if err != nil {
return nil, errors.Wrap(err, "failed to create newPrivateRecordSetClient")
}

return &dnsClient{recordSetClient: rsc, privateRecordSetClient: prsc}, nil
}

func (c *dnsClient) Put(ctx context.Context, zone Zone, arec ARecord) error {
switch zone.Provider {
case "Microsoft.Network/privateDnsZones":
return c.privateRecordSetClient.Put(ctx, zone, arec)
case "Microsoft.Network/dnszones":
return c.recordSetClient.Put(ctx, zone, arec)
default:
return errors.Errorf("unsupported Zone provider %s", zone.Provider)
}
}

func (c *dnsClient) Delete(ctx context.Context, zone Zone, arec ARecord) error {
switch zone.Provider {
case "Microsoft.Network/privateDnsZones":
return c.privateRecordSetClient.Delete(ctx, zone, arec)
case "Microsoft.Network/dnszones":
return c.recordSetClient.Delete(ctx, zone, arec)
default:
return errors.Errorf("unsupported Zone provider %s", zone.Provider)
}
}

type recordSetClient struct {
client dns.RecordSetsClient
}

func newRecordSetClient(config Config, userAgentExtension string) (*recordSetClient, error) {
authorizer, err := getAuthorizerForResource(config)
if err != nil {
return nil, err
}
zc := dns.NewZonesClient(config.SubscriptionID)
zc.AddToUserAgent(userAgentExtension)
zc.Authorizer = authorizer

rc := dns.NewRecordSetsClient(config.SubscriptionID)
rc.AddToUserAgent(userAgentExtension)
rc.Authorizer = authorizer
return &dnsClient{zones: zc, recordSets: rc, config: config}, nil
return &recordSetClient{client: rc}, nil
}

func (c *dnsClient) Put(ctx context.Context, zone Zone, arec ARecord) error {
func (c *recordSetClient) Put(ctx context.Context, zone Zone, arec ARecord) error {
rs := dns.RecordSet{
RecordSetProperties: &dns.RecordSetProperties{
TTL: &arec.TTL,
Expand All @@ -62,20 +99,65 @@ func (c *dnsClient) Put(ctx context.Context, zone Zone, arec ARecord) error {
},
},
}
_, err := c.recordSets.CreateOrUpdate(ctx, zone.ResourceGroup, zone.Name, arec.Name, dns.A, rs, "", "")
_, err := c.client.CreateOrUpdate(ctx, zone.ResourceGroup, zone.Name, arec.Name, dns.A, rs, "", "")
if err != nil {
return errors.Wrapf(err, "failed to update dns a record: %s.%s", arec.Name, zone.Name)
}
return nil
}

func (c *dnsClient) Delete(ctx context.Context, zone Zone, arec ARecord) error {
_, err := c.recordSets.Get(ctx, zone.ResourceGroup, zone.Name, arec.Name, dns.A)
func (c *recordSetClient) Delete(ctx context.Context, zone Zone, arec ARecord) error {
_, err := c.client.Get(ctx, zone.ResourceGroup, zone.Name, arec.Name, dns.A)
if err != nil {
// TODO: How do we interpret this as a notfound error?
return nil
}
_, err = c.client.Delete(ctx, zone.ResourceGroup, zone.Name, arec.Name, dns.A, "")
if err != nil {
return errors.Wrapf(err, "failed to delete dns a record: %s.%s", arec.Name, zone.Name)
}
return nil
}

type privateRecordSetClient struct {
client privatedns.RecordSetsClient
}

func newPrivateRecordSetClient(config Config, userAgentExtension string) (*privateRecordSetClient, error) {
authorizer, err := getAuthorizerForResource(config)
if err != nil {
return nil, err
}

prc := privatedns.NewRecordSetsClient(config.SubscriptionID)
prc.AddToUserAgent(userAgentExtension)
prc.Authorizer = authorizer
return &privateRecordSetClient{client: prc}, nil
}

func (c *privateRecordSetClient) Put(ctx context.Context, zone Zone, arec ARecord) error {
rs := privatedns.RecordSet{
RecordSetProperties: &privatedns.RecordSetProperties{
TTL: &arec.TTL,
ARecords: &[]privatedns.ARecord{
{Ipv4Address: &arec.Address},
},
},
}
_, err := c.client.CreateOrUpdate(ctx, zone.ResourceGroup, zone.Name, privatedns.A, arec.Name, rs, "", "")
if err != nil {
return errors.Wrapf(err, "failed to update dns a record: %s.%s", arec.Name, zone.Name)
}
return nil
}

func (c *privateRecordSetClient) Delete(ctx context.Context, zone Zone, arec ARecord) error {
_, err := c.client.Get(ctx, zone.ResourceGroup, zone.Name, privatedns.A, arec.Name)
if err != nil {
// TODO: How do we interpret this as a notfound error?
return nil
}
_, err = c.recordSets.Delete(ctx, zone.ResourceGroup, zone.Name, arec.Name, dns.A, "")
_, err = c.client.Delete(ctx, zone.ResourceGroup, zone.Name, privatedns.A, arec.Name, "")
if err != nil {
return errors.Wrapf(err, "failed to delete dns a record: %s.%s", arec.Name, zone.Name)
}
Expand Down
4 changes: 3 additions & 1 deletion pkg/dns/azure/client/zone.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package client

import (
"errors"
"fmt"
"strings"
)

type Zone struct {
SubscriptionID string
ResourceGroup string
Provider string
Name string
}

Expand All @@ -16,5 +18,5 @@ func ParseZone(id string) (*Zone, error) {
if len(s) < 9 {
return nil, errors.New("invalid azure dns zone id")
}
return &Zone{SubscriptionID: s[2], ResourceGroup: s[4], Name: s[8]}, nil
return &Zone{SubscriptionID: s[2], ResourceGroup: s[4], Provider: fmt.Sprintf("%s/%s", s[6], s[7]), Name: s[8]}, nil
}
24 changes: 15 additions & 9 deletions pkg/dns/azure/client/zone_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,22 @@ import (

func TestFunction(t *testing.T) {
var zoneTests = []struct {
desc string
id string
err error
subID string
rg string
name string
desc string
id string
err error
subID string
rg string
provider string
name string
}{
{"TestValidZoneID", "/subscriptions/E540B02D-5CCE-4D47-A13B-EB05A19D696E/resourceGroups/test-rg/providers/Microsoft.Network/dnszones/test-rg.dnszone.io",
nil, "E540B02D-5CCE-4D47-A13B-EB05A19D696E", "test-rg", "test-rg.dnszone.io"},
nil, "E540B02D-5CCE-4D47-A13B-EB05A19D696E", "test-rg", "Microsoft.Network/dnszones", "test-rg.dnszone.io"},
{"TestValidZoneID", "/subscriptions/E540B02D-5CCE-4D47-A13B-EB05A19D696E/resourceGroups/test-rg/providers/Microsoft.Network/privateDnsZones/test-rg.dnszone.io",
nil, "E540B02D-5CCE-4D47-A13B-EB05A19D696E", "test-rg", "Microsoft.Network/privateDnsZones", "test-rg.dnszone.io"},
{"TestInvalidZoneID", "/subscriptions/E540B02D-5CCE-4D47-A13B-EB05A19D696E/resourceGroups/test-rg/providers/Microsoft.Network/dnszones",
errors.New("invalid azure dns zone id"), "E540B02D-5CCE-4D47-A13B-EB05A19D696E", "test-rg", "test-rg.dnszone.io"},
errors.New("invalid azure dns zone id"), "E540B02D-5CCE-4D47-A13B-EB05A19D696E", "test-rg", "Microsoft.Network/dnszones", "test-rg.dnszone.io"},
{"TestEmptyZoneID", "", errors.New("invalid azure dns zone id"),
"E540B02D-5CCE-4D47-A13B-EB05A19D696E", "test-rg", "test-rg.dnszone.io"},
"E540B02D-5CCE-4D47-A13B-EB05A19D696E", "test-rg", "Microsoft.Network/dnszones", "test-rg.dnszone.io"},
}
for _, tt := range zoneTests {
t.Run(tt.desc, func(t *testing.T) {
Expand All @@ -44,6 +47,9 @@ func TestFunction(t *testing.T) {
if zone.ResourceGroup != tt.rg {
t.Errorf("expected [%s] actual [%s]", tt.rg, zone.ResourceGroup)
}
if zone.Provider != tt.provider {
t.Errorf("expected [%s] actual [%s]", tt.provider, zone.Provider)
}
if zone.Name != tt.name {
t.Errorf("expected [%s] actual [%s]", tt.name, zone.Name)
}
Expand Down

0 comments on commit 0038ee3

Please sign in to comment.