1
0
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:
Ross McFarland
2021-01-23 09:12:26 -08:00
committed by GitHub
2 changed files with 112 additions and 10 deletions

View File

@@ -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',

View File

@@ -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):