feat(routes): Static-Routes-Management + Live-View (Networks-Tab)

Migration 0019: static_routes (id, destination, gateway, dev, metric,
table_name, active, comment).

internal/services/staticroutes/:
  - CRUD-Repo
  - Generator schreibt /etc/edgeguard/routes.conf (pipe-format) und
    triggert `sudo systemctl restart edgeguard-routes.service`
  - LiveAll() ruft `ip -j route show table all` und parsed JSON

internal/handlers/routes.go:
  GET /api/v1/routes           — managed (DB)
  POST/PUT/DELETE              — CRUD (re-render + apply on mutate)
  GET /api/v1/routes/live      — kernel-state via ip(8)

postinst:
  - /usr/sbin/edgeguard-apply-routes (root-owned shell-script). Liest
    routes.conf, flusht `proto 250` (= edgeguard), setzt neue Routen
    mit proto 250. Andere Quellen (kernel/dhcp/manuell) bleiben
    unangetastet.
  - /etc/systemd/system/edgeguard-routes.service (Type=oneshot,
    After=network-online.target). Beim Boot automatisch via
    multi-user.target.
  - /etc/iproute2/rt_protos.d/edgeguard.conf — Symbol "edgeguard" =
    250 damit `ip route show proto edgeguard` funktioniert.
    (Debian 13 hat kein /etc/iproute2 default → .d-Pattern statt
    rt_protos-Anhängen.)
  - sudoers: edgeguard ALL=(root) NOPASSWD: /usr/bin/systemctl
    restart edgeguard-routes.service

UI: Networks-Page jetzt mit Tabs (Interfaces + Routen). Routes-Tab
hat zwei Cards:
  - Live-Routen (read-only, 30s refresh, `proto edgeguard` farblich
    hervorgehoben)
  - Verwaltete Routen (CRUD-Tabelle, Add/Edit-Modal mit destination/
    gateway/dev/metric/table/active/comment)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Debian
2026-05-12 23:50:26 +02:00
parent dbc14a24a4
commit b031725dfe
14 changed files with 1162 additions and 275 deletions

View File

@@ -114,8 +114,12 @@
}
},
"networks": {
"title": "Network interfaces",
"intro": "Manage WAN, LAN, VLAN and bond interfaces. Read-only kernel discovery above; declared configuration below — runtime apply via systemd-networkd lands in a later release.",
"title": "Network",
"intro": "Interfaces (Ethernet / VLAN / bond / bridge) and static routes. Live kernel discovery + declared configuration from the DB.",
"tabs": {
"interfaces": "Interfaces",
"routes": "Routes"
},
"systemDiscovered": "System interfaces (read-only)",
"addInterface": "Add interface",
"editInterface": "Edit interface",
@@ -622,6 +626,36 @@
"cta": "Activate now →",
"openPage": "Open license page →"
},
"routes": {
"liveTitle": "Live routes (kernel)",
"liveIntro": "Current state from `ip -j route show table all`. proto edgeguard marks routes managed by EdgeGuard — other sources (kernel/static/dhcp) are left untouched.",
"liveEmpty": "No routes in kernel.",
"managedTitle": "Managed routes",
"managedIntro": "Static routes EdgeGuard installs via `ip route … proto edgeguard` on boot. Changes here trigger `systemctl restart edgeguard-routes.service` immediately.",
"add": "Add route",
"addTitle": "Add static route",
"editTitle": "Edit static route",
"empty": "No managed routes yet.",
"confirmDelete": "Really delete route to {{dest}}?",
"refreshTooltip": "Reload live routes",
"destExtra": "CIDR — e.g. 10.0.5.0/24 or 0.0.0.0/0 for the default route.",
"gatewayExtra": "Optional. Empty = on-link via dev.",
"devExtra": "Output interface. Optional if gateway resolves; explicit is more stable.",
"metricExtra": "Lower wins. Default 100. Linux defaults: dhcp 1024, kernel-link 0.",
"tableExtra": "Routing table. main = default. Custom tables via /etc/iproute2/rt_tables.",
"col": {
"destination": "Destination",
"gateway": "Gateway",
"dev": "Interface",
"metric": "Metric",
"table": "Table",
"active": "Active",
"comment": "Comment",
"proto": "Protocol",
"scope": "Scope",
"src": "Source IP"
}
},
"backups": {
"title": "Backups",
"intro": "Snapshots of the PostgreSQL database + /var/lib/edgeguard (setup, license, JWT, ACME account). Daily auto job + manual trigger.",