1
0
mirror of https://github.com/github/octodns.git synced 2024-05-11 05:55:00 +00:00

parse_rdata_text supports unquoting things (powerdns)

This commit is contained in:
Ross McFarland
2023-09-25 12:59:51 -07:00
parent 76e330a7c3
commit bca8db6c8f
17 changed files with 118 additions and 12 deletions

View File

@ -12,6 +12,12 @@ from .change import Update
from .exception import RecordException, ValidationError
def unquote(s):
if s and s[0] in ('"', "'"):
return s[1:-1]
return s
class Record(EqualityTupleMixin):
log = getLogger('Record')

View File

@ -3,7 +3,7 @@
#
from ..equality import EqualityTupleMixin
from .base import Record, ValuesMixin
from .base import Record, ValuesMixin, unquote
from .rr import RrParseError
@ -20,6 +20,8 @@ class CaaValue(EqualityTupleMixin, dict):
flags = int(flags)
except ValueError:
pass
tag = unquote(tag)
value = unquote(value)
return {'flags': flags, 'tag': tag, 'value': value}
@classmethod

View File

@ -3,7 +3,7 @@
#
from ..equality import EqualityTupleMixin
from .base import Record, ValuesMixin
from .base import Record, ValuesMixin, unquote
from .rr import RrParseError
@ -58,21 +58,23 @@ class LocValue(EqualityTupleMixin, dict):
except ValueError:
pass
try:
altitude = float(altitude)
altitude = float(unquote(altitude))
except ValueError:
pass
try:
size = float(size)
size = float(unquote(size))
except ValueError:
pass
try:
precision_horz = float(precision_horz)
precision_horz = float(unquote(precision_horz))
except ValueError:
pass
try:
precision_vert = float(precision_vert)
precision_vert = float(unquote(precision_vert))
except ValueError:
pass
lat_direction = unquote(lat_direction)
long_direction = unquote(long_direction)
return {
'lat_degrees': lat_degrees,
'lat_minutes': lat_minutes,

View File

@ -6,7 +6,7 @@ from fqdn import FQDN
from ..equality import EqualityTupleMixin
from ..idna import idna_encode
from .base import Record, ValuesMixin
from .base import Record, ValuesMixin, unquote
from .rr import RrParseError
@ -21,6 +21,7 @@ class MxValue(EqualityTupleMixin, dict):
preference = int(preference)
except ValueError:
pass
exchange = unquote(exchange)
return {'preference': preference, 'exchange': exchange}
@classmethod

View File

@ -3,7 +3,7 @@
#
from ..equality import EqualityTupleMixin
from .base import Record, ValuesMixin
from .base import Record, ValuesMixin, unquote
from .rr import RrParseError
@ -28,6 +28,10 @@ class NaptrValue(EqualityTupleMixin, dict):
preference = int(preference)
except ValueError:
pass
flags = unquote(flags)
service = unquote(service)
regexp = unquote(regexp)
replacement = unquote(replacement)
return {
'order': order,
'preference': preference,

View File

@ -8,7 +8,7 @@ from fqdn import FQDN
from ..equality import EqualityTupleMixin
from ..idna import idna_encode
from .base import Record, ValuesMixin
from .base import Record, ValuesMixin, unquote
from .rr import RrParseError
@ -31,6 +31,7 @@ class SrvValue(EqualityTupleMixin, dict):
port = int(port)
except ValueError:
pass
target = unquote(target)
return {
'priority': priority,
'weight': weight,

View File

@ -3,7 +3,7 @@
#
from ..equality import EqualityTupleMixin
from .base import Record, ValuesMixin
from .base import Record, ValuesMixin, unquote
from .rr import RrParseError
@ -25,6 +25,7 @@ class SshfpValue(EqualityTupleMixin, dict):
fingerprint_type = int(fingerprint_type)
except ValueError:
pass
fingerprint = unquote(fingerprint)
return {
'algorithm': algorithm,
'fingerprint_type': fingerprint_type,

View File

@ -3,7 +3,7 @@
#
from ..equality import EqualityTupleMixin
from .base import Record, ValuesMixin
from .base import Record, ValuesMixin, unquote
from .rr import RrParseError
@ -31,6 +31,7 @@ class TlsaValue(EqualityTupleMixin, dict):
matching_type = int(matching_type)
except ValueError:
pass
certificate_association_data = unquote(certificate_association_data)
return {
'certificate_usage': certificate_usage,
'selector': selector,

View File

@ -22,6 +22,7 @@ from octodns.record import (
ValidationError,
ValuesMixin,
)
from octodns.record.base import unquote
from octodns.yaml import ContextDict
from octodns.zone import Zone
@ -412,6 +413,18 @@ class TestRecord(TestCase):
record.rrs,
)
def test_unquote(self):
s = 'Hello "\'"World!'
single = f"'{s}'"
double = f'"{s}"'
self.assertEqual(s, unquote(s))
self.assertEqual(s, unquote(single))
self.assertEqual(s, unquote(double))
# edge cases
self.assertEqual(None, unquote(None))
self.assertEqual('', unquote(''))
class TestRecordValidation(TestCase):
zone = Zone('unit.tests.', [])

View File

@ -105,6 +105,12 @@ class TestRecordCaa(TestCase):
CaaValue.parse_rdata_text('0 tag 99148c81'),
)
# quoted
self.assertEqual(
{'flags': 0, 'tag': 'tag', 'value': '99148c81'},
CaaValue.parse_rdata_text('0 "tag" "99148c81"'),
)
zone = Zone('unit.tests.', [])
a = CaaRecord(
zone,

View File

@ -21,6 +21,8 @@ class TestRecordChunked(TestCase):
'some.words.that.here',
'1.2.word.4',
'1.2.3.4',
# quotes are not removed
'"Hello World!"',
):
self.assertEqual(s, _ChunkedValue.parse_rdata_text(s))

View File

@ -160,6 +160,26 @@ class TestRecordLoc(TestCase):
LocValue.parse_rdata_text(s),
)
# quoted
s = '0 1 2.2 "N" 3 4 5.5 "E" "6.6m" "7.7m" "8.8m" "9.9m"'
self.assertEqual(
{
'altitude': 6.6,
'lat_degrees': 0,
'lat_direction': 'N',
'lat_minutes': 1,
'lat_seconds': 2.2,
'long_degrees': 3,
'long_direction': 'E',
'long_minutes': 4,
'long_seconds': 5.5,
'precision_horz': 8.8,
'precision_vert': 9.9,
'size': 7.7,
},
LocValue.parse_rdata_text(s),
)
# make sure that the cstor is using parse_rdata_text
zone = Zone('unit.tests.', [])
a = LocRecord(
@ -196,7 +216,7 @@ class TestRecordLoc(TestCase):
self.assertEqual(7.7, a.values[0].size)
self.assertEqual(8.8, a.values[0].precision_horz)
self.assertEqual(9.9, a.values[0].precision_vert)
self.assertEqual(s, a.values[0].rdata_text)
self.assertEqual(s.replace('"', ''), a.values[0].rdata_text)
def test_loc_value(self):
a = LocValue(

View File

@ -92,6 +92,12 @@ class TestRecordMx(TestCase):
MxValue.parse_rdata_text('10 mx.unit.tests.'),
)
# quoted
self.assertEqual(
{'preference': 10, 'exchange': 'mx.unit.tests.'},
MxValue.parse_rdata_text('10 "mx.unit.tests."'),
)
zone = Zone('unit.tests.', [])
a = MxRecord(
zone,

View File

@ -346,6 +346,19 @@ class TestRecordNaptr(TestCase):
NaptrValue.parse_rdata_text('1 2 three four five six'),
)
# string fields are unquoted if needed
self.assertEqual(
{
'order': 1,
'preference': 2,
'flags': 'three',
'service': 'four',
'regexp': 'five',
'replacement': 'six',
},
NaptrValue.parse_rdata_text('1 2 "three" "four" "five" "six"'),
)
# make sure that the cstor is using parse_rdata_text
zone = Zone('unit.tests.', [])
a = NaptrRecord(

View File

@ -123,6 +123,17 @@ class TestRecordSrv(TestCase):
SrvValue.parse_rdata_text('1 2 3 srv.unit.tests.'),
)
# quoted
self.assertEqual(
{
'priority': 1,
'weight': 2,
'port': 3,
'target': 'srv.unit.tests.',
},
SrvValue.parse_rdata_text('1 2 3 "srv.unit.tests."'),
)
zone = Zone('unit.tests.', [])
a = SrvRecord(
zone,

View File

@ -113,6 +113,12 @@ class TestRecordSshfp(TestCase):
SshfpValue.parse_rdata_text('1 2 00479b27'),
)
# valid
self.assertEqual(
{'algorithm': 1, 'fingerprint_type': 2, 'fingerprint': '00479b27'},
SshfpValue.parse_rdata_text('1 2 "00479b27"'),
)
zone = Zone('unit.tests.', [])
a = SshfpRecord(
zone,

View File

@ -160,6 +160,17 @@ class TestRecordTlsa(TestCase):
TlsaValue.parse_rdata_text('1 2 3 abcd'),
)
# valid
self.assertEqual(
{
'certificate_usage': 1,
'selector': 2,
'matching_type': 3,
'certificate_association_data': 'abcd',
},
TlsaValue.parse_rdata_text('1 2 3 "abcd"'),
)
zone = Zone('unit.tests.', [])
a = TlsaRecord(
zone,