IP-адреса VM стали искаться в нескольких источниках
Этот коммит содержится в:
@@ -31,21 +31,104 @@ if removed_helpers:
|
|||||||
changed.append('old VM IP helper block was removed')
|
changed.append('old VM IP helper block was removed')
|
||||||
|
|
||||||
new_parse_virsh_list = '''def parse_virsh_list() -> list[dict[str, str]]:
|
new_parse_virsh_list = '''def parse_virsh_list() -> list[dict[str, str]]:
|
||||||
def resolve_ip(name: str) -> str:
|
def clean_ip(ip: str) -> str:
|
||||||
if not name:
|
ip = (ip or "").split("/")[0].strip()
|
||||||
return "—"
|
if not ip or ip.startswith("127.") or ip.startswith("169.254.") or ip == "0.0.0.0":
|
||||||
|
return ""
|
||||||
|
return ip
|
||||||
|
|
||||||
|
def vm_macs(name: str) -> list[str]:
|
||||||
|
try:
|
||||||
|
result = run_cmd(["virsh", "domiflist", name], timeout=8)
|
||||||
|
if not result.get("ok"):
|
||||||
|
return []
|
||||||
|
macs = []
|
||||||
|
for mac in re.findall(r"(?:[0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}", result.get("stdout", "")):
|
||||||
|
macs.append(mac.lower())
|
||||||
|
return macs
|
||||||
|
except Exception:
|
||||||
|
return []
|
||||||
|
|
||||||
|
def ip_from_domifaddr(name: str) -> str:
|
||||||
try:
|
try:
|
||||||
result = run_cmd(["virsh", "domifaddr", name], timeout=8)
|
result = run_cmd(["virsh", "domifaddr", name], timeout=8)
|
||||||
if result.get("ok"):
|
if result.get("ok"):
|
||||||
for ip in re.findall(r"\\b(\\d{1,3}(?:\\.\\d{1,3}){3})/\\d+", result.get("stdout", "")):
|
for ip in re.findall(r"\\b(\\d{1,3}(?:\\.\\d{1,3}){3})/\\d+", result.get("stdout", "")):
|
||||||
if not ip.startswith("127.") and not ip.startswith("169.254."):
|
ip = clean_ip(ip)
|
||||||
|
if ip:
|
||||||
return ip
|
return ip
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def ip_from_network_core(name: str) -> str:
|
||||||
try:
|
try:
|
||||||
resolved = network_core.resolve_vm_ip(name)
|
resolved = network_core.resolve_vm_ip(name)
|
||||||
if resolved:
|
if resolved:
|
||||||
return str(resolved)
|
return clean_ip(str(resolved))
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def ip_from_dnsmasq_leases(macs: list[str]) -> str:
|
||||||
|
if not macs:
|
||||||
|
return ""
|
||||||
|
try:
|
||||||
|
for lease_file in Path("/var/lib/libvirt/dnsmasq").glob("*.leases"):
|
||||||
|
for line in lease_file.read_text(errors="ignore").splitlines():
|
||||||
|
low = line.lower()
|
||||||
|
if not any(mac in low for mac in macs):
|
||||||
|
continue
|
||||||
|
parts = line.split()
|
||||||
|
if len(parts) >= 3:
|
||||||
|
ip = clean_ip(parts[2])
|
||||||
|
if ip:
|
||||||
|
return ip
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def ip_from_neighbor_tables(macs: list[str]) -> str:
|
||||||
|
if not macs:
|
||||||
|
return ""
|
||||||
|
commands = [
|
||||||
|
["ip", "neigh", "show"],
|
||||||
|
["ip", "neigh", "show", "dev", "virbr100"],
|
||||||
|
["ip", "neigh", "show", "dev", "br0"],
|
||||||
|
["arp", "-an"],
|
||||||
|
]
|
||||||
|
for cmd in commands:
|
||||||
|
try:
|
||||||
|
result = run_cmd(cmd, timeout=8)
|
||||||
|
if not result.get("ok"):
|
||||||
|
continue
|
||||||
|
for line in result.get("stdout", "").splitlines():
|
||||||
|
low = line.lower()
|
||||||
|
if not any(mac in low for mac in macs):
|
||||||
|
continue
|
||||||
|
matches = re.findall(r"\\b(\\d{1,3}(?:\\.\\d{1,3}){3})\\b", line)
|
||||||
|
for value in matches:
|
||||||
|
ip = clean_ip(value)
|
||||||
|
if ip:
|
||||||
|
return ip
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def resolve_ip(name: str) -> str:
|
||||||
|
if not name:
|
||||||
|
return "—"
|
||||||
|
macs = vm_macs(name)
|
||||||
|
for resolver in (
|
||||||
|
lambda: ip_from_domifaddr(name),
|
||||||
|
lambda: ip_from_network_core(name),
|
||||||
|
lambda: ip_from_dnsmasq_leases(macs),
|
||||||
|
lambda: ip_from_neighbor_tables(macs),
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
ip = resolver()
|
||||||
|
if ip:
|
||||||
|
return ip
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
return "—"
|
return "—"
|
||||||
@@ -75,7 +158,7 @@ text, replaced = re.subn(
|
|||||||
flags=re.S,
|
flags=re.S,
|
||||||
)
|
)
|
||||||
if replaced:
|
if replaced:
|
||||||
changed.append('parse_virsh_list was replaced with a safe inline IP resolver')
|
changed.append('parse_virsh_list was replaced with multi-source VM IP resolver')
|
||||||
else:
|
else:
|
||||||
warnings.append('parse_virsh_list block not found, app.py IP injection skipped')
|
warnings.append('parse_virsh_list block not found, app.py IP injection skipped')
|
||||||
|
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user