Add Go TUI implementation plan
- Comprehensive research on Go TUI libraries - Architecture design with Bubble Tea stack - 14-day implementation roadmap - Package structure and component design - User experience wireframes - Security and performance considerations
This commit is contained in:
543
GO_TUI_PLAN.md
Normal file
543
GO_TUI_PLAN.md
Normal file
@@ -0,0 +1,543 @@
|
||||
# WireGuard Client Manager - Go TUI Implementation Plan
|
||||
|
||||
## Executive Summary
|
||||
|
||||
Converting the bash-based `wg-client-manager` to a modern, responsive Go TUI application using Bubble Tea and the Charm ecosystem. This will provide a better user experience with interactive forms, real-time status updates, and intuitive navigation.
|
||||
|
||||
## Technology Stack
|
||||
|
||||
### Core Framework
|
||||
- **bubbletea** (v1.3.10) - Elm-architecture TUI framework
|
||||
- **lipgloss** - Expressive styling and theming
|
||||
|
||||
### Component Libraries
|
||||
- **huh** - Terminal forms for client creation
|
||||
- **bubble-table** - Interactive table for client list
|
||||
- **bubbles** - Text input and other UI components
|
||||
- **qrterminal** - QR code generation for terminal display
|
||||
|
||||
### Go Modules
|
||||
- WireGuard Go library (if available) or exec-based wrapper
|
||||
- Configuration management (Viper or native config)
|
||||
- File system operations (os, path/filepath)
|
||||
|
||||
## Functional Requirements Analysis
|
||||
|
||||
### Commands to Implement
|
||||
|
||||
| Command | Current Behavior | TUI Implementation |
|
||||
|---------|-----------------|-------------------|
|
||||
| **add** | Interactive prompts or WGI_ env vars | Form modal with fields: name, DNS, PSK option |
|
||||
| **remove** | Command-line with confirmation | Select from list → Confirm modal → Delete |
|
||||
| **list** | Table view with status | Interactive table with sorting, filtering |
|
||||
| **show** | Display client config | Detail view with copyable sections |
|
||||
| **qr** | Display QR code | Inline QR code in modal |
|
||||
|
||||
### Key Features
|
||||
|
||||
#### 1. Client Management
|
||||
- **Add client**
|
||||
- Name input (regex validation: `[a-zA-Z0-9_-]+`, max 64 chars)
|
||||
- Optional DNS configuration
|
||||
- PSK toggle (yes/no)
|
||||
- Auto-assign IPv4/IPv6 addresses
|
||||
- Generate client keys
|
||||
- Create server and client configs
|
||||
- Generate QR code
|
||||
|
||||
- **Remove client**
|
||||
- Select from list
|
||||
- Confirmation dialog
|
||||
- Remove config files
|
||||
- Reload WireGuard
|
||||
|
||||
- **List clients**
|
||||
- Table view: Name, IPv4, IPv6, Status (Connected/Disconnected)
|
||||
- Sorting by column
|
||||
- Filtering/search
|
||||
- Real-time status refresh
|
||||
|
||||
- **Show client details**
|
||||
- Full configuration display
|
||||
- Copy to clipboard functionality
|
||||
- Status information (last handshake, transfer stats)
|
||||
|
||||
- **QR code display**
|
||||
- ANSI-colored QR code in terminal
|
||||
- Toggle fullscreen/inline mode
|
||||
|
||||
#### 2. Configuration Loading
|
||||
- Read `/etc/wg-admin/config.conf`
|
||||
- Environment variable support
|
||||
- Validation of required settings (SERVER_DOMAIN, WG_PORT, etc.)
|
||||
|
||||
#### 3. Validation
|
||||
- Client name format
|
||||
- IP availability checks
|
||||
- DNS server format validation
|
||||
- Pre-install checks (WireGuard installed, config exists)
|
||||
|
||||
#### 4. Security
|
||||
- Run as root required
|
||||
- Proper file permissions (0600 for keys)
|
||||
- Atomic config writes
|
||||
- Temporary key cleanup
|
||||
|
||||
#### 5. Backup & Recovery
|
||||
- Auto-backup before add/remove
|
||||
- Config backup/restore functionality
|
||||
|
||||
## Architecture Design
|
||||
|
||||
### Package Structure
|
||||
|
||||
```
|
||||
wg-admin-tui/
|
||||
├── cmd/
|
||||
│ └── main.go # Entry point
|
||||
├── internal/
|
||||
│ ├── config/
|
||||
│ │ ├── config.go # Configuration loading
|
||||
│ │ └── defaults.go # Default values
|
||||
│ ├── wireguard/
|
||||
│ │ ├── client.go # Client management
|
||||
│ │ ├── keys.go # Key generation
|
||||
│ │ ├── config.go # WireGuard config parsing
|
||||
│ │ └── status.go # Status monitoring
|
||||
│ ├── tui/
|
||||
│ │ ├── app.go # Main TUI application
|
||||
│ │ ├── model.go # Application state
|
||||
│ │ ├── update.go # Message handlers
|
||||
│ │ ├── view.go # Rendering
|
||||
│ │ ├── screens/
|
||||
│ │ │ ├── list.go # Client list view
|
||||
│ │ │ ├── add.go # Add client form
|
||||
│ │ │ ├── detail.go # Client detail view
|
||||
│ │ │ └── qr.go # QR code view
|
||||
│ │ ├── components/
|
||||
│ │ │ ├── table.go # Client table
|
||||
│ │ │ ├── statusbar.go # Status bar
|
||||
│ │ │ └── modal.go # Modal dialogs
|
||||
│ │ └── theme/
|
||||
│ │ ├── colors.go # Color scheme
|
||||
│ │ └── style.go # Styling utilities
|
||||
│ ├── validation/
|
||||
│ │ ├── client.go # Client name validation
|
||||
│ │ ├── network.go # IP/DNS validation
|
||||
│ │ └── config.go # Config syntax validation
|
||||
│ └── backup/
|
||||
│ ├── backup.go # Backup operations
|
||||
│ └── restore.go # Restore operations
|
||||
├── pkg/
|
||||
│ └── util/
|
||||
│ ├── exec.go # Command execution helpers
|
||||
│ └── file.go # File operations
|
||||
└── go.mod
|
||||
```
|
||||
|
||||
### Component Design
|
||||
|
||||
#### 1. Main Application (app.go)
|
||||
```go
|
||||
type Application struct {
|
||||
model Model
|
||||
programs *tea.Program
|
||||
config *config.Config
|
||||
wireguard *wireguard.Client
|
||||
}
|
||||
|
||||
func NewApplication() (*Application, error)
|
||||
func (a *Application) Run() error
|
||||
```
|
||||
|
||||
#### 2. Model (model.go)
|
||||
```go
|
||||
type Model struct {
|
||||
screen Screen // Current active screen
|
||||
clients []Client // Client data
|
||||
selected int // Selected client
|
||||
loading bool // Loading state
|
||||
error error // Error message
|
||||
table table.Model // Client table
|
||||
form *huh.Form // Add client form
|
||||
modal *Modal // Active modal
|
||||
status Status // Status bar state
|
||||
}
|
||||
|
||||
type Screen interface {
|
||||
Init() tea.Cmd
|
||||
Update(msg tea.Msg) (Screen, tea.Cmd)
|
||||
View() string
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. Screens
|
||||
- **ListScreen**: Display client table
|
||||
- **AddScreen**: Form for adding client
|
||||
- **DetailScreen**: Show client configuration
|
||||
- **QRScreen**: Display QR code
|
||||
|
||||
#### 4. WireGuard Integration
|
||||
```go
|
||||
type Client struct {
|
||||
Name string
|
||||
IPv4 string
|
||||
IPv6 string
|
||||
PublicKey string
|
||||
HasPSK bool
|
||||
Status ConnectionStatus
|
||||
LastSeen time.Time
|
||||
Handshake string
|
||||
ConfigPath string
|
||||
}
|
||||
|
||||
type Manager interface {
|
||||
ListClients() ([]Client, error)
|
||||
AddClient(name, dns string, usePSK bool) (*Client, error)
|
||||
RemoveClient(name string) error
|
||||
GetClient(name string) (*Client, error)
|
||||
GetStatus() (Status, error)
|
||||
ReloadConfig() error
|
||||
}
|
||||
```
|
||||
|
||||
## Implementation Roadmap
|
||||
|
||||
### Phase 1: Project Setup & Foundation (Days 1-2)
|
||||
|
||||
**Goal**: Establish project structure and core framework
|
||||
|
||||
**Tasks**:
|
||||
- [ ] Initialize Go module
|
||||
- [ ] Set up project structure
|
||||
- [ ] Add dependencies (bubbletea, lipgloss, huh, bubble-table, qrterminal)
|
||||
- [ ] Create configuration loading from `/etc/wg-admin/config.conf`
|
||||
- [ ] Implement root check
|
||||
- [ ] Create basic TUI skeleton with empty screens
|
||||
- [ ] Set up logging (both file and console)
|
||||
|
||||
**Deliverables**:
|
||||
- Working TUI that launches and shows a placeholder screen
|
||||
- Configuration system in place
|
||||
|
||||
### Phase 2: Client List View (Days 3-4)
|
||||
|
||||
**Goal**: Display clients in interactive table
|
||||
|
||||
**Tasks**:
|
||||
- [ ] Implement WireGuard client list parsing
|
||||
- [ ] Create `Client` struct
|
||||
- [ ] Set up bubble-table with columns: Name, IPv4, IPv6, Status
|
||||
- [ ] Parse client configs from `/etc/wireguard/conf.d/client-*.conf`
|
||||
- [ ] Check connection status using `wg show`
|
||||
- [ ] Implement keyboard navigation (j/k, arrows, Enter, q)
|
||||
- [ ] Add status bar with help text
|
||||
- [ ] Implement auto-refresh (every 30 seconds)
|
||||
|
||||
**Deliverables**:
|
||||
- Functional client list with real-time status
|
||||
|
||||
### Phase 3: Add Client Form (Days 5-6)
|
||||
|
||||
**Goal**: Create interactive form for adding clients
|
||||
|
||||
**Tasks**:
|
||||
- [ ] Create add screen with `huh` form
|
||||
- [ ] Implement fields:
|
||||
- Client name (text input)
|
||||
- DNS servers (text input with default)
|
||||
- Use PSK (toggle/confirm)
|
||||
- [ ] Add validation:
|
||||
- Client name regex
|
||||
- IP availability check
|
||||
- DNS format validation
|
||||
- [ ] Implement WireGuard key generation
|
||||
- [ ] Auto-assign IPv4/IPv6 addresses
|
||||
- [ ] Create server config file
|
||||
- [ ] Create client config file
|
||||
- [ ] Generate QR code
|
||||
- [ ] Implement atomic config writes
|
||||
- [ ] Auto-backup before add
|
||||
- [ ] Reload WireGuard config
|
||||
|
||||
**Deliverables**:
|
||||
- Working add client form with all validations
|
||||
|
||||
### Phase 4: Client Detail View (Days 7-8)
|
||||
|
||||
**Goal**: Show full client configuration
|
||||
|
||||
**Tasks**:
|
||||
- [ ] Create detail screen
|
||||
- [ ] Display:
|
||||
- Client name
|
||||
- IP addresses
|
||||
- Public key
|
||||
- Full configuration
|
||||
- Connection status
|
||||
- Last handshake
|
||||
- Transfer stats (Rx/Tx)
|
||||
- [ ] Implement copy to clipboard
|
||||
- [ ] Add "Back" and "Delete" buttons
|
||||
- [ ] Delete confirmation modal
|
||||
- [ ] Remove client with config deletion
|
||||
- [ ] Auto-backup before remove
|
||||
- [ ] Reload WireGuard config
|
||||
|
||||
**Deliverables**:
|
||||
- Functional detail view with delete capability
|
||||
|
||||
### Phase 5: QR Code Display (Days 9-10)
|
||||
|
||||
**Goal**: Display QR codes for mobile setup
|
||||
|
||||
**Tasks**:
|
||||
- [ ] Create QR screen
|
||||
- [ ] Read client config
|
||||
- [ ] Generate QR code using `qrterminal`
|
||||
- [ ] Display QR code inline
|
||||
- [ ] Implement fullscreen QR mode
|
||||
- [ ] Add resize handling for QR codes
|
||||
- [ ] Test with various terminal sizes
|
||||
|
||||
**Deliverables**:
|
||||
- Working QR code display
|
||||
|
||||
### Phase 6: Polish & UX Improvements (Days 11-12)
|
||||
|
||||
**Goal**: Improve user experience
|
||||
|
||||
**Tasks**:
|
||||
- [ ] Add color themes
|
||||
- [ ] Implement modal dialogs for confirmations
|
||||
- [ ] Add toast notifications for success/error
|
||||
- [ ] Implement search/filter clients
|
||||
- [ ] Add sorting by columns
|
||||
- [ ] Improve error messages with actionable guidance
|
||||
- [ ] Add keyboard shortcuts help
|
||||
- [ ] Implement loading indicators
|
||||
|
||||
**Deliverables**:
|
||||
- Polished, user-friendly interface
|
||||
|
||||
### Phase 7: Backup & Recovery (Days 13-14)
|
||||
|
||||
**Goal**: Add backup and restore functionality
|
||||
|
||||
**Tasks**:
|
||||
- [ ] Implement backup operations
|
||||
- [ ] Create restore functionality
|
||||
- [ ] Add backup history view
|
||||
- [ ] Implement retention policy
|
||||
- [ ] Add backup/restore screens
|
||||
|
||||
**Deliverables**:
|
||||
- Complete backup/restore system
|
||||
|
||||
## User Experience Design
|
||||
|
||||
### Screen Flow
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Client List (Main) │
|
||||
│ ┌─────┬─────┬──────────┬─────────┐│
|
||||
│ │Name │IPv4 │ IPv6 │ Status ││
|
||||
│ ├─────┼─────┼──────────┼─────────┤│
|
||||
│ │laptop│ .2 │ ::2 │Connected││ ← Selected
|
||||
│ │phone │ .3 │ ::3 │ Disc ││
|
||||
│ └─────┴─────┴──────────┴─────────┘│
|
||||
│ │
|
||||
│ [a] Add [d] Detail [?] Help [q] Quit│
|
||||
└─────────────────────────────────────┘
|
||||
↓ Enter
|
||||
┌─────────────────────────────────────┐
|
||||
│ Client Detail: laptop │
|
||||
│ │
|
||||
│ Name: laptop │
|
||||
│ IPv4: 10.10.69.2 │
|
||||
│ IPv6: fd69:dead:beef:69::2 │
|
||||
│ Status: Connected │
|
||||
│ Last Handshake: 2m ago │
|
||||
│ Rx: 1.2 MB Tx: 3.4 MB │
|
||||
│ │
|
||||
│ [Interface] │
|
||||
│ PrivateKey = ... │
|
||||
│ Address = 10.10.69.2/24... │
|
||||
│ │
|
||||
│ [ESC] Back [x] Delete [c] Copy │
|
||||
└─────────────────────────────────────┘
|
||||
↓ 'a' from list
|
||||
┌─────────────────────────────────────┐
|
||||
│ Add New Client │
|
||||
│ │
|
||||
│ Client Name: [_________] │
|
||||
│ DNS Servers: [8.8.8.8, 8.8.4.4] │
|
||||
│ Use PSK? [x] Yes │
|
||||
│ │
|
||||
│ [Enter] Submit [ESC] Cancel │
|
||||
└─────────────────────────────────────┘
|
||||
↓ 'q' from detail
|
||||
┌─────────────────────────────────────┐
|
||||
│ Delete Confirmation │
|
||||
│ │
|
||||
│ Delete client 'laptop'? │
|
||||
│ │
|
||||
│ [Enter] Yes [ESC] No │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Keyboard Shortcuts
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `q` | Quit |
|
||||
| `a` | Add client |
|
||||
| `d` | Show details |
|
||||
| `x` | Delete |
|
||||
| `r` | Refresh |
|
||||
| `/` | Search/filter |
|
||||
| `↑/k` | Move up |
|
||||
| `↓/j` | Move down |
|
||||
| `Enter` | Select/Confirm |
|
||||
| `Esc` | Back/Cancel |
|
||||
| `?` | Help |
|
||||
| `c` | Copy to clipboard |
|
||||
|
||||
### Color Scheme
|
||||
|
||||
```go
|
||||
// Default theme
|
||||
const (
|
||||
ColorPrimary lipgloss.Color
|
||||
ColorSecondary lipgloss.Color
|
||||
ColorSuccess lipgloss.Color
|
||||
ColorWarning lipgloss.Color
|
||||
ColorError lipgloss.Color
|
||||
ColorMuted lipgloss.Color
|
||||
)
|
||||
|
||||
// Example
|
||||
ColorPrimary = lipgloss.Color("#007AFF") // Blue
|
||||
ColorSuccess = lipgloss.Color("#34C759") // Green
|
||||
ColorWarning = lipgloss.Color("#FF9500") // Orange
|
||||
ColorError = lipgloss.Color("#FF3B30") // Red
|
||||
ColorMuted = lipgloss.Color("#8E8E93") // Gray
|
||||
```
|
||||
|
||||
## Error Handling Strategy
|
||||
|
||||
### Validation Errors
|
||||
- Display inline validation messages
|
||||
- Show specific error with action guidance
|
||||
- Keep form state on error
|
||||
- Highlight invalid fields
|
||||
|
||||
### System Errors
|
||||
- Show modal with error message
|
||||
- Log full error to file
|
||||
- Provide actionable guidance
|
||||
- Offer retry or cancel options
|
||||
|
||||
### Examples
|
||||
```
|
||||
ERROR: Client 'laptop' already exists
|
||||
Action: Choose a different name or remove existing client first
|
||||
|
||||
ERROR: No available IPv4 addresses
|
||||
Action: Remove unused clients or expand VPN range
|
||||
```
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
1. **Lazy Loading**
|
||||
- Load clients on screen init
|
||||
- Cache client data between refreshes
|
||||
|
||||
2. **Asynchronous Operations**
|
||||
- Run WireGuard status checks in background
|
||||
- Use tea.Cmd for async operations
|
||||
|
||||
3. **Throttled Refresh**
|
||||
- Auto-refresh every 30 seconds (configurable)
|
||||
- Manual refresh with 'r' key
|
||||
|
||||
4. **QR Code Optimization**
|
||||
- Generate on demand, not cached
|
||||
- Use appropriate error correction level
|
||||
|
||||
## Security Considerations
|
||||
|
||||
1. **Root Privileges**
|
||||
- Check for root at startup
|
||||
- Display clear error if not root
|
||||
|
||||
2. **Key Storage**
|
||||
- Write keys with 0600 permissions
|
||||
- Clean up temporary key files
|
||||
|
||||
3. **Atomic Operations**
|
||||
- Write to temp file, then move
|
||||
- Prevent config corruption
|
||||
|
||||
4. **Input Validation**
|
||||
- Strict regex for client names
|
||||
- IP availability checks
|
||||
- DNS format validation
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Unit Tests
|
||||
- Validation functions
|
||||
- Configuration parsing
|
||||
- Client model methods
|
||||
|
||||
### Integration Tests
|
||||
- WireGuard config generation
|
||||
- Key generation
|
||||
- Backup/restore
|
||||
|
||||
### Manual Testing
|
||||
- End-to-end workflows
|
||||
- Terminal size handling
|
||||
- Error scenarios
|
||||
|
||||
## Milestones
|
||||
|
||||
| Milestone | Days | Goal |
|
||||
|-----------|------|------|
|
||||
| M1: Foundation | 2 | Project setup, basic TUI |
|
||||
| M2: List View | 4 | Client list with status |
|
||||
| M3: Add Client | 6 | Working add form |
|
||||
| M4: Detail & Delete | 8 | Full client management |
|
||||
| M5: QR Codes | 10 | QR code display |
|
||||
| M6: Polish | 12 | UX improvements |
|
||||
| M7: Complete | 14 | Fully functional TUI |
|
||||
|
||||
## Success Criteria
|
||||
|
||||
- ✅ All bash functionality replicated in TUI
|
||||
- ✅ Responsive and performant UI
|
||||
- ✅ Clear error messages with actionable guidance
|
||||
- ✅ Keyboard shortcuts for all actions
|
||||
- ✅ Real-time client status updates
|
||||
- ✅ Working QR code generation
|
||||
- ✅ Backup/restore functionality
|
||||
- ✅ Polished, intuitive user experience
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
- Config import/export
|
||||
- Client statistics dashboard
|
||||
- Connection monitoring view
|
||||
- Multiple server support
|
||||
- Template-based client creation
|
||||
- Bulk operations
|
||||
- Dark/Light theme toggle
|
||||
|
||||
---
|
||||
|
||||
**Estimated Timeline**: 14 days for MVP
|
||||
**Primary Dependencies**: bubbletea, lipgloss, huh, bubble-table, qrterminal
|
||||
**Minimum Go Version**: 1.21+
|
||||
**Target Terminal**: ANSI-compatible terminals (Linux, macOS, Windows with WSL)
|
||||
Reference in New Issue
Block a user