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'
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,
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
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)
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
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
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)
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: