Merge pull request #436 from stromming/azureTtl

Added TTL annotation check for azure records.
This commit is contained in:
Nick Jüttner 2018-01-18 17:19:30 +01:00 committed by GitHub
commit a80d755404
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 65 additions and 36 deletions

View File

@ -153,7 +153,12 @@ func (p *AzureProvider) Records() (endpoints []*endpoint.Endpoint, _ error) {
log.Errorf("Failed to extract target for '%s' with type '%s'.", name, recordType) log.Errorf("Failed to extract target for '%s' with type '%s'.", name, recordType)
return true return true
} }
ep := endpoint.NewEndpoint(name, target, recordType) var ttl endpoint.TTL
if recordSet.TTL != nil {
ttl = endpoint.TTL(*recordSet.TTL)
}
ep := endpoint.NewEndpointWithTTL(name, target, recordType, endpoint.TTL(ttl))
log.Debugf( log.Debugf(
"Found %s record for '%s' with target '%s'.", "Found %s record for '%s' with target '%s'.",
ep.RecordType, ep.RecordType,
@ -372,11 +377,15 @@ func (p *AzureProvider) recordSetNameForZone(zone string, endpoint *endpoint.End
} }
func (p *AzureProvider) newRecordSet(endpoint *endpoint.Endpoint) (dns.RecordSet, error) { func (p *AzureProvider) newRecordSet(endpoint *endpoint.Endpoint) (dns.RecordSet, error) {
var ttl int64 = azureRecordTTL
if endpoint.RecordTTL.IsConfigured() {
ttl = int64(endpoint.RecordTTL)
}
switch dns.RecordType(endpoint.RecordType) { switch dns.RecordType(endpoint.RecordType) {
case dns.A: case dns.A:
return dns.RecordSet{ return dns.RecordSet{
RecordSetProperties: &dns.RecordSetProperties{ RecordSetProperties: &dns.RecordSetProperties{
TTL: to.Int64Ptr(azureRecordTTL), TTL: to.Int64Ptr(ttl),
ARecords: &[]dns.ARecord{ ARecords: &[]dns.ARecord{
{ {
Ipv4Address: to.StringPtr(endpoint.Target), Ipv4Address: to.StringPtr(endpoint.Target),
@ -387,7 +396,7 @@ func (p *AzureProvider) newRecordSet(endpoint *endpoint.Endpoint) (dns.RecordSet
case dns.CNAME: case dns.CNAME:
return dns.RecordSet{ return dns.RecordSet{
RecordSetProperties: &dns.RecordSetProperties{ RecordSetProperties: &dns.RecordSetProperties{
TTL: to.Int64Ptr(azureRecordTTL), TTL: to.Int64Ptr(ttl),
CnameRecord: &dns.CnameRecord{ CnameRecord: &dns.CnameRecord{
Cname: to.StringPtr(endpoint.Target), Cname: to.StringPtr(endpoint.Target),
}, },
@ -396,7 +405,7 @@ func (p *AzureProvider) newRecordSet(endpoint *endpoint.Endpoint) (dns.RecordSet
case dns.TXT: case dns.TXT:
return dns.RecordSet{ return dns.RecordSet{
RecordSetProperties: &dns.RecordSetProperties{ RecordSetProperties: &dns.RecordSetProperties{
TTL: to.Int64Ptr(azureRecordTTL), TTL: to.Int64Ptr(ttl),
TxtRecords: &[]dns.TxtRecord{ TxtRecords: &[]dns.TxtRecord{
{ {
Value: &[]string{ Value: &[]string{

View File

@ -24,7 +24,9 @@ import (
"github.com/Azure/go-autorest/autorest/to" "github.com/Azure/go-autorest/autorest/to"
"github.com/kubernetes-incubator/external-dns/endpoint" "github.com/kubernetes-incubator/external-dns/endpoint"
"github.com/kubernetes-incubator/external-dns/internal/testutils"
"github.com/kubernetes-incubator/external-dns/plan" "github.com/kubernetes-incubator/external-dns/plan"
"github.com/stretchr/testify/assert"
) )
type mockZonesClient struct { type mockZonesClient struct {
@ -54,8 +56,9 @@ func (client *mockZonesClient) ListByResourceGroupNextResults(lastResults dns.Zo
return dns.ZoneListResult{}, nil return dns.ZoneListResult{}, nil
} }
func aRecordSetPropertiesGetter(value string) *dns.RecordSetProperties { func aRecordSetPropertiesGetter(value string, ttl int64) *dns.RecordSetProperties {
return &dns.RecordSetProperties{ return &dns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
ARecords: &[]dns.ARecord{ ARecords: &[]dns.ARecord{
{ {
Ipv4Address: to.StringPtr(value), Ipv4Address: to.StringPtr(value),
@ -64,16 +67,18 @@ func aRecordSetPropertiesGetter(value string) *dns.RecordSetProperties {
} }
} }
func cNameRecordSetPropertiesGetter(value string) *dns.RecordSetProperties { func cNameRecordSetPropertiesGetter(value string, ttl int64) *dns.RecordSetProperties {
return &dns.RecordSetProperties{ return &dns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
CnameRecord: &dns.CnameRecord{ CnameRecord: &dns.CnameRecord{
Cname: to.StringPtr(value), Cname: to.StringPtr(value),
}, },
} }
} }
func txtRecordSetPropertiesGetter(value string) *dns.RecordSetProperties { func txtRecordSetPropertiesGetter(value string, ttl int64) *dns.RecordSetProperties {
return &dns.RecordSetProperties{ return &dns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
TxtRecords: &[]dns.TxtRecord{ TxtRecords: &[]dns.TxtRecord{
{ {
Value: &[]string{value}, Value: &[]string{value},
@ -82,12 +87,16 @@ func txtRecordSetPropertiesGetter(value string) *dns.RecordSetProperties {
} }
} }
func othersRecordSetPropertiesGetter(value string) *dns.RecordSetProperties { func othersRecordSetPropertiesGetter(value string, ttl int64) *dns.RecordSetProperties {
return &dns.RecordSetProperties{} return &dns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
}
} }
func createMockRecordSet(name, recordType, value string) dns.RecordSet { func createMockRecordSet(name, recordType, value string) dns.RecordSet {
var getterFunc func(value string) *dns.RecordSetProperties return createMockRecordSetWithTTL(name, recordType, value, 0)
}
func createMockRecordSetWithTTL(name, recordType, value string, ttl int64) dns.RecordSet {
var getterFunc func(value string, ttl int64) *dns.RecordSetProperties
switch recordType { switch recordType {
case endpoint.RecordTypeA: case endpoint.RecordTypeA:
@ -102,7 +111,7 @@ func createMockRecordSet(name, recordType, value string) dns.RecordSet {
return dns.RecordSet{ return dns.RecordSet{
Name: to.StringPtr(name), Name: to.StringPtr(name),
Type: to.StringPtr("Microsoft.Network/dnszones/" + recordType), Type: to.StringPtr("Microsoft.Network/dnszones/" + recordType),
RecordSetProperties: getterFunc(value), RecordSetProperties: getterFunc(value, ttl),
} }
} }
@ -128,12 +137,17 @@ func (client *mockRecordsClient) Delete(resourceGroupName string, zoneName strin
} }
func (client *mockRecordsClient) CreateOrUpdate(resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, parameters dns.RecordSet, ifMatch string, ifNoneMatch string) (dns.RecordSet, error) { func (client *mockRecordsClient) CreateOrUpdate(resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, parameters dns.RecordSet, ifMatch string, ifNoneMatch string) (dns.RecordSet, error) {
var ttl endpoint.TTL
if parameters.TTL != nil {
ttl = endpoint.TTL(*parameters.TTL)
}
client.updatedEndpoints = append( client.updatedEndpoints = append(
client.updatedEndpoints, client.updatedEndpoints,
endpoint.NewEndpoint( endpoint.NewEndpointWithTTL(
formatAzureDNSName(relativeRecordSetName, zoneName), formatAzureDNSName(relativeRecordSetName, zoneName),
extractAzureTarget(&parameters), extractAzureTarget(&parameters),
string(recordType), string(recordType),
ttl,
), ),
) )
return parameters, nil return parameters, nil
@ -150,6 +164,10 @@ func newAzureProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryR
} }
} }
func validateAzureEndpoints(t *testing.T, endpoints []*endpoint.Endpoint, expected []*endpoint.Endpoint) {
assert.True(t, testutils.SameEndpoints(endpoints, expected), "expected and actual endpoints don't match. %s:%s", endpoints, expected)
}
func TestAzureRecord(t *testing.T) { func TestAzureRecord(t *testing.T) {
zonesClient := mockZonesClient{ zonesClient := mockZonesClient{
mockZoneListResult: &dns.ZoneListResult{ mockZoneListResult: &dns.ZoneListResult{
@ -165,13 +183,14 @@ func TestAzureRecord(t *testing.T) {
createMockRecordSet("@", "SOA", "Email: azuredns-hostmaster.microsoft.com"), createMockRecordSet("@", "SOA", "Email: azuredns-hostmaster.microsoft.com"),
createMockRecordSet("@", endpoint.RecordTypeA, "123.123.123.122"), createMockRecordSet("@", endpoint.RecordTypeA, "123.123.123.122"),
createMockRecordSet("@", endpoint.RecordTypeTXT, "heritage=external-dns,external-dns/owner=default"), createMockRecordSet("@", endpoint.RecordTypeTXT, "heritage=external-dns,external-dns/owner=default"),
createMockRecordSet("nginx", endpoint.RecordTypeA, "123.123.123.123"), createMockRecordSetWithTTL("nginx", endpoint.RecordTypeA, "123.123.123.123", 3600),
createMockRecordSet("nginx", endpoint.RecordTypeTXT, "heritage=external-dns,external-dns/owner=default"), createMockRecordSetWithTTL("nginx", endpoint.RecordTypeTXT, "heritage=external-dns,external-dns/owner=default", recordTTL),
createMockRecordSet("hack", endpoint.RecordTypeCNAME, "hack.azurewebsites.net"), createMockRecordSetWithTTL("hack", endpoint.RecordTypeCNAME, "hack.azurewebsites.net", 10),
}, },
} }
provider := newAzureProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true, "k8s", &zonesClient, &recordsClient) provider := newAzureProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true, "k8s", &zonesClient, &recordsClient)
actual, err := provider.Records() actual, err := provider.Records()
if err != nil { if err != nil {
@ -180,12 +199,13 @@ func TestAzureRecord(t *testing.T) {
expected := []*endpoint.Endpoint{ expected := []*endpoint.Endpoint{
endpoint.NewEndpoint("example.com", "123.123.123.122", endpoint.RecordTypeA), endpoint.NewEndpoint("example.com", "123.123.123.122", endpoint.RecordTypeA),
endpoint.NewEndpoint("example.com", "heritage=external-dns,external-dns/owner=default", endpoint.RecordTypeTXT), endpoint.NewEndpoint("example.com", "heritage=external-dns,external-dns/owner=default", endpoint.RecordTypeTXT),
endpoint.NewEndpoint("nginx.example.com", "123.123.123.123", endpoint.RecordTypeA), endpoint.NewEndpointWithTTL("nginx.example.com", "123.123.123.123", endpoint.RecordTypeA, 3600),
endpoint.NewEndpoint("nginx.example.com", "heritage=external-dns,external-dns/owner=default", endpoint.RecordTypeTXT), endpoint.NewEndpointWithTTL("nginx.example.com", "heritage=external-dns,external-dns/owner=default", endpoint.RecordTypeTXT, recordTTL),
endpoint.NewEndpoint("hack.example.com", "hack.azurewebsites.net", endpoint.RecordTypeCNAME), endpoint.NewEndpointWithTTL("hack.example.com", "hack.azurewebsites.net", endpoint.RecordTypeCNAME, 10),
} }
validateEndpoints(t, actual, expected) validateAzureEndpoints(t, actual, expected)
} }
func TestAzureApplyChanges(t *testing.T) { func TestAzureApplyChanges(t *testing.T) {
@ -193,24 +213,24 @@ func TestAzureApplyChanges(t *testing.T) {
testAzureApplyChangesInternal(t, false, &recordsClient) testAzureApplyChangesInternal(t, false, &recordsClient)
validateEndpoints(t, recordsClient.deletedEndpoints, []*endpoint.Endpoint{ validateAzureEndpoints(t, recordsClient.deletedEndpoints, []*endpoint.Endpoint{
endpoint.NewEndpoint("old.example.com", "", endpoint.RecordTypeA), endpoint.NewEndpoint("old.example.com", "", endpoint.RecordTypeA),
endpoint.NewEndpoint("oldcname.example.com", "", endpoint.RecordTypeCNAME), endpoint.NewEndpoint("oldcname.example.com", "", endpoint.RecordTypeCNAME),
endpoint.NewEndpoint("deleted.example.com", "", endpoint.RecordTypeA), endpoint.NewEndpoint("deleted.example.com", "", endpoint.RecordTypeA),
endpoint.NewEndpoint("deletedcname.example.com", "", endpoint.RecordTypeCNAME), endpoint.NewEndpoint("deletedcname.example.com", "", endpoint.RecordTypeCNAME),
}) })
validateEndpoints(t, recordsClient.updatedEndpoints, []*endpoint.Endpoint{ validateAzureEndpoints(t, recordsClient.updatedEndpoints, []*endpoint.Endpoint{
endpoint.NewEndpoint("example.com", "1.2.3.4", endpoint.RecordTypeA), endpoint.NewEndpointWithTTL("example.com", "1.2.3.4", endpoint.RecordTypeA, endpoint.TTL(recordTTL)),
endpoint.NewEndpoint("example.com", "tag", endpoint.RecordTypeTXT), endpoint.NewEndpointWithTTL("example.com", "tag", endpoint.RecordTypeTXT, endpoint.TTL(recordTTL)),
endpoint.NewEndpoint("foo.example.com", "1.2.3.4", endpoint.RecordTypeA), endpoint.NewEndpointWithTTL("foo.example.com", "1.2.3.4", endpoint.RecordTypeA, endpoint.TTL(recordTTL)),
endpoint.NewEndpoint("foo.example.com", "tag", endpoint.RecordTypeTXT), endpoint.NewEndpointWithTTL("foo.example.com", "tag", endpoint.RecordTypeTXT, endpoint.TTL(recordTTL)),
endpoint.NewEndpoint("bar.example.com", "other.com", endpoint.RecordTypeCNAME), endpoint.NewEndpointWithTTL("bar.example.com", "other.com", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL)),
endpoint.NewEndpoint("bar.example.com", "tag", endpoint.RecordTypeTXT), endpoint.NewEndpointWithTTL("bar.example.com", "tag", endpoint.RecordTypeTXT, endpoint.TTL(recordTTL)),
endpoint.NewEndpoint("other.com", "5.6.7.8", endpoint.RecordTypeA), endpoint.NewEndpointWithTTL("other.com", "5.6.7.8", endpoint.RecordTypeA, endpoint.TTL(recordTTL)),
endpoint.NewEndpoint("other.com", "tag", endpoint.RecordTypeTXT), endpoint.NewEndpointWithTTL("other.com", "tag", endpoint.RecordTypeTXT, endpoint.TTL(recordTTL)),
endpoint.NewEndpoint("new.example.com", "111.222.111.222", endpoint.RecordTypeA), endpoint.NewEndpointWithTTL("new.example.com", "111.222.111.222", endpoint.RecordTypeA, 3600),
endpoint.NewEndpoint("newcname.example.com", "other.com", endpoint.RecordTypeCNAME), endpoint.NewEndpointWithTTL("newcname.example.com", "other.com", endpoint.RecordTypeCNAME, 10),
}) })
} }
@ -219,9 +239,9 @@ func TestAzureApplyChangesDryRun(t *testing.T) {
testAzureApplyChangesInternal(t, true, &recordsClient) testAzureApplyChangesInternal(t, true, &recordsClient)
validateEndpoints(t, recordsClient.deletedEndpoints, []*endpoint.Endpoint{}) validateAzureEndpoints(t, recordsClient.deletedEndpoints, []*endpoint.Endpoint{})
validateEndpoints(t, recordsClient.updatedEndpoints, []*endpoint.Endpoint{}) validateAzureEndpoints(t, recordsClient.updatedEndpoints, []*endpoint.Endpoint{})
} }
func testAzureApplyChangesInternal(t *testing.T, dryRun bool, client RecordsClient) { func testAzureApplyChangesInternal(t *testing.T, dryRun bool, client RecordsClient) {
@ -260,8 +280,8 @@ func testAzureApplyChangesInternal(t *testing.T, dryRun bool, client RecordsClie
endpoint.NewEndpoint("old.nope.com", "121.212.121.212", endpoint.RecordTypeA), endpoint.NewEndpoint("old.nope.com", "121.212.121.212", endpoint.RecordTypeA),
} }
updatedRecords := []*endpoint.Endpoint{ updatedRecords := []*endpoint.Endpoint{
endpoint.NewEndpoint("new.example.com", "111.222.111.222", endpoint.RecordTypeA), endpoint.NewEndpointWithTTL("new.example.com", "111.222.111.222", endpoint.RecordTypeA, 3600),
endpoint.NewEndpoint("newcname.example.com", "other.com", endpoint.RecordTypeCNAME), endpoint.NewEndpointWithTTL("newcname.example.com", "other.com", endpoint.RecordTypeCNAME, 10),
endpoint.NewEndpoint("new.nope.com", "222.111.222.111", endpoint.RecordTypeA), endpoint.NewEndpoint("new.nope.com", "222.111.222.111", endpoint.RecordTypeA),
} }