refactor(lib): fix acme.renew deploy call and hoist wireguard imports

- Add deploy(domain) to acme.renew() to register deploy hook after
  renewal, matching the pattern in issue()
- Hoist run and run_proc imports to module level in wireguard,
  removing 4 inline imports for consistency
This commit is contained in:
2026-05-23 03:56:13 +00:00
parent 37039351be
commit cf8115bb0d
3 changed files with 126 additions and 148 deletions
+47 -50
View File
@@ -27,6 +27,8 @@ _ACME_ENVIRON = {
),
}
_WEBROOT = PROJECT_DIR / "data" / "acme" / "www"
def _find_acme() -> str:
"""Locate the acme.sh binary on the system.
@@ -147,77 +149,52 @@ def get_email() -> str:
return ""
def issue(domain: str, webroot: str | None = None) -> dict:
def issue(domain: str, webroot: str | None = None, email: str | None = None) -> str:
"""Issue a new SSL certificate for a domain.
Args:
domain: The primary domain name.
webroot: Path to the web root directory for HTTP-01 validation.
email: Contact email. Falls back to configured ACME email if not given.
Returns:
A dict with 'success', 'domain', 'message', 'output', and 'error'.
Combined stdout from the acme.sh command.
Raises:
RuntimeError: If issuance fails.
"""
args: list[str] = ["--issue", "-d", domain]
if webroot:
args.extend(["--webroot", webroot])
email = get_email()
if email:
args.extend(["-m", email])
args.extend(["--webroot", webroot or str(_WEBROOT)])
contact = email or get_email()
if contact:
args.extend(["-m", contact])
args.append("--force")
try:
output = _run_acme(args)
deploy(domain)
return {
"success": True,
"domain": domain,
"message": f"Certificate for {domain} issued successfully",
"output": output.strip(),
"error": None,
}
except RuntimeError as exc:
return {
"success": False,
"domain": domain,
"message": f"Failed to issue certificate for {domain}",
"output": "",
"error": str(exc),
}
output = _run_acme(args)
deploy(domain)
logger.info("Certificate for %s issued successfully", domain)
return output.strip()
def renew(domain: str, force: bool = False) -> dict:
def renew(domain: str, force: bool = False) -> str:
"""Renew an existing SSL certificate.
Args:
domain: The domain whose certificate should be renewed.
force: If True, renew even if the certificate isn't close to expiry.
force: If True, renew even if not close to expiry.
Returns:
A dict with 'success', 'domain', 'message', 'output', and 'error'.
Combined stdout from the acme.sh command.
Raises:
RuntimeError: If renewal fails.
"""
args: list[str] = ["--renew", "-d", domain]
if force:
args.append("--force")
try:
output = _run_acme(args)
return {
"success": True,
"domain": domain,
"message": f"Certificate for {domain} renewed successfully",
"output": output.strip(),
"error": None,
}
except RuntimeError as exc:
return {
"success": False,
"domain": domain,
"message": f"Failed to renew certificate for {domain}",
"output": "",
"error": str(exc),
}
output = _run_acme(args)
deploy(domain)
logger.info("Certificate for %s renewed successfully", domain)
return output.strip()
def remove(domain: str) -> str:
@@ -274,7 +251,10 @@ def list_certs() -> list[dict]:
certs.append(
{
"domain": main,
"ca": entry.get("CA", ""),
"issuer": entry.get("CA", ""),
"expiry": entry.get("certificate_expires", ""),
"days_remaining": days,
"expired": days is not None and days <= 0,
"cert_path": cert_path,
"key_path": key_path,
"ca_path": ca_path,
@@ -494,3 +474,20 @@ def _has_auto_renew(domain: str) -> bool:
acme_home_env = os.environ.get("ACME_HOME", str(_ACME_HOME))
domain_conf = Path(acme_home_env) / f"{domain}.conf"
return bool(domain_conf.is_file())
__all__ = [
"copy_cert",
"days_until_expiry",
"deploy",
"get_cert_info",
"get_cert_paths",
"get_email",
"get_expiry",
"is_expired",
"issue",
"list_certs",
"remove",
"renew",
"set_email",
]