haiku Вайб 11

This commit is contained in:
dv 2026-04-08 12:42:05 +03:00
parent 435e425cd1
commit 23ee10a28e

View file

@ -96,8 +96,17 @@ class DiscoveredDevice:
cls: str
def _parse_config(config_text: str, rack_host: str) -> list[DiscoveredDevice]:
"""Extract discovered network devices from a caps config file."""
def _parse_config(config_text: str, rack_host: str, all_rack_hosts: list[str] | None = None) -> list[DiscoveredDevice]:
"""Extract discovered network devices from a caps config file.
Args:
config_text: Config file content
rack_host: IP of current rack (will be excluded from results)
all_rack_hosts: All rack IPs (will be excluded to avoid confusing rack servers with devices)
"""
if all_rack_hosts is None:
all_rack_hosts = [rack_host]
parser = RawConfigParser(strict=False)
parser.read_string(config_text)
@ -137,8 +146,8 @@ def _parse_config(config_text: str, rack_host: str) -> list[DiscoveredDevice]:
if not ip:
logger.info(f"[ssh_discovery] → IGNORED (not a valid network IP)")
continue
if ip == rack_host:
logger.info(f"[ssh_discovery] → IGNORED (matches rack_host {rack_host})")
if ip in all_rack_hosts:
logger.info(f"[ssh_discovery] → IGNORED (is a rack server IP: {ip})")
continue
if ip in seen_ips:
logger.info(f"[ssh_discovery] → IGNORED (duplicate, already seen)")
@ -567,7 +576,9 @@ async def discover_via_ssh(
category="embedded",
role="other",
))
devices_found = _parse_config(config_text, rack_host)
# Get all rack IPs to exclude them from device discovery
all_rack_ips = [host for _, host, _ in rack_hosts]
devices_found = _parse_config(config_text, rack_host, all_rack_ips)
logger.info(f"[ssh_discovery] Found {len(devices_found)} devices from plugins in {rack_host}")
for found in devices_found:
@ -585,6 +596,22 @@ async def discover_via_ssh(
if existing is not None:
changes = []
# PROTECT: Don't overwrite embedded (rack) devices with plugin devices!
# If device is currently embedded (a rack), never change it
if existing.category == "embedded":
logger.info(f"[ssh_discovery] {found.ip} ({found.plugin_name}) - SKIPPED: device is rack server (embedded), cannot overwrite with plugin device")
result.skipped += 1
result.actions.append(DeviceAction(
ip=found.ip,
hostname=existing.hostname,
action="SKIPPED",
reason=f"device is rack server (embedded), cannot overwrite with plugin device",
category=existing.category,
role=existing.role,
))
continue
if existing.category != found.category and existing.source == "auto_ssh":
changes.append(f"category: {existing.category}{found.category}")
existing.category = found.category
@ -592,7 +619,7 @@ async def discover_via_ssh(
changes.append(f"role: other→{found.role}")
existing.role = found.role
# Update hostname if it was never set or still auto-generated
if not existing.hostname or existing.hostname.startswith("rack") or existing.hostname.startswith("lane"):
if not existing.hostname or existing.hostname.startswith("rack") or (existing.hostname.startswith("lane") and not existing.hostname.startswith(f"{external_id}")):
if existing.hostname != hostname:
changes.append(f"hostname: '{existing.hostname}''{hostname}'")
existing.hostname = hostname