proxstar/proxmox.py

236 lines
7.1 KiB
Python

import time
from proxmoxer import ProxmoxAPI
from db import *
def connect_proxmox(host, user, password):
try:
proxmox = ProxmoxAPI(
host, user=user, password=password, verify_ssl=False)
except:
print("Unable to connect to Proxmox!")
raise
return proxmox
def get_vms_for_user(proxmox, user):
if user not in get_pools(proxmox):
proxmox.pools.post(poolid=user, comment='Managed by Proxstar')
return proxmox.pools(user).get()['members']
def get_user_allowed_vms(proxmox, user):
allowed_vms = []
for vm in get_vms_for_user(proxmox, user):
allowed_vms.append(vm['vmid'])
return allowed_vms
def get_node_least_mem(proxmox):
nodes = proxmox.nodes.get()
sorted_nodes = sorted(nodes, key=lambda x: x['mem'])
return sorted_nodes[0]['node']
def get_free_vmid(proxmox):
return proxmox.cluster.nextid.get()
def get_vm_node(proxmox, vmid):
for vm in proxmox.cluster.resources.get(type='vm'):
if vm['vmid'] == int(vmid):
return vm['node']
def get_vm(proxmox, vmid):
node = proxmox.nodes(get_vm_node(proxmox, vmid))
return node.qemu(vmid).status.current.get()
def get_vm_config(proxmox, vmid):
node = proxmox.nodes(get_vm_node(proxmox, vmid))
return node.qemu(vmid).config.get()
def get_vm_mac(proxmox, vmid, config=None, interface='net0'):
if not config:
config = get_vm_config(proxmox, vmid)
mac = config[interface].split(',')
if 'virtio' in mac[0]:
mac = mac[0].split('=')[1]
else:
mac = mac[1].split('=')[1]
return mac
def get_vm_interfaces(proxmox, vmid, config=None):
if not config:
config = get_vm_config(proxmox, vmid)
interfaces = []
for key, val in config.items():
if 'net' in key:
mac = config[key].split(',')
valid_int_types = ['virtio', 'e1000', 'rtl8139', 'vmxnet3']
if any(int_type in mac[0] for int_type in valid_int_types):
mac = mac[0].split('=')[1]
else:
mac = mac[1].split('=')[1]
interfaces.append([key, mac])
interfaces = sorted(interfaces, key=lambda x: x[0])
return interfaces
def get_vm_disk_size(proxmox, vmid, config=None, name='virtio0'):
if not config:
config = get_vm_config(proxmox, vmid)
disk_size = config[name].split(',')
if 'size' in disk_size[0]:
disk_size = disk_size[0].split('=')[1].rstrip('G')
else:
disk_size = disk_size[1].split('=')[1].rstrip('G')
return disk_size
def get_vm_disks(proxmox, vmid, config=None):
if not config:
config = get_vm_config(proxmox, vmid)
disks = []
for key, val in config.items():
valid_disk_types = ['virtio', 'ide', 'sata', 'scsi']
if any(disk_type in key for disk_type in valid_disk_types):
if 'scsihw' not in key and 'cdrom' not in val:
disk_size = val.split(',')
if 'size' in disk_size[0]:
disk_size = disk_size[0].split('=')[1].rstrip('G')
else:
disk_size = disk_size[1].split('=')[1].rstrip('G')
disks.append([key, disk_size])
disks = sorted(disks, key=lambda x: x[0])
return disks
def get_vm_iso(proxmox, vmid, config=None):
if not config:
config = get_vm_config(proxmox, vmid)
if config.get('ide2'):
if config['ide2'].split(',')[0] == 'none':
iso = 'None'
else:
iso = config['ide2'].split(',')[0].split('/')[1]
else:
iso = 'None'
return iso
def get_user_usage(proxmox, user):
usage = dict()
usage['cpu'] = 0
usage['mem'] = 0
usage['disk'] = 0
vms = get_vms_for_user(proxmox, user)
for vm in vms:
config = get_vm_config(proxmox, vm['vmid'])
if 'status' in vm:
if vm['status'] == 'running' or vm['status'] == 'paused':
usage['cpu'] += int(config['cores'] * config.get('sockets', 1))
usage['mem'] += (int(config['memory']) // 1024)
for disk in get_vm_disks(proxmox, vm['vmid'], config):
usage['disk'] += int(disk[1])
return usage
def check_user_usage(proxmox, user, vm_cpu, vm_mem, vm_disk):
limits = get_user_usage_limits(user)
cur_usage = get_user_usage(proxmox, user)
if int(cur_usage['cpu']) + int(vm_cpu) > int(limits['cpu']):
return 'exceeds_cpu_limit'
elif int(cur_usage['mem']) + (int(vm_mem) / 1024) > int(limits['mem']):
return 'exceeds_memory_limit'
elif int(cur_usage['disk']) + int(vm_disk) > int(limits['disk']):
return 'exceeds_disk_limit'
def get_user_usage_percent(proxmox, usage=None, limits=None):
percents = dict()
if not usage:
usage = get_user_usage(proxmox, user)
if not limits:
limits = get_user_usage_limits(user)
percents['cpu'] = round(int(usage['cpu']) / int(limits['cpu']) * 100)
percents['mem'] = round(int(usage['mem']) / int(limits['mem']) * 100)
percents['disk'] = round(int(usage['disk']) / int(limits['disk']) * 100)
return percents
def create_vm(proxmox, starrs, user, name, cores, memory, disk, iso):
node = proxmox.nodes(get_node_least_mem(proxmox))
vmid = get_free_vmid(proxmox)
node.qemu.create(
vmid=vmid,
name=name,
cores=cores,
memory=memory,
storage='ceph',
virtio0="ceph:{}".format(disk),
ide2="{},media=cdrom".format(iso),
net0='virtio,bridge=vmbr0',
pool=user,
description='Managed by Proxstar')
time.sleep(3)
mac = get_vm_mac(proxmox, vmid)
return vmid, mac
def delete_vm(proxmox, starrs, vmid):
node = proxmox.nodes(get_vm_node(proxmox, vmid))
node.qemu(vmid).delete()
def change_vm_power(proxmox, vmid, action):
node = proxmox.nodes(get_vm_node(proxmox, vmid))
if action == 'start':
node.qemu(vmid).status.start.post()
elif action == 'stop':
node.qemu(vmid).status.stop.post()
elif action == 'shutdown':
node.qemu(vmid).status.shutdown.post()
elif action == 'reset':
node.qemu(vmid).status.reset.post()
elif action == 'suspend':
node.qemu(vmid).status.suspend.post()
elif action == 'resume':
node.qemu(vmid).status.resume.post()
def change_vm_cpu(proxmox, vmid, cores):
node = proxmox.nodes(get_vm_node(proxmox, vmid))
node.qemu(vmid).config.put(cores=cores)
def change_vm_mem(proxmox, vmid, mem):
node = proxmox.nodes(get_vm_node(proxmox, vmid))
node.qemu(vmid).config.put(memory=mem)
def get_isos(proxmox, storage):
isos = []
for iso in proxmox.nodes('proxmox01').storage(storage).content.get():
isos.append(iso['volid'].split('/')[1])
return isos
def eject_vm_iso(proxmox, vmid):
node = proxmox.nodes(get_vm_node(proxmox, vmid))
node.qemu(vmid).config.post(ide2='none,media=cdrom')
def mount_vm_iso(proxmox, vmid, iso):
node = proxmox.nodes(get_vm_node(proxmox, vmid))
node.qemu(vmid).config.post(ide2="{},media=cdrom".format(iso))
def get_pools(proxmox):
pools = []
for pool in proxmox.pools.get():
pools.append(pool['poolid'])
return pools