Browse Source

Record.parse_rdata_texts, TinyDns support for arbitrary record types

pull/1020/head
Ross McFarland 2 years ago
parent
commit
59a8958226
No known key found for this signature in database GPG Key ID: 943B179E15D3B22A
5 changed files with 88 additions and 6 deletions
  1. +4
    -0
      octodns/record/base.py
  2. +39
    -4
      octodns/source/tinydns.py
  3. +15
    -0
      tests/test_octodns_record.py
  4. +22
    -2
      tests/test_octodns_source_tinydns.py
  5. +8
    -0
      tests/zones/tinydns/example.com

+ 4
- 0
octodns/record/base.py View File

@ -123,6 +123,10 @@ class Record(EqualityTupleMixin):
return records
@classmethod
def parse_rdata_texts(cls, rdatas):
return [cls._value_type.parse_rdata_text(r) for r in rdatas]
def __init__(self, zone, name, data, source=None):
self.zone = zone
if name:


+ 39
- 4
octodns/source/tinydns.py View File

@ -357,6 +357,44 @@ class TinyDnsBaseSource(BaseSource):
yield 'SRV', name, ttl, values
def _records_for_colon(self, zone, name, lines, arpa=False):
# :fqdn:n:rdata:ttl:timestamp:lo
# ANY
if arpa:
# no arpa
return []
if not zone.owns('SRV', name):
# if name doesn't live under our zone there's nothing for us to do
return
# group by lines by the record type
types = defaultdict(list)
for line in lines:
types[line[1].upper()].append(line)
classes = Record.registered_types()
for _type, lines in types.items():
_class = classes.get(_type, None)
if not _class:
self.log.info(
'_records_for_colon: unrecognized type %s, %s', _type, line
)
continue
# see if we can find a ttl on any of the lines, first one wins
ttl = self.default_ttl
for line in lines:
try:
ttl = int(line[3])
break
except IndexError:
pass
rdatas = [l[2] for l in lines]
yield _type, name, ttl, _class.parse_rdata_texts(rdatas)
def _records_for_six(self, zone, name, lines, arpa=False):
# 6fqdn:ip:ttl:timestamp:lo
# AAAA (arpa False) & PTR (arpa True)
@ -376,11 +414,8 @@ class TinyDnsBaseSource(BaseSource):
'\'': _records_for_quote, # TXT
'3': _records_for_three, # AAAA
'S': _records_for_S, # SRV
':': _records_for_colon, # arbitrary
'6': _records_for_six, # AAAA
# TODO:
# Sfqdn:ip:x:port:priority:weight:ttl:timestamp:lo
#':': _record_for_semicolon # arbitrary
# :fqdn:n:rdata:ttl:timestamp:lo
}
def _process_lines(self, zone, lines):


+ 15
- 0
tests/test_octodns_record.py View File

@ -8,6 +8,7 @@ from octodns.idna import idna_encode
from octodns.record import (
AliasRecord,
ARecord,
CnameRecord,
Create,
Delete,
MxValue,
@ -176,6 +177,20 @@ class TestRecord(TestCase):
# make sure there's nothing extra
self.assertEqual(5, len(records))
def test_parse_rdata_texts(self):
self.assertEqual(['2.3.4.5'], ARecord.parse_rdata_texts(['2.3.4.5']))
self.assertEqual(
['2.3.4.6', '3.4.5.7'],
ARecord.parse_rdata_texts(['2.3.4.6', '3.4.5.7']),
)
self.assertEqual(
['some.target.'], CnameRecord.parse_rdata_texts(['some.target.'])
)
self.assertEqual(
['some.target.', 'other.target.'],
CnameRecord.parse_rdata_texts(['some.target.', 'other.target.']),
)
def test_values_mixin_data(self):
# no values, no value or values in data
a = ARecord(self.zone, '', {'type': 'A', 'ttl': 600, 'values': []})


+ 22
- 2
tests/test_octodns_source_tinydns.py View File

@ -17,7 +17,7 @@ class TestTinyDnsFileSource(TestCase):
def test_populate_normal(self):
got = Zone('example.com.', [])
self.source.populate(got)
self.assertEqual(28, len(got.records))
self.assertEqual(30, len(got.records))
expected = Zone('example.com.', [])
for name, data in (
@ -177,6 +177,26 @@ class TestTinyDnsFileSource(TestCase):
],
},
),
(
'arbitrary-sshfp',
{
'type': 'SSHFP',
'ttl': 45,
'values': [
{
'algorithm': 1,
'fingerprint_type': 2,
'fingerprint': '00479b27',
},
{
'algorithm': 2,
'fingerprint_type': 2,
'fingerprint': '00479a28',
},
],
},
),
('arbitrary-a', {'type': 'A', 'ttl': 3600, 'value': '80.81.82.83'}),
):
record = Record.new(expected, name, data)
expected.add_record(record)
@ -253,4 +273,4 @@ class TestTinyDnsFileSource(TestCase):
got = Zone('example.com.', ['sub'])
self.source.populate(got)
# we don't see one www.sub.example.com. record b/c it's in a sub
self.assertEqual(27, len(got.records))
self.assertEqual(29, len(got.records))

+ 8
- 0
tests/zones/tinydns/example.com View File

@ -72,3 +72,11 @@ S_a._tcp.example.com::target.somewhere.else:8080:10:50:43
S_b._tcp.example.com:56.57.58.59:target.srv.example.com.:9999
# complete duplicate should be ignored
S_b._tcp.example.com:56.57.58.59:target.srv.example.com.:9999
# arbitrary multi-value non-spec record
:arbitrary-sshfp.example.com:SSHFP:2 2 00479a28
:arbitrary-sshfp.example.com:SSHFP:1 2 00479b27:45
# does not make sense to do an A this way, but it'll work
:arbitrary-a.example.com:a:80.81.82.83
# this should just be inored b/c the type is unknown
:arbitrary-invalid.example.com:invalid:does not matter:99

Loading…
Cancel
Save