From 4aa6ef3cdf95e3a3ad5aa01e8bcfeb684f3adb13 Mon Sep 17 00:00:00 2001 From: Frank Brehm Date: Mon, 30 Nov 2020 17:00:16 +0100 Subject: [PATCH] Ignoring group entires on the first attempt --- lib/ldap_migration/__init__.py | 75 +++++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 14 deletions(-) diff --git a/lib/ldap_migration/__init__.py b/lib/ldap_migration/__init__.py index 2071011..b4726b5 100644 --- a/lib/ldap_migration/__init__.py +++ b/lib/ldap_migration/__init__.py @@ -45,7 +45,7 @@ from .config import LDAPMigrationConfiguration from .idict import CaseInsensitiveDict from .istringset import CaseInsensitiveStringSet -__version__ = '0.8.1' +__version__ = '0.8.2' LOG = logging.getLogger(__name__) CFG_BASENAME = 'ldap-migration.ini' @@ -209,6 +209,7 @@ class LDAPMigrationApplication(BaseApplication): self.struct_dns = CaseInsensitiveDict() self.migrated_entries = CaseInsensitiveDict() self.integer_attribute_types = CaseInsensitiveStringSet([]) + self.group_entries = CaseInsensitiveDict() super(LDAPMigrationApplication, self).__init__( appname=appname, verbose=verbose, version=version, base_dir=base_dir, @@ -263,6 +264,7 @@ class LDAPMigrationApplication(BaseApplication): res['only_struct'] = self.only_struct res['dns'] = self.dns.as_dict(short=short) res['struct_dns'] = self.struct_dns.as_dict(short=short) + res['group_entries'] = self.group_entries.as_dict(short=short) res['integer_attribute_types'] = self.integer_attribute_types.as_list() return res @@ -1053,7 +1055,8 @@ class LDAPMigrationApplication(BaseApplication): try: self._migrate_entries( - self.struct_dns, fh=fh, force=False, is_root=True, with_acl=False) + self.struct_dns, fh=fh, force=False, is_root=True, + with_group_entries=True, with_acl=False) except (ReadLDAPItemError, WriteLDAPItemError) as e: msg = "Abort migration: " + str(e) LOG.error(msg) @@ -1074,12 +1077,12 @@ class LDAPMigrationApplication(BaseApplication): def migrate_all_entries(self, fh): print() - LOG.info("Migrating all entries from source to target LDAP cluster.") + LOG.info("Migrating all entries without group entries from source to target LDAP cluster.") print("", file=fh, flush=True) - print("#############", file=fh, flush=True) - print("# All entries", file=fh, flush=True) - print("#############", file=fh, flush=True) + print("#######################", file=fh, flush=True) + print("# All non group entries", file=fh, flush=True) + print("#######################", file=fh, flush=True) self.count_unchanged = 0 self.count_added = 0 @@ -1087,20 +1090,33 @@ class LDAPMigrationApplication(BaseApplication): try: self._migrate_entries( - self.dns, fh=fh, force=False, is_root=True, with_acl=False) + self.dns, fh=fh, force=False, is_root=True, + with_group_entries=False, with_acl=False) except (ReadLDAPItemError, WriteLDAPItemError) as e: msg = "Abort migration: " + str(e) LOG.error(msg) return False print() - total = self.count_unchanged + self.count_added + self.count_modified + count_groups = 0 + if self.group_entries: + count_groups = len(self.group_entries) + if count_groups == 1: + msg = "The following entry is a group entry:" + else: + msg = "The following {} entries are group entries:".format(count_groups) + msg += "\n" + '\n'.join(map(lambda x: ' * {!r}'.format(x), self.group_entries.keys())) + LOG.info(msg) + + print() + total = self.count_unchanged + self.count_added + self.count_modified + count_groups msg = ( "Performed all entries: {to} total, {ad} added, {mo} modified, " - "{un} unchanged.").format( + "{un} unchanged, {g} ignored groups.").format( to=total, ad=self.count_added, mo=self.count_modified, - un=self.count_unchanged) + un=self.count_unchanged, g=count_groups) LOG.info(msg) + time.sleep(3) return True @@ -1225,23 +1241,30 @@ class LDAPMigrationApplication(BaseApplication): return None # ------------------------------------------------------------------------- - def _migrate_entries(self, cur_hash, fh, force=False, is_root=False, with_acl=False): + def _migrate_entries( + self, cur_hash, fh, force=False, is_root=False, + with_group_entries=True, with_acl=False): wait = self.config.wait_after_write if not is_root: src_dn = cur_hash['dn'] - if self.migrate_entry(src_dn, fh=fh, force=force, with_acl=with_acl): + if self.migrate_entry( + src_dn, fh=fh, force=force, with_acl=with_acl, + migrate_if_group=with_group_entries): if wait: time.sleep(wait) for key in cur_hash['childs'].keys(): self._migrate_entries( - cur_hash['childs'][key], fh=fh, force=force, is_root=False, with_acl=with_acl) + cur_hash['childs'][key], fh=fh, force=force, is_root=False, + with_group_entries=with_group_entries, with_acl=with_acl) # ------------------------------------------------------------------------- - def migrate_entry(self, src_dn, fh, force=False, with_acl=False): + def migrate_entry( + self, src_dn, fh, force=False, with_acl=False, + migrate_if_group=True): tgt_dn = self.mangle_dn(src_dn) rev_dn = self.get_reverse_dn(tgt_dn) @@ -1254,6 +1277,30 @@ class LDAPMigrationApplication(BaseApplication): return False src_entry = self.get_source_item(src_dn, tgt_dn, with_acl=with_acl) + if not migrate_if_group: + + object_classes = CaseInsensitiveStringSet([]) + for src_at_name in src_entry['attributes']: + if src_at_name.lower() == 'objectclass': + for src_oc_name in src_entry['attributes'][src_at_name]: + object_classes.add(src_oc_name) + is_group = False + if 'groupOfURLs' in object_classes: + is_group = True + elif 'groupOfNames' in object_classes: + is_group = True + elif 'groupOfUniqueNames' in object_classes: + is_group = True + + if is_group: + self.group_entries[tgt_dn] = { + 'migrated': False, + 'object_classes': object_classes, + } + LOG.debug("Entry {e!r} is a group entry: {c}".format( + e=tgt_dn, c=object_classes.as_list())) + return False + tgt_entry = self.get_target_item(tgt_dn, with_acl=with_acl) if tgt_entry: -- 2.39.5