From: Frank Brehm Date: Fri, 29 Oct 2021 14:23:47 +0000 (+0200) Subject: Many Bugfixes, Finishing update of groups. X-Git-Url: https://git.uhu-banane.org/?a=commitdiff_plain;h=d970c6e237c09f7cf60e3c973eef1517c5d39191;p=pixelpark%2Fldap-migration.git Many Bugfixes, Finishing update of groups. --- diff --git a/lib/ldap_migration/__init__.py b/lib/ldap_migration/__init__.py index 34ec6b0..442a0c6 100644 --- a/lib/ldap_migration/__init__.py +++ b/lib/ldap_migration/__init__.py @@ -48,7 +48,7 @@ from fb_tools.collections import FrozenCIStringSet, CIStringSet, CIDict from .config import LDAPMigrationConfiguration -__version__ = '0.11.2' +__version__ = '0.12.0' LOG = logging.getLogger(__name__) CFG_BASENAME = 'ldap-migration.ini' @@ -1390,6 +1390,8 @@ class LDAPMigrationApplication(BaseApplication): if not self.migrate_all_entries(fh): return False + self.migrate_group_entries(fh) + print() return True @@ -1900,7 +1902,7 @@ class LDAPMigrationApplication(BaseApplication): return False # ------------------------------------------------------------------------- - def migrate_group_entries(self): + def migrate_group_entries(self, fh): print() LOG.info("Next lap - migration af all group entries ...") @@ -1917,24 +1919,29 @@ class LDAPMigrationApplication(BaseApplication): for tgt_dn in self.group_entries: - if self.migrate_group_entry(tgt_dn): + src_dn = self.group_entries[tgt_dn]['src_dn'] + migrated = False + try: + if self.migrate_group_entry(tgt_dn, fh): + migrated = True + LOG.debug("Group entry {src!r} -> {tgt!r} successful migrated.".format( + src=src_dn, tgt=tgt_dn)) + + except GroupEntryNotMigratableError as e: + msg = ("Group entry {src!r} -> {tgt!r} could not migrated " + "in lap {lap}.").format(src=src_dn, tgt=tgt_dn, lap=lap) + LOG.error(msg) + continue - src_dn = self.group_entries[tgt_dn]['src_dn'] - migrated_dns.add(tgt_dn) - self.group_entries[tgt_dn]['migrated'] = True - self.migrated_group_entries[tgt_dn] = { - 'migrated_at': datetime.datetime.now(), - 'src_dn': src_dn, - 'object_classes': self.group_entries[tgt_dn]['object_classes'], - } - LOG.info("Group entry {src!r} -> {tgt!r} successful migrated.".format( - src=src_dn, tgt=tgt_dn)) - if wait: - time.sleep(wait) - else: - LOG.info(( - "Group entry {src!r} -> {tgt!r} could not migrated " - "in lap {lap}.").format(src=src_dn, tgt=tgt_dn, lap=lap)) + migrated_dns.add(tgt_dn) + self.group_entries[tgt_dn]['migrated'] = True + self.migrated_group_entries[tgt_dn] = { + 'migrated_at': datetime.datetime.now(), + 'src_dn': src_dn, + 'object_classes': self.group_entries[tgt_dn]['object_classes'], + } + if wait and migrated: + time.sleep(wait) for tgt_dn in migrated_dns: del self.group_entries[tgt_dn] @@ -1955,32 +1962,33 @@ class LDAPMigrationApplication(BaseApplication): return True # ------------------------------------------------------------------------- - def migrate_group_entry(self, tgt_dn): + def migrate_group_entry(self, tgt_dn, fh): src_dn = self.group_entries[tgt_dn]['src_dn'] object_classes = self.group_entries[tgt_dn]['object_classes'] msg = "Migrating group entry {src!r} -> {tgt!r} ...".format(src=src_dn, tgt=tgt_dn) - LOG.info(msg) + LOG.debug(msg) src_entry = self.get_source_item(src_dn, tgt_dn, with_acl=self.do_aci) + if self.verbose > 2: + LOG.debug("Source entry as {c}:\n{e}".format( + c=src_entry.__class__.__name__, e=pp(src_entry))) tgt_entry = self.get_target_item(tgt_dn, with_acl=self.do_aci) + if self.verbose > 2: + LOG.debug("Target entry as {c}:\n{e}".format( + c=tgt_entry.__class__.__name__, e=pp(tgt_entry))) - try: - if tgt_entry: - return self.migrate_existing_group_entry(src_dn, tgt_dn, src_entry, tgt_entry) - return self.migrate_new_group_entry(src_dn, tgt_dn, src_entry) - except GroupEntryNotMigratableError as e: - LOG.debug("Group entry {dn!r} could not migrated: {e}".format(dn=tgt_dn, e=e)) - return False + if tgt_entry: + return self.migrate_existing_group_entry(src_dn, tgt_dn, src_entry, tgt_entry, fh) + return self.migrate_new_group_entry(src_dn, tgt_dn, src_entry, fh) # ------------------------------------------------------------------------- - def migrate_new_group_entry(self, src_dn, tgt_dn, src_entry): + def migrate_new_group_entry(self, src_dn, tgt_dn, src_entry, fh): (tgt_obj_classes, tgt_entry) = self.generate_target_group_entry(src_entry, src_dn, tgt_dn) - if self.verbose: - LOG.info("Creating target entry {!r} ...".format(tgt_dn)) + LOG.debug("Creating target entry {!r} ...".format(tgt_dn)) if self.verbose > 2: msg = "Generated entry for target DN {dn!r}:\n" msg += "object classes:\n{oc}\n" @@ -2017,6 +2025,10 @@ class LDAPMigrationApplication(BaseApplication): dn=tgt_dn, ocs=pp(tgt_obj_classes), tattr=pp(tgt_entry)) raise WriteLDAPItemError(msg) + self.write_result_file(fh, tgt_dn, '*') + + LOG.info("Group entry {src!r} -> {tgt!r} successful created.".format( + src=src_dn, tgt=tgt_dn)) return True # ------------------------------------------------------------------------- @@ -2073,9 +2085,13 @@ class LDAPMigrationApplication(BaseApplication): if len(members): tgt_at_name = self.attribute_types.real_key('uniqueMember') - target_entry[tgt_at_name] = [] + members_list = [] for member in members: - target_entry[tgt_at_name].append(member) + member = member.strip() + if member: + members_list.append(member) + if members_list: + target_entry[tgt_at_name] = members_list for oc in used_classes: object_classes.append(oc) @@ -2172,7 +2188,7 @@ class LDAPMigrationApplication(BaseApplication): elif aname.lower() in ('member', 'uniquemember') and as_group: if self.verbose > 1: - LOG.debug("Transforming members: {!r}".format(attribute)) + LOG.debug("Transforming members:\n{}".format(pp(attribute))) if is_sequence(attribute): for attr in attribute: member = self.mangle_dn(attr) @@ -2225,7 +2241,7 @@ class LDAPMigrationApplication(BaseApplication): return ret # ------------------------------------------------------------------------- - def migrate_existing_group_entry(self, src_dn, tgt_dn, src_entry, tgt_entry): + def migrate_existing_group_entry(self, src_dn, tgt_dn, src_entry, tgt_entry, fh): try: changes = self.generate_modify_group_entry_data(src_entry, tgt_entry, src_dn, tgt_dn) @@ -2270,13 +2286,17 @@ class LDAPMigrationApplication(BaseApplication): else: msg = "Modifying NOT successfull:\n{res}\n" msg += "Source attributes:\n{sattr}\n" + msg += "Target attributes:\n{tattr}\n" msg += "Changes:\n{ch}" msg = msg.format( res=pp(mod_result), sattr=pp(src_entry['attributes']), - ch=pp(changes)) + tattr=pp(tgt_entry['attributes']), ch=pp(changes)) raise WriteLDAPItemError(msg) + rev_dn = self.get_reverse_dn(tgt_dn) self.migrated_entries[rev_dn] = tgt_dn self.write_result_file(fh, tgt_dn, '+') + LOG.info("Group entry {src!r} -> {tgt!r} successful updated.".format( + src=src_dn, tgt=tgt_dn)) return True else: if self.verbose: @@ -2298,7 +2318,14 @@ class LDAPMigrationApplication(BaseApplication): members_having = CIStringSet() src_data = self.normalize_entry_data(src_entry, as_group=True, is_src_entry=True) + if self.verbose > 2: + msg = "Normalized source members:\n{}".format(pp(src_data['members'].as_list())) + LOG.debug(msg) + tgt_data = self.normalize_entry_data(tgt_entry, as_group=True, is_src_entry=False) + if self.verbose > 2: + msg = "Normalized target members:\n{}".format(pp(tgt_data['members'].as_list())) + LOG.debug(msg) for src_oc_name in src_data['classes']: if src_oc_name.lower() not in ('groupofurls', 'groupofnames', 'groupofuniquenames'): @@ -2319,18 +2346,33 @@ class LDAPMigrationApplication(BaseApplication): changes['objectClass'].append((MODIFY_ADD, oc_diff.as_list())) oc_diff = tgt_obj_classes - src_obj_classes + if oc_diff: + if 'nsMemberOf' in oc_diff: + oc_diff.discard('nsMemberOf') if oc_diff: if 'objectClass' not in changes: changes['objectClass'] = [] changes['objectClass'].append((MODIFY_DELETE, oc_diff.as_list())) for member in src_data['members']: - members_to_have.add(member) - members_to_have |= self.get_dyn_members(src_data['member_url']) + member = member.strip() + if member: + members_to_have.add(member) + LOG.debug("Static source members:\n{}".format(pp(members_to_have.as_list()))) + if src_data['member_url']: + dyn_src_members = self.get_dyn_members(src_data['member_url']) + LOG.debug("Dynamic source members:\n{}".format(pp(dyn_src_members.as_list()))) + members_to_have.update(dyn_src_members) + LOG.debug("Members to have:\n{}".format(pp(members_to_have.as_list()))) for member in tgt_data['members']: members_having.add(member) - members_having |= self.get_dyn_members(tgt_data['member_url'], from_src=False) + LOG.debug("Static target members:\n{}".format(pp(members_having.as_list()))) + if tgt_data['member_url']: + dyn_tgt_members = self.get_dyn_members(tgt_data['member_url']) + LOG.debug("Dynamic target members:\n{}".format(pp(dyn_tgt_members.as_list()))) + members_having.update(dyn_tgt_members) + LOG.debug("Members having:\n{}".format(pp(members_having.as_list()))) for at_name in src_data['attributes']: @@ -2350,6 +2392,9 @@ class LDAPMigrationApplication(BaseApplication): LOG.debug(msg) continue + if at_name.lower() in ('member', 'uniquemember'): + continue + src_value = src_data['attributes'][at_name] if at_name in tgt_data['attributes']: @@ -2382,12 +2427,14 @@ class LDAPMigrationApplication(BaseApplication): else: if at_name not in changes: changes[at_name] = [] - member_diff = members_to_have - members_having + member_diff = members_to_have.difference(members_having) + LOG.debug("Members to add:\n{}".format(pp(member_diff.as_list()))) if member_diff: - changes[at_name].append((MODIFY_ADD, member_diff.as_dict())) - member_diff = members_having - members_to_have + changes[at_name].append((MODIFY_ADD, member_diff.as_list())) + member_diff = members_having.difference(members_to_have) + LOG.debug("Members to remove:\n{}".format(pp(member_diff.as_list()))) if member_diff: - changes[at_name].append((MODIFY_DELETE, member_diff.as_dict())) + changes[at_name].append((MODIFY_DELETE, member_diff.as_list())) else: if 'members' in tgt_data and tgt_data['members']: @@ -2476,7 +2523,6 @@ class LDAPMigrationApplication(BaseApplication): self.get_all_dns() self.get_structural_dns() self.migrate_entries() - self.migrate_group_entries() self.detailled_summary() finally: