mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Lookup ipa-ca record with NSS
DNS data management now uses NSS's getaddrinfo() instead of direct DNS queries to resolve the ipa-ca record. This fixes missing ipa-ca records when the current hostname is not resolvable in DNS but has correct records in /etc/hosts. Reduce timeout to 15 seconds and tighten timeout loop. The changeset can speed up installation by almost 60 seconds. ipa-server-install without built-in DNS calls into DNS data management twice with a timeout of 30 seconds for each call. Fixes: https://pagure.io/freeipa/issue/8529 Related: https://pagure.io/freeipa/issue/8521 Related: https://pagure.io/freeipa/issue/8501 Signed-off-by: Christian Heimes <cheimes@redhat.com> Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
This commit is contained in:
@@ -15,13 +15,13 @@ from dns import (
|
|||||||
rdatatype,
|
rdatatype,
|
||||||
zone,
|
zone,
|
||||||
)
|
)
|
||||||
from dns.exception import DNSException
|
|
||||||
|
|
||||||
from time import sleep, time
|
from time import sleep, time
|
||||||
|
|
||||||
from ipalib import errors
|
from ipalib import errors
|
||||||
from ipalib.dns import record_name_format
|
from ipalib.dns import record_name_format
|
||||||
from ipapython.dnsutil import DNSName, resolve_rrsets
|
from ipapython.dnsutil import DNSName
|
||||||
|
from ipaserver.install import installutils
|
||||||
|
|
||||||
if six.PY3:
|
if six.PY3:
|
||||||
unicode=str
|
unicode=str
|
||||||
@@ -55,7 +55,7 @@ IPA_DEFAULT_NTP_SRV_REC = (
|
|||||||
(DNSName("_ntp._udp"), 123),
|
(DNSName("_ntp._udp"), 123),
|
||||||
)
|
)
|
||||||
|
|
||||||
CA_RECORDS_DNS_TIMEOUT = 30 # timeout in seconds
|
CA_RECORDS_DNS_TIMEOUT = 15 # timeout in seconds
|
||||||
|
|
||||||
|
|
||||||
class IPADomainIsNotManagedByIPAError(Exception):
|
class IPADomainIsNotManagedByIPAError(Exception):
|
||||||
@@ -139,16 +139,20 @@ class IPASystemRecords:
|
|||||||
def __add_ca_records_from_hostname(self, zone_obj, hostname):
|
def __add_ca_records_from_hostname(self, zone_obj, hostname):
|
||||||
assert isinstance(hostname, DNSName) and hostname.is_absolute()
|
assert isinstance(hostname, DNSName) and hostname.is_absolute()
|
||||||
r_name = DNSName('ipa-ca') + self.domain_abs
|
r_name = DNSName('ipa-ca') + self.domain_abs
|
||||||
rrsets = []
|
rrsets = None
|
||||||
end_time = time() + CA_RECORDS_DNS_TIMEOUT
|
end_time = time() + CA_RECORDS_DNS_TIMEOUT
|
||||||
while time() < end_time:
|
while True:
|
||||||
try:
|
try:
|
||||||
rrsets = resolve_rrsets(hostname, (rdatatype.A, rdatatype.AAAA))
|
# function logs errors
|
||||||
except DNSException: # logging is done inside resolve_rrsets
|
rrsets = installutils.resolve_rrsets_nss(hostname)
|
||||||
|
except OSError:
|
||||||
|
# also retry on EAI_AGAIN, EAI_FAIL
|
||||||
pass
|
pass
|
||||||
if rrsets:
|
if rrsets:
|
||||||
break
|
break
|
||||||
sleep(5)
|
if time() >= end_time:
|
||||||
|
break
|
||||||
|
sleep(3)
|
||||||
|
|
||||||
if not rrsets:
|
if not rrsets:
|
||||||
logger.error('unable to resolve host name %s to IP address, '
|
logger.error('unable to resolve host name %s to IP address, '
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ from contextlib import contextmanager
|
|||||||
from configparser import ConfigParser as SafeConfigParser
|
from configparser import ConfigParser as SafeConfigParser
|
||||||
from configparser import NoOptionError
|
from configparser import NoOptionError
|
||||||
|
|
||||||
from dns import rdatatype
|
from dns import rrset, rdatatype, rdataclass
|
||||||
from dns.exception import DNSException
|
from dns.exception import DNSException
|
||||||
import ldap
|
import ldap
|
||||||
import six
|
import six
|
||||||
@@ -55,7 +55,7 @@ from ipalib.util import validate_hostname
|
|||||||
from ipalib import api, errors, x509
|
from ipalib import api, errors, x509
|
||||||
from ipalib.install import dnsforwarders
|
from ipalib.install import dnsforwarders
|
||||||
from ipapython.dn import DN
|
from ipapython.dn import DN
|
||||||
from ipapython.dnsutil import resolve
|
from ipapython.dnsutil import DNSName, resolve
|
||||||
from ipaserver.install import certs, service, sysupgrade
|
from ipaserver.install import certs, service, sysupgrade
|
||||||
from ipaplatform import services
|
from ipaplatform import services
|
||||||
from ipaplatform.paths import paths
|
from ipaplatform.paths import paths
|
||||||
@@ -480,6 +480,40 @@ def resolve_ip_addresses_nss(fqdn):
|
|||||||
return ip_addresses
|
return ip_addresses
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_rrsets_nss(fqdn):
|
||||||
|
"""Get list of dnspython RRsets from NSS"""
|
||||||
|
if not isinstance(fqdn, DNSName):
|
||||||
|
fqdn = DNSName.from_text(fqdn)
|
||||||
|
|
||||||
|
ip_addresses = resolve_ip_addresses_nss(fqdn.to_text())
|
||||||
|
|
||||||
|
# split IP addresses into IPv4 and IPv6
|
||||||
|
ipv4 = []
|
||||||
|
ipv6 = []
|
||||||
|
for ip_address in ip_addresses:
|
||||||
|
if ip_address.version == 4:
|
||||||
|
ipv4.append(str(ip_address))
|
||||||
|
elif ip_address.version == 6:
|
||||||
|
ipv6.append(str(ip_address))
|
||||||
|
|
||||||
|
# construct an RRset for each address type. TTL is irrelevant
|
||||||
|
ttl = 3600
|
||||||
|
rrs = []
|
||||||
|
if ipv4:
|
||||||
|
rrs.append(
|
||||||
|
rrset.from_text_list(
|
||||||
|
fqdn, ttl, rdataclass.IN, rdatatype.A, ipv4
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if ipv6:
|
||||||
|
rrs.append(
|
||||||
|
rrset.from_text_list(
|
||||||
|
fqdn, ttl, rdataclass.IN, rdatatype.AAAA, ipv6
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return rrs
|
||||||
|
|
||||||
|
|
||||||
def get_server_ip_address(host_name, unattended, setup_dns, ip_addresses):
|
def get_server_ip_address(host_name, unattended, setup_dns, ip_addresses):
|
||||||
hostaddr = resolve_ip_addresses_nss(host_name)
|
hostaddr = resolve_ip_addresses_nss(host_name)
|
||||||
if hostaddr.intersection(
|
if hostaddr.intersection(
|
||||||
|
|||||||
Reference in New Issue
Block a user