On 09/09/15 13:39, Petr Spacek wrote:
On 8.9.2015 16:30, David Kupka wrote:
On 28/08/15 13:36, Martin Basti wrote:


On 08/28/2015 10:03 AM, Petr Spacek wrote:
On 27.8.2015 14:22, David Kupka wrote:
@@ -2101,11 +2101,25 @@ class DNSZoneBase(LDAPObject):
   class DNSZoneBase_add(LDAPCreate):
+    takes_options = LDAPCreate.takes_options + (
+        Flag('force',
+             label=_('Force'),
+             doc=_('Force DNS zone creation.')
+        ),
+        Flag('skip_overlap_check',
+             doc=_('Force DNS zone creation even if it will overlap
with '
+                   'existing zone.')
+        ),
+    )
+
       has_output_params = LDAPCreate.has_output_params +
dnszone_output_params
       def pre_callback(self, ldap, dn, entry_attrs, attrs_list,
*keys, **options):
           assert isinstance(dn, DN)
+        if options['force']:
+            options['skip_overlap_check'] = True
+
           try:
               entry = ldap.get_entry(dn)
           except errors.NotFound:
@@ -2120,6 +2134,12 @@ class DNSZoneBase_add(LDAPCreate):
           entry_attrs['idnszoneactive'] = 'TRUE'
+        if not options['skip_overlap_check']:
+            try:
+                check_zone_overlap(keys[-1])
+            except RuntimeError as e:
+                raise errors.InvocationError(e.message)
+
           return dn
