fix(scan): 修复单IP扫描500错误并清除MySQL不兼容SQL
1. enhanced_scan.py: comprehensive_scan_ip 误用 schema 的 IPAddress 做 db.query 导致 ArgumentError(500)。改用 ORM 模型 IPAddressModel,与 文件内其他函数一致。 2. enhanced_scan_service.py: update_ip_from_scan_result 使用 PostgreSQL 的 @> 包含操作符,MySQL 上报 SQL语法错误(1064)。改为纯 Python ipaddress 遍历匹配网段,新增 _find_network_for_ip 辅助方法。
This commit is contained in:
@@ -429,17 +429,7 @@ class EnhancedScanService:
|
||||
|
||||
# 如果IP不存在,尝试自动创建
|
||||
if not db_ip:
|
||||
network = db.query(Network).filter(
|
||||
Network.cidr.op('@>')((ip_address + '/32').encode('utf-8'))
|
||||
).first()
|
||||
if not network:
|
||||
for net in db.query(Network).all():
|
||||
try:
|
||||
if ip_address in ipaddress.ip_network(net.cidr, strict=False):
|
||||
network = net
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
network = EnhancedScanService._find_network_for_ip(db, ip_address)
|
||||
if not network:
|
||||
logger.warning(f"无法为扫描到的IP {ip_address} 找到所属网段,跳过创建")
|
||||
return
|
||||
@@ -481,6 +471,31 @@ class EnhancedScanService:
|
||||
|
||||
return db_ip
|
||||
|
||||
@staticmethod
|
||||
def _find_network_for_ip(db: Session, ip_address: str) -> Optional[Network]:
|
||||
"""
|
||||
查找 IP 所属的网段(兼容 MySQL,不使用 PostgreSQL 的 @> 操作符)。
|
||||
优先按网段越大越精确匹配,无法精确匹配时返回包含该 IP 的最小/最合适网段。
|
||||
"""
|
||||
try:
|
||||
target = ipaddress.ip_address(ip_address)
|
||||
except ValueError:
|
||||
return None
|
||||
best = None
|
||||
best_prefix = -1
|
||||
for net in db.query(Network).all():
|
||||
try:
|
||||
cidr = str(net.cidr)
|
||||
net_obj = ipaddress.ip_network(cidr, strict=False)
|
||||
if target in net_obj:
|
||||
# 取前缀最长的(网段最小、最精确)
|
||||
if net_obj.prefixlen > best_prefix:
|
||||
best = net
|
||||
best_prefix = net_obj.prefixlen
|
||||
except Exception:
|
||||
continue
|
||||
return best
|
||||
|
||||
@staticmethod
|
||||
def bulk_update_ips_from_scan(db: Session, scan_results: List[Dict[str, Any]]):
|
||||
"""批量更新IP信息"""
|
||||
|
||||
Reference in New Issue
Block a user