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()