fix(snmp): 修复异步函数同步调用导致'coroutine object is not an iterator'错误
问题原因: - pysnmp.hlapi.asyncio 的 getCmd/bulkCmd/nextCmd 都是 async def 协程函数 - 返回的是 coroutine 对象,需要用 await 获取结果 - 原代码用 next() 或 for...in 同步迭代协程对象,报错: 'coroutine' object is not an iterator 解决方案: 1. snmp_service.py: 所有 SNMP 操作改为 async def - test_connection(): getCmd 改为 await getCmd() - get_arp_table(): bulkCmd 改为 await bulkCmd() - get_mac_address_table(): bulkCmd 改为 await bulkCmd() - get_interfaces(): bulkCmd 改为 await bulkCmd() - poll_device(): 所有子调用加 await 2. api/v1/snmp.py: API 路由改为 async def + await bulkCmd await 后返回 (errorIndication, errorStatus, errorIndex, varBindTable) 其中 varBindTable 是列表的列表(table 形式),需双层循环解析
This commit is contained in:
@@ -437,7 +437,7 @@ def delete_network_device(
|
||||
# ========== SNMP 操作 ==========
|
||||
|
||||
@router.post("/devices/{device_id}/test", summary="测试 SNMP 连接")
|
||||
def test_snmp_connection(device_id: int, db: Session = Depends(get_db)):
|
||||
async def test_snmp_connection(device_id: int, db: Session = Depends(get_db)):
|
||||
"""测试设备的 SNMP 连接(不写审计,避免刷屏)"""
|
||||
from app.models.snmp import NetworkDevice
|
||||
|
||||
@@ -448,7 +448,7 @@ def test_snmp_connection(device_id: int, db: Session = Depends(get_db)):
|
||||
if not device.snmp_credential:
|
||||
raise HTTPException(status_code=400, detail="设备未配置 SNMP 凭据")
|
||||
|
||||
success, info = SNMPService.test_connection(device, device.snmp_credential)
|
||||
success, info = await SNMPService.test_connection(device, device.snmp_credential)
|
||||
|
||||
return {
|
||||
"device_id": device_id,
|
||||
@@ -459,9 +459,9 @@ def test_snmp_connection(device_id: int, db: Session = Depends(get_db)):
|
||||
|
||||
|
||||
@router.post("/devices/{device_id}/poll", summary="立即轮询设备")
|
||||
def poll_device_now(device_id: int, db: Session = Depends(get_db)):
|
||||
async def poll_device_now(device_id: int, db: Session = Depends(get_db)):
|
||||
"""立即轮询设备,获取 ARP 表、MAC 地址表、接口信息(不写审计,常规操作)"""
|
||||
result = SNMPService.poll_device(db, device_id)
|
||||
result = await SNMPService.poll_device(db, device_id)
|
||||
|
||||
if 'error' in result:
|
||||
raise HTTPException(status_code=400, detail=result['error'])
|
||||
@@ -470,7 +470,7 @@ def poll_device_now(device_id: int, db: Session = Depends(get_db)):
|
||||
|
||||
|
||||
@router.post("/devices/{device_id}/arp", summary="获取设备 ARP 表")
|
||||
def get_device_arp_table(device_id: int, db: Session = Depends(get_db)):
|
||||
async def get_device_arp_table(device_id: int, db: Session = Depends(get_db)):
|
||||
"""获取设备的 ARP 表"""
|
||||
from app.models.snmp import NetworkDevice, ARPEntry
|
||||
|
||||
@@ -481,7 +481,7 @@ def get_device_arp_table(device_id: int, db: Session = Depends(get_db)):
|
||||
if not device.snmp_credential:
|
||||
raise HTTPException(status_code=400, detail="设备未配置 SNMP 凭据")
|
||||
|
||||
entries = SNMPService.get_arp_table(device, device.snmp_credential, db)
|
||||
entries = await SNMPService.get_arp_table(device, device.snmp_credential, db)
|
||||
|
||||
return {
|
||||
"device_id": device_id,
|
||||
|
||||
Reference in New Issue
Block a user