Recent-Activity-Karte zeigt neue audit_log-Events jetzt sofort statt
in 15s-Polls.
internal/services/audit/audit.go:
- Repo bekommt Subscribe()-Methode mit fan-out-channel (Buffer 32,
non-blocking-send — langsame Clients droppen Events statt die
Pipeline zu blockieren).
- Log() macht jetzt INSERT … RETURNING id, created_at und broadcastet
den fertigen Entry an alle Subscribers. Broadcast nur nach
erfolgreichem INSERT — failed inserts erscheinen nicht.
internal/handlers/audit.go:
- Neuer GET /api/v1/audit/live (WebSocket): sendet beim Connect die
letzten 50 Einträge (oldest→newest), danach Live-Stream aus
Subscribe-Channel. 30s-Ping gegen HAProxy-Tunnel-Timeout.
- Recent (Poll-Endpoint) bleibt für Fallbacks erhalten.
UI Dashboard:
- useAuditLive(keep=15)-Hook ersetzt das 15s-useQuery-Poll.
- WebSocket auf wss://<host>/api/v1/audit/live; Auto-Reconnect alle
2s nach Drop.
- dedupe per id (Snapshot + erste live-Events können sich kurz
überschneiden während des Subscribe-Race).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
60 lines
2.0 KiB
Go
60 lines
2.0 KiB
Go
// Command edgeguard-ctl is the admin CLI for setup, migrations and
|
|
// (later) cluster ops. v1 wires migrate + initdb so postinst can
|
|
// initialise a fresh node; cluster-* and promote remain stubs until
|
|
// Phase 3.
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
)
|
|
|
|
var version = "1.0.73"
|
|
|
|
const usage = `edgeguard-ctl — EdgeGuard CLI
|
|
|
|
Usage:
|
|
edgeguard-ctl <command> [args]
|
|
|
|
Commands:
|
|
version Print version and exit
|
|
migrate up Apply pending migrations
|
|
migrate down Roll back the most recent migration (dev only)
|
|
migrate check Validate embedded migrations (no DB connect)
|
|
migrate dump [dir] Write embedded SQL files to dir (default: ./migrations)
|
|
initdb Create PostgreSQL role + database (idempotent)
|
|
render-config Regenerate haproxy / nftables configs from PG (--no-reload, --only=)
|
|
wg-import [--path <dir>] Import existing /etc/wireguard/*.conf files into the DB
|
|
cluster-join Join an existing cluster (Phase 3, not yet implemented)
|
|
promote Promote this node's PG to primary (Phase 3, not yet implemented)
|
|
dump-config Print effective config (Phase 3, not yet implemented)
|
|
`
|
|
|
|
func main() {
|
|
if len(os.Args) < 2 {
|
|
fmt.Fprint(os.Stderr, usage)
|
|
os.Exit(2)
|
|
}
|
|
switch os.Args[1] {
|
|
case "-h", "--help", "help":
|
|
fmt.Print(usage)
|
|
case "version", "--version":
|
|
fmt.Println(version)
|
|
case "migrate":
|
|
os.Exit(cmdMigrate(os.Args[2:]))
|
|
case "initdb":
|
|
os.Exit(cmdInitDB(os.Args[2:]))
|
|
case "render-config":
|
|
os.Exit(cmdRenderConfig(os.Args[2:]))
|
|
case "wg-import":
|
|
os.Exit(cmdWGImport(os.Args[2:]))
|
|
case "cluster-join", "cluster-leave", "promote", "dump-config":
|
|
fmt.Fprintf(os.Stderr, "edgeguard-ctl: %q is a Phase-3 stub — not yet implemented\n", os.Args[1])
|
|
os.Exit(1)
|
|
default:
|
|
fmt.Fprintf(os.Stderr, "edgeguard-ctl: unknown command %q\n", os.Args[1])
|
|
fmt.Fprint(os.Stderr, usage)
|
|
os.Exit(2)
|
|
}
|
|
}
|