mirror of
https://gitlab.com/simple-nixos-mailserver/nixos-mailserver.git
synced 2025-12-25 12:20:52 +01:00
Drop most of the existing certificate handling, because we're effectively duplicating functionality that NixOS offers for free with better design, testing and maintainance than what we could provide downstream. The remaining two options are to reference an existing `security.acme.certs` configuration through `mailserver.x509.useACMEHost` or to provide existing key material via `mailserver.x509.certificateFile` and `mailserver.x509.privateKeyFile`. Support for automatic creation of self-signed certificates has been removed, because it is undesirable in public mail setups. The updated setup guide now displays the recommended configuration that relies on the NixOS ACME module, but requires further customization to select a suitable challenge. Co-Authored-By: Emily <git@emilylange.de>
113 lines
2.7 KiB
Python
113 lines
2.7 KiB
Python
import json
|
|
import sys
|
|
from textwrap import indent
|
|
from typing import Any, Mapping
|
|
|
|
header = """
|
|
# Mailserver options
|
|
|
|
## `mailserver`
|
|
|
|
"""
|
|
|
|
template = """
|
|
({key})=
|
|
`````{{option}} {key}
|
|
{description}
|
|
|
|
{type}
|
|
{default}
|
|
{example}
|
|
`````
|
|
"""
|
|
|
|
f = open(sys.argv[1])
|
|
options = json.load(f)
|
|
|
|
groups = [
|
|
"mailserver.loginAccounts",
|
|
"mailserver.x509",
|
|
"mailserver.dkim",
|
|
"mailserver.srs",
|
|
"mailserver.dmarcReporting",
|
|
"mailserver.fullTextSearch",
|
|
"mailserver.redis",
|
|
"mailserver.ldap",
|
|
"mailserver.monitoring",
|
|
"mailserver.backup",
|
|
"mailserver.borgbackup",
|
|
]
|
|
|
|
|
|
def md_literal(value: str) -> str:
|
|
return f"`{value}`"
|
|
|
|
|
|
def md_codefence(value: str, language: str = "nix") -> str:
|
|
return indent(
|
|
f"\n```{language}\n{value}\n```",
|
|
prefix=2 * " ",
|
|
)
|
|
|
|
|
|
def render_option_value(option: Mapping[str, Any], key: str) -> str:
|
|
if key not in option:
|
|
return ""
|
|
|
|
if isinstance(option[key], dict) and "_type" in option[key]:
|
|
if option[key]["_type"] == "literalExpression":
|
|
# multi-line codeblock
|
|
if "\n" in option[key]["text"]:
|
|
text = option[key]["text"].rstrip("\n")
|
|
value = md_codefence(text)
|
|
# inline codeblock
|
|
else:
|
|
value = md_literal(option[key]["text"])
|
|
# literal markdown
|
|
elif option[key]["_type"] == "literalMD":
|
|
value = option[key]["text"]
|
|
else:
|
|
assert RuntimeError(f"Unhandled option type {option[key]['_type']}")
|
|
else:
|
|
text = str(option[key])
|
|
if text == "":
|
|
value = md_literal('""')
|
|
elif "\n" in text:
|
|
value = md_codefence(text.rstrip("\n"))
|
|
else:
|
|
value = md_literal(text)
|
|
|
|
return f"- {key}: {value}" # type: ignore
|
|
|
|
|
|
def print_option(option):
|
|
if (
|
|
isinstance(option["description"], dict) and "_type" in option["description"]
|
|
): # mdDoc
|
|
description = option["description"]["text"]
|
|
else:
|
|
description = option["description"]
|
|
print(
|
|
template.format(
|
|
key=option["name"],
|
|
description=description or "",
|
|
type=f"- type: {md_literal(option['type'])}",
|
|
default=render_option_value(option, "defaultText")
|
|
if "defaultText" in option
|
|
else render_option_value(option, "default"),
|
|
example=render_option_value(option, "example"),
|
|
)
|
|
)
|
|
|
|
|
|
print(header)
|
|
for opt in options:
|
|
if any([opt["name"].startswith(c) for c in groups]):
|
|
continue
|
|
print_option(opt)
|
|
|
|
for c in groups:
|
|
print(f"## `{c}`\n")
|
|
for opt in options:
|
|
if opt["name"].startswith(c):
|
|
print_option(opt)
|