]> Frank Brehm's Git Trees - pixelpark/pp-admin-tools.git/commitdiff
Refactoring checking virtual alias mappings
authorFrank Brehm <frank.brehm@pixelpark.com>
Wed, 24 May 2023 09:29:47 +0000 (11:29 +0200)
committerFrank Brehm <frank.brehm@pixelpark.com>
Wed, 24 May 2023 09:29:47 +0000 (11:29 +0200)
lib/pp_admintools/app/barracuda_sync.py

index 52c1eed628d459b47bdc96d0a1de296f607481ac..db251fca4053b2c713e7b64f28e6a953f069c993 100644 (file)
@@ -26,7 +26,7 @@ from fb_tools.multi_config import DEFAULT_ENCODING
 from .ldap import BaseLdapApplication
 from ..xlate import XLATOR
 
-__version__ = '0.7.4'
+__version__ = '0.7.5'
 LOG = logging.getLogger(__name__)
 
 _ = XLATOR.gettext
@@ -65,7 +65,9 @@ class BarracudaSyncApp(BaseLdapApplication):
     re_virtaliases_line = re.compile(r'^([^#\s:]+)\s', re.MULTILINE)
     re_pf_config = re.compile(r'^(?P<key>\S+)\s*=\s*(?P<value>\S.*)?')
     re_pf_fieldsep = re.compile(r'\s*[,;]\s*')
+    re_pf_valsep = re.compile(r'\s+')
     re_empty_line = re.compile(r'^\s*(?:#.*|$)')
+    re_pf_lookup_map = re.compile(r'^(?P<table_type>[^:]+):(?P<path>\S.*)')
 
     default_postmap_command = 'postmap'
     default_postconf_command = 'postconf'
@@ -94,7 +96,7 @@ class BarracudaSyncApp(BaseLdapApplication):
     def __init__(self, appname=None, base_dir=None):
         """Constructz the application object."""
         self.barracuda_base_dn = self.default_barracuda_base_dn
-        self.virtaliases_files = []
+        self.virtalias_mappings = []
         self.postfix_db_hashtype = self.default_postfix_db_hashtype
         self.postconf_command = Path('/sbin') / self.default_postconf_command
         self.postmap_command = Path('/sbin') / self.default_postmap_command
@@ -168,8 +170,8 @@ class BarracudaSyncApp(BaseLdapApplication):
         self._check_postfix_commands()
         self._check_postfix_table_types()
         self._get_postfix_default_db_type()
-        self._init_virtaliases_files()
-        # self._check_virtaliases_files()
+        self._init_virtaliases_files()
+        self._check_virtalias_mappings()
 
     # -------------------------------------------------------------------------
     def _check_postfix_commands(self):
@@ -253,81 +255,115 @@ class BarracudaSyncApp(BaseLdapApplication):
                     table_type = table_type.strip()
                 if table_type:
                     self.postfix_db_hashtype = table_type
-                    self.debug(_('Found postfix default database type: {!r}.').format(table_type))
+                    LOG.debug(_('Found postfix default database type: {!r}.').format(table_type))
 
     # -------------------------------------------------------------------------
     def _init_virtaliases_files(self):
         """Collect all files used as database for virtual aliases."""
         LOG.debug(_('Collecting all available virtual aliases table files ...'))
 
-        va_files = []
-        basenames = [
-            'virtual', 'virtual-alias', 'virtual-aliases',
-            'virtualalias', 'virtualaliases']
-
-        if self.args.basename:
-            for basename in self.args.basename:
-                if basename not in basenames:
-                    basenames.append(basename)
-
-        for va_file in self.default_virtaliases_files:
-            if va_file.exists() and va_file.is_file():
-                if self.verbose > 1:
-                    LOG.debug(_('Using virtual aliases file: {!r}').format(str(va_file)))
-                va_files.append(va_file)
-
-        for maps_dir in (self.postfix_config_dir, self.postfix_maps_dir):
-            if not maps_dir.exists():
-                LOG.debug(_('Directory {!r} does not exists.').format(str(maps_dir)))
-                continue
-            if not maps_dir.is_dir():
-                LOG.debug(_('Path {!r} exists, but is not a directory.').format(str(maps_dir)))
-                continue
-
-            for basename in basenames:
-                va_file = maps_dir / basename
-                if va_file.exists() and va_file.is_file():
-                    va_file = va_file.resolve()
-                    if va_file not in va_files:
-                        if self.verbose > 1:
-                            LOG.debug(_('Using virtual aliases file: {!r}').format(str(va_file)))
-                        va_files.append(va_file)
-
-        if not len(va_files):
-            LOG.error(_('Did not found any virtual aliases files.'))
+        handler = BaseHandler(appname=self.appname, verbose=self.verbose)
+        pdata = handler.call([str(self.postconf_command), 'virtual_alias_maps'], quiet=True)
+        if pdata.returncode > 0:
+            msg = _('Error {} on evaluating postfix virtual alias maps').format(
+                pdata.returncode)
+            if pdata.stderr:
+                msg += ': ' + pdata.stderr
+            else:
+                msg += '.'
+            LOG.err(msg)
             self.exit(6)
 
