Files
Nexus-Guard-Suite/.sisyphus/plans/nxg-wgdashboard-config-parity.md
T
datadunia bf9cbba535 feat: complete WGDashboard config parity
Backend (server-core):
- Extend firewall NetManager with AddForwardRule, AddInputRule via nft CLI
- Sync FORWARD rules on peer create, update, delete, suspend/unsuspend
- Sync INPUT rules on server create, update (port change), delete
- Fix duplicate import and missing firewall cleanup calls

Frontend (dashboard-ui):
- Add Edit Node modal for MTU, DNS, ListenPort configuration
- Add Advanced Peer Settings accordion (AllowedIPs, DNS, MTU, Keepalive, Notes)
- Add Suspend/Unsuspend toggle with SUSPENDED badge
- Update API client for new endpoints and fields
2026-05-22 02:27:04 +07:00

207 lines
8.0 KiB
Markdown

# Plan: WGDashboard Config Parity (Phase 5.5)
## 1. Goal
Achieve feature parity with WGDashboard for WireGuard configuration editing and peer settings, adapting WGDashboard's local-file management approach to NexusGuard's multi-node database-driven SD-WAN architecture.
---
## 2. Current Status (May 22, 2026)
### ✅ COMPLETED
#### Phase 1: Database Model Updates (Backend)
- [x] **Update `WgServer` Model**: Added MTU (default 1420), DNS (default "1.1.1.1").
- [x] **Update `Device` Model**: Added EndpointAllowedIPs, DNS, MTU, PersistentKeepalive (default 25), Notes, IsSuspended, RxBytes, TxBytes.
- [x] **Database Migration**: Auto-migrate via GORM AutoMigrate.
#### Phase 2: API Updates (Backend)
- [x] **Server API (`servers.go`)**: `PUT /api/v1/servers/:id` — pointer fields for partial updates, firewall sync on port change.
- [x] **Device API (`devices.go`)**: `PUT /api/v1/devices/:id` — pointer fields for EndpointAllowedIPs, DNS, MTU, PersistentKeepalive, Notes.
- [x] **Config Generation (`peers.go`)**: `getDeviceConfig` — DNS override (device > server > "1.1.1.1"), MTU override, PersistentKeepalive, EndpointAllowedIPs.
- [x] **Peer Suspension API**: `POST /api/v1/devices/:id/suspend` and `/unsuspend` with `IsSuspended` toggle + firewall rule add/remove.
#### Phase 3: Firewall Enforcement Sync (nftables) — MOSTLY DONE
- [x] **Firewall Manager Interface**: Extended with `AddForwardRule`, `RemoveForwardRule`, `AddInputRule`, `RemoveInputRule`.
- [x] **Linux Implementation**: `nftables_linux.go` via `nft` CLI (AddForwardRule, RemoveForwardRule, AddInputRule, RemoveInputRule).
- [x] **Stub Implementation**: `nftables_stub.go` for non-Linux builds.
- [x] **Server Create**: `AddInputRule(server.Name, server.ListenPort)` in `servers.go`.
- [x] **Server Update**: Firewall re-sync when ListenPort changes in `servers.go`.
- [x] **Server Delete**: `RemoveInputRule(server.Name)` in `servers.go`.
- [x] **Peer Suspend**: `RemoveForwardRule` / `AddForwardRule` in `devices.go` toggleSuspension.
- [x] **Device Delete (partial)**: `RemoveRangeRule` called but **missing `RemoveForwardRule`**.
### ❌ REMAINING (to be completed now)
#### Phase 3: Backend Firewall Fixes
- [x] **Fix duplicate `"net"` import** in `devices.go` (lines 4-5, two imports of same package).
- [x] **Add `AddForwardRule` in `peers.go` CreatePeer** — after device creation, add FORWARD rule for device AllowedIPs.
- [x] **Add firewall sync in `devices.go` Update** — when EndpointAllowedIPs or AllowInternet changes, re-sync FORWARD rule.
- [x] **Add `RemoveForwardRule` in `devices.go` Delete** — clean up FORWARD rule when device is deleted.
#### Phase 4: Dashboard UI (Frontend)
- [x] **Node Edit Modal** in `Servers.vue` — Edit Node button + modal to configure MTU, DNS, ListenPort via `PUT /api/v1/servers/:id`.
- [x] **Advanced Peer Settings** in `DeviceDetail.vue` — Accordion section with fields for AllowedIPs, DNS, MTU, Keepalive, Notes, Suspend toggle, using new API fields.
- [x] **Update API client** (`servers.ts`, `devices.ts`) — Add `updateServer()`, `suspendDevice()`, `unsuspendDevice()` and extend `updateDevice()` with new fields.
---
## 3. Implementation Tasks
### Task A: Backend Fixes (4 edits across 2 files)
#### A.1 devices.go — Duplicate import
- Remove second `"net"` import on line 5.
- File: `apps/server-core/api/devices.go`
- Verify: `go build ./...` passes.
#### A.2 peers.go — Add ForwardRule on CreatePeer
- After line ~131 (configText generation), add:
```go
// Sync firewall FORWARD rule for this peer
h.fw.AddForwardRule(device.Name, ip, allowedIPs)
```
- Also handle case where EndpointAllowedIPs is empty — derive from AllowInternet.
- File: `apps/server-core/api/peers.go`
#### A.3 devices.go — Firewall sync on Update
- In `Update()` handler, after device is updated, re-sync FORWARD rule if:
- `EndpointAllowedIPs` changed (req.EndpointAllowedIPs != nil)
- `AllowInternet` changed (req.AllowInternet != nil)
- Calculate destCIDR from device's EndpointAllowedIPs > AllowInternet > InternalIP
- Call `h.fw.RemoveForwardRule(device.Name)` then `h.fw.AddForwardRule(...)` with new CIDR.
#### A.4 devices.go — ForwardRule cleanup on Delete
- In `Delete()` handler, add `h.fw.RemoveForwardRule(device.Name)` before or after the existing `h.db.Delete(&device)`.
- File: `apps/server-core/api/devices.go`
### Task B: Frontend API Client Updates
#### B.1 servers.ts — Add updateServer()
```typescript
export const updateServer = async (id: string, data: {
name?: string;
public_endpoint?: string;
listen_address?: string;
listen_port?: number;
mtu?: number;
dns?: string;
}) => {
await api.put(`/servers/${id}`, data)
}
```
#### B.2 devices.ts — Extend updateDevice() + add suspend/unsuspend
```typescript
export const updateDevice = async (id: string, data: {
name?: string;
allow_internet?: boolean;
endpoint_allowed_ips?: string;
dns?: string;
mtu?: number;
persistent_keepalive?: number;
notes?: string;
}) => {
await api.put(`/devices/${id}`, data)
}
export const suspendDevice = async (id: string) => {
const { data } = await api.post(`/devices/${id}/suspend`)
return data
}
export const unsuspendDevice = async (id: string) => {
const { data } = await api.post(`/devices/${id}/unsuspend`)
return data
}
```
#### B.3 Device interface — Add new fields
```typescript
export interface Device {
// ... existing fields ...
EndpointAllowedIPs?: string
DNS?: string
MTU?: number
PersistentKeepalive?: number
Notes?: string
IsSuspended?: boolean
}
```
### Task C: Frontend UI Components
#### C.1 Servers.vue — Edit Node Modal
Add to the template:
- An "Edit" button next to "Delete" in each server row
- A modal dialog (glassmorphism style matching current design) with fields:
- ListenPort (number input)
- MTU (number input)
- DNS (text input)
- Form submits to `updateServer(id, payload)` API
- Modal uses `v-model="showEditModal"` to open/close
- Refresh list after update
Implementation approach:
- Add `editingServer` ref to track which server is being edited
- Add modal template with glassmorphism card (bg-gray-900/90 rounded-2xl border border-white/10 shadow-lg backdrop-blur-xl)
- Pre-populate form with current server values
- On submit: call API, close modal, reload list
#### C.2 DeviceDetail.vue — Advanced Peer Settings
Add after the AllowInternet toggle section:
- A collapsible "Advanced Settings" accordion
- Inside: form fields for:
- AllowedIPs (text input - comma-separated CIDRs)
- DNS (text input)
- MTU (number input)
- PersistentKeepalive (number input)
- Notes (textarea)
- Suspend (toggle switch with API call)
- "Save" button calls `updateDevice()` with all fields
- Suspend toggle calls `suspendDevice()` / `unsuspendDevice()` separately
- Show "Suspended" badge when device is suspended
---
## 4. Execution Strategy
```
Wave 1 (parallel — backend fixes + frontend API):
├── Task A: Backend fixes (devices.go, peers.go)
├── Task B: Frontend API client updates (servers.ts, devices.ts, peers.ts)
Wave 2 (parallel — frontend UI):
├── Task C.1: Servers.vue Edit Node modal
├── Task C.2: DeviceDetail.vue Advanced Peer Settings accordion
Wave 3 (final — verification):
├── Verify go build ./... passes
├── Verify npm build passes (or at least no TS errors)
├── Update plan file with final status
├── Commit all changes
```
---
## 5. Verification Strategy
### Backend Verification
```bash
cd apps/server-core
go build ./... # Expected: PASS (no errors)
go vet ./... # Expected: PASS (no warnings)
```
### Frontend Verification
```bash
cd apps/dashboard-ui
npx vue-tsc --noEmit # Expected: PASS (no type errors)
npm run build # Expected: PASS (build succeeds)
```
### Manual QA (after deploy to wglab)
- Add Node → Edit Node (change MTU, DNS, ListenPort) → Verify
- Create Peer → Edit Advanced Settings (AllowedIPs, DNS, MTU, Keepalive, Notes) → Verify
- Toggle Suspend → Verify peer status changes → Verify firewall rules update
- Verify nftables rules: `nft list chain ip nexusguard forward`, `nft list chain ip nexusguard input`