diff --git a/octodns/record/__init__.py b/octodns/record/__init__.py index c945aaf..f22eebf 100644 --- a/octodns/record/__init__.py +++ b/octodns/record/__init__.py @@ -10,6 +10,7 @@ from logging import getLogger import re from six import string_types, text_type +from fqdn import FQDN from ..equality import EqualityTupleMixin from .geo import GeoCodes @@ -757,6 +758,9 @@ class _TargetValue(object): reasons.append('empty value') elif not data: reasons.append('missing value') + elif not FQDN(data, allow_underscores=True).is_valid: + reasons.append('{} value "{}" is not a valid FQDN' + .format(_type, data)) elif not data.endswith('.'): reasons.append('{} value "{}" missing trailing .' .format(_type, data)) diff --git a/requirements.txt b/requirements.txt index bc9a019..8b9c052 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,6 +7,7 @@ dnspython==1.16.0 docutils==0.16 dyn==1.8.1 edgegrid-python==1.1.1 +fqdn==1.5.0 futures==3.2.0; python_version < '3.2' google-cloud-core==1.4.1 google-cloud-dns==0.32.0 diff --git a/tests/test_octodns_record.py b/tests/test_octodns_record.py index d4497e8..d55b3b8 100644 --- a/tests/test_octodns_record.py +++ b/tests/test_octodns_record.py @@ -1799,6 +1799,16 @@ class TestRecordValidation(TestCase): }) self.assertEquals(['empty value'], ctx.exception.reasons) + # not a valid FQDN + with self.assertRaises(ValidationError) as ctx: + Record.new(self.zone, '', { + 'type': 'ALIAS', + 'ttl': 600, + 'value': '__.', + }) + self.assertEquals(['ALIAS value "__." is not a valid FQDN'], + ctx.exception.reasons) + # missing trailing . with self.assertRaises(ValidationError) as ctx: Record.new(self.zone, '', { @@ -1895,6 +1905,16 @@ class TestRecordValidation(TestCase): }) self.assertEquals(['root CNAME not allowed'], ctx.exception.reasons) + # not a valid FQDN + with self.assertRaises(ValidationError) as ctx: + Record.new(self.zone, 'www', { + 'type': 'CNAME', + 'ttl': 600, + 'value': '___.', + }) + self.assertEquals(['CNAME value "___." is not a valid FQDN'], + ctx.exception.reasons) + # missing trailing . with self.assertRaises(ValidationError) as ctx: Record.new(self.zone, 'www', { @@ -1920,6 +1940,16 @@ class TestRecordValidation(TestCase): 'value': 'foo.bar.com.', }) + # not a valid FQDN + with self.assertRaises(ValidationError) as ctx: + Record.new(self.zone, 'www', { + 'type': 'DNAME', + 'ttl': 600, + 'value': '.', + }) + self.assertEquals(['DNAME value "." is not a valid FQDN'], + ctx.exception.reasons) + # missing trailing . with self.assertRaises(ValidationError) as ctx: Record.new(self.zone, 'www', { @@ -2103,6 +2133,16 @@ class TestRecordValidation(TestCase): }) self.assertEquals(['missing value'], ctx.exception.reasons) + # not a valid FQDN + with self.assertRaises(ValidationError) as ctx: + Record.new(self.zone, '', { + 'type': 'PTR', + 'ttl': 600, + 'value': '_.', + }) + self.assertEquals(['PTR value "_." is not a valid FQDN'], + ctx.exception.reasons) + # no trailing . with self.assertRaises(ValidationError) as ctx: Record.new(self.zone, '', {