From: Frank Brehm Date: Wed, 24 May 2023 09:29:47 +0000 (+0200) Subject: Refactoring checking virtual alias mappings X-Git-Tag: 0.9.0~1^2~33 X-Git-Url: https://git.uhu-banane.net/?a=commitdiff_plain;h=5842f902693129e0cc53b4afe7b9f487abecf8b5;p=pixelpark%2Fpp-admin-tools.git Refactoring checking virtual alias mappings --- diff --git a/lib/pp_admintools/app/barracuda_sync.py b/lib/pp_admintools/app/barracuda_sync.py index 52c1eed..db251fc 100644 --- a/lib/pp_admintools/app/barracuda_sync.py +++ b/lib/pp_admintools/app/barracuda_sync.py @@ -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\S+)\s*=\s*(?P\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[^:]+):(?P\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() # =============================================================================