summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorence Blanc-Renaud <flo@redhat.com>2018-02-08 16:55:20 +0100
committerFlorence Blanc-Renaud <flo@redhat.com>2018-02-12 17:30:52 +0100
commit7364c268ebc241c2fa456951f0790ee5d83a7b3a (patch)
tree1a495ccb8d08e016b0b26d843b940ccbac6be280
parent93b7c40158313b9f0f125706265ea0ac07fb4c0e (diff)
downloadfreeipa-7364c268ebc241c2fa456951f0790ee5d83a7b3a.tar.gz
freeipa-7364c268ebc241c2fa456951f0790ee5d83a7b3a.tar.xz
freeipa-7364c268ebc241c2fa456951f0790ee5d83a7b3a.zip
ipa host-add --ip-address: properly handle NoNameservers
When ipa host-add --ip-address is called but no DNS server is able to answer for the reverse zone, get_reverse_zone raises a NoNameservers exception. The exception is not managed by add_records_for_host_validation, and this leads to the command exiting on failure with an InternalError: $ ipa host-add testhost.ipadomain.com --ip-address 172.16.30.22 ipa: ERROR: an internal error has occurred A traceback is also logged in httpd error_log. This commit properly handles the exception, and adds a test. https://pagure.io/freeipa/issue/7397 Reviewed-By: Christian Heimes <cheimes@redhat.com>
-rw-r--r--ipaserver/plugins/dns.py9
-rw-r--r--ipatests/test_xmlrpc/test_host_plugin.py72
2 files changed, 80 insertions, 1 deletions
diff --git a/ipaserver/plugins/dns.py b/ipaserver/plugins/dns.py
index e6a1f580e..016be0c6f 100644
--- a/ipaserver/plugins/dns.py
+++ b/ipaserver/plugins/dns.py
@@ -539,7 +539,14 @@ def get_reverse_zone(ipaddr):
"""
ip = netaddr.IPAddress(str(ipaddr))
revdns = DNSName(unicode(ip.reverse_dns))
- revzone = DNSName(dns.resolver.zone_for_name(revdns))
+ try:
+ revzone = DNSName(dns.resolver.zone_for_name(revdns))
+ except dns.resolver.NoNameservers:
+ raise errors.NotFound(
+ reason=_(
+ 'All nameservers failed to answer the query '
+ 'for DNS reverse zone %(revdns)s') % dict(revdns=revdns)
+ )
try:
api.Command['dnszone_show'](revzone)
diff --git a/ipatests/test_xmlrpc/test_host_plugin.py b/ipatests/test_xmlrpc/test_host_plugin.py
index e0df6bc04..0acb6cf10 100644
--- a/ipatests/test_xmlrpc/test_host_plugin.py
+++ b/ipatests/test_xmlrpc/test_host_plugin.py
@@ -100,6 +100,9 @@ hostgroup1_dn = DN(('cn',hostgroup1),('cn','hostgroups'),('cn','accounts'),
host_cert = get_testcert(DN(('CN', api.env.host), subject_base()),
'host/%s@%s' % (api.env.host, api.env.realm))
+missingrevzone = u'22.30.16.172.in-addr.arpa.'
+ipv4_in_missingrevzone_ip = u'172.16.30.22'
+
@pytest.fixture(scope='class')
def host(request):
@@ -120,6 +123,12 @@ def host3(request):
@pytest.fixture(scope='class')
+def host4(request):
+ tracker = HostTracker(name=u'testhost4')
+ return tracker.make_fixture(request)
+
+
+@pytest.fixture(scope='class')
def lab_host(request):
name = u'testhost1'
tracker = HostTracker(name=name,
@@ -591,6 +600,69 @@ class TestHostFalsePwdChange(XMLRPC_test):
@yield_fixture(scope='class')
+def dns_setup_nonameserver(host4):
+ # Make sure that the server does not handle the reverse zone used
+ # for the test
+ try:
+ host4.run_command('dnszone_del', missingrevzone, **{'continue': True})
+ except (errors.NotFound, errors.EmptyModlist):
+ pass
+
+ # Save the current forward policy
+ result = host4.run_command('dnsserver_show', api.env.host)
+ current_fwd_pol = result['result']['idnsforwardpolicy'][0]
+
+ # Configure the forward policy to none to make sure that no DNS
+ # server will answer for the reverse zone either
+ try:
+ host4.run_command('dnsserver_mod', api.env.host,
+ idnsforwardpolicy=u'none')
+ except errors.EmptyModlist:
+ pass
+
+ try:
+ yield
+ finally:
+ # Restore the previous forward-policy
+ try:
+ host4.run_command('dnsserver_mod', api.env.host,
+ idnsforwardpolicy=current_fwd_pol)
+ except errors.EmptyModlist:
+ pass
+
+
+@pytest.mark.tier1
+class TestHostNoNameserversForRevZone(XMLRPC_test):
+ def test_create_host_with_ip(self, dns_setup_nonameserver, host4):
+ """
+ Regression test for ticket 7397
+
+ Configure the master with forward-policy = none to make sure
+ that no DNS server will answer for the reverse zone
+ Try to add a new host with an IP address in the missing reverse
+ zone.
+ With issue 7397, a NoNameserver exception generates a Traceback in
+ httpd error_log, and the command returns an InternalError.
+ """
+ try:
+ command = host4.make_create_command()
+ with raises_exact(errors.NonFatalError(
+ reason=u'The host was added but the DNS update failed with'
+ ': All nameservers failed to answer the query for DNS '
+ 'reverse zone %s' % missingrevzone)):
+ command(ip_address=ipv4_in_missingrevzone_ip)
+ # Make sure the host is added
+ host4.run_command('host_show', host4.fqdn)
+ finally:
+ # Delete the host entry
+ command = host4.make_delete_command()
+ try:
+ command(updatedns=True)
+ except Exception:
+ pass
+
+
+@yield_fixture(scope='class')
def dns_setup(host):
try:
host.run_command('dnszone_del', dnszone, revzone, revipv6zone,