Files
vconnect-api/app/api/vms.py
2025-12-08 21:35:55 +09:00

142 lines
4.6 KiB
Python

from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from typing import List
from app.database import get_db
from app.schemas.vm import VMInfo, VMListResponse, VMDetail, VMControlRequest, VMControlResponse
from app.schemas.auth import CurrentUser
from app.api.auth import get_current_user
from app.services.proxmox_service import proxmox_service
from app.models.vm import VMAccess
from app.utils.exceptions import NotFoundError, PermissionDeniedError
router = APIRouter()
@router.get("/my", response_model=VMListResponse)
async def get_my_vms(
current_user: CurrentUser = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""
내 VM 목록 조회
현재 사용자가 접근 가능한 VM 목록을 반환합니다.
"""
# Proxmox에서 모든 VM 가져오기
all_vms = await proxmox_service.get_all_vms()
# 현재 사용자의 VMAccess 정보 조회
vm_accesses = db.query(VMAccess).filter(
VMAccess.user_id == current_user.id,
VMAccess.is_active == True
).all()
# vm_id를 키로 하는 딕셔너리 생성
access_map = {access.vm_id: access for access in vm_accesses}
vm_list = []
for vm in all_vms:
vm_id = vm["vmid"]
access = access_map.get(vm_id)
# VMAccess가 있으면 해당 정보 사용, 없으면 기본값
vm_info = VMInfo(
vm_id=vm_id,
node=vm["node"],
name=vm.get("name", "Unknown"),
status=vm.get("status", "unknown"),
ip_address=access.static_ip if access else None, # Static IP 자동 설정
cpus=vm.get("cpus", 0),
memory=vm.get("maxmem", 0) // (1024 * 1024), # bytes to MB
memory_usage=vm.get("mem", 0) // (1024 * 1024) if vm.get("mem") else None,
cpu_usage=vm.get("cpu", 0),
can_start=True,
can_stop=True,
can_reboot=True,
can_connect=True,
rdp_username=access.rdp_username if access else None, # RDP 사용자명
rdp_password=access.rdp_password if access else None, # RDP 비밀번호
rdp_port=access.rdp_port if access else 3389 # RDP 포트
)
vm_list.append(vm_info)
return VMListResponse(total=len(vm_list), vms=vm_list)
@router.get("/{vm_id}", response_model=VMDetail)
async def get_vm_detail(
vm_id: int,
node: str,
current_user: CurrentUser = Depends(get_current_user)
):
"""
VM 상세 정보 조회
"""
# VM 상태 조회
status = await proxmox_service.get_vm_status(node, vm_id)
if not status:
raise NotFoundError(f"VM {vm_id}를 찾을 수 없습니다")
# IP 조회 제거 - 연결에 필요하지 않음
return VMDetail(
vm_id=vm_id,
node=node,
name=status.get("name", "Unknown"),
status=status.get("status", "unknown"),
ip_address=None, # IP 조회 안 함
cpus=status.get("cpus", 0),
memory=status.get("maxmem", 0) // (1024 * 1024),
memory_usage=status.get("mem", 0) // (1024 * 1024) if status.get("mem") else None,
cpu_usage=status.get("cpu", 0),
uptime=status.get("uptime"),
rdp_port=3389,
has_guest_agent=False # Guest Agent 불필요
)
@router.post("/{vm_id}/start", response_model=VMControlResponse)
async def start_vm(
vm_id: int,
node: str,
current_user: CurrentUser = Depends(get_current_user)
):
"""VM 시작"""
success = await proxmox_service.start_vm(node, vm_id)
return VMControlResponse(
success=success,
message="VM이 시작되었습니다" if success else "VM 시작에 실패했습니다",
vm_id=vm_id,
action="start"
)
@router.post("/{vm_id}/stop", response_model=VMControlResponse)
async def stop_vm(
vm_id: int,
node: str,
current_user: CurrentUser = Depends(get_current_user)
):
"""VM 종료"""
success = await proxmox_service.stop_vm(node, vm_id)
return VMControlResponse(
success=success,
message="VM이 종료되었습니다" if success else "VM 종료에 실패했습니다",
vm_id=vm_id,
action="stop"
)
@router.post("/{vm_id}/reboot", response_model=VMControlResponse)
async def reboot_vm(
vm_id: int,
node: str,
current_user: CurrentUser = Depends(get_current_user)
):
"""VM 재시작"""
success = await proxmox_service.reboot_vm(node, vm_id)
return VMControlResponse(
success=success,
message="VM이 재시작되었습니다" if success else "VM 재시작에 실패했습니다",
vm_id=vm_id,
action="reboot"
)