mirror of
https://github.com/Jerryplusy/AI-powered-switches.git
synced 2025-07-04 13:19:20 +00:00
修改(存在未调用库error)
This commit is contained in:
parent
628726e6b1
commit
495ec0df40
26
src/backend/Dockerfile/Dockerfile
Normal file
26
src/backend/Dockerfile/Dockerfile
Normal 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"]
|
@ -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
|
@ -1 +1,6 @@
|
||||
# 注册api蓝图
|
||||
# 注册api蓝图
|
||||
from flask import Blueprint
|
||||
|
||||
api_blueprint = Blueprint('api', __name__)
|
||||
|
||||
from . import command_parser, network_config
|
@ -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)}")
|
@ -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
|
61
src/backend/app/services/ai_services.py
Normal file
61
src/backend/app/services/ai_services.py
Normal 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
11
src/backend/exceptions.py
Normal file
@ -0,0 +1,11 @@
|
||||
class InvalidInputError(Exception):
|
||||
"""输入验证异常"""
|
||||
pass
|
||||
|
||||
class NetworkDeviceError(Exception):
|
||||
"""网络设备通信异常"""
|
||||
pass
|
||||
|
||||
class AIServiceError(Exception):
|
||||
"""AI服务异常"""
|
||||
pass
|
@ -0,0 +1,6 @@
|
||||
from app import create_app
|
||||
|
||||
app = create_app()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host="0.0.0.0", port=5000)
|
Loading…
x
Reference in New Issue
Block a user