- 'cn=Replication monitor,o=isp'
spk-stage:
- 'cn=Replication monitor,dc=spk,dc=pixelpark,dc=net'
+ - 'dnaHostname=prd-ds01-spk.spk.pixelpark.net+dnaPortNum=389,cn=Account UIDs,ou=Ranges,dc=spk,dc=pixelpark,dc=net'
+ - 'dnaHostname=prd-ds02-spk.spk.pixelpark.net+dnaPortNum=389,cn=Account UIDs,ou=Ranges,dc=spk,dc=pixelpark,dc=net'
+ - 'dnaHostname=prd-ds01-spk.spk.pixelpark.net+dnaPortNum=389,cn=Group GIDs,ou=Ranges,dc=spk,dc=pixelpark,dc=net'
+ - 'dnaHostname=prd-ds02-spk.spk.pixelpark.net+dnaPortNum=389,cn=Group GIDs,ou=Ranges,dc=spk,dc=pixelpark,dc=net'
+ - 'dnaHostname=stage-ds01-spk.spk.pixelpark.net,cn=Account UIDs,ou=Ranges,dc=spk,dc=pixelpark,dc=net'
+ - 'dnaHostname=stage-ds02-spk.spk.pixelpark.net,cn=Account UIDs,ou=Ranges,dc=spk,dc=pixelpark,dc=net'
+ - 'dnaHostname=stage-ds01-spk.spk.pixelpark.net,cn=Group GIDs,ou=Ranges,dc=spk,dc=pixelpark,dc=net'
+ - 'dnaHostname=stage-ds02-spk.spk.pixelpark.net,cn=Group GIDs,ou=Ranges,dc=spk,dc=pixelpark,dc=net'
# vim: filetype=yaml
from ..argparse_actions import NonNegativeItegerOptionAction
from ..argparse_actions import LimitedFloatOptionAction
-__version__ = '0.7.3'
+__version__ = '0.8.1'
LOG = logging.getLogger(__name__)
_ = XLATOR.gettext
self.only_struct = False
self.mirrored_entries = 0
+ self.total_deleted = 0
+ self.total_updated = 0
+ self.total_created = 0
+
self.structural_entr_dns = []
self.non_structural_entr_dns = []
self.keep_entry_dns = []
self.clean_tgt_non_struct_entries()
self.clean_tgt_struct_entries()
self.mirror_struct_entries()
+ self.mirror_non_struct_entries()
+
+ if not self.quiet:
+ self.empty_line()
+ title = _("Changes total:")
+ print(self.colored(title, 'CYAN'))
+ self.line(width=len(title), linechar='=', color='CYAN')
+ self.empty_line()
+
+ msg = ' * ' + ngettext(
+ "{:>5} entry deleted.", "{:>5} entries deleted.", self.total_deleted).format(
+ self.total_deleted)
+ print(msg)
+
+ msg = ' * ' + ngettext(
+ "{:>5} entry updated.", "{:>5} entries updated.", self.total_updated).format(
+ self.total_updated)
+ print(msg)
+
+ msg = ' * ' + ngettext(
+ "{:>5} entry created.", "{:>5} entries created.", self.total_created).format(
+ self.total_created)
+ print(msg)
+
+ self.empty_line()
except KeyboardInterrupt:
msg = _("Got a {}:").format('KeyboardInterrupt') + ' ' + _("Interrupted on demand.")
self.empty_line()
self.delete_entry(self.tgt_instance, dn)
count += 1
+ self.total_deleted += 1
if self.wait_after_write and not self.simulate:
time.sleep(self.wait_after_write)
if count:
+ self.empty_line()
msg = ngettext(
"Removed one not structural entry in target LDAP instance.",
"Removed {no} not structural entries in target LDAP instance.",
self.empty_line()
self.delete_entry(self.tgt_instance, dn)
+ self.total_deleted += 1
count += 1
if self.wait_after_write and not self.simulate:
time.sleep(self.wait_after_write)
if count:
+ self.empty_line()
msg = ngettext(
"Removed one structural entry in target LDAP instance.",
"Removed {no} structural entries in target LDAP instance.",
# -------------------------------------------------------------------------
def mirror_struct_entries(self):
- """Mirroring all structurale entries."""
+ """Mirroring all structural entries."""
self.empty_line()
self.line(color='CYAN')
LOG.info(_("Mirroring structural entries from source to target LDAP instance."))
if self.verbose:
self.empty_line()
+
+ if dn in self.keep_entry_dns:
+ LOG.debug(_("Entry {!r} is set to be kept.").format(dn))
+ continue
+
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_oclasses = src_attribs['objectClass'].as_list()
src_attribs_dict = src_attribs.dict()
self.modify_entry(self.tgt_instance, dn, changes)
self.mirrored_entries += 1
count += 1
+ self.total_updated += 1
+ 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))
continue
self.add_entry(self.tgt_instance, dn, object_classes, target_entry)
self.mirrored_entries += 1
count += 1
+ if self.wait_after_write and not self.simulate:
+ time.sleep(self.wait_after_write)
if self.limit and self.mirrored_entries >= self.limit:
break
if count:
+ self.empty_line()
msg = ngettext(
"Mirrored one structural entry in target LDAP instance.",
"Mirrored {no} structural entries to target LDAP instance.",
msg = _("Mirrored no structural entries to target LDAP instance.")
LOG.info(msg)
+ # -------------------------------------------------------------------------
+ def mirror_non_struct_entries(self):
+ """Mirroring all non-structural entries."""
+ self.empty_line()
+ self.line(color='CYAN')
+ LOG.info(_("Mirroring non-structural 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 = [ALL_ATTRIBUTES, 'aci']
+
+ for dn in dns:
+
+ if dn in self.src_struct_dns:
+ continue
+
+ if dn in self.keep_entry_dns:
+ 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))
+
+ 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_oclasses = src_attribs['objectClass'].as_list()
+ src_attribs_dict = src_attribs.dict()
+ src_attribs_dict['objectClass'] = src_oclasses
+
+ if self.verbose > 1:
+ 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_oclasses = tgt_attribs['objectClass'].as_list()
+ tgt_attribs_dict = tgt_attribs.dict()
+ tgt_attribs_dict['objectClass'] = tgt_oclasses
+
+ if self.verbose > 1:
+ 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
+ self.total_updated += 1
+ 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))
+ continue
+
+ else:
+ LOG.debug(_("Target entry {!r} not found.").format(dn))
+ (object_classes, target_entry) = self.generate_create_entry(src_attribs)
+ self.empty_line()
+ LOG.info(_("Creating entry {!r} ...").format(dn))
+ msg = _("Got create data for DN {!r}:").format(dn)
+ msg += '\nobjectClasses:\n' + pp(object_classes)
+ msg += "\nAttributes:\n" + pp(target_entry)
+ LOG.debug(msg)
+ self.add_entry(self.tgt_instance, dn, object_classes, target_entry)
+ self.mirrored_entries += 1
+ count += 1
+ self.total_created += 1
+ if self.wait_after_write and not self.simulate:
+ time.sleep(self.wait_after_write)
+
+ if self.limit and self.mirrored_entries >= self.limit:
+ break
+
+ 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.",
+ count).format(no=count)
+ else:
+ msg = _("Mirrored non structural entries to target LDAP instance.")
+ LOG.info(msg)
+
# =============================================================================
if __name__ == "__main__":