-        LOG.debug(_('Found virtual aliases files:') + '\n' + pp(
-            list(map(lambda x: str(x), va_files))))
-        self.virtaliases_files = va_files
+        valias_maps = []
+
+        for line in pdata.stdout.splitlines():
+            if self.re_empty_line.match(line):
+                continue
+            m = self.re_pf_config.match(line)
+            if m and m.group('key') == 'virtual_alias_maps':
+                values =  m.group('value')
+                for mapping in self.re_pf_valsep.split(values):
+                    if self.verbose > 1:
+                        LOG.debug(_('Evaluating mapping {!r}.').format(mapping))
+                    m = self.re_pf_lookup_map.match(mapping.strip())
+                    if m:
+                        table_type = m.group('table_type')
+                        path = m.group('path')
+                        if table_type.lower() == '${default_database_type}':
+                            table_type = self.postfix_db_hashtype
+                        va_mappping = table_type + ':' + path
+                        if table_type in self.usable_postfix_hashtypes:
+                            LOG.debug(_('Using virtual alias map {!r}.').format(va_mappping))
+                            valias_maps.append(va_mappping)
+                        else:
+                            msg = _(
+                                'Cannot use virtual alias mapping {va!r}: table type {ty!r} '
+                                'cannot be searched for all database elements.').format(
+                                va=path, ty=table_type)
+                            LOG.debug(msg)
+
+        if not len(valias_maps):
+            msg = _(
+                'Did not found any parsable virtual alias mappings in '
+                'postfix configuration.')
+            LOG.warn(msg)
+
+        self.virtalias_mappings = valias_maps
 
     # -------------------------------------------------------------------------
-    def _check_virtaliases_files(self):
-        """Check existence of given ."""
-        LOG.debug(_('Checking all available virtual aliases table files ...'))
+    def _check_virtalias_mappings(self):
+        """Check validity of all virtual alias mappings."""
+        LOG.debug(_('Checking all available virtual alias mappings ...'))
 
-        db_extension = self.postfix_filetype_extensions[self.postfix_db_hashtype]
-        if self.verbose > 1:
-            LOG.debug(_('Using file extension for db-files: {!r}.').format(db_extension))
+        if not len(self.virtalias_mappings):
+            return
 
-        for va_file in self.virtaliases_files:
-            db_file = va_file.parent / (va_file.name + db_extension)
-            if not db_file.exists() or not db_file.is_file():
-                LOG.error(_(
-                    'DB file for virtual aliases {!r} does not exists or is not a regular '
-                    'file.').format(str(db_file)))
-                self.virtaliases_files.remove(va_file)
-                continue
-            mtime_db_file = db_file.stat().st_mtime
-            mtime_va_file = va_file.stat().st_mtime
-            if mtime_db_file < mtime_va_file:
-                LOG.warn(_(
-                    'The last modification time of {db!r} is older than this '
-                    'of {va!r}.').format(db=str(db_file), va=str(va_file)))
-            elif self.verbose > 1:
-                LOG.debug(_(
-                    'The last modification time of {db!r} and {va!r} are '
-                    'okay.').format(db=str(db_file), va=str(va_file)))
+        for mapping in self.virtalias_mappings:
+            self._check_virtalias_mapping(mapping)
+
+    # -------------------------------------------------------------------------
+    def _check_virtalias_mapping(self, mapping):
+        """Check validity of given virtual alias mapping."""
+        LOG.debug(_('Checking virtual alias mapping {!r}.').format(mapping))
+
+        m = self.re_pf_lookup_map.match(mapping)
+        if not m:
+            msg = _('Could not evaluate virtual alias mapping {!r}.').format(mapping)
+            LOG.error(msg)
+            self.virtalias_mappings.remove(va_file)
+            return
+
+        table_type = m.group('table_type')
+        va_file = Path(m.group('path'))
+        db_extension = self.postfix_filetype_extensions[table_type]
+        if self.verbose > 1:
+            LOG.debug(_('Using file extension for db-file {f!r}: {e!r}.').format(
+                f=str(va_file), e=db_extension))
+
+        if not va_file.exists() or not va_file.is_file():
+            msg = _('Virtual alias mapping file {!r} does not exists.').format(str(va_file))
+            LOG.error(msg)
+            self.virtalias_mappings.remove(va_file)
+            return
+
+        db_file = va_file.parent / (va_file.name + db_extension)
+        if not db_file.exists() or not db_file.is_file():
+            LOG.error(_(
+                'DB file for virtual aliases {!r} does not exists or is not a regular '
+                'file.').format(str(db_file)))
+            self.virtalias_mappings.remove(va_file)
+            return
+
+        mtime_db_file = db_file.stat().st_mtime
+        mtime_va_file = va_file.stat().st_mtime
+        if mtime_db_file < mtime_va_file:
+            LOG.warn(_(
+                'The last modification times of {db!r} is older than this '
+                'of {va!r}.').format(db=str(db_file), va=str(va_file)))
+        elif self.verbose > 1:
+            LOG.debug(_(
+                'The last modification times of {db!r} and {va!r} are '
+                'okay.').format(db=str(db_file), va=str(va_file)))
 
     # -------------------------------------------------------------------------
     def read_local_virtual_aliases(self):
@@ -363,7 +399,8 @@ class BarracudaSyncApp(BaseLdapApplication):
     # -------------------------------------------------------------------------
     def _run(self):
 
-        self.read_local_virtual_aliases()
+        pass
+        # self.read_local_virtual_aliases()
 
 
 # =============================================================================