so far you can view and create vms

This commit is contained in:
Jordan Rodgers 2017-11-26 11:48:51 -05:00
commit 568f242010
7 changed files with 246 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
config.py

1
README.md Normal file
View file

@ -0,0 +1 @@
# proxstar

55
app.py Normal file
View file

@ -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()

75
proxmox.py Normal file
View file

@ -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)

49
starrs.py Normal file
View file

@ -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

29
templates/create.html Normal file
View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<head>
<style>
table, th, td {
border: 1px solid black;
}
</style>
</head>
<body>
<a href="/proxstar/">VM List</a>
Create VM
<form action="get_create" method="post">
<label for="name">VM Name</label>
<input type="text" name="name">
<label for="cores">Cores</label>
<input type="text" name="cores">
<label for="memory">Memory</label>
<input type="text" name="memory">
<label for="disk">Disk</label>
<input type="text" name="disk">
<input type="submit">
</form>
</body>
</html>

36
templates/get_vms.html Normal file
View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head>
<style>
table, th, td {
border: 1px solid black;
}
</style>
</head>
<body>
<a href="/proxstar/create">Create VM</a>
<table>
<tr>
<th> Name </th>
<th> Status </th>
<th> Cores </th>
<th> Memory </th>
<th> Disk Size </th>
</tr>
{% for vm in vms %}
<tr>
<td> {{ vm['name'] }} </td>
<td> {{ vm['status'] }} </td>
<td> {{ vm['config']['cores'] * vm['config']['sockets'] }} </td>
<td> {{ vm['config']['memory'] }} MB </td>
<td> {{ vm['disk_size'] }} </td>
</tr>
{% endfor %}
</table>
{{ vms }}
</body>
</html>