From 83abb3a3e12a3e59a118f045501621f26609beb2 Mon Sep 17 00:00:00 2001 From: holger krekel Date: Thu, 13 Nov 2025 21:25:13 +0100 Subject: [PATCH] factor out opendkim deployer --- cmdeploy/src/cmdeploy/basedeploy.py | 5 + cmdeploy/src/cmdeploy/deployers.py | 127 +-------------------- cmdeploy/src/cmdeploy/opendkim/deployer.py | 123 ++++++++++++++++++++ 3 files changed, 131 insertions(+), 124 deletions(-) create mode 100644 cmdeploy/src/cmdeploy/opendkim/deployer.py diff --git a/cmdeploy/src/cmdeploy/basedeploy.py b/cmdeploy/src/cmdeploy/basedeploy.py index a55eb4ef..b7820141 100644 --- a/cmdeploy/src/cmdeploy/basedeploy.py +++ b/cmdeploy/src/cmdeploy/basedeploy.py @@ -1,8 +1,13 @@ +import importlib.resources import os from pyinfra.operations import server +def get_resource(arg, pkg=__package__): + return importlib.resources.files(pkg).joinpath(arg) + + class Deployment: def install(self, deployer): # optional 'required_users' contains a list of (user, group, secondary-group-list) tuples. diff --git a/cmdeploy/src/cmdeploy/deployers.py b/cmdeploy/src/cmdeploy/deployers.py index 2a1c88a5..3af8a2bb 100644 --- a/cmdeploy/src/cmdeploy/deployers.py +++ b/cmdeploy/src/cmdeploy/deployers.py @@ -2,7 +2,6 @@ Chat Mail pyinfra deploy. """ -import importlib.resources import io import shutil import subprocess @@ -13,7 +12,7 @@ from pathlib import Path from chatmaild.config import Config, read_config from pyinfra import facts, host, logger from pyinfra.api import FactBase -from pyinfra.facts.files import File, Sha256File +from pyinfra.facts.files import Sha256File from pyinfra.facts.server import Sysctl from pyinfra.facts.systemd import SystemdEnabled from pyinfra.operations import apt, files, pip, server, systemd @@ -21,7 +20,8 @@ from pyinfra.operations import apt, files, pip, server, systemd from cmdeploy.cmdeploy import Out from .acmetool import AcmetoolDeployer -from .basedeploy import Deployer, Deployment +from .basedeploy import Deployer, Deployment, get_resource +from .opendkim.deployer import OpendkimDeployer from .www import build_webpages, find_merge_conflict, get_paths @@ -40,10 +40,6 @@ class Port(FactBase): return output[0] -def get_resource(arg, pkg=__package__): - return importlib.resources.files(pkg).joinpath(arg) - - def _build_chatmaild(dist_dir) -> None: dist_dir = Path(dist_dir).resolve() if dist_dir.exists(): @@ -184,122 +180,6 @@ def _activate_remote_units(units) -> None: ) -def _configure_opendkim(domain: str, dkim_selector: str = "dkim") -> bool: - """Configures OpenDKIM""" - need_restart = False - - main_config = files.template( - src=get_resource("opendkim/opendkim.conf"), - dest="/etc/opendkim.conf", - user="root", - group="root", - mode="644", - config={"domain_name": domain, "opendkim_selector": dkim_selector}, - ) - need_restart |= main_config.changed - - screen_script = files.put( - src=get_resource("opendkim/screen.lua"), - dest="/etc/opendkim/screen.lua", - user="root", - group="root", - mode="644", - ) - need_restart |= screen_script.changed - - final_script = files.put( - src=get_resource("opendkim/final.lua"), - dest="/etc/opendkim/final.lua", - user="root", - group="root", - mode="644", - ) - need_restart |= final_script.changed - - files.directory( - name="Add opendkim directory to /etc", - path="/etc/opendkim", - user="opendkim", - group="opendkim", - mode="750", - present=True, - ) - - keytable = files.template( - src=get_resource("opendkim/KeyTable"), - dest="/etc/dkimkeys/KeyTable", - user="opendkim", - group="opendkim", - mode="644", - config={"domain_name": domain, "opendkim_selector": dkim_selector}, - ) - need_restart |= keytable.changed - - signing_table = files.template( - src=get_resource("opendkim/SigningTable"), - dest="/etc/dkimkeys/SigningTable", - user="opendkim", - group="opendkim", - mode="644", - config={"domain_name": domain, "opendkim_selector": dkim_selector}, - ) - need_restart |= signing_table.changed - files.directory( - name="Add opendkim socket directory to /var/spool/postfix", - path="/var/spool/postfix/opendkim", - user="opendkim", - group="opendkim", - mode="750", - present=True, - ) - - if not host.get_fact(File, f"/etc/dkimkeys/{dkim_selector}.private"): - server.shell( - name="Generate OpenDKIM domain keys", - commands=[ - f"/usr/sbin/opendkim-genkey -D /etc/dkimkeys -d {domain} -s {dkim_selector}" - ], - _use_su_login=True, - _su_user="opendkim", - ) - - service_file = files.put( - name="Configure opendkim to restart once a day", - src=get_resource("opendkim/systemd.conf"), - dest="/etc/systemd/system/opendkim.service.d/10-prevent-memory-leak.conf", - ) - need_restart |= service_file.changed - - return need_restart - - -class OpendkimDeployer(Deployer): - required_users = [("opendkim", None, ["opendkim"])] - - def __init__(self, mail_domain): - self.mail_domain = mail_domain - - def install(self): - apt.packages( - name="apt install opendkim opendkim-tools", - packages=["opendkim", "opendkim-tools"], - ) - - def configure(self): - self.need_restart = _configure_opendkim(self.mail_domain, "opendkim") - - def activate(self): - systemd.service( - name="Start and enable OpenDKIM", - service="opendkim.service", - running=True, - enabled=True, - daemon_reload=self.need_restart, - restarted=self.need_restart, - ) - self.need_restart = False - - class UnboundDeployer(Deployer): def install(self): # Run local DNS resolver `unbound`. @@ -1132,4 +1012,3 @@ def deploy_chatmail(config_path: Path, disable_mail: bool) -> None: ] Deployment().perform_stages(all_deployers) - diff --git a/cmdeploy/src/cmdeploy/opendkim/deployer.py b/cmdeploy/src/cmdeploy/opendkim/deployer.py new file mode 100644 index 00000000..b9ce1b91 --- /dev/null +++ b/cmdeploy/src/cmdeploy/opendkim/deployer.py @@ -0,0 +1,123 @@ +""" +Installs OpenDKIM +""" + +from pyinfra import host +from pyinfra.facts.files import File +from pyinfra.operations import apt, files, server, systemd + +from cmdeploy.basedeploy import Deployer, get_resource + + +class OpendkimDeployer(Deployer): + required_users = [("opendkim", None, ["opendkim"])] + + def __init__(self, mail_domain): + self.mail_domain = mail_domain + + def install(self): + apt.packages( + name="apt install opendkim opendkim-tools", + packages=["opendkim", "opendkim-tools"], + ) + + def configure(self): + domain = self.mail_domain + dkim_selector = "dkim" + """Configures OpenDKIM""" + need_restart = False + + main_config = files.template( + src=get_resource("opendkim/opendkim.conf"), + dest="/etc/opendkim.conf", + user="root", + group="root", + mode="644", + config={"domain_name": domain, "opendkim_selector": dkim_selector}, + ) + need_restart |= main_config.changed + + screen_script = files.put( + src=get_resource("opendkim/screen.lua"), + dest="/etc/opendkim/screen.lua", + user="root", + group="root", + mode="644", + ) + need_restart |= screen_script.changed + + final_script = files.put( + src=get_resource("opendkim/final.lua"), + dest="/etc/opendkim/final.lua", + user="root", + group="root", + mode="644", + ) + need_restart |= final_script.changed + + files.directory( + name="Add opendkim directory to /etc", + path="/etc/opendkim", + user="opendkim", + group="opendkim", + mode="750", + present=True, + ) + + keytable = files.template( + src=get_resource("opendkim/KeyTable"), + dest="/etc/dkimkeys/KeyTable", + user="opendkim", + group="opendkim", + mode="644", + config={"domain_name": domain, "opendkim_selector": dkim_selector}, + ) + need_restart |= keytable.changed + + signing_table = files.template( + src=get_resource("opendkim/SigningTable"), + dest="/etc/dkimkeys/SigningTable", + user="opendkim", + group="opendkim", + mode="644", + config={"domain_name": domain, "opendkim_selector": dkim_selector}, + ) + need_restart |= signing_table.changed + files.directory( + name="Add opendkim socket directory to /var/spool/postfix", + path="/var/spool/postfix/opendkim", + user="opendkim", + group="opendkim", + mode="750", + present=True, + ) + + if not host.get_fact(File, f"/etc/dkimkeys/{dkim_selector}.private"): + server.shell( + name="Generate OpenDKIM domain keys", + commands=[ + f"/usr/sbin/opendkim-genkey -D /etc/dkimkeys -d {domain} -s {dkim_selector}" + ], + _use_su_login=True, + _su_user="opendkim", + ) + + service_file = files.put( + name="Configure opendkim to restart once a day", + src=get_resource("opendkim/systemd.conf"), + dest="/etc/systemd/system/opendkim.service.d/10-prevent-memory-leak.conf", + ) + need_restart |= service_file.changed + + self.need_restart = need_restart + + def activate(self): + systemd.service( + name="Start and enable OpenDKIM", + service="opendkim.service", + running=True, + enabled=True, + daemon_reload=self.need_restart, + restarted=self.need_restart, + ) + self.need_restart = False