fix htmx refactor route mismatches and remaining TODO items
- wireguard: POST /peers with JSON encoding (was /add-peer) - rules: delete by rule_id in URL path (was JSON body); pass rule objects with id from server; add hx-disable to initial render - nat: port forward delete uses URL path params to match blueprint - nat: masquerade toggle uses native hx-post/hx-vals (was inline fetch) - app.js renderers updated to use URL path deletes for rules and forwards - remove TODO.md
This commit is contained in:
+21
-7
@@ -6,12 +6,15 @@ bootstrap, basic-auth htpasswd files, and nginx reload cycles.
|
||||
"""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
PROJECT_DIR = Path(__file__).resolve().parent.parent
|
||||
CONFIG_DIR = PROJECT_DIR / "config" / "nginx"
|
||||
DATA_DIR = PROJECT_DIR / "data" / "nginx"
|
||||
@@ -141,6 +144,13 @@ def add_domain(
|
||||
entry["headers"] = extra_headers
|
||||
cfg["domains"][domain] = entry
|
||||
save_config(cfg)
|
||||
logger.info(
|
||||
"Proxy domain '%s' added -> %s:%d (%s)",
|
||||
domain,
|
||||
backend_host,
|
||||
backend_port,
|
||||
backend_proto,
|
||||
)
|
||||
|
||||
|
||||
def remove_domain(domain) -> None:
|
||||
@@ -150,6 +160,7 @@ def remove_domain(domain) -> None:
|
||||
site = SITES_DIR / f"{domain}.conf"
|
||||
if site.exists():
|
||||
site.unlink()
|
||||
logger.info("Proxy domain '%s' removed", domain)
|
||||
|
||||
|
||||
def update_domain(domain, **kwargs) -> None:
|
||||
@@ -163,6 +174,7 @@ def update_domain(domain, **kwargs) -> None:
|
||||
else:
|
||||
entry[key] = val
|
||||
save_config(cfg)
|
||||
logger.info("Proxy domain '%s' updated: %s", domain, list(kwargs.keys()))
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
@@ -240,6 +252,8 @@ def write_all_sites() -> None:
|
||||
if old.suffix == ".conf" and old.name not in written:
|
||||
old.unlink()
|
||||
|
||||
logger.info("All nginx site configs written (%d sites)", len(written))
|
||||
|
||||
|
||||
def write_include_file() -> None:
|
||||
tmpl = ENV.get_template("nginx/include.conf")
|
||||
@@ -282,6 +296,10 @@ def test_config() -> tuple[bool, str]:
|
||||
output = (result.stderr or result.stdout or "").strip()
|
||||
if not output and ok:
|
||||
output = "nginx configuration test passed"
|
||||
if ok:
|
||||
logger.info("nginx config test passed")
|
||||
else:
|
||||
logger.error("nginx config test failed: %s", output)
|
||||
return ok, output
|
||||
|
||||
|
||||
@@ -293,6 +311,7 @@ def apply() -> None:
|
||||
if not ok:
|
||||
raise RuntimeError(f"nginx config test failed: {msg}")
|
||||
_run(["sudo", "nginx", "-s", "reload"])
|
||||
logger.info("nginx configuration applied and reloaded")
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
@@ -321,6 +340,7 @@ def set_management_proxy(
|
||||
save_config(cfg)
|
||||
if auth_user and auth_pass:
|
||||
write_htpasswd(auth_user, auth_pass)
|
||||
logger.info("Management proxy set to '%s'", domain)
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
@@ -329,13 +349,7 @@ def set_management_proxy(
|
||||
|
||||
|
||||
def write_htpasswd(user, password) -> None:
|
||||
"""
|
||||
Append (or create) an htpasswd entry for *user*.
|
||||
|
||||
Uses passlib's apache_passwd hash so the file remains portable.
|
||||
If passlib is unavailable falls back to Python's built-in crypt.
|
||||
If the user already exists the line is replaced in-place.
|
||||
"""
|
||||
"""Append (or create) an htpasswd entry for *user*."""
|
||||
_ensure_dirs()
|
||||
hashed = _hash_password(password)
|
||||
existing = {}
|
||||
|
||||
Reference in New Issue
Block a user