import logging import logging.config import pathlib import traceback import socket from subprocess import call, DEVNULL import click import toml import requests from jinja2 import Environment, FileSystemLoader from re2oapi import Re2oAPIClient RUN_PATH = pathlib.Path(__file__).parent CLIENT_HOSTNAME = socket.gethostname().split('.', 1)[0] @click.command() @click.option( "--config-dir", default=RUN_PATH.resolve(), help="Configuration directory." ) @click.option("--dry-run/--complete", default=False, help="Performs a dry run.") @click.option( "--keep/--update", default=False, help="Update service status on Re2o. Won't update if it is a dry-run.", ) def main(config_dir, dry_run, keep): logging.config.fileConfig(config_dir / "logging.conf") logger = logging.getLogger("re2o-mails") logger.debug("Fetching configuration from %s.", config_dir) config = toml.load(config_dir / "config.toml") re2o_client = Re2oAPIClient( config["Re2o"]["hostname"], config["Re2o"]["username"], config["Re2o"]["password"], use_tls=config["Re2o"]["use_TLS"], ) users_emails = re2o_client.list("localemail/users") users = set(map(lambda x: x['email_address'][0]['user'], users_emails)) local_email_domain = re2o_client.view("preferences/optionaluser/")["local_email_domain"] env = Environment(loader=FileSystemLoader(str(config_dir))) generated_folder = config_dir / "generated" generated_folder.mkdir(exist_ok=True) virtual_alias = generated_folder / "virtual_alias" virtual_mailbox = generated_folder / "virtual_mailbox" template_alias = env.get_template('templates/virtual_alias.j2') template_mailbox = env.get_template('templates/virtual_mailbox.j2') with virtual_mailbox.open(mode='w') as f_mailbox: rendered_mailbox = template_mailbox.render(users=users, local_email_domain=local_email_domain) if dry_run: logging.info("New virtual mailboxes would be : %s", rendered_mailbox) else: logging.info("Writing virtual mailboxes") f_mailbox.write(rendered_mailbox) with virtual_alias.open(mode='w') as f_alias: rendered_alias = template_alias.render(users_emails=users_emails, local_email_domain=local_email_domain) if dry_run: logging.info("New virtual aliases would be : %s", rendered_alias) else: logging.info("Writing virtual aliases") f_alias.write(rendered_alias) if not dry_run: logging.info("Generating new maps") call(["/usr/sbin/postmap", str(virtual_alias)], stdout=DEVNULL) call(["/usr/sbin/postmap", str(virtual_mailbox)], stdout=DEVNULL) logging.info("Reloading postfix") call(["/usr/sbin/postfix", "reload"]) if not keep and not dry_run: for service in re2o_client.list("services/regen/"): if ( service["hostname"] == CLIENT_HOSTNAME and service["service_name"] == "mail-server" and service["need_regen"] ): re2o_client.patch(service["api_url"], data={"need_regen": False}) if __name__ == "__main__": main()