я устал

This commit is contained in:
dv 2026-04-08 16:59:49 +03:00
parent 3b63d2c533
commit 1c472dbe24

View file

@ -424,8 +424,8 @@ async def _get_rack_hosts_direct(
tunnel_ssh_port: int = 22,
tunnel_ssh_user: str | None = None,
tunnel_ssh_password: str | None = None,
) -> list[tuple[str, str, str]]:
"""Return list of (external_id, host_ip, rack_name) from the racks table."""
) -> list[tuple[str, str, str, str | None]]:
"""Return list of (external_id, host_ip, rack_name, rack_type) from the racks table."""
if via_tunnel and tunnel_host and tunnel_ssh_user and tunnel_ssh_password:
async with asyncssh.connect(
tunnel_host,
@ -446,14 +446,15 @@ async def _get_rack_hosts_direct(
return await _fetch_rack_hosts(dsn, table)
async def _fetch_rack_hosts(dsn: str, table: str) -> list[tuple[str, str, str]]:
"""Return list of (external_id, host_ip, rack_name) from the racks table."""
async def _fetch_rack_hosts(dsn: str, table: str) -> list[tuple[str, str, str, str | None]]:
"""Return list of (external_id, host_ip, rack_name, rack_type) from the racks table."""
async with await psycopg.AsyncConnection.connect(dsn) as conn:
cursor = await conn.execute(
f"SELECT id, data->>'host' AS host, name FROM \"{table}\" WHERE data->>'host' IS NOT NULL"
f"SELECT id, data->>'host' AS host, name, data->>'rack_type' AS rack_type "
f"FROM \"{table}\" WHERE data->>'host' IS NOT NULL"
)
rows = await cursor.fetchall()
return [(str(r[0]), str(r[1]), str(r[2] or r[0])) for r in rows if r[1]]
return [(str(r[0]), str(r[1]), str(r[2] or r[0]), r[3] or None) for r in rows if r[1]]
# ── Main entry point ──────────────────────────────────────────────────────────
@ -608,18 +609,21 @@ async def discover_via_ssh(
# If a rack with that name doesn't exist yet in our racks table, create it now.
from app.models.rack import Rack
rack_id_mapping: dict[str, int] = {}
for ext_id, _, _ in rack_hosts:
for ext_id, _, _, rack_type_db in rack_hosts:
existing_rack_row = (await db.execute(
select(Rack).where(Rack.object_id == obj.id, Rack.name == ext_id)
)).scalar_one_or_none()
if existing_rack_row:
rack_id_mapping[ext_id] = existing_rack_row.id
if rack_type_db and not existing_rack_row.rack_type:
existing_rack_row.rack_type = rack_type_db
logger.info(f"[ssh_discovery] Updated rack '{ext_id}' rack_type={rack_type_db}")
else:
new_rack = Rack(object_id=obj.id, name=ext_id)
new_rack = Rack(object_id=obj.id, name=ext_id, rack_type=rack_type_db)
db.add(new_rack)
await db.flush() # get the new PK
rack_id_mapping[ext_id] = new_rack.id
logger.info(f"[ssh_discovery] Created rack entry '{ext_id}' (id={new_rack.id})")
logger.info(f"[ssh_discovery] Created rack entry '{ext_id}' rack_type={rack_type_db} (id={new_rack.id})")
# Step 1b: Add main CAPS server and DB server as devices
# verified=True means we successfully connected to this host during this discovery run
@ -697,7 +701,7 @@ async def discover_via_ssh(
if infra_devices:
await db.flush()
for rack_idx, (external_id, rack_host, rack_name) in enumerate(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,
@ -822,7 +826,7 @@ async def discover_via_ssh(
discovered_device_ips.add(rack_host) # rack PC itself is a known device
# Get all rack IPs to exclude them from device discovery
all_rack_ips = [host for _, host, _ in rack_hosts]
all_rack_ips = [host for _, host, _, _ in rack_hosts]
await _emit("disc_action", {"message": f"Парсинг конфигурации {rack_name}..."})
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}")
@ -956,7 +960,7 @@ async def discover_via_ssh(
# Step 2.5: Discover slave racks via ARP neighbor tables
# Filter out already-known IPs: rack hosts, discovered devices, infra IPs, common gateways
all_rack_ips_set = {host for _, host, _ in rack_hosts}
all_rack_ips_set = {host for _, host, _, _ in rack_hosts}
infra_ips = {ip for ip in [obj.server_ip, db_host] if ip}
common_gateways = {ip for ip in neighbor_candidates if ip.endswith(".1") or ip.endswith(".254")}
slave_candidates = (
@ -980,7 +984,7 @@ async def discover_via_ssh(
slave_identifier = ""
slave_config_text = ""
master_ip_for_slave = ""
for _, master_host, _ in rack_hosts:
for _, master_host, _, _ in rack_hosts:
ok, identifier, slave_cfg = await _check_if_slave(
host=candidate_ip,
port=ssh_port,
@ -995,7 +999,7 @@ async def discover_via_ssh(
master_ip_for_slave = master_host
# Derive slave name from master's external_id: "lane-1-1" → "lane-1-1-slave"
master_ext_id = next(
(ext_id for ext_id, host, _ in rack_hosts if host == master_host),
(ext_id for ext_id, host, _, _ in rack_hosts if host == master_host),
master_host,
)
slave_identifier = f"{master_ext_id}-slave"