mirror of
https://github.com/github/octodns.git
synced 2024-05-11 05:55:00 +00:00
Merge pull request #596 from ppieprzycki/azuredns_txt
Azuredns txt record too long , Skip alias entires
This commit is contained in:
@@ -28,6 +28,25 @@ def unescape_semicolon(s):
|
||||
return s.replace('\\;', ';')
|
||||
|
||||
|
||||
def azure_chunked_value(val):
|
||||
CHUNK_SIZE = 255
|
||||
val_replace = val.replace('"', '\\"')
|
||||
value = unescape_semicolon(val_replace)
|
||||
if len(val) > CHUNK_SIZE:
|
||||
vs = [value[i:i + CHUNK_SIZE]
|
||||
for i in range(0, len(value), CHUNK_SIZE)]
|
||||
else:
|
||||
vs = value
|
||||
return vs
|
||||
|
||||
|
||||
def azure_chunked_values(s):
|
||||
values = []
|
||||
for v in s:
|
||||
values.append(azure_chunked_value(v))
|
||||
return values
|
||||
|
||||
|
||||
class _AzureRecord(object):
|
||||
'''Wrapper for OctoDNS record for AzureProvider to make dns_client calls.
|
||||
|
||||
@@ -72,6 +91,8 @@ class _AzureRecord(object):
|
||||
|
||||
:type return: _AzureRecord
|
||||
'''
|
||||
self.log = logging.getLogger('AzureRecord')
|
||||
|
||||
self.resource_group = resource_group
|
||||
self.zone_name = record.zone.name[:len(record.zone.name) - 1]
|
||||
self.relative_record_set_name = record.name or '@'
|
||||
@@ -162,11 +183,19 @@ class _AzureRecord(object):
|
||||
return {key_name: [azure_class(ptrdname=v) for v in values]}
|
||||
|
||||
def _params_for_TXT(self, data, key_name, azure_class):
|
||||
|
||||
params = []
|
||||
try: # API for TxtRecord has list of str, even for singleton
|
||||
values = [unescape_semicolon(v) for v in data['values']]
|
||||
values = [v for v in azure_chunked_values(data['values'])]
|
||||
except KeyError:
|
||||
values = [unescape_semicolon(data['value'])]
|
||||
return {key_name: [azure_class(value=[v]) for v in values]}
|
||||
values = [azure_chunked_value(data['value'])]
|
||||
|
||||
for v in values:
|
||||
if isinstance(v, list):
|
||||
params.append(azure_class(value=v))
|
||||
else:
|
||||
params.append(azure_class(value=[v]))
|
||||
return {key_name: params}
|
||||
|
||||
def _equals(self, b):
|
||||
'''Checks whether two records are equal by comparing all fields.
|
||||
@@ -234,6 +263,13 @@ def _parse_azure_type(string):
|
||||
return string.split('/')[len(string.split('/')) - 1]
|
||||
|
||||
|
||||
def _check_for_alias(azrecord):
|
||||
if (azrecord.target_resource.id and not azrecord.arecords and not
|
||||
azrecord.cname_record):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class AzureProvider(BaseProvider):
|
||||
'''
|
||||
Azure DNS Provider
|
||||
@@ -387,11 +423,20 @@ class AzureProvider(BaseProvider):
|
||||
for azrecord in _records:
|
||||
record_name = azrecord.name if azrecord.name != '@' else ''
|
||||
typ = _parse_azure_type(azrecord.type)
|
||||
|
||||
if typ in ['A', 'CNAME']:
|
||||
if _check_for_alias(azrecord):
|
||||
self.log.debug(
|
||||
'Skipping - ALIAS. zone=%s record=%s, type=%s',
|
||||
zone_name, record_name, typ) # pragma: no cover
|
||||
continue # pragma: no cover
|
||||
|
||||
data = getattr(self, '_data_for_{}'.format(typ))
|
||||
data = data(azrecord)
|
||||
data['type'] = typ
|
||||
data['ttl'] = azrecord.ttl
|
||||
record = Record.new(zone, record_name, data, source=self)
|
||||
|
||||
zone.add_record(record, lenient=lenient)
|
||||
|
||||
self.log.info('populate: found %s records, exists=%s',
|
||||
|
@@ -7,13 +7,13 @@ from __future__ import absolute_import, division, print_function, \
|
||||
|
||||
from octodns.record import Create, Delete, Record
|
||||
from octodns.provider.azuredns import _AzureRecord, AzureProvider, \
|
||||
_check_endswith_dot, _parse_azure_type
|
||||
_check_endswith_dot, _parse_azure_type, _check_for_alias
|
||||
from octodns.zone import Zone
|
||||
from octodns.provider.base import Plan
|
||||
|
||||
from azure.mgmt.dns.models import ARecord, AaaaRecord, CaaRecord, \
|
||||
CnameRecord, MxRecord, SrvRecord, NsRecord, PtrRecord, TxtRecord, \
|
||||
RecordSet, SoaRecord, Zone as AzureZone
|
||||
RecordSet, SoaRecord, SubResource, Zone as AzureZone
|
||||
from msrestazure.azure_exceptions import CloudError
|
||||
|
||||
from unittest import TestCase
|
||||
@@ -134,6 +134,18 @@ octo_records.append(Record.new(zone, 'txt2', {
|
||||
'type': 'TXT',
|
||||
'values': ['txt multiple test', 'txt multiple test 2']}))
|
||||
|
||||
long_txt = "v=spf1 ip4:10.10.0.0/24 ip4:10.10.1.0/24 ip4:10.10.2.0/24"
|
||||
long_txt += " ip4:10.10.3.0/24 ip4:10.10.4.0/24 ip4:10.10.5.0/24 "
|
||||
long_txt += " 10.6.0/24 ip4:10.10.7.0/24 ip4:10.10.8.0/24 "
|
||||
long_txt += " ip4:10.10.10.0/24 ip4:10.10.11.0/24 ip4:10.10.12.0/24"
|
||||
long_txt += " ip4:10.10.13.0/24 ip4:10.10.14.0/24 ip4:10.10.15.0/24"
|
||||
long_txt += " ip4:10.10.16.0/24 ip4:10.10.17.0/24 ip4:10.10.18.0/24"
|
||||
long_txt += " ip4:10.10.19.0/24 ip4:10.10.20.0/24 ~all"
|
||||
octo_records.append(Record.new(zone, 'txt3', {
|
||||
'ttl': 10,
|
||||
'type': 'TXT',
|
||||
'values': ['txt multiple test', long_txt]}))
|
||||
|
||||
azure_records = []
|
||||
_base0 = _AzureRecord('TestAzure', octo_records[0])
|
||||
_base0.zone_name = 'unit.tests'
|
||||
@@ -306,6 +318,22 @@ _base17.params['txt_records'] = [TxtRecord(value=['txt multiple test']),
|
||||
TxtRecord(value=['txt multiple test 2'])]
|
||||
azure_records.append(_base17)
|
||||
|
||||
long_txt_az1 = "v=spf1 ip4:10.10.0.0/24 ip4:10.10.1.0/24 ip4:10.10.2.0/24"
|
||||
long_txt_az1 += " ip4:10.10.3.0/24 ip4:10.10.4.0/24 ip4:10.10.5.0/24 "
|
||||
long_txt_az1 += " 10.6.0/24 ip4:10.10.7.0/24 ip4:10.10.8.0/24 "
|
||||
long_txt_az1 += " ip4:10.10.10.0/24 ip4:10.10.11.0/24 ip4:10.10.12.0/24"
|
||||
long_txt_az1 += " ip4:10.10.13.0/24 ip4:10.10.14.0/24 ip4:10.10."
|
||||
long_txt_az2 = "15.0/24 ip4:10.10.16.0/24 ip4:10.10.17.0/24 ip4:10.10.18.0/24"
|
||||
long_txt_az2 += " ip4:10.10.19.0/24 ip4:10.10.20.0/24 ~all"
|
||||
_base18 = _AzureRecord('TestAzure', octo_records[18])
|
||||
_base18.zone_name = 'unit.tests'
|
||||
_base18.relative_record_set_name = 'txt3'
|
||||
_base18.record_type = 'TXT'
|
||||
_base18.params['ttl'] = 10
|
||||
_base18.params['txt_records'] = [TxtRecord(value=['txt multiple test']),
|
||||
TxtRecord(value=[long_txt_az1, long_txt_az2])]
|
||||
azure_records.append(_base18)
|
||||
|
||||
|
||||
class Test_AzureRecord(TestCase):
|
||||
def test_azure_record(self):
|
||||
@@ -333,6 +361,17 @@ class Test_CheckEndswithDot(TestCase):
|
||||
self.assertEquals(expected, _check_endswith_dot(test))
|
||||
|
||||
|
||||
class Test_CheckAzureAlias(TestCase):
|
||||
def test_check_for_alias(self):
|
||||
alias_record = type('C', (object,), {})
|
||||
alias_record.target_resource = type('C', (object,), {})
|
||||
alias_record.target_resource.id = "/subscriptions/x/resourceGroups/y/z"
|
||||
alias_record.arecords = None
|
||||
alias_record.cname_record = None
|
||||
|
||||
self.assertEquals(_check_for_alias(alias_record), True)
|
||||
|
||||
|
||||
class TestAzureDnsProvider(TestCase):
|
||||
def _provider(self):
|
||||
return self._get_provider('mock_spc', 'mock_dns_client')
|
||||
@@ -358,19 +397,23 @@ class TestAzureDnsProvider(TestCase):
|
||||
rs = []
|
||||
recordSet = RecordSet(arecords=[ARecord(ipv4_address='1.1.1.1')])
|
||||
recordSet.name, recordSet.ttl, recordSet.type = 'a1', 0, 'A'
|
||||
recordSet.target_resource = SubResource()
|
||||
rs.append(recordSet)
|
||||
recordSet = RecordSet(arecords=[ARecord(ipv4_address='1.1.1.1'),
|
||||
ARecord(ipv4_address='2.2.2.2')])
|
||||
recordSet.name, recordSet.ttl, recordSet.type = 'a2', 1, 'A'
|
||||
recordSet.target_resource = SubResource()
|
||||
rs.append(recordSet)
|
||||
aaaa1 = AaaaRecord(ipv6_address='1:1ec:1::1')
|
||||
recordSet = RecordSet(aaaa_records=[aaaa1])
|
||||
recordSet.name, recordSet.ttl, recordSet.type = 'aaaa1', 2, 'AAAA'
|
||||
recordSet.target_resource = SubResource()
|
||||
rs.append(recordSet)
|
||||
aaaa2 = AaaaRecord(ipv6_address='1:1ec:1::2')
|
||||
recordSet = RecordSet(aaaa_records=[aaaa1,
|
||||
aaaa2])
|
||||
recordSet.name, recordSet.ttl, recordSet.type = 'aaaa2', 3, 'AAAA'
|
||||
recordSet.target_resource = SubResource()
|
||||
rs.append(recordSet)
|
||||
recordSet = RecordSet(caa_records=[CaaRecord(flags=0,
|
||||
tag='issue',
|
||||
@@ -388,6 +431,7 @@ class TestAzureDnsProvider(TestCase):
|
||||
cname1 = CnameRecord(cname='cname.unit.test.')
|
||||
recordSet = RecordSet(cname_record=cname1)
|
||||
recordSet.name, recordSet.ttl, recordSet.type = 'cname1', 5, 'CNAME'
|
||||
recordSet.target_resource = SubResource()
|
||||
rs.append(recordSet)
|
||||
recordSet = RecordSet(mx_records=[MxRecord(preference=10,
|
||||
exchange='mx1.unit.test.')])
|
||||
@@ -428,22 +472,35 @@ class TestAzureDnsProvider(TestCase):
|
||||
rs.append(recordSet)
|
||||
recordSet = RecordSet(txt_records=[TxtRecord(value='sample text1')])
|
||||
recordSet.name, recordSet.ttl, recordSet.type = 'txt1', 15, 'TXT'
|
||||
recordSet.target_resource = SubResource()
|
||||
rs.append(recordSet)
|
||||
recordSet = RecordSet(txt_records=[TxtRecord(value='sample text1'),
|
||||
TxtRecord(value='sample text2')])
|
||||
recordSet.name, recordSet.ttl, recordSet.type = 'txt2', 16, 'TXT'
|
||||
recordSet.target_resource = SubResource()
|
||||
rs.append(recordSet)
|
||||
recordSet = RecordSet(soa_record=[SoaRecord()])
|
||||
recordSet.name, recordSet.ttl, recordSet.type = '', 17, 'SOA'
|
||||
rs.append(recordSet)
|
||||
long_txt = "v=spf1 ip4:10.10.0.0/24 ip4:10.10.1.0/24 ip4:10.10.2.0/24"
|
||||
long_txt += " ip4:10.10.3.0/24 ip4:10.10.4.0/24 ip4:10.10.5.0/24 "
|
||||
long_txt += " 10.6.0/24 ip4:10.10.7.0/24 ip4:10.10.8.0/24 "
|
||||
long_txt += " ip4:10.10.10.0/24 ip4:10.10.11.0/24 ip4:10.10.12.0/24"
|
||||
long_txt += " ip4:10.10.13.0/24 ip4:10.10.14.0/24 ip4:10.10.15.0/24"
|
||||
long_txt += " ip4:10.10.16.0/24 ip4:10.10.17.0/24 ip4:10.10.18.0/24"
|
||||
long_txt += " ip4:10.10.19.0/24 ip4:10.10.20.0/24 ~all"
|
||||
recordSet = RecordSet(txt_records=[TxtRecord(value='sample value1'),
|
||||
TxtRecord(value=long_txt)])
|
||||
recordSet.name, recordSet.ttl, recordSet.type = 'txt3', 18, 'TXT'
|
||||
recordSet.target_resource = SubResource()
|
||||
rs.append(recordSet)
|
||||
|
||||
record_list = provider._dns_client.record_sets.list_by_dns_zone
|
||||
record_list.return_value = rs
|
||||
|
||||
exists = provider.populate(zone)
|
||||
self.assertTrue(exists)
|
||||
|
||||
self.assertEquals(len(zone.records), 16)
|
||||
self.assertEquals(len(zone.records), 17)
|
||||
|
||||
def test_populate_zone(self):
|
||||
provider = self._get_provider()
|
||||
@@ -477,9 +534,9 @@ class TestAzureDnsProvider(TestCase):
|
||||
changes.append(Create(i))
|
||||
deletes.append(Delete(i))
|
||||
|
||||
self.assertEquals(18, provider.apply(Plan(None, zone,
|
||||
self.assertEquals(19, provider.apply(Plan(None, zone,
|
||||
changes, True)))
|
||||
self.assertEquals(18, provider.apply(Plan(zone, zone,
|
||||
self.assertEquals(19, provider.apply(Plan(zone, zone,
|
||||
deletes, True)))
|
||||
|
||||
def test_create_zone(self):
|
||||
@@ -495,7 +552,7 @@ class TestAzureDnsProvider(TestCase):
|
||||
_get = provider._dns_client.zones.get
|
||||
_get.side_effect = CloudError(Mock(status=404), err_msg)
|
||||
|
||||
self.assertEquals(18, provider.apply(Plan(None, desired, changes,
|
||||
self.assertEquals(19, provider.apply(Plan(None, desired, changes,
|
||||
True)))
|
||||
|
||||
def test_check_zone_no_create(self):
|
||||
|
Reference in New Issue
Block a user