import logging import logging.config import pathlib import traceback import socket 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 = filter(lambda x: x["local_email_enabled"], re2o_client.list("users/user")) local_email_domain = re2o_client.get("preferences/optionaluser")["local_email_domain"] env = Environment(loader=FileSystemLoader(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()