diff --git a/octodns/processor/arpa.py b/octodns/processor/arpa.py index 0f7742a..491a353 100644 --- a/octodns/processor/arpa.py +++ b/octodns/processor/arpa.py @@ -2,6 +2,7 @@ # # +from collections import defaultdict from ipaddress import ip_address from logging import getLogger @@ -14,7 +15,7 @@ class AutoArpa(BaseProcessor): super().__init__(name) self.log = getLogger(f'AutoArpa[{name}]') self.ttl = ttl - self._records = {} + self._records = defaultdict(set) def process_source_zone(self, desired, sources): for record in desired.records: @@ -30,7 +31,7 @@ class AutoArpa(BaseProcessor): for ip in ips: ptr = ip_address(ip).reverse_pointer - self._records[f'{ptr}.'] = record.fqdn + self._records[f'{ptr}.'].add(record.fqdn) return desired @@ -46,11 +47,14 @@ class AutoArpa(BaseProcessor): zone_name = zone.name n = len(zone_name) + 1 - for arpa, fqdn in self._records.items(): + for arpa, fqdns in self._records.items(): if arpa.endswith(zone_name): name = arpa[:-n] + fqdns = sorted(fqdns) record = Record.new( - zone, name, {'ttl': self.ttl, 'type': 'PTR', 'value': fqdn} + zone, + name, + {'ttl': self.ttl, 'type': 'PTR', 'values': fqdns}, ) zone.add_record(record) diff --git a/tests/test_octodns_processor_arpa.py b/tests/test_octodns_processor_arpa.py index e02eeeb..c2eacbc 100644 --- a/tests/test_octodns_processor_arpa.py +++ b/tests/test_octodns_processor_arpa.py @@ -27,7 +27,7 @@ class TestAutoArpa(TestCase): aa = AutoArpa('auto-arpa') aa.process_source_zone(zone, []) self.assertEqual( - {'4.3.2.1.in-addr.arpa.': 'a.unit.tests.'}, aa._records + {'4.3.2.1.in-addr.arpa.': {'a.unit.tests.'}}, aa._records ) # matching zone @@ -56,8 +56,8 @@ class TestAutoArpa(TestCase): aa.process_source_zone(zone, []) self.assertEqual( { - '4.3.2.1.in-addr.arpa.': 'a.unit.tests.', - '5.3.2.1.in-addr.arpa.': 'a.unit.tests.', + '4.3.2.1.in-addr.arpa.': {'a.unit.tests.'}, + '5.3.2.1.in-addr.arpa.': {'a.unit.tests.'}, }, aa._records, ) @@ -81,7 +81,7 @@ class TestAutoArpa(TestCase): aa = AutoArpa('auto-arpa') aa.process_source_zone(zone, []) ip6_arpa = '2.0.0.0.4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.c.0.0.0.f.f.0.0.ip6.arpa.' - self.assertEqual({ip6_arpa: 'aaaa.unit.tests.'}, aa._records) + self.assertEqual({ip6_arpa: {'aaaa.unit.tests.'}}, aa._records) # matching zone arpa = Zone('c.0.0.0.f.f.0.0.ip6.arpa.', []) @@ -117,13 +117,13 @@ class TestAutoArpa(TestCase): aa.process_source_zone(zone, []) self.assertEqual( { - '1.1.1.1.in-addr.arpa.': 'geo.unit.tests.', - '2.2.2.2.in-addr.arpa.': 'geo.unit.tests.', - '3.3.3.3.in-addr.arpa.': 'geo.unit.tests.', - '4.4.4.4.in-addr.arpa.': 'geo.unit.tests.', - '5.5.5.5.in-addr.arpa.': 'geo.unit.tests.', - '4.3.2.1.in-addr.arpa.': 'geo.unit.tests.', - '5.3.2.1.in-addr.arpa.': 'geo.unit.tests.', + '1.1.1.1.in-addr.arpa.': {'geo.unit.tests.'}, + '2.2.2.2.in-addr.arpa.': {'geo.unit.tests.'}, + '3.3.3.3.in-addr.arpa.': {'geo.unit.tests.'}, + '4.4.4.4.in-addr.arpa.': {'geo.unit.tests.'}, + '5.5.5.5.in-addr.arpa.': {'geo.unit.tests.'}, + '4.3.2.1.in-addr.arpa.': {'geo.unit.tests.'}, + '5.3.2.1.in-addr.arpa.': {'geo.unit.tests.'}, }, aa._records, ) @@ -167,11 +167,37 @@ class TestAutoArpa(TestCase): aa.process_source_zone(zone, []) self.assertEqual( { - '3.3.3.3.in-addr.arpa.': 'dynamic.unit.tests.', - '4.4.4.4.in-addr.arpa.': 'dynamic.unit.tests.', - '5.5.5.5.in-addr.arpa.': 'dynamic.unit.tests.', - '4.3.2.1.in-addr.arpa.': 'dynamic.unit.tests.', - '5.3.2.1.in-addr.arpa.': 'dynamic.unit.tests.', + '3.3.3.3.in-addr.arpa.': {'dynamic.unit.tests.'}, + '4.4.4.4.in-addr.arpa.': {'dynamic.unit.tests.'}, + '5.5.5.5.in-addr.arpa.': {'dynamic.unit.tests.'}, + '4.3.2.1.in-addr.arpa.': {'dynamic.unit.tests.'}, + '5.3.2.1.in-addr.arpa.': {'dynamic.unit.tests.'}, }, aa._records, ) + + def test_multiple_names(self): + zone = Zone('unit.tests.', []) + record1 = Record.new( + zone, 'a1', {'ttl': 32, 'type': 'A', 'value': '1.2.3.4'} + ) + zone.add_record(record1) + record2 = Record.new( + zone, 'a2', {'ttl': 32, 'type': 'A', 'value': '1.2.3.4'} + ) + zone.add_record(record2) + aa = AutoArpa('auto-arpa') + aa.process_source_zone(zone, []) + self.assertEqual( + {'4.3.2.1.in-addr.arpa.': {'a1.unit.tests.', 'a2.unit.tests.'}}, + aa._records, + ) + + # matching zone + arpa = Zone('3.2.1.in-addr.arpa.', []) + aa.populate(arpa) + self.assertEqual(1, len(arpa.records)) + (ptr,) = arpa.records + self.assertEqual('4.3.2.1.in-addr.arpa.', ptr.fqdn) + self.assertEqual([record1.fqdn, record2.fqdn], ptr.values) + self.assertEqual(3600, ptr.ttl)