secubox-openwrt/package/secubox/secubox-p2p/root/www/api/factory/mesh-services
CyberMind-FR cf115b346a feat(p2p): Add distributed mesh services panel
- Add mesh-services CGI endpoint for aggregated service discovery
  across all mesh peers
- Update Factory UI with tabbed interface: Dashboard and Mesh Services
- Mesh Services panel features:
  - Real-time service discovery from all nodes
  - Filter by search, status, or node
  - Direct access links for services with ports
  - Status indicators (running/stopped/disabled)
  - Summary stats (nodes online, running/total services)
- Bump version to 0.5.0

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 08:56:22 +01:00

135 lines
4.6 KiB
Bash

#!/bin/sh
# Factory Mesh Services - Aggregated service discovery across mesh
# CGI endpoint for distributed service panel
echo "Content-Type: application/json"
echo "Access-Control-Allow-Origin: *"
echo "Access-Control-Allow-Methods: GET, OPTIONS"
echo ""
# Handle CORS preflight
if [ "$REQUEST_METHOD" = "OPTIONS" ]; then
exit 0
fi
# Get local node ID
P2P_STATE_DIR="/var/run/secubox-p2p"
LOCAL_NODE_ID=$(cat "$P2P_STATE_DIR/node.id" 2>/dev/null || hostname)
LOCAL_NODE_NAME=$(uci -q get system.@system[0].hostname || hostname)
# Get local services
get_local_services() {
local services_json=$(/usr/sbin/secubox-p2p services 2>/dev/null)
if [ -z "$services_json" ]; then
echo '{"services":[]}'
return
fi
echo "$services_json"
}
# Get services from a peer
get_peer_services() {
local peer_addr="$1"
local peer_name="$2"
# Query peer's services endpoint with timeout
local peer_services=$(curl -s --connect-timeout 3 --max-time 5 "http://$peer_addr:7331/api/services" 2>/dev/null)
if [ -n "$peer_services" ] && echo "$peer_services" | grep -q "services"; then
echo "$peer_services"
else
echo '{"services":[],"error":"unreachable"}'
fi
}
# Build aggregated mesh services
build_mesh_services() {
local result='{"nodes":['
local first_node=1
# Add local node
local local_services=$(get_local_services)
local local_svc_list=$(echo "$local_services" | jsonfilter -e '@.services[*]' 2>/dev/null)
local local_svc_count=$(echo "$local_services" | jsonfilter -e '@.services[*]' 2>/dev/null | wc -l)
result="$result{\"node_id\":\"$LOCAL_NODE_ID\",\"node_name\":\"$LOCAL_NODE_NAME\",\"is_local\":true,\"status\":\"online\","
result="$result\"services\":["
local i=0
while [ $i -lt $local_svc_count ]; do
local svc_name=$(echo "$local_services" | jsonfilter -e "@.services[$i].name" 2>/dev/null)
local svc_status=$(echo "$local_services" | jsonfilter -e "@.services[$i].status" 2>/dev/null)
local svc_enabled=$(echo "$local_services" | jsonfilter -e "@.services[$i].enabled" 2>/dev/null)
local svc_port=$(echo "$local_services" | jsonfilter -e "@.services[$i].port" 2>/dev/null)
[ $i -gt 0 ] && result="$result,"
result="$result{\"name\":\"$svc_name\",\"status\":\"$svc_status\",\"enabled\":$svc_enabled,\"port\":\"$svc_port\"}"
i=$((i + 1))
done
result="$result]}"
first_node=0
# Get peer services
local peers_file="/tmp/secubox-p2p-peers.json"
if [ -f "$peers_file" ]; then
local peer_count=$(jsonfilter -i "$peers_file" -e '@.peers[*]' 2>/dev/null | wc -l)
local p=0
while [ $p -lt $peer_count ]; do
local peer_addr=$(jsonfilter -i "$peers_file" -e "@.peers[$p].address" 2>/dev/null)
local peer_name=$(jsonfilter -i "$peers_file" -e "@.peers[$p].name" 2>/dev/null)
local peer_id=$(jsonfilter -i "$peers_file" -e "@.peers[$p].id" 2>/dev/null)
local is_local=$(jsonfilter -i "$peers_file" -e "@.peers[$p].is_local" 2>/dev/null)
# Skip local node in peers list
if [ "$is_local" != "true" ] && [ -n "$peer_addr" ]; then
local peer_services=$(get_peer_services "$peer_addr" "$peer_name")
local peer_status="offline"
local peer_error=""
if echo "$peer_services" | grep -q '"error"'; then
peer_error=$(echo "$peer_services" | jsonfilter -e '@.error' 2>/dev/null)
else
peer_status="online"
fi
result="$result,{\"node_id\":\"${peer_id:-$peer_addr}\",\"node_name\":\"${peer_name:-$peer_addr}\",\"address\":\"$peer_addr\",\"is_local\":false,\"status\":\"$peer_status\","
if [ "$peer_status" = "online" ]; then
# Parse peer services
local peer_svc_count=$(echo "$peer_services" | jsonfilter -e '@.services[*]' 2>/dev/null | wc -l)
result="$result\"services\":["
local j=0
while [ $j -lt $peer_svc_count ]; do
local svc_name=$(echo "$peer_services" | jsonfilter -e "@.services[$j].name" 2>/dev/null)
local svc_status=$(echo "$peer_services" | jsonfilter -e "@.services[$j].status" 2>/dev/null)
local svc_enabled=$(echo "$peer_services" | jsonfilter -e "@.services[$j].enabled" 2>/dev/null)
local svc_port=$(echo "$peer_services" | jsonfilter -e "@.services[$j].port" 2>/dev/null)
[ $j -gt 0 ] && result="$result,"
result="$result{\"name\":\"$svc_name\",\"status\":\"$svc_status\",\"enabled\":${svc_enabled:-0},\"port\":\"$svc_port\"}"
j=$((j + 1))
done
result="$result]}"
else
result="$result\"services\":[],\"error\":\"$peer_error\"}"
fi
fi
p=$((p + 1))
done
fi
result="$result],"
# Add summary stats
result="$result\"summary\":{\"total_nodes\":0,\"online_nodes\":0,\"total_services\":0,\"running_services\":0}}"
echo "$result"
}
# Output aggregated mesh services
build_mesh_services