- 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>
135 lines
4.6 KiB
Bash
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
|