See commit message for details. Patch attached.

This test does not cover:

* NTP service records

* ipa-ca A/AAAA records

* ADTrust records

Should I open tickets to cover cases above?

From 63335082b23a8ecc4195bece9944b74d4ca3f795 Mon Sep 17 00:00:00 2001
From: Martin Basti <mba...@redhat.com>
Date: Mon, 4 Jul 2016 14:20:03 +0200
Subject: [PATCH] CI: DNS locations

This test is testing default IPA system records in locations, if
priority and weight were properly set per service, per server, per
location.
---
 ipatests/test_integration/tasks.py              |   7 +
 ipatests/test_integration/test_dns_locations.py | 261 ++++++++++++++++++++++++
 ipatests/test_integration/test_dnssec.py        |  26 +--
 3 files changed, 277 insertions(+), 17 deletions(-)
 create mode 100644 ipatests/test_integration/test_dns_locations.py

diff --git a/ipatests/test_integration/tasks.py b/ipatests/test_integration/tasks.py
index 5be7cdae3ac777bbf0fc52e6c511969e9fabcd72..5ce2595c078e093adc3af024d41ddb5fb6892776 100644
--- a/ipatests/test_integration/tasks.py
+++ b/ipatests/test_integration/tasks.py
@@ -1173,3 +1173,10 @@ def assert_error(result, stderr_text, returncode=None):
         assert result.returncode == returncode
     else:
         assert result.returncode > 0
