From 074de669888582fc8e8857f0104949f84a56d52f Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Thu, 19 Aug 2021 18:18:07 -0700 Subject: [PATCH 1/4] Normalize IP addresses --- octodns/record/__init__.py | 9 +++++++-- tests/test_octodns_record.py | 16 +++++++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/octodns/record/__init__.py b/octodns/record/__init__.py index 77663a5..a8dd834 100644 --- a/octodns/record/__init__.py +++ b/octodns/record/__init__.py @@ -749,8 +749,13 @@ class _IpList(object): @classmethod def process(cls, values): - # Translating None into '' so that the list will be sortable in python3 - return [v if v is not None else '' for v in values] + # Translating None into '' so that the list will be sortable in + # python3, get everything to str first + values = [text_type(v) if v is not None else '' for v in values] + # Now round trip all non-'' through the address type and back to a str + # to normalize the address representation. + return [text_type(cls._address_type(v)) if v != '' else '' + for v in values] class Ipv4List(_IpList): diff --git a/tests/test_octodns_record.py b/tests/test_octodns_record.py index 886dbfb..c848853 100644 --- a/tests/test_octodns_record.py +++ b/tests/test_octodns_record.py @@ -259,11 +259,21 @@ class TestRecord(TestCase): self.assertEquals(b_data, b.data) def test_aaaa(self): - a_values = ['2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b', - '2001:0db8:3c4d:0015:0000:0000:1a2f:1a3b'] - b_value = '2001:0db8:3c4d:0015:0000:0000:1a2f:1a4b' + a_values = ['2001:db8:3c4d:15::1a2f:1a2b', + '2001:db8:3c4d:15::1a2f:1a3b'] + b_value = '2001:db8:3c4d:15::1a2f:1a4b' self.assertMultipleValues(AaaaRecord, a_values, b_value) + # Specifically validate that we normalize IPv6 addresses + values = ['2001:db8:3c4d:15:0000:0000:1a2f:1a2b', + '2001:0db8:3c4d:0015::1a2f:1a3b'] + data = { + 'ttl': 30, + 'values': values, + } + record = AaaaRecord(self.zone, 'aaaa', data) + self.assertEquals(a_values, record.values) + def assertSingleValue(self, _type, a_value, b_value): a_data = {'ttl': 30, 'value': a_value} a = _type(self.zone, 'a', a_data) From e06c42c4fc6798688a2a8498ea46cdfb3031f0a8 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Mon, 23 Aug 2021 12:41:06 -0700 Subject: [PATCH 2/4] No need to ip_address normalize AAAA in constellix now --- octodns/provider/constellix.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/octodns/provider/constellix.py b/octodns/provider/constellix.py index 5ca89e1..cd0d85b 100644 --- a/octodns/provider/constellix.py +++ b/octodns/provider/constellix.py @@ -8,7 +8,6 @@ from __future__ import absolute_import, division, print_function, \ from collections import defaultdict from requests import Session from base64 import b64encode -from ipaddress import ip_address from six import string_types import hashlib import hmac @@ -138,11 +137,6 @@ class ConstellixClient(object): v['value'] = self._absolutize_value(v['value'], zone_name) - # compress IPv6 addresses - if record['type'] == 'AAAA': - for i, v in enumerate(value): - value[i] = str(ip_address(v)) - return resp def record_create(self, zone_name, record_type, params): From aa3bc8fb9e682bba46ef32b0728b917e6f9f8a2e Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Mon, 23 Aug 2021 13:33:06 -0700 Subject: [PATCH 3/4] Correct Route53 IPv6 IPAddress comment --- octodns/provider/route53.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/octodns/provider/route53.py b/octodns/provider/route53.py index 477a53e..b4bd557 100644 --- a/octodns/provider/route53.py +++ b/octodns/provider/route53.py @@ -1090,10 +1090,11 @@ class Route53Provider(BaseProvider): health_check, value=None): config = health_check['HealthCheckConfig'] - # So interestingly Route53 normalizes IPAddress which will cause us to - # fail to find see things as equivalent. To work around this we'll - # ip_address's returned object for equivalence - # E.g 2001:4860:4860::8842 -> 2001:4860:4860:0:0:0:0:8842 + # So interestingly Route53 normalizes IPv6 addresses to a funky, but + # valid, form which will cause us to fail to find see things as + # equivalent. To work around this we'll ip_address's returned objects + # for equivalence. + # E.g 2001:4860:4860:0:0:0:0:8842 -> 2001:4860:4860::8842 if value: value = ip_address(text_type(value)) config_ip_address = ip_address(text_type(config['IPAddress'])) From e1c8e96e2e51055e58d8ebd6115a9e6f66e359bc Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Mon, 23 Aug 2021 13:34:14 -0700 Subject: [PATCH 4/4] No need to normalize IPv6 values in ultra now that they are by default --- octodns/provider/ultra.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/octodns/provider/ultra.py b/octodns/provider/ultra.py index bc855d4..afa4d0a 100644 --- a/octodns/provider/ultra.py +++ b/octodns/provider/ultra.py @@ -1,5 +1,4 @@ from collections import defaultdict -from ipaddress import ip_address from logging import getLogger from requests import Session @@ -196,8 +195,6 @@ class UltraProvider(BaseProvider): } def _data_for_AAAA(self, _type, records): - for i, v in enumerate(records['rdata']): - records['rdata'][i] = str(ip_address(v)) return { 'ttl': records['ttl'], 'type': _type,