Selaa lähdekoodia

Update docs: README, ARCHITECTURE with mermaid diagrams

- Complete README with all features, commands, events
- ARCHITECTURE.md with mermaid diagrams
- Port mappings, configuration, docker usage
- Updated memory file in workspace
Luis Rosales 2 kuukautta sitten
vanhempi
sitoutus
4c4653b3a3
2 muutettua tiedostoa jossa 517 lisäystä ja 126 poistoa
  1. 354 0
      ARCHITECTURE.md
  2. 163 126
      README.md

+ 354 - 0
ARCHITECTURE.md

@@ -0,0 +1,354 @@
+# client2server Architecture
+
+> Complete system architecture for bidirectional event forwarding between OpenWrt routers and central server.
+
+## System Overview
+
+```mermaid
+flowchart TB
+    subgraph Router["OpenWrt Router"]
+        direction TB
+        Lua[("client2server-unified.lua")]
+        DHCP[("DHCP Monitor")]
+        WAN[("WAN Monitor")]
+        CMD[("Command Executor")]
+        Link[("Link Monitor")]
+    end
+    
+    subgraph Cloud["Cloud"]
+        subgraph CaddyLB["Caddy Load Balancer :3843"]
+            WS[("WebSocket")]
+            API[("HTTP :3844")]
+        end
+        
+        subgraph Server["Go Servers (x2)"]
+            S1[("server1")]
+            S2[("server2")]
+        end
+        
+        subgraph Redpanda["Redpanda"]
+            Events[("router-events")]
+            Commands[("router-commands")]
+        end
+        
+        subgraph Backend["LuIS Backend"]
+            API2[("API Server")]
+            DB[(Database)]
+        end
+    end
+    
+    Router -->|WS| CaddyLB
+    CaddyLB --> WS
+    WS <-->|lb| S1
+    WS <-->|lb| S2
+    S1 -->|publish| Events
+    S2 -->|publish| Commands
+    Events --> Redpanda
+    Commands --> Redpanda
+    Redpanda --> API2
+    API2 --> DB
+```
+
+## Data Flows
+
+### Event Flow (Router → Server)
+
+```mermaid
+sequenceDiagram
+    participant R as Router
+    participant C as Caddy
+    participant S as Go Server
+    participant K as Redpanda
+    participant L as LuIS
+
+    Note over R,L: DHCP Event Example
+    
+    R->>C: WebSocket connect → :3843
+    activate C
+    C->>S: Proxy to server1
+    activate S
+    S->>K: Produce → router-events
+    activate K
+    K-->>S: ACK
+    deactivate K
+    S-->>C: ACK
+    deactivate S
+    C-->>R: Connected!
+    deactivate C
+    
+    Note over R,L: Later - New DHCP Lease
+    R->>C: Event: dhcp_lease_new
+    C->>S: Forward event
+    S->>K: Publish event
+    S->>R: ACK
+    
+    Note over R,L: LuIS Dashboard consumes
+    L->>K: Consume router-events
+    K-->>L: Event data
+```
+
+### Command Flow (Server → Router)
+
+```mermaid
+sequenceDiagram
+    participant L as LuIS
+    participant S as Go Server
+    participant K as Redpanda
+    participant R as Router
+    
+    Note over L,R: Server sends command to router
+    L->>S: POST /api/command
+    S->>K: Publish → router-commands
+    K-->>S: ACK
+    S-->>L: command_id
+    
+    Note over R,R: Router receives via WebSocket
+    R->>R: Listen for commands
+    R->>R: Execute: uci set network.lan.ipaddr='192.168.1.1'
+    R->>R: Commit: uci commit network
+    R->>S: Return result
+    S->>K: Publish result (optional)
+```
+
+## Component Architecture
+
+```mermaid
+flowchart LR
+    subgraph Router["Router (OpenWrt)"]
+        WSCli[("WebSocket Client")]
+        Buf[("Buffer File
+/tmp/event_buffer")]
+        Events[("Event Sources")] 
+        CMD[("Command Executor")]
+        
+        Events -->|new| WSCli
+        WSCli -->|offline| Buf
+        Buf -->|flush| WSCli
+    end
+    
+    subgraph Server["Go Server"]
+        WSHan[("WS Handler")]
+        RedProd[("Producer")]
+        RedCons[("Consumer")]
+        Routers[("Router State")]
+        CMDServ[("Command Service")]
+    end
+    
+    WSCli -->|connect| WSHan
+    WSHan --> RedProd
+    RedProd -->|topics| Redpanda["Redpanda"]
+    Redpanda --> RedCons
+    RedCons --> CMDServ
+    CMDServ --> Routers
+```
+
+## Port Mappings
+
+| Service | Port | Protocol | Purpose |
+|---------|------|----------|--------||
+| Caddy WS | 3843 | WebSocket | Router connections |
+| Caddy HTTP | 3844 | HTTP | REST API |
+| Redpanda | 9092 | Kafka | Event storage |
+| Redpanda REST | 8082 | HTTP | Schema registry |
+
+## Configuration
+
+```yaml
+# docker-compose.yml
+environment:
+  REDPANDA_BROKERS: redpanda:9092
+  TOKEN: ***
+  PORT: 3843
+```
+
+## Build Targets
+
+```mermaid
+flowchart LR
+    A[("Source")] --> B[("Build")]
+    B --> C[("Package")]
+    B --> D[("Docker")]
+    B --> E[("IPK")]
+    
+    C -->|Go| D[("server binary")]
+    C -->|Lua| E[("OpenWrt ipk")]
+    
+    subgraph Build["Builds"]
+        direction TB
+        F[("docker-compose up")]
+        G[("./scripts/feeds")]
+    end
+```
+
+## Topics (Redpanda)
+
+
+| Topic | Partitions | Retention | Purpose |
+|-------|-----------|-----------|---------|
+| router-events | 3 | 7 days | All router events |
+| router-commands | 3 | 1 hour | Commands to routers |
+
+## Error Handling
+
+```mermaid
+flowchart TD
+    A[("Connection Lost")] --> B{Router Online?}
+    B -->|Yes| C[("Buffer Events")]
+    C --> D[("Retry Every 5s")]
+    D --> E{Connected?}
+    E -->|Yes| F[("Flush Buffer")]
+    E -->|No| D
+    B -->|No| G[("Wait")]
+    G --> H[("Timer Reset")]
+    H --> A
+```
+
+## System Overview
+
+```mermaid
+flowchart TB
+    subgraph Router["OpenWrt Router"]
+        direction TB
+        Lua[("client2server-unified.lua")]
+        DHCP[("DHCP Monitor")]
+        WAN[("WAN Monitor")]
+        CMD[("Command Executor")]
+    end
+    
+    subgraph CaddyLB["Caddy Load Balancer"]
+        WS["WebSocket :3843"]
+        API["HTTP API :3844"]
+    end
+    
+    subgraph Server["Go Servers"]
+        S1["server1"]
+        S2["server2"]
+    end
+    
+    subgraph Redpanda["Redpanda Cluster"]
+        Events[("router-events")]
+        Commands[("router-commands")]
+    end
+    
+    subgraph Backend["LuIS Backend"]
+        API2[("API Server")]
+        DB[(Database)]
+    end
+    
+    Router -->|WebSocket| CaddyLB
+    CaddyLB --> WS
+    WS --> S1
+    WS --> S2
+    S1 --> Events
+    S2 --> Commands
+    Events --> Redpanda
+    Commands --> Redpanda
+    Redpanda --> API2
+    API2 --> DB
+```
+
+## Data Flow
+
+```mermaid
+sequenceDiagram
+    participant R as Router
+    participant C as Caddy
+    participant S as Go Server
+    participant K as Redpanda
+    participant L as LuIS
+
+    Note over R,L: Event Flow
+    
+    R->>C: WebSocket connect :3843
+    C->>S: Proxy to server1
+    S->>K: Publish to router-events
+    
+    Note over R,L: Command Flow
+    
+    L->>K: Publish command
+    K->>S: Consume from router-commands
+    S->>R: WebSocket send command
+    R->>R: Execute (uci_set, shell, etc)
+    R->>S: Ack result
+    S->>K: Publish result
+    K->>L: Result stored
+```
+
+## Component Details
+
+```mermaid
+flowchart LR
+    subgraph Lua["Lua Client"]
+        WS[("WebSocket")]
+        Buf[("Buffer")]
+        DHCP[("DHCP")]
+        WAN[("WAN")]
+        CMD[("Commands")]
+    end
+    
+    subgraph GoServer["Go Server"]
+        Handler[("Handler")]
+        Redpanda[("Redpanda")]
+        RouterMgr[("Router State")]
+    end
+    
+    WS -->|buffer when offline| Buf
+    Buf -->|flush on reconnect| Handler
+    DHCP -->|events| Handler
+    WAN -->|events| Handler
+    Handler --> Redpanda
+    Redpanda --> RouterMgr
+```
+
+## Ports
+
+| Service | Port | Protocol |
+|---------|------|----------|
+| WebSocket LB | 3843 | WS |
+| HTTP API | 3844 | HTTP |
+| Redpanda Kafka | 9092 | Kafka |
+| Redpanda REST | 8082 | HTTP |
+
+## Config
+
+```yaml
+# Environment
+TOKEN: ***              # Auth token
+REDPANDA_BROKERS: redpanda:9092   # Redpanda address
+PORT: 3843             # Listening port
+```
+
+## Commands
+
+| Command | Example | Response |
+|---------|---------|-----------|
+| `uci_set` | `{"config":"network", "section":"lan", "option":"ipaddr", "value":"192.168.1.1"}` | Success |
+| `shell` | `{"command":"reboot"}` | Output |
+| `reboot` | `{}` | Scheduled |
+| `wifi_restart` | `{}` | Network restart |
+| `status` | `{}` | JSON status |
+
+## Events
+
+| Event | Source | Payload |
+|-------|--------|---------|
+| `dhcp_lease_new` | dnsmasq | mac, ip, hostname |
+| `dhcp_lease_expire` | dnsmasq | mac, old_ip |
+| `wan_link_up` | /sys/class/net/* | device |
+| `wan_link_down` | /sys/class/net/* | device |
+| `wan_dhcp_new` | ubus | new_ip |
+| `wan_dhcp_changed` | ubus | old_ip, new_ip |
+
+## Docker Run
+
+```bash
+TOKEN=*** docker-compose up -d
+```
+
+## IPK Build
+
+```bash
+# With OpenWrt SDK
+make package/client2server-unified/compile
+make package/client2server-unified/ipk
+```

+ 163 - 126
README.md

@@ -1,183 +1,220 @@
 # client2server
 
-> **Lightweight event forwarder for OpenWrt routers to central server**
-> Version 2.0 - Lua + WebSocket implementation
+> **Lightweight bi-directional event forwarder for OpenWrt routers**
 
-## Overview
-
-Lightweight Lua scripts that listen to OpenWrt events (WiFi, DHCP, network) and forward them to a central server via WebSocket with auto-reconnect and local buffering.
-
-## Why Lua + WebSocket?
-
-| Feature | Bash (v1) | Lua + WS (v2) |
-|---------|----------|--------------|
-| **Connection** | HTTP polling | WebSocket (persistent) |
-| **Auto-reconnect** | Manual | Built-in |
-| **Offline buffer** | File only | In-memory + file |
-| **Error handling** | Basic | Exception-safe |
-| **Size** | ~20KB | ~30KB inc. deps |
+[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
 
-## Architecture
+## Overview
 
 ```
-┌─────────────────┐      WebSocket       ┌─────────────────┐
-│   OpenWrt       │ ════════════════►  │ Central Server  │
-│   Router       │                   │                │
-│                 │                   │  - Receive    │
-│  - DHCP       │                   │  - Store      │
-│  - WiFi      │                   │  - Real-time  │
-│  - Network   │                   │  - LuIS UI   │
-│                 │                   │               │
-│ Buffer [offline]│─► sync when ──►  │              │
-└─────────────────┘    online        └─────────────────┘
+┌─────────────────────────────────────────────────────────────┐
+│                    client2server Architecture               │
+├─────────────────────────────────────────────────────────────┤
+│                                                              │
+│   OpenWrt Routers                                             │
+│       │                                                      │
+│       ▼ WebSocket :3843                                      │
+│   ┌──────────────────────────────────────────┐               │
+│   │   Caddy Load Balancer                    │               │
+│   │   - Health checks                       │               │
+│   │   - Auto-failover                       │               │
+│   └──────────────────┬───────────────────┘               │
+│                      │                                    │
+│          ┌───────────┴───────────┐                      │
+│          ▼                     ▼                      │
+│   ┌─────────────┐       ┌─────────────┐               │
+│   │  server1   │       │  server2   │               │
+│   │  (Go)      │       │  (Go)      │               │
+│   └─────┬───────┘       └─────┬───────┘               │
+│         │                  │                        │
+│         └────────┬─────────┘                        │
+│                  │                                 │
+│                  ▼                                 │
+│         ┌─────────────────┐                       │
+│         │   Redpanda     │  Events stored          │
+│         │   (Kafka)      │  Persisted             │
+│         └───────────────┘                       │
+│                                                             │
+└─────────────────────────────────────────────────────────────┘
 ```
 
-## Installing
-
-### On OpenWrt Router
+## Features
 
-```bash
-# Install dependencies
-opkg update
-opkg install lua luasocket
+- ✅ **WebSocket connection** with auto-reconnect
+- ✅ **Local buffer** (store-and-forward while offline)
+- ✅ **DHCP lease events** (new/expire)
+- ✅ **WAN link state** (up/down monitoring)
+- ✅ **WAN IP changes** (new ISP detection)
+- ✅ **Bidirectional** (receive commands from server)
+- ✅ **Command executor** (uci_set, shell, reboot, status)
+- ✅ **Load balancer** ready (Caddy)
+- ✅ **Event persistence** (Redpanda)
 
-# Copy files
-scp -r etc root@router:/etc/
-scp -r usr root@router:/usr/
+## Quick Start
 
-# Make executable
-chmod +x /etc/init.d/event-forwarder
-chmod +x /usr/sbin/event-forwarder.lua
+### Option 1: Docker Compose (Recommended)
 
-# Configure
-uci set event-forwarder.server.url='wss://your-server.com/ws'
-uci set event-forwarder.server.token='your-secret-token'
-uci set event-forwarder.general.enabled='1'
-uci commit event-forwarder
+```bash
+# Clone and run
+git clone https://git3.techno-world.net/lrosales/client2server.git
+cd client2server
 
-# Enable and start
-/etc/init.d/event-forwarder enable
-/etc/init.d/event-forwarder start
+# Start all services
+TOKEN=your-secret-token docker-compose up -d
 
-# Check logs
-logread -f -e client2server
+# Check status
+docker-compose ps
 ```
 
-### On Central Server
+### Option 2: Manual (Development)
 
 ```bash
+# Go server
 cd server
-npm install express ws
-node server.js
+go build -o server .
+REDPANDA_BROKERS=localhost:9092 TOKEN=*** ./server
+
+# On OpenWrt router (copy Lua script)
+scp package/src/client2server-unified.lua root@router:/usr/sbin/
+ssh root@router "chmod +x /usr/sbin/client2server-unified.lua"
 ```
 
-## Files
+## Ports
 
-| File | Purpose |
-|------|---------|
-| `usr/sbin/client2server.lua` | Main Lua forwarder |
-| `usr/sbin/event-forwarder.lua` | Original Lua prototype |
-| `etc/init.d/event-forwarder` | Init script |
-| `etc/config/event-forwarder` | UCI config |
-| `server/index.js` | Central Node.js receiver |
-| `README.md` | This file |
+| Service | Port | Protocol |
+|----------|------|----------|
+| WebSocket | 3843 | WS |
+| HTTP API | 3844 | HTTP |
+| Redpanda | 9092 | Kafka |
 
 ## Configuration
 
-### UCI Config
+### Environment Variables
+
+```bash
+TOKEN=***                # Authentication token
+REDPANDA_BROKERS=redpanda:9092   # Redpanda address
+PORT=3843               # Server port
+```
+
+### UCI Config (on Router)
 
 ```bash
-# /etc/config/event-forwarder
-config event-forwarder 'general'
+# /etc/config/client2server
+config client2server 'general'
     option enabled '1'
 
 config server
-    option url 'wss://your-server.com/ws'
-    option token 'CHANGE_ME_SECRET_TOKEN'
+    option url 'wss://your-server.com:3843'
+    option token '***'
 
-config router
-    option id 'router-hostname'
+config wan
+    option interface 'wan'
+    option device 'eth0'
 ```
 
-### Environment Variables
+## Commands
+
+Send from server to router via WebSocket or HTTP API:
 
 ```bash
-export SERVER_URL="wss://your-server.com/ws"
-export SERVER_TOKEN="your-token"
-export ROUTER_ID="router-name"
+# UCI set
+curl -X POST http://localhost:3844/api/command \
+  -H "Authorization: Bearer TOKEN" \
+  -d '{"router_id":"router1","command":"uci_set","args":{"config":"network","section":"lan","option":"ipaddr","value":"192.168.1.1"}}'
+
+# Shell
+curl -X POST http://localhost:3844/api/command \
+  -H "Authorization: Bearer TOKEN" \
+  -d '{"router_id":"router1","command":"shell","args":{"command":"reboot"}}'
+
+# Reboot
+curl -X POST http://localhost:3844/api/command \
+  -H "Authorization: Bearer TOKEN" \
+  -d '{"router_id":"router1","command":"reboot"}'
 ```
 
-## Event Types
+### Available Commands
 
-| Event | Source | Payload |
-|-------|-------|---------|
-| `dhcp_lease` | dnsmasq | mac, ip, hostname, action |
-| `wifi_connect` | hostapd | mac, signal, ssid |
-| `wifi_disconnect` | hostapd | mac, reason |
-| `interface_up` | netifd | device |
-| `interface_down` | netifd | device |
-
-## API Specification
-
-### WebSocket Message Format
-
-```json
-{
-  "router_id": "router-name",
-  "hostname": "openwrt-device",
-  "event_type": "dhcp_lease",
-  "timestamp": "2026-06-04T18:00:00Z",
-  "payload": {
-    "mac": "AA:BB:CC:DD:EE:FF",
-    "ip": "192.168.1.100",
-    "hostname": "iphone",
-    "action": "new"
-  }
-}
-```
+| Command | Description | Arguments |
+|---------|-------------|-----------|
+| `uci_set` | Set UCI config value | `config`, `section`, `option`, `value` |
+| `shell` | Run shell command | `command` |
+| `reboot` | Reboot router | - |
+| `wifi_restart` | Restart WiFi | - |
+| `status` | Get router status | - |
 
-### Server Endpoint
+## Events
 
-```javascript
-// Expects WebSocket connection
-wss://your-server.com/ws
+Router sends these events to server:
 
-// Or HTTP POST fallback
-POST /api/events
-Authorization: Bearer <token>
-Content-Type: application/json
+| Event | Source | Payload |
+|-------|--------|---------|
+| `dhcp_lease_new` | dnsmasq | `mac`, `ip`, `hostname` |
+| `dhcp_lease_expire` | dnsmasq | `mac`, `old_ip` |
+| `wan_link_up` | /sys/class/net/* | `device` |
+| `wan_link_down` | /sys/class/net/* | `device` |
+| `wan_dhcp_new` | ubus | `new_ip` |
+| `wan_dhcp_changed` | ubus | `old_ip`, `new_ip` |
+
+## Project Structure
+
+```
+client2server/
+├── ARCHITECTURE.md         # Architecture docs
+├── README.md             # This file
+├── Caddyfile            # Caddy load balancer
+├── docker-compose.yml   # Full stack
+├── package/
+│   ├── Makefile         # IPK build
+│   ├── src/
+│   │   └── client2server-unified.lua  # Router script
+│   └── files/
+│       ├── etc/init.d/
+│       └── etc/config/
+└── server/
+    ├── main.go
+    ├── go.mod
+    ├── Dockerfile
+    └── index.js         # HTTP fallback
 ```
 
-## Offline Behavior
+## Building IPK
 
-1. **Internet disconnects** → Events saved to local buffer
-2. **Router reboots** → Buffer persists in `/tmp/event_buffer`
-3. **Internet restores** → Buffer flushed in order
-4. **Never lose events** ✓
+```bash
+# With OpenWrt SDK
+./scripts/feeds update -a
+./scripts/feeds install client2server-unified
+make package/client2server-unified/compile
+make package/client2server-unified/ipk
+
+# Output
+# bin/packages/*/client2server-unified_*.ipk
+```
 
-## Troubleshooting
+## Monitoring
 
 ```bash
-# Check if running
-pgrep -a client2server
+# Server logs
+docker-compose logs -f server1
 
-# View logs
+# Router logs (on OpenWrt)
 logread -f -e client2server
 
-# Check buffer
-cat /tmp/event_buffer
-
-# Manual test
-lua /usr/sbin/client2server.lua
+# Redpanda
+docker-compose logs -f redpanda
 
-# Force stop
-killall -9 client2server
+# API
+curl http://localhost:3844/api/routers
+curl http://localhost:3844/api/events
 ```
 
-## Dependencies
+## Security
 
-- OpenWrt: `lua`, `luasocket`
-- Server: `express`, `ws` (npm)
+- Token-based auth on both WS and HTTP
+- Use TLS (wss://) in production
+- Firewalls: Only allow port 3843 from router network
+- Redpanda: Enable auth for production
 
 ## License