from .config import LDAPMigrationConfiguration
-__version__ = '0.11.2'
+__version__ = '0.12.0'
LOG = logging.getLogger(__name__)
CFG_BASENAME = 'ldap-migration.ini'
if not self.migrate_all_entries(fh):
return False
+ self.migrate_group_entries(fh)
+
print()
return True
return False
# -------------------------------------------------------------------------
- def migrate_group_entries(self):
+ def migrate_group_entries(self, fh):
print()
LOG.info("Next lap - migration af all 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 = 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]
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"
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
# -------------------------------------------------------------------------
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)
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)
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)
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:
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'):
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']:
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']:
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']:
self.get_all_dns()
self.get_structural_dns()
self.migrate_entries()
- self.migrate_group_entries()
self.detailled_summary()
finally: