mirror of
https://github.com/myronblair/jarvis
synced 2026-06-30 17:50:23 -05:00
Fix network panel: include netscan devices; fix Scan Now to queue agent command
This commit is contained in:
@@ -149,7 +149,28 @@ if ($action === 'scan') {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. External services we can actually ping from DO
|
// 3. Netscan-discovered devices (PVE1 nmap push — status from last scan)
|
||||||
|
$discovered = JarvisDB::query(
|
||||||
|
'SELECT ip, mac, hostname, device_type, status, last_seen FROM network_devices
|
||||||
|
WHERE (alias IS NULL OR alias = "") AND last_seen > DATE_SUB(NOW(), INTERVAL 15 MINUTE)
|
||||||
|
ORDER BY ip'
|
||||||
|
);
|
||||||
|
foreach ($discovered as $dev) {
|
||||||
|
if (in_array($dev['ip'], $agentIPs)) continue;
|
||||||
|
$devices[] = [
|
||||||
|
'ip' => $dev['ip'],
|
||||||
|
'name' => $dev['hostname'] ?: ($dev['device_type'] ?: $dev['ip']),
|
||||||
|
'mac' => $dev['mac'],
|
||||||
|
'type' => $dev['device_type'] ?: 'device',
|
||||||
|
'alive' => $dev['status'] === 'online',
|
||||||
|
'status' => $dev['status'],
|
||||||
|
'last_seen' => $dev['last_seen'],
|
||||||
|
'source' => 'netscan',
|
||||||
|
'deletable' => false,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. External services we can actually ping from DO
|
||||||
$external = [
|
$external = [
|
||||||
['ip' => '134.209.72.226', 'name' => 'FusionPBX DO', 'type' => 'server'],
|
['ip' => '134.209.72.226', 'name' => 'FusionPBX DO', 'type' => 'server'],
|
||||||
];
|
];
|
||||||
|
|||||||
+22
-21
@@ -88,23 +88,20 @@ if ($action) {
|
|||||||
j(JarvisDB::query('SELECT id,ip,mac,hostname,alias,device_type,status,last_seen FROM network_devices ORDER BY status="online" DESC, COALESCE(alias,hostname,ip)'));
|
j(JarvisDB::query('SELECT id,ip,mac,hostname,alias,device_type,status,last_seen FROM network_devices ORDER BY status="online" DESC, COALESCE(alias,hostname,ip)'));
|
||||||
|
|
||||||
case 'network_scan':
|
case 'network_scan':
|
||||||
// Trigger immediate nmap scan via PVE1
|
// Queue shell command to PVE1 agent — it runs jarvis-netscan.sh and pushes results back
|
||||||
$out = shell_exec("sshpass -p 'Joker1974!!!' ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 root@10.48.200.90 'nmap -sn --send-ip 10.48.200.0/24 2>/dev/null' 2>/dev/null");
|
$pve1 = JarvisDB::single('SELECT agent_id FROM registered_agents WHERE ip_address="10.48.200.90" AND status="online" LIMIT 1');
|
||||||
$count = 0;
|
if (!$pve1) {
|
||||||
if ($out) {
|
$pve1 = JarvisDB::single('SELECT agent_id FROM registered_agents WHERE hostname LIKE "%pve%" AND status="online" LIMIT 1');
|
||||||
$cur = null;
|
}
|
||||||
foreach (explode("\n", $out) as $line) {
|
if ($pve1) {
|
||||||
$line = trim($line);
|
JarvisDB::execute(
|
||||||
if (preg_match('/Nmap scan report for (?:(\S+) \()?(\d+\.\d+\.\d+\.\d+)\)?/', $line, $m)) {
|
'INSERT INTO agent_commands (agent_id, command_type, command_data, status) VALUES (?,?,?,?)',
|
||||||
if ($cur) { self_upsert_device($cur); $count++; }
|
[$pve1['agent_id'], 'shell', json_encode(['command'=>'/usr/local/bin/jarvis-netscan.sh','allowed'=>true]), 'pending']
|
||||||
$cur = ['hostname' => ($m[1] && $m[1] !== $m[2]) ? $m[1] : null, 'ip' => $m[2], 'mac' => null, 'vendor' => null];
|
);
|
||||||
} elseif ($cur && preg_match('/MAC Address: ([0-9A-Fa-f:]{17}) \(([^)]+)\)/i', $line, $m)) {
|
j(['ok' => true, 'queued' => true, 'note' => 'Scan command sent to PVE1 agent — results in ~40 seconds']);
|
||||||
$cur['mac'] = strtolower($m[1]); $cur['vendor'] = $m[2] !== 'Unknown' ? $m[2] : null;
|
} else {
|
||||||
}
|
j(['ok' => false, 'note' => 'PVE1 agent offline — scan will run automatically via cron in < 3 minutes']);
|
||||||
}
|
|
||||||
if ($cur) { self_upsert_device($cur); $count++; }
|
|
||||||
}
|
}
|
||||||
j(['ok' => true, 'found' => $count]);
|
|
||||||
|
|
||||||
case 'network_save':
|
case 'network_save':
|
||||||
$id = (int)($_POST['id'] ?? 0);
|
$id = (int)($_POST['id'] ?? 0);
|
||||||
@@ -762,15 +759,19 @@ function renderNetwork() {
|
|||||||
|
|
||||||
async function scanNow() {
|
async function scanNow() {
|
||||||
const btn = document.getElementById('scanBtn');
|
const btn = document.getElementById('scanBtn');
|
||||||
btn.textContent = 'SCANNING...'; btn.disabled = true;
|
btn.textContent = 'QUEUING...'; btn.disabled = true;
|
||||||
const fd = new FormData(); fd.append('action','network_scan');
|
const fd = new FormData(); fd.append('action','network_scan');
|
||||||
try {
|
try {
|
||||||
const r = await fetch(location.href,{method:'POST',body:fd});
|
const r = await fetch(location.href,{method:'POST',body:fd});
|
||||||
const d = await r.json();
|
const d = await r.json();
|
||||||
if (d.ok) { toast(`Scan complete — ${d.found} devices found`,'ok'); loadNetwork(); }
|
if (d.ok && d.queued) {
|
||||||
else toast(d.error||'Scan failed','err');
|
toast('Scan queued — refreshing in 45s...','ok');
|
||||||
} catch(e){ toast('Scan failed','err'); }
|
setTimeout(()=>{ loadNetwork(); }, 45000);
|
||||||
btn.textContent = 'SCAN NOW'; btn.disabled = false;
|
} else {
|
||||||
|
toast(d.note || 'Scan scheduled via cron','ok');
|
||||||
|
}
|
||||||
|
} catch(e){ toast('Request failed','err'); }
|
||||||
|
setTimeout(()=>{ btn.textContent='SCAN NOW'; btn.disabled=false; }, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function netModal(id=0, ip='', alias='', type='') {
|
function netModal(id=0, ip='', alias='', type='') {
|
||||||
|
|||||||
Reference in New Issue
Block a user