ipa host-add: do not raise exception when reverse record not added

When ipa host-add --random is unable to add a reverse record (for instance
because the server does not manage any reverse zone), the command
adds the host but exits (return code=1) with an error without actually
outputing the random password generated.
With this fix, the behavior is modified. The commands succeeds (return code=0)
but prints a warning.

This commit also adds a unit test.

https://pagure.io/freeipa/issue/7374

Reviewed-By: Christian Heimes <cheimes@redhat.com>
This commit is contained in:
Florence Blanc-Renaud 2018-01-30 12:49:35 +01:00 committed by Christian Heimes
parent 642712f9c4
commit 4295df17a4
3 changed files with 49 additions and 14 deletions

View File

@ -476,6 +476,17 @@ class CertificateInvalid(PublicMessage):
"%(reason)s")
class FailedToAddHostDNSRecords(PublicMessage):
"""
**13030** Failed to add host DNS records
"""
errno = 13030
type = "warning"
format = _("The host was added but the DNS update failed with: "
"%(reason)s")
def iter_messages(variables, base):
"""Return a tuple with all subclasses
"""

View File

@ -700,7 +700,6 @@ class host_add(LDAPCreate):
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
assert isinstance(dn, DN)
exc = None
if dns_container_exists(ldap):
try:
parts = keys[-1].split('.')
@ -719,18 +718,15 @@ class host_add(LDAPCreate):
update_sshfp_record(domain, unicode(parts[0]), entry_attrs)
except Exception as e:
exc = e
self.add_message(messages.FailedToAddHostDNSRecords(reason=e))
if options.get('random', False):
try:
entry_attrs['randompassword'] = unicode(getattr(context, 'randompassword'))
entry_attrs['randompassword'] = unicode(
getattr(context, 'randompassword'))
except AttributeError:
# On the off-chance some other extension deletes this from the
# context, don't crash.
pass
if exc:
raise errors.NonFatalError(
reason=_('The host was added but the DNS update failed with: %(exc)s') % dict(exc=exc)
)
set_certificate_attrs(entry_attrs)
set_kerberos_attrs(entry_attrs, options)
rename_ipaallowedtoperform_from_ldap(entry_attrs, options)

View File

@ -31,7 +31,7 @@ import base64
import pytest
from ipapython import ipautil
from ipalib import api, errors
from ipalib import api, errors, messages
from ipapython.dn import DN
from ipapython.dnsutil import DNSName
from ipatests.test_util import yield_fixture
@ -646,11 +646,13 @@ class TestHostNoNameserversForRevZone(XMLRPC_test):
"""
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)
result = command(ip_address=ipv4_in_missingrevzone_ip)
msg = result['messages'][0]
assert msg['code'] == messages.FailedToAddHostDNSRecords.errno
expected_msg = ("The host was added but the DNS update failed "
"with: All nameservers failed to answer the query "
"for DNS reverse zone {}").format(missingrevzone)
assert msg['message'] == expected_msg
# Make sure the host is added
host4.run_command('host_show', host4.fqdn)
finally:
@ -658,7 +660,33 @@ class TestHostNoNameserversForRevZone(XMLRPC_test):
command = host4.make_delete_command()
try:
command(updatedns=True)
except Exception:
except errors.NotFound:
pass
def test_create_host_with_otp(self, dns_setup_nonameserver, host4):
"""
Create a test host specifying an IP address for which
IPA does not handle the reverse zone, and requesting
the creation of a random password.
Non-reg test for ticket 7374.
"""
command = host4.make_create_command()
try:
result = command(random=True, ip_address=ipv4_in_missingrevzone_ip)
# Make sure a random password is returned
assert result['result']['randompassword']
# Make sure the warning about missing DNS record is added
msg = result['messages'][0]
assert msg['code'] == messages.FailedToAddHostDNSRecords.errno
assert msg['message'].startswith(
u'The host was added but the DNS update failed with:')
finally:
# Cleanup
try:
command = host4.make_delete_command()
command(updatedns=True)
except errors.NotFound:
pass