删掉一些东西

This commit is contained in:
Jerry 2025-08-12 00:30:15 +08:00
parent 0b6b9624a6
commit d77a0dacad
4 changed files with 8 additions and 295 deletions

View File

@ -1,29 +1,17 @@
import socket import socket
from datetime import datetime, timedelta from fastapi import (APIRouter, HTTPException, Response)
from fastapi import (APIRouter, HTTPException, Response, WebSocket, WebSocketDisconnect)
from typing import List from typing import List
from pydantic import BaseModel from pydantic import BaseModel
import asyncio
from fastapi.responses import HTMLResponse from fastapi.responses import HTMLResponse
import matplotlib.pyplot as plt
import io
import base64
import psutil import psutil
import ipaddress import ipaddress
from ..services.switch_traffic_monitor import get_switch_monitor
from ..utils import logger
from ...app.services.ai_services import AIService from ...app.services.ai_services import AIService
from ...app.api.network_config import SwitchConfigurator from ...app.api.network_config import SwitchConfigurator
from ...config import settings from ...config import settings
from ..services.network_scanner import NetworkScanner from ..services.network_scanner import NetworkScanner
from ...app.services.traffic_monitor import traffic_monitor
from ...app.models.traffic_models import TrafficRecord, SwitchTrafficRecord
from src.backend.app.api.database import SessionLocal
from ..services.network_visualizer import NetworkVisualizer from ..services.network_visualizer import NetworkVisualizer
from ..services.config_validator import ConfigValidator from ..services.config_validator import ConfigValidator
from ..services.report_generator import ReportGenerator from ..services.report_generator import ReportGenerator
from fastapi.responses import JSONResponse
@ -59,22 +47,6 @@ class BatchConfigRequest(BaseModel):
password: str = None password: str = None
timeout: int = None timeout: int = None
@router.post("/batch_apply_config")
async def batch_apply_config(request: BatchConfigRequest):
results = {}
for ip in request.switch_ips:
try:
configurator = SwitchConfigurator(
username=request.username,
password=request.password,
timeout=request.timeout )
results[ip] = await configurator.apply_config(ip, request.config)
except Exception as e:
results[ip] = str(e)
return {"results": results}
@router.get("/test") @router.get("/test")
async def test_endpoint(): async def test_endpoint():
return {"message": "Hello World"} return {"message": "Hello World"}
@ -196,47 +168,6 @@ async def execute_cli_commands(request: CLICommandRequest):
except Exception as e: except Exception as e:
raise HTTPException(500, detail=str(e)) raise HTTPException(500, detail=str(e))
@router.get("/traffic/interfaces", summary="获取所有网络接口")
async def get_network_interfaces():
return {
"interfaces": traffic_monitor.get_interfaces()
}
@router.get("/traffic/current", summary="获取当前流量数据")
async def get_current_traffic(interface: str = None):
return traffic_monitor.get_current_traffic(interface)
@router.get("/traffic/history", summary="获取流量历史数据")
async def get_traffic_history(interface: str = None, limit: int = 100):
history = traffic_monitor.get_traffic_history(interface)
return {
"sent": history["sent"][-limit:],
"recv": history["recv"][-limit:],
"time": [t.isoformat() for t in history["time"]][-limit:]
}
@router.get("/traffic/records", summary="获取流量记录")
async def get_traffic_records(interface: str = None, limit: int = 100):
with SessionLocal() as session:
query = session.query(TrafficRecord)
if interface:
query = query.filter(TrafficRecord.interface == interface)
records = query.order_by(TrafficRecord.timestamp.desc()).limit(limit).all()
return [record.to_dict() for record in records]
@router.websocket("/ws/traffic")
async def websocket_traffic(websocket: WebSocket):
"""实时流量WebSocket"""
await websocket.accept()
try:
while True:
traffic_data = traffic_monitor.get_current_traffic()
await websocket.send_json(traffic_data)
await asyncio.sleep(1)
except WebSocketDisconnect:
print("客户端断开连接")
@router.get("/", include_in_schema=False) @router.get("/", include_in_schema=False)
async def root(): async def root():
return { return {
@ -253,195 +184,6 @@ async def root():
"/traffic/switch/history" "/traffic/switch/history"
] ]
} }
@router.get("/traffic/switch/interfaces", summary="获取交换机的网络接口")
async def get_switch_interfaces(switch_ip: str):
"""获取指定交换机的所有接口"""
try:
monitor = get_switch_monitor(switch_ip)
interfaces = list(monitor.interface_oids.keys())
return {
"switch_ip": switch_ip,
"interfaces": interfaces
}
except Exception as e:
logger.error(f"获取交换机接口失败: {str(e)}")
raise HTTPException(500, f"获取接口失败: {str(e)}")
@router.get("/traffic/switch/current", summary="获取交换机的当前流量数据")
async def get_switch_current_traffic(switch_ip: str, interface: str = None):
"""获取交换机的当前流量数据"""
try:
monitor = get_switch_monitor(switch_ip)
if not interface:
traffic_data = {}
for iface in monitor.interface_oids:
traffic_data[iface] = await get_interface_current_traffic(switch_ip, iface)
return {
"switch_ip": switch_ip,
"traffic": traffic_data
}
return await get_interface_current_traffic(switch_ip, interface)
except Exception as e:
logger.error(f"获取交换机流量失败: {str(e)}")
raise HTTPException(500, f"获取流量失败: {str(e)}")
async def get_interface_current_traffic(switch_ip: str, interface: str) -> dict:
"""获取指定交换机接口的当前流量数据"""
try:
with SessionLocal() as session:
record = session.query(SwitchTrafficRecord).filter(
SwitchTrafficRecord.switch_ip == switch_ip,
SwitchTrafficRecord.interface == interface
).order_by(SwitchTrafficRecord.timestamp.desc()).first()
if not record:
return {
"switch_ip": switch_ip,
"interface": interface,
"rate_in": 0.0,
"rate_out": 0.0,
"bytes_in": 0,
"bytes_out": 0
}
return {
"switch_ip": switch_ip,
"interface": interface,
"rate_in": record.rate_in,
"rate_out": record.rate_out,
"bytes_in": record.bytes_in,
"bytes_out": record.bytes_out
}
except Exception as e:
logger.error(f"获取接口流量失败: {str(e)}")
raise HTTPException(500, f"获取接口流量失败: {str(e)}")
@router.get("/traffic/switch/history", summary="获取交换机的流量历史数据")
async def get_switch_traffic_history(switch_ip: str, interface: str = None, minutes: int = 10):
"""获取交换机的流量历史数据"""
try:
monitor = get_switch_monitor(switch_ip)
if not interface:
return {
"switch_ip": switch_ip,
"history": monitor.get_traffic_history()
}
with SessionLocal() as session:
time_threshold = datetime.now() - timedelta(minutes=minutes)
records = session.query(SwitchTrafficRecord).filter(
SwitchTrafficRecord.switch_ip == switch_ip,
SwitchTrafficRecord.interface == interface,
SwitchTrafficRecord.timestamp >= time_threshold
).order_by(SwitchTrafficRecord.timestamp.asc()).all()
history_data = {
"in": [record.rate_in for record in records],
"out": [record.rate_out for record in records],
"time": [record.timestamp.isoformat() for record in records]
}
return {
"switch_ip": switch_ip,
"interface": interface,
"history": history_data
}
except Exception as e:
logger.error(f"获取历史流量失败: {str(e)}")
raise HTTPException(500, f"获取历史流量失败: {str(e)}")
@router.websocket("/ws/traffic/switch")
async def websocket_switch_traffic(websocket: WebSocket, switch_ip: str, interface: str = None):
"""交换机实时流量WebSocket"""
await websocket.accept()
try:
monitor = get_switch_monitor(switch_ip)
while True:
if interface:
traffic_data = await get_interface_current_traffic(switch_ip, interface)
await websocket.send_json(traffic_data)
else:
traffic_data = {}
for iface in monitor.interface_oids:
traffic_data[iface] = await get_interface_current_traffic(switch_ip, iface)
await websocket.send_json({
"switch_ip": switch_ip,
"traffic": traffic_data
})
await asyncio.sleep(1)
except WebSocketDisconnect:
logger.info(f"客户端断开交换机流量连接: {switch_ip}")
except Exception as e:
logger.error(f"交换机流量WebSocket错误: {str(e)}")
await websocket.close(code=1011, reason=str(e))
@router.get("/traffic/switch/plot", response_class=HTMLResponse, summary="交换机流量可视化")
async def plot_switch_traffic(switch_ip: str, interface: str, minutes: int = 10):
"""生成交换机流量图表"""
try:
history = await get_switch_traffic_history(switch_ip, interface, minutes)
history_data = history["history"]
time_points = [datetime.fromisoformat(t) for t in history_data["time"]]
in_rates = history_data["in"]
out_rates = history_data["out"]
plt.figure(figsize=(12, 6))
plt.plot(time_points, in_rates, label="流入流量 (B/s)")
plt.plot(time_points, out_rates, label="流出流量 (B/s)")
plt.title(f"交换机 {switch_ip} 接口 {interface} 流量监控 - 最近 {minutes} 分钟")
plt.xlabel("时间")
plt.ylabel("流量 (字节/秒)")
plt.legend()
plt.grid(True)
plt.xticks(rotation=45)
plt.tight_layout()
buf = io.BytesIO()
plt.savefig(buf, format="png")
buf.seek(0)
image_base64 = base64.b64encode(buf.read()).decode("utf-8")
plt.close()
return f"""
<html>
<head>
<title>交换机流量监控</title>
<style>
body {{ font-family: Arial, sans-serif; margin: 20px; }}
.container {{ max-width: 900px; margin: 0 auto; }}
</style>
</head>
<body>
<div class="container">
<h1>交换机 {switch_ip} 接口 {interface} 流量监控</h1>
<img src="data:image/png;base64,{image_base64}" alt="流量图表">
<p>更新时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
</div>
</body>
</html>
"""
except Exception as e:
logger.error(f"生成流量图表失败: {str(e)}")
return HTMLResponse(content=f"<h1>错误</h1><p>{str(e)}</p>", status_code=500)
@router.get("/network_adapters", summary="获取网络适配器网段") @router.get("/network_adapters", summary="获取网络适配器网段")
async def get_network_adapters(): async def get_network_adapters():
try: try:
@ -475,7 +217,7 @@ report_gen = ReportGenerator()
async def visualize_topology(): async def visualize_topology():
"""获取网络拓扑可视化图""" """获取网络拓扑可视化图"""
try: try:
devices = await list_devices() # 复用现有的设备列表接口 devices = await list_devices()
visualizer.update_topology(devices["devices"]) visualizer.update_topology(devices["devices"])
image_data = visualizer.generate_topology_image() image_data = visualizer.generate_topology_image()
@ -500,34 +242,4 @@ async def validate_config(config: dict):
"valid": is_valid, "valid": is_valid,
"errors": errors, "errors": errors,
"has_security_risks": len(ConfigValidator.check_security_risks(config.get("commands", []))) > 0 "has_security_risks": len(ConfigValidator.check_security_risks(config.get("commands", []))) > 0
} }
@router.get("/reports/traffic/{ip}")
async def get_traffic_report(ip: str, days: int = 1):
"""获取流量分析报告"""
try:
report = report_gen.generate_traffic_report(ip, days)
return JSONResponse(content=report)
except Exception as e:
raise HTTPException(500, detail=str(e))
@router.get("/reports/traffic")
async def get_local_traffic_report(days: int = 1):
"""获取本地网络流量报告"""
try:
report = report_gen.generate_traffic_report(days=days)
return JSONResponse(content=report)
except Exception as e:
raise HTTPException(500, detail=str(e))
@router.get("/topology/traffic_heatmap")
async def get_traffic_heatmap(minutes: int = 10):
"""获取流量热力图数据"""
try:
heatmap = visualizer.get_traffic_heatmap(minutes)
return {"heatmap": heatmap}
except Exception as e:
raise HTTPException(500, detail=str(e))

