]> Frank Brehm's Git Trees - pixelpark/pp-admin-tools.git/commitdiff
Completing and evaluating command line options of eval-duplicate-ldap-attributes
authorFrank Brehm <frank.brehm@pixelpark.com>
Wed, 10 May 2023 11:07:49 +0000 (13:07 +0200)
committerFrank Brehm <frank.brehm@pixelpark.com>
Wed, 10 May 2023 11:07:49 +0000 (13:07 +0200)
lib/pp_admintools/app/duplicate_attribs.py

index f8591adb35b473ba07a39bbba0e13e9f570132a8..ffad4bdec65d6e81a59432246a5d15643cc6f6e3 100644 (file)
@@ -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<attrib>[a-z](?:[a-z0-9-]*[a-z0-9])?):\s*'
+        pat_dep_attribs += r'(?P<quote>[\'"])?(?P<filter>.+)(?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__":