+
+
+def restart_named(*args):
+    time.sleep(20)  # give a time to DNSSEC daemons to provide keys for named
+    for host in args:
+        host.run_command(["systemctl", "restart", "named-pkcs11.service"])
+    time.sleep(20)  # give a time to named to be ready (zone loading)
diff --git a/ipatests/test_integration/test_dns_locations.py b/ipatests/test_integration/test_dns_locations.py
new file mode 100644
index 0000000000000000000000000000000000000000..e37e1dde35831a3087a4fd5cdd3c77cb887d0c51
--- /dev/null
+++ b/ipatests/test_integration/test_dns_locations.py
@@ -0,0 +1,261 @@
+#
+# Copyright (C) 2016  FreeIPA Contributors see COPYING for license
+#
+import time
+import dns.resolver
+import dns.rrset
+import dns.rdatatype
+import dns.rdataclass
+
+from ipatests.test_integration.base import IntegrationTest
+from ipatests.test_integration import tasks
+from ipapython.dnsutil import DNSName
+
+IPA_DEFAULT_MASTER_SRV_REC = (
+    # srv record name, port
+    (DNSName(u'_ldap._tcp'), 389),
+    (DNSName(u'_kerberos._tcp'), 88),
+    (DNSName(u'_kerberos._udp'), 88),
+    (DNSName(u'_kerberos-master._tcp'), 88),
+    (DNSName(u'_kerberos-master._udp'), 88),
+    (DNSName(u'_kpasswd._tcp'), 464),
+    (DNSName(u'_kpasswd._udp'), 464),
+)
+
+
+def resolve_records_from_server(rname, rtype, nameserver, logger):
+    res = dns.resolver.Resolver()
+    res.nameservers = [nameserver]
+    res.lifetime = 10
+    logger.debug("Query: %s %s, nameserver %s", rname, rtype, nameserver)
+    ans = res.query(rname, rtype)
+    logger.debug("Answer: %s", ans.rrset)
+    return ans.rrset
+
+
+def _gen_expected_srv_rrset(rname, port, servers, ttl=86400):
+    rdata_list = [
+        "{prio} {weight} {port} {servername}".format(
+            prio=prio,
+            weight=weight,
+            port=port,
+            servername=servername.make_absolute()
+        )
+        for prio, weight, servername in servers
+    ]
+    return dns.rrset.from_text_list(
+        rname, ttl, dns.rdataclass.IN, dns.rdatatype.SRV, rdata_list
+    )
+
+
+class TestDNSLocations(IntegrationTest):
+    """Simple test if SRV DNS records for IPA locations are generated properly
+
+    Topology:
+        * 3 servers (replica0 --- master --- replica1)
+        * 2 locations (prague, paris)
+    """
+    num_replicas = 2
+    topology = 'star'
+
+    LOC_PRAGUE = u'prague'
+    LOC_PARIS = u'paris'
+
+    PRIO_HIGH = 0
+    PRIO_LOW = 50
+    WEIGHT = 100
+
+    @classmethod
+    def install(cls, mh):
+        tasks.install_master(cls.master, setup_dns=True)
+        tasks.install_replica(cls.master, cls.replicas[0], setup_dns=True,
+                              setup_ca=False)
+        tasks.install_replica(cls.master, cls.replicas[1], setup_dns=True,
+                              setup_ca=False)
+
+        for host in (cls.master, cls.replicas[0], cls.replicas[1]):
+            ldap = host.ldap_connect()
+            tasks.wait_for_replication(ldap)
+
+        # give time to named to retrieve new records
+        time.sleep(20)
+
+    def _test_against_server(self, server_ip, domain, expected_servers):
+        for rname, port in IPA_DEFAULT_MASTER_SRV_REC:
+            name_abs = rname.derelativize(domain)
+            expected = _gen_expected_srv_rrset(
+                name_abs, port, expected_servers)
+            query = resolve_records_from_server(
+                name_abs, 'SRV', server_ip, self.log)
+            assert expected == query, (
+                "Expected and received DNS data do not match on server "
+                "with IP: '{}' for name '{}' (expected:\n{}\ngot:\n{})".format(
+                    server_ip, name_abs, expected, query))
+
+    def test_without_locations(self):
+        """Servers are not in locations, this tests if basic system records
+        are generated properly"""
+        domain = DNSName(self.master.domain.name).make_absolute()
+        expected_servers = (
+            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.master.hostname)),
+            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[0].hostname)),
+            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[1].hostname)),
+        )
+        for ip in (self.master.ip, self.replicas[0].ip, self.replicas[1].ip):
+            self._test_against_server(ip, domain, expected_servers)
+
+    def test_one_replica_in_location(self):
+        """Put one replica to location and test if records changed properly
+        """
+
+        # create location prague, replica0 --> location prague
+        self.master.run_command([
+            'ipa', 'location-add', self.LOC_PRAGUE
+        ])
+        self.master.run_command([
+            'ipa', 'server-mod', self.replicas[0].hostname,
+            '--location', self.LOC_PRAGUE
+        ])
+        tasks.restart_named(self.replicas[0])
+
+        servers_without_loc = (
+            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.master.hostname)),
+            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[0].hostname)),
+            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[1].hostname)),
+        )
+        domain_without_loc = DNSName(self.master.domain.name).make_absolute()
+
+        servers_prague_loc = (
+            (self.PRIO_LOW, self.WEIGHT, DNSName(self.master.hostname)),
+            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[0].hostname)),
+            (self.PRIO_LOW, self.WEIGHT, DNSName(self.replicas[1].hostname)),
+        )
+        domain_prague_loc = (
+            DNSName('{}._locations'.format(self.LOC_PRAGUE)) +
+            DNSName(self.master.domain.name).make_absolute()
+        )
+
+        self._test_against_server(
+            self.replicas[0].ip, domain_prague_loc, servers_prague_loc)
+
+        for ip in (self.master.ip, self.replicas[1].ip):
+            self._test_against_server(
+                ip, domain_without_loc, servers_without_loc)
+
+    def test_two_replicas_in_location(self):
+        """Put second replica to location and test if records changed properly
+        """
+
+        # create location paris, replica1 --> location prague
+        self.master.run_command(['ipa', 'location-add', self.LOC_PARIS])
+        self.master.run_command([
+            'ipa', 'server-mod', self.replicas[1].hostname, '--location',
+            self.LOC_PARIS])
+        tasks.restart_named(self.replicas[1])
+
+        servers_without_loc = (
+            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.master.hostname)),
+            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[0].hostname)),
+            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[1].hostname)),
+        )
+        domain_without_loc = DNSName(self.master.domain.name).make_absolute()
+
+        servers_prague_loc = (
+            (self.PRIO_LOW, self.WEIGHT, DNSName(self.master.hostname)),
+            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[0].hostname)),
+            (self.PRIO_LOW, self.WEIGHT, DNSName(self.replicas[1].hostname)),
+        )
+        domain_prague_loc = (
+            DNSName('{}._locations'.format(self.LOC_PRAGUE)) + DNSName(
+                self.master.domain.name).make_absolute())
+
+        servers_paris_loc = (
+            (self.PRIO_LOW, self.WEIGHT, DNSName(self.master.hostname)),
+            (self.PRIO_LOW, self.WEIGHT, DNSName(self.replicas[0].hostname)),
+            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[1].hostname)),
+        )
+        domain_paris_loc = (
+            DNSName('{}._locations'.format(self.LOC_PARIS)) + DNSName(
+                self.master.domain.name).make_absolute())
+
+        self._test_against_server(
+            self.replicas[0].ip, domain_prague_loc, servers_prague_loc)
+
+        self._test_against_server(
+            self.replicas[1].ip, domain_paris_loc, servers_paris_loc)
+
+        self._test_against_server(
+            self.master.ip, domain_without_loc, servers_without_loc)
+
+    def test_all_servers_in_location(self):
+        """Put master (as second server) to location and test if records
+        changed properly
+        """
+
+        # master --> location paris
+        self.master.run_command([
+            'ipa', 'server-mod', self.master.hostname, '--location',
+            self.LOC_PARIS])
+        tasks.restart_named(self.master)
+
+        servers_prague_loc = (
+            (self.PRIO_LOW, self.WEIGHT, DNSName(self.master.hostname)),
+            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[0].hostname)),
+            (self.PRIO_LOW, self.WEIGHT, DNSName(self.replicas[1].hostname)),
+        )
+        domain_prague_loc = (
+            DNSName('{}._locations'.format(self.LOC_PRAGUE)) + DNSName(
+                self.master.domain.name).make_absolute())
+
+        servers_paris_loc = (
+            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.master.hostname)),
+            (self.PRIO_LOW, self.WEIGHT, DNSName(self.replicas[0].hostname)),
+            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[1].hostname)),
+        )
+        domain_paris_loc = (
+            DNSName('{}._locations'.format(self.LOC_PARIS)) + DNSName(
+                self.master.domain.name).make_absolute())
+
+        self._test_against_server(
+            self.replicas[0].ip, domain_prague_loc, servers_prague_loc)
+
+        for ip in (self.replicas[1].ip, self.master.ip):
+            self._test_against_server(ip, domain_paris_loc, servers_paris_loc)
+
+    def test_change_weight(self):
+        """Change weight of master and test if records changed properly
+        """
+
+        new_weight = 2000
+
+        self.master.run_command([
+            'ipa', 'server-mod', self.master.hostname, '--service-weight',
+            str(new_weight)
+        ])
+
+        # all servers must be restarted
+        tasks.restart_named(self.master, self.replicas[0], self.replicas[1])
+
+        servers_prague_loc = (
+            (self.PRIO_LOW, new_weight, DNSName(self.master.hostname)),
+            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[0].hostname)),
+            (self.PRIO_LOW, self.WEIGHT, DNSName(self.replicas[1].hostname)),
+        )
+        domain_prague_loc = (
+            DNSName('{}._locations'.format(self.LOC_PRAGUE)) + DNSName(
+                self.master.domain.name).make_absolute())
+
+        servers_paris_loc = (
+            (self.PRIO_HIGH, new_weight, DNSName(self.master.hostname)),
+            (self.PRIO_LOW, self.WEIGHT, DNSName(self.replicas[0].hostname)),
+            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[1].hostname)),
+        )
+        domain_paris_loc = (
+            DNSName('{}._locations'.format(self.LOC_PARIS)) + DNSName(
+                self.master.domain.name).make_absolute())
+
+        self._test_against_server(
+            self.replicas[0].ip, domain_prague_loc, servers_prague_loc)
+
+        for ip in (self.replicas[1].ip, self.master.ip):
+            self._test_against_server(ip, domain_paris_loc, servers_paris_loc)
diff --git a/ipatests/test_integration/test_dnssec.py b/ipatests/test_integration/test_dnssec.py
index 554e96c638fcac03379ed17cbc4d9ac1311ab7ea..56380dda811f7f4921393dc9b5cc21d0a910fa8b 100644
--- a/ipatests/test_integration/test_dnssec.py
+++ b/ipatests/test_integration/test_dnssec.py
@@ -72,14 +72,6 @@ def wait_until_record_is_signed(nameserver, record, log, rtype="SOA",
     return False
 
 
-def restart_named(*args):
-        # A workaround for ticket N 5348
-        time.sleep(20)  # wait till dnssec key is exported to named
-        for host in args:
-            host.run_command(["systemctl", "restart",
-                              "named-pkcs11.service"])
-
-
 class TestInstallDNSSECLast(IntegrationTest):
     """Simple DNSSEC test
 
@@ -114,7 +106,7 @@ class TestInstallDNSSECLast(IntegrationTest):
         ]
         self.master.run_command(args)
 
-        restart_named(self.master, self.replicas[0])
+        tasks.restart_named(self.master, self.replicas[0])
         # test master
         assert wait_until_record_is_signed(
             self.master.ip, test_zone, self.log, timeout=100
@@ -135,7 +127,7 @@ class TestInstallDNSSECLast(IntegrationTest):
         ]
         self.replicas[0].run_command(args)
 
-        restart_named(self.replicas[0])
+        tasks.restart_named(self.replicas[0])
         # test replica
         assert wait_until_record_is_signed(
             self.replicas[0].ip, test_zone_repl, self.log, timeout=300
@@ -181,7 +173,7 @@ class TestInstallDNSSECLast(IntegrationTest):
         ]
         self.master.run_command(args)
 
-        restart_named(self.master)
+        tasks.restart_named(self.master)
         # test master
         assert wait_until_record_is_signed(
             self.master.ip, test_zone, self.log, timeout=100
@@ -229,7 +221,7 @@ class TestInstallDNSSECLast(IntegrationTest):
         ]
         self.master.run_command(args)
 
-        restart_named(self.master, self.replicas[0])
+        tasks.restart_named(self.master, self.replicas[0])
 
         # test master
         assert wait_until_record_is_signed(
@@ -375,7 +367,7 @@ class TestInstallDNSSECFirst(IntegrationTest):
             "--ns-rec=" + self.master.hostname
         ]
         self.master.run_command(args)
-        restart_named(self.master, self.replicas[0])
+        tasks.restart_named(self.master, self.replicas[0])
         # test master
         assert wait_until_record_is_signed(
             self.master.ip, root_zone, self.log, timeout=100
@@ -406,7 +398,7 @@ class TestInstallDNSSECFirst(IntegrationTest):
             "--ns-rec=" + self.master.hostname
         ]
         self.master.run_command(args)
-        restart_named(self.master, self.replicas[0])
+        tasks.restart_named(self.master, self.replicas[0])
         # wait until zone is signed
         assert wait_until_record_is_signed(
             self.master.ip, example_test_zone, self.log, timeout=100
@@ -544,7 +536,7 @@ class TestMigrateDNSSECMaster(IntegrationTest):
 
         self.master.run_command(args)
 
-        restart_named(self.master, self.replicas[0])
+        tasks.restart_named(self.master, self.replicas[0])
         # wait until zone is signed
         assert wait_until_record_is_signed(
             self.master.ip, example_test_zone, self.log, timeout=100
@@ -601,7 +593,7 @@ class TestMigrateDNSSECMaster(IntegrationTest):
             "--skip-overlap-check",
         ]
         self.replicas[0].run_command(args)
-        restart_named(self.master, self.replicas[0])
+        tasks.restart_named(self.master, self.replicas[0])
         # wait until zone is signed
         assert wait_until_record_is_signed(
             self.replicas[0].ip, example2_test_zone, self.log, timeout=100
@@ -634,7 +626,7 @@ class TestMigrateDNSSECMaster(IntegrationTest):
             "--skip-overlap-check",
         ]
         self.replicas[1].run_command(args)
-        restart_named(self.replicas[0], self.replicas[1])
+        tasks.restart_named(self.replicas[0], self.replicas[1])
         # wait until zone is signed
         assert wait_until_record_is_signed(
             self.replicas[1].ip, example3_test_zone, self.log, timeout=200
-- 
2.5.5

-- 
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