pass
+# =============================================================================
+class GroupEntryNotMigratableError(CommonLDAPMigrationError):
+ """Exception, that happens, if a group entry could not migrated."""
+ pass
+
+
# =============================================================================
class FatalLDAPMigrationError(CommonLDAPMigrationError):
"""Fatal errors leading to interrupt the migration process."""
msg += "on target LDAP server."
msg = msg.format(oc=src_oc_name, dn=src_dn)
LOG.debug(msg)
- self.unknown_objectclasses.add(src_oc_name)
+ self.unknown_objectclasses.add(src_oc_name)
continue
tgt_oc_name = self.object_classes.real_key(src_oc_name)
used_classes.add(tgt_oc_name)
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!r} -> {tgt!r} ...".format(src=src_dn, tgt=tgt_dn)
- LOG.debug(msg)
+ msg = "Migrating group entry {src!r} -> {tgt!r} ...".format(src=src_dn, tgt=tgt_dn)
+ LOG.info(msg)
+
+ src_entry = self.get_source_item(src_dn, tgt_dn, with_acl=False)
+ tgt_entry = self.get_target_item(tgt_dn, with_acl=False)
+
+ 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
+
+ # -------------------------------------------------------------------------
+ def migrate_new_group_entry(self, src_dn, tgt_dn, src_entry):
+
+ (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))
+ if self.verbose > 2:
+ msg = "Generated entry for target DN {dn!r}:\n"
+ msg += "object classes: {oc}\n"
+ msg += "entry: {en}"
+ msg = msg.format(dn=tgt_dn, oc=tgt_obj_classes, en=tgt_entry)
+ LOG.debug(msg)
+ self.count_added += 1
+ if not self.simulate:
+ try:
+ cr_status, cr_result, cr_response, _ = self.target.add(
+ tgt_dn, object_class=tgt_obj_classes, attributes=tgt_entry)
+ except LDAPException as e:
+ msg = "Modifying NOT successfull - {c}: {e}\n"
+ msg += "Source attributes:\n{sattr}\n"
+ msg += "Target-DN: {dn!r}\n"
+ msg += "Target Object classes:\n{ocs}\n"
+ msg += "Target attributes:\n{tattr}"
+ msg = msg.format(
+ c=e.__class__.__name__, e=e, sattr=pp(src_entry['attributes']),
+ dn=tgt_dn, ocs=pp(tgt_obj_classes), tattr=pp(tgt_entry))
+ raise WriteLDAPItemError(msg)
+ if cr_status:
+ LOG.debug("Creation successfull.")
+ if self.verbose > 2:
+ LOG.debug("Result of creation:\n{}".format(pp(cr_result)))
+ else:
+ msg = "Creation NOT successfull:\n{res}\n"
+ msg += "Source attributes:\n{sattr}\n"
+ msg += "Target-DN: {dn!r}\n"
+ msg += "Target Object classes:\n{ocs}\n"
+ msg += "Target attributes:\n{tattr}"
+ msg = msg.format(
+ res=pp(cr_result), sattr=pp(src_entry['attributes']),
+ dn=tgt_dn, ocs=pp(tgt_obj_classes), tattr=pp(tgt_entry))
+ raise WriteLDAPItemError(msg)
+
+ return True
+
+ # -------------------------------------------------------------------------
+ def generate_target_group_entry(self, src_entry, src_dn, tgt_dn):
+
+ object_classes = []
+ target_entry = {}
+ used_classes = CIStringSet()
+ name_group_classes = CIStringSet('groupOfNames', 'groupOfUniqueNames')
+
+ src_data = self.get_src_entry_data(src_entry, as_group=True)
+ for src_oc_name in src_data['classes']:
+ if src_oc_name.lower() not in ('groupofurls', 'groupofnames', 'groupofuniquenames'):
+ tgt_oc_name = self.object_classes.real_key(src_oc_name)
+ used_classes.add(tgt_oc_name)
+
+ members = src_data['members']
+
+ if 'groupOfURLs' in src_data['classes']:
+ if name_group_classes.isdisjoint(src_data['classes']):
+ members.clear()
+ tgt_oc_name = self.object_classes.real_key('groupOfURLs')
+ used_classes.add(tgt_oc_name)
+ if len(src_data['member_url']):
+ tgt_at_name = self.attribute_types.real_key('memberURL')
+ target_entry[tgt_at_name] = src_data['member_url']
+ else:
+ tgt_oc_name = self.object_classes.real_key('groupOfUniqueNames')
+ used_classes.add(tgt_oc_name)
+ if len(src_data['member_url']):
+ dyn_members = self.get_dyn_members(self, src_data['member_url'])
+ for member in dyn_members:
+ members.add(member)
+ else:
+ tgt_oc_name = self.object_classes.real_key('groupOfUniqueNames')
+ used_classes.add(tgt_oc_name)
+
+ if len(members):
+ tgt_at_name = self.attribute_types.real_key('uniqueMember')
+ target_entry[tgt_at_name] = []
+ for member in members:
+ target_entry[tgt_at_name].append(member)
+
+ for oc in used_classes:
+ object_classes.append(oc)
+
+ return (object_classes, target_entry)
+
+ # -------------------------------------------------------------------------
+ def get_dyn_members(self, member_urls):
+
+ members = CIStringSet()
+
+
+ return members
+
+ # -------------------------------------------------------------------------
+ def get_src_entry_data(self, src_entry, as_group=False):
+
+ src_classes = CIStringSet()
+ src_attributes = CIDict()
+ src_members = CIStringSet()
+ src_member_url = CIStringSet()
+
+ for src_aname in src_entry['attributes']:
+
+ src_attr = src_entry['attributes'][src_aname]
+
+ if src_aname.lower() == 'objectclass':
+ for src_oc_name in src_attr:
+ if src_oc_name not in self.object_classes:
+ if self.verbose > 3:
+ msg = "ObjectClass {oc!r} of sorce entry {dn!r} not found "
+ msg += "on target LDAP server."
+ msg = msg.format(oc=src_oc_name, dn=src_dn)
+ LOG.debug(msg)
+ self.unknown_objectclasses.add(src_oc_name)
+ continue
+ src_classes.add(src_oc_name)
+
+ elif src_aname.lower() in ('member', 'uniquemember') and as_group:
+ if is_sequence(src_attr):
+ for attr in src_attr:
+ member = self.mangle_dn(attr)
+ src_members.add(member)
+ else:
+ member = self.mangle_dn(src_attr)
+ src_members.add(member)
+ elif src_aname.lower() == 'memberurl' and as_group:
+ if is_sequence(src_attr):
+ for attr in src_attr:
+ src_member_url.add(attr)
+ else:
+ src_member_url.add(src_attr)
+ else:
+ if is_sequence(src_attr):
+ for attr in src_attr:
+ if attr == '':
+ continue
+ if src_aname not in src_attributes:
+ src_attributes[src_aname] = []
+ if src_aname in self.boolean_attr_types:
+ if to_bool(attr):
+ attr = 'TRUE'
+ else:
+ attr = 'FALSE'
+ src_attributes[src_aname].append(attr)
+ elif src_attr != '':
+ if src_aname not in src_attributes:
+ src_attributes[src_aname] = []
+ if src_aname in self.boolean_attr_types:
+ if to_bool(src_attr):
+ src_attr = 'TRUE'
+ else:
+ src_attr = 'FALSE'
+ src_attributes[src_aname].append(src_attr)
+
+ ret = {
+ 'classes': src_classes,
+ 'attributes': src_attributes,
+ }
+ if as_group:
+ ret['members'] = src_members
+ ret['member_url'] = src_member_url
+
+ return ret
+
+ # -------------------------------------------------------------------------
+ def migrate_existing_group_entry(self, src_dn, tgt_dn, src_entry, tgt_entry):
return True