From 4c9fbee618f98455004d982a3dc6a73597da52d9 Mon Sep 17 00:00:00 2001 From: Lukas Oyen Date: Tue, 19 Sep 2017 16:41:17 +0200 Subject: [PATCH 1/4] Bug #39060: s4c: fix duplicate dns objects --- .../modules/univention/s4connector/s4/__init__.py | 1 + .../modules/univention/s4connector/s4/dns.py | 31 +++++++++++----------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/services/univention-s4-connector/modules/univention/s4connector/s4/__init__.py b/services/univention-s4-connector/modules/univention/s4connector/s4/__init__.py index 8f01992..b83e352 100644 --- a/services/univention-s4-connector/modules/univention/s4connector/s4/__init__.py +++ b/services/univention-s4-connector/modules/univention/s4connector/s4/__init__.py @@ -2418,6 +2418,7 @@ class s4(univention.s4connector.ucs): if hasattr(self.property[property_type], 'dn_mapping_function'): tmp_object = copy.deepcopy(object) tmp_object['dn'] = old_dn + del tmp_object['olddn'] for function in self.property[property_type].dn_mapping_function: tmp_object = function(self, tmp_object, [], isUCSobject=True) old_dn = tmp_object['dn'] diff --git a/services/univention-s4-connector/modules/univention/s4connector/s4/dns.py b/services/univention-s4-connector/modules/univention/s4connector/s4/dns.py index 39d1d07..cc667ca 100644 --- a/services/univention-s4-connector/modules/univention/s4connector/s4/dns.py +++ b/services/univention-s4-connector/modules/univention/s4connector/s4/dns.py @@ -167,18 +167,24 @@ def dns_dn_mapping(s4connector, given_object, dn_mapping_stored, isUCSobject): exploded_dn = ldap.dn.str2dn(unicode_to_utf8(dn)) (fst_rdn_attribute_utf8, fst_rdn_value_utf8, _flags) = exploded_dn[0][0] + attributes_from_dn = {attr: value for rdn in exploded_dn + for (attr, value, _flags) in rdn} + if isUCSobject: ud.debug(ud.LDAP, ud.INFO, "dns_dn_mapping: got an UCS-Object") # lookup the relativeDomainName as DC/dnsNode in S4 to get corresponding DN, if not found create new try: - relativeDomainName = obj['attributes'][ol_RR_attr][0] - except (KeyError, IndexError): - # Safety fallback for the unexpected case, where relativeDomainName would not be set - if 'zoneName' == fst_rdn_attribute_utf8: - relativeDomainName = '@' - else: - raise # can't determine relativeDomainName + relativeDomainName = attributes_from_dn[ol_RR_attr] + except KeyError: + try: + relativeDomainName = obj['attributes'][ol_RR_attr][0] + except (KeyError, IndexError): + # Safety fallback for the unexpected case, where relativeDomainName would not be set + if 'zoneName' == fst_rdn_attribute_utf8: + relativeDomainName = '@' + else: + raise # can't determine relativeDomainName if s4connector.property[propertyname].mapping_table and propertyattrib in s4connector.property[propertyname].mapping_table.keys(): for ucsval, conval in s4connector.property[propertyname].mapping_table[propertyattrib]: @@ -191,15 +197,10 @@ def dns_dn_mapping(s4connector, given_object, dn_mapping_stored, isUCSobject): pass # values are not the same codec try: + ol_zone_name = attributes_from_dn['zoneName'] + except KeyError: + # let exceptions pass through, we have no other fallback ol_zone_name = obj['attributes']['zoneName'][0] - except (KeyError, IndexError): - # Safety fallback for the unexpected case, where zoneName would not be set - if ol_RR_attr == fst_rdn_attribute_utf8: - (snd_rdn_attribute_utf8, snd_rdn_value_utf8, _flags) = exploded_dn[1][0] - if 'zoneName' == snd_rdn_attribute_utf8: - ol_zone_name = snd_rdn_value_utf8 - else: - raise # can't determine zoneName for this relativeDomainName target_RR_val = relativeDomainName target_zone_name = ol_zone_name -- 2.7.4 From 4049552fa7e425a9205b1d40e94b0f7a2c1df070 Mon Sep 17 00:00:00 2001 From: Lukas Oyen Date: Tue, 19 Sep 2017 16:42:35 +0200 Subject: [PATCH 2/4] Bug #39060: s4c-test: add `s4c_dns` tag to dns tests --- test/ucs-test/tests/52_s4connector/175sync_create_dns_a_record | 2 ++ test/ucs-test/tests/52_s4connector/175sync_create_dns_aaaa_record | 2 ++ test/ucs-test/tests/52_s4connector/175sync_create_dns_alias | 2 ++ .../tests/52_s4connector/175sync_create_dns_msdcs_record_con2ucs | 2 ++ .../tests/52_s4connector/175sync_create_dns_msdcs_record_ucs2con | 2 ++ test/ucs-test/tests/52_s4connector/175sync_create_dns_pointer_record | 2 ++ test/ucs-test/tests/52_s4connector/175sync_create_dns_serial | 2 ++ test/ucs-test/tests/52_s4connector/175sync_create_dns_service_record | 2 ++ test/ucs-test/tests/52_s4connector/175sync_create_dns_ttl | 2 ++ test/ucs-test/tests/52_s4connector/175sync_create_dns_txt | 2 ++ test/ucs-test/tests/52_s4connector/175sync_create_dns_wildcard_host | 2 ++ 11 files changed, 22 insertions(+) diff --git a/test/ucs-test/tests/52_s4connector/175sync_create_dns_a_record b/test/ucs-test/tests/52_s4connector/175sync_create_dns_a_record index 32feeb7..04b1659 100755 --- a/test/ucs-test/tests/52_s4connector/175sync_create_dns_a_record +++ b/test/ucs-test/tests/52_s4connector/175sync_create_dns_a_record @@ -6,6 +6,8 @@ ## - univention-directory-manager-tools ## - univention-s4-connector ## - dnsutils +## tags: +## - s4c_dns import univention.testing.udm as udm_test from univention.testing.utils import fail, wait_for_replication_and_postrun diff --git a/test/ucs-test/tests/52_s4connector/175sync_create_dns_aaaa_record b/test/ucs-test/tests/52_s4connector/175sync_create_dns_aaaa_record index 04eba53..af9d250 100755 --- a/test/ucs-test/tests/52_s4connector/175sync_create_dns_aaaa_record +++ b/test/ucs-test/tests/52_s4connector/175sync_create_dns_aaaa_record @@ -6,6 +6,8 @@ ## - univention-directory-manager-tools ## - univention-s4-connector ## - dnsutils +## tags: +## - s4c_dns import univention.testing.udm as udm_test from univention.testing.utils import fail, wait_for_replication_and_postrun diff --git a/test/ucs-test/tests/52_s4connector/175sync_create_dns_alias b/test/ucs-test/tests/52_s4connector/175sync_create_dns_alias index bd88819..d34ca3a 100755 --- a/test/ucs-test/tests/52_s4connector/175sync_create_dns_alias +++ b/test/ucs-test/tests/52_s4connector/175sync_create_dns_alias @@ -6,6 +6,8 @@ ## - univention-directory-manager-tools ## - univention-s4-connector ## - dnsutils +## tags: +## - s4c_dns import univention.testing.strings as uts import univention.testing.udm as udm_test diff --git a/test/ucs-test/tests/52_s4connector/175sync_create_dns_msdcs_record_con2ucs b/test/ucs-test/tests/52_s4connector/175sync_create_dns_msdcs_record_con2ucs index 52f1b98..4b6c3b0 100755 --- a/test/ucs-test/tests/52_s4connector/175sync_create_dns_msdcs_record_con2ucs +++ b/test/ucs-test/tests/52_s4connector/175sync_create_dns_msdcs_record_con2ucs @@ -6,6 +6,8 @@ ## - univention-directory-manager-tools ## - univention-s4-connector ## - dnsutils +## tags: +## - s4c_dns import univention.testing.strings as uts import univention.testing.udm as udm_test diff --git a/test/ucs-test/tests/52_s4connector/175sync_create_dns_msdcs_record_ucs2con b/test/ucs-test/tests/52_s4connector/175sync_create_dns_msdcs_record_ucs2con index 619aaad..0f870a7 100755 --- a/test/ucs-test/tests/52_s4connector/175sync_create_dns_msdcs_record_ucs2con +++ b/test/ucs-test/tests/52_s4connector/175sync_create_dns_msdcs_record_ucs2con @@ -6,6 +6,8 @@ ## - univention-directory-manager-tools ## - univention-s4-connector ## - dnsutils +## tags: +## - s4c_dns import univention.testing.strings as uts import univention.testing.utils as utils diff --git a/test/ucs-test/tests/52_s4connector/175sync_create_dns_pointer_record b/test/ucs-test/tests/52_s4connector/175sync_create_dns_pointer_record index cd163fe..a5a0868 100755 --- a/test/ucs-test/tests/52_s4connector/175sync_create_dns_pointer_record +++ b/test/ucs-test/tests/52_s4connector/175sync_create_dns_pointer_record @@ -6,6 +6,8 @@ ## - univention-directory-manager-tools ## - univention-s4-connector ## - dnsutils +## tags: +## - s4c_dns import univention.testing.udm as udm_test import univention.testing.utils as utils diff --git a/test/ucs-test/tests/52_s4connector/175sync_create_dns_serial b/test/ucs-test/tests/52_s4connector/175sync_create_dns_serial index 5493889..63cac63 100755 --- a/test/ucs-test/tests/52_s4connector/175sync_create_dns_serial +++ b/test/ucs-test/tests/52_s4connector/175sync_create_dns_serial @@ -8,6 +8,8 @@ ## - dnsutils ## bugs: ## - 32156 +## tags: +## - s4c_dns import univention.testing.udm as udm_test import univention.testing.utils as utils diff --git a/test/ucs-test/tests/52_s4connector/175sync_create_dns_service_record b/test/ucs-test/tests/52_s4connector/175sync_create_dns_service_record index 4132406..89a14a3 100755 --- a/test/ucs-test/tests/52_s4connector/175sync_create_dns_service_record +++ b/test/ucs-test/tests/52_s4connector/175sync_create_dns_service_record @@ -6,6 +6,8 @@ ## - univention-directory-manager-tools ## - univention-s4-connector ## - dnsutils +## tags: +## - s4c_dns import univention.testing.udm as udm_test import univention.testing.utils as utils diff --git a/test/ucs-test/tests/52_s4connector/175sync_create_dns_ttl b/test/ucs-test/tests/52_s4connector/175sync_create_dns_ttl index 36ba393..ced86e6 100755 --- a/test/ucs-test/tests/52_s4connector/175sync_create_dns_ttl +++ b/test/ucs-test/tests/52_s4connector/175sync_create_dns_ttl @@ -10,6 +10,8 @@ ## - 23732 ## versions: ## 3.2-0: skip +## tags: +## - s4c_dns import univention.testing.udm as udm_test diff --git a/test/ucs-test/tests/52_s4connector/175sync_create_dns_txt b/test/ucs-test/tests/52_s4connector/175sync_create_dns_txt index 86dd3e5..6c9fcb2 100755 --- a/test/ucs-test/tests/52_s4connector/175sync_create_dns_txt +++ b/test/ucs-test/tests/52_s4connector/175sync_create_dns_txt @@ -8,6 +8,8 @@ ## - dnsutils ## versions: ## 3.2-0: skip +## tags: +## - s4c_dns import univention.testing.udm as udm_test import univention.testing.utils as utils diff --git a/test/ucs-test/tests/52_s4connector/175sync_create_dns_wildcard_host b/test/ucs-test/tests/52_s4connector/175sync_create_dns_wildcard_host index 6271ad3..23daae7 100755 --- a/test/ucs-test/tests/52_s4connector/175sync_create_dns_wildcard_host +++ b/test/ucs-test/tests/52_s4connector/175sync_create_dns_wildcard_host @@ -6,6 +6,8 @@ ## - univention-directory-manager-tools ## - univention-s4-connector ## - dnsutils +## tags: +## - s4c_dns import univention.testing.udm as udm_test import dnstests -- 2.7.4 From 8b11a8fc3fdcea070b94136976a310a57012ec34 Mon Sep 17 00:00:00 2001 From: Lukas Oyen Date: Mon, 18 Sep 2017 16:42:09 +0200 Subject: [PATCH 3/4] Bug #39060: s4c-test: add 503_test_dns_rename.py --- .../tests/52_s4connector/503_test_dns_rename.py | 70 ++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100755 test/ucs-test/tests/52_s4connector/503_test_dns_rename.py diff --git a/test/ucs-test/tests/52_s4connector/503_test_dns_rename.py b/test/ucs-test/tests/52_s4connector/503_test_dns_rename.py new file mode 100755 index 0000000..13e52ae --- /dev/null +++ b/test/ucs-test/tests/52_s4connector/503_test_dns_rename.py @@ -0,0 +1,70 @@ +#!/usr/share/ucs-test/runner /usr/bin/py.test -s +# coding: utf-8 +## desc: "Test the UCS<->AD sync in {read,write,sync} mode for dns objects." +## exposure: dangerous +## packages: +## - univention-s4-connector +## bugs: +## - 39060 +## tags: +## - s4c_dns + +import ldap +import pytest + +from univention.testing.udm import UCSTestUDM +import univention.testing.connector_common as tcommon +import univention.testing.strings as tstring + +import s4connector +from s4connector import (connector_running_on_this_host, connector_setup) +import dnstests + + +def build_s4_host_dn(host, zone, domain): + first = [ + [("DC", host, ldap.AVA_STRING)], + [("DC", zone, ldap.AVA_STRING)], + [("CN", "MicrosoftDNS", ldap.AVA_STRING)], + [("DC", "DomainDnsZones", ldap.AVA_STRING)], + ] + return ldap.dn.dn2str(first + ldap.dn.str2dn(domain)) + + +@pytest.mark.parametrize("sync_mode", ["write", "sync"]) +@pytest.mark.skipif(not connector_running_on_this_host(), + reason="Univention S4 Connector not configured.") +def test_attribute_sync_from_udm_to_s4(sync_mode): + with connector_setup(sync_mode) as s4, UCSTestUDM() as udm: + base = dnstests.ucr.get('ldap/base') + ip = dnstests.make_random_ip() + random_zone = dnstests.random_zone() + random_host_a = tstring.random_name() + random_host_b = tstring.random_name() + nameserver = dnstests.get_hostname_of_ldap_master() + + print 'Creating objects..\n' + zone_dn = udm.create_object('dns/forward_zone', zone=random_zone, nameserver=nameserver) + host_dn = udm.create_object('dns/host_record', name=random_host_a, a=ip, superordinate=zone_dn) + s4connector.wait_for_sync() + s4_host_dn = build_s4_host_dn(random_host_a, random_zone, base) + s4.verify_object(s4_host_dn, {"name": random_host_a, "dc": random_host_a}) + tcommon.verify_udm_object("dns/host_record", host_dn, {"name": random_host_a, "a": ip}) + + print 'Modifying host record..\n' + new_host_dn = udm.modify_object('dns/host_record', dn=host_dn, name=random_host_b) + + s4connector.wait_for_sync() + s4_new_host_dn = build_s4_host_dn(random_host_b, random_zone, base) + s4.verify_object(s4_host_dn, None) + tcommon.verify_udm_object("dns/host_record", host_dn, None) + s4.verify_object(s4_new_host_dn, {"name": random_host_b, "dc": random_host_b}) + tcommon.verify_udm_object("dns/host_record", new_host_dn, {"name": random_host_b, "a": ip}) + + print 'Cleaning up..\n' + udm.remove_object('dns/host_record', dn=new_host_dn) + udm.remove_object('dns/forward_zone', dn=zone_dn) + + s4connector.wait_for_sync() + s4.verify_object(s4_new_host_dn, None) + tcommon.verify_udm_object("dns/host_record", new_host_dn, None) -- 2.7.4 From b1ca251a6e14dbc551e599743b56cee8224e168c Mon Sep 17 00:00:00 2001 From: Lukas Oyen Date: Mon, 18 Sep 2017 16:42:42 +0200 Subject: [PATCH 4/4] Bug #39060: s4c-test: workarround bug #41694 for 503_test_dns_rename.py --- test/ucs-test/tests/52_s4connector/503_test_dns_rename.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/ucs-test/tests/52_s4connector/503_test_dns_rename.py b/test/ucs-test/tests/52_s4connector/503_test_dns_rename.py index 13e52ae..2734d4b 100755 --- a/test/ucs-test/tests/52_s4connector/503_test_dns_rename.py +++ b/test/ucs-test/tests/52_s4connector/503_test_dns_rename.py @@ -53,6 +53,14 @@ def test_attribute_sync_from_udm_to_s4(sync_mode): print 'Modifying host record..\n' new_host_dn = udm.modify_object('dns/host_record', dn=host_dn, name=random_host_b) + # XXX after a modify, the old DN is _wrongly_ returned: see bug #41694 + if new_host_dn == host_dn: + new_host_dn = ldap.dn.dn2str([[("relativeDomainName", random_host_b, ldap.AVA_STRING)]] + + ldap.dn.str2dn(host_dn)[1:]) + if host_dn in udm._cleanup.get('dns/host_record', []): + udm._cleanup.setdefault('dns/host_record', []).append(new_host_dn) + udm._cleanup['dns/host_record'].remove(host_dn) + # XXX end of workarround for bug #41694 s4connector.wait_for_sync() s4_new_host_dn = build_s4_host_dn(random_host_b, random_zone, base) -- 2.7.4