初始化
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
"""业务下发服务"""
|
||||
from typing import Dict
|
||||
from sqlalchemy.orm import Session
|
||||
from app.services.ssh_service import SSHService
|
||||
from app.models.device import ONUDevice, OLTDevice
|
||||
import time
|
||||
|
||||
|
||||
class ProvisionService:
|
||||
"""业务下发服务"""
|
||||
|
||||
def __init__(self, db: Session):
|
||||
self.db = db
|
||||
|
||||
def provision_device(self, device_id: int) -> Dict[str, any]:
|
||||
"""
|
||||
业务下发流程(参照下发业务流程.md):
|
||||
1. system-view
|
||||
2. interface Onu{port_id}
|
||||
3. uni 1 vlan-mode trunk pvid 4094 2000 to 2000 3000 to 3010
|
||||
4. port link-type trunk
|
||||
5. undo port trunk permit vlan 1
|
||||
6. port trunk permit vlan 2000 3000 to 3010 4094
|
||||
7. save force
|
||||
"""
|
||||
device = self.db.query(ONUDevice).filter(ONUDevice.id == device_id).first()
|
||||
if not device:
|
||||
return {"success": False, "error": f"设备不存在: {device_id}"}
|
||||
|
||||
if not device.olt_id:
|
||||
return {"success": False, "error": "设备未关联 OLT,请先进行扫描"}
|
||||
|
||||
olt = self.db.query(OLTDevice).filter(OLTDevice.id == device.olt_id).first()
|
||||
if not olt:
|
||||
return {"success": False, "error": "关联的 OLT 设备不存在"}
|
||||
|
||||
if not device.port_id:
|
||||
return {"success": False, "error": "设备端口信息不完整,请先对 OLT 执行扫描"}
|
||||
|
||||
port_name = f"Onu{device.port_id}"
|
||||
ssh = SSHService(olt.ip_address, olt.username, olt.password)
|
||||
|
||||
try:
|
||||
ssh.connect()
|
||||
|
||||
def send_and_wait(cmd: str, expect: str, timeout: int = 15) -> str:
|
||||
ssh.shell.send(cmd + "\n")
|
||||
buf = ""
|
||||
deadline = time.time() + timeout
|
||||
while time.time() < deadline:
|
||||
if ssh.shell.recv_ready():
|
||||
buf += ssh.shell.recv(4096).decode("utf-8", errors="ignore")
|
||||
if expect in buf:
|
||||
return buf
|
||||
else:
|
||||
time.sleep(0.2)
|
||||
return buf
|
||||
|
||||
# 进入系统视图
|
||||
out = send_and_wait("system-view", "]")
|
||||
if "]" not in out:
|
||||
raise Exception("进入 system-view 失败")
|
||||
|
||||
# 进入端口
|
||||
out = send_and_wait(f"interface {port_name}", "]")
|
||||
if "]" not in out:
|
||||
raise Exception(f"进入端口 {port_name} 失败")
|
||||
|
||||
# 配置 VLAN
|
||||
send_and_wait("uni 1 vlan-mode trunk pvid 4094 2000 to 2000 3000 to 3010", "]")
|
||||
send_and_wait("port link-type trunk", "]")
|
||||
send_and_wait("undo port trunk permit vlan 1", "]")
|
||||
send_and_wait("port trunk permit vlan 2000 3000 to 3010 4094", "]")
|
||||
|
||||
# 保存配置(等待 "successfully" 出现)
|
||||
save_out = send_and_wait("save force", "successfully", timeout=30)
|
||||
if "successfully" not in save_out:
|
||||
raise Exception("save force 未确认成功,请检查 OLT 日志")
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"device_id": device_id,
|
||||
"mac_address": device.mac_address,
|
||||
"olt_ip": olt.ip_address,
|
||||
"port": port_name,
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
return {
|
||||
"success": False,
|
||||
"device_id": device_id,
|
||||
"mac_address": device.mac_address,
|
||||
"error": str(e),
|
||||
}
|
||||
finally:
|
||||
ssh.close()
|
||||
|
||||
def batch_provision(self, device_ids: list) -> Dict[str, any]:
|
||||
results = []
|
||||
success_count = 0
|
||||
fail_count = 0
|
||||
for device_id in device_ids:
|
||||
result = self.provision_device(device_id)
|
||||
results.append(result)
|
||||
if result.get("success"):
|
||||
success_count += 1
|
||||
else:
|
||||
fail_count += 1
|
||||
return {
|
||||
"total": len(device_ids),
|
||||
"success": success_count,
|
||||
"failed": fail_count,
|
||||
"results": results,
|
||||
}
|
||||
Reference in New Issue
Block a user