# rom ..config.ldap import DEFAULT_PORT_LDAP, DEFAULT_PORT_LDAPS
from ..config.ldap import DEFAULT_TIMEOUT
-__version__ = '0.10.5'
+__version__ = '0.10.6'
LOG = logging.getLogger(__name__)
_ = XLATOR.gettext
return result
# -------------------------------------------------------------------------
- def normalized_attributes(self, entry):
+ def normalized_attributes(self, entry, omit_members=False, omit_memberof=False):
attribs = CIDict()
for attrib in entry['attributes']:
values = entry['attributes'][attrib]
- if attrib.lower() == 'objectclass':
+ a_lc = attrib.lower()
+ if a_lc == 'objectclass':
if 'objectClass' not in attribs:
attribs['objectClass'] = CIStringSet()
if is_sequence(values):
else:
attribs['objectClass'].add(values)
else:
+ if omit_members and a_lc in ('member', 'uniquemember'):
+ continue
+ if omit_memberof and a_lc == 'memberof':
+ continue
if attrib not in attribs:
attribs[attrib] = []
if is_sequence(values):
req_status, req_result, req_response, req_whatever = ldap.add(
dn, object_class=object_classes, attributes=target_entry)
except LDAPException as e:
- msg = _("Creation of entry {dn!r} NOT successfull - {c}: {e}").format(
+ msg = _("Creation of entry {dn!r} was NOT successfull - {c}: {e}").format(
dn=dn, c=e.__class__.__name__, e=e)
msg += '\nobjectClasses:\n' + pp(object_classes)
msg += "\nAttributes:\n" + pp(target_entry)
LOG.debug(_("Result of creating:") + '\n' + pp(req_result))
if not req_status:
- msg = _("Creation NOT successful: {desc} - {msg}").format(
- desc=req_result['description'], msg=req_result['message'].strip())
+ msg = _("Creation of entry {dn!r} was NOT successful: {desc} - {msg}").format(
+ dn=dn, desc=req_result['description'], msg=req_result['message'].strip())
+ msg += '\nobjectClasses:\n' + pp(object_classes)
+ msg += "\nAttributes:\n" + pp(target_entry)
raise WriteLDAPItemError(msg)
LOG.debug(_('Creation successful.'))
try:
req_status, req_result, req_response, req_whatever = ldap.modify(dn, changes)
except LDAPException as e:
- msg = _("Modification NOT successfull - {c}: {e}").format(c=e.__class__.__name__, e=e)
+ msg = _("Modification of {dn!r} was NOT successfull - {c}: {e}").format(
+ dn=dn, c=e.__class__.__name__, e=e)
msg += '\n' + _("Changes:") + '\n' + pp(changes)
raise WriteLDAPItemError(msg)
LOG.debug(_("Result of modifying:") + '\n' + pp(req_result))
if not req_status:
- msg = _("Modification NOT successful: {desc} - {msg}").format(
- desc=req_result['description'], msg=req_result['message'].strip())
+ msg = _("Modification of {dn!r} was NOT successful: {desc} - {msg}").format(
+ dn=dn, desc=req_result['description'], msg=req_result['message'].strip())
+ msg += '\n' + _("Changes:") + '\n' + pp(changes)
raise WriteLDAPItemError(msg)
LOG.debug(_('Modification successful.'))
try:
req_status, req_result, req_response, req_whatever = ldap.delete(dn)
except LDAPException as e:
- msg = _("Deletion NOT successfull - {c}: {e}").format(c=e.__class__.__name__, e=e)
+ msg = _("Deletion of {dn!r} was NOT successfull - {c}: {e}").format(
+ c=e.__class__.__name__, e=e)
raise DeleteLDAPItemError(msg)
if self.verbose > 1:
LOG.debug(_("Result of deletion:") + '\n' + pp(req_result))
if not req_status:
- msg = _("Deletion NOT successful: {desc} - {msg}").format(
- desc=req_result['description'], msg=req_result['message'].strip())
+ msg = _("Deletion of {dn!r} was NOT successful: {desc} - {msg}").format(
+ dn=dn, desc=req_result['description'], msg=req_result['message'].strip())
raise DeleteLDAPItemError(msg)
LOG.debug(_('Deletion successful.'))
LOG.debug(msg)
continue
+ old_values = []
+ for value in tgt_attribs[attrib_name]:
+ old_values.append(value)
+
if attrib_name not in changes:
changes[attrib_name] = []
- changes[attrib_name].append((MODIFY_DELETE, ))
+ changes[attrib_name].append((MODIFY_DELETE, old_values))
return changes
from ..argparse_actions import NonNegativeItegerOptionAction
from ..argparse_actions import LimitedFloatOptionAction
-__version__ = '0.8.1'
+__version__ = '0.9.1'
LOG = logging.getLogger(__name__)
_ = XLATOR.gettext
self.src_dns = CIDict()
self.src_struct_dns = CIStringSet()
+ self.mirrored_dns = CIStringSet()
+
self.tgt_dns_current = CIDict()
self.tgt_struct_dns_current = CIStringSet()
self.clean_tgt_struct_entries()
self.mirror_struct_entries()
self.mirror_non_struct_entries()
+ self.update_memberships()
+
+ self.empty_line()
msg = ngettext(
"{:>5} entry deleted.", "{:>5} entries deleted.", self.total_deleted).format(
self.total_deleted)
if parent_dn not in self.sync_entry_dns:
self.sync_entry_dns.append(parent_dn)
- LOG.debug("DNs of sync entries:\n" + pp(self.sync_entry_dns))
+ if self.verbose > 1:
+ LOG.debug("DNs of sync entries:\n" + pp(self.sync_entry_dns))
# -------------------------------------------------------------------------
def register_dn_tokens(self, dn, entry, registry):
continue
if dn in self.keep_entry_dns:
- LOG.debug(_("Entry {!r} is set to be kept.").format(dn))
+ if self.verbose > 1:
+ LOG.debug(_("Entry {!r} is set to be kept.").format(dn))
continue
self.empty_line()
continue
if dn in self.keep_entry_dns:
- LOG.debug(_("Entry {!r} is set to be kept.").format(dn))
+ if self.verbose > 1:
+ LOG.debug(_("Entry {!r} is set to be kept.").format(dn))
continue
if dn in self.sync_entry_dns:
- LOG.debug(_("Entry {!r} is set to be synchronized.").format(dn))
+ if self.verbose > 1:
+ LOG.debug(_("Entry {!r} is set to be synchronized.").format(dn))
continue
self.empty_line()
for dn in dns:
- if self.verbose:
+ if self.verbose > 1:
self.empty_line()
if dn in self.keep_entry_dns:
- LOG.debug(_("Entry {!r} is set to be kept.").format(dn))
+ if self.verbose > 1:
+ LOG.debug(_("Entry {!r} is set to be kept.").format(dn))
continue
- LOG.debug(_("Mirroring entry {!r} ...").format(dn))
+ if self.verbose > 1:
+ LOG.debug(_("Mirroring entry {!r} ...").format(dn))
src_entry = self.get_entry(dn, self.src_instance, attributes)
if not src_entry:
msg = _("Did not found {!r} in the source LDAP.").format(dn)
LOG.warn(msg)
continue
- src_attribs = self.normalized_attributes(src_entry)
+ src_attribs = self.normalized_attributes(
+ src_entry, omit_members=True, omit_memberof=True)
src_oclasses = src_attribs['objectClass'].as_list()
src_attribs_dict = src_attribs.dict()
src_attribs_dict['objectClass'] = src_oclasses
- if self.verbose > 1:
+ if self.verbose > 2:
LOG.debug("Got source entry:\n" + pp(src_attribs_dict))
tgt_entry = self.get_entry(dn, self.tgt_instance, attributes)
if tgt_entry:
- tgt_attribs = self.normalized_attributes(tgt_entry)
+ tgt_attribs = self.normalized_attributes(
+ tgt_entry, omit_members=True, omit_memberof=True)
tgt_oclasses = tgt_attribs['objectClass'].as_list()
tgt_attribs_dict = tgt_attribs.dict()
tgt_attribs_dict['objectClass'] = tgt_oclasses
- if self.verbose > 1:
+ if self.verbose > 2:
LOG.debug("Got target entry:\n" + pp(tgt_attribs_dict))
changes = self.generate_modify_data(dn, src_attribs, tgt_attribs)
self.mirrored_entries += 1
count += 1
self.total_updated += 1
+ self.mirrored_dns.add(dn)
if self.wait_after_write and not self.simulate:
time.sleep(self.wait_after_write)
else:
- LOG.debug(_("No changes necessary on DN {!r}.").format(dn))
+ if self.verbose > 1:
+ LOG.debug(_("No changes necessary on DN {!r}.").format(dn))
continue
else:
self.add_entry(self.tgt_instance, dn, object_classes, target_entry)
self.mirrored_entries += 1
count += 1
+ self.total_created += 1
+ self.mirrored_dns.add(dn)
if self.wait_after_write and not self.simulate:
time.sleep(self.wait_after_write)
if dn in self.src_struct_dns:
continue
+ if self.verbose > 1:
+ self.empty_line()
+
if dn in self.keep_entry_dns:
- LOG.debug(_("Entry {!r} is set to be kept.").format(dn))
+ if self.verbose > 1:
+ LOG.debug(_("Entry {!r} is set to be kept.").format(dn))
continue
- if self.verbose:
- self.empty_line()
- LOG.debug(_("Mirroring entry {!r} ...").format(dn))
+ if self.verbose > 1:
+ LOG.debug(_("Mirroring entry {!r} ...").format(dn))
src_entry = self.get_entry(dn, self.src_instance, attributes)
if not src_entry:
msg = _("Did not found {!r} in the source LDAP.").format(dn)
LOG.warn(msg)
continue
- src_attribs = self.normalized_attributes(src_entry)
+ src_attribs = self.normalized_attributes(
+ src_entry, omit_members=True, omit_memberof=True)
src_oclasses = src_attribs['objectClass'].as_list()
src_attribs_dict = src_attribs.dict()
src_attribs_dict['objectClass'] = src_oclasses
- if self.verbose > 1:
+ if self.verbose > 2:
LOG.debug("Got source entry:\n" + pp(src_attribs_dict))
tgt_entry = self.get_entry(dn, self.tgt_instance, attributes)
if tgt_entry:
- tgt_attribs = self.normalized_attributes(tgt_entry)
+ tgt_attribs = self.normalized_attributes(
+ tgt_entry, omit_members=True, omit_memberof=True)
tgt_oclasses = tgt_attribs['objectClass'].as_list()
tgt_attribs_dict = tgt_attribs.dict()
tgt_attribs_dict['objectClass'] = tgt_oclasses
- if self.verbose > 1:
+ if self.verbose > 2:
LOG.debug("Got target entry:\n" + pp(tgt_attribs_dict))
changes = self.generate_modify_data(dn, src_attribs, tgt_attribs)
self.mirrored_entries += 1
count += 1
self.total_updated += 1
+ self.mirrored_dns.add(dn)
if self.wait_after_write and not self.simulate:
time.sleep(self.wait_after_write)
else:
- LOG.debug(_("No changes necessary on DN {!r}.").format(dn))
+ if self.verbose > 1:
+ LOG.debug(_("No changes necessary on DN {!r}.").format(dn))
continue
else:
self.mirrored_entries += 1
count += 1
self.total_created += 1
+ self.mirrored_dns.add(dn)
if self.wait_after_write and not self.simulate:
time.sleep(self.wait_after_write)
if count:
self.empty_line()
msg = ngettext(
- "Mirrored one none structural entry in target LDAP instance.",
- "Mirrored {no} none structural entries to target LDAP instance.",
+ "Mirrored one non-structural entry in target LDAP instance.",
+ "Mirrored {no} non-structural entries to target LDAP instance.",
+ count).format(no=count)
+ else:
+ msg = _("Mirrored none not-structural entries to target LDAP instance.")
+ LOG.info(msg)
+
+ # -------------------------------------------------------------------------
+ def update_memberships(self):
+ """Updating all 'member' and 'uniqueMember' attributes."""
+ self.empty_line()
+
+ self.line(color='CYAN')
+ LOG.info(_("Mirroring members in group entries from source to target LDAP instance."))
+ if not self.quiet:
+ time.sleep(2)
+
+ dns = sorted(list(self.src_dns.keys()), key=cmp_to_key(self.compare_ldap_dns))
+
+ count = 0
+
+ attributes = ['member', 'uniqueMember']
+
+ for dn in dns:
+
+ if dn in self.keep_entry_dns:
+ if self.verbose > 1:
+ LOG.debug(_("Entry {!r} is set to be kept.").format(dn))
+ continue
+
+ if self.verbose > 1:
+ self.empty_line()
+ if self.verbose > 1:
+ LOG.debug(_("Mirroring entry {!r} ...").format(dn))
+
+ src_entry = self.get_entry(dn, self.src_instance, attributes)
+ if not src_entry:
+ msg = _("Did not found {!r} in the source LDAP.").format(dn)
+ LOG.warn(msg)
+ continue
+ src_attribs = self.normalized_attributes(src_entry, omit_memberof=True)
+ src_attribs_dict = src_attribs.dict()
+ if self.verbose > 2:
+ LOG.debug("Got source entry:\n" + pp(src_attribs_dict))
+
+ tgt_entry = self.get_entry(dn, self.tgt_instance, attributes)
+ if not tgt_entry:
+ LOG.warn(_("Target entry {!r} not found.").format(dn))
+ continue
+
+ tgt_attribs = self.normalized_attributes(tgt_entry, omit_memberof=True)
+ tgt_attribs_dict = tgt_attribs.dict()
+
+ if self.verbose > 2:
+ LOG.debug("Got target entry:\n" + pp(tgt_attribs_dict))
+
+ changes = self.generate_modify_data(dn, src_attribs, tgt_attribs)
+ if changes:
+ self.empty_line()
+ LOG.info(_("Modifying entry {!r} ...").format(dn))
+ msg = _("Got modify data for DN {!r}:").format(dn)
+ LOG.debug(msg + '\n' + pp(changes))
+ self.modify_entry(self.tgt_instance, dn, changes)
+ self.mirrored_entries += 1
+ count += 1
+ if dn not in self.mirrored_dns:
+ self.total_updated += 1
+ if self.wait_after_write and not self.simulate:
+ time.sleep(self.wait_after_write * 2)
+ else:
+ if self.verbose > 1:
+ LOG.debug(_("No changes necessary on DN {!r}.").format(dn))
+ continue
+
+ if count:
+ self.empty_line()
+ msg = ngettext(
+ "Mirrored one group entry in target LDAP instance.",
+ "Mirrored {no} group entries to target LDAP instance.",
count).format(no=count)
else:
- msg = _("Mirrored non structural entries to target LDAP instance.")
+ msg = _("Mirrored no group entries to target LDAP instance.")
LOG.info(msg)