phyidgen function
This commit is contained in:
parent
49e70c2449
commit
4f43446eef
3 changed files with 114 additions and 65 deletions
33
grid.py
33
grid.py
|
@ -8,7 +8,6 @@ import json
|
||||||
import re
|
import re
|
||||||
import datetime
|
import datetime
|
||||||
import random
|
import random
|
||||||
import netaddr
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
#import local packages
|
#import local packages
|
||||||
|
@ -33,7 +32,7 @@ def read(data):
|
||||||
dbf = open(dbfile, 'r')
|
dbf = open(dbfile, 'r')
|
||||||
data = json.load(dbf)
|
data = json.load(dbf)
|
||||||
dbf.close()
|
dbf.close()
|
||||||
logger.info('{}> --> {}'.format(dbfile, data))
|
logger.info('grid> --> {}'.format(dbfile))
|
||||||
return data
|
return data
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.critical('{}> '.format(e))
|
logger.critical('{}> '.format(e))
|
||||||
|
@ -47,7 +46,7 @@ def create(json):
|
||||||
dbf = open(dbfile, 'w')
|
dbf = open(dbfile, 'w')
|
||||||
json.dump(data, dbf)
|
json.dump(data, dbf)
|
||||||
dbf.close()
|
dbf.close()
|
||||||
logger.info('grid> {} --> {}'.format(data, dbfile))
|
logger.info('grid> <-- {}'.format(data))
|
||||||
return data
|
return data
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.critical('grid> {}'.format(e))
|
logger.critical('grid> {}'.format(e))
|
||||||
|
@ -61,6 +60,29 @@ def delete(unit_type, unit_id):
|
||||||
os.remove(dbfile)
|
os.remove(dbfile)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def phyidgen(slave_name, unit_type):
|
||||||
|
""" scans all current db files and generate new id within a range between 1000 and 9999, and avoid any duplicates """
|
||||||
|
full_list = list(range(1000,10000))
|
||||||
|
exclude_list = []
|
||||||
|
directory = 'db/'
|
||||||
|
for dbfile in os.listdir(directory):
|
||||||
|
filename = os.fsdecode(dbfile)
|
||||||
|
if filename.startswith(str(unit_type)):
|
||||||
|
db_fullpath = os.path.join(directory, filename)
|
||||||
|
dbf = open(db_fullpath, 'r')
|
||||||
|
data = json.load(dbf)
|
||||||
|
if data['slave'] == str(slave_name):
|
||||||
|
exclude_list.append(data['phyid'])
|
||||||
|
dbf.close()
|
||||||
|
valid_list = list(set(full_list) - set(exclude_list))
|
||||||
|
if len(valid_list) > 1:
|
||||||
|
choice = random.choice(valid_list)
|
||||||
|
logger.info('grid> physical id generated: {}'.format(choice))
|
||||||
|
return choice
|
||||||
|
else:
|
||||||
|
logger.critical('grid> no free physical ids!')
|
||||||
|
return none
|
||||||
|
|
||||||
def analyze_happiness(region_id):
|
def analyze_happiness(region_id):
|
||||||
""" analyzes grid data for the reuqested region and returns proposed slave_id,
|
""" analyzes grid data for the reuqested region and returns proposed slave_id,
|
||||||
based on a "happiness" factor. happiness means alive and free :) """
|
based on a "happiness" factor. happiness means alive and free :) """
|
||||||
|
@ -148,7 +170,7 @@ def generate_ipv4(region_name, how_many=1):
|
||||||
ip_range_min = ioconfig.parser.get(str(region_name), 'ipv4_min')
|
ip_range_min = ioconfig.parser.get(str(region_name), 'ipv4_min')
|
||||||
ip_range_max = ioconfig.parser.get(str(region_name), 'ipv4_max')
|
ip_range_max = ioconfig.parser.get(str(region_name), 'ipv4_max')
|
||||||
|
|
||||||
region_ipset = netaddr.IPSet(netaddr.IPRange(ip_range_min, ip_range_max))
|
#region_ipset = netaddr.IPSet(netaddr.IPRange(ip_range_min, ip_range_max))
|
||||||
region_ips = []
|
region_ips = []
|
||||||
for ip in region_ipset:
|
for ip in region_ipset:
|
||||||
region_ips.append(ip)
|
region_ips.append(ip)
|
||||||
|
@ -331,9 +353,8 @@ def sync(cached=True):
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print(sync())
|
|
||||||
#print(query_happiness(0))
|
#print(query_happiness(0))
|
||||||
#print(generate_ipv4(0,3))
|
#print(generate_ipv4(0,3))
|
||||||
#print(generate_vmid())
|
#print(generate_vmid())
|
||||||
print(queryvm(147344))
|
print(phyidgen('warrior', 'kvm'))
|
||||||
|
|
||||||
|
|
145
plugin.py
145
plugin.py
|
@ -1,7 +1,6 @@
|
||||||
#. -*- coding: utf-8 -
|
#. -*- coding: utf-8 -
|
||||||
# required proxmox permissions: PVEAdmin
|
# required proxmox permissions: PVEAdmin
|
||||||
#
|
#
|
||||||
# afx 2015-2017
|
|
||||||
|
|
||||||
# site
|
# site
|
||||||
from proxmoxer import ProxmoxAPI
|
from proxmoxer import ProxmoxAPI
|
||||||
|
@ -32,29 +31,31 @@ def auth(slave_name):
|
||||||
def create(json):
|
def create(json):
|
||||||
""" create an unit. returns JSON with data """
|
""" create an unit. returns JSON with data """
|
||||||
try:
|
try:
|
||||||
region_id = ioconfig.parser.get(str(json['region']), 'regionid')
|
region_name = json['region']
|
||||||
region_fullname = ioconfig.parser.get(str(json['region']), 'fullname')
|
region_id = ioconfig.parser.get(region_name, 'regionid')
|
||||||
|
region_fullname = ioconfig.parser.get(region_name, 'fullname')
|
||||||
except:
|
except:
|
||||||
ioconfig.logger.error('grid> region not found')
|
ioconfig.logger.error('grid> region not found')
|
||||||
return None
|
return None
|
||||||
vm_name_utf8 = json['hostname']
|
|
||||||
vm_name = unidecode(vm_name_utf8)
|
|
||||||
try:
|
try:
|
||||||
vm_pass = json['rootpass']
|
slave_name = json['slave']
|
||||||
except:
|
except Exception as e:
|
||||||
vm_pass = '!%%^)@&&(K3B'
|
ioconfig.logger.warning('grid> slave not predefined. I will query for a capable one.')
|
||||||
#slave_name = str(grid.query_happiness(region_id, weight)) #TODO: provide weight parameters here and calculate route
|
#slave_name = str(grid.query_happiness(region_id, weight))
|
||||||
#slave_name = 'lexx'
|
#slave_name = 'lexx'
|
||||||
slave_name = 'warrior'
|
slave_name = 'warrior'
|
||||||
|
ioconfig.logger.info('grid> slave [{}] selected'.format(slave_name))
|
||||||
unit_id = int(time.time() * 10000 * 10000)
|
|
||||||
phy_id = grid.phyidgen(json['type'])
|
|
||||||
proxobject = auth(slave_name)
|
proxobject = auth(slave_name)
|
||||||
real_slave_name = proxobject.cluster.status.get()[0]['name']
|
real_slave_name = proxobject.cluster.status.get()[0]['name']
|
||||||
description = vm_name + ' (' + str(unit_id) + '-' + str(phy_id) + ')\n' + 'owned by ' + json['clientemail'] + ' (' + json['clientid'] + ')\n'
|
|
||||||
|
unit_id = int(time.time() * 10000 * 10000) #currently unit_id is just a timestamp
|
||||||
if json['type'] == 'deploy':
|
phy_id = grid.phyidgen(slave_name, json['type'])
|
||||||
#create partition
|
description = ' (' + str(unit_id) + ' - ' + str(phy_id) + ')\n' + 'owned by ' + json['clientemail'] + ' (' + json['clientid'] + ')\n'
|
||||||
|
|
||||||
|
if json['type'] == 'kvm':
|
||||||
|
vm_name_utf8 = json['hostname']
|
||||||
|
vm_name = unidecode(vm_name_utf8)
|
||||||
image_name = 'vm-' + str(phy_id) + '-disk-1'
|
image_name = 'vm-' + str(phy_id) + '-disk-1'
|
||||||
try:
|
try:
|
||||||
local_storage = proxobject.nodes(real_slave_name).storage('lvm')
|
local_storage = proxobject.nodes(real_slave_name).storage('lvm')
|
||||||
|
@ -62,69 +63,95 @@ def create(json):
|
||||||
ioconfig.logger.info('%s[%s]> allocated %s as %s' % (json['clientemail'], slave_name, json['hdd'], image_name))
|
ioconfig.logger.info('%s[%s]> allocated %s as %s' % (json['clientemail'], slave_name, json['hdd'], image_name))
|
||||||
except:
|
except:
|
||||||
ioconfig.logger.info('%s[%s]> unable to allocate %s' % (json['clientemail'], slave_name, image_name))
|
ioconfig.logger.info('%s[%s]> unable to allocate %s' % (json['clientemail'], slave_name, image_name))
|
||||||
response = { 'status':'FAIL' }
|
response = { 'status':'vol_alloc_failed' }
|
||||||
return response
|
return response
|
||||||
|
try:
|
||||||
create_result = proxobject.nodes(real_slave_name).qemu.post(vmid=int(phy_id),
|
create_result = proxobject.nodes(real_slave_name).qemu.post(vmid=int(phy_id),
|
||||||
name=vm_name,
|
name=vm_name,
|
||||||
onboot=1,
|
onboot=1,
|
||||||
sockets=1,
|
sockets=1,
|
||||||
cores=json['cpu'],
|
cores=json['cpu'],
|
||||||
memory=json['mem'],
|
memory=json['mem'],
|
||||||
scsihw='virtio-scsi-pci',
|
scsihw='virtio-scsi-pci',
|
||||||
scsi0='file=lvm:' + image_name + ',discard=on',
|
scsi0='file=lvm:' + image_name + ',discard=on',
|
||||||
description=description)
|
description=description)
|
||||||
|
except:
|
||||||
|
return { 'status': 'kvm_create_failed' }
|
||||||
data = { 'unit_id': int(unit_id),
|
data = { 'unit_id': int(unit_id),
|
||||||
'type': 'kvm',
|
'type': 'kvm',
|
||||||
'clientid': json['clientid'],
|
'clientid': json['clientid'],
|
||||||
'clientemail': json['clientemail'],
|
'clientemail': json['clientemail'],
|
||||||
'hostname': vm_name,
|
'hostname': vm_name,
|
||||||
'region': region_fullname,
|
'region': region_name,
|
||||||
'slave': slave_name,
|
'slave': slave_name,
|
||||||
'phyid': phy_id
|
'phyid': phy_id,
|
||||||
|
'net0if': json['net0if']
|
||||||
}
|
}
|
||||||
response = { 'status': 'deploy_created', 'unit_id': unit_id, 'hostname': vm_name, 'password': vm_pass, 'slave': real_slave_name }
|
grid.create(data)
|
||||||
|
response = { 'status': 'kvm_created', 'unit_id': unit_id, 'hostname': vm_name, 'region': region_name, 'slave': real_slave_name }
|
||||||
|
|
||||||
if json['type'] == 'router':
|
if json['type'] == 'lxc':
|
||||||
create_result = proxobject.nodes(real_slave_name).lxc.post(vmid=int(phy_id),
|
vm_name_utf8 = json['hostname']
|
||||||
hostname=vm_name,
|
vm_name = unidecode(vm_name_utf8)
|
||||||
onboot=1,
|
image_name = 'vm-' + str(phy_id) + '-disk-1'
|
||||||
unprivileged=1,
|
try:
|
||||||
password=vm_pass,
|
local_storage = proxobject.nodes(real_slave_name).storage('lvm')
|
||||||
cores=json['cpu'],
|
storage_create_result = local_storage.content.post(vmid=phy_id, filename=image_name, size=json['hdd'] + 'G')
|
||||||
memory=json['mem'],
|
ioconfig.logger.info('%s[%s]> allocated %s as %s' % (json['clientemail'], slave_name, json['hdd'], image_name))
|
||||||
net0='name=eth0,bridge=' + json['bridge_id'] + ',gw=' + json['region_gw'] + ',hwaddr=' + json['macaddr'] + ',ip=' + json['ipv4addr'] + '/' + json['region_netmask'],
|
except:
|
||||||
ostemplate='backup:vztmpl/debian-9.0-standard_9.0-2_amd64.tar.gz',
|
ioconfig.logger.info('%s[%s]> unable to allocate %s' % (json['clientemail'], slave_name, image_name))
|
||||||
rootfs='volume=lvm:' + image_name,
|
response = { 'status':'vol_alloc_failed' }
|
||||||
swap=32,
|
return response
|
||||||
description=description)
|
try:
|
||||||
|
vm_pass = json['rootpass']
|
||||||
|
except:
|
||||||
|
vm_pass = '!%%^)@&&(K3B'
|
||||||
|
try:
|
||||||
|
create_result = proxobject.nodes(real_slave_name).lxc.post(vmid=int(phy_id),
|
||||||
|
hostname=vm_name,
|
||||||
|
onboot=1,
|
||||||
|
unprivileged=1,
|
||||||
|
password=vm_pass,
|
||||||
|
cores=json['cpu'],
|
||||||
|
memory=json['mem'],
|
||||||
|
net0='name=eth0,bridge=' + json['net0if'] + ',gw=' + json['region_gw'] + ',hwaddr=' + json['macaddr'] + ',ip=' + json['ipv4addr'] + '/' + json['region_netmask'],
|
||||||
|
ostemplate='backup:vztmpl/debian-9.0-standard_9.0-2_amd64.tar.gz',
|
||||||
|
rootfs='volume=lvm:' + image_name,
|
||||||
|
swap=32,
|
||||||
|
description=description)
|
||||||
|
except:
|
||||||
|
return { 'status': 'lxc_create_failed' }
|
||||||
data = { 'unit_id': int(unit_id),
|
data = { 'unit_id': int(unit_id),
|
||||||
'type': 'lxc',
|
'type': 'lxc',
|
||||||
'clientid': json['clientid'],
|
'clientid': json['clientid'],
|
||||||
'clientemail': json['clientemail'],
|
'clientemail': json['clientemail'],
|
||||||
'hostname': vm_name,
|
'hostname': vm_name,
|
||||||
'region': region_fullname,
|
'region': region_name,
|
||||||
'slave': slave_name,
|
'slave': slave_name,
|
||||||
'phyid': phy_id
|
'phyid': phy_id,
|
||||||
|
'net0if': json['net0if']
|
||||||
}
|
}
|
||||||
response = { 'status': 'router_created', 'unit_id': unit_id, 'hostname': vm_name, 'password': vm_pass, 'slave': real_slave_name }
|
grid.create(data)
|
||||||
|
response = { 'status': 'lxc_created', 'unit_id': unit_id, 'hostname': vm_name, 'region': region_name, 'slave': real_slave_name }
|
||||||
|
|
||||||
|
if json['type'] == 'br':
|
||||||
if json['type'] == 'bridge':
|
try:
|
||||||
|
create_result = proxobject.nodes(real_slave_name).network.post(iface='vmbr' + int(phy_id),
|
||||||
|
type='bridge',
|
||||||
|
autostart=1)
|
||||||
|
except:
|
||||||
|
return { 'status': 'br_create_failed' }
|
||||||
data = { 'unit_id': int(unit_id),
|
data = { 'unit_id': int(unit_id),
|
||||||
'type': 'vmbr',
|
'type': 'br',
|
||||||
'clientid': json['clientid'],
|
'clientid': json['clientid'],
|
||||||
'clientemail': json['clientemail'],
|
'clientemail': json['clientemail'],
|
||||||
'region': region_fullname,
|
'region': region_name,
|
||||||
'slave': slave_name,
|
'slave': slave_name,
|
||||||
'phyid': phy_id
|
'phyid': phy_id
|
||||||
}
|
}
|
||||||
#TODO: CREATE BRIDGE
|
grid.create(data)
|
||||||
response = { 'status': 'bridge_created', 'unit_id': unit_id, 'hostname': vm_name, 'password': vm_pass, 'slave': real_slave_name }
|
response = { 'status': 'bridge_created', 'unit_id': unit_id, 'region': region_name, 'slave': real_slave_name, 'phyid': phy_id }
|
||||||
|
|
||||||
time.sleep(7) #wait few seconds for the slave to prepare the machine for initial run
|
|
||||||
|
|
||||||
grid.create(data)
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def remove(json):
|
def remove(json):
|
||||||
|
@ -144,7 +171,9 @@ def remove(json):
|
||||||
|
|
||||||
def query(json):
|
def query(json):
|
||||||
""" return the db info of an unit """
|
""" return the db info of an unit """
|
||||||
return grid.query(json)
|
query = grid.query(json)
|
||||||
|
query['status'] = 'query_success'
|
||||||
|
return query
|
||||||
|
|
||||||
def status(json):
|
def status(json):
|
||||||
""" returns the status of an unit """
|
""" returns the status of an unit """
|
||||||
|
|
|
@ -2,7 +2,6 @@ uwsgi
|
||||||
pyOpenSSL
|
pyOpenSSL
|
||||||
requests
|
requests
|
||||||
falcon
|
falcon
|
||||||
netaddr
|
|
||||||
proxmoxer
|
proxmoxer
|
||||||
proxmox-deploy
|
proxmox-deploy
|
||||||
websockify
|
websockify
|
||||||
|
|
Loading…
Reference in a new issue