feat(dashboard): Add system overview infographic to LuCI admin

- Add get_system_overview RPCD method
- Add renderSystemOverview to admin dashboard.js
- Display system health, resources, services, network, security stats
- Styled with cyberpunk theme

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
CyberMind-FR 2026-02-10 10:21:15 +01:00
parent 0f5fc39778
commit b1c22b7f10
3 changed files with 89 additions and 1 deletions

View File

@ -51,6 +51,13 @@ var callGetHealth = rpc.declare({
expect: { }
});
// System Overview (infographic dashboard)
var callGetSystemOverview = rpc.declare({
object: 'luci.secubox',
method: 'get_system_overview',
expect: { }
});
var callGetAlerts = rpc.declare({
object: 'luci.secubox',
method: 'get_alerts',
@ -458,6 +465,7 @@ return baseclass.extend({
getHealth: debugRPC('getHealth', callGetHealth, { retries: 1 }),
getAlerts: debugRPC('getAlerts', callGetAlerts, { retries: 1 }),
getLogs: debugRPC('getLogs', callGetLogs),
getSystemOverview: debugRPC('getSystemOverview', callGetSystemOverview, { retries: 1 }),
// Catalog Sources (critical - more retries)
getCatalogSources: debugRPC('getCatalogSources', callGetCatalogSources, { retries: 3, retryDelay: 2000 }),

View File

@ -51,7 +51,8 @@ return view.extend({
L.resolveDefault(API.getModules(), { modules: {} }),
L.resolveDefault(API.getHealth(), {}),
L.resolveDefault(API.getAlerts(), { alerts: [] }),
L.resolveDefault(API.checkUpdates(), { updates: [] })
L.resolveDefault(API.checkUpdates(), { updates: [] }),
L.resolveDefault(API.getSystemOverview(), {})
]);
},
@ -61,6 +62,7 @@ return view.extend({
var health = data[2];
var alerts = DataUtils.normalizeAlerts(data[3]);
var updateInfo = DataUtils.normalizeUpdates(data[4]);
var sysOverview = data[5] || {};
var stats = DataUtils.buildAppStats(apps, modules, alerts, updateInfo, API.getAppStatus);
var healthSnapshot = DataUtils.normalizeHealth(health);
@ -79,6 +81,9 @@ return view.extend({
E('div', { 'class': 'cyber-header-subtitle' }, 'System Overview · Applications · Health Monitoring')
]),
// System Overview Infographic
this.renderSystemOverview(sysOverview),
// Stats grid
E('div', { 'class': 'stats-grid' }, [
Components.renderStatCard('📦', stats.totalApps, 'Total Apps', 'blue'),
@ -118,6 +123,66 @@ return view.extend({
return wrapper;
},
renderSystemOverview: function(overview) {
if (!overview || !overview.system) return E('div');
var sys = overview.system || {};
var net = overview.network || {};
var svc = overview.services || {};
var sec = overview.security || {};
return E('div', { 'class': 'system-overview card', 'style': 'margin-bottom:20px;' }, [
E('h3', { 'style': 'margin:0 0 16px 0;color:#0ff;' }, '📊 SYSTEM OVERVIEW'),
E('div', { 'class': 'overview-grid', 'style': 'display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px;' }, [
// System section
E('div', { 'class': 'overview-section', 'style': 'background:rgba(0,255,255,0.05);padding:12px;border-radius:8px;border:1px solid rgba(0,255,255,0.2);' }, [
E('h4', { 'style': 'margin:0 0 8px 0;color:#0ff;font-size:12px;' }, '⚡ SYSTEM'),
E('div', { 'style': 'font-size:11px;line-height:1.8;' }, [
E('div', {}, 'Load: ' + (sys.load || 'N/A')),
E('div', {}, 'CPU: ' + (sys.cpu_used || 0) + '% used'),
E('div', {}, 'Uptime: ' + (sys.uptime || 'N/A'))
])
]),
// Resources section
E('div', { 'class': 'overview-section', 'style': 'background:rgba(0,255,255,0.05);padding:12px;border-radius:8px;border:1px solid rgba(0,255,255,0.2);' }, [
E('h4', { 'style': 'margin:0 0 8px 0;color:#0ff;font-size:12px;' }, '💾 RESOURCES'),
E('div', { 'style': 'font-size:11px;line-height:1.8;' }, [
E('div', {}, 'Memory: ' + (sys.mem_free || 0) + 'MB free'),
E('div', {}, 'Disk /: ' + (sys.disk_root || 'N/A')),
E('div', {}, 'Disk /srv: ' + (sys.disk_srv || 'N/A'))
])
]),
// Services section
E('div', { 'class': 'overview-section', 'style': 'background:rgba(0,255,255,0.05);padding:12px;border-radius:8px;border:1px solid rgba(0,255,255,0.2);' }, [
E('h4', { 'style': 'margin:0 0 8px 0;color:#0ff;font-size:12px;' }, '🔧 SERVICES'),
E('div', { 'style': 'font-size:11px;line-height:1.8;' }, [
E('div', {}, 'HAProxy: ' + (svc.haproxy_backends || 0) + ' backends'),
E('div', {}, 'VHosts: ' + (svc.haproxy_vhosts || 0)),
E('div', {}, 'Sites: ' + (svc.metablog_sites || 0) + ' / Apps: ' + (svc.streamlit_apps || 0))
])
]),
// Network section
E('div', { 'class': 'overview-section', 'style': 'background:rgba(0,255,255,0.05);padding:12px;border-radius:8px;border:1px solid rgba(0,255,255,0.2);' }, [
E('h4', { 'style': 'margin:0 0 8px 0;color:#0ff;font-size:12px;' }, '🌐 NETWORK'),
E('div', { 'style': 'font-size:11px;line-height:1.8;' }, [
E('div', {}, 'Connections: ' + (net.connections || 0)),
E('div', {}, 'Tor: ' + (net.tor || 0)),
E('div', {}, 'HTTPS: ' + (net.https || 0))
])
]),
// Security section
E('div', { 'class': 'overview-section', 'style': 'background:rgba(255,0,100,0.1);padding:12px;border-radius:8px;border:1px solid rgba(255,0,100,0.3);' }, [
E('h4', { 'style': 'margin:0 0 8px 0;color:#ff0064;font-size:12px;' }, '🛡️ SECURITY'),
E('div', { 'style': 'font-size:11px;line-height:1.8;' }, [
E('div', {}, 'Active Bans: ' + (sec.active_bans || 0)),
E('div', {}, 'SSRF: ' + (sec.attacks_ssrf || 0) + ' | Bots: ' + (sec.attacks_botscan || 0)),
E('div', {}, 'Countries: ' + (sec.top_countries || 'N/A'))
])
])
])
]);
},
renderHealthSummary: function(health) {
if (!health) return E('div');

View File

@ -7,6 +7,7 @@
# Register methods
list_methods_dashboard() {
add_method "get_dashboard_data"
add_method "get_system_overview"
add_method "get_public_ips"
add_method "refresh_public_ips"
add_method_str "quick_action" "action"
@ -23,6 +24,9 @@ handle_dashboard() {
get_dashboard_data)
_do_dashboard_data
;;
get_system_overview)
_do_system_overview
;;
get_public_ips)
_do_public_ips
;;
@ -46,6 +50,17 @@ handle_dashboard() {
esac
}
# System Overview - Full infographic data
_do_system_overview() {
if [ -x "/usr/sbin/secubox-dashboard" ]; then
/usr/sbin/secubox-dashboard json
else
json_init
json_add_string "error" "secubox-dashboard not installed"
json_dump
fi
}
# Dashboard summary data (optimized - no slow appstore call)
_do_dashboard_data() {
json_init