commit 568f2420104ff6446d9223565b8aa1012dcf94f2 Author: Jordan Rodgers Date: Sun Nov 26 11:48:51 2017 -0500 so far you can view and create vms diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4acd06b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +config.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..e68bdc9 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# proxstar diff --git a/app.py b/app.py new file mode 100644 index 0000000..640ac4d --- /dev/null +++ b/app.py @@ -0,0 +1,55 @@ +import os +import time +import psycopg2 +from starrs import * +from proxmox import * +from proxmoxer import ProxmoxAPI +from flask import Flask, render_template, request + + +app = Flask(__name__) + + +config = os.path.join(app.config.get('ROOT_DIR', os.getcwd()), "config.py") + + +app.config.from_pyfile(config) + + +user = 'ram' +proxmox = connect_proxmox(app.config['PROXMOX_HOST'], app.config['PROXMOX_USER'], app.config['PROXMOX_PASS']) +starrs = connect_starrs(app.config['STARRS_DB_NAME'], app.config['STARRS_DB_USER'], app.config['STARRS_DB_HOST'], app.config['STARRS_DB_PASS']) +#print(get_vms_for_user(user)) +#vmid = create_vm(proxmox, starrs, user, name) +#time.sleep(10) +#delete_vm(proxmox, starrs, vmid, name) + + +@app.route("/") +def get_vms(): + vms = get_vms_for_user(proxmox, user) + for vm in vms: + vm['config'] = get_vm_config(proxmox, vm['vmid']) + vm['disk_size'] = get_vm_disk_size(proxmox, vm['vmid'], config=vm['config']) + return render_template('get_vms.html', vms=vms) + + +@app.route("/create") +def create(): + return render_template('create.html') + + +@app.route("/get_create", methods=['POST']) +def get_create(): + name = request.form['name'] + cores = request.form['cores'] + memory = request.form['memory'] + disk = request.form['disk'] + print(name, cores, memory, disk) + vmid = create_vm(proxmox, starrs, user, name, cores, memory, disk) + print(vmid) + return vmid + + +if __name__ == "__main__": + app.run() diff --git a/proxmox.py b/proxmox.py new file mode 100644 index 0000000..43e21b0 --- /dev/null +++ b/proxmox.py @@ -0,0 +1,75 @@ +import time +from proxmoxer import ProxmoxAPI + + +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): + return proxmox.pools(user).get()['members'] + + +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_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_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] + else: + disk_size = disk_size[1].split('=')[1] + return disk_size + + +def create_vm(proxmox, starrs, user, name, cores, memory, disk): + 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:10', net0='virtio,bridge=vmbr0', pool=user) + time.sleep(3) + mac = get_vm_mac(proxmox, vmid) + register_starrs(starrs, name, user, mac, get_next_ip(starrs, '49net Public Fixed')[0][0]) + return vmid + +def delete_vm(proxmox, starrs, vmid, name): + print(vmid) + print(get_vm_node(proxmox, vmid)) + node = proxmox.nodes(get_vm_node(proxmox, vmid)) + node.qemu(vmid).delete() + delete_starrs(starrs, name) diff --git a/starrs.py b/starrs.py new file mode 100644 index 0000000..970684b --- /dev/null +++ b/starrs.py @@ -0,0 +1,49 @@ +import psycopg2 + + +def connect_starrs(db, user, host, password): + try: + starrs = psycopg2.connect("dbname='{}' user='{}' host='{}' password='{}'".format(db, user, host, password)) + except: + print("Unable to connect to STARRS database.") + raise + return starrs + + +def get_next_ip(starrs, range_name): + c = starrs.cursor() + try: + c.execute("BEGIN") + c.callproc("api.initialize", ('root',)) + c.callproc("api.get_address_from_range", (range_name,)) + results = c.fetchall() + c.execute("COMMIT") + finally: + c.close() + return results + + +def register_starrs(starrs, name, owner, mac, addr): + c = starrs.cursor() + try: + c.execute("BEGIN") + c.callproc("api.initialize", ('root',)) + c.callproc("api.create_system_quick", (name, owner, 'members', mac, addr, 'csh.rit.edu', 'dhcp', True)) + results = c.fetchall() + c.execute("COMMIT") + finally: + c.close() + return results + + +def delete_starrs(starrs, name): + c = starrs.cursor() + try: + c.execute("BEGIN") + c.callproc("api.initialize", ('root',)) + c.callproc("api.remove_system", (name,)) + results = c.fetchall() + c.execute("COMMIT") + finally: + c.close() + return results diff --git a/templates/create.html b/templates/create.html new file mode 100644 index 0000000..6ebfba5 --- /dev/null +++ b/templates/create.html @@ -0,0 +1,29 @@ + + + + + + + +VM List + +Create VM + +
+ + + + + + + + + +
+ + + diff --git a/templates/get_vms.html b/templates/get_vms.html new file mode 100644 index 0000000..c4396c1 --- /dev/null +++ b/templates/get_vms.html @@ -0,0 +1,36 @@ + + + + + + + +Create VM + + + + + + + + + +{% for vm in vms %} + + + + + + + +{% endfor %} +
Name Status Cores Memory Disk Size
{{ vm['name'] }} {{ vm['status'] }} {{ vm['config']['cores'] * vm['config']['sockets'] }} {{ vm['config']['memory'] }} MB {{ vm['disk_size'] }}
+ +{{ vms }} + + +