From: Frank Brehm Date: Fri, 8 Jan 2021 10:59:44 +0000 (+0100) Subject: Starting migration of group entries X-Git-Url: https://git.uhu-banane.org/?a=commitdiff_plain;h=fb4aa7b8f9e5c39b80994a96d56eb2fc1b4d27aa;p=pixelpark%2Fldap-migration.git Starting migration of group entries --- diff --git a/lib/ldap_migration/__init__.py b/lib/ldap_migration/__init__.py index d55575f..25880da 100644 --- a/lib/ldap_migration/__init__.py +++ b/lib/ldap_migration/__init__.py @@ -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: