From 8955d86a552446fa166d7622d5149f8612ad61e2 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Wed, 14 Sep 2022 19:30:32 -0700 Subject: [PATCH] WIP: value.display to handle idna_decode when needed for values --- octodns/record/__init__.py | 55 +++++++++++++++++++++++++++++++----- tests/test_octodns_record.py | 2 +- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/octodns/record/__init__.py b/octodns/record/__init__.py index 1893629..1dc97a6 100644 --- a/octodns/record/__init__.py +++ b/octodns/record/__init__.py @@ -373,8 +373,10 @@ class ValuesMixin(object): return ret def __repr__(self): - values = "', '".join([str(v) for v in self.values]) klass = self.__class__.__name__ + values = self.values + values = [v.display() for v in values] + values = "', '".join(values) return f"<{klass} {self._type} {self.ttl}, {self.decoded_fqdn}, ['{values}']>" @@ -457,7 +459,10 @@ class ValueMixin(object): def __repr__(self): klass = self.__class__.__name__ - return f'<{klass} {self._type} {self.ttl}, {self.decoded_fqdn}, {self.value}>' + value = self.value.display() + return ( + f'<{klass} {self._type} {self.ttl}, {self.decoded_fqdn}, {value}>' + ) class _DynamicPool(object): @@ -505,7 +510,14 @@ class _DynamicPool(object): return not self.__eq__(other) def __repr__(self): - return f'{self.data}' + values = [] + data = self.data + for value in data['values']: + # make a copy so we can muck with it safely + value = dict(value) + value['value'] = value['value'].display() + values.append(value) + return str({'fallback': data['fallback'], 'values': values}) class _DynamicRule(object): @@ -779,9 +791,9 @@ class _DynamicMixin(object): # improvements the value types should deal with serializing their # value try: - values = self.values + values = [v.display() for v in self.values] except AttributeError: - values = self.value + values = self.value.display() klass = self.__class__.__name__ return ( @@ -817,6 +829,9 @@ class _TargetValue(str): v = idna_encode(v) return super().__new__(cls, v) + def display(self): + return idna_decode(self) + class CnameValue(_TargetValue): pass @@ -860,6 +875,9 @@ class _IpAddress(str): v = str(cls._address_type(v)) return super().__new__(cls, v) + def display(self): + return self + class Ipv4Address(_IpAddress): _address_type = _IPv4Address @@ -976,6 +994,8 @@ class CaaValue(EqualityTupleMixin, dict): def __repr__(self): return f'{self.flags} {self.tag} "{self.value}"' + display = __repr__ + class CaaRecord(ValuesMixin, Record): _type = 'CAA' @@ -1269,6 +1289,8 @@ class LocValue(EqualityTupleMixin, dict): f"{self.precision_horz:.2f}m {self.precision_vert:.2f}m'" ) + display = __repr__ + class LocRecord(ValuesMixin, Record): _type = 'LOC' @@ -1361,7 +1383,9 @@ class MxValue(EqualityTupleMixin, dict): return (self.preference, self.exchange) def __repr__(self): - return f"'{self.preference} {self.exchange}'" + return f"'{self.preference} {idna_decode(self.exchange)}'" + + display = __repr__ class MxRecord(ValuesMixin, Record): @@ -1497,6 +1521,8 @@ class NaptrValue(EqualityTupleMixin, dict): f"\"{regexp}\" {self.replacement}'" ) + display = __repr__ + class NaptrRecord(ValuesMixin, Record): _type = 'NAPTR' @@ -1532,6 +1558,9 @@ class _NsValue(str): v = idna_encode(v) return super().__new__(cls, v) + def display(self): + return idna_decode(self) + class NsRecord(ValuesMixin, Record): _type = 'NS' @@ -1661,6 +1690,8 @@ class SshfpValue(EqualityTupleMixin, dict): def __repr__(self): return f"'{self.algorithm} {self.fingerprint_type} {self.fingerprint}'" + display = __repr__ + class SshfpRecord(ValuesMixin, Record): _type = 'SSHFP' @@ -1715,6 +1746,9 @@ class _ChunkedValue(str): ret.append(cls(v.replace('" "', ''))) return ret + def display(self): + return self + class SpfRecord(_ChunkedValuesMixin, Record): _type = 'SPF' @@ -1826,7 +1860,10 @@ class SrvValue(EqualityTupleMixin, dict): return (self.priority, self.weight, self.port, self.target) def __repr__(self): - return f"'{self.priority} {self.weight} {self.port} {self.target}'" + target = idna_decode(self.target) + return f"'{self.priority} {self.weight} {self.port} {target}'" + + display = __repr__ class SrvRecord(ValuesMixin, Record): @@ -1953,6 +1990,8 @@ class TlsaValue(EqualityTupleMixin, dict): f"'{self.matching_type} {self.certificate_association_data}'" ) + display = __repr__ + class TlsaRecord(ValuesMixin, Record): _type = 'TLSA' @@ -2080,6 +2119,8 @@ class UrlfwdValue(EqualityTupleMixin, dict): def __repr__(self): return f'"{self.path}" "{self.target}" {self.code} {self.masking} {self.query}' + display = __repr__ + class UrlfwdRecord(ValuesMixin, Record): _type = 'URLFWD' diff --git a/tests/test_octodns_record.py b/tests/test_octodns_record.py index 180089a..80cd0f2 100644 --- a/tests/test_octodns_record.py +++ b/tests/test_octodns_record.py @@ -4437,7 +4437,7 @@ class TestDynamicRecords(TestCase): # smoke test of _DynamicMixin.__repr__ a.__repr__() delattr(a, 'values') - a.value = 'abc' + a.value = _NsValue('ns1.unit.tests.') a.__repr__() def test_simple_aaaa_weighted(self):