@@ -2673,9 +2693,9 @@ class dnszone_add(DNSZoneBase_add):
       __doc__ = _('Create new DNS zone (SOA record).')
       takes_options = DNSZoneBase_add.takes_options + (
-        Flag('force',
-             label=_('Force'),
-             doc=_('Force DNS zone creation even if nameserver is
not resolvable.'),
+        Flag('skip_nameserver_check',
+             doc=_('Force DNS zone creation even if nameserver is not '
+                   'resolvable.')
           ),
           # Deprecated
@@ -2699,6 +2719,9 @@ class dnszone_add(DNSZoneBase_add):
       def pre_callback(self, ldap, dn, entry_attrs, attrs_list,
*keys, **options):
           assert isinstance(dn, DN)
+        if options['force']:
+            options['skip_nameserver_check'] = True
Why is it in DNSZoneBase_add.pre_callback?

Shouldn't the equation force = (skip_nameserver_check +
skip_nameserver_check)
be handled in parameter parsing & validation? (Again, I do not know
the IPA
framework :-))

+
           dn = super(dnszone_add, self).pre_callback(
               ldap, dn, entry_attrs, attrs_list, *keys, **options)
@@ -2713,7 +2736,7 @@ class dnszone_add(DNSZoneBase_add):
                       error=_("Nameserver for reverse zone cannot be
a relative DNS name"))
               # verify if user specified server is resolvable
-            if not options['force']:
+            if not options['skip_nameserver_check']:
                   check_ns_rec_resolvable(keys[0],
entry_attrs['idnssoamname'])
               # show warning about --name-server option
               context.show_warning_nameserver_option = True
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index
d959bb369d946217acd080e78483cc9013dda4c7..18f477d4fb6620090b7073689c8df51b65a8307a

100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -924,6 +924,20 @@ def host_exists(host):
       else:
           return True
+def check_zone_overlap(zone):
+    if resolver.zone_for_name(zone) == zone:
+        try:
+            ns = [ans.to_text() for ans in resolver.query(zone, 'NS')]
+        except DNSException as e:
+            root_logger.debug("Failed to resolve nameserver(s) for
domain"
+                " {0}: {1}".format(zone, e))
+            ns = []
+
+        msg = u"DNS zone {0} already exists".format(zone)
Nitpick: I would say "already exists in DNS" to make it absolutely
clear. Just
'already exists' might be confusing because ipa dnszone-show will say
that the
zone does not exist ...

+        if ns:
+            msg += u" and is handled by server(s): {0}".format(',
'.join(ns))
+        raise RuntimeError(msg)
+
   def get_ipa_basedn(conn):
       """
       Get base DN of IPA suffix in given LDAP server.
0064
NACK

ipa-replica-install should have the --skip-overlap-check too, because
any replica can be the first DNS server.

Thanks for the catch, added.


0064+0058
Can be the options --allow-zone-overlap and --skip-overlap-check merged
into an one name, to have just one name for same thing?


Each option has bit different behavior:
The '--skip-overlap-check' option in API call prevent the check to be
performed and thus no error or warning is raised. This is the way '--force'
option was originally working.

The '--allow-zone-overlap' options in installers do not skip the check but
change the error to warning instead and let the installation continue.

If you think that this can confuse users we need to change the names  or even
the logic.

Updated patches attached.

Hello,

thank you very much for updating the patch.

Unfortunately it is not yet ready, but we are getting there.


* Serious problems:

a) ipa-server/replica/dns-install by default creates reverse zones even if
these zones exist. The check which is done for main IPA domain should be done
for all reverse zones, too. If a zone exists user should use --no-reverse or
--allow-zone-overlap if necessary.

I believe that this is in scope of https://fedorahosted.org/freeipa/ticket/3681 
.


b) ipa-server/replica/dns-install by default always add DNS zone which
contains hostname of the IPA server, even if the IPA domain is different and
even if the DNS zone already exists.

If the hostname of the server does not belong to IPA domain we should not add
anything. Just check that the hostname is resolvable. Theoretically we could
add an option which explicitly asks for creating zone which encloses the
hostnmame.

I believe that this is in scope of https://fedorahosted.org/freeipa/ticket/5087 
.


c) I did not realize that checks in ipa dns*zone-add will break zone addition
for automatic empty zones.

There is list of special-case DNS zones which need special handling:
https://source.isc.org/cgi-bin/gitweb.cgi?p=bind9.git;a=blob;f=bin/named/server.c;h=1a25531df354f6f0593bfb86e5aa3e3c9b9c80e5;hb=HEAD#l272

Feel free to copy&paste list of the domains to IPA code - list comes from
RFCs, so it should be pretty stable. It would be good

If one of these zones is detected as "already existing" we need to further
check values in SOA record and automatically override the check if:
(SOA mname = zone name) & (SOA rname = .)

In that case we should print informational message "automatic empty zone will
be overridden by the zone you defined now".


d) ipa-server/replica/dns-install fails when attempt to resolve main IPA
domain name fails with DNS timeout. This might easily happen if the domain
name is already delegated to IPA server which is being installed. In that case
we should print a warning and allow to continue.

"""
Warning: DNS check for domain <IPA domain> failed with error <exception>.
Please make sure that the domain is properly delegated to this IPA server.
"""


* Nitpicks - can be handled in separate patches:
1) Interactive ipa-server-install tells the user that the zone name he entered
exists too late in the process.

I.e. user has to enter DM and admin password (twice!) and only after that he
will receive an error, which may be frustrating :-)

Please move the check right after DNS zone name input so user does not waste
his time and nerves :-) Even better, in an interactive mode it could make
sense to ask the user again if the previous input was not acceptable.


2) I found out that ipa-server-install prints message "Warning: skipping DNS
resolution of host vm-206.abc.idm.lab.eng.brq.redhat.com" even if the host
name does not belong to IPA domain. That is a mistake - the check should be
skipped only in case when IPA server is part of the IPA domain.


3) When adding an forward as an override for automatic empty zones we should
throw a warning if forward policy is not 'only'. It does not make sense to use
policy 'forward' in these cases.
"""
Warning: It is strongly recommended to use forward policy 'only' for the
forward zones defined for private use.
"""


Hi!
I was finally able to get back to this patches. I've (hopefully) addressed all the items from "Serious problems" section plus the first "nitpick" as I found it really annoying. Updated patches attached. Patch freeipa-dkupka-0070 is needed for this to work.


--
David Kupka
From e50170d9a51a78c065f681f77069ee0beec75e65 Mon Sep 17 00:00:00 2001
From: David Kupka <dku...@redhat.com>
Date: Wed, 2 Dec 2015 13:17:13 +0000
Subject: [PATCH] dns: do not add (forward)zone if it is already resolvable.

Check if the zone user wants to add is already resolvable and refuse to
create it if yes. --skip-overlap-check and --force options suppress this check.

https://fedorahosted.org/freeipa/ticket/5087
---
 API.txt               |  7 +++--
 ipalib/plugins/dns.py | 33 ++++++++++++++++---
 ipapython/ipautil.py  | 87 +++++++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 118 insertions(+), 9 deletions(-)

diff --git a/API.txt b/API.txt
index 60c98c31aa85d6c8879cd145f3d84188d4fea5b7..3a9fb65a386a2a6529b8cd241642446c135471f2 100644
--- a/API.txt
+++ b/API.txt
@@ -959,7 +959,7 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: PrimaryKey('value', None, None)
 command: dnsforwardzone_add
-args: 1,8,3
+args: 1,9,3
 arg: DNSNameParam('idnsname', attribute=True, cli_name='name', multivalue=False, only_absolute=True, primary_key=True, required=True)
 option: Str('addattr*', cli_name='addattr', exclude='webui')
 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
@@ -968,6 +968,7 @@ option: StrEnum('idnsforwardpolicy', attribute=True, cli_name='forward_policy',
 option: Str('name_from_ip', attribute=False, cli_name='name_from_ip', multivalue=False, required=False)
 option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
 option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Flag('skip_overlap_check', autofill=True, default=False)
 option: Str('version?', exclude='webui')
 output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
@@ -1366,7 +1367,7 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: PrimaryKey('value', None, None)
 command: dnszone_add
-args: 1,26,3
+args: 1,28,3
 arg: DNSNameParam('idnsname', attribute=True, cli_name='name', multivalue=False, only_absolute=True, primary_key=True, required=True)
 option: Str('addattr*', cli_name='addattr', exclude='webui')
 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
@@ -1393,6 +1394,8 @@ option: Str('name_from_ip', attribute=False, cli_name='name_from_ip', multivalue
 option: Str('nsec3paramrecord', attribute=True, cli_name='nsec3param_rec', multivalue=False, pattern='^\\d+ \\d+ \\d+ (([0-9a-fA-F]{2})+|-)$', required=False)
 option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
 option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Flag('skip_nameserver_check', autofill=True, default=False)
+option: Flag('skip_overlap_check', autofill=True, default=False)
 option: Str('version?', exclude='webui')
 output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
diff --git a/ipalib/plugins/dns.py b/ipalib/plugins/dns.py
index 67947360eb207de31ed114bb630705c409b2f9a9..c3d157d6951b1be84811012003bf29bb858949fa 100644
--- a/ipalib/plugins/dns.py
+++ b/ipalib/plugins/dns.py
@@ -53,8 +53,8 @@ from ipalib.util import (normalize_zonemgr,
                          validate_dnssec_zone_forwarder_step1,
                          validate_dnssec_zone_forwarder_step2,
                          verify_host_resolvable)
-
-from ipapython.ipautil import CheckedIPAddress
+from ipapython.ipautil import (CheckedIPAddress, is_host_resolvable,
+                               check_zone_overlap)
 from ipapython.dnsutil import DNSName
 
 if six.PY3:
@@ -2121,6 +2121,13 @@ class DNSZoneBase(LDAPObject):
 
 class DNSZoneBase_add(LDAPCreate):
 
+    takes_options = LDAPCreate.takes_options + (
+        Flag('skip_overlap_check',
+             doc=_('Force DNS zone creation even if it will overlap with '
+                   'an existing zone.')
+        ),
+    )
+
     has_output_params = LDAPCreate.has_output_params + dnszone_output_params
 
     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
@@ -2140,6 +2147,12 @@ class DNSZoneBase_add(LDAPCreate):
 
         entry_attrs['idnszoneactive'] = 'TRUE'
 
+        if not options['skip_overlap_check']:
+            try:
+                check_zone_overlap(keys[-1])
+            except ValueError as e:
+                raise errors.InvocationError(e.message)
+
         return dn
 
 
@@ -2696,8 +2709,13 @@ class dnszone_add(DNSZoneBase_add):
 
     takes_options = DNSZoneBase_add.takes_options + (
         Flag('force',
-             label=_('Force'),
-             doc=_('Force DNS zone creation even if nameserver is not resolvable.'),
+            doc=_('Force DNS zone creation even if nameserver is not '
+                  'resolvable. (Deprecated)'),
+        ),
+
+        Flag('skip_nameserver_check',
+            doc=_('Force DNS zone creation even if nameserver is not '
+                  'resolvable.'),
         ),
 
         # Deprecated
@@ -2721,6 +2739,11 @@ class dnszone_add(DNSZoneBase_add):
     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
         assert isinstance(dn, DN)
 
+        if options.get('force'):
+            if options.get('skip_nameserver_check'):
+                ("'force' is deprecated.")
+            options['skip_nameserver_check'] = True
+
         dn = super(dnszone_add, self).pre_callback(
             ldap, dn, entry_attrs, attrs_list, *keys, **options)
 
@@ -2736,7 +2759,7 @@ class dnszone_add(DNSZoneBase_add):
                     error=_("Nameserver for reverse zone cannot be a relative DNS name"))
 
             # verify if user specified server is resolvable
-            if not options['force']:
+            if not options['skip_nameserver_check']:
                 check_ns_rec_resolvable(keys[0], entry_attrs['idnssoamname'],
                                         self.log)
             # show warning about --name-server option
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index 89047b2e8ea16d14a6634e551c49abe240c54009..3ce61e31872ad69ca6ec366b67799b4adca8a63b 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -39,7 +39,7 @@ import grp
 from contextlib import contextmanager
 
 from dns import resolver, rdatatype
-from dns.exception import DNSException
+from dns.exception import DNSException, Timeout
 import six
 from six.moves import input
 from six.moves import urllib
@@ -50,6 +50,7 @@ from ipapython import config
 from ipaplatform.paths import paths
 from ipapython.dn import DN
 from ipapython.dnsutil import DNSName
+from ipalib.util import normalize_zone
 
 SHARE_DIR = paths.USR_SHARE_IPA_DIR
 PLUGINS_SHARE_DIR = paths.IPA_PLUGINS
@@ -240,7 +241,6 @@ def template_file(infilename, vars):
     with open(infilename) as f:
         return template_str(f.read(), vars)
 
-
 def copy_template_file(infilename, outfilename, vars):
     """Copy a file, performing template substitutions"""
     txt = template_file(infilename, vars)
@@ -925,6 +925,89 @@ def host_exists(host):
     else:
         return True
 
+def check_zone_overlap(zone, raise_on_timeout=True):
+    if not isinstance(zone, DNSName):
+        zone = DNSName(normalize_zone(zone))
+
+    try:
+        containing_zone = resolver.zone_for_name(zone)
+    except Timeout as e:
+        msg = ("DNS check for domain %s failed: %s. Please make sure that the "
+               "domain is properly delegated to this IPA server." % (zone, e))
+        if raise_on_timeout:
+            raise ValueError(msg)
+        else:
+            root_logger.warning(msg)
+            return
+
+    if containing_zone == zone:
+        try:
+            ns = [ans.to_text() for ans in resolver.query(zone, 'NS')]
+        except DNSException as e:
+            root_logger.debug("Failed to resolve nameserver(s) for domain"
+                " {0}: {1}".format(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)
+
+def check_reverse_zone_overlap(zone, raise_on_timeout=True):
+    automatic_empty_zones = [
+        # RFC 1918
+        "10.IN-ADDR.ARPA", "16.172.IN-ADDR.ARPA", "17.172.IN-ADDR.ARPA",
+        "18.172.IN-ADDR.ARPA", "19.172.IN-ADDR.ARPA", "20.172.IN-ADDR.ARPA",
+        "21.172.IN-ADDR.ARPA", "22.172.IN-ADDR.ARPA", "23.172.IN-ADDR.ARPA",
+        "24.172.IN-ADDR.ARPA", "25.172.IN-ADDR.ARPA", "26.172.IN-ADDR.ARPA",
+        "27.172.IN-ADDR.ARPA", "28.172.IN-ADDR.ARPA", "29.172.IN-ADDR.ARPA",
+        "30.172.IN-ADDR.ARPA", "31.172.IN-ADDR.ARPA", "168.192.IN-ADDR.ARPA",
+        # RFC 6598
+        "64.100.IN-ADDR.ARPA", "65.100.IN-ADDR.ARPA", "66.100.IN-ADDR.ARPA",
+        "67.100.IN-ADDR.ARPA", "68.100.IN-ADDR.ARPA", "69.100.IN-ADDR.ARPA",
+        "70.100.IN-ADDR.ARPA", "71.100.IN-ADDR.ARPA", "72.100.IN-ADDR.ARPA",
+        "73.100.IN-ADDR.ARPA", "74.100.IN-ADDR.ARPA", "75.100.IN-ADDR.ARPA",
+        "76.100.IN-ADDR.ARPA", "77.100.IN-ADDR.ARPA", "78.100.IN-ADDR.ARPA",
+        "79.100.IN-ADDR.ARPA", "80.100.IN-ADDR.ARPA", "81.100.IN-ADDR.ARPA",
+        "82.100.IN-ADDR.ARPA", "83.100.IN-ADDR.ARPA", "84.100.IN-ADDR.ARPA",
+        "85.100.IN-ADDR.ARPA", "86.100.IN-ADDR.ARPA", "87.100.IN-ADDR.ARPA",
+        "88.100.IN-ADDR.ARPA", "89.100.IN-ADDR.ARPA", "90.100.IN-ADDR.ARPA",
+        "91.100.IN-ADDR.ARPA", "92.100.IN-ADDR.ARPA", "93.100.IN-ADDR.ARPA",
+        "94.100.IN-ADDR.ARPA", "95.100.IN-ADDR.ARPA", "96.100.IN-ADDR.ARPA",
+        "97.100.IN-ADDR.ARPA", "98.100.IN-ADDR.ARPA", "99.100.IN-ADDR.ARPA",
+        "100.100.IN-ADDR.ARPA", "101.100.IN-ADDR.ARPA",
+        "102.100.IN-ADDR.ARPA", "103.100.IN-ADDR.ARPA",
+        "104.100.IN-ADDR.ARPA", "105.100.IN-ADDR.ARPA",
+        "106.100.IN-ADDR.ARPA", "107.100.IN-ADDR.ARPA",
+        "108.100.IN-ADDR.ARPA", "109.100.IN-ADDR.ARPA",
+        "110.100.IN-ADDR.ARPA", "111.100.IN-ADDR.ARPA",
+        "112.100.IN-ADDR.ARPA", "113.100.IN-ADDR.ARPA",
+        "114.100.IN-ADDR.ARPA", "115.100.IN-ADDR.ARPA",
+        "116.100.IN-ADDR.ARPA", "117.100.IN-ADDR.ARPA",
+        "118.100.IN-ADDR.ARPA", "119.100.IN-ADDR.ARPA",
+        "120.100.IN-ADDR.ARPA", "121.100.IN-ADDR.ARPA",
+        "122.100.IN-ADDR.ARPA", "123.100.IN-ADDR.ARPA",
+        "124.100.IN-ADDR.ARPA", "125.100.IN-ADDR.ARPA",
+        "126.100.IN-ADDR.ARPA", "127.100.IN-ADDR.ARPA",
+        # RFC 5735 and RFC 5737
+        "0.IN-ADDR.ARPA", "127.IN-ADDR.ARPA", "254.169.IN-ADDR.ARPA",
+        "2.0.192.IN-ADDR.ARPA", "100.51.198.IN-ADDR.ARPA",
+        "113.0.203.IN-ADDR.ARPA", "255.255.255.255.IN-ADDR.ARPA",
+        # Local IPv6 Unicast Addresses
+        "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA",
+        "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA",
+        # LOCALLY ASSIGNED LOCAL ADDRESS SCOPE
+        "D.F.IP6.ARPA", "8.E.F.IP6.ARPA", "9.E.F.IP6.ARPA", "A.E.F.IP6.ARPA",
+        "B.E.F.IP6.ARPA",
+        # Example Prefix, RFC 3849.
+        "8.B.D.0.1.0.0.2.IP6.ARPA",
+        # RFC 7534
+        "EMPTY.AS112.ARPA",
+    ]
+    if zone in automatic_empty_zones:
+        return
+    check_zone_overlap(zone, raise_on_timeout=raise_on_timeout)
+
 def get_ipa_basedn(conn):
     """
     Get base DN of IPA suffix in given LDAP server.
-- 
2.5.0

From 5467325d2b5c0b20b60644f6712e2402b174417f Mon Sep 17 00:00:00 2001
From: David Kupka <dku...@redhat.com>
Date: Fri, 21 Aug 2015 13:25:34 +0200
Subject: [PATCH 2/2] dns: Check if domain already exists.

Raise an error when the domain already exists. This can be overriden using
--force or --allow-zone-overlap options.

https://fedorahosted.org/freeipa/ticket/3681
---
 install/tools/ipa-dns-install       |  3 +++
 ipaserver/install/dns.py            | 13 +++++++++++++
 ipaserver/install/server/install.py |  6 ++++++
 3 files changed, 22 insertions(+)

diff --git a/install/tools/ipa-dns-install b/install/tools/ipa-dns-install
index 34b952859e56c6aa5ae861a4d1fb615f0a2d8f55..11767f106dfc47721aa038977fcc4357c83c94c3 100755
--- a/install/tools/ipa-dns-install
+++ b/install/tools/ipa-dns-install
@@ -70,6 +70,9 @@ def parse_options():
                       "kasp.db file)")
     parser.add_option("--force", dest="force", action="store_true",
                       help="Force install")
+    parser.add_option("--allow-zone-overlap", dest="allow_zone_overlap",
+                      action="store_true", default=False, help="Create DNS "
+                      "zone even if it already exists")
 
     options, args = parser.parse_args()
     safe_options = parser.get_safe_opts(options)
diff --git a/ipaserver/install/dns.py b/ipaserver/install/dns.py
index 9430d189978b0984b0b71d7d754516a4135053fb..2d3874f282d6dd306a75b1aec039ca1e8377f675 100644
--- a/ipaserver/install/dns.py
+++ b/ipaserver/install/dns.py
@@ -8,11 +8,13 @@ from subprocess import CalledProcessError
 
 from ipalib import api
 from ipalib import errors
+from ipalib import util
 from ipaplatform.paths import paths
 from ipaplatform.constants import constants
 from ipaplatform import services
 from ipapython import ipautil
 from ipapython import sysrestore
+from ipapython import dnsutil
 from ipapython.dn import DN
 from ipapython.ipa_log_manager import root_logger
 from ipapython.ipaldap import AUTOBIND_ENABLED
@@ -101,6 +103,17 @@ def install_check(standalone, replica, options, hostname):
         raise RuntimeError("Integrated DNS requires '%s' package" %
                            constants.IPA_DNS_PACKAGE_NAME)
 
+    domain = dnsutil.DNSName(util.normalize_zone(api.env.domain))
+    try:
+        ipautil.check_zone_overlap(domain)
+    except RuntimeError as e:
+        msg = e.message + u" Either use different domain or delete" \
+            " its record(s) on name server(s)."
+        if options.force or options.allow_zone_overlap:
+            root_logger.warning(msg)
+        else:
+            raise RuntimeError(msg)
+
     if standalone:
         print "=============================================================================="
         print "This program will setup DNS for the FreeIPA Server."
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
index 967538334b63f95e8b0b05cef7569b1c6d7dea9e..f473a0f112e94ecd6b77adc9bb3df3a67f54e3ac 100644
--- a/ipaserver/install/server/install.py
+++ b/ipaserver/install/server/install.py
@@ -1345,6 +1345,11 @@ class ServerDNS(common.Installable, core.Group, core.Composite):
         description="Do not automatically create DNS SSHFP records",
     )
 
+    allow_zone_overlap = Knob(
+        bool, False,
+        description="Create DNS zone even if it already exists",
+    )
+
 
 class Server(common.Installable, common.Interactive, core.Composite):
     realm_name = Knob(
@@ -1611,6 +1616,7 @@ class Server(common.Installable, common.Interactive, core.Composite):
         self.zonemgr = self.dns.zonemgr
         self.no_host_dns = self.dns.no_host_dns
         self.no_dns_sshfp = self.dns.no_dns_sshfp
+        self.allow_zone_overlap = self.dns.allow_zone_overlap
 
         self.unattended = not self.interactive
 
-- 
2.4.3

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to