]> Frank Brehm's Git Trees - pixelpark/pp-admin-tools.git/commitdiff
Allowing export of errors int a yaml file.
authorFrank Brehm <frank.brehm@pixelpark.com>
Mon, 9 Jan 2023 15:41:22 +0000 (16:41 +0100)
committerFrank Brehm <frank.brehm@pixelpark.com>
Mon, 9 Jan 2023 15:41:22 +0000 (16:41 +0100)
lib/pp_admintools/app/check_ldap_dn_attributes.py

index 2cfe0d072071e00d549199304d0e6b5f2564d656..11c36c0a87a304025ef14d6ba39f49c749e08c0d 100644 (file)
@@ -9,13 +9,11 @@
 from __future__ import absolute_import
 
 # Standard modules
-import sys
+import re
 import logging
-import copy
-import time
 
 # Third party modules
-from ldap3 import ALL_ATTRIBUTES
+import yaml
 
 # Own modules
 # from fb_tools.common import to_bool, is_sequence
@@ -33,10 +31,7 @@ from ..config.ldap import LdapConfiguration
 from .ldap import LdapAppError
 from .ldap import BaseLdapApplication
 
-from ..argparse_actions import NonNegativeItegerOptionAction
-from ..argparse_actions import LimitedFloatOptionAction
-
-__version__ = '0.2.2'
+__version__ = '0.3.1'
 LOG = logging.getLogger(__name__)
 
 _ = XLATOR.gettext
@@ -63,6 +58,8 @@ class CheckLdapDnAttributesApplication(BaseLdapApplication):
     show_force_option = False
     show_assume_options = False
 
+    re_yaml_extension = re.compile(r'\.ya?ml$', re.IGNORECASE)
+
     check_attributes = ['member', 'uniqueMember', 'owner', 'seeAlso']
 
     # -------------------------------------------------------------------------
@@ -78,6 +75,8 @@ class CheckLdapDnAttributesApplication(BaseLdapApplication):
         self.all_check_dns = CIStringSet()
         self.failed_entries = CIDict()
 
+        self.export_file = None
+
         attr_list = format_list(self.check_attributes, do_repr=True)
 
         desc = _(
@@ -86,8 +85,8 @@ class CheckLdapDnAttributesApplication(BaseLdapApplication):
             "to existing entries in LDAP.").format(alist=attr_list)
 
         super(CheckLdapDnAttributesApplication, self).__init__(
-             appname=appname, description=desc, base_dir=base_dir,
-             cfg_class=LdapConfiguration, initialized=False)
+            appname=appname, description=desc, base_dir=base_dir,
+            cfg_class=LdapConfiguration, initialized=False)
 
         self.initialized = True
 
@@ -96,12 +95,31 @@ class CheckLdapDnAttributesApplication(BaseLdapApplication):
 
         super(CheckLdapDnAttributesApplication, self)._verify_instances(is_admin=True)
 
+    # -------------------------------------------------------------------------
+    def init_arg_parser(self):
+
+        app_group = self.arg_parser.add_argument_group(_("Script options"))
+
+        app_group.add_argument(
+            '-E', '--export', dest='export', metavar=_('FILE'),
+            help=_(
+                "Exportig the faulty entries and attributes into a YAML file, "
+                "if there were found some of them."),
+        )
+
+        super(CheckLdapDnAttributesApplication, self).init_arg_parser()
+
     # -------------------------------------------------------------------------
     def post_init(self):
         """Execute some actions after initialising."""
 
         super(CheckLdapDnAttributesApplication, self).post_init()
 
+        self.export_file = getattr(self.args, 'export', None)
+        if self.export_file:
+            if not self.re_yaml_extension.search(self.export_file):
+                self.export_file += '.yaml'
+
         self.instance = self.ldap_instances[0]
         self.connect_info = self.cfg.ldap_connection[self.instance]
 
@@ -110,6 +128,11 @@ class CheckLdapDnAttributesApplication(BaseLdapApplication):
 
         ldap_url = self.cfg.ldap_connection[self.instance].url
 
+        if self.export_file:
+            with open(self.export_file, 'wt', encoding='utf-8', errors='surrogateescape') as fh:
+                fh.write('---\n\n')
+            LOG.debug(_("Created export file {!r}.").format(self.export_file))
+
         msg = _(
             "Start checking all DN-like attributes in in LDAP instance {inst!r} "
             "({url}) ...").format(inst=self.instance, url=ldap_url)
@@ -147,6 +170,7 @@ class CheckLdapDnAttributesApplication(BaseLdapApplication):
             self.check_entry(dn)
 
         if self.failed_entries:
+            print(pp(self.failed_entries.as_dict(pure=True)))
             nr = len(self.failed_entries)
             nr_attr = 0
             for e_dn in self.failed_entries:
@@ -160,7 +184,13 @@ class CheckLdapDnAttributesApplication(BaseLdapApplication):
                 "There is one inconsistent attribute.",
                 "There are {} inconsistent attributes.", nr_attr).format(nr_attr)
             LOG.warn(msg)
-            print(pp(self.failed_entries.as_dict(pure=True)))
+            if self.export_file:
+                LOG.debug(_("Writing export file {!r} ...").format(self.export_file))
+                with open(
+                        self.export_file, 'wt', encoding='utf-8', errors='surrogateescape') as fh:
+                    yaml.dump(
+                        self.failed_entries.as_dict(pure=True), fh, explicit_start=True,
+                        default_flow_style=False, indent=2)
             self.exit(5)
 
         msg = _("Did not found any inconsistent entries.")
@@ -186,20 +216,14 @@ class CheckLdapDnAttributesApplication(BaseLdapApplication):
                             self.failed_entries[dn] = {}
                         if attrib not in self.failed_entries[dn]:
                             self.failed_entries[dn][attrib] = []
-                        self.failed_entries[dn][attrib].append({
-                            'value': ref,
-                            'what': 'syntax',
-                        })
+                        self.failed_entries[dn][attrib].append(ref)
                         continue
                     if not self.check_ref_existence(ref, self.instance):
                         if dn not in self.failed_entries:
                             self.failed_entries[dn] = {}
                         if attrib not in self.failed_entries[dn]:
                             self.failed_entries[dn][attrib] = []
-                        self.failed_entries[dn][attrib].append({
-                            'value': ref,
-                            'what': 'existence',
-                        })
+                        self.failed_entries[dn][attrib].append(ref)
 
     # -------------------------------------------------------------------------
     def check_ref_syntax(self, dn):
@@ -225,6 +249,7 @@ class CheckLdapDnAttributesApplication(BaseLdapApplication):
         self.checked_ref_dn[dn] = False
         return False
 
+
 # =============================================================================
 if __name__ == "__main__":