Use manufacturer from NocoDB to select correct Netmiko device type
Aruba/HP switches now connect with hp_procurve instead of cisco_ios, fixing the 'terminal width 511' failure. Manufacturer is read from NocoDB and mapped to the correct device type before SSH connect. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
# scanner.py - Orchestrates the full scan pipeline
|
# scanner.py - Orchestrates the full scan pipeline
|
||||||
import logging
|
import logging
|
||||||
from nocodb_client import get_switch_ips
|
from nocodb_client import get_switches
|
||||||
from ssh_client import scan_all_switches
|
from ssh_client import scan_all_switches
|
||||||
from db import (
|
from db import (
|
||||||
upsert_switch, upsert_link, clear_links,
|
upsert_switch, upsert_link, clear_links,
|
||||||
@@ -39,7 +39,7 @@ def run_scan(dept: str = None, workers: int = 5, login_delay: int = 3):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Fetch switch list from NocoDB (or fallback)
|
# Fetch switch list from NocoDB (or fallback)
|
||||||
switches = get_switch_ips(dept=dept)
|
switches = get_switches(dept=dept)
|
||||||
|
|
||||||
if not switches:
|
if not switches:
|
||||||
logger.error("NocoDB returned no switches — aborting scan.")
|
logger.error("NocoDB returned no switches — aborting scan.")
|
||||||
|
|||||||
+26
-6
@@ -26,9 +26,18 @@ _pt.Transport.auth_password = _auth_password_no_fallback
|
|||||||
_login_lock = threading.Semaphore(1)
|
_login_lock = threading.Semaphore(1)
|
||||||
|
|
||||||
|
|
||||||
def connect_and_query(ip, login_delay=3):
|
def _device_type_for(manufacturer: str) -> str:
|
||||||
|
m = (manufacturer or "").lower()
|
||||||
|
if any(k in m for k in ("aruba", "hp", "hewlett", "procurve")):
|
||||||
|
return "hp_procurve"
|
||||||
|
if "dell" in m:
|
||||||
|
return "dell_os10"
|
||||||
|
return DEVICE_TYPE
|
||||||
|
|
||||||
|
|
||||||
|
def connect_and_query(ip, login_delay=3, device_type=None):
|
||||||
device = {
|
device = {
|
||||||
"device_type": DEVICE_TYPE,
|
"device_type": device_type or DEVICE_TYPE,
|
||||||
"host": ip,
|
"host": ip,
|
||||||
"username": SSH_USERNAME,
|
"username": SSH_USERNAME,
|
||||||
"password": SSH_PASSWORD,
|
"password": SSH_PASSWORD,
|
||||||
@@ -194,14 +203,25 @@ def _aruba_firmware(version_output):
|
|||||||
|
|
||||||
# ── Scan orchestration ────────────────────────────────────────────────────────
|
# ── Scan orchestration ────────────────────────────────────────────────────────
|
||||||
|
|
||||||
def scan_all_switches(ip_list, progress_callback=None, max_workers=5, login_delay=3):
|
def scan_all_switches(switch_list, progress_callback=None, max_workers=5, login_delay=3):
|
||||||
|
"""switch_list: list of IP strings or dicts with 'ip' and optional 'manufacturer'."""
|
||||||
results = []
|
results = []
|
||||||
total = len(ip_list)
|
total = len(switch_list)
|
||||||
done = 0
|
done = 0
|
||||||
|
|
||||||
_scan = partial(connect_and_query, login_delay=login_delay)
|
def _submit(entry):
|
||||||
|
if isinstance(entry, dict):
|
||||||
|
ip = entry["ip"]
|
||||||
|
dt = _device_type_for(entry.get("manufacturer", ""))
|
||||||
|
else:
|
||||||
|
ip, dt = entry, None
|
||||||
|
return ip, executor.submit(connect_and_query, ip, login_delay=login_delay, device_type=dt)
|
||||||
|
|
||||||
with ThreadPoolExecutor(max_workers=max_workers) as executor:
|
with ThreadPoolExecutor(max_workers=max_workers) as executor:
|
||||||
future_to_ip = {executor.submit(_scan, ip): ip for ip in ip_list}
|
future_to_ip = {}
|
||||||
|
for entry in switch_list:
|
||||||
|
ip, fut = _submit(entry)
|
||||||
|
future_to_ip[fut] = ip
|
||||||
|
|
||||||
for future in as_completed(future_to_ip):
|
for future in as_completed(future_to_ip):
|
||||||
ip = future_to_ip[future]
|
ip = future_to_ip[future]
|
||||||
|
|||||||
Reference in New Issue
Block a user