diff --git a/ipalib/plugins/dns.py b/ipalib/plugins/dns.py index 192cc051c..1bf754272 100644 --- a/ipalib/plugins/dns.py +++ b/ipalib/plugins/dns.py @@ -18,9 +18,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +from __future__ import absolute_import + import netaddr import time import re +import dns.name from ipalib.request import context from ipalib import api, errors, output @@ -1488,7 +1491,11 @@ def zone_is_reverse(zone_name): return False -def check_ns_rec_resolvable(name): +def check_ns_rec_resolvable(zone, name): + if not name.endswith('.'): + # this is a DNS name relative to the zone + zone = dns.name.from_text(zone) + name = unicode(dns.name.from_text(name, origin=zone)) try: return api.Command['dns_resolve'](name) except errors.NotFound: @@ -1707,12 +1714,12 @@ class dnszone_add(LDAPCreate): raise errors.ValidationError(name='name-server', error=unicode(_("Nameserver address is not a fully qualified domain name"))) - if not 'ip_address' in options and not options['force']: - check_ns_rec_resolvable(nameserver) - if nameserver[-1] != '.': nameserver += '.' + if not 'ip_address' in options and not options['force']: + check_ns_rec_resolvable(keys[0], nameserver) + entry_attrs['nsrecord'] = nameserver entry_attrs['idnssoamname'] = nameserver return dn @@ -1878,7 +1885,8 @@ class dnsrecord(LDAPObject): nsrecords = entry_attrs.get('nsrecord') if options.get('force', False) or nsrecords is None: return - map(check_ns_rec_resolvable, nsrecords) + for nsrecord in nsrecords: + check_ns_rec_resolvable(keys[0], nsrecord) def _ptrrecord_pre_callback(self, ldap, dn, entry_attrs, *keys, **options): ptrrecords = entry_attrs.get('ptrrecord') diff --git a/tests/test_xmlrpc/test_dns_plugin.py b/tests/test_xmlrpc/test_dns_plugin.py index b18ca9081..532961039 100644 --- a/tests/test_xmlrpc/test_dns_plugin.py +++ b/tests/test_xmlrpc/test_dns_plugin.py @@ -820,14 +820,20 @@ class test_dns(Declarative): ), dict( - desc='Try to add unresolvable NS record to %r using dnsrecord_add' % (dnsres1), + desc='Try to add unresolvable absolute NS record to %r using dnsrecord_add' % (dnsres1), + command=('dnsrecord_add', [dnszone1, dnsres1], {'nsrecord': u'does.not.exist.'}), + expected=errors.NotFound(reason=u"Nameserver 'does.not.exist.' does not have a corresponding A/AAAA record"), + ), + + dict( + desc='Try to add unresolvable relative NS record to %r using dnsrecord_add' % (dnsres1), command=('dnsrecord_add', [dnszone1, dnsres1], {'nsrecord': u'does.not.exist'}), - expected=errors.NotFound(reason=u"Nameserver 'does.not.exist' does not have a corresponding A/AAAA record"), + expected=errors.NotFound(reason=u"Nameserver 'does.not.exist.%s.' does not have a corresponding A/AAAA record" % dnszone1), ), dict( desc='Add unresolvable NS record with --force to %r using dnsrecord_add' % (dnsres1), - command=('dnsrecord_add', [dnszone1, dnsres1], {'nsrecord': u'does.not.exist', + command=('dnsrecord_add', [dnszone1, dnsres1], {'nsrecord': u'does.not.exist.', 'force' : True}), expected={ 'value': dnsres1, @@ -841,7 +847,7 @@ class test_dns(Declarative): 'kxrecord': [u'1 foo-1'], 'txtrecord': [u'foo bar'], 'nsecrecord': [dnszone1 + u' TXT A'], - 'nsrecord': [u'does.not.exist'], + 'nsrecord': [u'does.not.exist.'], }, }, ), @@ -866,7 +872,7 @@ class test_dns(Declarative): 'kxrecord': [u'1 foo-1'], 'txtrecord': [u'foo bar'], 'nsecrecord': [dnszone1 + u' TXT A'], - 'nsrecord': [u'does.not.exist'], + 'nsrecord': [u'does.not.exist.'], }, }, ),