"""Resolve Nexus center IP for Baota API whitelist.""" from __future__ import annotations import ipaddress import logging import socket from urllib.parse import urlparse from server.config import settings logger = logging.getLogger("nexus.btpanel.source_ip") def _is_ip(value: str) -> bool: try: ipaddress.ip_address(value.strip()) return True except ValueError: return False def _host_from_url(url: str) -> str | None: parsed = urlparse(url.strip()) host = (parsed.hostname or "").strip() return host or None def resolve_center_ip_from_dns(host: str) -> str | None: if not host: return None if _is_ip(host): return host try: infos = socket.getaddrinfo(host, None, type=socket.SOCK_STREAM) for info in infos: addr = info[4][0] if _is_ip(addr): return addr except OSError as exc: logger.warning("bt panel source ip dns failed host=%s: %s", host, exc) return None def get_bt_panel_source_ip() -> str | None: """Center outbound IP for Baota ``limit_addr`` (settings → API_BASE_URL DNS).""" explicit = (getattr(settings, "BT_PANEL_SOURCE_IP", None) or "").strip() if explicit and _is_ip(explicit): return explicit base = (settings.API_BASE_URL or "").strip() host = _host_from_url(base) if base else None if host: resolved = resolve_center_ip_from_dns(host) if resolved: return resolved return None