refact: use only server
This commit is contained in:
247
backend/app/api/hosts.py
Normal file
247
backend/app/api/hosts.py
Normal file
@@ -0,0 +1,247 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import List
|
||||
from app.database import get_db, ProxmoxHost
|
||||
from app.models.schemas import ProxmoxHost as ProxmoxHostSchema, ProxmoxHostCreate, ProxmoxVM
|
||||
from app.services.proxmox_host_service import ProxmoxHostService
|
||||
from app.services.logging_service import LoggingService
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@router.get("/", response_model=List[ProxmoxHostSchema])
|
||||
async def get_hosts(db: Session = Depends(get_db)):
|
||||
"""Get all Proxmox hosts"""
|
||||
hosts = db.query(ProxmoxHost).all()
|
||||
return hosts
|
||||
|
||||
@router.post("/", response_model=ProxmoxHostSchema)
|
||||
async def create_host(host: ProxmoxHostCreate, db: Session = Depends(get_db)):
|
||||
"""Create a new Proxmox host"""
|
||||
try:
|
||||
# Test Proxmox connection before creating
|
||||
temp_host = ProxmoxHost(**host.dict())
|
||||
host_service = ProxmoxHostService(temp_host)
|
||||
|
||||
if not await host_service.test_proxmox_connection():
|
||||
raise HTTPException(status_code=400, detail="Cannot connect to Proxmox host")
|
||||
|
||||
# Create the host in database
|
||||
db_host = ProxmoxHost(**host.dict())
|
||||
db.add(db_host)
|
||||
db.commit()
|
||||
db.refresh(db_host)
|
||||
|
||||
# Log host creation
|
||||
LoggingService.log_host_action(
|
||||
db=db,
|
||||
action="create",
|
||||
host_id=db_host.id,
|
||||
host_name=db_host.name,
|
||||
success=True,
|
||||
message=f"Proxmox host '{db_host.name}' created successfully"
|
||||
)
|
||||
|
||||
return db_host
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Error creating host: {str(e)}")
|
||||
|
||||
@router.get("/{host_id}", response_model=ProxmoxHostSchema)
|
||||
async def get_host(host_id: int, db: Session = Depends(get_db)):
|
||||
"""Get a specific Proxmox host"""
|
||||
host = db.query(ProxmoxHost).filter(ProxmoxHost.id == host_id).first()
|
||||
if not host:
|
||||
raise HTTPException(status_code=404, detail="Host not found")
|
||||
return host
|
||||
|
||||
@router.put("/{host_id}", response_model=ProxmoxHostSchema)
|
||||
async def update_host(host_id: int, host_update: ProxmoxHostCreate, db: Session = Depends(get_db)):
|
||||
"""Update a Proxmox host"""
|
||||
host = db.query(ProxmoxHost).filter(ProxmoxHost.id == host_id).first()
|
||||
if not host:
|
||||
raise HTTPException(status_code=404, detail="Host not found")
|
||||
|
||||
# Test new connection if Proxmox settings changed
|
||||
temp_host = ProxmoxHost(**host_update.dict(), id=host_id)
|
||||
host_service = ProxmoxHostService(temp_host)
|
||||
|
||||
if not await host_service.test_proxmox_connection():
|
||||
raise HTTPException(status_code=400, detail="Cannot connect to Proxmox with new settings")
|
||||
|
||||
old_name = host.name
|
||||
for key, value in host_update.dict().items():
|
||||
setattr(host, key, value)
|
||||
|
||||
db.commit()
|
||||
db.refresh(host)
|
||||
|
||||
# Log host update
|
||||
LoggingService.log_host_action(
|
||||
db=db,
|
||||
action="update",
|
||||
host_id=host.id,
|
||||
host_name=host.name,
|
||||
success=True,
|
||||
message=f"Proxmox host '{old_name}' updated successfully"
|
||||
)
|
||||
|
||||
return host
|
||||
|
||||
@router.delete("/{host_id}")
|
||||
async def delete_host(host_id: int, db: Session = Depends(get_db)):
|
||||
"""Delete a Proxmox host"""
|
||||
host = db.query(ProxmoxHost).filter(ProxmoxHost.id == host_id).first()
|
||||
if not host:
|
||||
raise HTTPException(status_code=404, detail="Host not found")
|
||||
|
||||
# Log host deletion before deleting
|
||||
LoggingService.log_host_action(
|
||||
db=db,
|
||||
action="delete",
|
||||
host_id=host.id,
|
||||
host_name=host.name,
|
||||
success=True,
|
||||
message=f"Proxmox host '{host.name}' deleted successfully"
|
||||
)
|
||||
|
||||
db.delete(host)
|
||||
db.commit()
|
||||
return {"message": "Host deleted successfully"}
|
||||
|
||||
@router.post("/{host_id}/wake")
|
||||
async def wake_host(host_id: int, db: Session = Depends(get_db)):
|
||||
"""Wake up a Proxmox host using Wake-on-LAN"""
|
||||
host = db.query(ProxmoxHost).filter(ProxmoxHost.id == host_id).first()
|
||||
if not host:
|
||||
raise HTTPException(status_code=404, detail="Host not found")
|
||||
|
||||
host_service = ProxmoxHostService(host)
|
||||
success = await host_service.wake_host(db)
|
||||
|
||||
if not success:
|
||||
raise HTTPException(status_code=500, detail="Failed to wake host")
|
||||
|
||||
return {"message": f"WOL packet sent to {host.name}", "success": True}
|
||||
|
||||
@router.post("/{host_id}/shutdown")
|
||||
async def shutdown_host(host_id: int, db: Session = Depends(get_db)):
|
||||
"""Shutdown a Proxmox host (and all its VMs)"""
|
||||
host = db.query(ProxmoxHost).filter(ProxmoxHost.id == host_id).first()
|
||||
if not host:
|
||||
raise HTTPException(status_code=404, detail="Host not found")
|
||||
|
||||
host_service = ProxmoxHostService(host)
|
||||
success = await host_service.shutdown_host(db)
|
||||
|
||||
if not success:
|
||||
raise HTTPException(status_code=500, detail="Failed to shutdown host")
|
||||
|
||||
return {"message": f"Shutdown initiated for {host.name}", "success": True}
|
||||
|
||||
@router.get("/{host_id}/vms", response_model=List[ProxmoxVM])
|
||||
async def get_host_vms(host_id: int, db: Session = Depends(get_db)):
|
||||
"""Get all VMs/containers from a Proxmox host"""
|
||||
host = db.query(ProxmoxHost).filter(ProxmoxHost.id == host_id).first()
|
||||
if not host:
|
||||
raise HTTPException(status_code=404, detail="Host not found")
|
||||
|
||||
try:
|
||||
host_service = ProxmoxHostService(host)
|
||||
vms = await host_service.get_vms()
|
||||
return vms
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Error getting VMs: {str(e)}")
|
||||
|
||||
@router.post("/{host_id}/vms/{vmid}/start")
|
||||
async def start_vm(host_id: int, vmid: str, node: str, vm_type: str = "qemu", db: Session = Depends(get_db)):
|
||||
"""Start a VM/container on a Proxmox host"""
|
||||
host = db.query(ProxmoxHost).filter(ProxmoxHost.id == host_id).first()
|
||||
if not host:
|
||||
raise HTTPException(status_code=404, detail="Host not found")
|
||||
|
||||
host_service = ProxmoxHostService(host)
|
||||
success = await host_service.start_vm(node, vmid, vm_type)
|
||||
|
||||
# Get VM name for logging
|
||||
try:
|
||||
vms = await host_service.get_vms()
|
||||
vm_name = next((vm.name for vm in vms if vm.vmid == vmid), f"VM-{vmid}")
|
||||
except:
|
||||
vm_name = f"VM-{vmid}"
|
||||
|
||||
# Log VM start action
|
||||
LoggingService.log_proxmox_vm_action(
|
||||
db=db,
|
||||
action="start",
|
||||
vmid=vmid,
|
||||
vm_name=vm_name,
|
||||
node=node,
|
||||
success=success,
|
||||
message=f"VM {vm_name} ({'started' if success else 'failed to start'}) on node {node}"
|
||||
)
|
||||
|
||||
if not success:
|
||||
raise HTTPException(status_code=500, detail="Failed to start VM")
|
||||
|
||||
return {"message": f"VM {vmid} start command sent", "success": True}
|
||||
|
||||
@router.post("/{host_id}/vms/{vmid}/stop")
|
||||
async def stop_vm(host_id: int, vmid: str, node: str, vm_type: str = "qemu", db: Session = Depends(get_db)):
|
||||
"""Stop a VM/container on a Proxmox host"""
|
||||
host = db.query(ProxmoxHost).filter(ProxmoxHost.id == host_id).first()
|
||||
if not host:
|
||||
raise HTTPException(status_code=404, detail="Host not found")
|
||||
|
||||
host_service = ProxmoxHostService(host)
|
||||
success = await host_service.stop_vm(node, vmid, vm_type)
|
||||
|
||||
# Get VM name for logging
|
||||
try:
|
||||
vms = await host_service.get_vms()
|
||||
vm_name = next((vm.name for vm in vms if vm.vmid == vmid), f"VM-{vmid}")
|
||||
except:
|
||||
vm_name = f"VM-{vmid}"
|
||||
|
||||
# Log VM stop action
|
||||
LoggingService.log_proxmox_vm_action(
|
||||
db=db,
|
||||
action="stop",
|
||||
vmid=vmid,
|
||||
vm_name=vm_name,
|
||||
node=node,
|
||||
success=success,
|
||||
message=f"VM {vm_name} ({'stopped' if success else 'failed to stop'}) on node {node}"
|
||||
)
|
||||
|
||||
if not success:
|
||||
raise HTTPException(status_code=500, detail="Failed to stop VM")
|
||||
|
||||
return {"message": f"VM {vmid} stop command sent", "success": True}
|
||||
|
||||
@router.post("/check-status")
|
||||
async def check_all_hosts_status(db: Session = Depends(get_db)):
|
||||
"""Check online status of all Proxmox hosts"""
|
||||
await ProxmoxHostService.check_all_hosts_status(db)
|
||||
return {"message": "Host status checked for all hosts"}
|
||||
|
||||
@router.get("/{host_id}/status")
|
||||
async def check_host_status(host_id: int, db: Session = Depends(get_db)):
|
||||
"""Check online status of a specific Proxmox host"""
|
||||
host = db.query(ProxmoxHost).filter(ProxmoxHost.id == host_id).first()
|
||||
if not host:
|
||||
raise HTTPException(status_code=404, detail="Host not found")
|
||||
|
||||
is_online = await ProxmoxHostService.ping_host(host.ip_address)
|
||||
|
||||
from datetime import datetime
|
||||
host.is_online = is_online
|
||||
host.last_ping = datetime.utcnow()
|
||||
db.commit()
|
||||
|
||||
return {
|
||||
"host_id": host_id,
|
||||
"host_name": host.name,
|
||||
"is_online": is_online,
|
||||
"last_ping": host.last_ping
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import List
|
||||
from app.database import get_db, ProxmoxCluster
|
||||
from app.models.schemas import ProxmoxCluster as ProxmoxClusterSchema, ProxmoxClusterCreate, ProxmoxVM
|
||||
from app.services.proxmox_service import ProxmoxService
|
||||
from app.services.logging_service import LoggingService
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@router.get("/clusters", response_model=List[ProxmoxClusterSchema])
|
||||
async def get_clusters(db: Session = Depends(get_db)):
|
||||
clusters = db.query(ProxmoxCluster).all()
|
||||
return clusters
|
||||
|
||||
@router.post("/clusters", response_model=ProxmoxClusterSchema)
|
||||
async def create_cluster(cluster: ProxmoxClusterCreate, db: Session = Depends(get_db)):
|
||||
try:
|
||||
proxmox_service = ProxmoxService(
|
||||
host=cluster.host,
|
||||
user=cluster.username,
|
||||
password=cluster.password,
|
||||
port=cluster.port,
|
||||
verify_ssl=cluster.verify_ssl
|
||||
)
|
||||
|
||||
if not await proxmox_service.test_connection():
|
||||
raise HTTPException(status_code=400, detail="Cannot connect to Proxmox cluster")
|
||||
|
||||
db_cluster = ProxmoxCluster(**cluster.dict())
|
||||
db.add(db_cluster)
|
||||
db.commit()
|
||||
db.refresh(db_cluster)
|
||||
|
||||
# Log cluster creation
|
||||
LoggingService.log_proxmox_cluster_action(
|
||||
db=db,
|
||||
action="create",
|
||||
cluster_id=db_cluster.id,
|
||||
cluster_name=db_cluster.name,
|
||||
success=True,
|
||||
message=f"Proxmox cluster '{db_cluster.name}' created successfully"
|
||||
)
|
||||
|
||||
return db_cluster
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Error creating cluster: {str(e)}")
|
||||
|
||||
@router.get("/clusters/{cluster_id}", response_model=ProxmoxClusterSchema)
|
||||
async def get_cluster(cluster_id: int, db: Session = Depends(get_db)):
|
||||
cluster = db.query(ProxmoxCluster).filter(ProxmoxCluster.id == cluster_id).first()
|
||||
if not cluster:
|
||||
raise HTTPException(status_code=404, detail="Cluster not found")
|
||||
return cluster
|
||||
|
||||
@router.delete("/clusters/{cluster_id}")
|
||||
async def delete_cluster(cluster_id: int, db: Session = Depends(get_db)):
|
||||
cluster = db.query(ProxmoxCluster).filter(ProxmoxCluster.id == cluster_id).first()
|
||||
if not cluster:
|
||||
raise HTTPException(status_code=404, detail="Cluster not found")
|
||||
|
||||
# Log cluster deletion before deleting
|
||||
LoggingService.log_proxmox_cluster_action(
|
||||
db=db,
|
||||
action="delete",
|
||||
cluster_id=cluster.id,
|
||||
cluster_name=cluster.name,
|
||||
success=True,
|
||||
message=f"Proxmox cluster '{cluster.name}' deleted successfully"
|
||||
)
|
||||
|
||||
db.delete(cluster)
|
||||
db.commit()
|
||||
return {"message": "Cluster deleted successfully"}
|
||||
|
||||
@router.get("/clusters/{cluster_id}/vms", response_model=List[ProxmoxVM])
|
||||
async def get_cluster_vms(cluster_id: int, db: Session = Depends(get_db)):
|
||||
cluster = db.query(ProxmoxCluster).filter(ProxmoxCluster.id == cluster_id).first()
|
||||
if not cluster:
|
||||
raise HTTPException(status_code=404, detail="Cluster not found")
|
||||
|
||||
try:
|
||||
proxmox_service = ProxmoxService(
|
||||
host=cluster.host,
|
||||
user=cluster.username,
|
||||
password=cluster.password,
|
||||
port=cluster.port,
|
||||
verify_ssl=cluster.verify_ssl
|
||||
)
|
||||
|
||||
vms = await proxmox_service.get_vms()
|
||||
return vms
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Error getting VMs: {str(e)}")
|
||||
|
||||
@router.post("/clusters/{cluster_id}/vms/{vmid}/start")
|
||||
async def start_vm(cluster_id: int, vmid: str, node: str, vm_type: str = "qemu", db: Session = Depends(get_db)):
|
||||
cluster = db.query(ProxmoxCluster).filter(ProxmoxCluster.id == cluster_id).first()
|
||||
if not cluster:
|
||||
raise HTTPException(status_code=404, detail="Cluster not found")
|
||||
|
||||
proxmox_service = ProxmoxService(
|
||||
host=cluster.host,
|
||||
user=cluster.username,
|
||||
password=cluster.password,
|
||||
port=cluster.port,
|
||||
verify_ssl=cluster.verify_ssl
|
||||
)
|
||||
|
||||
success = await proxmox_service.start_vm(node, vmid, vm_type)
|
||||
|
||||
# Get VM name from the cluster's VMs
|
||||
vms = await proxmox_service.get_vms()
|
||||
vm_name = next((vm.name for vm in vms if vm.vmid == vmid), f"VM-{vmid}")
|
||||
|
||||
# Log VM start action
|
||||
LoggingService.log_proxmox_vm_action(
|
||||
db=db,
|
||||
action="start",
|
||||
vmid=vmid,
|
||||
vm_name=vm_name,
|
||||
node=node,
|
||||
success=success,
|
||||
message=f"VM {vm_name} ({'started' if success else 'failed to start'}) on node {node}"
|
||||
)
|
||||
|
||||
if not success:
|
||||
raise HTTPException(status_code=500, detail="Failed to start VM")
|
||||
|
||||
return {"message": f"VM {vmid} start command sent", "success": True}
|
||||
|
||||
@router.post("/clusters/{cluster_id}/vms/{vmid}/stop")
|
||||
async def stop_vm(cluster_id: int, vmid: str, node: str, vm_type: str = "qemu", db: Session = Depends(get_db)):
|
||||
cluster = db.query(ProxmoxCluster).filter(ProxmoxCluster.id == cluster_id).first()
|
||||
if not cluster:
|
||||
raise HTTPException(status_code=404, detail="Cluster not found")
|
||||
|
||||
proxmox_service = ProxmoxService(
|
||||
host=cluster.host,
|
||||
user=cluster.username,
|
||||
password=cluster.password,
|
||||
port=cluster.port,
|
||||
verify_ssl=cluster.verify_ssl
|
||||
)
|
||||
|
||||
success = await proxmox_service.stop_vm(node, vmid, vm_type)
|
||||
|
||||
# Get VM name from the cluster's VMs
|
||||
vms = await proxmox_service.get_vms()
|
||||
vm_name = next((vm.name for vm in vms if vm.vmid == vmid), f"VM-{vmid}")
|
||||
|
||||
# Log VM stop action
|
||||
LoggingService.log_proxmox_vm_action(
|
||||
db=db,
|
||||
action="stop",
|
||||
vmid=vmid,
|
||||
vm_name=vm_name,
|
||||
node=node,
|
||||
success=success,
|
||||
message=f"VM {vm_name} ({'stopped' if success else 'failed to stop'}) on node {node}"
|
||||
)
|
||||
|
||||
if not success:
|
||||
raise HTTPException(status_code=500, detail="Failed to stop VM")
|
||||
|
||||
return {"message": f"VM {vmid} stop command sent", "success": True}
|
||||
@@ -1,90 +0,0 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import List
|
||||
from app.database import get_db, Server
|
||||
from app.models.schemas import Server as ServerSchema, ServerCreate
|
||||
from app.services.wol_service import WolService
|
||||
from app.services.logging_service import LoggingService
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@router.get("/", response_model=List[ServerSchema])
|
||||
async def get_servers(db: Session = Depends(get_db)):
|
||||
servers = db.query(Server).all()
|
||||
return servers
|
||||
|
||||
@router.post("/", response_model=ServerSchema)
|
||||
async def create_server(server: ServerCreate, db: Session = Depends(get_db)):
|
||||
db_server = Server(**server.dict())
|
||||
db.add(db_server)
|
||||
db.commit()
|
||||
db.refresh(db_server)
|
||||
|
||||
# Log server creation
|
||||
LoggingService.log_server_action(
|
||||
db=db,
|
||||
action="create",
|
||||
server_id=db_server.id,
|
||||
server_name=db_server.name,
|
||||
success=True,
|
||||
message=f"Server '{db_server.name}' created successfully"
|
||||
)
|
||||
|
||||
return db_server
|
||||
|
||||
@router.get("/{server_id}", response_model=ServerSchema)
|
||||
async def get_server(server_id: int, db: Session = Depends(get_db)):
|
||||
server = db.query(Server).filter(Server.id == server_id).first()
|
||||
if not server:
|
||||
raise HTTPException(status_code=404, detail="Server not found")
|
||||
return server
|
||||
|
||||
@router.put("/{server_id}", response_model=ServerSchema)
|
||||
async def update_server(server_id: int, server_update: ServerCreate, db: Session = Depends(get_db)):
|
||||
server = db.query(Server).filter(Server.id == server_id).first()
|
||||
if not server:
|
||||
raise HTTPException(status_code=404, detail="Server not found")
|
||||
|
||||
old_name = server.name
|
||||
for key, value in server_update.dict().items():
|
||||
setattr(server, key, value)
|
||||
|
||||
db.commit()
|
||||
db.refresh(server)
|
||||
|
||||
# Log server update
|
||||
LoggingService.log_server_action(
|
||||
db=db,
|
||||
action="update",
|
||||
server_id=server.id,
|
||||
server_name=server.name,
|
||||
success=True,
|
||||
message=f"Server '{old_name}' updated successfully"
|
||||
)
|
||||
|
||||
return server
|
||||
|
||||
@router.delete("/{server_id}")
|
||||
async def delete_server(server_id: int, db: Session = Depends(get_db)):
|
||||
server = db.query(Server).filter(Server.id == server_id).first()
|
||||
if not server:
|
||||
raise HTTPException(status_code=404, detail="Server not found")
|
||||
|
||||
# Log server deletion before deleting
|
||||
LoggingService.log_server_action(
|
||||
db=db,
|
||||
action="delete",
|
||||
server_id=server.id,
|
||||
server_name=server.name,
|
||||
success=True,
|
||||
message=f"Server '{server.name}' deleted successfully"
|
||||
)
|
||||
|
||||
db.delete(server)
|
||||
db.commit()
|
||||
return {"message": "Server deleted successfully"}
|
||||
|
||||
@router.post("/check-status")
|
||||
async def check_all_servers_status(db: Session = Depends(get_db)):
|
||||
await WolService.check_all_servers_status(db)
|
||||
return {"message": "Server status checked for all servers"}
|
||||
Reference in New Issue
Block a user