修改(存在未调用库error)

This commit is contained in:
3 2025-05-26 18:29:25 +08:00
parent 628726e6b1
commit 495ec0df40
8 changed files with 204 additions and 2 deletions

View File

@ -0,0 +1,26 @@
FROM python:3.13.2-slim
WORKDIR /app
# 安装系统依赖
RUN apt-get update && \
apt-get install -y --no-install-recommends gcc python3-dev libffi-dev && \
rm -rf /var/lib/apt/lists/*
# 安装Python依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY . .
# 设置环境变量
ENV FLASK_APP=run.py
ENV FLASK_ENV=production
ENV PYTHONPATH=/app
# 暴露端口
EXPOSE 5000
# 启动命令
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "run:app"]

View File

@ -1 +1,26 @@
# 解析中文命令逻辑
from flask import request, jsonify
from ...services.ai_service import get_network_config
from ...exceptions import InvalidInputError
@api_blueprint.route('/parse_command', methods=['POST'])
def parse_command_handler():
"""处理自然语言命令解析"""
try:
data = request.get_json()
if not data or 'command' not in data:
raise InvalidInputError("缺少命令参数")
command = data['command']
config = get_network_config(command)
return jsonify({
"status": "success",
"config": config
})
except InvalidInputError as e:
return jsonify({"status": "error", "message": str(e)}), 400
except Exception as e:
return jsonify({"status": "error", "message": f"服务器内部错误: {str(e)}"}), 500

View File

@ -1 +1,6 @@
# 注册api蓝图
# 注册api蓝图
from flask import Blueprint
api_blueprint = Blueprint('api', __name__)
from . import command_parser, network_config

View File

@ -1 +1,64 @@
#配置生成和交换机交互逻辑
from flask import request, jsonify
from netmiko import ConnectHandler
from ...config import Config
from ...exceptions import NetworkDeviceError
@api_blueprint.route('/apply_config', methods=['POST'])
def apply_config_handler():
"""应用配置到网络设备"""
try:
data = request.get_json()
required_fields = ['config', 'device_ip']
if not all(field in data for field in required_fields):
raise InvalidInputError("缺少必要参数")
# 安全验证
validate_configuration(data['config'])
# 执行配置
output = execute_switch_config(
device_ip=data['device_ip'],
commands=data['config'],
username=Config.SWITCH_USERNAME,
password=Config.SWITCH_PASSWORD
)
return jsonify({
"status": "success",
"output": output
})
except NetworkDeviceError as e:
return jsonify({"status": "error", "message": str(e)}), 502
except Exception as e:
return jsonify({"status": "error", "message": str(e)}), 500
def validate_configuration(commands):
"""配置安全验证"""
dangerous_commands = ['delete', 'erase', 'format', 'reload']
for cmd in dangerous_commands:
if any(cmd in line.lower() for line in commands):
raise InvalidInputError(f"检测到危险命令: {cmd}")
def execute_switch_config(device_ip, commands, username, password):
"""执行交换机配置"""
device = {
'device_type': 'cisco_ios',
'host': device_ip,
'username': username,
'password': password,
'timeout': 10
}
try:
with ConnectHandler(**device) as conn:
conn.enable() # 进入特权模式
output = conn.send_config_set(commands)
conn.save_config() # 保存配置
return output
except Exception as e:
raise NetworkDeviceError(f"设备配置失败: {str(e)}")

View File

@ -1,12 +1,17 @@
from flask import Flask
from .api import api_blueprint
from flask_cors import CORS
def create_app():
app = Flask(__name__)
app.config.from_object('config.Config')
# 启用CORS开发环境
CORS(app, resources={r"/api/*": {"origins": "*"}})
# 注册蓝图
from .api import api_blueprint
app.register_blueprint(api_blueprint, url_prefix='/api')
return app

View File

@ -0,0 +1,61 @@
# 调用api
import requests
import json
from ...config import Config
from ...exceptions import AIServiceError
def get_network_config(command: str) -> list:
"""调用AI服务生成配置"""
headers = {
"Authorization": f"Bearer {Config.AI_API_KEY}",
"Content-Type": "application/json"
}
payload = {
"command": command,
"vendor": "cisco",
"strict_mode": True
}
try:
response = requests.post(
Config.AI_API_ENDPOINT,
headers=headers,
json=payload,
timeout=8
)
response.raise_for_status()
result = response.json()
if not result.get('success'):
raise AIServiceError(result.get('message', 'AI服务返回错误'))
return result['config']
except requests.exceptions.Timeout:
raise AIServiceError("AI服务响应超时")
except requests.exceptions.RequestException as e:
raise AIServiceError(f"API请求失败: {str(e)}")
# --------------- backend/config.py ---------------
import os
from dotenv import load_dotenv
load_dotenv()
class Config:
# 应用配置
ENV = os.getenv("FLASK_ENV", "production")
SECRET_KEY = os.getenv("SECRET_KEY", "supersecretkey")
# AI服务配置
AI_API_KEY = os.getenv("AI_API_KEY", "")
AI_API_ENDPOINT = os.getenv("AI_API_ENDPOINT", "https://api.siliconflow.ai/v1/network")
# 网络设备配置
SWITCH_USERNAME = os.getenv("SWITCH_USER", "admin")
SWITCH_PASSWORD = os.getenv("SWITCH_PASS", "Cisco123!")
DEFAULT_DEVICE_IP = os.getenv("DEFAULT_DEVICE_IP", "192.168.1.1")

11
src/backend/exceptions.py Normal file
View File

@ -0,0 +1,11 @@
class InvalidInputError(Exception):
"""输入验证异常"""
pass
class NetworkDeviceError(Exception):
"""网络设备通信异常"""
pass
class AIServiceError(Exception):
"""AI服务异常"""
pass

View File

@ -0,0 +1,6 @@
from app import create_app
app = create_app()
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)