From 31a864b0b065de85f66442dce6c24a4067cde39b Mon Sep 17 00:00:00 2001 From: 3 Date: Tue, 10 Jun 2025 18:42:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9F=BA=E7=A1=80api=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E5=8F=AF=E8=BF=9B=E8=A1=8C,=E5=8F=AF=E6=89=AB=E6=8F=8F?= =?UTF-8?q?=E7=BD=91=E7=BB=9C=E4=BA=A4=E6=8D=A2=E6=9C=BA(=E5=B7=B2?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=9B=B8=E5=85=B3=E9=97=AE=E9=A2=98=EF=BC=8C?= =?UTF-8?q?=E6=B3=A8=E6=84=8F=E4=B8=8B=E8=BD=BDNmap=E6=89=8D=E5=8F=AF?= =?UTF-8?q?=E6=89=AB=E6=8F=8F=E4=BA=A4=E6=8D=A2=E6=9C=BA=E7=BD=91=E5=9D=80?= =?UTF-8?q?=EF=BC=9Ahttps://nmap.org/download.html=EF=BC=89,=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E4=BA=86=E9=85=8D=E7=BD=AE=E5=A4=9A=E5=8F=B0=E4=BA=A4?= =?UTF-8?q?=E6=8D=A2=E6=9C=BA=E7=9A=84=E5=8A=9F=E8=83=BD,ensp=E9=85=8D?= =?UTF-8?q?=E7=BD=AE.=E9=9C=80=E7=94=A8=E5=AE=9E=E9=99=85=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E8=BF=9B=E4=B8=80=E6=AD=A5=E8=B0=83=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/README.md | 2 +- src/backend/app/api/endpoints.py | 5 +++-- src/backend/app/api/network_config.py | 4 ++++ src/backend/app/utils/exceptions.py | 30 ++++++++++++++++++++------- src/backend/requirements.txt | 3 ++- switch_devices.json | 1 + 6 files changed, 33 insertions(+), 12 deletions(-) create mode 100644 switch_devices.json diff --git a/src/backend/README.md b/src/backend/README.md index cc340a6..0a34790 100644 --- a/src/backend/README.md +++ b/src/backend/README.md @@ -1,7 +1,7 @@ # AI-powered-switches Backend 这是 AI-powered-switches 的后端服务,基于 `Flask` 构建,提供 `REST API` 接口,用于解析自然语言生成网络交换机配置并下发到设备 - +注意下载Nmap才可扫描交换机网址:https://nmap.org/download.html ### 项目结构 ```bash diff --git a/src/backend/app/api/endpoints.py b/src/backend/app/api/endpoints.py index c5d3678..917bb2a 100644 --- a/src/backend/app/api/endpoints.py +++ b/src/backend/app/api/endpoints.py @@ -1,4 +1,4 @@ -from fastapi import APIRouter, Depends, HTTPException +from fastapi import (APIRouter, HTTPException) from typing import List from pydantic import BaseModel @@ -86,4 +86,5 @@ async def apply_config(request: ConfigRequest): raise HTTPException( status_code=500, detail=f"Failed to apply config: {str(e)}" - ) \ No newline at end of file + ) + diff --git a/src/backend/app/api/network_config.py b/src/backend/app/api/network_config.py index 3f791c2..ebc1b82 100644 --- a/src/backend/app/api/network_config.py +++ b/src/backend/app/api/network_config.py @@ -1,8 +1,11 @@ import paramiko import asyncio +import aiofiles +from datetime import datetime from typing import Dict, List, Optional, Union from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type from pydantic import BaseModel +from paramiko.channel import ChannelFile import logging @@ -41,6 +44,7 @@ class SwitchConfigurator: is_emulated: bool = False, emulated_delay: float = 2.0 ): + """ 初始化配置器 diff --git a/src/backend/app/utils/exceptions.py b/src/backend/app/utils/exceptions.py index 4108d08..ccbd2de 100644 --- a/src/backend/app/utils/exceptions.py +++ b/src/backend/app/utils/exceptions.py @@ -1,4 +1,5 @@ from fastapi import HTTPException, status +from typing import Optional class AICommandParseException(HTTPException): def __init__(self, detail: str): @@ -8,15 +9,28 @@ class AICommandParseException(HTTPException): ) class SwitchConfigException(HTTPException): - def __init__(self, detail: str): + def __init__( + self, + detail: str, + status_code: int = status.HTTP_500_INTERNAL_SERVER_ERROR + ): super().__init__( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail=f"Switch configuration error: {detail}" + status_code=status_code, + detail=f"Switch error: {detail}" ) -class SiliconFlowAPIException(HTTPException): - def __init__(self, detail: str): +class ConfigBackupException(SwitchConfigException): + """配置备份失败异常""" + def __init__(self, ip: str): super().__init__( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail=f"SiliconFlow API error: {detail}" - ) \ No newline at end of file + detail=f"无法备份设备 {ip} 的配置", + recovery_guide="检查设备存储空间或权限" + ) + +class ConfigRollbackException(SwitchConfigException): + """回滚失败异常""" + def __init__(self, ip: str, original_error: str): + super().__init__( + detail=f"设备 {ip} 回滚失败(原始错误:{original_error})", + status_code=status.HTTP_422_UNPROCESSABLE_ENTITY + ) diff --git a/src/backend/requirements.txt b/src/backend/requirements.txt index 4ca45f3..916c9ce 100644 --- a/src/backend/requirements.txt +++ b/src/backend/requirements.txt @@ -7,4 +7,5 @@ pydantic>=1.10.7 loguru>=0.7.0 python-nmap>=0.7.1 tenacity>=9.1.2 -typing-extensions>=4.0.0 \ No newline at end of file +typing-extensions>=4.0.0 +aiofiles>=24.1.0 \ No newline at end of file diff --git a/switch_devices.json b/switch_devices.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/switch_devices.json @@ -0,0 +1 @@ +[] \ No newline at end of file