754 lines
23 KiB
Bash
Executable File
754 lines
23 KiB
Bash
Executable File
#!/bin/sh
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
# System Hub - Central Control & Remote Assistance RPCD Backend
|
|
# Copyright (C) 2024 CyberMind.fr - Gandalf
|
|
|
|
. /lib/functions.sh
|
|
. /usr/share/libubox/jshn.sh
|
|
|
|
CONFIG_FILE="/etc/config/system-hub"
|
|
LOG_FILE="/var/log/system-hub.log"
|
|
REPORTS_DIR="/etc/system-hub/reports"
|
|
DIAG_DIR="/etc/system-hub/diagnostics"
|
|
|
|
# Logging function
|
|
log_event() {
|
|
local level="$1"
|
|
local message="$2"
|
|
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
|
echo "[$timestamp] [$level] $message" >> "$LOG_FILE"
|
|
}
|
|
|
|
# Get system overview status
|
|
get_status() {
|
|
json_init
|
|
|
|
local enabled=$(uci -q get system-hub.config.enabled || echo "1")
|
|
json_add_boolean "enabled" "$enabled"
|
|
|
|
# System info
|
|
json_add_object "system"
|
|
json_add_string "hostname" "$(uci -q get system.@system[0].hostname || hostname)"
|
|
json_add_string "model" "$(cat /tmp/sysinfo/model 2>/dev/null || echo 'Unknown')"
|
|
json_add_string "architecture" "$(uname -m)"
|
|
json_add_string "kernel" "$(uname -r)"
|
|
json_add_string "openwrt_version" "$(cat /etc/openwrt_release 2>/dev/null | grep DISTRIB_RELEASE | cut -d= -f2 | tr -d \"\')"
|
|
json_add_int "uptime" "$(cat /proc/uptime | cut -d. -f1)"
|
|
json_add_string "local_time" "$(date '+%Y-%m-%d %H:%M:%S')"
|
|
json_close_object
|
|
|
|
# CPU info
|
|
json_add_object "cpu"
|
|
local load1=$(cat /proc/loadavg | awk '{print $1}')
|
|
local load5=$(cat /proc/loadavg | awk '{print $2}')
|
|
local load15=$(cat /proc/loadavg | awk '{print $3}')
|
|
local cores=$(grep -c processor /proc/cpuinfo)
|
|
local usage=$(top -bn1 | grep "CPU:" | awk '{print 100-$8}' | head -1)
|
|
[ -z "$usage" ] && usage=$(awk '/^cpu / {print 100-($5*100/($2+$3+$4+$5+$6+$7+$8))}' /proc/stat)
|
|
json_add_string "load_1m" "$load1"
|
|
json_add_string "load_5m" "$load5"
|
|
json_add_string "load_15m" "$load15"
|
|
json_add_int "cores" "$cores"
|
|
json_add_int "usage_percent" "${usage%.*}"
|
|
json_close_object
|
|
|
|
# Memory info
|
|
json_add_object "memory"
|
|
local mem_total=$(grep MemTotal /proc/meminfo | awk '{print $2}')
|
|
local mem_free=$(grep MemFree /proc/meminfo | awk '{print $2}')
|
|
local mem_available=$(grep MemAvailable /proc/meminfo | awk '{print $2}')
|
|
local mem_buffers=$(grep Buffers /proc/meminfo | awk '{print $2}')
|
|
local mem_cached=$(grep "^Cached:" /proc/meminfo | awk '{print $2}')
|
|
local mem_used=$((mem_total - mem_free - mem_buffers - mem_cached))
|
|
local mem_percent=$((mem_used * 100 / mem_total))
|
|
json_add_int "total_kb" "$mem_total"
|
|
json_add_int "used_kb" "$mem_used"
|
|
json_add_int "free_kb" "$mem_free"
|
|
json_add_int "available_kb" "$mem_available"
|
|
json_add_int "usage_percent" "$mem_percent"
|
|
json_close_object
|
|
|
|
# Storage info
|
|
json_add_object "storage"
|
|
local disk_info=$(df / | tail -1)
|
|
local disk_total=$(echo "$disk_info" | awk '{print $2}')
|
|
local disk_used=$(echo "$disk_info" | awk '{print $3}')
|
|
local disk_free=$(echo "$disk_info" | awk '{print $4}')
|
|
local disk_percent=$(echo "$disk_info" | awk '{print $5}' | tr -d '%')
|
|
json_add_int "total_kb" "$disk_total"
|
|
json_add_int "used_kb" "$disk_used"
|
|
json_add_int "free_kb" "$disk_free"
|
|
json_add_int "usage_percent" "$disk_percent"
|
|
json_close_object
|
|
|
|
# Temperature (if available)
|
|
local temp=""
|
|
if [ -f /sys/class/thermal/thermal_zone0/temp ]; then
|
|
temp=$(($(cat /sys/class/thermal/thermal_zone0/temp) / 1000))
|
|
fi
|
|
json_add_int "temperature" "${temp:-0}"
|
|
|
|
# Network summary
|
|
json_add_object "network"
|
|
local wan_status=$(ubus call network.interface.wan status 2>/dev/null | jsonfilter -e '@.up' 2>/dev/null)
|
|
local wan_ip=$(ubus call network.interface.wan status 2>/dev/null | jsonfilter -e '@["ipv4-address"][0].address' 2>/dev/null)
|
|
local lan_ip=$(ubus call network.interface.lan status 2>/dev/null | jsonfilter -e '@["ipv4-address"][0].address' 2>/dev/null)
|
|
json_add_boolean "wan_up" "${wan_status:-0}"
|
|
json_add_string "wan_ip" "${wan_ip:-N/A}"
|
|
json_add_string "lan_ip" "${lan_ip:-N/A}"
|
|
local clients=$(cat /proc/net/arp | grep -v "IP address" | wc -l)
|
|
json_add_int "connected_clients" "$clients"
|
|
json_close_object
|
|
|
|
# Component summary
|
|
local installed=0
|
|
local running=0
|
|
local issues=0
|
|
config_load system-hub
|
|
config_foreach count_components component
|
|
|
|
json_add_object "components"
|
|
json_add_int "installed" "$installed"
|
|
json_add_int "running" "$running"
|
|
json_add_int "issues" "$issues"
|
|
json_close_object
|
|
|
|
# Remote status
|
|
json_add_object "remote"
|
|
local remote_enabled=$(uci -q get system-hub.remote.enabled || echo "0")
|
|
local rustdesk_enabled=$(uci -q get system-hub.remote.rustdesk_enabled || echo "0")
|
|
local rustdesk_id=$(uci -q get system-hub.remote.rustdesk_id || echo "")
|
|
json_add_boolean "enabled" "$remote_enabled"
|
|
json_add_boolean "rustdesk_enabled" "$rustdesk_enabled"
|
|
json_add_string "rustdesk_id" "$rustdesk_id"
|
|
json_add_boolean "session_active" "0"
|
|
json_close_object
|
|
|
|
# Last health check
|
|
json_add_string "last_health_check" "$(stat -c %Y $REPORTS_DIR/health_latest.json 2>/dev/null | xargs -I{} date -d @{} '+%Y-%m-%d %H:%M:%S' 2>/dev/null || echo 'Never')"
|
|
|
|
json_dump
|
|
}
|
|
|
|
count_components() {
|
|
local status=$(uci -q get system-hub.$1.status)
|
|
local service=$(uci -q get system-hub.$1.service)
|
|
|
|
[ "$status" = "installed" ] && installed=$((installed + 1))
|
|
|
|
if [ -n "$service" ] && /etc/init.d/$service enabled 2>/dev/null; then
|
|
if /etc/init.d/$service running 2>/dev/null; then
|
|
running=$((running + 1))
|
|
else
|
|
issues=$((issues + 1))
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Get all components with status
|
|
get_components() {
|
|
json_init
|
|
json_add_array "components"
|
|
|
|
config_load system-hub
|
|
config_foreach output_component component
|
|
|
|
json_close_array
|
|
json_dump
|
|
}
|
|
|
|
output_component() {
|
|
local section="$1"
|
|
local service=$(uci -q get system-hub.$section.service)
|
|
local status=$(uci -q get system-hub.$section.status)
|
|
|
|
# Check if service is running
|
|
local is_running=0
|
|
local is_enabled=0
|
|
if [ -n "$service" ] && [ "$status" = "installed" ]; then
|
|
/etc/init.d/$service enabled 2>/dev/null && is_enabled=1
|
|
/etc/init.d/$service running 2>/dev/null && is_running=1
|
|
fi
|
|
|
|
json_add_object
|
|
json_add_string "id" "$section"
|
|
json_add_string "name" "$(uci -q get system-hub.$section.name)"
|
|
json_add_string "description" "$(uci -q get system-hub.$section.description)"
|
|
json_add_string "package" "$(uci -q get system-hub.$section.package)"
|
|
json_add_string "service" "$service"
|
|
json_add_string "icon" "$(uci -q get system-hub.$section.icon)"
|
|
json_add_string "color" "$(uci -q get system-hub.$section.color)"
|
|
json_add_string "category" "$(uci -q get system-hub.$section.category)"
|
|
json_add_string "status" "$status"
|
|
json_add_string "version" "$(uci -q get system-hub.$section.version)"
|
|
json_add_boolean "enabled" "$is_enabled"
|
|
json_add_boolean "running" "$is_running"
|
|
json_add_string "web_port" "$(uci -q get system-hub.$section.web_port)"
|
|
json_add_string "roadmap_date" "$(uci -q get system-hub.$section.roadmap_date)"
|
|
json_close_object
|
|
}
|
|
|
|
# Get health report
|
|
get_health() {
|
|
json_init
|
|
|
|
# Overall score
|
|
local score=100
|
|
local issues=""
|
|
|
|
# CPU health
|
|
local cpu_usage=$(awk '/^cpu / {print int(100-($5*100/($2+$3+$4+$5+$6+$7+$8)))}' /proc/stat)
|
|
local cpu_warning=$(uci -q get system-hub.health.cpu_warning || echo 80)
|
|
local cpu_critical=$(uci -q get system-hub.health.cpu_critical || echo 95)
|
|
local cpu_status="ok"
|
|
if [ "$cpu_usage" -ge "$cpu_critical" ]; then
|
|
cpu_status="critical"
|
|
score=$((score - 30))
|
|
issues="$issues CPU critical ($cpu_usage%);"
|
|
elif [ "$cpu_usage" -ge "$cpu_warning" ]; then
|
|
cpu_status="warning"
|
|
score=$((score - 15))
|
|
issues="$issues CPU warning ($cpu_usage%);"
|
|
fi
|
|
|
|
# Memory health
|
|
local mem_total=$(grep MemTotal /proc/meminfo | awk '{print $2}')
|
|
local mem_free=$(grep MemFree /proc/meminfo | awk '{print $2}')
|
|
local mem_buffers=$(grep Buffers /proc/meminfo | awk '{print $2}')
|
|
local mem_cached=$(grep "^Cached:" /proc/meminfo | awk '{print $2}')
|
|
local mem_used=$((mem_total - mem_free - mem_buffers - mem_cached))
|
|
local mem_percent=$((mem_used * 100 / mem_total))
|
|
local mem_warning=$(uci -q get system-hub.health.memory_warning || echo 80)
|
|
local mem_critical=$(uci -q get system-hub.health.memory_critical || echo 95)
|
|
local mem_status="ok"
|
|
if [ "$mem_percent" -ge "$mem_critical" ]; then
|
|
mem_status="critical"
|
|
score=$((score - 25))
|
|
issues="$issues Memory critical ($mem_percent%);"
|
|
elif [ "$mem_percent" -ge "$mem_warning" ]; then
|
|
mem_status="warning"
|
|
score=$((score - 10))
|
|
issues="$issues Memory warning ($mem_percent%);"
|
|
fi
|
|
|
|
# Disk health
|
|
local disk_percent=$(df / | tail -1 | awk '{print $5}' | tr -d '%')
|
|
local disk_warning=$(uci -q get system-hub.health.disk_warning || echo 80)
|
|
local disk_critical=$(uci -q get system-hub.health.disk_critical || echo 95)
|
|
local disk_status="ok"
|
|
if [ "$disk_percent" -ge "$disk_critical" ]; then
|
|
disk_status="critical"
|
|
score=$((score - 25))
|
|
issues="$issues Disk critical ($disk_percent%);"
|
|
elif [ "$disk_percent" -ge "$disk_warning" ]; then
|
|
disk_status="warning"
|
|
score=$((score - 10))
|
|
issues="$issues Disk warning ($disk_percent%);"
|
|
fi
|
|
|
|
# Temperature health
|
|
local temp=0
|
|
local temp_status="ok"
|
|
if [ -f /sys/class/thermal/thermal_zone0/temp ]; then
|
|
temp=$(($(cat /sys/class/thermal/thermal_zone0/temp) / 1000))
|
|
local temp_warning=$(uci -q get system-hub.health.temperature_warning || echo 70)
|
|
local temp_critical=$(uci -q get system-hub.health.temperature_critical || echo 85)
|
|
if [ "$temp" -ge "$temp_critical" ]; then
|
|
temp_status="critical"
|
|
score=$((score - 20))
|
|
issues="$issues Temperature critical (${temp}°C);"
|
|
elif [ "$temp" -ge "$temp_warning" ]; then
|
|
temp_status="warning"
|
|
score=$((score - 10))
|
|
issues="$issues Temperature warning (${temp}°C);"
|
|
fi
|
|
fi
|
|
|
|
# Services health
|
|
local services_ok=0
|
|
local services_failed=0
|
|
for svc in network dnsmasq firewall uhttpd; do
|
|
if /etc/init.d/$svc enabled 2>/dev/null; then
|
|
if /etc/init.d/$svc running 2>/dev/null; then
|
|
services_ok=$((services_ok + 1))
|
|
else
|
|
services_failed=$((services_failed + 1))
|
|
score=$((score - 5))
|
|
issues="$issues Service $svc not running;"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# Network health
|
|
local wan_up=0
|
|
local wan_status=$(ubus call network.interface.wan status 2>/dev/null | jsonfilter -e '@.up' 2>/dev/null)
|
|
[ "$wan_status" = "true" ] && wan_up=1
|
|
local net_status="ok"
|
|
if [ "$wan_up" = "0" ]; then
|
|
net_status="critical"
|
|
score=$((score - 20))
|
|
issues="$issues WAN down;"
|
|
fi
|
|
|
|
# Ensure score is not negative
|
|
[ "$score" -lt 0 ] && score=0
|
|
|
|
# Determine overall status
|
|
local overall="healthy"
|
|
[ "$score" -lt 80 ] && overall="warning"
|
|
[ "$score" -lt 50 ] && overall="critical"
|
|
|
|
json_add_int "score" "$score"
|
|
json_add_string "status" "$overall"
|
|
json_add_string "issues" "$issues"
|
|
json_add_string "timestamp" "$(date '+%Y-%m-%d %H:%M:%S')"
|
|
|
|
json_add_object "cpu"
|
|
json_add_int "usage" "$cpu_usage"
|
|
json_add_string "status" "$cpu_status"
|
|
json_close_object
|
|
|
|
json_add_object "memory"
|
|
json_add_int "usage" "$mem_percent"
|
|
json_add_string "status" "$mem_status"
|
|
json_close_object
|
|
|
|
json_add_object "disk"
|
|
json_add_int "usage" "$disk_percent"
|
|
json_add_string "status" "$disk_status"
|
|
json_close_object
|
|
|
|
json_add_object "temperature"
|
|
json_add_int "value" "$temp"
|
|
json_add_string "status" "$temp_status"
|
|
json_close_object
|
|
|
|
json_add_object "services"
|
|
json_add_int "running" "$services_ok"
|
|
json_add_int "failed" "$services_failed"
|
|
json_close_object
|
|
|
|
json_add_object "network"
|
|
json_add_boolean "wan_up" "$wan_up"
|
|
json_add_string "status" "$net_status"
|
|
json_close_object
|
|
|
|
# Recommendations
|
|
json_add_array "recommendations"
|
|
[ "$cpu_status" != "ok" ] && json_add_string "" "Réduire la charge CPU en désactivant des services non essentiels"
|
|
[ "$mem_status" != "ok" ] && json_add_string "" "Libérer de la mémoire ou augmenter le swap"
|
|
[ "$disk_status" != "ok" ] && json_add_string "" "Nettoyer les fichiers temporaires et logs anciens"
|
|
[ "$temp_status" != "ok" ] && json_add_string "" "Améliorer la ventilation ou réduire la charge"
|
|
[ "$net_status" != "ok" ] && json_add_string "" "Vérifier la connexion WAN et les paramètres réseau"
|
|
json_close_array
|
|
|
|
json_dump
|
|
}
|
|
|
|
# Get remote assistance config
|
|
get_remote() {
|
|
json_init
|
|
|
|
json_add_boolean "enabled" "$(uci -q get system-hub.remote.enabled || echo 0)"
|
|
json_add_boolean "rustdesk_enabled" "$(uci -q get system-hub.remote.rustdesk_enabled || echo 0)"
|
|
json_add_string "rustdesk_server" "$(uci -q get system-hub.remote.rustdesk_server)"
|
|
json_add_string "rustdesk_id" "$(uci -q get system-hub.remote.rustdesk_id)"
|
|
json_add_boolean "allow_unattended" "$(uci -q get system-hub.remote.allow_unattended || echo 0)"
|
|
json_add_boolean "require_approval" "$(uci -q get system-hub.remote.require_approval || echo 1)"
|
|
json_add_boolean "notify_on_connect" "$(uci -q get system-hub.remote.notify_on_connect || echo 1)"
|
|
json_add_int "session_timeout" "$(uci -q get system-hub.remote.session_timeout || echo 3600)"
|
|
|
|
# Check if RustDesk is installed and running
|
|
local rustdesk_installed=0
|
|
local rustdesk_running=0
|
|
which rustdesk >/dev/null 2>&1 && rustdesk_installed=1
|
|
pgrep -x rustdesk >/dev/null 2>&1 && rustdesk_running=1
|
|
json_add_boolean "rustdesk_installed" "$rustdesk_installed"
|
|
json_add_boolean "rustdesk_running" "$rustdesk_running"
|
|
|
|
# Support info
|
|
json_add_object "support"
|
|
json_add_string "provider" "$(uci -q get system-hub.support.provider)"
|
|
json_add_string "email" "$(uci -q get system-hub.support.email)"
|
|
json_add_string "phone" "$(uci -q get system-hub.support.phone)"
|
|
json_add_string "website" "$(uci -q get system-hub.support.website)"
|
|
json_add_string "ticket_url" "$(uci -q get system-hub.support.ticket_url)"
|
|
json_close_object
|
|
|
|
json_dump
|
|
}
|
|
|
|
# Collect diagnostic data
|
|
collect_diagnostics() {
|
|
read input
|
|
json_load "$input"
|
|
json_get_var include_logs include_logs
|
|
json_get_var include_config include_config
|
|
json_get_var include_network include_network
|
|
json_get_var anonymize anonymize
|
|
|
|
json_init
|
|
|
|
local diag_file="$DIAG_DIR/diagnostic_$(date +%Y%m%d_%H%M%S).tar.gz"
|
|
local temp_dir="/tmp/system-hub-diag-$$"
|
|
mkdir -p "$temp_dir"
|
|
|
|
# System info
|
|
{
|
|
echo "=== System Info ==="
|
|
echo "Date: $(date)"
|
|
echo "Hostname: $(hostname)"
|
|
echo "Model: $(cat /tmp/sysinfo/model 2>/dev/null)"
|
|
echo "Kernel: $(uname -a)"
|
|
echo "OpenWrt: $(cat /etc/openwrt_release)"
|
|
echo ""
|
|
echo "=== Uptime ==="
|
|
uptime
|
|
echo ""
|
|
echo "=== Memory ==="
|
|
free
|
|
cat /proc/meminfo
|
|
echo ""
|
|
echo "=== Disk ==="
|
|
df -h
|
|
echo ""
|
|
echo "=== CPU ==="
|
|
cat /proc/cpuinfo
|
|
echo ""
|
|
echo "=== Processes ==="
|
|
ps w
|
|
} > "$temp_dir/system_info.txt"
|
|
|
|
# Logs
|
|
if [ "$include_logs" = "1" ]; then
|
|
{
|
|
echo "=== System Log ==="
|
|
logread | tail -500
|
|
echo ""
|
|
echo "=== Kernel Log ==="
|
|
dmesg | tail -200
|
|
} > "$temp_dir/logs.txt"
|
|
|
|
# Component logs
|
|
[ -f /var/log/crowdsec.log ] && tail -200 /var/log/crowdsec.log > "$temp_dir/crowdsec.log"
|
|
[ -f /var/log/netifyd.log ] && tail -200 /var/log/netifyd.log > "$temp_dir/netifyd.log"
|
|
[ -f /var/log/system-hub.log ] && tail -200 /var/log/system-hub.log > "$temp_dir/system-hub.log"
|
|
fi
|
|
|
|
# Network info
|
|
if [ "$include_network" = "1" ]; then
|
|
{
|
|
echo "=== Interfaces ==="
|
|
ip addr
|
|
echo ""
|
|
echo "=== Routes ==="
|
|
ip route
|
|
echo ""
|
|
echo "=== ARP ==="
|
|
cat /proc/net/arp
|
|
echo ""
|
|
echo "=== Connections ==="
|
|
netstat -tuln 2>/dev/null || ss -tuln
|
|
echo ""
|
|
echo "=== Firewall ==="
|
|
iptables -L -n -v 2>/dev/null
|
|
echo ""
|
|
echo "=== WiFi ==="
|
|
iwinfo 2>/dev/null || iw dev 2>/dev/null
|
|
} > "$temp_dir/network.txt"
|
|
fi
|
|
|
|
# Config (anonymized if requested)
|
|
if [ "$include_config" = "1" ]; then
|
|
mkdir -p "$temp_dir/config"
|
|
for conf in network wireless firewall dhcp system; do
|
|
if [ -f "/etc/config/$conf" ]; then
|
|
if [ "$anonymize" = "1" ]; then
|
|
# Remove passwords and sensitive data
|
|
sed -e 's/option key .*/option key *****/g' \
|
|
-e 's/option password .*/option password *****/g' \
|
|
-e 's/option private_key .*/option private_key *****/g' \
|
|
-e 's/option preshared_key .*/option preshared_key *****/g' \
|
|
"/etc/config/$conf" > "$temp_dir/config/$conf"
|
|
else
|
|
cp "/etc/config/$conf" "$temp_dir/config/"
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Packages list
|
|
opkg list-installed > "$temp_dir/packages.txt"
|
|
|
|
# Create archive
|
|
tar -czf "$diag_file" -C "$temp_dir" .
|
|
rm -rf "$temp_dir"
|
|
|
|
local file_size=$(stat -c%s "$diag_file")
|
|
|
|
json_add_boolean "success" 1
|
|
json_add_string "file" "$diag_file"
|
|
json_add_int "size" "$file_size"
|
|
json_add_string "timestamp" "$(date '+%Y-%m-%d %H:%M:%S')"
|
|
|
|
log_event "info" "Diagnostic collected: $diag_file"
|
|
|
|
json_dump
|
|
}
|
|
|
|
# Generate health report
|
|
generate_report() {
|
|
json_init
|
|
|
|
local report_file="$REPORTS_DIR/health_$(date +%Y%m%d_%H%M%S).json"
|
|
|
|
# Get health data and save
|
|
get_health > "$report_file"
|
|
|
|
# Also save as latest
|
|
cp "$report_file" "$REPORTS_DIR/health_latest.json"
|
|
|
|
json_add_boolean "success" 1
|
|
json_add_string "file" "$report_file"
|
|
json_add_string "timestamp" "$(date '+%Y-%m-%d %H:%M:%S')"
|
|
|
|
log_event "info" "Health report generated: $report_file"
|
|
|
|
json_dump
|
|
}
|
|
|
|
# Get unified logs from all components
|
|
get_logs() {
|
|
read input
|
|
json_load "$input"
|
|
json_get_var limit limit
|
|
json_get_var source source
|
|
json_get_var level level
|
|
|
|
[ -z "$limit" ] && limit=100
|
|
|
|
json_init
|
|
json_add_array "logs"
|
|
|
|
# System log
|
|
if [ -z "$source" ] || [ "$source" = "system" ]; then
|
|
logread | tail -n $limit | while read line; do
|
|
local ts=$(echo "$line" | awk '{print $1" "$2" "$3}')
|
|
local msg=$(echo "$line" | cut -d' ' -f4-)
|
|
local lvl="info"
|
|
echo "$line" | grep -qi "error\|fail\|critical" && lvl="error"
|
|
echo "$line" | grep -qi "warn" && lvl="warning"
|
|
|
|
json_add_object
|
|
json_add_string "timestamp" "$ts"
|
|
json_add_string "source" "system"
|
|
json_add_string "level" "$lvl"
|
|
json_add_string "message" "$msg"
|
|
json_close_object
|
|
done
|
|
fi
|
|
|
|
# Component logs
|
|
for logfile in /var/log/system-hub.log /var/log/crowdsec.log /var/log/client-guardian.log; do
|
|
if [ -f "$logfile" ]; then
|
|
local src=$(basename "$logfile" .log)
|
|
[ -z "$source" ] || [ "$source" = "$src" ] && tail -n $((limit / 3)) "$logfile" | while read line; do
|
|
json_add_object
|
|
json_add_string "timestamp" "$(echo "$line" | sed -n 's/\[\([^]]*\)\].*/\1/p')"
|
|
json_add_string "source" "$src"
|
|
json_add_string "level" "$(echo "$line" | sed -n 's/.*\] \[\([^]]*\)\].*/\1/p')"
|
|
json_add_string "message" "$(echo "$line" | sed 's/.*\] \[.*\] //')"
|
|
json_close_object
|
|
done
|
|
fi
|
|
done
|
|
|
|
json_close_array
|
|
json_dump
|
|
}
|
|
|
|
# Start remote session
|
|
start_remote_session() {
|
|
read input
|
|
json_load "$input"
|
|
json_get_var type type
|
|
|
|
json_init
|
|
|
|
case "$type" in
|
|
rustdesk)
|
|
if which rustdesk >/dev/null 2>&1; then
|
|
rustdesk --service &
|
|
sleep 2
|
|
local id=$(rustdesk --get-id 2>/dev/null)
|
|
json_add_boolean "success" 1
|
|
json_add_string "type" "rustdesk"
|
|
json_add_string "id" "$id"
|
|
json_add_string "message" "RustDesk session started"
|
|
log_event "info" "Remote session started: RustDesk ID $id"
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "RustDesk not installed"
|
|
fi
|
|
;;
|
|
ssh)
|
|
json_add_boolean "success" 1
|
|
json_add_string "type" "ssh"
|
|
json_add_string "host" "$(ubus call network.interface.wan status 2>/dev/null | jsonfilter -e '@["ipv4-address"][0].address')"
|
|
json_add_int "port" "22"
|
|
;;
|
|
*)
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "Unknown session type"
|
|
;;
|
|
esac
|
|
|
|
json_dump
|
|
}
|
|
|
|
# Update component
|
|
manage_component() {
|
|
read input
|
|
json_load "$input"
|
|
json_get_var component component
|
|
json_get_var action action
|
|
|
|
json_init
|
|
|
|
local service=$(uci -q get system-hub.$component.service)
|
|
|
|
if [ -z "$service" ]; then
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "Component not found"
|
|
json_dump
|
|
return
|
|
fi
|
|
|
|
case "$action" in
|
|
start)
|
|
/etc/init.d/$service start 2>&1
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "Service $service started"
|
|
log_event "info" "Component $component started"
|
|
;;
|
|
stop)
|
|
/etc/init.d/$service stop 2>&1
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "Service $service stopped"
|
|
log_event "info" "Component $component stopped"
|
|
;;
|
|
restart)
|
|
/etc/init.d/$service restart 2>&1
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "Service $service restarted"
|
|
log_event "info" "Component $component restarted"
|
|
;;
|
|
enable)
|
|
/etc/init.d/$service enable 2>&1
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "Service $service enabled"
|
|
;;
|
|
disable)
|
|
/etc/init.d/$service disable 2>&1
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "Service $service disabled"
|
|
;;
|
|
*)
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "Unknown action"
|
|
;;
|
|
esac
|
|
|
|
json_dump
|
|
}
|
|
|
|
# Upload diagnostic file
|
|
upload_diagnostic() {
|
|
read input
|
|
json_load "$input"
|
|
json_get_var file file
|
|
|
|
json_init
|
|
|
|
local upload_url=$(uci -q get system-hub.diagnostics.upload_url)
|
|
local upload_token=$(uci -q get system-hub.diagnostics.upload_token)
|
|
|
|
if [ -z "$upload_url" ]; then
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "Upload URL not configured"
|
|
json_dump
|
|
return
|
|
fi
|
|
|
|
if [ ! -f "$file" ]; then
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "File not found"
|
|
json_dump
|
|
return
|
|
fi
|
|
|
|
# Upload via curl
|
|
local response=$(curl -s -X POST \
|
|
-H "Authorization: Bearer $upload_token" \
|
|
-F "file=@$file" \
|
|
-F "hostname=$(hostname)" \
|
|
"$upload_url" 2>&1)
|
|
|
|
if [ $? -eq 0 ]; then
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "File uploaded successfully"
|
|
json_add_string "response" "$response"
|
|
log_event "info" "Diagnostic uploaded: $file"
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "Upload failed: $response"
|
|
fi
|
|
|
|
json_dump
|
|
}
|
|
|
|
# Get schedules
|
|
get_schedules() {
|
|
json_init
|
|
json_add_array "schedules"
|
|
|
|
config_load system-hub
|
|
config_foreach output_schedule schedule
|
|
|
|
json_close_array
|
|
json_dump
|
|
}
|
|
|
|
output_schedule() {
|
|
json_add_object
|
|
json_add_string "id" "$1"
|
|
json_add_string "name" "$(uci -q get system-hub.$1.name)"
|
|
json_add_boolean "enabled" "$(uci -q get system-hub.$1.enabled || echo 0)"
|
|
json_add_string "type" "$(uci -q get system-hub.$1.type)"
|
|
json_add_string "cron" "$(uci -q get system-hub.$1.cron)"
|
|
json_close_object
|
|
}
|
|
|
|
# Main dispatcher
|
|
case "$1" in
|
|
list)
|
|
echo '{"status":{},"components":{},"health":{},"remote":{},"logs":{"limit":"int","source":"str","level":"str"},"schedules":{},"collect_diagnostics":{"include_logs":"bool","include_config":"bool","include_network":"bool","anonymize":"bool"},"generate_report":{},"start_remote_session":{"type":"str"},"manage_component":{"component":"str","action":"str"},"upload_diagnostic":{"file":"str"}}'
|
|
;;
|
|
call)
|
|
case "$2" in
|
|
status) get_status ;;
|
|
components) get_components ;;
|
|
health) get_health ;;
|
|
remote) get_remote ;;
|
|
logs) get_logs ;;
|
|
schedules) get_schedules ;;
|
|
collect_diagnostics) collect_diagnostics ;;
|
|
generate_report) generate_report ;;
|
|
start_remote_session) start_remote_session ;;
|
|
manage_component) manage_component ;;
|
|
upload_diagnostic) upload_diagnostic ;;
|
|
*) echo '{"error": "Unknown method"}' ;;
|
|
esac
|
|
;;
|
|
esac
|