diff options
author | Petr Spacek <pspacek@redhat.com> | 2016-05-17 17:26:20 +0200 |
---|---|---|
committer | Martin Basti <mbasti@redhat.com> | 2016-05-30 20:14:32 +0200 |
commit | dc405005f537cf278fd6ddfe6b87060bd13d9a67 (patch) | |
tree | e77d279876f8be3e0ead4c298ed32a7cd0da05f7 /ipapython/dnsutil.py | |
parent | ec49130b94d2aa195c6b704a30fe6c3137fabdbf (diff) | |
download | freeipa-dc405005f537cf278fd6ddfe6b87060bd13d9a67.tar.gz freeipa-dc405005f537cf278fd6ddfe6b87060bd13d9a67.tar.xz freeipa-dc405005f537cf278fd6ddfe6b87060bd13d9a67.zip |
Move IP address resolution from ipaserver.install.installutils to ipapython.dnsutil
This is to make it reusable from other modules and to avoid future code
duplication.
https://fedorahosted.org/freeipa/ticket/5710
Reviewed-By: Martin Basti <mbasti@redhat.com>
Diffstat (limited to 'ipapython/dnsutil.py')
-rw-r--r-- | ipapython/dnsutil.py | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/ipapython/dnsutil.py b/ipapython/dnsutil.py index 6287e3eef..7fa7646d9 100644 --- a/ipapython/dnsutil.py +++ b/ipapython/dnsutil.py @@ -24,6 +24,9 @@ import copy import six +from ipapython.ipautil import CheckedIPAddress +from ipapython.ipa_log_manager import root_logger + if six.PY3: unicode = str @@ -231,6 +234,62 @@ def inside_auto_empty_zone(name): return False +def resolve_rrsets(fqdn, rdtypes): + """ + Get Resource Record sets for given FQDN. + CNAME chain is followed during resolution + but CNAMEs are not returned in the resulting rrset. + + :returns: + set of dns.rrset.RRset objects, can be empty + if the FQDN does not exist or if none of rrtypes exist + """ + # empty set of rdtypes would always return empty set of rrsets + assert rdtypes, "rdtypes must not be empty" + + if not isinstance(fqdn, DNSName): + fqdn = DNSName(fqdn) + + fqdn = fqdn.make_absolute() + rrsets = set() + for rdtype in rdtypes: + try: + answer = dns.resolver.query(fqdn, rdtype) + root_logger.debug('found %d %s records for %s: %s', + len(answer), rdtype, fqdn, ' '.join( + str(rr) for rr in answer)) + rrsets.add(answer.rrset) + except dns.resolver.NXDOMAIN as ex: + root_logger.debug(ex) + break # no such FQDN, do not iterate + except dns.resolver.NoAnswer as ex: + root_logger.debug(ex) # record type does not exist for given FQDN + except dns.exception.DNSException as ex: + root_logger.error('DNS query for %s %s failed: %s', + fqdn, rdtype, ex) + raise + + return rrsets + + +def resolve_ip_addresses(fqdn): + """Get IP addresses from DNS A/AAAA records for given host. + :returns: + list of IP addresses as CheckedIPAddress objects + """ + rrsets = resolve_rrsets(fqdn, ['A', 'AAAA']) + ip_addresses = set() + for rrset in rrsets: + ip_addresses.update({CheckedIPAddress(ip, # accept whatever is in DNS + parse_netmask=False, + allow_network=True, + allow_loopback=True, + allow_broadcast=True, + allow_multicast=True) + for ip in rrset}) + return ip_addresses + + def check_zone_overlap(zone, raise_on_error=True): root_logger.info("Checking DNS domain %s, please wait ..." % zone) if not isinstance(zone, DNSName): |