]> Frank Brehm's Git Trees - pixelpark/ldap-migration.git/commitdiff
Starting migration of group entries
authorFrank Brehm <frank.brehm@pixelpark.com>
Fri, 8 Jan 2021 10:59:44 +0000 (11:59 +0100)
committerFrank Brehm <frank.brehm@pixelpark.com>
Fri, 8 Jan 2021 10:59:44 +0000 (11:59 +0100)
lib/ldap_migration/__init__.py

index d55575fd1edf2bb55df720ba655f28a81cf1a269..25880da91b897da3668bc36e8aa405dcf7222d4d 100644 (file)
@@ -45,7 +45,7 @@ from fb_tools.collections import CIStringSet, CIDict
 
 from .config import LDAPMigrationConfiguration
 
-__version__ = '0.9.12'
+__version__ = '0.10.0'
 
 LOG = logging.getLogger(__name__)
 CFG_BASENAME = 'ldap-migration.ini'
@@ -69,7 +69,13 @@ class ReadLDAPItemError(CommonLDAPMigrationError):
 
 
 # =============================================================================
-class WriteLDAPItemError(CommonLDAPMigrationError):
+class FatalLDAPMigrationError(CommonLDAPMigrationError):
+    """Fatal errors leading to interrupt the migration process."""
+    pass
+
+
+# =============================================================================
+class WriteLDAPItemError(FatalLDAPMigrationError):
     """Error class in case, a LDAP item could not be written."""
     pass
 
@@ -275,6 +281,7 @@ class LDAPMigrationApplication(BaseApplication):
         self.struct_entries = []
         self.all_entries = []
         self.group_entries = CIDict()
+        self.migrated_group_entries = CIDict()
         self.ignored_entries = CIStringSet()
 
         self.limit = 0
@@ -338,18 +345,20 @@ class LDAPMigrationApplication(BaseApplication):
         """
 
         res = super(LDAPMigrationApplication, self).as_dict(short=short)
-        res['object_classes'] = self.object_classes.as_dict(short=short)
-        res['attribute_types'] = self.attribute_types.as_dict(short=short)
+        res['object_classes'] = self.object_classes.as_dict(short=short)
+        res['attribute_types'] = self.attribute_types.as_dict(short=short)
         res['cfg_dir'] = self.cfg_dir
         res['cfg_file'] = self.cfg_file
         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['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['migrated_group_entries'] = self.migrated_group_entries.as_dict(short=short)
         res['integer_attribute_types'] = self.integer_attribute_types.as_list()
         res['pure_binary_attr_types'] = self.pure_binary_attr_types.as_list()
         res['dn_attr_types'] = self.dn_attr_types.as_list()
         res['boolean_attr_types'] = self.boolean_attr_types.as_list()
+        res['ignored_entries'] = self.ignored_entries.as_list()
 
         return res
 
@@ -1356,8 +1365,8 @@ class LDAPMigrationApplication(BaseApplication):
             self._migrate_entries(
                 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)
+        except CommonLDAPMigrationError as e:
+            msg = "Abort migration by {c}: {e}".format(c=e.__class__.__name__, e=e)
             LOG.error(msg)
             return False
 
@@ -1394,8 +1403,8 @@ class LDAPMigrationApplication(BaseApplication):
                         src_dn, fh=fh, force=False, with_acl=False, migrate_if_group=False):
                     if wait:
                         time.sleep(wait)
-            except WriteLDAPItemError as e:
-                msg = "Abort migration: " + str(e)
+            except FatalLDAPMigrationError as e:
+                msg = "Abort migration by {c}: {e}".format(c=e.__class__.__name__, e=e)
                 LOG.error(msg)
                 return False
             except ReadLDAPItemError as e:
@@ -1406,15 +1415,17 @@ class LDAPMigrationApplication(BaseApplication):
                 continue
 
         print()
-        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)
+        if self.verbose > 1:
+            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)
 
         LOG.info("Performed all entries.")
         time.sleep(3)
@@ -1689,6 +1700,7 @@ class LDAPMigrationApplication(BaseApplication):
             if is_group:
                 self.group_entries[tgt_dn] = {
                     'migrated': False,
+                    'src_dn': src_dn,
                     'object_classes': object_classes,
                 }
                 LOG.debug("Entry {e!r} is a group entry: {c}".format(
@@ -1708,7 +1720,7 @@ class LDAPMigrationApplication(BaseApplication):
                 LOG.debug(msg)
                 msg = "UnicodeDecodeError on generating changes for source DN {s!r}: {e}".format(
                         s=src_dn, e=e)
-                raise WriteLDAPItemError(msg)
+                raise FatalLDAPMigrationError(msg)
             if changes:
                 if self.verbose:
                     LOG.info("Updating target entry {!r} ...".format(tgt_dn))
@@ -1840,6 +1852,69 @@ class LDAPMigrationApplication(BaseApplication):
 
         return False
 
+    # -------------------------------------------------------------------------
+    def migrate_group_entries(self):
+
+        print()
+        LOG.info("Next lap - migration af all group entries ...")
+
+        lap = 0
+        while len(self.group_entries):
+
+            lap += 1
+            print()
+            LOG.info("Lap {} on migrating of group entries.".format(lap))
+            migrated_dns = CIStringSet()
+            count_groups_before = len(self.group_entries)
+
+            for tgt_dn in self.group_entries:
+
+                if self.migrate_group_entry(tgt_dn):
+
+                    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!} -> {tgt!r} successful migrated.".format(
+                        src=src_dn, tgt=tgt_dn))
+                else:
+                    LOG.info((
+                        "Group entry {src!} -> {tgt!r} could not migrated "
+                        "in lap {lap}.").format(src=src_dn, tgt=tgt_dn, lap=lap))
+
+            for tgt_dn in migrated_dns:
+                del self.group_entries[tgt_dn]
+            migrated_dns = None
+
+            count_groups_after = len(self.group_entries)
+            if (count_groups_after > 0 and
+                    count_groups_aftercount_groups_after == count_groups_before):
+
+                msg = (
+                    "No change in the list of group items to migrate, there "
+                    "are {} group entries left.").format(count_groups_after)
+                raise FatalLDAPMigrationError(msg)
+
+        print()
+        LOG.info("Performed all group entries.")
+        time.sleep(3)
+        return True
+
+    # -------------------------------------------------------------------------
+    def migrate_group_entry(self, tgt_dn):
+
+        src_dn = self.group_entries[tgt_dn]['src_dn']
+        object_classes = self.group_entries[tgt_dn]['object_classes']
+
+        msg = "Trying to migrate group entry {src!} -> {tgt!r} ...".format(src=src_dn, tgt=tgt_dn)
+        LOG.debug(msg)
+
+        return True
+
     # -------------------------------------------------------------------------
     def detailled_summary(self):
 
@@ -1902,6 +1977,7 @@ class LDAPMigrationApplication(BaseApplication):
             self.get_all_dns()
             self.get_structural_dns()
             self.migrate_entries()
+            self.migrate_group_entries()
             self.detailled_summary()
 
         finally: