First real commit

This commit is contained in:
Stanislav Hubacek
2026-04-04 23:44:32 +02:00
parent 5c5ecf506a
commit 98320fc827
2 changed files with 113 additions and 0 deletions

96
scripts/generate_caddy.py Normal file → Executable file
View File

@@ -0,0 +1,96 @@
#!/usr/bin/env python3
from pathlib import Path
import sys
import yaml
from jinja2 import Environment, FileSystemLoader, StrictUndefined
BASE = Path("/opt/homelab")
SERVICES_DIR = BASE / "services"
TEMPLATES_DIR = BASE / "templates"
OUTPUT_DIR = BASE / "generated" / "caddy"
def load_yaml(path: Path) -> dict:
with path.open("r", encoding="utf-8") as f:
data = yaml.safe_load(f) or {}
return data
def validate_service(data: dict, source: Path) -> None:
required_common = ["name", "type", "domain"]
for key in required_common:
if key not in data:
raise ValueError(f"{source.name}: missing required key '{key}'")
svc_type = data["type"]
if svc_type not in {"static", "proxy"}:
raise ValueError(f"{source.name}: unsupported type '{svc_type}'")
if svc_type == "static" and "root" not in data:
raise ValueError(f"{source.name}: static service requires 'root'")
if svc_type == "proxy" and "backend" not in data:
raise ValueError(f"{source.name}: proxy service requires 'backend'")
def render_service(env: Environment, data: dict) -> str:
svc_type = data["type"]
defaults = {
"headers": False,
"auth": False,
"real_ip": False,
"health_uri": None,
"health_interval": None,
}
merged = {**defaults, **data}
if svc_type == "static":
template = env.get_template("static.caddy.j2")
return template.render(**merged).strip() + "\n"
reverse_proxy_block = any(
[
merged.get("real_ip"),
merged.get("health_uri"),
merged.get("health_interval"),
]
)
merged["reverse_proxy_block"] = reverse_proxy_block
template = env.get_template("proxy.caddy.j2")
return template.render(**merged).strip() + "\n"
def main() -> int:
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
env = Environment(
loader=FileSystemLoader(str(TEMPLATES_DIR)),
undefined=StrictUndefined,
trim_blocks=True,
lstrip_blocks=True,
)
rendered_files = []
for svc_file in sorted(SERVICES_DIR.glob("*.yml")):
data = load_yaml(svc_file)
validate_service(data, svc_file)
rendered = render_service(env, data)
output_file = OUTPUT_DIR / f"{data['name']}.caddy"
output_file.write_text(rendered, encoding="utf-8")
rendered_files.append(output_file.name)
print("Generated:")
for name in rendered_files:
print(f" - {name}")
return 0
if __name__ == "__main__":
sys.exit(main())