Browse Source

PtrValue should no longer be using _TargetValue now that it acceps multiple values

pull/947/head
Ross McFarland 3 years ago
parent
commit
4a6fae34b3
No known key found for this signature in database GPG Key ID: 943B179E15D3B22A
2 changed files with 64 additions and 18 deletions
  1. +26
    -13
      octodns/record/__init__.py
  2. +38
    -5
      tests/test_octodns_record.py

+ 26
- 13
octodns/record/__init__.py View File

@ -1778,26 +1778,39 @@ class NsRecord(ValuesMixin, Record):
Record.register_type(NsRecord) Record.register_type(NsRecord)
class PtrValue(_TargetValue):
class PtrValue(str):
@classmethod @classmethod
def validate(cls, values, _type):
if not isinstance(values, list):
values = [values]
def parse_rdata_text(self, value):
return value
@classmethod
def validate(cls, data, _type):
if not data:
return ['missing value(s)']
elif not isinstance(data, (list, tuple)):
data = (data,)
reasons = [] reasons = []
if not values:
reasons.append('missing values')
for value in values:
reasons.extend(super().validate(value, _type))
for value in data:
value = idna_encode(value)
if not FQDN(value, allow_underscores=True).is_valid:
reasons.append(
f'Invalid PTR value "{value}" is not a valid FQDN.'
)
elif not value.endswith('.'):
reasons.append(f'PTR value "{value}" missing trailing .')
return reasons return reasons
@classmethod @classmethod
def process(cls, values): def process(cls, values):
supr = super()
return [supr.process(v) for v in values]
return [cls(v) for v in values]
def __new__(cls, v):
v = idna_encode(v)
return super().__new__(cls, v)
@property
def rdata_text(self):
return self
class PtrRecord(ValuesMixin, Record): class PtrRecord(ValuesMixin, Record):


+ 38
- 5
tests/test_octodns_record.py View File

@ -25,6 +25,7 @@ from octodns.record import (
NaptrValue, NaptrValue,
NsRecord, NsRecord,
PtrRecord, PtrRecord,
PtrValue,
Record, Record,
RecordException, RecordException,
Rr, Rr,
@ -217,12 +218,12 @@ class TestRecord(TestCase):
upper_record = PtrRecord( upper_record = PtrRecord(
self.zone, self.zone,
'PtrUppwerValue', 'PtrUppwerValue',
{'ttl': 30, 'type': 'PTR', 'value': 'GITHUB.COM'},
{'ttl': 30, 'type': 'PTR', 'value': 'GITHUB.COM.'},
) )
lower_record = PtrRecord( lower_record = PtrRecord(
self.zone, self.zone,
'PtrLowerValue', 'PtrLowerValue',
{'ttl': 30, 'type': 'PTR', 'value': 'github.com'},
{'ttl': 30, 'type': 'PTR', 'value': 'github.com.'},
) )
self.assertEqual(upper_record.value, lower_record.value) self.assertEqual(upper_record.value, lower_record.value)
@ -3871,7 +3872,7 @@ class TestRecordValidation(TestCase):
ctx.exception.reasons, ctx.exception.reasons,
) )
def test_PTR(self):
def test_ptr(self):
# doesn't blow up (name & zone here don't make any sense, but not # doesn't blow up (name & zone here don't make any sense, but not
# important) # important)
Record.new( Record.new(
@ -3881,7 +3882,12 @@ class TestRecordValidation(TestCase):
# missing value # missing value
with self.assertRaises(ValidationError) as ctx: with self.assertRaises(ValidationError) as ctx:
Record.new(self.zone, '', {'type': 'PTR', 'ttl': 600}) Record.new(self.zone, '', {'type': 'PTR', 'ttl': 600})
self.assertEqual(['missing values'], ctx.exception.reasons)
self.assertEqual(['missing value(s)'], ctx.exception.reasons)
# empty value
with self.assertRaises(ValidationError) as ctx:
Record.new(self.zone, '', {'type': 'PTR', 'ttl': 600, 'value': ''})
self.assertEqual(['missing value(s)'], ctx.exception.reasons)
# not a valid FQDN # not a valid FQDN
with self.assertRaises(ValidationError) as ctx: with self.assertRaises(ValidationError) as ctx:
@ -3889,7 +3895,8 @@ class TestRecordValidation(TestCase):
self.zone, '', {'type': 'PTR', 'ttl': 600, 'value': '_.'} self.zone, '', {'type': 'PTR', 'ttl': 600, 'value': '_.'}
) )
self.assertEqual( self.assertEqual(
['PTR value "_." is not a valid FQDN'], ctx.exception.reasons
['Invalid PTR value "_." is not a valid FQDN.'],
ctx.exception.reasons,
) )
# no trailing . # no trailing .
@ -3901,6 +3908,32 @@ class TestRecordValidation(TestCase):
['PTR value "foo.bar" missing trailing .'], ctx.exception.reasons ['PTR value "foo.bar" missing trailing .'], ctx.exception.reasons
) )
def test_ptr_rdata_text(self):
# anything goes, we're a noop
for s in (
None,
'',
'word',
42,
42.43,
'1.2.3',
'some.words.that.here',
'1.2.word.4',
'1.2.3.4',
):
self.assertEqual(s, PtrValue.parse_rdata_text(s))
zone = Zone('unit.tests.', [])
a = PtrRecord(zone, 'a', {'ttl': 42, 'value': 'some.target.'})
self.assertEqual('some.target.', a.values[0].rdata_text)
a = PtrRecord(
zone, 'a', {'ttl': 42, 'values': ['some.target.', 'second.target.']}
)
self.assertEqual('second.target.', a.values[0].rdata_text)
self.assertEqual('some.target.', a.values[1].rdata_text)
def test_SSHFP(self): def test_SSHFP(self):
# doesn't blow up # doesn't blow up
Record.new( Record.new(


Loading…
Cancel
Save