From fbfc3f8bb9c8d1f597089a1ba31e941990ae93f2 Mon Sep 17 00:00:00 2001 From: Andy Hawkins Date: Fri, 12 Apr 2019 20:40:28 +0100 Subject: [PATCH 1/8] Add support for TinyDNS TXT records --- octodns/source/tinydns.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) mode change 100644 => 100755 octodns/source/tinydns.py diff --git a/octodns/source/tinydns.py b/octodns/source/tinydns.py old mode 100644 new mode 100755 index 679accb..1b6be86 --- a/octodns/source/tinydns.py +++ b/octodns/source/tinydns.py @@ -20,7 +20,7 @@ from .base import BaseSource class TinyDnsBaseSource(BaseSource): SUPPORTS_GEO = False SUPPORTS_DYNAMIC = False - SUPPORTS = set(('A', 'CNAME', 'MX', 'NS')) + SUPPORTS = set(('A', 'CNAME', 'MX', 'NS', 'TXT')) split_re = re.compile(r':+') @@ -45,6 +45,22 @@ class TinyDnsBaseSource(BaseSource): 'values': values, } + def _data_for_TXT(self, _type, records): + values = [] + + for record in records: + values.append(record[0].decode('unicode-escape')) + + try: + ttl = records[0][1] + except IndexError: + ttl = self.default_ttl + return { + 'ttl': ttl, + 'type': _type, + 'values': values, + } + def _data_for_CNAME(self, _type, records): first = records[0] try: @@ -104,6 +120,7 @@ class TinyDnsBaseSource(BaseSource): 'C': 'CNAME', '+': 'A', '@': 'MX', + '\'': 'TXT', } name_re = re.compile(r'((?P.+)\.)?{}$'.format(zone.name[:-1])) From 1892489e77b8ad99061d26bc1d24860e09588408 Mon Sep 17 00:00:00 2001 From: Andy Hawkins Date: Fri, 12 Apr 2019 20:41:02 +0100 Subject: [PATCH 2/8] Add tests for TinyDNS TXT records --- tests/test_octodns_source_tinydns.py | 19 +++++++++++++++++-- tests/zones/tinydns/example.com | 4 ++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/tests/test_octodns_source_tinydns.py b/tests/test_octodns_source_tinydns.py index d2e0e21..7c8f70d 100644 --- a/tests/test_octodns_source_tinydns.py +++ b/tests/test_octodns_source_tinydns.py @@ -20,7 +20,7 @@ class TestTinyDnsFileSource(TestCase): def test_populate_normal(self): got = Zone('example.com.', []) self.source.populate(got) - self.assertEquals(11, len(got.records)) + self.assertEquals(14, len(got.records)) expected = Zone('example.com.', []) for name, data in ( @@ -86,6 +86,21 @@ class TestTinyDnsFileSource(TestCase): 'exchange': 'smtp-2-host.example.com.', }] }), + ('', { + 'type': 'TXT', + 'ttl': 300, + 'value': 'test TXT', + }), + ('colon', { + 'type': 'TXT', + 'ttl': 300, + 'value': 'test : TXT', + }), + ('nottl', { + 'type': 'TXT', + 'ttl': 3600, + 'value': 'nottl test TXT', + }), ): record = Record.new(expected, name, data) expected.add_record(record) @@ -173,4 +188,4 @@ class TestTinyDnsFileSource(TestCase): def test_ignores_subs(self): got = Zone('example.com.', ['sub']) self.source.populate(got) - self.assertEquals(10, len(got.records)) + self.assertEquals(13, len(got.records)) diff --git a/tests/zones/tinydns/example.com b/tests/zones/tinydns/example.com index 818d974..a827204 100644 --- a/tests/zones/tinydns/example.com +++ b/tests/zones/tinydns/example.com @@ -46,3 +46,7 @@ Ccname.other.foo:www.other.foo +a1.blah-asdf.subtest.com:10.2.3.5 +a2.blah-asdf.subtest.com:10.2.3.6 +a3.asdf.subtest.com:10.2.3.7 + +'example.com:test TXT:300 +'colon.example.com:test \072 TXT:300 +'nottl.example.com:nottl test TXT From a10cab351b9d324c825644cf7d3c06bda57c0f8a Mon Sep 17 00:00:00 2001 From: Andy Hawkins Date: Fri, 12 Apr 2019 21:29:58 +0100 Subject: [PATCH 3/8] Add support for TinyDNS AAAA records --- octodns/source/tinydns.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/octodns/source/tinydns.py b/octodns/source/tinydns.py index 1b6be86..beb586f 100755 --- a/octodns/source/tinydns.py +++ b/octodns/source/tinydns.py @@ -11,6 +11,7 @@ from os import listdir from os.path import join import logging import re +import textwrap from ..record import Record from ..zone import DuplicateRecordException, SubzoneRecordException @@ -20,7 +21,7 @@ from .base import BaseSource class TinyDnsBaseSource(BaseSource): SUPPORTS_GEO = False SUPPORTS_DYNAMIC = False - SUPPORTS = set(('A', 'CNAME', 'MX', 'NS', 'TXT')) + SUPPORTS = set(('A', 'CNAME', 'MX', 'NS', 'TXT', 'AAAA')) split_re = re.compile(r':+') @@ -45,6 +46,20 @@ class TinyDnsBaseSource(BaseSource): 'values': values, } + def _data_for_AAAA(self, _type, records): + values = [] + for record in records: + values.append(u":".join(textwrap.wrap(record[0], 4))) + try: + ttl = records[0][1] + except IndexError: + ttl = self.default_ttl + return { + 'ttl': ttl, + 'type': _type, + 'values': values, + } + def _data_for_TXT(self, _type, records): values = [] @@ -121,6 +136,8 @@ class TinyDnsBaseSource(BaseSource): '+': 'A', '@': 'MX', '\'': 'TXT', + '3': 'AAAA', + '6': 'AAAA', } name_re = re.compile(r'((?P.+)\.)?{}$'.format(zone.name[:-1])) From 3b98f3e0e110611eeefea8e3ff49e8a5e047c01b Mon Sep 17 00:00:00 2001 From: Andy Hawkins Date: Fri, 12 Apr 2019 21:30:45 +0100 Subject: [PATCH 4/8] Add tests for TinyDNS AAAA records --- tests/test_octodns_source_tinydns.py | 14 ++++++++++++-- tests/zones/tinydns/example.com | 3 +++ 2 files changed, 15 insertions(+), 2 deletions(-) mode change 100644 => 100755 tests/zones/tinydns/example.com diff --git a/tests/test_octodns_source_tinydns.py b/tests/test_octodns_source_tinydns.py index 7c8f70d..4850bba 100644 --- a/tests/test_octodns_source_tinydns.py +++ b/tests/test_octodns_source_tinydns.py @@ -20,7 +20,7 @@ class TestTinyDnsFileSource(TestCase): def test_populate_normal(self): got = Zone('example.com.', []) self.source.populate(got) - self.assertEquals(14, len(got.records)) + self.assertEquals(16, len(got.records)) expected = Zone('example.com.', []) for name, data in ( @@ -101,6 +101,16 @@ class TestTinyDnsFileSource(TestCase): 'ttl': 3600, 'value': 'nottl test TXT', }), + ('ipv6-3', { + 'type': 'AAAA', + 'ttl': 300, + 'value': '2a02:1348:017c:d5d0:0024:19ff:fef3:5742', + }), + ('ipv6-6', { + 'type': 'AAAA', + 'ttl': 3600, + 'value': '2a02:1348:017c:d5d0:0024:19ff:fef3:5743', + }), ): record = Record.new(expected, name, data) expected.add_record(record) @@ -188,4 +198,4 @@ class TestTinyDnsFileSource(TestCase): def test_ignores_subs(self): got = Zone('example.com.', ['sub']) self.source.populate(got) - self.assertEquals(13, len(got.records)) + self.assertEquals(15, len(got.records)) diff --git a/tests/zones/tinydns/example.com b/tests/zones/tinydns/example.com old mode 100644 new mode 100755 index a827204..6099501 --- a/tests/zones/tinydns/example.com +++ b/tests/zones/tinydns/example.com @@ -50,3 +50,6 @@ Ccname.other.foo:www.other.foo 'example.com:test TXT:300 'colon.example.com:test \072 TXT:300 'nottl.example.com:nottl test TXT + +3ipv6-3.example.com:2a021348017cd5d0002419fffef35742:300 +6ipv6-6.example.com:2a021348017cd5d0002419fffef35743 From 799e939381f1483c0da14b533635249210db5b5c Mon Sep 17 00:00:00 2001 From: Andy Hawkins Date: Wed, 17 Apr 2019 11:34:55 +0100 Subject: [PATCH 5/8] Escape semicolons read in from TinyDNS TXT records --- octodns/source/tinydns.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/octodns/source/tinydns.py b/octodns/source/tinydns.py index beb586f..dd9a8b4 100755 --- a/octodns/source/tinydns.py +++ b/octodns/source/tinydns.py @@ -64,7 +64,8 @@ class TinyDnsBaseSource(BaseSource): values = [] for record in records: - values.append(record[0].decode('unicode-escape')) + new_value = record[0].decode('unicode-escape').replace(";", "\\;") + values.append(new_value) try: ttl = records[0][1] From c89b0dbabd14d81f3ce460b0dd34b5a652c33b22 Mon Sep 17 00:00:00 2001 From: Andy Hawkins Date: Wed, 17 Apr 2019 11:35:51 +0100 Subject: [PATCH 6/8] Add tests for escaping semicolons in TinyDNS TXT records --- tests/test_octodns_source_tinydns.py | 9 +++++++-- tests/zones/tinydns/example.com | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/test_octodns_source_tinydns.py b/tests/test_octodns_source_tinydns.py index 4850bba..3693e17 100644 --- a/tests/test_octodns_source_tinydns.py +++ b/tests/test_octodns_source_tinydns.py @@ -20,7 +20,7 @@ class TestTinyDnsFileSource(TestCase): def test_populate_normal(self): got = Zone('example.com.', []) self.source.populate(got) - self.assertEquals(16, len(got.records)) + self.assertEquals(17, len(got.records)) expected = Zone('example.com.', []) for name, data in ( @@ -111,6 +111,11 @@ class TestTinyDnsFileSource(TestCase): 'ttl': 3600, 'value': '2a02:1348:017c:d5d0:0024:19ff:fef3:5743', }), + ('semicolon', { + 'type': 'TXT', + 'ttl': 300, + 'value': 'v=DKIM1\\; k=rsa\\; p=blah', + }), ): record = Record.new(expected, name, data) expected.add_record(record) @@ -198,4 +203,4 @@ class TestTinyDnsFileSource(TestCase): def test_ignores_subs(self): got = Zone('example.com.', ['sub']) self.source.populate(got) - self.assertEquals(15, len(got.records)) + self.assertEquals(16, len(got.records)) diff --git a/tests/zones/tinydns/example.com b/tests/zones/tinydns/example.com index 6099501..32781ca 100755 --- a/tests/zones/tinydns/example.com +++ b/tests/zones/tinydns/example.com @@ -53,3 +53,5 @@ Ccname.other.foo:www.other.foo 3ipv6-3.example.com:2a021348017cd5d0002419fffef35742:300 6ipv6-6.example.com:2a021348017cd5d0002419fffef35743 + +'semicolon.example.com:v=DKIM1; k=rsa; p=blah:300 From 29e477edbdaf50798d49c85a9caef4d253130575 Mon Sep 17 00:00:00 2001 From: Andy Hawkins Date: Fri, 26 Apr 2019 09:44:03 +0100 Subject: [PATCH 7/8] Add comment about adding ':' characters into AAAA records read from TinyDNS files --- octodns/source/tinydns.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/octodns/source/tinydns.py b/octodns/source/tinydns.py index dd9a8b4..f92e41f 100755 --- a/octodns/source/tinydns.py +++ b/octodns/source/tinydns.py @@ -47,6 +47,12 @@ class TinyDnsBaseSource(BaseSource): } def _data_for_AAAA(self, _type, records): + ''' + TinyDNS files have the ipv6 address written in full, but with the + colons removed. This inserts a colon every 4th character to make + the address correct. + ''' + values = [] for record in records: values.append(u":".join(textwrap.wrap(record[0], 4))) From 8c9b9fce89e0b762882d0ea505551c042be30b17 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Fri, 26 Apr 2019 02:43:58 -0700 Subject: [PATCH 8/8] Move method doc to comment --- octodns/source/tinydns.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/octodns/source/tinydns.py b/octodns/source/tinydns.py index f92e41f..dc2bc1b 100755 --- a/octodns/source/tinydns.py +++ b/octodns/source/tinydns.py @@ -47,14 +47,11 @@ class TinyDnsBaseSource(BaseSource): } def _data_for_AAAA(self, _type, records): - ''' - TinyDNS files have the ipv6 address written in full, but with the - colons removed. This inserts a colon every 4th character to make - the address correct. - ''' - values = [] for record in records: + # TinyDNS files have the ipv6 address written in full, but with the + # colons removed. This inserts a colon every 4th character to make + # the address correct. values.append(u":".join(textwrap.wrap(record[0], 4))) try: ttl = records[0][1]