From 85bc681683a8a5d71b9cfaf9c70e0f388732f285 Mon Sep 17 00:00:00 2001
From: Justin Stephenson <jstephen@redhat.com>
Date: Wed, 27 Dec 2017 16:32:47 -0500
Subject: [PATCH] Skip zone overlap check with auto-reverse
Skip the existing reverse zone overlap check during DNS installation
when both --auto-reverse and --allow-zone-overlap arguments are
provided.
https://pagure.io/freeipa/issue/7239
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Christian Heimes <cheimes@redhat.com>
---
ipaserver/install/bindinstance.py | 18 ++--
.../test_integration/test_installation.py | 95 +++++++++++++++++++
2 files changed, 105 insertions(+), 8 deletions(-)
diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py
index 940667db9c40559d5369188395bb18f2d1eac025..4de2c6442175a64f4048a93b2006a6d5c6b2a045 100644
--- a/ipaserver/install/bindinstance.py
+++ b/ipaserver/install/bindinstance.py
@@ -304,7 +304,7 @@ def read_reverse_zone(default, ip_address, allow_zone_overlap=False):
return normalize_zone(zone)
-def get_auto_reverse_zones(ip_addresses):
+def get_auto_reverse_zones(ip_addresses, allow_zone_overlap=False):
auto_zones = []
for ip in ip_addresses:
if ipautil.reverse_record_exists(ip):
@@ -312,12 +312,13 @@ def get_auto_reverse_zones(ip_addresses):
logger.info("Reverse record for IP address %s already exists", ip)
continue
default_reverse = get_reverse_zone_default(ip)
- try:
- dnsutil.check_zone_overlap(default_reverse)
- except ValueError:
- logger.info("Reverse zone %s for IP address %s already exists",
- default_reverse, ip)
- continue
+ if not allow_zone_overlap:
+ try:
+ dnsutil.check_zone_overlap(default_reverse)
+ except ValueError:
+ logger.info("Reverse zone %s for IP address %s already exists",
+ default_reverse, ip)
+ continue
auto_zones.append((ip, default_reverse))
return auto_zones
@@ -488,7 +489,8 @@ def check_reverse_zones(ip_addresses, reverse_zones, options, unattended,
ips_missing_reverse.append(ip)
# create reverse zone for IP addresses that does not have one
- for (ip, rz) in get_auto_reverse_zones(ips_missing_reverse):
+ for (ip, rz) in get_auto_reverse_zones(ips_missing_reverse,
+ options.allow_zone_overlap):
if options.auto_reverse:
logger.info("Reverse zone %s will be created", rz)
checked_reverse_zones.append(rz)
diff --git a/ipatests/test_integration/test_installation.py b/ipatests/test_integration/test_installation.py
index 4cd8a3e33927b7522e9b2a8908a8c179daaa1280..7e6c728102e29753ec7b56cedea734dd18b8bb8c 100644
--- a/ipatests/test_integration/test_installation.py
+++ b/ipatests/test_integration/test_installation.py
@@ -9,6 +9,7 @@ installed.
from __future__ import absolute_import
+import os
import pytest
from ipalib.constants import DOMAIN_LEVEL_0
from ipaplatform.constants import constants
@@ -16,9 +17,46 @@ from ipaplatform.paths import paths
from ipatests.pytest_ipa.integration.env_config import get_global_config
from ipatests.test_integration.base import IntegrationTest
from ipatests.pytest_ipa.integration import tasks
+from ipatests.test_integration.test_caless import CALessBase, ipa_certs_cleanup
config = get_global_config()
+
+def create_broken_resolv_conf(master):
+ # Force a broken resolv.conf to simulate a bad response to
+ # reverse zone lookups
+ master.run_command([
+ '/usr/bin/mv',
+ paths.RESOLV_CONF,
+ '%s.sav' % paths.RESOLV_CONF
+ ])
+
+ contents = "# Set as broken by ipatests\nnameserver 127.0.0.2\n"
+ master.put_file_contents(paths.RESOLV_CONF, contents)
+
+
+def restore_resolv_conf(master):
+ if os.path.exists('%s.sav' % paths.RESOLV_CONF):
+ master.run_command([
+ '/usr/bin/mv',
+ '%s.sav' % paths.RESOLV_CONF,
+ paths.RESOLV_CONF
+ ])
+
+
+def server_install_setup(func):
+ def wrapped(*args):
+ master = args[0].master
+ create_broken_resolv_conf(master)
+ try:
+ func(*args)
+ finally:
+ tasks.uninstall_master(master, clean=False)
+ restore_resolv_conf(master)
+ ipa_certs_cleanup(master)
+ return wrapped
+
+
class InstallTestBase1(IntegrationTest):
num_replicas = 3
@@ -226,6 +264,63 @@ class TestInstallWithCA_DNS2(InstallTestBase2):
super(TestInstallWithCA_DNS2, self).test_replica2_ipa_kra_install()
+class TestInstallWithCA_DNS3(CALessBase):
+ """
+ Test an install with a bad DNS resolver configured to force a
+ timeout trying to verify the existing zones. In the case of a reverse
+ zone it is skipped unless --allow-zone-overlap is set regardless of
+ the value of --auto-reverse. Confirm that --allow-zone-overlap
+ lets the reverse zone be created.
+
+ ticket 7239
+ """
+
+ @server_install_setup
+ def test_number_of_zones(self):
+ """There should be two zones: one forward, one reverse"""
+
+ self.create_pkcs12('ca1/server')
+ self.prepare_cacert('ca1')
+
+ self.install_server(extra_args=['--allow-zone-overlap'])
+
+ result = self.master.run_command([
+ 'ipa', 'dnszone-find'])
+
+ assert "in-addr.arpa." in result.stdout_text
+
+ assert "returned 2" in result.stdout_text
+
+
+class TestInstallWithCA_DNS4(CALessBase):
+ """
+ Test an install with a bad DNS resolver configured to force a
+ timeout trying to verify the existing zones. In the case of a reverse
+ zone it is skipped unless --allow-zone-overlap is set regardless of
+ the value of --auto-reverse. Confirm that without --allow-reverse-zone
+ only the forward zone is created.
+
+ ticket 7239
+ """
+
+ @server_install_setup
+ def test_number_of_zones(self):
+ """There should be one zone, a forward because rev timed-out"""
+
+ self.create_pkcs12('ca1/server')
+ self.prepare_cacert('ca1')
+
+ # no zone overlap by default
+ self.install_server()
+
+ result = self.master.run_command([
+ 'ipa', 'dnszone-find'])
+
+ assert "in-addr.arpa." not in result.stdout_text
+
+ assert "returned 1" in result.stdout_text
+
+
@pytest.mark.cs_acceptance
class TestInstallWithCA_KRA_DNS1(InstallTestBase1):
--
2.20.1