mirror of
https://github.com/Jerryplusy/AI-powered-switches.git
synced 2025-10-14 09:49:19 +00:00
修改
This commit is contained in:
parent
a57e4d4b46
commit
7030adb81c
@ -50,13 +50,19 @@ async def favicon():
|
|||||||
class BatchConfigRequest(BaseModel):
|
class BatchConfigRequest(BaseModel):
|
||||||
config: dict
|
config: dict
|
||||||
switch_ips: List[str] # 支持多个IP
|
switch_ips: List[str] # 支持多个IP
|
||||||
|
username: str = None # 添加用户名参数
|
||||||
|
password: str = None # 添加密码参数
|
||||||
|
timeout: int = None
|
||||||
|
|
||||||
@router.post("/batch_apply_config")
|
@router.post("/batch_apply_config")
|
||||||
async def batch_apply_config(request: BatchConfigRequest):
|
async def batch_apply_config(request: BatchConfigRequest):
|
||||||
results = {}
|
results = {}
|
||||||
for ip in request.switch_ips:
|
for ip in request.switch_ips:
|
||||||
try:
|
try:
|
||||||
configurator = SwitchConfigurator()
|
configurator = SwitchConfigurator(
|
||||||
|
username=request.username,
|
||||||
|
password=request.password,
|
||||||
|
timeout=request.timeout )
|
||||||
results[ip] = await configurator.apply_config(ip, request.config)
|
results[ip] = await configurator.apply_config(ip, request.config)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
results[ip] = str(e)
|
results[ip] = str(e)
|
||||||
@ -92,6 +98,9 @@ class CommandRequest(BaseModel):
|
|||||||
class ConfigRequest(BaseModel):
|
class ConfigRequest(BaseModel):
|
||||||
config: dict
|
config: dict
|
||||||
switch_ip: str
|
switch_ip: str
|
||||||
|
username: str = None
|
||||||
|
password: str = None
|
||||||
|
timeout: int = None
|
||||||
|
|
||||||
@router.post("/parse_command", response_model=dict)
|
@router.post("/parse_command", response_model=dict)
|
||||||
async def parse_command(request: CommandRequest):
|
async def parse_command(request: CommandRequest):
|
||||||
@ -115,9 +124,9 @@ async def apply_config(request: ConfigRequest):
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
configurator = SwitchConfigurator(
|
configurator = SwitchConfigurator(
|
||||||
username=settings.SWITCH_USERNAME,
|
username=request.username,
|
||||||
password=settings.SWITCH_PASSWORD,
|
password=request.password,
|
||||||
timeout=settings.SWITCH_TIMEOUT
|
timeout=request.timeout
|
||||||
)
|
)
|
||||||
result = await configurator.safe_apply(request.switch_ip, request.config)
|
result = await configurator.safe_apply(request.switch_ip, request.config)
|
||||||
return {"success": True, "result": result}
|
return {"success": True, "result": result}
|
||||||
@ -133,16 +142,40 @@ class CLICommandRequest(BaseModel):
|
|||||||
commands: List[str] # 前端生成的CLI命令列表
|
commands: List[str] # 前端生成的CLI命令列表
|
||||||
is_ensp: bool = False # 是否为eNSP模拟器模式
|
is_ensp: bool = False # 是否为eNSP模拟器模式
|
||||||
|
|
||||||
|
# 添加方法从commands中提取凭据
|
||||||
|
def extract_credentials(self) -> tuple:
|
||||||
|
"""从commands中提取用户名和密码"""
|
||||||
|
username = None
|
||||||
|
password = None
|
||||||
|
|
||||||
|
for cmd in self.commands:
|
||||||
|
if cmd.startswith("!username="):
|
||||||
|
username = cmd.split("=")[1]
|
||||||
|
elif cmd.startswith("!password="):
|
||||||
|
password = cmd.split("=")[1]
|
||||||
|
|
||||||
|
return username, password
|
||||||
|
|
||||||
|
def get_clean_commands(self) -> List[str]:
|
||||||
|
"""获取去除凭据后的实际命令"""
|
||||||
|
return [cmd for cmd in self.commands
|
||||||
|
if not (cmd.startswith("!username=") or cmd.startswith("!password="))]
|
||||||
|
|
||||||
@router.post("/execute_cli_commands", response_model=dict)
|
@router.post("/execute_cli_commands", response_model=dict)
|
||||||
async def execute_cli_commands(request: CLICommandRequest):
|
async def execute_cli_commands(request: CLICommandRequest):
|
||||||
"""
|
"""
|
||||||
执行前端生成的CLI命令
|
执行前端生成的CLI命令
|
||||||
|
支持在commands中嵌入凭据:
|
||||||
|
!username=admin
|
||||||
|
!password=cisco123
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
username, password = request.extract_credentials()
|
||||||
|
clean_commands = request.get_clean_commands()
|
||||||
|
|
||||||
configurator = SwitchConfigurator(
|
configurator = SwitchConfigurator(
|
||||||
username=settings.SWITCH_USERNAME,
|
username=username,
|
||||||
password=settings.SWITCH_PASSWORD,
|
password=password,
|
||||||
timeout=settings.SWITCH_TIMEOUT,
|
timeout=settings.SWITCH_TIMEOUT,
|
||||||
ensp_mode=request.is_ensp
|
ensp_mode=request.is_ensp
|
||||||
)
|
)
|
||||||
@ -220,7 +253,7 @@ async def root():
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# ... 其他路由保持不变 ...
|
|
||||||
|
|
||||||
@router.get("/traffic/switch/interfaces", summary="获取交换机的网络接口")
|
@router.get("/traffic/switch/interfaces", summary="获取交换机的网络接口")
|
||||||
async def get_switch_interfaces(switch_ip: str):
|
async def get_switch_interfaces(switch_ip: str):
|
||||||
|
@ -10,6 +10,8 @@ import asyncssh
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from tenacity import retry, stop_after_attempt, wait_exponential
|
from tenacity import retry, stop_after_attempt, wait_exponential
|
||||||
|
|
||||||
|
from src.backend.config import settings
|
||||||
|
|
||||||
|
|
||||||
# ----------------------
|
# ----------------------
|
||||||
# 数据模型
|
# 数据模型
|
||||||
@ -44,18 +46,18 @@ class SSHConnectionException(SwitchConfigException):
|
|||||||
class SwitchConfigurator:
|
class SwitchConfigurator:
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
username: str = "admin",
|
username: str = None,
|
||||||
password: str = "admin",
|
password: str = None,
|
||||||
timeout: int = 10,
|
timeout: int = None,
|
||||||
max_workers: int = 5,
|
max_workers: int = 5,
|
||||||
ensp_mode: bool = False,
|
ensp_mode: bool = False,
|
||||||
ensp_port: int = 2000,
|
ensp_port: int = 2000,
|
||||||
ensp_command_delay: float = 0.5,
|
ensp_command_delay: float = 0.5,
|
||||||
**ssh_options
|
**ssh_options
|
||||||
):
|
):
|
||||||
self.username = username
|
self.username = username if username is not None else settings.SWITCH_USERNAME
|
||||||
self.password = password
|
self.password = password if password is not None else settings.SWITCH_PASSWORD
|
||||||
self.timeout = timeout
|
self.timeout = timeout if timeout is not None else settings.SWITCH_TIMEOUT
|
||||||
self.semaphore = asyncio.Semaphore(max_workers)
|
self.semaphore = asyncio.Semaphore(max_workers)
|
||||||
self.backup_dir = Path("config_backups")
|
self.backup_dir = Path("config_backups")
|
||||||
self.backup_dir.mkdir(exist_ok=True)
|
self.backup_dir.mkdir(exist_ok=True)
|
||||||
|
@ -16,6 +16,8 @@ class Settings(BaseSettings):
|
|||||||
SILICONFLOW_API_URL: str = os.getenv("SILICONFLOW_API_URL", "https://api.siliconflow.cn/v1")
|
SILICONFLOW_API_URL: str = os.getenv("SILICONFLOW_API_URL", "https://api.siliconflow.cn/v1")
|
||||||
|
|
||||||
# 交换机配置
|
# 交换机配置
|
||||||
|
SWITCH_USERNAME: str = os.getenv("SWITCH_USERNAME", "admin")
|
||||||
|
SWITCH_PASSWORD: str = os.getenv("SWITCH_PASSWORD", "admin")
|
||||||
SWITCH_TIMEOUT: int = os.getenv("SWITCH_TIMEOUT", 10)
|
SWITCH_TIMEOUT: int = os.getenv("SWITCH_TIMEOUT", 10)
|
||||||
|
|
||||||
# eNSP配置
|
# eNSP配置
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
fastapi==0.110.0
|
fastapi==0.110.0
|
||||||
uvicorn==0.29.0
|
uvicorn==0.29.0
|
||||||
python-dotenv==1.0.1
|
python-dotenv==1.0.1
|
||||||
pysnmp
|
|
||||||
pydantic==2.6.4
|
pydantic==2.6.4
|
||||||
pydantic-settings==2.2.1
|
pydantic-settings==2.2.1
|
||||||
openai==1.93.2
|
openai==1.93.2
|
||||||
|
Loading…
x
Reference in New Issue
Block a user