feat(app): add WGRplane web UI and backend features
- Add Vue 3 frontend with glassmorphism design (Tailwind CSS) - Add Go backend handlers: auth, webhooks, stats, scheduler, validation - Add i18n support (EN, ID, ZH) - Add Swagger docs and API handlers - Add nftables integration and plugins support - Remove deprecated go.mod (migrated to wgrplane)
This commit is contained in:
+28
-28
@@ -82,21 +82,21 @@ iptables / ipset rules
|
||||
|
||||
### Phase A: Submodule Initialization
|
||||
|
||||
- [ ] **Task A1**: Initialize WGRplane submodule at `/app`
|
||||
- [x] **Task A1**: Initialize WGRplane submodule at `/app`
|
||||
- File: `/app` (new submodule directory)
|
||||
- Command: `git submodule add https://git.datadunia.com/hainzero/WGRplane.git app`
|
||||
- Followed by: `git submodule update --init --recursive`
|
||||
- QA: `git submodule status` shows `app` with commit hash, no errors
|
||||
- QA: `/app` directory exists with WGRplane files (Python/Flask backend, Vue.js frontend)
|
||||
|
||||
- [ ] **Task A2**: Verify WGRplane structure and dependencies
|
||||
- [x] **Task A2**: Verify WGRplane structure and dependencies
|
||||
- File: `/app` (submodule contents)
|
||||
- Inspect: `ls /app` — should contain Python backend, Vue.js frontend, requirements.txt
|
||||
- Verify WGDashboard-equivalent structure: `app.py` or similar Flask entry point
|
||||
- QA: WGRplane files present, Python/Flask + Vue.js stack confirmed
|
||||
- QA: `cat /app/requirements.txt` shows Flask, SQLite, other dependencies
|
||||
|
||||
- [ ] **Task A3**: Create Go module for `wg-engine-api` in `/app`
|
||||
- [x] **Task A3**: Create Go module for `wg-engine-api` in `/app`
|
||||
- File: `/app/wg-engine-api/main.go` (new)
|
||||
- File: `/app/wg-engine-api/go.mod` (new)
|
||||
- Command: `cd /app/wg-engine-api && go mod init git.datadunia.com/hainzero/WGRplane/wg-engine-api`
|
||||
@@ -106,26 +106,26 @@ iptables / ipset rules
|
||||
|
||||
### Phase B: WGRplane Base Setup (WGDashboard Parity)
|
||||
|
||||
- [ ] **Task B1**: Review WGDashboard features for parity checklist
|
||||
- [x] **Task B1**: Review WGDashboard features for parity checklist
|
||||
- Reference: Librarian findings (bg_f53966bd) — full feature list
|
||||
- Features to implement: peer CRUD, QR codes, real-time monitoring, scheduling, TOTP auth, multi-server, plugins, i18n, themes
|
||||
- File: `/app/README.md` (document feature parity status)
|
||||
- QA: Checklist created with ALL WGDashboard features mapped to WGRplane implementation status
|
||||
|
||||
- [ ] **Task B2**: Configure WGRplane to use port 10086 (WGDashboard default)
|
||||
- [x] **Task B2**: Configure WGRplane to use port 10086 (WGDashboard default)
|
||||
- File: `/app/app.py` or `/app/config.json` (WGRplane config)
|
||||
- Set: `app_port = 10086` (consistent with WGDashboard)
|
||||
- Ensure: Does not conflict with `wg-engine-api` on port 10087
|
||||
- QA: `curl http://localhost:10086` returns WGRplane dashboard page
|
||||
- QA: Port 10086 in use by WGRplane, 10087 available for wg-engine-api
|
||||
|
||||
- [ ] **Task B3**: Integrate WGRplane with existing WireGuard config path
|
||||
- [x] **Task B3**: Integrate WGRplane with existing WireGuard config path
|
||||
- File: `/app/app.py` (WGRplane backend)
|
||||
- Set WireGuard config path: `/etc/wireguard/wg0.conf` (consistent with existing scripts)
|
||||
- QA: WGRplane can read `/etc/wireguard/wg0.conf` and list peers
|
||||
- QA: WGRplane "Add Peer" creates valid WireGuard config entries
|
||||
|
||||
- [ ] **Task B4**: Add policy.json API awareness to WGRplane frontend
|
||||
- [x] **Task B4**: Add policy.json API awareness to WGRplane frontend
|
||||
- File: `/app/src/views/` or `/app/src/components/` (Vue.js components)
|
||||
- Add: New UI section for "Policy API" (link to `http://localhost:10087/api/policy`)
|
||||
- Note: WGRplane frontend will proxy or link to Go API (decision: proxy via Flask or direct link)
|
||||
@@ -134,7 +134,7 @@ iptables / ipset rules
|
||||
|
||||
### Phase C: Go wg-engine-api Development
|
||||
|
||||
- [ ] **Task C1**: Implement Go API server skeleton with routing
|
||||
- [x] **Task C1**: Implement Go API server skeleton with routing
|
||||
- File: `/app/wg-engine-api/main.go`
|
||||
- Framework: `github.com/gorilla/mux` (router)
|
||||
- Port: **10087** (avoid conflict with WGDashboard's 10086)
|
||||
@@ -143,7 +143,7 @@ iptables / ipset rules
|
||||
- QA: `go build` succeeds, binary runs on port 10087
|
||||
- QA: `curl -H "wg-rplane-datadunia: test" http://localhost:10087/api/policy` returns 200 or 401 (if auth enforced)
|
||||
|
||||
- [ ] **Task C2**: Implement locking mechanism (flock) in Go
|
||||
- [x] **Task C2**: Implement locking mechanism (flock) in Go
|
||||
- File: `/app/wg-engine-api/main.go` (lock function)
|
||||
- Lock file: `/var/lock/wg-policy.lock` (SAME as existing scripts)
|
||||
- Implementation: Use `syscall.Flock()` or exec `flock` command
|
||||
@@ -151,7 +151,7 @@ iptables / ipset rules
|
||||
- QA: Simultaneous API calls do not corrupt `policy.json`
|
||||
- QA: Lock acquired within 10 seconds, else return 503 (timeout)
|
||||
|
||||
- [ ] **Task C3**: Implement atomic write for policy.json in Go
|
||||
- [x] **Task C3**: Implement atomic write for policy.json in Go
|
||||
- File: `/app/wg-engine-api/main.go` (write function)
|
||||
- Pattern: Write to tmp file → `mv` (atomic, same filesystem)
|
||||
- Reference: `wg-sync-policy.sh` lines 124-126: `mv -f "$tmp_policy" "$POLICY_FILE"`
|
||||
@@ -159,7 +159,7 @@ iptables / ipset rules
|
||||
- QA: `policy.json` never partially written (crash during write doesn't corrupt)
|
||||
- QA: `jq empty /etc/wireguard/policy.json` validates JSON after write
|
||||
|
||||
- [ ] **Task C4**: Add CLI flag for sync without HTTP server
|
||||
- [x] **Task C4**: Add CLI flag for sync without HTTP server
|
||||
- File: `/app/wg-engine-api/main.go` (flag parsing)
|
||||
- Flag: `--sync` (perform merge + write to `policy.json`, then exit)
|
||||
- Use case: Called by `wg-policy.service` instead of `wg-sync-policy.sh`
|
||||
@@ -168,7 +168,7 @@ iptables / ipset rules
|
||||
|
||||
### Phase D: Policy API Implementation
|
||||
|
||||
- [ ] **Task D1**: Implement `GET /api/policy` (merged: API + #Access fallback)
|
||||
- [x] **Task D1**: Implement `GET /api/policy` (merged: API + #Access fallback)
|
||||
- File: `/app/wg-engine-api/main.go` (GET handler)
|
||||
- Step 1: Read API storage (`/etc/wireguard/api-policy.json`)
|
||||
- Step 2: Parse `wg0.conf` for `#Access` comments (fallback, using Go or exec `wg-sync-policy.sh`)
|
||||
@@ -178,7 +178,7 @@ iptables / ipset rules
|
||||
- QA: Client with API policy + `#Access` → API policy wins in response
|
||||
- QA: Client with ONLY `#Access` → fallback returns `#Access` value
|
||||
|
||||
- [ ] **Task D2**: Implement `POST /api/policy` (update API-managed policy)
|
||||
- [x] **Task D2**: Implement `POST /api/policy` (update API-managed policy)
|
||||
- File: `/app/wg-engine-api/main.go` (POST handler)
|
||||
- Input: JSON body `{"ip": "10.0.0.2", "access": ["1.1.1.1/32"], "internet": true}`
|
||||
- Validate: IP and CIDRs using Go validation functions (port from `wg-policy-lib.sh`)
|
||||
@@ -188,14 +188,14 @@ iptables / ipset rules
|
||||
- QA: `policy.json` updated with merged data (API overrides #Access)
|
||||
- QA: `wg-policy-ctl rules` shows new targets after POST
|
||||
|
||||
- [ ] **Task D3**: Implement `POST /api/reload` (trigger policy engine)
|
||||
- [x] **Task D3**: Implement `POST /api/reload` (trigger policy engine)
|
||||
- File: `/app/wg-engine-api/main.go` (reload handler)
|
||||
- Action: Exec `/usr/local/bin/wg-policy-engine.sh`
|
||||
- Optional: Also exec `/usr/local/bin/wg-sync-policy.sh` first (if #Access fallback needed)
|
||||
- QA: `curl -X POST -H "wg-rplane-datadunia: VALID" http://localhost:10087/api/reload` returns 200
|
||||
- QA: After reload, `wg-policy-ctl status` shows engine applied successfully
|
||||
|
||||
- [ ] **Task D4**: Implement authentication middleware
|
||||
- [x] **Task D4**: Implement authentication middleware
|
||||
- File: `/app/wg-engine-api/main.go` (middleware)
|
||||
- Header: `wg-rplane-datadunia`
|
||||
- Validation: Check header exists and matches configured token (from env or config file)
|
||||
@@ -204,7 +204,7 @@ iptables / ipset rules
|
||||
- QA: `curl -H "wg-rplane-datadunia: wrong" http://localhost:10087/api/policy` → 401
|
||||
- QA: `curl -H "wg-rplane-datadunia: VALID" http://localhost:10087/api/policy` → 200
|
||||
|
||||
- [ ] **Task D5**: Create API storage file (`api-policy.json`) with schema
|
||||
- [x] **Task D5**: Create API storage file (`api-policy.json`) with schema
|
||||
- File: `/etc/wireguard/api-policy.json` (new, API-managed)
|
||||
- Schema: Same as `policy.json` but ONLY API-managed entries:
|
||||
```json
|
||||
@@ -224,7 +224,7 @@ iptables / ipset rules
|
||||
|
||||
### Phase E: #Access Migration & Merge Logic
|
||||
|
||||
- [ ] **Task E1**: Implement #Access comment parser in Go (fallback)
|
||||
- [x] **Task E1**: Implement #Access comment parser in Go (fallback)
|
||||
- File: `/app/wg-engine-api/main.go` (parse function)
|
||||
- Method: Exec `wg-sync-policy.sh` OR parse `wg0.conf` directly in Go
|
||||
- Prefer: Parse `wg0.conf` in Go (avoid exec dependency)
|
||||
@@ -232,7 +232,7 @@ iptables / ipset rules
|
||||
- QA: Go parser extracts same data as `wg-sync-policy.sh` awk script
|
||||
- QA: `curl GET /api/policy` with no API policy returns `#Access` data correctly
|
||||
|
||||
- [ ] **Task E2**: Implement merge logic (API overrides #Access)
|
||||
- [x] **Task E2**: Implement merge logic (API overrides #Access)
|
||||
- File: `/app/wg-engine-api/main.go` (merge function)
|
||||
- Logic: For each client IP:
|
||||
1. Start with `#Access` parsed data (fallback)
|
||||
@@ -242,13 +242,13 @@ iptables / ipset rules
|
||||
- QA: Client with API policy `"access": ["1.1.1.1/32"]` + `#Access 2.2.2.2/32` → GET returns `["1.1.1.1/32"]`
|
||||
- QA: Client with ONLY `#Access 2.2.2.2/32` → GET returns `["2.2.2.2/32"]`
|
||||
|
||||
- [ ] **Task E3**: Handle `internet` flag merge
|
||||
- [x] **Task E3**: Handle `internet` flag merge
|
||||
- File: `/app/wg-engine-api/main.go` (merge function extension)
|
||||
- Logic: Same as access merge — API `internet` flag overrides `#Internet` comment
|
||||
- QA: Client with API `internet: true` + no `#Internet` in wg0.conf → GET returns `true`
|
||||
- QA: Client with API `internet: false` + `#Internet true` in wg0.conf → GET returns `false`
|
||||
|
||||
- [ ] **Task E4**: Update `wg-policy.service` to use Go API sync (optional, recommended)
|
||||
- [x] **Task E4**: Update `wg-policy.service` to use Go API sync (optional, recommended)
|
||||
- File: `wg-policy.service` (systemd unit)
|
||||
- Change: `ExecStartPre` from `wg-sync-policy.sh` to `wg-engine-api --sync`
|
||||
- Note: NOT modifying `.sh` scripts (only systemd unit)
|
||||
@@ -257,21 +257,21 @@ iptables / ipset rules
|
||||
|
||||
### Phase F: Integration & Testing
|
||||
|
||||
- [ ] **Task F1**: Add `bats` test framework for shell script validation
|
||||
- [x] **Task F1**: Add `bats` test framework for shell script validation
|
||||
- File: `/tests/` (new directory) or use existing pattern
|
||||
- Test cases: Policy.json validation, JSON structure, lock file behavior
|
||||
- Install: `apt install bats` (add to `install.sh` if needed)
|
||||
- QA: `bats /tests/policy.bats` passes all test cases
|
||||
- QA: Test coverage for `wg-policy-ctl validate` command
|
||||
|
||||
- [ ] **Task F2**: Add Go tests for `wg-engine-api`
|
||||
- [x] **Task F2**: Add Go tests for `wg-engine-api`
|
||||
- File: `/app/wg-engine-api/main_test.go` (new)
|
||||
- Test cases: Auth middleware, GET/POST handlers, merge logic, lock mechanism
|
||||
- Run: `cd /app/wg-engine-api && go test ./...`
|
||||
- QA: `go test` passes with >80% coverage
|
||||
- QA: Mock `wg0.conf` and `api-policy.json` for isolated tests
|
||||
|
||||
- [ ] **Task F3**: Integration test: Full flow validation
|
||||
- [x] **Task F3**: Integration test: Full flow validation
|
||||
- Test: POST to API → policy.json updated → iptables rules applied
|
||||
- Steps:
|
||||
1. `curl -X POST ... http://localhost:10087/api/policy` (add client)
|
||||
@@ -280,7 +280,7 @@ iptables / ipset rules
|
||||
- QA: All 3 steps succeed in sequence
|
||||
- QA: Fallback to `#Access` works when API has no entry for client
|
||||
|
||||
- [ ] **Task F4**: Manual test documentation in README
|
||||
- [x] **Task F4**: Manual test documentation in README
|
||||
- File: `/app/README.md` (test section)
|
||||
- Document: How to run bats tests, Go tests, manual QA scenarios
|
||||
- Note: No CI (none exists in repo), document manual commands
|
||||
@@ -291,21 +291,21 @@ iptables / ipset rules
|
||||
|
||||
### Phase G: Documentation & Push
|
||||
|
||||
- [ ] **Task G1**: Create comprehensive README.md for WGRplane submodule
|
||||
- [x] **Task G1**: Create comprehensive README.md for WGRplane submodule
|
||||
- File: `/app/README.md` (new or update existing)
|
||||
- Sections: Overview, Architecture, API Endpoints, Authentication, Integration with WGDashboard, Testing, Deployment
|
||||
- Document: Go API endpoint (`http://localhost:10087/api/policy`), auth header `wg-rplane-datadunia`
|
||||
- QA: README.md exists with all sections
|
||||
- QA: `cat /app/README.md` shows complete documentation
|
||||
|
||||
- [ ] **Task G2**: Document integration between WGRplane (Python) and wg-engine-api (Go)
|
||||
- [x] **Task G2**: Document integration between WGRplane (Python) and wg-engine-api (Go)
|
||||
- File: `/app/README.md` (integration section)
|
||||
- Explain: WGRplane on port 10086, Go API on port 10087
|
||||
- Note: Frontend can proxy API requests or link directly
|
||||
- QA: README has "Integration" section with port numbers and proxy examples
|
||||
- QA: Developer understands how Python Flask talks to Go API
|
||||
|
||||
- [ ] **Task G3**: Push WGRplane submodule to remote
|
||||
- [x] **Task G3**: Push WGRplane submodule to remote
|
||||
- Commands:
|
||||
```bash
|
||||
cd /app
|
||||
@@ -316,7 +316,7 @@ iptables / ipset rules
|
||||
- QA: `git push` succeeds, remote updated
|
||||
- QA: `git submodule status` in parent repo shows app with commit hash
|
||||
|
||||
- [ ] **Task G4**: Update parent repo to reference pushed submodule
|
||||
- [x] **Task G4**: Update parent repo to reference pushed submodule
|
||||
- Commands:
|
||||
```bash
|
||||
cd /path/to/03.wireguard-policy
|
||||
|
||||
Reference in New Issue
Block a user