From 760de13bd3af6899748f21ed37840167a6e63242 Mon Sep 17 00:00:00 2001 From: Frank Brehm Date: Wed, 10 May 2023 13:07:49 +0200 Subject: [PATCH] Completing and evaluating command line options of eval-duplicate-ldap-attributes --- lib/pp_admintools/app/duplicate_attribs.py | 90 +++++++++++++++++++++- 1 file changed, 87 insertions(+), 3 deletions(-) diff --git a/lib/pp_admintools/app/duplicate_attribs.py b/lib/pp_admintools/app/duplicate_attribs.py index f8591ad..ffad4bd 100644 --- a/lib/pp_admintools/app/duplicate_attribs.py +++ b/lib/pp_admintools/app/duplicate_attribs.py @@ -10,6 +10,8 @@ from __future__ import absolute_import # Standard modules import logging import copy +import re +import sys # Third party modules from fb_tools.xlate import format_list @@ -22,7 +24,7 @@ from ..xlate import XLATOR from .ldap import LdapAppError, FatalLDAPError from .ldap import BaseLdapApplication -__version__ = '0.1.0' +__version__ = '0.2.0' LOG = logging.getLogger(__name__) _ = XLATOR.gettext @@ -33,8 +35,13 @@ ngettext = XLATOR.ngettext class EvalDuplicateAttribsApplication(BaseLdapApplication): """Application class for evaluating duplicate attributes, which should be unique, in LDAP.""" + use_default_ldap_connection = False + use_multiple_ldap_connections = False + show_cmdline_ldap_timeout = True + apply_default_ldap_instance_if_not_given = True + default_uniq_attributes = ['uid', 'uidNumber', 'mail'] - default_dpendend_uniq_attribs = { + default_dependend_uniq_attribs = { 'gidNumber': 'objectClass=posixGroup', } @@ -42,7 +49,7 @@ class EvalDuplicateAttribsApplication(BaseLdapApplication): def __init__(self, appname=None, base_dir=None): """Constructor.""" self.uniq_attributes = copy.copy(self.default_uniq_attributes) - self.dpendend_uniq_attribs = copy.copy(self.default_dpendend_uniq_attribs) + self.dependend_uniq_attribs = copy.copy(self.default_dependend_uniq_attribs) self.result = {} desc = _( @@ -68,6 +75,18 @@ class EvalDuplicateAttribsApplication(BaseLdapApplication): ) + ' ' + format_list(self.default_uniq_attributes, do_repr=True), ) + eval_group.add_argument( + '--dependend-attribs', nargs='*', dest='dependend_attribs', metavar=_('ATTRIBUTE'), + help=_( + "All attributes, where their uniqueness depends on an additional " + "LDAP filter. For instance, dhe attribute 'gidNumber' should be unique for " + "all entries, which are using the objectClass 'posixGroup'. The value " + "for this argument should be in the form: 'ATTRIBUTE: \"FILTER\"'. For the latter " + "example this would be: 'gidNumber: \"objectClass=posixGroup\"' (which " + "is also the default for this option). Please note, that this filter will " + "be wrapped by parenthesis.") + ) + super(EvalDuplicateAttribsApplication, self).init_arg_parser() # ------------------------------------------------------------------------- @@ -76,11 +95,76 @@ class EvalDuplicateAttribsApplication(BaseLdapApplication): super(EvalDuplicateAttribsApplication, self)._verify_instances( is_admin=False, readonly=True) + # ------------------------------------------------------------------------- + def post_init(self): + """ + Method to execute before calling run(). + """ + + super(EvalDuplicateAttribsApplication, self).post_init() + + pat_dep_attribs = r'^(?P[a-z](?:[a-z0-9-]*[a-z0-9])?):\s*' + pat_dep_attribs += r'(?P[\'"])?(?P.+)(?P=quote)?$' + if self.verbose > 2: + LOG.debug("Pattern for verifying dependend unique attributes: {!r}".format( + pat_dep_attribs)) + re_dep_attribs = re.compile(pat_dep_attribs, re.IGNORECASE) + + given_unique_attribs = getattr(self.args, 'uniq_attribs', []) + if given_unique_attribs: + self.uniq_attributes = given_unique_attribs + + dependend_attribs = getattr(self.args, 'dependend_attribs', []) + wrong_attribs = False + if dependend_attribs: + dep_attribs = {} + for attrib in dependend_attribs: + m = re_dep_attribs.match(attrib) + if m: + attr_name = m.group('attrib') + attr_filter = m.group('filter') + dep_attribs[attr_name] = attr_filter + else: + wrong_attribs = True + msg = _("Wrong definition if a filter dependend unique attribute given:") + msg += ' {!r}'.format(attrib) + LOG.error(msg) + if wrong_attribs: + self.empty_line() + self.arg_parser.print_usage(sys.stdout) + self.exit(1) + self.dependend_uniq_attribs = dep_attribs + # ------------------------------------------------------------------------- def _run(self): LOG.info("And here we go ...") + for attrib in self.uniq_attributes: + self.empty_line() + msg1 = _("Checking for globally unique attribute '") + msg2 = _("' ...") + msg_oc = msg1 + attrib + msg2 + msg_c = ( + self.colored(msg1, 'cyan') + self.colored(attrib, 'GREEN') + self.colored( + msg2, 'cyan')) + print(msg_c) + self.line(len(msg_oc)) + + for attrib in self.dependend_uniq_attribs.keys(): + flter = self.dependend_uniq_attribs[attrib] + self.empty_line() + msg1 = _("Checking for dependend unique attribute '") + msg2 = _("' ...") + msg_oc = msg1 + attrib + msg2 + msg_c = ( + self.colored(msg1, 'cyan') + self.colored(attrib, 'GREEN') + self.colored( + msg2, 'cyan')) + print(msg_c) + self.line(len(msg_oc)) + print(_('Used filter:') + ' ' + flter) + + self.empty_line() # ============================================================================= if __name__ == "__main__": -- 2.39.5