]> Frank Brehm's Git Trees - pixelpark/ldap-migration.git/commitdiff
Many Bugfixes, Finishing update of groups.
authorFrank Brehm <frank@brehm-online.com>
Fri, 29 Oct 2021 14:23:47 +0000 (16:23 +0200)
committerFrank Brehm <frank@brehm-online.com>
Fri, 29 Oct 2021 14:23:47 +0000 (16:23 +0200)
lib/ldap_migration/__init__.py

index 34ec6b0111a85d542baadccc657b0662050001de..442a0c65ea4e9e9949d114edb6e55c483877f5c4 100644 (file)
@@ -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: