HEX
Server: Apache/2.4.65 (Unix) OpenSSL/1.1.1k
System: Linux vps109042.inmotionhosting.com 4.18.0 #1 SMP Mon Sep 30 15:36:27 MSK 2024 x86_64
User: cisa (1010)
PHP: 8.2.30
Disabled: NONE
Upload Files
File: //opt/dedrads/mailparse/mail_analytics
#!/usr/lib/rads/venv/bin/python3
from pathlib import Path
import argparse
import socket
import os
import signal
import contextlib

from exim_analytics import scraper, Host, config, api


def get_hostname() -> str:
    """Get hostname from /etc/salt/minion_id"""
    if not Path("/etc/salt/minion_id").exists():
        return socket.gethostname()  # fallback to system hostname

    minion_id = Path("/etc/salt/minion_id")
    if not minion_id.is_file():
        return socket.gethostname()  # fallback to system hostname

    return minion_id.read_text(encoding="utf-8").strip()


def run(dry_run: bool = False):
    scraper.init_logging()
    hostname = get_hostname()
    if not api.check_status(hostname):
        print("API did not report OK status, exiting")
        return

    if not scraper.process_hosts(
        [
            Host(
                exim_log_path="/var/log/exim_mainlog",
                offset_file_path="/var/log/exim.offset",
                parsed_log_path="/var/log/exim.parsed",
                hostname=hostname,
            )
        ],
        platform="dedi",
        dry_run=dry_run,
    ):
        api.send_no_mail(hostname)


def main():
    config.load_config("/opt/dedrads/mailparse/analytics.yaml")

    parser = argparse.ArgumentParser(
        description="Collect mail analytics for abuse detection purposes"
    )
    parser.add_argument(
        "--dry-run",
        action="store_true",
        help="Do everything but send data.",
    )
    args = parser.parse_args()
    run(dry_run=args.dry_run)


if __name__ == "__main__":
    pidfile = Path("/run/mail_analytics.pid")
    if pidfile.exists():
        pid = int(pidfile.read_text())
        if pid and (Path("/proc/") / str(pid)).exists():
            # kill the preceding version of ourselves.
            os.kill(pid, signal.SIGTERM)
    try:
        with contextlib.suppress(Exception):
            pidfile.write_text(str(os.getpid()))
        main()
    finally:
        if pidfile.exists():
            pidfile.unlink()