proxmaster/plugin.py

328 lines
13 KiB
Python
Raw Normal View History

2016-02-15 05:30:43 -05:00
#. -*- coding: utf-8 -
# required proxmox permissions: PVESysAdmin, PVEVMAdmin
#
# afx 2015-2016
# site
from proxmoxer import ProxmoxAPI
import base64
import json
import time
import socket
2016-11-03 00:25:01 -04:00
import random
2016-05-08 08:44:19 -04:00
from unidecode import unidecode
2016-02-15 05:30:43 -05:00
#local
import grid
import utils
import ioconfig
import novnc
2016-11-03 00:05:51 -04:00
def auth(slave_name):
""" return control object from config slave names """
2016-02-15 05:30:43 -05:00
adminuser = ioconfig.parser.get('general', 'adminuser')
2016-11-03 00:05:51 -04:00
slaveip = ioconfig.parser.get(str(slave_name), 'ipv4')
slavepass = ioconfig.parser.get(str(slave_name), 'password')
slavetype = ioconfig.parser.get(str(slave_name), 'type')
2016-02-15 05:30:43 -05:00
#vendor specific
2016-11-03 00:05:51 -04:00
if slavetype == 'proxmoxia':
connection = lib_proxmoxia.Connector(slaveip)
auth_token = connection.get_auth_token(adminuser, slavepass)
proxobject = lib_proxmoxia.Proxmox(connection)
if slavetype == 'proxmox':
proxobject = ProxmoxAPI(slaveip, user=adminuser, password=slavepass, verify_ssl=False)
2016-02-15 05:30:43 -05:00
return proxobject
def vmlist(proxobject):
""" get vmlist """
#we keep a single node proxmoxes so node id = 0
2016-11-03 00:05:51 -04:00
2016-02-15 05:30:43 -05:00
#slave_name = proxobject.get('cluster/status')#'name']
slave_name = proxobject.cluster.status.get()[0]['name']
#query_kvm = proxobject.get('nodes/%s/qemu' % slave_name)
query_kvm = proxobject.nodes(slave_name).qemu.get()
query_lxc = proxobject.nodes(slave_name).lxc.get()
2016-11-03 00:05:51 -04:00
2016-02-15 05:30:43 -05:00
for kvm_dict in query_kvm:
kvm_dict['vmtype'] = 'kvm'
for lxc_dict in query_lxc:
lxc_dict['vmtype'] = 'lxc'
vmlist = query_kvm + query_lxc #merge machine list
return vmlist
def vmcreate(req):
2016-11-03 00:05:51 -04:00
""" create vm. returns JSON with data """
try:
region_id = ioconfig.parser.get(str(req['region']), 'regionid')
region_fullname = ioconfig.parser.get(str(req['region']), 'fullname')
except:
2016-10-28 22:57:57 -04:00
ioconfig.logger.error('grid> no region found')
2016-11-03 00:05:51 -04:00
return None
2016-05-08 08:44:19 -04:00
vm_name_utf8 = req['hostname']
vm_name = unidecode(vm_name_utf8)
2016-11-03 00:05:51 -04:00
try:
vm_pass = req['vmpass']
except:
vm_pass = 'kvm-no-pass'
#generators
#slave_name = str(grid.query_happiness(region_id, weight)) #TODO: provide weight parameters here and calculate route
2016-11-03 00:28:44 -04:00
slave_name = 'warrior' #staic route
2016-11-03 00:05:51 -04:00
#vmid = str(grid.generate_vmid()) #TODO: this should be between 100 and 65000
2016-11-03 00:39:39 -04:00
vm_id = random.randint(200, 62000)
2016-11-03 00:38:26 -04:00
cubeid = time.time() #TODO: make sure this is unique. time since epoch is not random enough but should do the trick for now
2016-11-03 00:05:51 -04:00
ipv4_list = grid.generate_ipv4(req['region'], req['vps_ipv4'])
#metadata
2016-11-03 00:38:26 -04:00
deploy = { 'cube': int(cubeid),
2016-11-03 00:22:47 -04:00
'type': req['vps_type'],
2016-11-03 00:05:51 -04:00
'host': vm_name,
'region': region_fullname,
'slave': slave_name,
2016-11-03 00:38:26 -04:00
'vmid': vm_id,
2016-11-03 00:05:51 -04:00
'cpu_mem_hdd': (req['vps_cpu'], req['vps_mem'], req['vps_hdd']),
'clientid': req['clientid'],
'clientname': req['clientname'],
'clientemail': req['clientemail'],
'os': req['vps_os'],
'ipv4': ipv4_list }
proxobject = auth(slave_name)
2016-11-03 00:22:47 -04:00
#slave_name = proxobject.cluster.status.get()[0]['name']
2016-02-15 05:30:43 -05:00
2016-11-03 00:38:26 -04:00
ioconfig.logger.info('slave[' + slave_name + ']> deploying %s on %s (%s) at %s with %s and %s', cubeid, slave_name, vm_id, region_id, vm_ipv4, req)
grid.writedb(deploy)
2016-02-19 21:26:04 -05:00
ipv4_dict = {}
ipidx = 0
2016-11-03 00:38:26 -04:00
2016-02-15 05:30:43 -05:00
for ip in vm_ipv4:
ipv4_dict[str(ipidx)] = str(ip)
ipidx += 1
2016-03-30 18:12:38 -04:00
2016-11-03 00:38:26 -04:00
response = { 'status':'CREATE', 'cube':vm_id, 'name':vm_name, 'password':vm_pass, 'ipv4_0':vm_ipv4[0] }
2016-11-03 00:05:51 -04:00
description = vm_name + ' (' + vm_id + ')\n' + 'owned by ' + client_name + ' (' + client_id + ')\n' + 'master ip: ' + vm_ipv4[0]
2016-02-15 05:30:43 -05:00
#create partition
image_name = 'vm-' + vm_id + '-disk-0'
local_storage = proxobject.nodes(slave_name).storage('lvm')
local_storage.content.post(vmid=vm_id,
filename=image_name,
size=req['vps_disk'] + 'G')
if req['vps_type'] == 'KVM':
create_result = proxobject.nodes(slave_name).qemu.post(vmid=vm_id,
name=vm_name,
sockets=1,
cores=req['vps_cpu'],
2016-11-03 00:22:47 -04:00
memory=req['vps_mem'],
2016-02-15 05:30:43 -05:00
virtio0='lvm:' + image_name,
ide1='skyblue:iso/' + req['vps_os'] + ',media=cdrom',
net0='e1000,bridge=pub',
onboot=1,
description=description)
2016-11-03 00:05:51 -04:00
2016-02-15 05:30:43 -05:00
if req['vps_type'] == 'LXC':
create_result = proxobject.nodes(slave_name).lxc.post(vmid=vm_id,
2016-11-03 00:05:51 -04:00
hostname=vm_name,
password=vm_pass,
sockets=1,
cores=req['vps_cpu'],
2016-11-03 00:22:47 -04:00
memory=req['vps_mem'],
2016-11-03 00:05:51 -04:00
virtio0='lvm:' + image_name,
ip_address=vm_ipv4[0],
onboot=1,
description=description)
print('result:')
print(create_result)
2016-02-15 05:30:43 -05:00
#start the machihe
time.sleep(7) #wait few seconds for the slave to prepare the machine for initial run
2016-11-03 00:38:26 -04:00
vmstart(cubeid)
2016-02-15 05:30:43 -05:00
return response
2016-11-03 00:05:51 -04:00
def vmstatus(cubeid):
2016-02-15 05:30:43 -05:00
""" returns the status of the machine """
2016-11-03 00:05:51 -04:00
slave_name, vm_type, vm_id = grid.query_vm(cubeid)
proxobject = auth(slave_name)
2016-02-15 05:30:43 -05:00
vm_type = vm_type.lower()
2016-11-03 00:05:51 -04:00
#slave_name = proxobject.c:luster.status.get()[0]['name']
2016-05-08 08:44:19 -04:00
ioconfig.logger.info('slave[%s]> get status of %s %s' % (slave_name, vm_type, vm_id))
2016-02-15 05:30:43 -05:00
if vm_type == 'kvm':
result = proxobject.nodes(slave_name).qemu(vm_id).status.current.get()
if vm_type == 'lxc':
result = proxobject.nodes(slave_name).lxc(vm_id).status.current.get()
return result
2016-11-03 00:05:51 -04:00
def vmstart(cubeid):
2016-02-15 05:30:43 -05:00
""" starts a machine """
2016-11-03 00:05:51 -04:00
slave_name, vm_type, vm_id = grid.query_vm(cubeid)
proxobject = auth(slave_name)
2016-02-15 05:30:43 -05:00
vm_type = vm_type.lower()
2016-11-03 00:05:51 -04:00
#slave_name = proxobject.c:luster.status.get()[0]['name']
2016-03-31 10:40:40 -04:00
ioconfig.logger.info('slave[%s]> starting %s %s' % (slave_name, vm_type, vm_id))
2016-02-15 05:30:43 -05:00
if vm_type == 'kvm':
result = proxobject.nodes(slave_name).qemu(vm_id).status.start.post()
if vm_type == 'lxc':
result = proxobject.nodes(slave_name).lxc(vm_id).status.start.post()
2016-02-16 14:12:12 -05:00
response = { 'status':'START' }
2016-02-15 05:30:43 -05:00
return response
2016-11-03 00:05:51 -04:00
def vmshutdown(cubeid):
2016-02-15 05:30:43 -05:00
""" acpi shutdown the machine.. """
2016-11-03 00:05:51 -04:00
slave_name, vm_type, vm_id = grid.query_vm(cubeid)
proxobject = auth(slave_name)
2016-02-15 05:30:43 -05:00
vm_type = vm_type.lower()
2016-11-03 00:05:51 -04:00
#slave_name = proxobject.c:luster.status.get()[0]['name']
2016-03-31 10:40:40 -04:00
ioconfig.logger.info('slave[%s]> acpi shutdown %s %s' % (slave_name, vm_type, vm_id))
2016-02-15 05:30:43 -05:00
if vm_type == 'kvm':
2016-07-03 21:33:16 -04:00
result = proxobject.nodes(slave_name).qemu(vm_id).status.shutdown.post()
2016-02-15 05:30:43 -05:00
if vm_type == 'lxc':
2016-07-03 21:33:16 -04:00
result = proxobject.nodes(slave_name).lxc(vm_id).status.shutdown.post()
2016-03-31 10:40:40 -04:00
#ioconfig.logger.info('slave[{}]> {}'.format(slave_name, result))
2016-02-15 05:30:43 -05:00
response = { 'status':'SHUTDOWN', 'vmid':vm_id }
return response
2016-11-03 00:05:51 -04:00
def vmstop(cubeid):
2016-02-15 05:30:43 -05:00
""" poweroff the machine.. """
2016-11-03 00:05:51 -04:00
slave_name, vm_type, vm_id = grid.query_vm(cubeid)
proxobject = auth(slave_name)
2016-02-15 05:30:43 -05:00
vm_type = vm_type.lower()
2016-11-03 00:05:51 -04:00
#slave_name = proxobject.c:luster.status.get()[0]['name']
2016-03-31 10:40:40 -04:00
ioconfig.logger.info('slave[%s]> power off %s %s' % (slave_name, vm_type, vm_id))
2016-02-15 05:30:43 -05:00
if vm_type == 'kvm':
result = proxobject.nodes(slave_name).qemu(vm_id).status.stop.post()
if vm_type == 'lxc':
result = proxobject.nodes(slave_name).lxc(vm_id).status.stop.post()
2016-03-31 10:40:40 -04:00
#ioconfig.logger.info('slave[{}]> {}'.format(slave_name, result))
2016-02-16 14:12:12 -05:00
response = { 'status':'STOP', 'vmid':vm_id }
2016-02-15 05:30:43 -05:00
return response
2016-11-03 00:05:51 -04:00
def vmsuspend(cubeid):
2016-02-15 05:30:43 -05:00
""" suspend machine """
2016-11-03 00:05:51 -04:00
slave_name, vm_type, vm_id = grid.query_vm(cubeid)
proxobject = auth(slave_name)
2016-02-15 05:30:43 -05:00
vm_type = vm_type.lower()
2016-11-03 00:05:51 -04:00
#slave_name = proxobject.c:luster.status.get()[0]['name']
2016-03-31 10:40:40 -04:00
ioconfig.logger.info('slave[%s]> suspending %s %s' % (slave_name, vm_type, vm_id))
2016-02-15 05:30:43 -05:00
if vm_type == 'kvm':
result = proxobject.nodes(slave_name).qemu(vm_id).status.suspend.post()
if vm_type == 'lxc':
result = proxobject.nodes(slave_name).lxc(vm_id).status.suspend.post()
response = { 'status':'SUSPEND', 'vmid':vm_id }
return response
2016-11-03 00:05:51 -04:00
def vmresume(cubeid):
2016-02-15 05:30:43 -05:00
""" resume machine """
2016-11-03 00:05:51 -04:00
slave_name, vm_type, vm_id = grid.query_vm(cubeid)
proxobject = auth(slave_name)
2016-02-15 05:30:43 -05:00
vm_type = vm_type.lower()
2016-11-03 00:05:51 -04:00
#slave_name = proxobject.c:luster.status.get()[0]['name']
2016-03-31 10:40:40 -04:00
ioconfig.logger.info('slave[%s]> resuming %s %s' % (slave_name, vm_type, vm_id))
2016-02-15 05:30:43 -05:00
if vm_type == 'kvm':
result = proxobject.nodes(slave_name).qemu(vm_id).status.resume.post()
if vm_type == 'lxc':
result = proxobject.nodes(slave_name).lxc(vm_id).status.resume.post()
response = { 'status':'RESUME', 'vmid':vm_id }
return response
2016-11-03 00:05:51 -04:00
def vmrrd(cubeid):
2016-06-26 11:09:22 -04:00
""" retrieve rrd graphs (PNG) """
2016-11-03 00:05:51 -04:00
slave_name, vm_type, vm_id = grid.query_vm(cubeid)
proxobject = auth(slave_name)
2016-06-26 11:09:22 -04:00
vm_type = vm_type.lower()
2016-11-03 00:05:51 -04:00
#slave_name = proxobject.c:luster.status.get()[0]['name']
2016-06-26 11:09:22 -04:00
ioconfig.logger.info('slave[%s]> query rrd of %s %s' % (slave_name, vm_type, vm_id))
result = {}
if vm_type == 'kvm':
2016-06-26 12:41:01 -04:00
rcpu = proxobject.nodes(slave_name).qemu(vm_id).rrd.get(timeframe='day', cf='AVERAGE', ds='cpu')
rmem = proxobject.nodes(slave_name).qemu(vm_id).rrd.get(timeframe='day', cf='AVERAGE', ds='mem,maxmem')
rnet = proxobject.nodes(slave_name).qemu(vm_id).rrd.get(timeframe='day', cf='AVERAGE', ds='netin,netout')
rhdd = proxobject.nodes(slave_name).qemu(vm_id).rrd.get(timeframe='day', cf='AVERAGE', ds='diskread,diskwrite')
2016-06-26 11:09:22 -04:00
if vm_type == 'lxc':
2016-06-26 12:41:01 -04:00
rcpu = proxobject.nodes(slave_name).lxc(vm_id).rrd.get(timeframe='day', cf='AVERAGE', ds='cpu')
rmem = proxobject.nodes(slave_name).lxc(vm_id).rrd.get(timeframe='day', cf='AVERAGE', ds='mem,maxmem')
rnet = proxobject.nodes(slave_name).lxc(vm_id).rrd.get(timeframe='day', cf='AVERAGE', ds='netin,netout')
rhdd = proxobject.nodes(slave_name).lxc(vm_id).rrd.get(timeframe='day', cf='AVERAGE', ds='diskread,diskwrite')
2016-06-26 12:42:00 -04:00
response = { 'status':'RRD', 'vmid':vm_id, 'cpu':rcpu, 'mem':rmem, 'net':rnet, 'hdd':rhdd }
2016-06-26 11:54:27 -04:00
return response
2016-06-26 12:42:00 -04:00
2016-02-15 05:30:43 -05:00
def vmvnc(vm_id):
""" invoke vnc ticket """
2016-11-03 00:05:51 -04:00
slave_name, vm_type, vm_id = grid.query_vm(cubeid)
proxobject = auth(slave_name)
2016-02-15 05:30:43 -05:00
vm_type = vm_type.lower()
2016-11-03 00:05:51 -04:00
#slave_name = proxobject.c:luster.status.get()[0]['name']
2016-03-31 10:40:40 -04:00
ioconfig.logger.info('slave[%s]> invoking vnc ticket for %s %s' % (slave_name, vm_type, vm_id))
2016-02-15 05:30:43 -05:00
if vm_type == 'kvm':
ticket = proxobject.nodes(slave_name).qemu(vm_id).vncproxy.post(websocket=1)
#socket = proxobject.nodes(slave_name).qemu(vm_id).vncwebsocket.get(port=ticket['port'],
# vncticket=ticket['ticket'])
if vm_type == 'lxc':
ticket = proxobject.nodes(slave_name).lxc(vm_id).vncproxy.post()
#socket = proxobject.nodes(slave_name).lxc(vm_id).vncwebsocket.get(port=ticket['port'],
# vncticket=ticket['ticket'])
2016-11-03 00:05:51 -04:00
slaveip = ioconfig.parser.get(str(slave_name), 'ipv4')
2016-02-15 05:30:43 -05:00
#slaveport = socket['port']
slaveport = ticket['port']
listenport = str(int(slaveport) + 1000 + (int(slave_id) * 100)) #TODO: max 100 parallel connections/slave.
myip = getmyip()
vnc_target = { 'target_host': slaveip,
'target_port': slaveport,
'listen_host': myip,
2016-02-15 06:14:19 -05:00
'listen_port': listenport
}
2016-02-15 05:30:43 -05:00
2016-07-03 21:33:16 -04:00
vnc_options = { 'idle-timeout': 20,
2016-02-15 06:14:19 -05:00
'verbose': True
}
2016-02-15 05:30:43 -05:00
novnc.spawn(vnc_target, vnc_options)
external_url = ioconfig.parser.get('general', 'novnc_url')
2016-07-02 18:43:39 -04:00
prefix = external_url + "?host=" + myip + "&port=" + listenport + "&encrypt=0&true_color=1&password="
2016-02-16 14:12:12 -05:00
vnc_url = prefix + ticket['ticket']
2016-02-15 05:30:43 -05:00
2016-06-26 11:09:22 -04:00
ioconfig.logger.info('slave[{}]> vnc port {} ready'.format(slave_name, listenport))
#response = { 'status':'VNC', 'fqdn':external_url, 'host':myip, 'port':listenport, 'encrypt':'0', 'true_color':'1', 'ticket':ticket['ticket'] }
response = { 'status':'VNC', 'url':vnc_url }
2016-02-15 05:30:43 -05:00
return response
def getmyip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("gmail.com",80))
myip = s.getsockname()[0]
s.close
return myip
if __name__ == '__main__':
#internal module tests
2016-05-08 08:44:19 -04:00
time.sleep(1)
2016-05-16 08:56:40 -04:00
vmvnc(656758)
2016-02-15 05:30:43 -05:00