add basic db setup, add vm expirations and cron to handle them, and add fields for sweetalert button classes

This commit is contained in:
Jordan Rodgers 2017-12-08 09:51:45 -05:00
parent 6debe3d9fd
commit 9beecf12fa
7 changed files with 186 additions and 8 deletions

26
app.py
View file

@ -2,9 +2,9 @@ import os
import time import time
import psycopg2 import psycopg2
import subprocess import subprocess
from db import *
from starrs import * from starrs import *
from proxmox import * from proxmox import *
from proxmoxer import ProxmoxAPI
from flask import Flask, render_template, request, redirect, send_from_directory from flask import Flask, render_template, request, redirect, send_from_directory
app = Flask(__name__) app = Flask(__name__)
@ -17,9 +17,6 @@ app.config["GIT_REVISION"] = subprocess.check_output(
['git', 'rev-parse', '--short', 'HEAD']).decode('utf-8').rstrip() ['git', 'rev-parse', '--short', 'HEAD']).decode('utf-8').rstrip()
user = 'proxstar' user = 'proxstar'
starrs = connect_starrs(
app.config['STARRS_DB_NAME'], app.config['STARRS_DB_USER'],
app.config['STARRS_DB_HOST'], app.config['STARRS_DB_PASS'])
@app.route("/") @app.route("/")
@ -57,6 +54,7 @@ def vm_details(vmid):
vm['iso'] = get_vm_iso(proxmox, vmid, config=vm['config']) vm['iso'] = get_vm_iso(proxmox, vmid, config=vm['config'])
vm['interfaces'] = get_vm_interfaces( vm['interfaces'] = get_vm_interfaces(
proxmox, vm['vmid'], config=vm['config']) proxmox, vm['vmid'], config=vm['config'])
vm['expire'] = get_vm_expire(vmid, app.config['VM_EXPIRE_MONTHS']).strftime('%m/%d/%Y')
return render_template('vm_details.html', username='com6056', vm=vm) return render_template('vm_details.html', username='com6056', vm=vm)
else: else:
return '', 403 return '', 403
@ -74,6 +72,18 @@ def vm_power(vmid, action):
return '', 403 return '', 403
@app.route("/vm/<string:vmid>/renew", methods=['POST'])
def vm_renew(vmid):
proxmox = connect_proxmox(app.config['PROXMOX_HOST'],
app.config['PROXMOX_USER'],
app.config['PROXMOX_PASS'])
if int(vmid) in get_user_allowed_vms(proxmox, user):
renew_vm_expire(vmid, app.config['VM_EXPIRE_MONTHS'])
return '', 200
else:
return '', 403
@app.route("/vm/<string:vmid>/eject", methods=['POST']) @app.route("/vm/<string:vmid>/eject", methods=['POST'])
def iso_eject(vmid): def iso_eject(vmid):
proxmox = connect_proxmox(app.config['PROXMOX_HOST'], proxmox = connect_proxmox(app.config['PROXMOX_HOST'],
@ -104,10 +114,14 @@ def delete(vmid):
proxmox = connect_proxmox(app.config['PROXMOX_HOST'], proxmox = connect_proxmox(app.config['PROXMOX_HOST'],
app.config['PROXMOX_USER'], app.config['PROXMOX_USER'],
app.config['PROXMOX_PASS']) 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'])
if int(vmid) in get_user_allowed_vms(proxmox, user): if int(vmid) in get_user_allowed_vms(proxmox, user):
vmname = get_vm_config(proxmox, vmid)['name'] vmname = get_vm_config(proxmox, vmid)['name']
delete_vm(proxmox, starrs, vmid) delete_vm(proxmox, starrs, vmid)
delete_starrs(starrs, vmname) delete_starrs(starrs, vmname)
delete_vm_expire(vmid)
return '', 200 return '', 200
else: else:
return '', 403 return '', 403
@ -118,6 +132,9 @@ def create():
proxmox = connect_proxmox(app.config['PROXMOX_HOST'], proxmox = connect_proxmox(app.config['PROXMOX_HOST'],
app.config['PROXMOX_USER'], app.config['PROXMOX_USER'],
app.config['PROXMOX_PASS']) 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'])
if request.method == 'GET': if request.method == 'GET':
usage = get_user_usage(proxmox, 'proxstar') usage = get_user_usage(proxmox, 'proxstar')
limits = get_user_usage_limits(user) limits = get_user_usage_limits(user)
@ -149,6 +166,7 @@ def create():
register_starrs(starrs, name, user, mac, register_starrs(starrs, name, user, mac,
get_next_ip(starrs, get_next_ip(starrs,
app.config['STARRS_IP_RANGE'])[0][0]) app.config['STARRS_IP_RANGE'])[0][0])
get_vm_expire(vmid, app.config['VM_EXPIRE_MONTHS'])
return redirect("/proxstar/vm/{}".format(vmid)) return redirect("/proxstar/vm/{}".format(vmid))

19
cron.py Normal file
View file

@ -0,0 +1,19 @@
from db import *
from config import *
from starrs import *
from proxmox import *
def process_expired_vms():
proxmox = connect_proxmox(PROXMOX_HOST, PROXMOX_USER, PROXMOX_PASS)
starrs = connect_starrs(STARRS_DB_NAME, STARRS_DB_USER, STARRS_DB_HOST,
STARRS_DB_PASS)
expired_vms = get_expired_vms()
for vmid in expired_vms:
vmname = get_vm_config(proxmox, vmid)['name']
delete_vm(proxmox, starrs, vmid)
delete_starrs(starrs, vmname)
delete_vm_expire(vmid)
process_expired_vms()

62
db.py Normal file
View file

@ -0,0 +1,62 @@
from sqlalchemy import create_engine, exists
from sqlalchemy.orm import sessionmaker
from dateutil.relativedelta import relativedelta
import datetime
from db_init import VM_Expiration, Base
engine = create_engine('sqlite:///proxstar.db')
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()
def get_vm_expire(vmid, months):
if session.query(exists().where(VM_Expiration.id == vmid)).scalar():
expire = session.query(VM_Expiration).filter(
VM_Expiration.id == vmid).one().expire_date
else:
expire = datetime.date.today() + relativedelta(months=months)
new_expire = VM_Expiration(id=vmid, expire_date=expire)
session.add(new_expire)
session.commit()
return expire
def renew_vm_expire(vmid, months):
if session.query(exists().where(VM_Expiration.id == vmid)).scalar():
expire = session.query(VM_Expiration).filter(
VM_Expiration.id == vmid).one()
new_expire = datetime.date.today() + relativedelta(months=months)
expire.expire_date = new_expire
session.commit()
else:
expire = datetime.date.today() + relativedelta(months=months)
new_expire = VM_Expiration(id=vmid, expire_date=expire)
session.add(new_expire)
session.commit()
def delete_vm_expire(vmid):
if session.query(exists().where(VM_Expiration.id == vmid)).scalar():
expire = session.query(VM_Expiration).filter(
VM_Expiration.id == vmid).one()
session.delete(expire)
session.commit()
def get_expired_vms():
expired = []
today = datetime.date.today().strftime('%Y-%m-%d')
expire = session.query(VM_Expiration).filter(
VM_Expiration.expire_date < today).all()
for vm in expire:
expired.append(vm.id)
return expired
#for entry in session.query(VM_Expiration).all():
# print(entry.id, entry.expire_date)
#expiry = session.query(VM_Expiration).filter(VM_Expiration.id == 100).one()
#print(expiry.expire_date)

17
db_init.py Normal file
View file

@ -0,0 +1,17 @@
from sqlalchemy import Column, ForeignKey, Integer, String, Date
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy import create_engine
Base = declarative_base()
class VM_Expiration(Base):
__tablename__ = 'vm_expiration'
id = Column(Integer, primary_key=True)
expire_date = Column(Date, nullable=False)
engine = create_engine('sqlite:///proxstar.db')
Base.metadata.create_all(engine)

View file

@ -81,6 +81,15 @@ table, th, td {
border-radius: 15px; border-radius: 15px;
} }
.proxstar-renewbtn {
width: 20px;
height: 20px;
text-align: center;
padding: 0px 0px 0px 0px;
border-radius: 15px;
line-height: 1;
}
.resource-usage { .resource-usage {
width: 50%; width: 50%;
margin: 0 auto; margin: 0 auto;

View file

@ -244,8 +244,13 @@ $("#eject-iso").click(function(){
title: `Are you sure you want to eject ${iso}?`, title: `Are you sure you want to eject ${iso}?`,
icon: "warning", icon: "warning",
buttons: { buttons: {
cancel: true, cancel: {
delete: { text: "Cancel",
visible: true,
closeModal: true,
className: "",
},
eject: {
text: "Eject", text: "Eject",
closeModal: false, closeModal: false,
className: "swal-button--danger", className: "swal-button--danger",
@ -262,6 +267,13 @@ $("#eject-iso").click(function(){
}).then((response) => { }).then((response) => {
return swal(`${iso} is now ejecting!`, { return swal(`${iso} is now ejecting!`, {
icon: "success", icon: "success",
buttons: {
ok: {
text: "OK",
closeModal: true,
className: "",
}
}
}); });
}).then(() => { }).then(() => {
window.location = `/proxstar/vm/${vmid}`; window.location = `/proxstar/vm/${vmid}`;
@ -294,11 +306,16 @@ $("#change-iso").click(function(){
title: 'Choose an ISO to mount:', title: 'Choose an ISO to mount:',
content: iso_list, content: iso_list,
buttons: { buttons: {
cancel: true, cancel: {
text: "Cancel",
visible: true,
closeModal: true,
className: "",
},
select: { select: {
text: "Select", text: "Select",
closeModal: false, closeModal: false,
className: "swal-button", className: "swal-button--danger",
} }
}, },
dangerMode: true, dangerMode: true,
@ -313,6 +330,13 @@ $("#change-iso").click(function(){
}).then((response) => { }).then((response) => {
return swal(`${iso} is now being mounted!`, { return swal(`${iso} is now being mounted!`, {
icon: "success", icon: "success",
buttons: {
ok: {
text: "OK",
closeModal: true,
className: "",
}
}
}); });
}).then(() => { }).then(() => {
window.location = `/proxstar/vm/${vmid}`; window.location = `/proxstar/vm/${vmid}`;
@ -335,3 +359,25 @@ $("#change-iso").click(function(){
} }
}); });
}); });
$("#renew-vm").click(function(){
const vmname = $(this).data('vmname')
const vmid = $(this).data('vmid')
fetch(`/proxstar/vm/${vmid}/renew`, {
credentials: 'same-origin',
method: 'post'
}).then((response) => {
return swal(`${vmname} is now renewing!`, {
icon: "success",
});
}).then(() => {
window.location = `/proxstar/vm/${vmid}`;
}).catch(err => {
if (err) {
swal("Uh oh...", `Unable to renew ${vmname}. Please try again later.`, "error");
} else {
swal.stopLoading();
swal.close();
}
});
});

View file

@ -75,6 +75,13 @@
<dd>{{ vm['config']['cores'] * vm['config'].get('sockets', 1) }}</dd> <dd>{{ vm['config']['cores'] * vm['config'].get('sockets', 1) }}</dd>
<dt>Memory</dt> <dt>Memory</dt>
<dd>{{ vm['config']['memory'] }} MB</dd> <dd>{{ vm['config']['memory'] }} MB</dd>
<dt>Expiration</dt>
<dd>
{{ vm['expire'] }}
<button class="btn btn-success proxstar-renewbtn" id="renew-vm" name="renew" data-vmid="{{ vm['vmid'] }}" data-vmname="{{ vm['name'] }}">
<span class="glyphicon glyphicon-plus"></span>
</button>
</dd>
</dl> </dl>
</div> </div>
</div> </div>