Fix RUN NETWORK SCAN button: queue PVE1 probe, return real DB data, no fake scan from DO

This commit is contained in:
2026-05-30 03:53:13 +00:00
parent e189a64ddd
commit 785b0fa7ab
2 changed files with 41 additions and 50 deletions
+29 -31
View File
@@ -35,41 +35,39 @@ $action = $action ?? 'status';
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET'; $method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
if ($action === 'scan') { if ($action === 'scan') {
$liveHosts = scanSubnet(LOCAL_SUBNET, 8); // JARVIS runs on DigitalOcean — cannot reach 10.48.200.x directly.
$arp = getArpTable(); // Scan is delegated to the PVE1 agent (jarvis-netscan.sh runs nmap locally).
$known = JarvisDB::query('SELECT * FROM network_devices'); // This endpoint: queues the scan command to PVE1, returns current DB state immediately.
$knownMap = [];
foreach ($known as $d) $knownMap[$d['ip']] = $d;
$devices = []; // Queue netscan to PVE1 agent
foreach ($liveHosts as $ip) { $pve1 = JarvisDB::single(
$mac = $arp[$ip] ?? null; "SELECT agent_id FROM registered_agents WHERE ip_address='10.48.200.90' AND status='online' LIMIT 1"
$known_dev = $knownMap[$ip] ?? null; );
$nsOut = shell_exec('timeout 1 nslookup ' . escapeshellarg($ip) . ' 2>/dev/null | grep "name ="'); $queued = false;
$hostname = null; if ($pve1) {
if ($nsOut && preg_match('/name = (.+)\./', $nsOut, $nm)) {
$hostname = rtrim($nm[1], '.');
}
$devices[] = [
'ip' => $ip,
'mac' => $mac,
'hostname' => $hostname,
'alias' => $known_dev['alias'] ?? null,
'type' => $known_dev['device_type'] ?? 'unknown',
'status' => 'online',
];
JarvisDB::execute( JarvisDB::execute(
'INSERT INTO network_devices (ip, mac, hostname, status, last_seen) VALUES (?,?,?,\'online\',NOW()) "INSERT INTO agent_commands (agent_id, command_type, command_data, status) VALUES (?,?,?,?)",
ON DUPLICATE KEY UPDATE mac=VALUES(mac), hostname=VALUES(hostname), status=\'online\', last_seen=NOW()', [$pve1['agent_id'], 'shell', json_encode(['command'=>'/usr/local/bin/jarvis-netscan.sh','allowed'=>true]), 'pending']
[$ip, $mac, $hostname]
); );
$queued = true;
} }
foreach ($knownMap as $ip => $dev) {
if (!in_array($ip, $liveHosts)) { // Return current online devices from DB (populated by PVE1 netscan every 3 min)
JarvisDB::execute('UPDATE network_devices SET status=\'offline\' WHERE ip=?', [$ip]); $devices = JarvisDB::query(
} "SELECT ip, mac, hostname, alias, device_type as type, status, last_seen
} FROM network_devices WHERE status='online' AND last_seen > DATE_SUB(NOW(), INTERVAL 15 MINUTE)
echo json_encode(['devices' => $devices, 'count' => count($devices), 'scanned_at' => date('c')]); ORDER BY COALESCE(alias,hostname,ip)"
);
echo json_encode([
'devices' => $devices,
'count' => count($devices),
'queued' => $queued,
'scanned_at' => date('c'),
'note' => $queued
? 'Scan dispatched to PVE1 — results update in ~40 seconds.'
: 'Returning cached scan data. PVE1 auto-scans every 3 minutes.',
]);
} elseif ($action === 'add' && $method === 'POST') { } elseif ($action === 'add' && $method === 'POST') {
$ip = filter_var($data['ip'] ?? '', FILTER_VALIDATE_IP); $ip = filter_var($data['ip'] ?? '', FILTER_VALIDATE_IP);
+12 -19
View File
@@ -1296,30 +1296,23 @@ function renderNetworkStatus(n) {
// ── NETWORK SCAN ────────────────────────────────────────────────────── // ── NETWORK SCAN ──────────────────────────────────────────────────────
async function scanNetwork() { async function scanNetwork() {
const btn = document.getElementById('scanBtn'); const btn = document.getElementById('scanBtn');
btn.textContent = 'SCANNING...'; btn.textContent = 'QUEUING...';
btn.disabled = true; btn.disabled = true;
addMessage('jarvis', 'Initiating subnet scan on 10.48.200.0/24, Sir. This will take approximately 10 seconds.');
speak('Initiating network scan.');
try { try {
const data = await api('network/scan'); const data = await api('network/scan');
if (data.devices) { const count = data.count ?? 0;
const el = document.getElementById('network-list'); const msg = data.queued
el.innerHTML = data.devices.map(d => ? `Network scan dispatched to PVE1 probe, ${userAddr}. Currently showing ${count} active device${count!==1?'s':''} — panel will refresh with live results in approximately 40 seconds.`
`<div class="device-item"> : `Showing last known network data: ${count} active device${count!==1?'s':''} on 10.48.200.0/24. PVE1 probe scans automatically every 3 minutes.`;
<div class="device-status on"></div> addMessage('jarvis', msg);
<div class="device-info"> speak(count + ' devices online.');
<div class="device-name">${d.alias||d.hostname||d.ip}</div> // Refresh the network panel with current data
<div class="device-ip">${d.ip}${d.mac?' · '+d.mac:''}</div> loadNetwork();
</div> // Auto-refresh again after 45s to catch PVE1 scan results
</div>` if (data.queued) setTimeout(loadNetwork, 45000);
).join('');
const msg = `Network scan complete. Found ${data.count} active device${data.count!==1?'s':''} on the 10.48.200.0/24 subnet.`;
addMessage('jarvis', msg);
speak(msg);
}
} catch(e) { } catch(e) {
addMessage('jarvis', 'Network scan encountered an error, Sir.'); addMessage('jarvis', 'Network scan request failed, Sir.');
} }
btn.textContent = 'RUN NETWORK SCAN'; btn.textContent = 'RUN NETWORK SCAN';