feat: cell-to-cell (PIC mesh) connection feature
Site-to-site WireGuard tunnels between PIC cells with automatic DNS forwarding. Each cell generates an invite JSON (public key, endpoint, VPN subnet, DNS IP, domain); the remote cell imports it to establish a bidirectional tunnel and CoreDNS forwarding block so each cell's domain resolves across the mesh. Backend: - CellLinkManager: invite generation, add/remove connections, live WireGuard handshake status; stores links in data/cell_links.json - WireGuardManager: add_cell_peer() accepts subnet CIDRs (not /32) and an optional endpoint for site-to-site peers; _read_iface_field() reads port, address, and network directly from wg0.conf at runtime instead of constants - NetworkManager: add/remove CoreDNS forwarding blocks per remote cell domain - app.py: /api/cells/* routes; _next_peer_ip() derives VPN range from configured address so peer allocation follows any address change Frontend: - CellNetwork page: invite panel (JSON + QR), connect form (paste JSON), connected cells list (green/red status, disconnect button) - App.jsx: Cell Network nav entry and route Tests: 25 new tests across test_wireguard_manager, test_network_manager, test_cell_link_manager (263 total) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -181,6 +181,15 @@ export const servicesAPI = {
|
||||
restartService: (serviceName) => api.post(`/api/services/bus/services/${serviceName}/restart`),
|
||||
};
|
||||
|
||||
// Cell-to-cell connections API
|
||||
export const cellLinkAPI = {
|
||||
getInvite: () => api.get('/api/cells/invite'),
|
||||
listConnections: () => api.get('/api/cells'),
|
||||
addConnection: (invite) => api.post('/api/cells', invite),
|
||||
removeConnection: (name) => api.delete(`/api/cells/${name}`),
|
||||
getStatus: (name) => api.get(`/api/cells/${name}/status`),
|
||||
};
|
||||
|
||||
// Health check
|
||||
export const healthAPI = {
|
||||
check: () => api.get('/health'),
|
||||
|
||||
Reference in New Issue
Block a user