- Resolves: RHEL-155027 Adding a group with 32Bit Idrange fails - Resolves: RHEL-153145 IdM password policy Min lifetime is not enforced when high minlife is set - Resolves: RHEL-166864 Include latest fixes in python3-ipatests package Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
1124 lines
41 KiB
Diff
1124 lines
41 KiB
Diff
From 69f9978dc8bfe33b0f02cfb62a7d9d6a6051657c Mon Sep 17 00:00:00 2001
|
|
From: PRANAV THUBE <pthube@redhat.com>
|
|
Date: Thu, 12 Feb 2026 10:54:17 +0530
|
|
Subject: [PATCH] ipatests: Add DNS integration tests.
|
|
|
|
Tests cover LDAP connection handling, PTR synchronization,
|
|
update policies, record validation, and zone management fixes.
|
|
|
|
Fixes: https://pagure.io/freeipa/issue/9911
|
|
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
|
Reviewed-By: David Hanina <dhanina@redhat.com>
|
|
Reviewed-By: Sudhir Menon <sumenon@redhat.com>
|
|
---
|
|
ipatests/test_integration/test_dns.py | 1078 ++++++++++++++++++++++++-
|
|
1 file changed, 1076 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/ipatests/test_integration/test_dns.py b/ipatests/test_integration/test_dns.py
|
|
index 6840a10d1a301a8f19cfdf95896e08be7cfd7ea2..4b9ab1fe8d7b8884760ed637cb2fcc5d5a060df0 100644
|
|
--- a/ipatests/test_integration/test_dns.py
|
|
+++ b/ipatests/test_integration/test_dns.py
|
|
@@ -6,12 +6,11 @@
|
|
from __future__ import absolute_import
|
|
|
|
import time
|
|
-
|
|
import dns.exception
|
|
import dns.resolver
|
|
from ipapython.dn import DN
|
|
from ipapython.dnsutil import DNSResolver
|
|
-from ipatests.pytest_ipa.integration import tasks
|
|
+from ipatests.pytest_ipa.integration import tasks, skip_if_fips
|
|
from ipatests.test_integration.base import IntegrationTest
|
|
|
|
# =============================================================================
|
|
@@ -71,6 +70,35 @@ PTR_TTL = 59
|
|
NEW_TXT = "newip=5.6.7.8"
|
|
NEWER_TXT = "newip=8.7.6.5"
|
|
|
|
+# TSIG key configuration for dynamic DNS updates (hmac-md5)
|
|
+KEY_NAME = "selfupdate"
|
|
+KEY_SECRET = "05Fu1ACKv1/1Ag=="
|
|
+KEY_CONFIG = f'''key {KEY_NAME} {{
|
|
+ algorithm hmac-md5;
|
|
+ secret "{KEY_SECRET}";
|
|
+}};
|
|
+'''
|
|
+
|
|
+# nsupdate template for deleting A record
|
|
+NSUPDATE_DELETE_A_TEMPLATE = """debug
|
|
+update delete {hostname} IN A {ip}
|
|
+send
|
|
+"""
|
|
+
|
|
+# nsupdate template for adding AAAA record
|
|
+NSUPDATE_ADD_AAAA_TEMPLATE = """debug
|
|
+update add {hostname} {ttl} IN AAAA {ip}
|
|
+send
|
|
+"""
|
|
+
|
|
+# nsupdate template for adding A record with TSIG key
|
|
+NSUPDATE_ADD_A_WITH_KEY_TEMPLATE = """server {server}
|
|
+zone {zone}
|
|
+key {key_name} {key_secret}
|
|
+update add {hostname} {ttl} IN A {ip}
|
|
+send
|
|
+"""
|
|
+
|
|
|
|
class TestDNS(IntegrationTest):
|
|
"""Tests for DNS feature.
|
|
@@ -1793,3 +1821,1049 @@ class TestDNSMisc(IntegrationTest):
|
|
self.master.run_command([
|
|
'/sbin/ip', '-6', 'addr', 'del', temp_ipv6, 'dev', eth
|
|
], raiseonerr=False)
|
|
+
|
|
+ @skip_if_fips(reason='hmac-md5 not supported in FIPS mode')
|
|
+ def test_updatepolicy_zonesub(self):
|
|
+ """Test BIND with bind-dyndb-ldap works with zonesub updatepolicy.
|
|
+
|
|
+ Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=921167
|
|
+
|
|
+ This test verifies that dynamic DNS updates work correctly when
|
|
+ using the 'zonesub' match type in the update policy. Note that
|
|
+ this test requires hmac-md5 which is not supported in FIPS mode.
|
|
+ """
|
|
+ tasks.kinit_admin(self.master)
|
|
+ domain = self.master.domain.name
|
|
+ realm = self.master.domain.realm
|
|
+
|
|
+ # Get IP address components for test record
|
|
+ ip_parts = self.master.ip.split('.')
|
|
+ test_ip = f'{ip_parts[0]}.{ip_parts[1]}.{ip_parts[2]}.100'
|
|
+
|
|
+ # Backup named.conf
|
|
+ self.master.run_command([
|
|
+ 'cp', '/etc/named.conf', '/etc/named.conf.bak'
|
|
+ ])
|
|
+
|
|
+ try:
|
|
+ # Add key to named.conf for dynamic updates
|
|
+ self.master.run_command([
|
|
+ 'sh', '-c',
|
|
+ f'echo \'{KEY_CONFIG}\' >> /etc/named.conf'
|
|
+ ])
|
|
+
|
|
+ # Update zone policy to include zonesub match type
|
|
+ update_policy = (
|
|
+ f'grant {realm} krb5-self * A; '
|
|
+ f'grant {realm} krb5-self * AAAA; '
|
|
+ f'grant {realm} krb5-self * SSHFP; '
|
|
+ 'grant selfupdate zonesub A;'
|
|
+ )
|
|
+ tasks.mod_dns_zone(
|
|
+ self.master, domain, f'--update-policy={update_policy}'
|
|
+ )
|
|
+
|
|
+ # Restart named to pick up changes
|
|
+ tasks.restart_named(self.master)
|
|
+
|
|
+ # Create nsupdate commands file
|
|
+ nsupdate_content = NSUPDATE_ADD_A_WITH_KEY_TEMPLATE.format(
|
|
+ server=self.master.hostname,
|
|
+ zone=domain,
|
|
+ key_name=KEY_NAME,
|
|
+ key_secret=KEY_SECRET,
|
|
+ hostname=f'foobz921167.{domain}.',
|
|
+ ttl=60,
|
|
+ ip=test_ip
|
|
+ )
|
|
+ self.master.put_file_contents(
|
|
+ '/tmp/dnsupdate.txt', nsupdate_content
|
|
+ )
|
|
+
|
|
+ # Execute nsupdate with zonesub policy and verify NOERROR
|
|
+ result = self.master.run_command([
|
|
+ 'nsupdate', '-v', '-D', '/tmp/dnsupdate.txt'
|
|
+ ])
|
|
+ assert 'NOERROR' in result.stdout_text, \
|
|
+ 'Dynamic update did not return NOERROR'
|
|
+
|
|
+ finally:
|
|
+ # Restore original named.conf
|
|
+ self.master.run_command([
|
|
+ 'cp', '/etc/named.conf.bak', '/etc/named.conf'
|
|
+ ], raiseonerr=False)
|
|
+
|
|
+ # Restore original update policy
|
|
+ original_policy = (
|
|
+ f'grant {realm} krb5-self * A; '
|
|
+ f'grant {realm} krb5-self * AAAA; '
|
|
+ f'grant {realm} krb5-self * SSHFP;'
|
|
+ )
|
|
+ tasks.mod_dns_zone(
|
|
+ self.master, domain, f'--update-policy={original_policy}',
|
|
+ raiseonerr=False
|
|
+ )
|
|
+
|
|
+ # Cleanup test record if it was created
|
|
+ tasks.del_dns_record(
|
|
+ self.master, domain, 'foobz921167',
|
|
+ del_all=True, raiseonerr=False
|
|
+ )
|
|
+
|
|
+ # Restart named
|
|
+ tasks.restart_named(self.master)
|
|
+
|
|
+ def test_bind_shutdown_ldap_failure(self):
|
|
+ """Test BIND shuts down correctly when psearch enabled and LDAP fails.
|
|
+
|
|
+ Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=802375
|
|
+
|
|
+ This test verifies that named service can be stopped cleanly
|
|
+ even when LDAP connection is configured with an invalid URI.
|
|
+ The test modifies named.conf to point to an invalid LDAP URI,
|
|
+ then verifies that 'rndc stop' works correctly.
|
|
+ """
|
|
+ tasks.kinit_admin(self.master)
|
|
+
|
|
+ # Get realm name with dashes instead of dots for socket path
|
|
+ realm_inst = self.master.domain.realm.replace('.', '-')
|
|
+
|
|
+ try:
|
|
+ # Check named is running
|
|
+ assert tasks.host_service_active(self.master, 'named')
|
|
+
|
|
+ # Backup named.conf
|
|
+ self.master.run_command(['cp', '/etc/named.conf', '/root/'])
|
|
+
|
|
+ # Comment out the valid LDAP URI and add invalid one
|
|
+ # The valid URI looks like:
|
|
+ # uri "ldapi://%2fvar%2frun%2fslapd-REALM.socket";
|
|
+ sed_pattern = (
|
|
+ f's|uri "ldapi://%2fvar%2frun%2fslapd-{realm_inst}.socket";'
|
|
+ f'|#uri "ldapi://%2fvar%2frun%2fslapd-{realm_inst}.socket";|g'
|
|
+ )
|
|
+ self.master.run_command([
|
|
+ 'sed', '-i', sed_pattern, '/etc/named.conf'
|
|
+ ])
|
|
+
|
|
+ # Add invalid LDAP URI before the commented line
|
|
+ insert_pattern = (
|
|
+ f'/ldapi:\\/\\/%2fvar%2frun%2fslapd-{realm_inst}.socket/i '
|
|
+ 'uri "ldapi://127.0.0.1";'
|
|
+ )
|
|
+ self.master.run_command([
|
|
+ 'sed', '-i', insert_pattern, '/etc/named.conf'
|
|
+ ])
|
|
+
|
|
+ # Restart named with invalid LDAP config
|
|
+ tasks.restart_named(self.master)
|
|
+
|
|
+ # Try to stop named with rndc - should work without hanging
|
|
+ self.master.run_command(['rndc', 'stop'], raiseonerr=False)
|
|
+
|
|
+ # Wait a moment for service to stop
|
|
+ time.sleep(5)
|
|
+
|
|
+ # Verify named is not running (exit code 3 = inactive)
|
|
+ result = self.master.run_command(
|
|
+ ['systemctl', 'is-active', 'named'], raiseonerr=False
|
|
+ )
|
|
+ assert result.returncode != 0, "named should be stopped"
|
|
+
|
|
+ finally:
|
|
+ # Restore original named.conf
|
|
+ # Remove the invalid URI line
|
|
+ self.master.run_command([
|
|
+ 'sed', '-i', '/ldapi:\\/\\/127.0.0.1/d', '/etc/named.conf'
|
|
+ ], raiseonerr=False)
|
|
+
|
|
+ # Uncomment the original valid URI
|
|
+ uncomment_pattern = (
|
|
+ f's|#uri "ldapi://%2fvar%2frun%2fslapd-{realm_inst}.socket";'
|
|
+ f'|uri "ldapi://%2fvar%2frun%2fslapd-{realm_inst}.socket";|g'
|
|
+ )
|
|
+ self.master.run_command([
|
|
+ 'sed', '-i', uncomment_pattern, '/etc/named.conf'
|
|
+ ], raiseonerr=False)
|
|
+
|
|
+ # Restart named to restore normal operation
|
|
+ tasks.restart_named(self.master)
|
|
+
|
|
+ def test_bind_ldap_reconnect(self):
|
|
+ """Test reconnect to LDAP when the first connection fails.
|
|
+
|
|
+ Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=767489
|
|
+
|
|
+ This test verifies that named service can handle LDAP connection
|
|
+ failures gracefully. It modifies named.conf to use an invalid LDAP
|
|
+ URI while blocking LDAP ports with iptables, then restarts named
|
|
+ to verify it handles the reconnection properly when connectivity
|
|
+ is restored.
|
|
+ """
|
|
+ tasks.kinit_admin(self.master)
|
|
+
|
|
+ # Get realm name with dashes instead of dots for socket path
|
|
+ realm_inst = self.master.domain.realm.replace('.', '-')
|
|
+
|
|
+ # Firewall rich rules to block LDAP ports
|
|
+ ldap_reject = 'rule family=ipv4 port port=389 protocol=tcp reject'
|
|
+ ldaps_reject = 'rule family=ipv4 port port=636 protocol=tcp reject'
|
|
+
|
|
+ try:
|
|
+ # Check named is running
|
|
+ assert tasks.host_service_active(self.master, 'named')
|
|
+
|
|
+ # Backup named.conf
|
|
+ self.master.run_command(['cp', '/etc/named.conf', '/root/'])
|
|
+
|
|
+ # Comment out the valid LDAP URI and add invalid one
|
|
+ sed_pattern = (
|
|
+ f's|uri "ldapi://%2fvar%2frun%2fslapd-{realm_inst}.socket";'
|
|
+ f'|#uri "ldapi://%2fvar%2frun%2fslapd-{realm_inst}.socket";|g'
|
|
+ )
|
|
+ self.master.run_command([
|
|
+ 'sed', '-i', sed_pattern, '/etc/named.conf'
|
|
+ ])
|
|
+
|
|
+ # Add invalid LDAP URI before the commented line
|
|
+ insert_pattern = (
|
|
+ f'/ldapi:\\/\\/%2fvar%2frun%2fslapd-{realm_inst}.socket/i '
|
|
+ 'uri "ldapi://127.0.0.1";'
|
|
+ )
|
|
+ self.master.run_command([
|
|
+ 'sed', '-i', insert_pattern, '/etc/named.conf'
|
|
+ ])
|
|
+
|
|
+ # Block LDAP ports with firewall-cmd to ensure connection fails
|
|
+ self.master.run_command([
|
|
+ 'firewall-cmd', f'--add-rich-rule={ldap_reject}'
|
|
+ ])
|
|
+ self.master.run_command([
|
|
+ 'firewall-cmd', f'--add-rich-rule={ldaps_reject}'
|
|
+ ])
|
|
+
|
|
+ # Restart named - it should handle the LDAP connection failure
|
|
+ tasks.restart_named(self.master)
|
|
+
|
|
+ # Verify named is still running (may be in degraded state)
|
|
+ result = self.master.run_command(
|
|
+ ['systemctl', 'is-active', 'named'], raiseonerr=False
|
|
+ )
|
|
+ # Named may be active or activating depending on timing
|
|
+ assert result.returncode == 0 or 'activating' in result.stdout_text
|
|
+
|
|
+ finally:
|
|
+ # Remove firewall rules to restore LDAP connectivity
|
|
+ self.master.run_command([
|
|
+ 'firewall-cmd', f'--remove-rich-rule={ldap_reject}'
|
|
+ ], raiseonerr=False)
|
|
+ self.master.run_command([
|
|
+ 'firewall-cmd', f'--remove-rich-rule={ldaps_reject}'
|
|
+ ], raiseonerr=False)
|
|
+
|
|
+ # Restore original named.conf
|
|
+ # Remove the invalid URI line
|
|
+ self.master.run_command([
|
|
+ 'sed', '-i', '/ldapi:\\/\\/127.0.0.1/d', '/etc/named.conf'
|
|
+ ], raiseonerr=False)
|
|
+
|
|
+ # Uncomment the original valid URI
|
|
+ uncomment_pattern = (
|
|
+ f's|#uri "ldapi://%2fvar%2frun%2fslapd-{realm_inst}.socket";'
|
|
+ f'|uri "ldapi://%2fvar%2frun%2fslapd-{realm_inst}.socket";|g'
|
|
+ )
|
|
+ self.master.run_command([
|
|
+ 'sed', '-i', uncomment_pattern, '/etc/named.conf'
|
|
+ ], raiseonerr=False)
|
|
+
|
|
+ # Restart named to restore normal operation
|
|
+ tasks.restart_named(self.master)
|
|
+
|
|
+ def test_dnsrecord_mod_nonexistent_error(self):
|
|
+ """Test correct error message when modifying nonexistent DNS record.
|
|
+
|
|
+ Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=856281
|
|
+ """
|
|
+ tasks.kinit_admin(self.master)
|
|
+ domain = self.master.domain.name
|
|
+
|
|
+ # Try to modify a non-existent record
|
|
+ result = tasks.mod_dns_record(
|
|
+ self.master, domain, 'this.does.not.exist',
|
|
+ '--txt-rec=foo', raiseonerr=False
|
|
+ )
|
|
+
|
|
+ assert result.returncode != 0
|
|
+ expected_msg = "this.does.not.exist: DNS resource record not found"
|
|
+ assert expected_msg in result.stderr_text
|
|
+
|
|
+ def test_zone_without_update_policy(self):
|
|
+ """Test zone without idnsUpdatePolicy works during zone refresh.
|
|
+
|
|
+ Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=908780
|
|
+
|
|
+ As per bind-dyndb-ldap/NEWS, psearch, serial_autoincrement and
|
|
+ zone_refresh were deprecated and removed. This test verifies
|
|
+ that zones without idnsUpdatePolicy still work correctly after
|
|
+ service restart.
|
|
+ """
|
|
+ tasks.kinit_admin(self.master)
|
|
+ zone = "bz908780zone"
|
|
+
|
|
+ try:
|
|
+ # Add test zone
|
|
+ tasks.add_dns_zone(
|
|
+ self.master, zone,
|
|
+ admin_email=self.EMAIL
|
|
+ )
|
|
+
|
|
+ # Modify zone to remove idnsUpdatePolicy attribute
|
|
+ tasks.mod_dns_zone(self.master, zone, '--update-policy=')
|
|
+
|
|
+ # Restart named service
|
|
+ tasks.restart_named(self.master)
|
|
+
|
|
+ # Check logs for error message (use journalctl for compatibility)
|
|
+ result = self.master.run_command([
|
|
+ 'journalctl', '-u', 'named', '-n', '100', '--no-pager'
|
|
+ ])
|
|
+
|
|
+ # Verify no error about zone failing to transfer
|
|
+ err_msg = "unchanged. zone may fail to transfer to slaves"
|
|
+ assert err_msg not in result.stdout_text
|
|
+
|
|
+ finally:
|
|
+ tasks.del_dns_zone(self.master, zone, raiseonerr=False)
|
|
+
|
|
+ def test_txt_record_with_comma(self):
|
|
+ """Test dnsrecord works if TXT record data contains comma.
|
|
+
|
|
+ Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=910460
|
|
+ """
|
|
+ tasks.kinit_admin(self.master)
|
|
+ domain = self.master.domain.name
|
|
+ txt_value = (
|
|
+ 'Holmes laughed. "It is quite a pretty little problem," '
|
|
+ 'said he.'
|
|
+ )
|
|
+ txt_mod_value = (
|
|
+ 'Holmes laughed. "It is quite a pretty little problem," '
|
|
+ 'said me.'
|
|
+ )
|
|
+
|
|
+ try:
|
|
+ # Add TXT record with comma - should not cause traceback
|
|
+ result = tasks.add_dns_record(
|
|
+ self.master, domain, '@', 'txt', [txt_value]
|
|
+ )
|
|
+ assert result.returncode == 0
|
|
+
|
|
+ # Modify TXT record with comma - should not cause traceback
|
|
+ result = tasks.mod_dns_record(
|
|
+ self.master, domain, '@',
|
|
+ f'--txt-rec={txt_value}', f'--txt-data={txt_mod_value}'
|
|
+ )
|
|
+ assert result.returncode == 0
|
|
+
|
|
+ finally:
|
|
+ # Delete TXT record
|
|
+ tasks.del_dns_record(
|
|
+ self.master, domain, '@',
|
|
+ record_type='txt', record_value=[txt_mod_value],
|
|
+ raiseonerr=False
|
|
+ )
|
|
+
|
|
+ def test_dname_single_value(self):
|
|
+ """Test DNAME record attribute allows single value only.
|
|
+
|
|
+ Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=915797
|
|
+
|
|
+ Verify that adding a second DNAME record to the same name fails
|
|
+ with appropriate error message.
|
|
+ """
|
|
+ tasks.kinit_admin(self.master)
|
|
+ domain = self.master.domain.name
|
|
+ dname1 = f"foo.{domain}"
|
|
+ dname2 = f"bar.{domain}"
|
|
+
|
|
+ try:
|
|
+ # Add first DNAME record
|
|
+ tasks.add_dns_record(
|
|
+ self.master, domain, 'dnamebz915797', 'dname', [dname1]
|
|
+ )
|
|
+
|
|
+ # Try to add second DNAME record - should fail
|
|
+ result = tasks.add_dns_record(
|
|
+ self.master, domain, 'dnamebz915797', 'dname', [dname2],
|
|
+ raiseonerr=False
|
|
+ )
|
|
+ assert result.returncode != 0
|
|
+ expected_msg = "only one DNAME record is allowed per name"
|
|
+ assert expected_msg in result.stderr_text
|
|
+
|
|
+ finally:
|
|
+ tasks.del_dns_record(
|
|
+ self.master, domain, 'dnamebz915797',
|
|
+ del_all=True, raiseonerr=False
|
|
+ )
|
|
+
|
|
+ def test_cname_single_value(self):
|
|
+ """Test CNAME record allows single value only.
|
|
+
|
|
+ Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=915807
|
|
+
|
|
+ Verify that adding a second CNAME record to the same name fails
|
|
+ with appropriate error message.
|
|
+ """
|
|
+ tasks.kinit_admin(self.master)
|
|
+ domain = self.master.domain.name
|
|
+ cname1 = f"foo.{domain}"
|
|
+ cname2 = f"bar.{domain}"
|
|
+
|
|
+ try:
|
|
+ # Add first CNAME record
|
|
+ tasks.add_dns_record(
|
|
+ self.master, domain, 'cnamebz915807', 'cname', [cname1]
|
|
+ )
|
|
+
|
|
+ # Try to add second CNAME record - should fail
|
|
+ result = tasks.add_dns_record(
|
|
+ self.master, domain, 'cnamebz915807', 'cname', [cname2],
|
|
+ raiseonerr=False
|
|
+ )
|
|
+ assert result.returncode != 0
|
|
+ expected_msg = "only one CNAME record is allowed per name"
|
|
+ assert expected_msg in result.stderr_text
|
|
+
|
|
+ finally:
|
|
+ tasks.del_dns_record(
|
|
+ self.master, domain, 'cnamebz915807',
|
|
+ del_all=True, raiseonerr=False
|
|
+ )
|
|
+
|
|
+ def test_idnszone_schema_no_cn(self):
|
|
+ """Test cn attribute is not present in idnsZone objectClasses.
|
|
+
|
|
+ Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=947911
|
|
+
|
|
+ Verify that 'cn' attribute is removed from idnsZone objectClasses
|
|
+ in LDAP schema. Note: 'cn' was returned back to idnsRecord to fix
|
|
+ bug 1167964, so we only check idnsZone.
|
|
+ """
|
|
+ tasks.kinit_admin(self.master)
|
|
+
|
|
+ # Check that cn attribute is not in idnsZone objectClass
|
|
+ # Use ldif-wrap=no to keep each objectClass on a single line
|
|
+ result = self.master.run_command([
|
|
+ 'ldapsearch', '-x', '-D',
|
|
+ 'cn=Directory Manager',
|
|
+ '-w', self.master.config.dirman_password,
|
|
+ '-b', 'cn=schema', 'objectClasses',
|
|
+ '-o', 'ldif-wrap=no'
|
|
+ ])
|
|
+
|
|
+ # Verify idnsZone objectClass exists and doesn't contain cn attribute
|
|
+ lines = result.stdout_text.split('\n')
|
|
+ is_valid = any(
|
|
+ "NAME 'idnsZone'" in line and ' cn ' not in line
|
|
+ for line in lines
|
|
+ )
|
|
+ assert is_valid, "cn attribute should not be in idnsZone objectClass"
|
|
+
|
|
+ def test_ptr_sync_preserves_txt_record(self):
|
|
+ """Test PTR sync deletes only PTR record, preserves TXT record.
|
|
+
|
|
+ Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=958140
|
|
+
|
|
+ When PTR record synchronization is enabled and an A record is
|
|
+ deleted via dynamic update, only the corresponding PTR record
|
|
+ should be deleted. Other records (like TXT) on the same name
|
|
+ in the reverse zone should be preserved.
|
|
+ """
|
|
+ tasks.kinit_admin(self.master)
|
|
+ test_zone = "examplebz958140.com"
|
|
+ reverse_zone = "3.2.1.in-addr.arpa."
|
|
+ realm = self.master.domain.realm
|
|
+ hostname = f"testbz958140.{test_zone}"
|
|
+
|
|
+ try:
|
|
+ # Add test zones
|
|
+ tasks.add_dns_zone(
|
|
+ self.master, test_zone,
|
|
+ skip_overlap_check=True,
|
|
+ admin_email=f"hostmaster.{test_zone}"
|
|
+ )
|
|
+ tasks.add_dns_zone(
|
|
+ self.master, reverse_zone,
|
|
+ skip_overlap_check=True,
|
|
+ admin_email=f"hostmaster.{reverse_zone}"
|
|
+ )
|
|
+
|
|
+ # Reload named so it can serve the new zones
|
|
+ self.master.run_command(['rndc', 'reload'])
|
|
+
|
|
+ # Add A record with reverse PTR
|
|
+ tasks.add_dns_record(
|
|
+ self.master, test_zone, 'testbz958140', 'a', ['1.2.3.4'],
|
|
+ '--a-create-reverse'
|
|
+ )
|
|
+
|
|
+ # Add TXT record to reverse zone on same name as PTR
|
|
+ tasks.add_dns_record(
|
|
+ self.master, reverse_zone, '4', 'txt', ['text']
|
|
+ )
|
|
+
|
|
+ # Enable PTR record synchronization
|
|
+ tasks.mod_dns_zone(
|
|
+ self.master, test_zone, '--dynamic-update=True'
|
|
+ )
|
|
+ tasks.mod_dns_zone(
|
|
+ self.master, test_zone, '--allow-sync-ptr=True'
|
|
+ )
|
|
+ tasks.mod_dns_zone(
|
|
+ self.master, reverse_zone, '--dynamic-update=True'
|
|
+ )
|
|
+
|
|
+ # Add host and get keytab for dynamic updates
|
|
+ self.master.run_command([
|
|
+ 'ipa', 'host-add', hostname, '--force'
|
|
+ ])
|
|
+ self.master.run_command([
|
|
+ 'ipa-getkeytab', '-s', self.master.hostname,
|
|
+ '-p', f'host/{hostname}@{realm}',
|
|
+ '-k', '/tmp/bz958140.keytab'
|
|
+ ])
|
|
+
|
|
+ self.master.run_command(['rndc', 'reload'])
|
|
+ self.master.run_command(['ipactl', 'restart'])
|
|
+
|
|
+ # Use nsupdate to delete A record (should trigger PTR sync)
|
|
+ nsupdate_content = NSUPDATE_DELETE_A_TEMPLATE.format(
|
|
+ hostname=hostname, ip='1.2.3.4'
|
|
+ )
|
|
+ self.master.put_file_contents('/tmp/nsupdate958140.txt',
|
|
+ nsupdate_content)
|
|
+ self.master.run_command([
|
|
+ 'kinit', '-k', '-t', '/tmp/bz958140.keytab',
|
|
+ f'host/{hostname}'
|
|
+ ])
|
|
+ self.master.run_command([
|
|
+ 'nsupdate', '-g', '-v', '/tmp/nsupdate958140.txt'
|
|
+ ], raiseonerr=False)
|
|
+
|
|
+ tasks.kinit_admin(self.master)
|
|
+
|
|
+ # Verify A record is deleted
|
|
+ result = tasks.find_dns_record(
|
|
+ self.master, test_zone, 'testbz958140', raiseonerr=False
|
|
+ )
|
|
+ assert 'A record' not in result.stdout_text
|
|
+
|
|
+ # Verify PTR record is deleted
|
|
+ result = self.master.run_command([
|
|
+ 'ipa', 'dnsrecord-find', reverse_zone, '4'
|
|
+ ], raiseonerr=False)
|
|
+ assert 'PTR record' not in result.stdout_text
|
|
+
|
|
+ # Verify TXT record is preserved
|
|
+ assert 'TXT record' in result.stdout_text
|
|
+
|
|
+ finally:
|
|
+ tasks.kinit_admin(self.master)
|
|
+ self.master.run_command([
|
|
+ 'ipa', 'host-del', hostname
|
|
+ ], raiseonerr=False)
|
|
+ tasks.del_dns_zone(self.master, test_zone, raiseonerr=False)
|
|
+ tasks.del_dns_zone(self.master, reverse_zone, raiseonerr=False)
|
|
+ self.master.run_command(['rm', '-f', '/tmp/bz958140.keytab',
|
|
+ '/tmp/nsupdate958140.txt'],
|
|
+ raiseonerr=False)
|
|
+
|
|
+ def test_invalid_policy_disables_operations(self):
|
|
+ """Test invalid policy disables updates, transfers, and queries.
|
|
+
|
|
+ Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=958141
|
|
+
|
|
+ When zone policy (update, transfer, or query) contains invalid
|
|
+ values, the corresponding operation should be disabled/refused.
|
|
+ """
|
|
+ tasks.kinit_admin(self.master)
|
|
+ test_zone = 'example.test'
|
|
+ realm = self.master.domain.realm
|
|
+ hostname = f'test.{test_zone}'
|
|
+
|
|
+ try:
|
|
+ # Add test zone and get original update policy
|
|
+ tasks.add_dns_zone(
|
|
+ self.master, test_zone,
|
|
+ skip_overlap_check=True,
|
|
+ admin_email=f'hostmaster.{test_zone}'
|
|
+ )
|
|
+
|
|
+ # Get original update policy
|
|
+ result = self.master.run_command([
|
|
+ 'ipa', 'dnszone-show', test_zone, '--all'
|
|
+ ])
|
|
+ original_policy = None
|
|
+ for line in result.stdout_text.split('\n'):
|
|
+ if 'BIND update policy:' in line:
|
|
+ original_policy = line.split(':', 1)[1].strip()
|
|
+ break
|
|
+
|
|
+ tasks.add_dns_record(
|
|
+ self.master, test_zone, 'test', 'a', ['1.2.3.4']
|
|
+ )
|
|
+
|
|
+ # Test 1: Verify dynamic update works with valid policy
|
|
+ tasks.mod_dns_zone(
|
|
+ self.master, test_zone, '--dynamic-update=True'
|
|
+ )
|
|
+
|
|
+ self.master.run_command([
|
|
+ 'ipa', 'host-add', hostname
|
|
+ ])
|
|
+ self.master.run_command([
|
|
+ 'ipa-getkeytab', '-s', self.master.hostname,
|
|
+ '-p', f'host/{hostname}@{realm}',
|
|
+ '-k', '/tmp/bz958141.keytab'
|
|
+ ])
|
|
+
|
|
+ self.master.run_command(['rndc', 'reload'])
|
|
+
|
|
+ # Create nsupdate file to delete A record
|
|
+ nsupdate_content = NSUPDATE_DELETE_A_TEMPLATE.format(
|
|
+ hostname=hostname, ip='1.2.3.4'
|
|
+ )
|
|
+ self.master.put_file_contents('/tmp/nsupdate958141.txt',
|
|
+ nsupdate_content)
|
|
+
|
|
+ self.master.run_command([
|
|
+ 'kinit', '-k', '-t', '/tmp/bz958141.keytab',
|
|
+ f'host/{hostname}'
|
|
+ ])
|
|
+
|
|
+ # Dynamic update should succeed with valid policy
|
|
+ result = self.master.run_command([
|
|
+ 'nsupdate', '-g', '-v', '/tmp/nsupdate958141.txt'
|
|
+ ], raiseonerr=False)
|
|
+ assert result.returncode == 0, \
|
|
+ 'Dynamic update should succeed with valid policy'
|
|
+
|
|
+ # Set invalid update policy
|
|
+ tasks.kinit_admin(self.master)
|
|
+ tasks.mod_dns_zone(
|
|
+ self.master, test_zone, '--update-policy=invalid value'
|
|
+ )
|
|
+
|
|
+ # Re-add A record for next test
|
|
+ tasks.add_dns_record(
|
|
+ self.master, test_zone, 'test', 'a', ['1.2.3.4']
|
|
+ )
|
|
+
|
|
+ # Dynamic update should fail with invalid policy
|
|
+ self.master.run_command([
|
|
+ 'kinit', '-k', '-t', '/tmp/bz958141.keytab',
|
|
+ f'host/{hostname}'
|
|
+ ])
|
|
+ result = self.master.run_command([
|
|
+ 'nsupdate', '-g', '/tmp/nsupdate958141.txt'
|
|
+ ], raiseonerr=False)
|
|
+ assert result.returncode == 2, \
|
|
+ 'Dynamic update should fail with invalid policy'
|
|
+
|
|
+ # Restore original update policy
|
|
+ tasks.kinit_admin(self.master)
|
|
+ tasks.mod_dns_zone(
|
|
+ self.master, test_zone,
|
|
+ f'--update-policy={original_policy}'
|
|
+ )
|
|
+
|
|
+ # Test 2: Invalid transfer policy disables zone transfers
|
|
+ tasks.mod_dns_zone(
|
|
+ self.master, test_zone, '--allow-transfer=any'
|
|
+ )
|
|
+
|
|
+ # Verify zone transfer works with valid policy
|
|
+ result = self.master.run_command([
|
|
+ 'dig', '@127.0.0.1', '-t', 'AXFR', test_zone
|
|
+ ], raiseonerr=False)
|
|
+ assert 'Transfer failed' not in result.stdout_text
|
|
+
|
|
+ # Set invalid transfer policy via LDAP
|
|
+ ldap = self.master.ldap_connect()
|
|
+ zone_dn = DN(
|
|
+ ('idnsname', f'{test_zone}.'),
|
|
+ ('cn', 'dns'),
|
|
+ self.master.domain.basedn
|
|
+ )
|
|
+ entry = ldap.get_entry(zone_dn)
|
|
+ entry['idnsAllowTransfer'] = ['192.0.2..0/24'] # Invalid
|
|
+ ldap.update_entry(entry)
|
|
+
|
|
+ # Verify zone transfer fails with invalid policy
|
|
+ result = self.master.run_command([
|
|
+ 'dig', '@127.0.0.1', '-t', 'AXFR', test_zone
|
|
+ ], raiseonerr=False)
|
|
+ assert 'Transfer failed' in result.stdout_text
|
|
+
|
|
+ # Restore valid transfer policy
|
|
+ tasks.mod_dns_zone(
|
|
+ self.master, test_zone, '--allow-transfer=none'
|
|
+ )
|
|
+
|
|
+ # Test 3: Invalid query policy disables queries
|
|
+ # First verify query works with valid policy
|
|
+ result = self.master.run_command([
|
|
+ 'dig', f'test.{test_zone}'
|
|
+ ], raiseonerr=False)
|
|
+ assert 'NOERROR' in result.stdout_text
|
|
+
|
|
+ # Set invalid query policy via LDAP
|
|
+ entry = ldap.get_entry(zone_dn)
|
|
+ entry['idnsAllowQuery'] = ['192.0.2..0/24'] # Invalid
|
|
+ ldap.update_entry(entry)
|
|
+
|
|
+ # Verify query is refused
|
|
+ result = self.master.run_command([
|
|
+ 'dig', f'test.{test_zone}'
|
|
+ ], raiseonerr=False)
|
|
+ assert 'REFUSED' in result.stdout_text
|
|
+
|
|
+ # Restore valid query policy
|
|
+ tasks.mod_dns_zone(
|
|
+ self.master, test_zone, '--allow-query=any'
|
|
+ )
|
|
+
|
|
+ finally:
|
|
+ tasks.kinit_admin(self.master)
|
|
+ self.master.run_command([
|
|
+ 'ipa', 'host-del', hostname
|
|
+ ], raiseonerr=False)
|
|
+ tasks.del_dns_zone(self.master, test_zone, raiseonerr=False)
|
|
+ self.master.run_command([
|
|
+ 'rm', '-f', '/tmp/bz958141.keytab', '/tmp/nsupdate958141.txt'
|
|
+ ], raiseonerr=False)
|
|
+
|
|
+ def test_ptr_sync_ipv6(self):
|
|
+ """Test PTR record synchronization works with IPv6 addresses.
|
|
+
|
|
+ Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=962814
|
|
+
|
|
+ Verify that when AAAA record is added via dynamic update with
|
|
+ PTR sync enabled, the corresponding PTR record is created in
|
|
+ the IPv6 reverse zone.
|
|
+ """
|
|
+ tasks.kinit_admin(self.master)
|
|
+ test_zone = "examplebz962814.com"
|
|
+ # Reverse zone for 1:2:3:4:5:6::/96
|
|
+ reverse_zone = (
|
|
+ "6.0.0.0.5.0.0.0.4.0.0.0.3.0.0.0.2.0.0.0.1.0.0.0.ip6.arpa."
|
|
+ )
|
|
+ realm = self.master.domain.realm
|
|
+ hostname = f"test.{test_zone}"
|
|
+
|
|
+ try:
|
|
+ # Add test zones
|
|
+ tasks.add_dns_zone(
|
|
+ self.master, test_zone,
|
|
+ skip_overlap_check=True,
|
|
+ admin_email=f"hostmaster.{test_zone}"
|
|
+ )
|
|
+ tasks.add_dns_zone(
|
|
+ self.master, reverse_zone,
|
|
+ skip_overlap_check=True,
|
|
+ admin_email=f"hostmaster.{reverse_zone}"
|
|
+ )
|
|
+
|
|
+ # Enable PTR record synchronization
|
|
+ tasks.mod_dns_zone(
|
|
+ self.master, test_zone, '--dynamic-update=True'
|
|
+ )
|
|
+ tasks.mod_dns_zone(
|
|
+ self.master, test_zone, '--allow-sync-ptr=True'
|
|
+ )
|
|
+ tasks.mod_dns_zone(
|
|
+ self.master, reverse_zone, '--dynamic-update=True'
|
|
+ )
|
|
+
|
|
+ # Add host and get keytab
|
|
+ self.master.run_command([
|
|
+ 'ipa', 'host-add', hostname, '--force'
|
|
+ ])
|
|
+ self.master.run_command([
|
|
+ 'ipa-getkeytab', '-s', self.master.hostname,
|
|
+ '-p', f'host/{hostname}@{realm}',
|
|
+ '-k', '/tmp/bz962814.keytab'
|
|
+ ])
|
|
+
|
|
+ self.master.run_command(['rndc', 'reload'])
|
|
+
|
|
+ # Use nsupdate to add AAAA record
|
|
+ nsupdate_content = NSUPDATE_ADD_AAAA_TEMPLATE.format(
|
|
+ hostname=hostname, ttl=3600, ip='1:2:3:4:5:6:7:8'
|
|
+ )
|
|
+ self.master.put_file_contents('/tmp/nsupdate962814.txt',
|
|
+ nsupdate_content)
|
|
+ self.master.run_command([
|
|
+ 'kinit', '-k', '-t', '/tmp/bz962814.keytab',
|
|
+ f'host/{hostname}'
|
|
+ ])
|
|
+
|
|
+ time.sleep(60)
|
|
+ self.master.run_command([
|
|
+ 'nsupdate', '-g', '/tmp/nsupdate962814.txt'
|
|
+ ])
|
|
+
|
|
+ tasks.kinit_admin(self.master)
|
|
+
|
|
+ # Verify AAAA record was added
|
|
+ result = tasks.find_dns_record(
|
|
+ self.master, test_zone, 'test', raiseonerr=False
|
|
+ )
|
|
+ assert 'AAAA record' in result.stdout_text
|
|
+
|
|
+ # Verify PTR record was created in reverse zone
|
|
+ # PTR for 1:2:3:4:5:6:7:8 should be at 8.0.0.0.7.0.0.0
|
|
+ result = self.master.run_command([
|
|
+ 'ipa', 'dnsrecord-find', reverse_zone, '8.0.0.0.7.0.0.0'
|
|
+ ], raiseonerr=False)
|
|
+ assert 'PTR record' in result.stdout_text
|
|
+
|
|
+ finally:
|
|
+ tasks.kinit_admin(self.master)
|
|
+ self.master.run_command([
|
|
+ 'ipa', 'host-del', hostname
|
|
+ ], raiseonerr=False)
|
|
+ tasks.del_dns_zone(self.master, test_zone, raiseonerr=False)
|
|
+ tasks.del_dns_zone(self.master, reverse_zone, raiseonerr=False)
|
|
+ self.master.run_command(['rm', '-f', '/tmp/bz962814.keytab',
|
|
+ '/tmp/nsupdate962814.txt'],
|
|
+ raiseonerr=False)
|
|
+
|
|
+ def test_ipv6_private_reverse_zone(self):
|
|
+ """Test serving reverse zones for IPv6 private ranges.
|
|
+
|
|
+ Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=962815
|
|
+
|
|
+ Verify that reverse zones for IPv6 private/documentation ranges
|
|
+ (like 2001:db8::/32) can be served without manual changes to
|
|
+ named.conf. These are in the automatic empty zones list.
|
|
+ """
|
|
+ tasks.kinit_admin(self.master)
|
|
+ # 2001:db8::/32 documentation prefix reverse zone
|
|
+ reverse_zone = "8.b.d.0.1.0.0.2.ip6.arpa"
|
|
+ test_record = "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0"
|
|
+ test_ptr = "test.example.com"
|
|
+ test_ipv6 = "2001:0db8::1"
|
|
+
|
|
+ try:
|
|
+ # Add reverse zone for IPv6 documentation prefix
|
|
+ tasks.add_dns_zone(
|
|
+ self.master, reverse_zone,
|
|
+ admin_email=f"hostmaster.{reverse_zone}"
|
|
+ )
|
|
+
|
|
+ # Add PTR record
|
|
+ tasks.add_dns_record(
|
|
+ self.master, f"{reverse_zone}.", test_record,
|
|
+ 'ptr', [test_ptr]
|
|
+ )
|
|
+
|
|
+ self.master.run_command(['ipactl', 'restart'])
|
|
+
|
|
+ # Verify reverse lookup works
|
|
+ result = self.master.run_command([
|
|
+ 'dig', '-x', test_ipv6
|
|
+ ])
|
|
+ assert test_record in result.stdout_text
|
|
+ assert test_ptr in result.stdout_text
|
|
+
|
|
+ # Restart named and verify zone loads
|
|
+ tasks.restart_named(self.master)
|
|
+ time.sleep(5)
|
|
+
|
|
+ # Check logs that zone was loaded without errors
|
|
+ result = self.master.run_command([
|
|
+ 'journalctl', '-u', 'named', '-n', '100', '--no-pager'
|
|
+ ])
|
|
+ # Verify zone is mentioned in logs (loaded)
|
|
+ assert reverse_zone in result.stdout_text, \
|
|
+ f'Zone {reverse_zone} not found in named logs'
|
|
+
|
|
+ finally:
|
|
+ tasks.del_dns_zone(self.master, reverse_zone, raiseonerr=False)
|
|
+
|
|
+ def test_tld_with_numbers(self):
|
|
+ """Test DNS record allows top-level domains with numbers.
|
|
+
|
|
+ Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=907913
|
|
+
|
|
+ Verify that DNS zones and records can be created with TLDs
|
|
+ that contain numbers, and NS records can reference them.
|
|
+ """
|
|
+ tasks.kinit_admin(self.master)
|
|
+ domain = self.master.domain.name
|
|
+ test_zone = "TBADTEST0" # TLD with number
|
|
+ test_record = "TBADTEST"
|
|
+
|
|
+ try:
|
|
+ # Add zone with numeric TLD
|
|
+ tasks.add_dns_zone(
|
|
+ self.master, test_zone,
|
|
+ admin_email=f"hostmaster.{test_zone}"
|
|
+ )
|
|
+
|
|
+ # Add A record in the zone
|
|
+ tasks.add_dns_record(
|
|
+ self.master, test_zone, test_record, 'a', ['1.2.3.4']
|
|
+ )
|
|
+
|
|
+ self.master.run_command(['ipactl', 'restart'])
|
|
+
|
|
+ # Verify NS hostname with numeric TLD is valid
|
|
+ result = tasks.add_dns_record(
|
|
+ self.master, domain, test_record, 'ns',
|
|
+ [f'{test_record}.{test_zone}.']
|
|
+ )
|
|
+ assert result.returncode == 0
|
|
+
|
|
+ # Cleanup NS record
|
|
+ tasks.del_dns_record(
|
|
+ self.master, domain, test_record,
|
|
+ record_type='ns',
|
|
+ record_value=[f'{test_record}.{test_zone}.']
|
|
+ )
|
|
+
|
|
+ finally:
|
|
+ tasks.del_dns_zone(self.master, test_zone, raiseonerr=False)
|
|
+
|
|
+ def test_rfc2317_classless_arpa(self):
|
|
+ """Test dnszone-add supports RFC 2317 classless in-addr.arpa.
|
|
+
|
|
+ Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1058688
|
|
+
|
|
+ Verify that DNS zones with RFC 2317 classless reverse delegation
|
|
+ format (like 0/27.10.10.in-addr.arpa) can be created.
|
|
+ """
|
|
+ tasks.kinit_admin(self.master)
|
|
+ # RFC 2317 classless delegation format
|
|
+ test_zone = "0/27.10.10.in-addr.arpa."
|
|
+
|
|
+ try:
|
|
+ # Add zone with RFC 2317 format
|
|
+ tasks.add_dns_zone(
|
|
+ self.master, test_zone,
|
|
+ skip_overlap_check=True,
|
|
+ admin_email="hostmaster.0.0.10.10.in-addr.arpa."
|
|
+ )
|
|
+
|
|
+ # Verify zone was created
|
|
+ result = tasks.find_dns_zone(self.master, test_zone)
|
|
+ assert result.returncode == 0
|
|
+ assert test_zone in result.stdout_text
|
|
+
|
|
+ finally:
|
|
+ tasks.del_dns_zone(self.master, test_zone, raiseonerr=False)
|
|
+
|
|
+ def test_dnsrecord_mod_no_warning(self):
|
|
+ """Test dnsrecord-mod doesn't display API version warning.
|
|
+
|
|
+ Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1054869
|
|
+
|
|
+ Verify that modifying DNS records doesn't show warning message
|
|
+ about API version. Also tests that setting txt-rec to empty
|
|
+ deletes the record.
|
|
+ """
|
|
+ tasks.kinit_admin(self.master)
|
|
+ domain = self.master.domain.name
|
|
+ record_name = "bz1054869"
|
|
+
|
|
+ try:
|
|
+ # Add TXT record
|
|
+ tasks.add_dns_record(
|
|
+ self.master, domain, record_name, 'txt', ['1054869']
|
|
+ )
|
|
+
|
|
+ # Verify record was added
|
|
+ result = tasks.show_dns_record(
|
|
+ self.master, domain, record_name, '--all', '--raw'
|
|
+ )
|
|
+ assert 'txtrecord: 1054869' in result.stdout_text.lower()
|
|
+
|
|
+ # Modify record with empty txt-rec (deletes the record)
|
|
+ result = tasks.mod_dns_record(
|
|
+ self.master, domain, record_name,
|
|
+ '--txt-rec='
|
|
+ )
|
|
+ # Verify no API version warning
|
|
+ assert 'WARNING: API Version' not in result.stdout_text
|
|
+
|
|
+ # Verify record was deleted
|
|
+ result = tasks.find_dns_record(
|
|
+ self.master, domain, record_name, raiseonerr=False
|
|
+ )
|
|
+ assert result.returncode != 0
|
|
+
|
|
+ finally:
|
|
+ tasks.del_dns_record(
|
|
+ self.master, domain, record_name,
|
|
+ del_all=True, raiseonerr=False
|
|
+ )
|
|
+
|
|
+ def test_dnszone_disable_enable_and_system_records(self):
|
|
+ """Test dnszone-disable, dnszone-enable and dns-update-system-records.
|
|
+
|
|
+ This test verifies that:
|
|
+ 1. A DNS zone can be disabled and enabled
|
|
+ 2. dns-update-system-records works correctly (dry-run and actual)
|
|
+ """
|
|
+ tasks.kinit_admin(self.master)
|
|
+ test_zone = 'disabletest.test'
|
|
+
|
|
+ try:
|
|
+ # Add test zone
|
|
+ tasks.add_dns_zone(
|
|
+ self.master, test_zone,
|
|
+ admin_email=f'hostmaster.{test_zone}'
|
|
+ )
|
|
+
|
|
+ result = self.master.run_command([
|
|
+ 'ipa', 'dnszone-show', test_zone
|
|
+ ])
|
|
+ assert 'Active zone: True' in result.stdout_text
|
|
+
|
|
+ # Disable the zone
|
|
+ result = self.master.run_command([
|
|
+ 'ipa', 'dnszone-disable', test_zone
|
|
+ ])
|
|
+ assert f'Disabled DNS zone "{test_zone}."' in result.stdout_text
|
|
+
|
|
+ result = self.master.run_command([
|
|
+ 'ipa', 'dnszone-show', test_zone
|
|
+ ])
|
|
+ assert 'Active zone: False' in result.stdout_text
|
|
+
|
|
+ # Enable the zone
|
|
+ result = self.master.run_command([
|
|
+ 'ipa', 'dnszone-enable', test_zone
|
|
+ ])
|
|
+ assert f'Enabled DNS zone "{test_zone}."' in result.stdout_text
|
|
+
|
|
+ result = self.master.run_command([
|
|
+ 'ipa', 'dnszone-show', test_zone
|
|
+ ])
|
|
+ assert 'Active zone: True' in result.stdout_text
|
|
+
|
|
+ # Test dns-update-system-records --dry-run
|
|
+ result = self.master.run_command([
|
|
+ 'ipa', 'dns-update-system-records', '--dry-run'
|
|
+ ])
|
|
+ assert result.returncode == 0
|
|
+
|
|
+ result = self.master.run_command([
|
|
+ 'ipa', 'dns-update-system-records'
|
|
+ ])
|
|
+ assert result.returncode == 0
|
|
+
|
|
+ finally:
|
|
+ tasks.del_dns_zone(self.master, test_zone, raiseonerr=False)
|
|
--
|
|
2.53.0
|
|
|