mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Turn verify_host_resolvable() into a wrapper around ipapython.dnsutil
The code was duplicate and less generic anyway. As a side-effect I had to re-wrap dns.exception.DNSException into a PublicError so it can be displayed to the user. DNSError is now a super class for other DNS-related errors. Errors from DNS resolver are re-raised as DNSResolverError. https://fedorahosted.org/freeipa/ticket/5710 Reviewed-By: Martin Basti <mbasti@redhat.com>
This commit is contained in:
committed by
Martin Basti
parent
dc405005f5
commit
70794c7b1d
@@ -93,7 +93,9 @@ current block assignments:
|
|||||||
|
|
||||||
- **4300 - 4399** `CertificateError` and its subclasses
|
- **4300 - 4399** `CertificateError` and its subclasses
|
||||||
|
|
||||||
- **4400 - 4999** *Reserved for future use*
|
- **4400 - 4499** `DNSError` and (some of) its subclasses
|
||||||
|
|
||||||
|
- **4500 - 4999** *Reserved for future use*
|
||||||
|
|
||||||
- **5000 - 5999** `GenericError` and its subclasses
|
- **5000 - 5999** `GenericError` and its subclasses
|
||||||
|
|
||||||
@@ -1164,21 +1166,6 @@ class DefaultGroupError(ExecutionError):
|
|||||||
errno = 4018
|
errno = 4018
|
||||||
format = _('The default users group cannot be removed')
|
format = _('The default users group cannot be removed')
|
||||||
|
|
||||||
class DNSNotARecordError(ExecutionError):
|
|
||||||
"""
|
|
||||||
**4019** Raised when a hostname is not a DNS A/AAAA record
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
>>> raise DNSNotARecordError()
|
|
||||||
Traceback (most recent call last):
|
|
||||||
...
|
|
||||||
DNSNotARecordError: Host does not have corresponding DNS A/AAAA record
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
errno = 4019
|
|
||||||
format = _('Host does not have corresponding DNS A/AAAA record')
|
|
||||||
|
|
||||||
class ManagedGroupError(ExecutionError):
|
class ManagedGroupError(ExecutionError):
|
||||||
"""
|
"""
|
||||||
@@ -1598,24 +1585,6 @@ class DatabaseTimeout(DatabaseError):
|
|||||||
format = _('LDAP timeout')
|
format = _('LDAP timeout')
|
||||||
|
|
||||||
|
|
||||||
class DNSDataMismatch(ExecutionError):
|
|
||||||
"""
|
|
||||||
**4212** Raised when an DNS query didn't return expected answer
|
|
||||||
in a configured time limit.
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
>>> raise DNSDataMismatch(expected="zone3.test. 86400 IN A 192.0.2.1", \
|
|
||||||
got="zone3.test. 86400 IN A 192.168.1.1")
|
|
||||||
Traceback (most recent call last):
|
|
||||||
...
|
|
||||||
DNSDataMismatch: DNS check failed: Expected {zone3.test. 86400 IN A 192.0.2.1} got {zone3.test. 86400 IN A 192.168.1.1}
|
|
||||||
"""
|
|
||||||
|
|
||||||
errno = 4212
|
|
||||||
format = _('DNS check failed: Expected {%(expected)s} got {%(got)s}')
|
|
||||||
|
|
||||||
|
|
||||||
class TaskTimeout(DatabaseError):
|
class TaskTimeout(DatabaseError):
|
||||||
"""
|
"""
|
||||||
**4213** Raised when an LDAP task times out
|
**4213** Raised when an LDAP task times out
|
||||||
@@ -1833,6 +1802,67 @@ class CertificateInvalidError(CertificateError):
|
|||||||
format = _('%(name)s certificate is not valid')
|
format = _('%(name)s certificate is not valid')
|
||||||
|
|
||||||
|
|
||||||
|
class DNSError(ExecutionError):
|
||||||
|
"""
|
||||||
|
**4400** Base class for DNS execution errors (*4400 - 4499*).
|
||||||
|
These are typically wrapper exceptions around dns.exception.DNSException.
|
||||||
|
"""
|
||||||
|
|
||||||
|
errno = 4400
|
||||||
|
|
||||||
|
|
||||||
|
class DNSNotARecordError(DNSError):
|
||||||
|
"""
|
||||||
|
**4019** Raised when a hostname is not a DNS A/AAAA record
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
>>> raise DNSNotARecordError(hostname='x')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
DNSNotARecordError: Host 'x' does not have corresponding DNS A/AAAA record
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
errno = 4019 # this exception was defined before DNSError
|
||||||
|
format = _(
|
||||||
|
'Host \'%(hostname)s\' does not have corresponding DNS A/AAAA record')
|
||||||
|
|
||||||
|
|
||||||
|
class DNSDataMismatch(DNSError):
|
||||||
|
"""
|
||||||
|
**4212** Raised when an DNS query didn't return expected answer
|
||||||
|
in a configured time limit.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
>>> raise DNSDataMismatch(expected="zone3.test. 86400 IN A 192.0.2.1", \
|
||||||
|
got="zone3.test. 86400 IN A 192.168.1.1")
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
DNSDataMismatch: DNS check failed: Expected {zone3.test. 86400 IN A 192.0.2.1} got {zone3.test. 86400 IN A 192.168.1.1}
|
||||||
|
"""
|
||||||
|
|
||||||
|
errno = 4212 # this exception was defined before DNSError
|
||||||
|
format = _('DNS check failed: Expected {%(expected)s} got {%(got)s}')
|
||||||
|
|
||||||
|
|
||||||
|
class DNSResolverError(DNSError):
|
||||||
|
"""
|
||||||
|
**4401** Wrapper around dns.exception.DNSException.
|
||||||
|
Raised when an error occured in dns.resolver.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
>>> raise DNSResolverError(exception=ValueError("this is bad"))
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
DNSResolverError: this is bad
|
||||||
|
"""
|
||||||
|
|
||||||
|
errno = 4401
|
||||||
|
format = _('%(exception)s')
|
||||||
|
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# 5000 - 5999: Generic errors
|
# 5000 - 5999: Generic errors
|
||||||
|
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ from ipalib.text import _
|
|||||||
from ipapython.ssh import SSHPublicKey
|
from ipapython.ssh import SSHPublicKey
|
||||||
from ipapython.dn import DN, RDN
|
from ipapython.dn import DN, RDN
|
||||||
from ipapython.dnsutil import DNSName
|
from ipapython.dnsutil import DNSName
|
||||||
|
from ipapython.dnsutil import resolve_ip_addresses
|
||||||
from ipapython.graph import Graph
|
from ipapython.graph import Graph
|
||||||
from ipapython.ipa_log_manager import root_logger
|
|
||||||
|
|
||||||
if six.PY3:
|
if six.PY3:
|
||||||
unicode = str
|
unicode = str
|
||||||
@@ -67,30 +67,12 @@ def json_serialize(obj):
|
|||||||
|
|
||||||
|
|
||||||
def verify_host_resolvable(fqdn):
|
def verify_host_resolvable(fqdn):
|
||||||
"""
|
try:
|
||||||
See if the hostname has a DNS A/AAAA record.
|
if not resolve_ip_addresses(fqdn):
|
||||||
"""
|
raise errors.DNSNotARecordError(hostname=fqdn)
|
||||||
if not isinstance(fqdn, DNSName):
|
except dns.exception.DNSException as ex:
|
||||||
fqdn = DNSName(fqdn)
|
# wrap DNSException in a PublicError
|
||||||
|
raise errors.DNSResolverError(exception=ex)
|
||||||
fqdn = fqdn.make_absolute()
|
|
||||||
for rdtype in ('A', 'AAAA'):
|
|
||||||
try:
|
|
||||||
answers = resolver.query(fqdn, rdtype)
|
|
||||||
root_logger.debug(
|
|
||||||
'IPA: found %d %s records for %s: %s' % (len(answers),
|
|
||||||
rdtype, fqdn, ' '.join(str(answer) for answer in answers))
|
|
||||||
)
|
|
||||||
except DNSException:
|
|
||||||
root_logger.debug(
|
|
||||||
'IPA: DNS %s record lookup failed for %s' %
|
|
||||||
(rdtype, fqdn)
|
|
||||||
)
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
# dns lookup failed in both tries
|
|
||||||
raise errors.DNSNotARecordError()
|
|
||||||
|
|
||||||
|
|
||||||
def has_soa_or_ns_record(domain):
|
def has_soa_or_ns_record(domain):
|
||||||
|
|||||||
@@ -311,8 +311,7 @@ class TestCRUD(XMLRPC_test):
|
|||||||
def test_try_add_not_in_dns(self, host):
|
def test_try_add_not_in_dns(self, host):
|
||||||
host.ensure_missing()
|
host.ensure_missing()
|
||||||
command = host.make_create_command(force=False)
|
command = host.make_create_command(force=False)
|
||||||
with raises_exact(errors.DNSNotARecordError(
|
with raises_exact(errors.DNSNotARecordError(hostname=host)):
|
||||||
reason=u'Host does not have corresponding DNS A/AAAA record')):
|
|
||||||
command()
|
command()
|
||||||
|
|
||||||
def test_add_host_with_null_password(self, host):
|
def test_add_host_with_null_password(self, host):
|
||||||
|
|||||||
Reference in New Issue
Block a user