From 47b0928b2a81c2635af31b98f65807a5ce98c634 Mon Sep 17 00:00:00 2001 From: dv Date: Wed, 8 Apr 2026 11:46:32 +0300 Subject: [PATCH] =?UTF-8?q?haiku=20=D0=B2=D0=B0=D0=B9=D0=B1=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/services/device_discovery.py | 57 +++++++++++++----------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/backend/app/services/device_discovery.py b/backend/app/services/device_discovery.py index 854eff5..6307bd5 100644 --- a/backend/app/services/device_discovery.py +++ b/backend/app/services/device_discovery.py @@ -11,6 +11,7 @@ Limitations (devices not discoverable automatically): - Physical MikroTik router (not in rack configs) """ +import logging import re from configparser import RawConfigParser from dataclasses import dataclass, field @@ -26,6 +27,8 @@ from app.models.device import Device from app.models.object import Object from app.services.crypto import decrypt +logger = logging.getLogger(__name__) + # ── URI extraction ──────────────────────────────────────────────────────────── _SERIAL_SCHEMES = {"serial", "com"} @@ -183,7 +186,7 @@ async def _discover_mikrotik_via_ssh_client( if parts: return parts[0] except Exception as e: - print(f"[ssh_discovery] Failed to discover MikroTik via SSH_CLIENT: {e}") + logger.warning(f"[ssh_discovery] Failed to discover MikroTik via SSH_CLIENT: {e}") return None @@ -218,7 +221,7 @@ async def _discover_proxmox_via_port_scan( ips = [line.strip() for line in result.stdout.strip().split('\n') if line.strip()] return ips except Exception as e: - print(f"[ssh_discovery] Failed to discover Proxmox servers via port scan: {e}") + logger.warning(f"[ssh_discovery] Failed to discover Proxmox servers via port scan: {e}") return [] @@ -467,9 +470,9 @@ async def discover_via_ssh( result.errors.append(f"SSH to {rack_host} failed: {exc}") continue - print(f"[ssh_discovery] Processing rack {rack_host} ({rack_name})") + logger.info(f"[ssh_discovery] Processing rack {rack_host} ({rack_name})") devices_found = _parse_config(config_text, rack_host) - print(f"[ssh_discovery] Found {len(devices_found)} devices from plugins in {rack_host}") + logger.info(f"[ssh_discovery] Found {len(devices_found)} devices from plugins in {rack_host}") for found in devices_found: # Hostname: "rack{rack_name}-{plugin_name}", e.g. "rack01-camera_grz" @@ -484,23 +487,25 @@ async def discover_via_ssh( )).scalar_one_or_none() if existing is not None: - changed = False + changes = [] if existing.category != found.category and existing.source == "auto_ssh": existing.category = found.category - changed = True + changes.append(f"category: {existing.category}→{found.category}") if existing.role == "other" and found.role != "other": existing.role = found.role - changed = True + changes.append(f"role: other→{found.role}") # Update hostname if it was never set or still auto-generated if not existing.hostname or existing.hostname.startswith("rack"): if existing.hostname != hostname: existing.hostname = hostname - changed = True + changes.append(f"hostname: {existing.hostname}→{hostname}") - action = "UPDATED" if changed else "SKIPPED" - print(f"[ssh_discovery] Device {found.ip} ({hostname}) - {action}") - result.updated += 1 if changed else 0 - result.skipped += 0 if changed else 1 + if changes: + logger.info(f"[ssh_discovery] Device {found.ip} ({hostname}) - UPDATED ({', '.join(changes)})") + result.updated += 1 + else: + logger.debug(f"[ssh_discovery] Device {found.ip} ({hostname}) - SKIPPED (no changes, category={existing.category}, role={existing.role}, hostname={existing.hostname})") + result.skipped += 1 else: db.add(Device( object_id=obj.id, @@ -511,10 +516,10 @@ async def discover_via_ssh( source="auto_ssh", device_meta={"plugin": found.plugin_name, "cls": found.cls}, )) - print(f"[ssh_discovery] Device {found.ip} ({hostname}) - ADDED") + logger.info(f"[ssh_discovery] Device {found.ip} ({hostname}) - ADDED (category={found.category}, role={found.role})") result.created += 1 except Exception as exc: - print(f"[ssh_discovery] Error upserting {found.ip}: {exc}") + logger.error(f"[ssh_discovery] Error upserting {found.ip}: {exc}") result.errors.append(f"Error upserting {found.ip}: {exc}") # Flush after each rack so that subsequent SELECTs (for other racks @@ -527,7 +532,7 @@ async def discover_via_ssh( result.errors.append(f"Flush error after rack {rack_host}: {exc}") # Step 3: Discover MikroTik via SSH_CLIENT - print(f"[ssh_discovery] Attempting to discover MikroTik via SSH_CLIENT on {obj.server_ip or 'main_server'}") + logger.info(f"[ssh_discovery] Attempting to discover MikroTik via SSH_CLIENT on {obj.server_ip or 'main_server'}") mikrotik_ip = await _discover_mikrotik_via_ssh_client( host=obj.server_ip or rack_hosts[0][1], port=obj.ssh_port or 22, @@ -535,7 +540,7 @@ async def discover_via_ssh( password=ssh_password, ) if mikrotik_ip: - print(f"[ssh_discovery] Discovered MikroTik at {mikrotik_ip}") + logger.info(f"[ssh_discovery] Discovered MikroTik at {mikrotik_ip}") try: existing = (await db.execute( select(Device).where( @@ -545,7 +550,7 @@ async def discover_via_ssh( )).scalar_one_or_none() if existing is not None: - print(f"[ssh_discovery] Device {mikrotik_ip} (mikrotik) - SKIPPED") + logger.debug(f"[ssh_discovery] Device {mikrotik_ip} (mikrotik) - SKIPPED (already exists, category={existing.category}, hostname={existing.hostname})") result.skipped += 1 else: db.add(Device( @@ -556,18 +561,18 @@ async def discover_via_ssh( role="other", source="auto_ssh", )) - print(f"[ssh_discovery] Device {mikrotik_ip} (mikrotik) - ADDED") + logger.info(f"[ssh_discovery] Device {mikrotik_ip} (mikrotik) - ADDED (category=router, role=other)") result.created += 1 except Exception as exc: - print(f"[ssh_discovery] Error upserting {mikrotik_ip}: {exc}") + logger.error(f"[ssh_discovery] Error upserting {mikrotik_ip}: {exc}") result.errors.append(f"Error upserting {mikrotik_ip}: {exc}") await db.flush() else: - print(f"[ssh_discovery] No MikroTik found via SSH_CLIENT") + logger.debug(f"[ssh_discovery] No MikroTik found via SSH_CLIENT") # Step 4: Discover Proxmox via port 8006 scan - print(f"[ssh_discovery] Attempting to discover Proxmox servers via port 8006 scan on {obj.server_ip or 'main_server'}") + logger.info(f"[ssh_discovery] Attempting to discover Proxmox servers via port 8006 scan on {obj.server_ip or 'main_server'}") proxmox_ips = await _discover_proxmox_via_port_scan( host=obj.server_ip or rack_hosts[0][1], port=obj.ssh_port or 22, @@ -575,7 +580,7 @@ async def discover_via_ssh( password=ssh_password, ) if proxmox_ips: - print(f"[ssh_discovery] Discovered {len(proxmox_ips)} Proxmox server(s): {proxmox_ips}") + logger.info(f"[ssh_discovery] Discovered {len(proxmox_ips)} Proxmox server(s): {proxmox_ips}") for idx, proxmox_ip in enumerate(proxmox_ips, 1): hostname = f"proxmox_{idx}" try: @@ -587,7 +592,7 @@ async def discover_via_ssh( )).scalar_one_or_none() if existing is not None: - print(f"[ssh_discovery] Device {proxmox_ip} ({hostname}) - SKIPPED") + logger.debug(f"[ssh_discovery] Device {proxmox_ip} ({hostname}) - SKIPPED (already exists, category={existing.category}, hostname={existing.hostname})") result.skipped += 1 else: db.add(Device( @@ -598,14 +603,14 @@ async def discover_via_ssh( role="other", source="auto_ssh", )) - print(f"[ssh_discovery] Device {proxmox_ip} ({hostname}) - ADDED") + logger.info(f"[ssh_discovery] Device {proxmox_ip} ({hostname}) - ADDED (category=vm, role=other)") result.created += 1 except Exception as exc: - print(f"[ssh_discovery] Error upserting {proxmox_ip}: {exc}") + logger.error(f"[ssh_discovery] Error upserting {proxmox_ip}: {exc}") result.errors.append(f"Error upserting {proxmox_ip}: {exc}") await db.flush() else: - print(f"[ssh_discovery] No Proxmox servers found via port 8006 scan") + logger.debug(f"[ssh_discovery] No Proxmox servers found via port 8006 scan") return result