diff --git a/ipapython/dnsutil.py b/ipapython/dnsutil.py index e51dabd37..aec1ec231 100644 --- a/ipapython/dnsutil.py +++ b/ipapython/dnsutil.py @@ -39,6 +39,12 @@ if six.PY3: logger = logging.getLogger(__name__) +class DNSZoneAlreadyExists(dns.exception.DNSException): + supp_kwargs = {'zone', 'ns'} + fmt = (u"DNS zone {zone} already exists in DNS " + "and is handled by server(s): {ns}") + + @six.python_2_unicode_compatible class DNSName(dns.name.Name): labels = None # make pylint happy @@ -374,10 +380,7 @@ def check_zone_overlap(zone, raise_on_error=True): zone, e) ns = [] - msg = u"DNS zone {0} already exists in DNS".format(zone) - if ns: - msg += u" and is handled by server(s): {0}".format(', '.join(ns)) - raise ValueError(msg) + raise DNSZoneAlreadyExists(zone=zone.to_text(), ns=ns) def _mix_weight(records): diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py index 80be9ff93..fe04f763e 100644 --- a/ipaserver/install/bindinstance.py +++ b/ipaserver/install/bindinstance.py @@ -327,7 +327,7 @@ def read_reverse_zone(default, ip_address, allow_zone_overlap=False): if not allow_zone_overlap: try: dnsutil.check_zone_overlap(zone, raise_on_error=False) - except ValueError as e: + except dnsutil.DNSZoneAlreadyExists as e: logger.error("Reverse zone %s will not be used: %s", zone, e) continue diff --git a/ipaserver/install/dns.py b/ipaserver/install/dns.py index 40688dc27..36ba6f899 100644 --- a/ipaserver/install/dns.py +++ b/ipaserver/install/dns.py @@ -130,13 +130,15 @@ def install_check(standalone, api, replica, options, hostname): domain = dnsutil.DNSName(util.normalize_zone(api.env.domain)) try: dnsutil.check_zone_overlap(domain, raise_on_error=False) - except ValueError as e: + except dnsutil.DNSZoneAlreadyExists as e: if options.force or options.allow_zone_overlap: logger.warning("%s Please make sure that the domain is " "properly delegated to this IPA server.", e) - else: - raise e + + hst = dnsutil.DNSName(hostname).make_absolute().to_text() + if hst not in e.kwargs['ns']: + raise ValueError(str(e)) for reverse_zone in options.reverse_zones: try: diff --git a/ipaserver/install/server/__init__.py b/ipaserver/install/server/__init__.py index d9adf76f3..21396e1ac 100644 --- a/ipaserver/install/server/__init__.py +++ b/ipaserver/install/server/__init__.py @@ -10,6 +10,7 @@ import random from ipaclient.install import client from ipalib import constants +from ipalib.util import validate_domain_name from ipalib.install import service from ipalib.install.service import (enroll_only, installs_master, @@ -17,7 +18,6 @@ from ipalib.install.service import (enroll_only, master_install_only, prepare_only, replica_install_only) -from ipapython.dnsutil import check_zone_overlap from ipapython.install import typing from ipapython.install.core import group, knob, extend_knob from ipapython.install.common import step @@ -524,10 +524,13 @@ class ServerMasterInstall(ServerMasterInstallInterface): @domain_name.validator def domain_name(self, value): - if (self.setup_dns and - not self.allow_zone_overlap): - print("Checking DNS domain %s, please wait ..." % value) - check_zone_overlap(value, False) + # There might be an overlap but at this point we don't have + # complete installer object to verify that DNS is hosted + # by the same machine (i.e. we are already installed). + # Later, DNS.install_check will do its zone overlap check + # and will make sure to fail if overlap does really exist. + # At this point we only verify that value is a valid DNS syntax. + validate_domain_name(value) dm_password = extend_knob( ServerMasterInstallInterface.dm_password, diff --git a/ipaserver/plugins/dns.py b/ipaserver/plugins/dns.py index c3c096971..014f208b5 100644 --- a/ipaserver/plugins/dns.py +++ b/ipaserver/plugins/dns.py @@ -79,7 +79,7 @@ from ipalib.util import (normalize_zonemgr, from ipaplatform import services from ipapython.dn import DN from ipapython.ipautil import CheckedIPAddress -from ipapython.dnsutil import check_zone_overlap +from ipapython.dnsutil import check_zone_overlap, DNSZoneAlreadyExists from ipapython.dnsutil import DNSName from ipapython.dnsutil import related_to_auto_empty_zone from ipaserver.dns_data_management import ( @@ -2153,7 +2153,7 @@ class DNSZoneBase_add(LDAPCreate): if not options['skip_overlap_check']: try: check_zone_overlap(keys[-1], raise_on_error=False) - except ValueError as e: + except DNSZoneAlreadyExists as e: raise errors.InvocationError(str(e)) return dn