Add multi-host Proxmox support with SSL certificate handling

- Added support for multiple Proxmox hosts (pve7.0bin.in:443, Healthport PVE:8006)
- Enhanced VM management APIs to accept host parameter
- Fixed WebSocket URL generation bug (dynamic port handling)
- Added comprehensive SSL certificate trust help system
- Implemented host selection dropdown in UI
- Added VNC connection failure detection and automatic SSL help redirection
- Updated session management to store host_key information
- Enhanced error handling for different Proxmox configurations

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-09-12 23:57:52 +09:00
parent ac620a0e15
commit fb00b0a5fd
14 changed files with 2029 additions and 32 deletions

View File

@@ -13,12 +13,19 @@ from typing import Dict, List, Optional, Tuple
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
class ProxmoxClient:
def __init__(self, host: str, username: str = "root@pam", password: str = "", api_token: str = ""):
self.host = host
def __init__(self, host: str, username: str = "root@pam", password: str = "", api_token: str = "", port: int = 8006):
# 호스트에서 포트가 포함된 경우 분리
if ':' in host:
self.host, port_str = host.split(':')
self.port = int(port_str)
else:
self.host = host
self.port = port
self.username = username
self.password = password
self.api_token = api_token
self.base_url = f"https://{host}:443/api2/json"
self.base_url = f"https://{self.host}:{self.port}/api2/json"
self.session = requests.Session()
self.session.verify = False
self.ticket = None
@@ -134,14 +141,14 @@ class ProxmoxClient:
vnc_data = response.json()['data']
print(f"✅ VNC 티켓 생성 성공: {vnc_data}")
# WebSocket URL 생성 (인증 토큰 포함)
# WebSocket URL 생성 (동적 포트 및 CSRF 토큰 포함)
encoded_ticket = quote_plus(vnc_data['ticket'])
# Proxmox 세션 쿠키도 함께 포함 (CSRFPreventionToken도 필요할 수 있음)
csrf_token = getattr(self, 'csrf_token', None)
if csrf_token:
vnc_data['websocket_url'] = f"wss://{self.host}:443/api2/json/nodes/{node}/qemu/{vmid}/vncwebsocket?port={vnc_data['port']}&vncticket={encoded_ticket}&CSRFPreventionToken={csrf_token}"
vnc_data['websocket_url'] = f"wss://{self.host}:{self.port}/api2/json/nodes/{node}/qemu/{vmid}/vncwebsocket?port={vnc_data['port']}&vncticket={encoded_ticket}&CSRFPreventionToken={csrf_token}"
else:
vnc_data['websocket_url'] = f"wss://{self.host}:443/api2/json/nodes/{node}/qemu/{vmid}/vncwebsocket?port={vnc_data['port']}&vncticket={encoded_ticket}"
vnc_data['websocket_url'] = f"wss://{self.host}:{self.port}/api2/json/nodes/{node}/qemu/{vmid}/vncwebsocket?port={vnc_data['port']}&vncticket={encoded_ticket}"
# 디버깅 정보 추가
print(f"🔗 WebSocket URL: {vnc_data['websocket_url']}")