View File

@ -42,7 +42,7 @@ class AIService:
] ]
try: try:
response = await self.client.chat.completions.create( response = self.client.chat.completions.create(
model="deepseek-ai/DeepSeek-V3", model="deepseek-ai/DeepSeek-V3",
messages=messages, messages=messages,
temperature=0.3, temperature=0.3,

View File

@ -15,7 +15,7 @@ class NetworkScanner:
devices = [] devices = []
try: try:
self.nm.scan(hosts=subnet, arguments=f'-p {",".join(map(str, ports))}') await self.nm.scan(hosts=subnet, arguments=f'-p {",".join(map(str, ports))}')
for host in self.nm.all_hosts(): for host in self.nm.all_hosts():
ip = host ip = host
mac = self.nm[host]['addresses'].get('mac', 'N/A') mac = self.nm[host]['addresses'].get('mac', 'N/A')

View File

@ -8,6 +8,7 @@ from typing import Dict, Optional, List
from ..models.traffic_models import TrafficRecord from ..models.traffic_models import TrafficRecord
from src.backend.app.api.database import SessionLocal from src.backend.app.api.database import SessionLocal
from ..utils.logger import logger
class TrafficMonitor: class TrafficMonitor:
@ -33,7 +34,7 @@ class TrafficMonitor:
if not self.running: if not self.running:
self.running = True self.running = True
self.task = asyncio.create_task(self._monitor_loop()) self.task = asyncio.create_task(self._monitor_loop())
print("流量监控已启动") logger.info("流量监控已启动")
async def stop_monitoring(self): async def stop_monitoring(self):
"""停止流量监控""" """停止流量监控"""
@ -44,7 +45,7 @@ class TrafficMonitor:
await self.task await self.task
except asyncio.CancelledError: except asyncio.CancelledError:
pass pass
print("流量监控已停止") logger.info("流量监控已停止")
async def _monitor_loop(self): async def _monitor_loop(self):
"""监控主循环""" """监控主循环"""