---
mirror-ldap:
+
keep-entries:
dpx-dev:
- 'cn=Replication monitor,o=isp'
- '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'
+ modify-entries:
+ dpx-dev:
+ 'dc=dpx-int.de,ou=Domains,o=Pixelpark,o=isp':
+ replace:
+ preferredMailHost: 'dev-imap01.pixelpark.com'
+ 'dc=mail.pixelpark.net,ou=Domains,o=Pixelpark,o=isp':
+ replace:
+ preferredMailHost: 'dev-imap01.pixelpark.com'
+ 'dc=pixelpark.com,ou=Domains,o=Pixelpark,o=isp':
+ replace:
+ preferredMailHost: 'dev-imap01.pixelpark.com'
+ 'dc=pixelpark.de,ou=Domains,o=Pixelpark,o=isp':
+ replace:
+ preferredMailHost: 'dev-imap01.pixelpark.com'
+ 'dc=wildpark.de,ou=Domains,o=Wildpark,o=isp':
+ replace:
+ preferredMailHost: 'dev-imap01.pixelpark.com'
+ dpx-dev-new:
+ 'dc=dpx-int.de,ou=Domains,o=Pixelpark,o=isp':
+ replace:
+ preferredMailHost: 'dev-imap01.pixelpark.com'
+ 'dc=mail.pixelpark.net,ou=Domains,o=Pixelpark,o=isp':
+ replace:
+ preferredMailHost: 'dev-imap01.pixelpark.com'
+ 'dc=pixelpark.com,ou=Domains,o=Pixelpark,o=isp':
+ replace:
+ preferredMailHost: 'dev-imap01.pixelpark.com'
+ 'dc=pixelpark.de,ou=Domains,o=Pixelpark,o=isp':
+ replace:
+ preferredMailHost: 'dev-imap01.pixelpark.com'
+ 'dc=wildpark.de,ou=Domains,o=Wildpark,o=isp':
+ replace:
+ preferredMailHost: 'dev-imap01.pixelpark.com'
+
# vim: filetype=yaml
# Third party modules
from fb_tools.common import is_sequence
from fb_tools.multi_config import DEFAULT_ENCODING
+from fb_tools.xlate import format_list
# Own modules
from .ldap import LdapConfigError, LdapConfiguration
pat_keep_entries_key = r'^\s*keep[_-]?entries\s*$'
re_keep_entries_key = re.compile(pat_keep_entries_key, re.IGNORECASE)
+ pat_modify_entries_key = r'^\s*modify[_-]?entries\s*$'
+ re_modify_entries_key = re.compile(pat_modify_entries_key, re.IGNORECASE)
+
+ valid_modify_actions = ('add', 'replace', 'delete')
+
# -------------------------------------------------------------------------
def __init__(
self, appname=None, verbose=0, version=__version__, base_dir=None,
"""Initialize the MirrorLdapConfiguration object."""
self.entries_keep = {}
self.transform = {}
+ self.entries_mofify = {}
+
+ self.action_list = format_list(self.valid_modify_actions, do_repr=True)
add_stems = []
if additional_stems:
for sub_section_name in section.keys():
+ if self.verbose > 2:
+ LOG.debug(_('Evaluating sub section {sn!r} ...').format(sn=sub_section_name))
+
sub_section = section[sub_section_name]
if self.re_keep_entries_key.match(sub_section_name):
self._eval_entries_keep(section_name, sub_section_name, sub_section)
continue
+ if self.re_modify_entries_key.match(sub_section_name):
+ self._eval_entries_modify(section_name, sub_section_name, sub_section)
+
# -------------------------------------------------------------------------
def _eval_entries_keep(self, section_name, sub_section_name, sub_section):
sub_section = section[sub_section_name]
sn = str(section_name) + '/' + str(sub_section_name)
- if self.verbose > 2:
+ if self.verbose > 1:
LOG.debug(_('Evaluating configuration section {sn!r} ...').format(sn=sn))
if self.verbose > 2:
self.entries_keep[inst_name].append(inst_entries)
return
+ # -------------------------------------------------------------------------
+ def _eval_entries_modify(self, section_name, sub_section_name, sub_section):
+
+ section = self.cfg[section_name]
+ sub_section = section[sub_section_name]
+ sn = str(section_name) + '/' + str(sub_section_name)
+
+ if self.verbose > 1:
+ LOG.debug(_('Evaluating configuration section {sn!r} ...').format(sn=sn))
+
+ if self.verbose > 2:
+ LOG.debug('Section:\n' + pp(sub_section))
+
+ if not isinstance(sub_section, Mapping):
+ LOG.warning(_('Section {sn!r} is not a {what}.').format(
+ sn=sn, what='Mapping (dict)'))
+ return
+
+ for inst_name in sub_section.keys():
+ inst_section = sub_section[inst_name]
+ inst_section_name = sn + '/' + str(inst_name)
+
+ self._eval_modify_inst(inst_name, inst_section_name, inst_section)
+
+ # -------------------------------------------------------------------------
+ def _eval_modify_inst(self, inst_name, inst_section_name, inst_section):
+
+ if self.verbose > 1:
+ LOG.debug(_('Evaluating configuration section {sn!r} ...').format(sn=inst_section_name))
+
+ if not isinstance(inst_section, Mapping):
+ LOG.warning(_('Section {sn!r} is not a {what}.').format(
+ sn=inst_section_name, what='Mapping (dict)'))
+ return
+
+ for dn_pattern in inst_section.keys():
+
+ dn_section = inst_section[dn_pattern]
+ dn_section_name = inst_section_name + '/' + dn_pattern
+
+ self._eval_modify_dn_pattern(dn_section_name, dn_pattern, dn_section, inst_name)
+
+ # -------------------------------------------------------------------------
+ def _eval_modify_dn_pattern(self, dn_section_name, dn_pattern, dn_section, inst_name):
+
+ if self.verbose > 2:
+ LOG.debug(_('Evaluating configuration section {sn!r} ...').format(sn=dn_section_name))
+
+ if not isinstance(dn_section, Mapping):
+ LOG.warning(_('Section {sn!r} is not a {what}.').format(
+ sn=dn_section_name, what='Mapping (dict)'))
+ return
+
+ for action in dn_section.keys():
+
+ action_lc = action.lower()
+ if action_lc not in self.valid_modify_actions:
+ msg = _(
+ 'Invalid action {a!r} in section {sn!r} found. An action must be '
+ 'one of {lst}.').format(
+ a=action, sn=dn_section_name, lst=self.action_list)
+ LOG.warning(msg)
+ return
+
+ action_section_name = dn_section_name + '/' + action
+ action_section = dn_section[action]
+
+ self._eval_mofify_action(
+ action_section_name, action_lc, action_section, inst_name, dn_pattern)
+
+ # -------------------------------------------------------------------------
+ def _eval_mofify_action(
+ self, action_section_name, action_lc, action_section, inst_name, dn_pattern):
+
+ if self.verbose > 2:
+ LOG.debug(_('Evaluating configuration section {sn!r} ...').format(sn=action_section_name))
+
+ if not isinstance(action_section, Mapping):
+ LOG.warning(_('Section {sn!r} is not a {what}.').format(
+ sn=action_section_name, what='Mapping (dict)'))
+ return
+
+ for entry in action_section.keys():
+ val = action_section[entry]
+ if val in (None, '', []):
+ if action_lc == 'delete':
+ self._set_modify_action(inst_name, dn_pattern, action_lc, entry, None)
+ continue
+ msg = _('Empty value for section {sn!r} found.').format(action_section_name)
+ continue
+ if is_sequence(val):
+ for value in val:
+ self._set_modify_action(inst_name, dn_pattern, action_lc, entry, str(value))
+ else:
+ self._set_modify_action(inst_name, dn_pattern, action_lc, entry, str(val))
+
+ # -------------------------------------------------------------------------
+ def _set_modify_action(self, inst_name, dn_pattern, action_lc, entry, value):
+
+ if inst_name not in self.entries_mofify:
+ self.entries_mofify[inst_name] = {}
+ if dn_pattern not in self.entries_mofify[inst_name]:
+ self.entries_mofify[inst_name][dn_pattern] = {}
+ if action_lc not in self.entries_mofify[inst_name][dn_pattern]:
+ self.entries_mofify[inst_name][dn_pattern][action_lc] = {}
+ if entry not in self.entries_mofify[inst_name][dn_pattern][action_lc]:
+ self.entries_mofify[inst_name][dn_pattern][action_lc][entry] = None
+ if value is not None:
+ if self.entries_mofify[inst_name][dn_pattern][action_lc][entry] is None:
+ self.entries_mofify[inst_name][dn_pattern][action_lc][entry] = []
+ if value not in self.entries_mofify[inst_name][dn_pattern][action_lc][entry]:
+ self.entries_mofify[inst_name][dn_pattern][action_lc][entry].append(value)
+
# =============================================================================
if __name__ == '__main__':