# -*- coding: utf-8 -*-
"""
+@summary: A base module for application classes with mail sending support.
+
@author: Frank Brehm
@contact: frank.brehm@pixelpark.com
@copyright: © 2023 by Frank Brehm, Berlin
-@summary: A base module for application classes with mail sending support
"""
from __future__ import absolute_import
# Standard modules
-import logging
import copy
-import pipes
+import logging
import os
-
-from email.mime.text import MIMEText
-from email import charset
-
-from subprocess import Popen, PIPE
-
+import pipes
import smtplib
+from email import charset
+from email.mime.text import MIMEText
+from subprocess import PIPE, Popen
# Third party modules
-from fb_tools.xlate import format_list
from fb_tools import MailAddress
+from fb_tools.xlate import format_list
# Own modules
+from . import BaseDPXApplication, DPXAppError
+from .. import DEFAULT_CONFIG_DIR, MAX_PORT_NUMBER
from .. import __version__ as GLOBAL_VERSION
-from .. import MAX_PORT_NUMBER, DEFAULT_CONFIG_DIR
from .. import pp
-
-from ..xlate import XLATOR
-
from ..argparse_actions import PortOptionAction
-
from ..config.mail import MailConfiguration
+from ..xlate import XLATOR
-from . import DPXAppError, BaseDPXApplication
-
-__version__ = '0.3.3'
+__version__ = '0.3.4'
LOG = logging.getLogger(__name__)
_ = XLATOR.gettext
# =============================================================================
class MailAppError(DPXAppError):
- """ Base exception class for all exceptions in all mail sending application classes."""
+ """Base exception class for all exceptions in all mail sending application classes."""
+
pass
# =============================================================================
class BaseMailApplication(BaseDPXApplication):
- """
- Base class for all mail sending application classes.
- """
+ """Base class for all mail sending application classes."""
charset.add_charset('utf-8', charset.SHORTEST, charset.QP)
cfg_class=MailConfiguration, initialized=False, usage=None, description=None,
argparse_epilog=None, argparse_prefix_chars='-', env_prefix=None,
config_dir=DEFAULT_CONFIG_DIR):
-
+ """Ini the current application object."""
super(BaseMailApplication, self).__init__(
appname=appname, verbose=verbose, version=version, base_dir=base_dir,
description=description, cfg_class=cfg_class, initialized=False,
# -------------------------------------------------------------------------
def post_init(self):
"""
- Method to execute before calling run(). Here could be done some
- finishing actions after reading in commandline parameters,
- configuration a.s.o.
+ Execute this before calling run().
+
+ Here could be done some finishing actions after reading in commandline
+ parameters, configuration a.s.o.
This method could be overwritten by descendant classes, these
methhods should allways include a call to post_init() of the
parent class.
-
"""
-
self.initialized = False
super(BaseMailApplication, self).post_init()
v = getattr(self.args, 'smtp_port', None)
if v is not None:
if v <= 0 or v > MAX_PORT_NUMBER:
- msg = _("Got invalid SMTP port number {!r}.").format(v)
+ msg = _('Got invalid SMTP port number {!r}.').format(v)
LOG.error(msg)
else:
self.cfg.smtp_port = v
return
if not MailAddress.valid_address(v):
- msg = _("Got invalid mail from address {!r}.").format(v)
+ msg = _('Got invalid mail from address {!r}.').format(v)
LOG.error(msg)
self.exit(1)
bad_rcpts.append(addr)
if bad_rcpts:
- msg = _("Got invalid recipient mail addresses:")
- msg += " " + format_list(bad_rcpts, do_repr=True)
+ msg = _('Got invalid recipient mail addresses:')
+ msg += ' ' + format_list(bad_rcpts, do_repr=True)
LOG.error(msg)
self.exit(1)
self.cfg.mail_recipients = copy.copy(recipients)
if not self.cfg.mail_recipients:
- msg = ("Did not found any valid recipient mail addresses.")
+ msg = ('Did not found any valid recipient mail addresses.')
LOG.error(msg)
# -------------------------------------------------------------------------
bad_cc.append(addr)
if bad_cc:
- msg = _("Got invalid cc mail addresses:")
- msg += " " + format_list(bad_cc, do_repr=True)
+ msg = _('Got invalid cc mail addresses:')
+ msg += ' ' + format_list(bad_cc, do_repr=True)
LOG.error(msg)
self.exit(1)
return
if not MailAddress.valid_address(v):
- msg = _("Got invalid reply mail address {!r}.").format(v)
+ msg = _('Got invalid reply mail address {!r}.').format(v)
LOG.error(msg)
self.exit(1)
# -------------------------------------------------------------------------
def init_arg_parser(self):
- """
- Public available method to initiate the argument parser.
- """
-
+ """Initiate the argument parser."""
super(BaseMailApplication, self).init_arg_parser()
mail_group = self.arg_parser.add_argument_group(_('Mailing options'))
mail_group.add_argument(
'--from', '--mail-from',
- metavar=_("ADDRESS"), dest="mail_from",
+ metavar=_('ADDRESS'), dest='mail_from',
help=_(
- "Sender mail address for mails generated by this script. "
- "Default: {!r}").format(mail_from),
+ 'Sender mail address for mails generated by this script. '
+ 'Default: {!r}').format(mail_from),
)
mail_group.add_argument(
'--recipients', '--mail-recipients',
- metavar=_("ADDRESS"), nargs='+', dest="mail_recipients",
- help=_("Mail addresses of all recipients for mails generated by this script.")
+ metavar=_('ADDRESS'), nargs='+', dest='mail_recipients',
+ help=_('Mail addresses of all recipients for mails generated by this script.')
)
mail_group.add_argument(
'--cc', '--mail-cc',
- metavar=_("ADDRESS"), nargs='*', dest="mail_cc",
- help=_("Mail addresses of all CC recipients for mails generated by this script.")
+ metavar=_('ADDRESS'), nargs='*', dest='mail_cc',
+ help=_('Mail addresses of all CC recipients for mails generated by this script.')
)
mail_group.add_argument(
'--reply-to', '--mail-reply-to',
- metavar=_("ADDRESS"), dest="mail_reply_to",
- help=_("Reply mail address for mails generated by this script.")
+ metavar=_('ADDRESS'), dest='mail_reply_to',
+ help=_('Reply mail address for mails generated by this script.')
)
methods = MailConfiguration.valid_mail_methods
method_list = format_list(methods, do_repr=True)
mail_group.add_argument(
'--mail-method',
- metavar=_("METHOD"), choices=methods, dest="mail_method",
+ metavar=_('METHOD'), choices=methods, dest='mail_method',
help=_(
- "Method for sending the mails generated by this script. "
- "Valid values: {v}, default: {d!r}.").format(
+ 'Method for sending the mails generated by this script. '
+ 'Valid values: {v}, default: {d!r}.').format(
v=method_list, d=mail_method)
)
mail_group.add_argument(
'--mail-server',
- metavar=_("SERVER"), dest="mail_server",
+ metavar=_('SERVER'), dest='mail_server',
help=_(
- "Mail server for submitting generated by this script if "
+ 'Mail server for submitting generated by this script if '
"the mail method of this script is 'smtp'. Default: {!r}.").format(mail_server)
)
mail_group.add_argument(
'--smtp-port',
- metavar=_("PORT"), type=int, dest='smtp_port', what="SMTP",
+ metavar=_('PORT'), type=int, dest='smtp_port', what='SMTP',
action=PortOptionAction,
help=_(
- "The port to use for submitting generated by this script if "
+ 'The port to use for submitting generated by this script if '
"the mail method of this script is 'smtp'. Default: {}.").format(smtp_port)
)
# -------------------------------------------------------------------------
def perform_arg_parser(self):
-
+ """Perform given command line parameters."""
if self.verbose > 2:
- LOG.debug(_("Got command line arguments:") + '\n' + pp(self.args))
+ LOG.debug(_('Got command line arguments:') + '\n' + pp(self.args))
super(BaseMailApplication, self).perform_arg_parser()
# -------------------------------------------------------------------------
def send_mail(self, subject, body):
-
+ """Send the mail finally."""
mail = MIMEText(body, 'plain', 'utf-8')
mail['Subject'] = subject
mail['From'] = self.cfg.mail_from
mail['Cc'] = ', '.join(self.mail_cc)
if self.verbose > 1:
- LOG.debug(_("Mail to send:") + '\n' + mail.as_string(unixfrom=True))
+ LOG.debug(_('Mail to send:') + '\n' + mail.as_string(unixfrom=True))
if self.mail_method == 'smtp':
self._send_mail_smtp(mail)
break
if not sendmail:
- msg = _("Did not found sendmail executable.")
+ msg = _('Did not found sendmail executable.')
LOG.error(msg)
return
- cmd = [sendmail, "-t", "-oi"]
- cmd_str = ' '.join(map(lambda x: pipes.quote(x), cmd))
- LOG.debug(_("Executing: {}").format(cmd_str))
+ cmd = [sendmail, '-t', '-oi']
+ cmd_str = ' '.join((pipes.quote(x) for x in cmd))
+ LOG.debug(_('Executing: {}').format(cmd_str))
p = Popen(cmd, stdin=PIPE, universal_newlines=True)
p.communicate(mail.as_string())
# =============================================================================
-if __name__ == "__main__":
+if __name__ == '__main__':
pass
# -*- coding: utf-8 -*-
"""
-@summary: An application module for mirroring one LDAP instance to another
+@summary: An application module for mirroring one LDAP instance to another.
@author: Frank Brehm
@contact: frank.brehm@pixelpark.com
from __future__ import absolute_import
# Standard modules
-import sys
-import logging
import copy
+import logging
+import sys
import time
-
from functools import cmp_to_key
# Third party modules
-# from ldap3 import MODIFY_REPLACE, MODIFY_ADD, MODIFY_DELETE
-from ldap3 import ALL_ATTRIBUTES
-
-# Own modules
# from fb_tools.common import to_bool, is_sequence
# from fb_tools.collections import FrozenCIStringSet, CIStringSet, CIDict
from fb_tools.collections import CIDict, CIStringSet
from fb_tools.xlate import format_list
-from .. import pp
-
-from ..xlate import XLATOR
-
-from ..config.mirror_ldap import MirrorLdapConfiguration
+# from ldap3 import MODIFY_REPLACE, MODIFY_ADD, MODIFY_DELETE
+from ldap3 import ALL_ATTRIBUTES
+# Own modules
# from .ldap import LdapAppError, FatalLDAPError
-from .ldap import LdapAppError
from .ldap import BaseLdapApplication
-
-from ..argparse_actions import NonNegativeItegerOptionAction
+from .ldap import LdapAppError
+from .. import pp
from ..argparse_actions import LimitedFloatOptionAction
+from ..argparse_actions import NonNegativeItegerOptionAction
+from ..config.mirror_ldap import MirrorLdapConfiguration
+from ..xlate import XLATOR
-__version__ = '0.9.1'
+__version__ = '0.9.2'
LOG = logging.getLogger(__name__)
_ = XLATOR.gettext
# -------------------------------------------------------------------------
def __init__(self, appname=None, base_dir=None):
-
+ """Initialize this application object."""
self.src_instance = None
self.tgt_instance = None
self.sync_entry_dns = []
desc = _(
- "Mirror the content of a complete LDAP instance (server or cluster) to "
- "another instance. This will be done first by clearing the target instance, "
- "then copying structural entries from the source to the target instance and "
- "then copying all other entries. During this some transformations are done, like "
- "substituting the content of some entry attributes by another values."
+ 'Mirror the content of a complete LDAP instance (server or cluster) to '
+ 'another instance. This will be done first by clearing the target instance, '
+ 'then copying structural entries from the source to the target instance and '
+ 'then copying all other entries. During this some transformations are done, like '
+ 'substituting the content of some entry attributes by another values.'
)
- self._force_desc_msg = _("Do not execute a countdown before starting the application.")
+ self._force_desc_msg = _('Do not execute a countdown before starting the application.')
super(MirrorLdapApplication, self).__init__(
appname=appname, description=desc, base_dir=base_dir,
# -------------------------------------------------------------------------
def init_arg_parser(self):
-
- app_group = self.arg_parser.add_argument_group(_("Miroring options"))
+ """Initialize specific command line parameters."""
+ app_group = self.arg_parser.add_argument_group(_('Miroring options'))
app_group.add_argument(
'-W', '--wait', '--wait-after-write', dest='wait', type=float, metavar=_('SECONDS'),
action=LimitedFloatOptionAction, min_val=0,
help=_(
- "Number of seconds to wait after each write operation. Given as a "
- "float value, and if set to zero, there is no waiting after a write. "
- "(default: {:.1f})").format(self.default_wait_after_write),
+ 'Number of seconds to wait after each write operation. Given as a '
+ 'float value, and if set to zero, there is no waiting after a write. '
+ '(default: {:.1f})').format(self.default_wait_after_write),
)
app_group.add_argument(
'-L', '--limit', dest='limit', type=int, metavar=_('NUMBER'),
action=NonNegativeItegerOptionAction,
help=_(
- "Limiting the mirroring to the first NUMBER entries. "
- "This option is valid only in simulation mode."),
+ 'Limiting the mirroring to the first NUMBER entries. '
+ 'This option is valid only in simulation mode.'),
)
app_group.add_argument(
- '-S', '--struct', '--only-struct', action="store_true", dest="struct",
- help=_("Mirror only structural entries (entries with childs)."),
+ '-S', '--struct', '--only-struct', action='store_true', dest='struct',
+ help=_('Mirror only structural entries (entries with childs).'),
)
super(MirrorLdapApplication, self).init_arg_parser()
# -------------------------------------------------------------------------
def post_init(self):
"""Execute some actions after initialising."""
-
super(MirrorLdapApplication, self).post_init()
limit = getattr(self.args, 'limit', 0)
if self.simulate:
self.limit = limit
LOG.warn(_(
- "Limiting the number of entries for mirroring to {} "
- "entries.").format(limit))
+ 'Limiting the number of entries for mirroring to {} '
+ 'entries.').format(limit))
else:
LOG.error(_(
- "Limition the number of entries for mirroring may "
- "only be done in simulation mode."))
+ 'Limition the number of entries for mirroring may '
+ 'only be done in simulation mode.'))
self.empty_line()
self.arg_parser.print_usage(sys.stdout)
self.exit(1)
if self.tgt_instance not in self.cfg.entries_keep:
if self.verbose > 4:
- LOG.debug(_("Did not found {tgt!r} in {e}:").format(
+ LOG.debug(_('Did not found {tgt!r} in {e}:').format(
tgt=self.tgt_instance, e='self.cfg.entries_keep') + '\n' + pp(
self.cfg.entries_keep))
return
tgt_name = self.ldap_instances[0]
self.tgt_connect_info = self.cfg.ldap_connection[tgt_name]
LOG.debug(_(
- "Checking mirror source instance for target instance {!r} ...").format(tgt_name))
+ 'Checking mirror source instance for target instance {!r} ...').format(tgt_name))
src_name = self.cfg.ldap_connection[tgt_name].sync_source
- LOG.debug(_("Got {!r} as the mirror source instance.").format(src_name))
+ LOG.debug(_('Got {!r} as the mirror source instance.').format(src_name))
if src_name not in self.cfg.ldap_connection:
- msg = _("Error in configuration:")
+ msg = _('Error in configuration:')
msg += ' ' + _(
- "the source LDAP instance {src!r} for mirroring to {tgt!r} "
- "does not exists.").format(src=src_name, tgt=tgt_name)
+ 'the source LDAP instance {src!r} for mirroring to {tgt!r} '
+ 'does not exists.').format(src=src_name, tgt=tgt_name)
LOG.error(msg)
self.exit(3)
self.src_connect_info = self.cfg.ldap_connection[src_name]
if tgt_name.lower() == src_name.lower():
- msg = _("Error in configuration:")
+ msg = _('Error in configuration:')
msg += ' ' + _(
- "the source LDAP instance {src!r} must not be the same like the "
- "target instance.").format(src=src_name)
+ 'the source LDAP instance {src!r} must not be the same like the '
+ 'target instance.').format(src=src_name)
LOG.error(msg)
self.exit(3)
tgt_base_dn = self.cfg.ldap_connection[tgt_name].base_dn
if src_base_dn != tgt_base_dn:
- msg = _("Error in configuration:")
+ msg = _('Error in configuration:')
msg += ' ' + _(
- "the base DN {src_dn!r} of the source instance {src!r} does not match the "
- "base DN {tgt_dn!r} of the target instance {tgt!r}.").format(
+ 'the base DN {src_dn!r} of the source instance {src!r} does not match the '
+ 'base DN {tgt_dn!r} of the target instance {tgt!r}.').format(
src_dn=src_base_dn, src=src_name, tgt_dn=tgt_base_dn, tgt=tgt_name)
LOG.error(msg)
self.exit(3)
src_url = self.cfg.ldap_connection[self.src_instance].url
tgt_url = self.cfg.ldap_connection[self.tgt_instance].url
msg = _(
- "Start mirroring LDAP instance {src!r} ({src_url}) to instance {tgt!r} ({tgt_url}) "
- "[{yes}/{no}]?").format(
+ 'Start mirroring LDAP instance {src!r} ({src_url}) to instance {tgt!r} ({tgt_url}) '
+ '[{yes}/{no}]?').format(
src=self.src_instance, src_url=src_url, tgt=self.tgt_instance, tgt_url=tgt_url,
yes=self.colored(_('yes'), 'RED'), no=self.colored(_('No'), 'GREEN')) + ' '
answer = self.ask_for_yes_or_no(msg)
if not answer:
self.empty_line()
- LOG.error(_("Interrupted on demand."))
+ LOG.error(_('Interrupted on demand.'))
self.exit(3)
if not self.quiet and not self.force:
self.empty_line()
msg = _(
- "Start mirroring LDAP instance {src!r} ({src_url}) to instance {tgt!r} "
- "({tgt_url}) ...").format(
+ 'Start mirroring LDAP instance {src!r} ({src_url}) to instance {tgt!r} '
+ '({tgt_url}) ...').format(
src=self.src_instance, src_url=src_url, tgt=self.tgt_instance, tgt_url=tgt_url)
self.countdown(number=5, delay=1, prompt=msg)
self.empty_line()
msg = ngettext(
- "{:>5} entry deleted.", "{:>5} entries deleted.", self.total_deleted).format(
+ '{:>5} entry deleted.', '{:>5} entries deleted.', self.total_deleted).format(
self.total_deleted)
msg += ' ' + ngettext(
- "{:>5} entry updated.", "{:>5} entries updated.", self.total_updated).format(
+ '{:>5} entry updated.', '{:>5} entries updated.', self.total_updated).format(
self.total_updated)
msg += ' ' + ngettext(
- "{:>5} entry created.", "{:>5} entries created.", self.total_created).format(
+ '{:>5} entry created.', '{:>5} entries created.', self.total_created).format(
self.total_created)
LOG.info(msg)
if not self.quiet:
self.empty_line()
- title = _("Changes total:")
+ 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(
+ '{:>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(
+ '{:>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(
+ '{:>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.")
+ msg = _('Got a {}:').format('KeyboardInterrupt') + ' ' + _('Interrupted on demand.')
LOG.error(msg)
self.exit(10)
self.empty_line()
- LOG.info(_("Finished."))
+ LOG.info(_('Finished.'))
# -------------------------------------------------------------------------
def get_current_src_entries(self):
"""Get DNs of all entries in the source LDAP instance and sort them."""
-
self.empty_line()
self.line(color='CYAN')
- LOG.info(_("Trying to get DNs of all entries in the source LDAP instance."))
+ LOG.info(_('Trying to get DNs of all entries in the source LDAP instance.'))
self.src_dns = self.get_all_entry_dns_hash(self.src_instance)
- sorted_dns = sorted(list(self.src_dns.keys()), key=cmp_to_key(self.compare_ldap_dns))
+ sorted_dns = sorted(self.src_dns.keys(), key=cmp_to_key(self.compare_ldap_dns))
for dn in sorted_dns:
self.register_dn_tokens(dn, self.src_dns[dn], self.src_dns)
if self.verbose > 2:
if self.verbose > 4:
- LOG.debug("Current source entries:\n" + pp(self.src_dns.dict()))
+ LOG.debug('Current source entries:\n' + pp(self.src_dns.dict()))
else:
- msg = _("Found DNs in instance {!r}:").format(self.src_instance)
+ msg = _('Found DNs in instance {!r}:').format(self.src_instance)
LOG.debug(msg + '\n' + pp(sorted_dns))
self.src_struct_dns = CIStringSet()
msgs = []
msgs.append(ngettext(
- "Found total one entry in source LDAP", "Found {no} entries in source LDAP",
+ 'Found total one entry in source LDAP', 'Found {no} entries in source LDAP',
no_total).format(no=no_total))
msgs.append(ngettext(
- "one structural entry in source LDAP", "{no} structural entries in source LDAP",
+ 'one structural entry in source LDAP', '{no} structural entries in source LDAP',
no_struct).format(no=no_struct))
msgs.append(ngettext(
- "one non-structural entry in source LDAP.",
- "{no} non-structural entries in source LDAP.",
+ 'one non-structural entry in source LDAP.',
+ '{no} non-structural entries in source LDAP.',
no_non_struct).format(no=no_non_struct))
LOG.info(format_list(msgs))
if self.verbose > 2:
- msg = _("Found structural DNs in instance {!r}:").format(self.src_instance)
+ msg = _('Found structural DNs in instance {!r}:').format(self.src_instance)
LOG.debug(msg + '\n' + pp(self.src_struct_dns.as_list()))
# -------------------------------------------------------------------------
def get_current_tgt_entries(self):
"""Get DNs of all entries in the target LDAP instance and sort them."""
-
self.empty_line()
self.line(color='CYAN')
- LOG.info(_("Trying to get DNs of all entries in the target LDAP instance."))
+ LOG.info(_('Trying to get DNs of all entries in the target LDAP instance.'))
self.tgt_dns_current = self.get_all_entry_dns_hash(self.tgt_instance)
sorted_dns = sorted(
- list(self.tgt_dns_current.keys()), key=cmp_to_key(self.compare_ldap_dns))
+ self.tgt_dns_current.keys(), key=cmp_to_key(self.compare_ldap_dns))
for dn in sorted_dns:
self.register_dn_tokens(dn, self.tgt_dns_current[dn], self.tgt_dns_current)
if self.verbose > 2:
if self.verbose > 4:
- LOG.debug("Current target entries:\n" + pp(self.tgt_dns_current.dict()))
+ LOG.debug('Current target entries:\n' + pp(self.tgt_dns_current.dict()))
else:
- msg = _("Found DNs in instance {!r}:").format(self.tgt_instance)
+ msg = _('Found DNs in instance {!r}:').format(self.tgt_instance)
LOG.debug(msg + '\n' + pp(sorted_dns))
self.tgt_struct_dns_current = CIStringSet()
msgs = []
msgs.append(ngettext(
- "Found total one entry in target LDAP", "Found {no} entries in target LDAP",
+ 'Found total one entry in target LDAP', 'Found {no} entries in target LDAP',
no_total).format(no=no_total))
msgs.append(ngettext(
- "one structural entry in target LDAP", "{no} structural entries in target LDAP",
+ 'one structural entry in target LDAP', '{no} structural entries in target LDAP',
no_struct).format(no=no_struct))
msgs.append(ngettext(
- "one non-structural entry in target LDAP.",
- "{no} non-structural entries in target LDAP.",
+ 'one non-structural entry in target LDAP.',
+ '{no} non-structural entries in target LDAP.',
no_non_struct).format(no=no_non_struct))
LOG.info(format_list(msgs))
if self.verbose > 2:
- msg = _("Found structural DNs in instance {!r}:").format(self.tgt_instance)
+ msg = _('Found structural DNs in instance {!r}:').format(self.tgt_instance)
LOG.debug(msg + '\n' + pp(self.tgt_struct_dns_current.as_list()))
# -------------------------------------------------------------------------
def eval_sync_entries(self):
- """Evaluating entries, which have to be synced, instead of to be removed and recreated."""
-
+ """Evaluate entries, which have to be synced, instead of to be removed and recreated."""
self.sync_entry_dns = []
LOG.debug(_(
- "Evaluating DNs of all target entries, which have to be synchronized, "
- "instead of removing and recreating them."))
+ 'Evaluating DNs of all target entries, which have to be synchronized, '
+ 'instead of removing and recreating them.'))
base_dn = self.tgt_connect_info.base_dn
self.sync_entry_dns.append(parent_dn)
if self.verbose > 1:
- LOG.debug("DNs of sync entries:\n" + pp(self.sync_entry_dns))
+ LOG.debug('DNs of sync entries:\n' + pp(self.sync_entry_dns))
# -------------------------------------------------------------------------
def register_dn_tokens(self, dn, entry, registry):
-
+ """Register DN tokens on their parent tokens."""
if self.verbose > 4:
- LOG.debug("Trying to register DN {!r} ...".format(dn))
+ LOG.debug('Trying to register DN {!r} ...'.format(dn))
parent_tokens = copy.copy(entry['path'])[0:-1]
if not parent_tokens:
return
parent_dn = ','.join(reversed(parent_tokens))
if self.verbose > 4:
- LOG.debug("Parent DN: {!r}.".format(parent_dn))
+ LOG.debug('Parent DN: {!r}.'.format(parent_dn))
registry[dn]['parent'] = parent_dn
if parent_dn not in registry:
if self.verbose > 1:
- LOG.debug("Entry {!r} seems to be a the root DN.".format(dn))
+ LOG.debug('Entry {!r} seems to be a the root DN.'.format(dn))
return
if not 'childs' not in registry[parent_dn]:
# -------------------------------------------------------------------------
def clean_tgt_non_struct_entries(self):
- """Removing non structural entries in target instance.
+ """
+ Remove non structural entries in target instance.
Only those entries are removed, which are no more existing in the source instance.
Structural entries are entries without any childs.
"""
-
self.empty_line()
self.line(color='CYAN')
- LOG.info(_("Removing non structural entries from target LDAP instance."))
+ LOG.info(_('Removing non structural entries from target LDAP instance.'))
if not self.quiet:
time.sleep(2)
self.empty_line()
count = 0
- for dn in sorted(list(self.tgt_dns_current.keys()), key=cmp_to_key(self.compare_ldap_dns)):
+ for dn in sorted(self.tgt_dns_current.keys(), key=cmp_to_key(self.compare_ldap_dns)):
entry = self.tgt_dns_current[dn]
if 'childs' not in entry:
- LOG.error("Found entry {dn!r}:\n{e}".format(dn=dn, e=pp(entry)))
+ LOG.error('Found entry {dn!r}:\n{e}'.format(dn=dn, e=pp(entry)))
self.exit(5)
if dn in self.src_dns:
if self.verbose > 4:
- msg = _("Entry {!r} exists on the source instance, will not be removed.")
+ msg = _('Entry {!r} exists on the source instance, will not be removed.')
LOG.debug(msg.format(dn))
continue
if entry['childs']:
if self.verbose > 4:
msg = _(
- "Entry {!r} is a structural entry, will not be removed at this point.")
+ 'Entry {!r} is a structural entry, will not be removed at this point.')
LOG.debug(msg.format(dn))
continue
if dn in self.keep_entry_dns:
if self.verbose > 1:
- LOG.debug(_("Entry {!r} is set to be kept.").format(dn))
+ LOG.debug(_('Entry {!r} is set to be kept.').format(dn))
continue
self.empty_line()
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.",
+ 'Removed one not structural entry in target LDAP instance.',
+ 'Removed {no} not structural entries in target LDAP instance.',
count).format(no=count)
else:
- msg = _("None not structural entries in target LDAP instance removed.")
+ msg = _('None not structural entries in target LDAP instance removed.')
LOG.info(msg)
# -------------------------------------------------------------------------
def clean_tgt_struct_entries(self):
- """Removing structural entries in target instance.
+ """
+ Remove structural entries in target instance.
Only those entries are removed, which are no more existing in the source instance.
Structural entries are entries without any childs.
"""
-
self.empty_line()
self.line(color='CYAN')
- LOG.info(_("Removing structural entries from target LDAP instance."))
+ LOG.info(_('Removing structural entries from target LDAP instance.'))
if not self.quiet:
time.sleep(2)
self.empty_line()
if dn in self.src_dns:
if self.verbose > 4:
- msg = _("Entry {!r} exists on the source instance, will not be removed.")
+ msg = _('Entry {!r} exists on the source instance, will not be removed.')
LOG.debug(msg.format(dn))
continue
if dn in self.keep_entry_dns:
if self.verbose > 1:
- LOG.debug(_("Entry {!r} is set to be kept.").format(dn))
+ LOG.debug(_('Entry {!r} is set to be kept.').format(dn))
continue
if dn in self.sync_entry_dns:
if self.verbose > 1:
- LOG.debug(_("Entry {!r} is set to be synchronized.").format(dn))
+ LOG.debug(_('Entry {!r} is set to be synchronized.').format(dn))
continue
self.empty_line()
if count:
self.empty_line()
msg = ngettext(
- "Removed one structural entry in target LDAP instance.",
- "Removed {no} structural entries in target LDAP instance.",
+ 'Removed one structural entry in target LDAP instance.',
+ 'Removed {no} structural entries in target LDAP instance.',
count).format(no=count)
else:
- msg = _("None structural entries in target LDAP instance removed.")
+ msg = _('None structural entries in target LDAP instance removed.')
LOG.info(msg)
# -------------------------------------------------------------------------
def mirror_struct_entries(self):
- """Mirroring all structural entries."""
+ """Mirror all structural entries."""
self.empty_line()
self.line(color='CYAN')
- LOG.info(_("Mirroring structural entries from source to target LDAP instance."))
+ LOG.info(_('Mirroring structural entries from source to target LDAP instance.'))
if not self.quiet:
time.sleep(2)
if dn in self.keep_entry_dns:
if self.verbose > 1:
- LOG.debug(_("Entry {!r} is set to be kept.").format(dn))
+ LOG.debug(_('Entry {!r} is set to be kept.').format(dn))
continue
if self.verbose > 1:
- LOG.debug(_("Mirroring entry {!r} ...").format(dn))
+ 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)
+ msg = _('Did not found {!r} in the source LDAP.').format(dn)
LOG.warn(msg)
continue
src_attribs = self.normalized_attributes(
src_attribs_dict['objectClass'] = src_oclasses
if self.verbose > 2:
- LOG.debug("Got source entry:\n" + pp(src_attribs_dict))
+ 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_dict['objectClass'] = tgt_oclasses
if self.verbose > 2:
- LOG.debug("Got target entry:\n" + pp(tgt_attribs_dict))
+ 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.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
time.sleep(self.wait_after_write)
else:
if self.verbose > 1:
- LOG.debug(_("No changes necessary on DN {!r}.").format(dn))
+ LOG.debug(_('No changes necessary on DN {!r}.').format(dn))
continue
else:
- LOG.debug(_("Target entry {!r} not found.").format(dn))
+ 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)
+ 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)
+ msg += '\nAttributes:\n' + pp(target_entry)
LOG.debug(msg)
self.add_entry(self.tgt_instance, dn, object_classes, target_entry)
self.mirrored_entries += 1
if count:
self.empty_line()
msg = ngettext(
- "Mirrored one structural entry in target LDAP instance.",
- "Mirrored {no} structural entries to target LDAP instance.",
+ 'Mirrored one structural entry in target LDAP instance.',
+ 'Mirrored {no} structural entries to target LDAP instance.',
count).format(no=count)
else:
- msg = _("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."""
+ """Mirror all non-structural entries."""
self.empty_line()
self.line(color='CYAN')
- LOG.info(_("Mirroring non-structural entries from source to target LDAP instance."))
+ 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))
+ dns = sorted(self.src_dns.keys(), key=cmp_to_key(self.compare_ldap_dns))
count = 0
if dn in self.keep_entry_dns:
if self.verbose > 1:
- LOG.debug(_("Entry {!r} is set to be kept.").format(dn))
+ LOG.debug(_('Entry {!r} is set to be kept.').format(dn))
continue
if self.verbose > 1:
- LOG.debug(_("Mirroring entry {!r} ...").format(dn))
+ 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)
+ msg = _('Did not found {!r} in the source LDAP.').format(dn)
LOG.warn(msg)
continue
src_attribs = self.normalized_attributes(
src_attribs_dict['objectClass'] = src_oclasses
if self.verbose > 2:
- LOG.debug("Got source entry:\n" + pp(src_attribs_dict))
+ 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_dict['objectClass'] = tgt_oclasses
if self.verbose > 2:
- LOG.debug("Got target entry:\n" + pp(tgt_attribs_dict))
+ 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.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
time.sleep(self.wait_after_write)
else:
if self.verbose > 1:
- LOG.debug(_("No changes necessary on DN {!r}.").format(dn))
+ LOG.debug(_('No changes necessary on DN {!r}.').format(dn))
continue
else:
- LOG.debug(_("Target entry {!r} not found.").format(dn))
+ 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)
+ 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)
+ msg += '\nAttributes:\n' + pp(target_entry)
LOG.debug(msg)
self.add_entry(self.tgt_instance, dn, object_classes, target_entry)
self.mirrored_entries += 1
if count:
self.empty_line()
msg = ngettext(
- "Mirrored one non-structural entry in target LDAP instance.",
- "Mirrored {no} non-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.")
+ msg = _('Mirrored none not-structural entries to target LDAP instance.')
LOG.info(msg)
# -------------------------------------------------------------------------
def update_memberships(self):
- """Updating all 'member' and 'uniqueMember' attributes."""
+ """Update 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."))
+ 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))
+ dns = sorted(self.src_dns.keys(), key=cmp_to_key(self.compare_ldap_dns))
count = 0
if dn in self.keep_entry_dns:
if self.verbose > 1:
- LOG.debug(_("Entry {!r} is set to be kept.").format(dn))
+ 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))
+ 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)
+ 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))
+ 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))
+ 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))
+ 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.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
time.sleep(self.wait_after_write * 2)
else:
if self.verbose > 1:
- LOG.debug(_("No changes necessary on DN {!r}.").format(dn))
+ 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.",
+ 'Mirrored one group entry in target LDAP instance.',
+ 'Mirrored {no} group entries to target LDAP instance.',
count).format(no=count)
else:
- msg = _("Mirrored no group entries to target LDAP instance.")
+ msg = _('Mirrored no group entries to target LDAP instance.')
LOG.info(msg)
# =============================================================================
-if __name__ == "__main__":
+if __name__ == '__main__':
pass