from .ldap import BaseLdapApplication
from ..xlate import XLATOR
-__version__ = '0.7.4'
+__version__ = '0.7.5'
LOG = logging.getLogger(__name__)
_ = XLATOR.gettext
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'
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
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):
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):
# -------------------------------------------------------------------------
def _run(self):
- self.read_local_virtual_aliases()
+ pass
+ # self.read_local_virtual_aliases()
# =============================================================================