фикс парсинга
This commit is contained in:
parent
4c422741c5
commit
8a7a2ff9e1
2 changed files with 56 additions and 40 deletions
|
|
@ -3,6 +3,7 @@ CAPS INI config parsing utilities.
|
|||
All functions are pure (no network I/O, no DB).
|
||||
"""
|
||||
|
||||
import configparser as _cp
|
||||
import logging
|
||||
import re
|
||||
from configparser import RawConfigParser
|
||||
|
|
@ -36,7 +37,12 @@ def parse_config(
|
|||
all_rack_hosts = [rack_host]
|
||||
|
||||
parser = RawConfigParser(strict=False)
|
||||
try:
|
||||
parser.read_string(config_text)
|
||||
except _cp.Error as exc:
|
||||
# Malformed lines in the config — parser is already partially populated
|
||||
# with all sections up to the error. Log and continue with what we have.
|
||||
logger.warning("[discovery] Config parse warning for %s: %s", rack_host, exc)
|
||||
|
||||
discovered: list[DiscoveredDevice] = []
|
||||
seen_ips: set[str] = set()
|
||||
|
|
|
|||
|
|
@ -123,12 +123,19 @@ async def discover_via_ssh(
|
|||
neighbor_candidates: set[str] = set()
|
||||
discovered_device_ips: set[str] = set()
|
||||
|
||||
all_rack_ips = [h for _, h, _, _ in rack_hosts]
|
||||
|
||||
for rack_idx, (external_id, rack_host, rack_name, _rack_type_db) in enumerate(rack_hosts):
|
||||
await _emit("disc_rack_start", {
|
||||
"rack_name": rack_name, "rack_host": rack_host,
|
||||
"index": rack_idx, "total": len(rack_hosts),
|
||||
})
|
||||
|
||||
_rack_found: int = 0
|
||||
_rack_ssh_ok: bool = False
|
||||
_flush_error: Exception | None = None
|
||||
|
||||
try:
|
||||
# Allow per-device config_path override stored in connection_params.
|
||||
effective_config_path = await _resolve_rack_config_path(
|
||||
db, obj, rack_host, config_path
|
||||
|
|
@ -137,30 +144,22 @@ async def discover_via_ssh(
|
|||
rack_ssh_ok, config_text = await _ssh_fetch_rack_config(
|
||||
rack_host, ssh_port, ssh_options, effective_config_path, rack_name, result, _emit
|
||||
)
|
||||
_rack_ssh_ok = rack_ssh_ok
|
||||
|
||||
await _upsert_rack_device(
|
||||
db, obj, external_id, rack_host, rack_name,
|
||||
rack_id_mapping, rack_ssh_ok, now, result
|
||||
)
|
||||
|
||||
if not rack_ssh_ok:
|
||||
try:
|
||||
await db.flush()
|
||||
except Exception as exc:
|
||||
raise RuntimeError(f"DB flush failed for offline rack {rack_host}: {exc}") from exc
|
||||
await _emit("disc_rack_done", {
|
||||
"rack_name": rack_name, "rack_host": rack_host, "found": 0, "ssh_ok": False
|
||||
})
|
||||
continue
|
||||
|
||||
if rack_ssh_ok:
|
||||
neigh_ips = await get_ip_neighbors_multi(rack_host, ssh_port, ssh_options)
|
||||
neighbor_candidates.update(neigh_ips)
|
||||
discovered_device_ips.add(rack_host)
|
||||
|
||||
all_rack_ips = [h for _, h, _, _ in rack_hosts]
|
||||
await _emit("disc_action", {"message": f"Парсинг конфигурации {rack_name}..."})
|
||||
devices_found = parse_config(config_text, rack_host, all_rack_ips)
|
||||
logger.info("[discovery] Found %d devices from plugins in %s", len(devices_found), rack_host)
|
||||
_rack_found = len(devices_found)
|
||||
|
||||
for found in devices_found:
|
||||
await _upsert_plugin_device(
|
||||
|
|
@ -171,15 +170,26 @@ async def discover_via_ssh(
|
|||
try:
|
||||
await db.flush()
|
||||
except Exception as exc:
|
||||
# Session is now invalid — re-raise so the outer handler emits disc_done with error.
|
||||
# Continuing would cause every subsequent DB call to fail silently, producing
|
||||
# an incomplete discovery with no clear termination signal to the frontend.
|
||||
raise RuntimeError(f"DB flush failed after rack {rack_host}: {exc}") from exc
|
||||
# Session is now invalid after a failed flush — capture the error so we can
|
||||
# still emit disc_rack_done before propagating and aborting discovery.
|
||||
_flush_error = RuntimeError(f"DB flush failed after rack {rack_host}: {exc}") from exc
|
||||
|
||||
except Exception as exc:
|
||||
# Unexpected per-rack error (e.g. SSH timeout, config parse failure not caught
|
||||
# at a lower level). Record it and fall through to emit disc_rack_done.
|
||||
result.errors.append(f"Rack {rack_name} ({rack_host}): {exc}")
|
||||
logger.error("[discovery] Rack %s (%s) error: %s", rack_host, rack_name, exc, exc_info=True)
|
||||
|
||||
# disc_rack_done is always emitted — frontend must never be left with a spinner
|
||||
# for a rack that already received disc_rack_start.
|
||||
await _emit("disc_rack_done", {
|
||||
"rack_name": rack_name, "rack_host": rack_host,
|
||||
"found": len(devices_found), "ssh_ok": True,
|
||||
"found": _rack_found, "ssh_ok": _rack_ssh_ok,
|
||||
})
|
||||
|
||||
if _flush_error:
|
||||
raise _flush_error
|
||||
|
||||
# ── Phase 2.5: Slave rack discovery via ARP ───────────────────────────────
|
||||
all_rack_ips_set = {h for _, h, _, _ in rack_hosts}
|
||||
infra_ips = {ip for ip in [obj.server_ip, db_host] if ip}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue