feat: 多主机纳管、用户认证、noVNC控制台、深色主题
主要功能: - 多主机管理: 支持TCP/SSH方式纳管远程KVM主机 - 用户认证: JWT token认证, 默认admin/admin123 - noVNC控制台: 前端集成noVNC, WebSocket代理VNC连接 - 深色主题: 全局Element Plus深色主题覆盖 - 虚拟机操作: 克隆、迁移、XML编辑、快照管理 - 资源监控: CPU/内存/磁盘IO/网络流量实时监控 Bug修复: - libvirt getInfo()内存单位修正(MiB非KiB) - 远程主机VNC 0.0.0.0监听地址连接策略修复 - Dashboard定时器内存泄漏修复 - bcrypt版本兼容性修复
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
"""网络管理路由"""
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from fastapi import APIRouter, HTTPException, Query
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional, List
|
||||
from lxml import etree
|
||||
|
||||
from app.libvirt_conn import libvirt_conn
|
||||
from app.libvirt_conn import conn_pool
|
||||
import libvirt
|
||||
|
||||
router = APIRouter()
|
||||
@@ -20,15 +20,14 @@ class NetworkCreate(BaseModel):
|
||||
|
||||
|
||||
@router.get("/list")
|
||||
async def list_networks():
|
||||
async def list_networks(host_id: str = Query("local")):
|
||||
"""列出所有网络"""
|
||||
conn = libvirt_conn.conn
|
||||
conn = conn_pool.get_conn(host_id)
|
||||
networks = conn.listAllNetworks(0)
|
||||
result = []
|
||||
for net in networks:
|
||||
xml = etree.fromstring(net.XMLDesc(0).encode())
|
||||
|
||||
# 解析网络信息
|
||||
forward = xml.find("forward")
|
||||
mode = forward.get("mode", "isolated") if forward is not None else "isolated"
|
||||
|
||||
@@ -39,18 +38,13 @@ async def list_networks():
|
||||
bridge = xml.find("bridge")
|
||||
bridge_name = bridge.get("name", "") if bridge is not None else ""
|
||||
|
||||
# DHCP范围
|
||||
dhcp_range = None
|
||||
dhcp = xml.find(".//dhcp")
|
||||
if dhcp is not None:
|
||||
r = dhcp.find("range")
|
||||
if r is not None:
|
||||
dhcp_range = {
|
||||
"start": r.get("start", ""),
|
||||
"end": r.get("end", ""),
|
||||
}
|
||||
dhcp_range = {"start": r.get("start", ""), "end": r.get("end", "")}
|
||||
|
||||
# 活跃租约
|
||||
leases = []
|
||||
try:
|
||||
for lease in net.DHCPLeases():
|
||||
@@ -79,9 +73,9 @@ async def list_networks():
|
||||
|
||||
|
||||
@router.get("/detail/{name}")
|
||||
async def get_network(name: str):
|
||||
async def get_network(name: str, host_id: str = Query("local")):
|
||||
"""获取网络详情"""
|
||||
conn = libvirt_conn.conn
|
||||
conn = conn_pool.get_conn(host_id)
|
||||
try:
|
||||
net = conn.networkLookupByName(name)
|
||||
except libvirt.libvirtError:
|
||||
@@ -92,7 +86,7 @@ async def get_network(name: str):
|
||||
|
||||
|
||||
@router.post("/create")
|
||||
async def create_network(net: NetworkCreate):
|
||||
async def create_network(net: NetworkCreate, host_id: str = Query("local")):
|
||||
"""创建网络"""
|
||||
if net.mode == "bridge" and not net.bridge:
|
||||
raise HTTPException(status_code=400, detail="桥接模式必须指定桥接网卡")
|
||||
@@ -104,7 +98,6 @@ async def create_network(net: NetworkCreate):
|
||||
<bridge name='{net.bridge}'/>
|
||||
</network>"""
|
||||
else:
|
||||
# NAT或隔离模式
|
||||
import ipaddress
|
||||
network = ipaddress.ip_network(net.subnet, strict=False)
|
||||
gateway = str(network.network_address + 1)
|
||||
@@ -129,7 +122,7 @@ async def create_network(net: NetworkCreate):
|
||||
</ip>
|
||||
</network>"""
|
||||
|
||||
with libvirt_conn.get_rw() as rw_conn:
|
||||
with conn_pool.get_rw(host_id) as rw_conn:
|
||||
try:
|
||||
n = rw_conn.networkDefineXML(xml)
|
||||
n.setAutostart(1)
|
||||
@@ -140,9 +133,9 @@ async def create_network(net: NetworkCreate):
|
||||
|
||||
|
||||
@router.delete("/delete/{name}")
|
||||
async def delete_network(name: str):
|
||||
async def delete_network(name: str, host_id: str = Query("local")):
|
||||
"""删除网络"""
|
||||
with libvirt_conn.get_rw() as rw_conn:
|
||||
with conn_pool.get_rw(host_id) as rw_conn:
|
||||
try:
|
||||
net = rw_conn.networkLookupByName(name)
|
||||
except libvirt.libvirtError:
|
||||
@@ -155,9 +148,9 @@ async def delete_network(name: str):
|
||||
|
||||
|
||||
@router.post("/action/{name}")
|
||||
async def network_action(name: str, action: str):
|
||||
async def network_action(name: str, action: str, host_id: str = Query("local")):
|
||||
"""网络操作: start/stop"""
|
||||
with libvirt_conn.get_rw() as rw_conn:
|
||||
with conn_pool.get_rw(host_id) as rw_conn:
|
||||
try:
|
||||
net = rw_conn.networkLookupByName(name)
|
||||
except libvirt.libvirtError:
|
||||
|
||||
Reference in New Issue
Block a user