feat: connectivity — registry-driven peer table, sshuttle/proxy egress, egress UI
The peer table was empty because it was not consulting the peer registry; now peers are driven by PeerRegistry so the Connectivity page reflects actual connected cells. Exit-key handling is unified: all code paths now use the same key derivation so a store-service exit bridge and a manual WireGuard peer both produce consistent routing state. Two new egress exit types are added (sshuttle via SSH tunnel and proxy via redsocks SOCKS5), wiring through connectivity_manager, egress_manager, and app.py routes. This lets a cell route its traffic through an SSH host or a SOCKS5 proxy as an alternative to WireGuard exit nodes. ServiceStoreManager and ServiceBus updated so the egress lifecycle (install / uninstall) is cleanly signalled between components. Connectivity.jsx gains the Service Egress section, letting operators assign and reassign egress methods from the UI without touching config files. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -117,9 +117,7 @@ export const networkAPI = {
|
||||
getDNSRecords: () => api.get('/api/dns/records'),
|
||||
addDNSRecord: (record) => api.post('/api/dns/records', record),
|
||||
removeDNSRecord: (record) => api.delete('/api/dns/records', { data: record }),
|
||||
getDHCPLeases: () => api.get('/api/dhcp/leases'),
|
||||
addDHCPReservation: (reservation) => api.post('/api/dhcp/reservations', reservation),
|
||||
removeDHCPReservation: (reservation) => api.delete('/api/dhcp/reservations', { data: reservation }),
|
||||
getDNSOverview: () => api.get('/api/dns/overview'),
|
||||
getNTPStatus: () => api.get('/api/ntp/status'),
|
||||
testNetwork: (data) => api.post('/api/network/test', data),
|
||||
};
|
||||
@@ -344,6 +342,7 @@ export const ddnsAPI = {
|
||||
updateConfig: (data) => api.put('/api/ddns', data),
|
||||
register: () => api.post('/api/ddns/register'),
|
||||
getStatus: () => api.get('/api/ddns/status'),
|
||||
syncRecords: () => api.post('/api/ddns/sync'),
|
||||
};
|
||||
|
||||
// Setup Wizard API
|
||||
@@ -353,12 +352,21 @@ export const setupAPI = {
|
||||
complete: (payload) => api.post('/api/setup/complete', payload),
|
||||
};
|
||||
|
||||
// Per-service Egress API
|
||||
export const egressAPI = {
|
||||
getStatus: () => api.get('/api/egress/status'),
|
||||
setServiceExit: (serviceId, exitType) =>
|
||||
api.put(`/api/egress/services/${serviceId}/exit`, { exit_type: exitType }),
|
||||
};
|
||||
|
||||
// Connectivity / Exit Routing API
|
||||
export const connectivityAPI = {
|
||||
getStatus: () => api.get('/api/connectivity/status'),
|
||||
listExits: () => api.get('/api/connectivity/exits'),
|
||||
uploadWireguard: (conf_text) => api.post('/api/connectivity/exits/wireguard', { conf_text }),
|
||||
uploadOpenvpn: (ovpn_text, name = 'default') => api.post('/api/connectivity/exits/openvpn', { ovpn_text, name }),
|
||||
configureSshuttle: (cfg) => api.post('/api/connectivity/exits/sshuttle', cfg),
|
||||
configureProxy: (cfg) => api.post('/api/connectivity/exits/proxy', cfg),
|
||||
applyRoutes: () => api.post('/api/connectivity/exits/apply'),
|
||||
getPeerExits: () => api.get('/api/connectivity/peers'),
|
||||
setPeerExit: (peer_name, exit_via) => api.put(`/api/connectivity/peers/${peer_name}/exit`, { exit_via }),
|
||||
|
||||
Reference in New Issue
Block a user