Development

This commit is contained in:
Matthew Grotke 2026-05-22 03:05:10 -04:00
parent 831bc88a92
commit 8756eb624e
2 changed files with 11 additions and 12 deletions

View file

@ -1411,7 +1411,7 @@ def render_layout(view_id, content_html, tokens):
text = e(item.get('detail', item.get('name', '')))
tip = item.get('suggestion', '')
if tip:
text += f' <span style="opacity:0.75"> {e(tip)}</span>'
text += f' <span style="opacity:0.75">- {e(tip)}</span>'
problem_bars += f'<div class="info-bar {cls}">{text}</div>\n'
except Exception:
pass

View file

@ -23,7 +23,7 @@ from pathlib import Path
from validation import derive_interface, derive_vlan_id, is_wg
# ===================================================================
# Constants (mirror core.py no import to avoid circular dependency)
# Constants (mirror core.py - no import to avoid circular dependency)
# ===================================================================
PRODUCT_NAME = "routlin"
@ -44,6 +44,7 @@ RADIUS_CLIENTS_CONF = Path("/etc/freeradius/3.0/clients.conf")
RADIUS_USERS_FILE = Path("/etc/freeradius/3.0/users")
BLIST_TIMER_NAME = f"{PRODUCT_NAME}-dns-blocklist-update"
DASHB_TIMER_NAME = f"{PRODUCT_NAME}-dashboard-queue"
STATUS_TIMER_NAME = f"{PRODUCT_NAME}-status-check"
DASHB_QUEUE_FILE = SCRIPT_DIR / ".dashboard-queue"
NAT_SERVICE_NAME = f"{PRODUCT_NAME}-nat"
BLOCKLIST_STALE_SECS = 36 * 3600
@ -160,6 +161,10 @@ def check_services(data):
"expected_active": "inactive",
"expected_enabled": "enabled"})
units.append({"id": f"{STATUS_TIMER_NAME}.timer",
"name": f"{STATUS_TIMER_NAME}.timer",
"expected_active": "active", "expected_enabled": "enabled"})
if DASHB_QUEUE_FILE.exists():
units.append({"id": f"{DASHB_TIMER_NAME}.timer",
"name": f"{DASHB_TIMER_NAME}.timer",
@ -212,17 +217,11 @@ def check_configurations(data):
vlans = data.get("vlans", [])
non_wg = [v for v in vlans if not is_wg(v)]
wg_vlans = [v for v in vlans if is_wg(v)]
core_mtime = CONFIG_FILE.stat().st_mtime if CONFIG_FILE.exists() else 0
def file_ok(id_, name, path, severity="error", suggestion=""):
if not path.exists():
return _problem(id_, name, severity,
f"{path} does not exist.",
suggestion or f"Run sudo python3 core.py --apply to create it.")
if path.stat().st_mtime < core_mtime:
return _problem(id_, name, "warning",
f"{path} is older than core.json and may be stale.",
"Run sudo python3 core.py --apply to update it.")
return _ok(id_, name)
# --- nftables tables ---
@ -296,12 +295,12 @@ def check_configurations(data):
results.append(_problem(id_, name, "error",
f"WireGuard interface {iface} does not exist.",
"Run sudo python3 core.py --apply to bring up WireGuard."))
elif state != "up":
elif state in ("up", "unknown"): # WireGuard interfaces normally report 'unknown'
results.append(_ok(id_, name))
else:
results.append(_problem(id_, name, "error",
f"WireGuard interface {iface} operstate is '{state}'.",
f"Try: sudo wg-quick up {iface}"))
else:
results.append(_ok(id_, name))
# --- Stale WG interfaces when no WG VLANs configured ---
if not wg_vlans:
@ -391,7 +390,7 @@ def check_configurations(data):
except OSError:
pass # already caught above by file_ok
else:
# RADIUS not enabled warn if generated config files still exist
# RADIUS not enabled - warn if generated config files still exist
if RADIUS_CLIENTS_CONF.exists():
try:
if "# Generated by" in RADIUS_CLIENTS_CONF.read_text():