bemade-addons/odoo_proxmox_manager/models/proxmox_server.py
2025-05-29 21:35:47 -04:00

164 lines
6.3 KiB
Python

from odoo import models, fields, api
from proxmoxer import ProxmoxAPI
import requests
import logging
_logger = logging.getLogger(__name__)
class ProxmoxServer(models.Model):
_name = 'proxmox.server'
_description = 'Proxmox Server'
_order = 'name'
_inherit = ['mail.thread']
name = fields.Char(string='Name', required=True, tracking=True)
hostname = fields.Char(string='Hostname', required=True, tracking=True)
port = fields.Integer(string='Port', default=8006, tracking=True)
cluster_id = fields.Many2one('proxmox.cluster', string='Cluster', tracking=True)
username = fields.Char(string='Username', required=True, tracking=True)
token_name = fields.Char(string='API Token Name', tracking=True)
token_value = fields.Char(string='API Token Value', tracking=True)
verify_ssl = fields.Boolean(string='Verify SSL', default=True, tracking=True)
company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env.company)
state = fields.Selection([
('offline', 'Offline'),
('online', 'Online')
], string='Status', default='offline', compute='_compute_state', store=True, tracking=True)
vm_ids = fields.One2many('proxmox.vm', 'server_id', string='Virtual Machines')
vm_count = fields.Integer(string='VM Count', compute='_compute_vm_count')
node_info = fields.Text(string='Node Information', compute='_compute_node_info')
def _get_proxmox_connection(self):
try:
if not self.token_name or not self.token_value:
raise ValueError("API Token is required")
return ProxmoxAPI(
self.hostname,
port=self.port,
user=self.username,
token_name=self.token_name,
token_value=self.token_value,
verify_ssl=self.verify_ssl
)
except Exception as e:
_logger.error(f"Failed to connect to Proxmox server {self.name}: {str(e)}")
return None
@api.depends('hostname', 'port', 'token_name', 'token_value')
def _compute_state(self):
for server in self:
try:
proxmox = server._get_proxmox_connection()
if proxmox:
# Test connection by getting version info
proxmox.version.get()
server.state = 'online'
else:
server.state = 'offline'
except:
server.state = 'offline'
@api.depends('vm_ids')
def _compute_vm_count(self):
for server in self:
server.vm_count = len(server.vm_ids)
def _compute_node_info(self):
for server in self:
try:
proxmox = server._get_proxmox_connection()
if proxmox:
node_info = proxmox.nodes(server.hostname).status.get()
server.node_info = str(node_info)
else:
server.node_info = "Unable to connect to server"
except Exception as e:
server.node_info = f"Error getting node info: {str(e)}"
def action_sync_vms(self):
"""Synchronize VMs from Proxmox server"""
self.ensure_one()
proxmox = self._get_proxmox_connection()
if not proxmox:
return False
try:
# Get all VMs from the server
vms = proxmox.nodes(self.hostname).qemu.get()
# Update or create VM records
for vm in vms:
vm_vals = {
'name': vm.get('name'),
'vmid': vm.get('vmid'),
'status': vm.get('status'),
'server_id': self.id,
}
existing_vm = self.env['proxmox.vm'].search([
('server_id', '=', self.id),
('vmid', '=', vm.get('vmid'))
])
if existing_vm:
existing_vm.write(vm_vals)
else:
self.env['proxmox.vm'].create(vm_vals)
return True
except Exception as e:
_logger.error(f"Failed to sync VMs for server {self.name}: {str(e)}")
return False
@api.model
def get_dashboard_data(self):
"""Get dashboard data for the Proxmox overview"""
servers = self.search([])
clusters = self.env['proxmox.cluster'].search([])
vms = self.env['proxmox.vm'].search([])
server_data = []
for server in servers:
try:
proxmox = server._get_proxmox_connection()
if proxmox:
node_info = proxmox.nodes(server.hostname).status.get()
memory_total = node_info.get('memory', {}).get('total', 0)
memory_used = node_info.get('memory', {}).get('used', 0)
memory_usage = round((memory_used / memory_total) * 100, 2) if memory_total else 0
cpu_usage = round(node_info.get('cpu', 0) * 100, 2)
server_data.append({
'id': server.id,
'name': server.name,
'state': server.state,
'vm_count': server.vm_count,
'memory_usage': memory_usage,
'cpu_usage': cpu_usage,
})
else:
server_data.append({
'id': server.id,
'name': server.name,
'state': 'offline',
'vm_count': server.vm_count,
'memory_usage': 0,
'cpu_usage': 0,
})
except Exception as e:
_logger.error(f"Error getting data for server {server.name}: {str(e)}")
server_data.append({
'id': server.id,
'name': server.name,
'state': 'offline',
'vm_count': server.vm_count,
'memory_usage': 0,
'cpu_usage': 0,
})
return {
'server_count': len(servers),
'cluster_count': len(clusters),
'vm_count': len(vms),
'servers': server_data,
}