various fixes 2

This commit is contained in:
deflax 2017-10-15 14:38:38 +03:00
parent 2399334a18
commit 541bd3663e
5 changed files with 121 additions and 56 deletions

View file

@ -1,5 +1,5 @@
from flask import render_template, abort, redirect, url_for, abort, flash, request, current_app, make_response, g from flask import render_template, abort, redirect, url_for, abort, flash, request, current_app, make_response, g
from flask_login import login_required, login_user, logout_user from flask_login import fresh_login_required, login_user, logout_user
from flask_sqlalchemy import get_debug_queries from flask_sqlalchemy import get_debug_queries
from . import admin from . import admin
@ -29,35 +29,35 @@ def after_request(response):
return response return response
@admin.route("/", methods=['GET']) @admin.route("/", methods=['GET'])
@login_required @fresh_login_required
@admin_required @admin_required
def index(): def index():
return redirect(url_for('admin.list_users')) return redirect(url_for('admin.list_users'))
@admin.route("/listdeployments", methods=['GET']) @admin.route("/listdeployments", methods=['GET'])
@login_required @fresh_login_required
@admin_required @admin_required
def list_deployments(): def list_deployments():
alldeployments = Deployment.query.filter_by(deleted=False).order_by(Deployment.daysleft.asc()).all() alldeployments = Deployment.query.filter_by(deleted=False).order_by(Deployment.daysleft.asc()).all()
return render_template('admin/list_deployments.html', deployments=alldeployments) return render_template('admin/list_deployments.html', deployments=alldeployments)
@admin.route("/listservices", methods=['GET']) @admin.route("/listservices", methods=['GET'])
@login_required @fresh_login_required
@admin_required @admin_required
def list_services(): def list_services():
allservices = Service.query.filter_by(deleted=False).order_by(Service.daysleft.asc()).all() allservices = Service.query.filter_by(deleted=False).order_by(Service.daysleft.asc()).all()
return render_template('admin/list_services.html', services=allservices) return render_template('admin/list_services.html', services=allservices)
@admin.route("/listdomains", methods=['GET']) @admin.route("/listdomains", methods=['GET'])
@login_required @fresh_login_required
@admin_required @admin_required
def list_domains(): def list_domains():
alldomains = Domain.query.filter_by(deleted=False).order_by(Domain.daysleft.asc()).all() alldomains = Domain.query.filter_by(deleted=False).order_by(Domain.daysleft.asc()).all()
return render_template('admin/list_domains.html', domains=alldomains) return render_template('admin/list_domains.html', domains=alldomains)
@admin.route("/listrecyclebin", methods=['GET']) @admin.route("/listrecyclebin", methods=['GET'])
@login_required @fresh_login_required
@admin_required @admin_required
def list_recyclebin(): def list_recyclebin():
deployments = Deployment.query.filter_by(protected=False).order_by(Deployment.daysleft.asc()).all() deployments = Deployment.query.filter_by(protected=False).order_by(Deployment.daysleft.asc()).all()
@ -66,14 +66,14 @@ def list_recyclebin():
return render_template('admin/list_recyclebin.html', deployments=deployments, services=services, domains=domains) return render_template('admin/list_recyclebin.html', deployments=deployments, services=services, domains=domains)
@admin.route("/listaddresses", methods=['GET']) @admin.route("/listaddresses", methods=['GET'])
@login_required @fresh_login_required
@admin_required @admin_required
def list_addresses(): def list_addresses():
alladdresses = Address.query.order_by(Address.ip.asc()).all() alladdresses = Address.query.order_by(Address.ip.asc()).all()
return render_template('admin/list_addresses.html', addresses=alladdresses) return render_template('admin/list_addresses.html', addresses=alladdresses)
@admin.route("/addr2pool", methods=['GET', 'POST']) @admin.route("/addr2pool", methods=['GET', 'POST'])
@login_required @fresh_login_required
@admin_required @admin_required
def addr2pool(): def addr2pool():
alladdrlist = [] alladdrlist = []
@ -94,14 +94,14 @@ def addr2pool():
return render_template('admin/addr2pool.html', form=form, alladdresses=alladdrlist) return render_template('admin/addr2pool.html', form=form, alladdresses=alladdrlist)
@admin.route("/listusers", methods=['GET']) @admin.route("/listusers", methods=['GET'])
@login_required @fresh_login_required
@admin_required @admin_required
def list_users(): def list_users():
allusers = User.query.filter_by(active=True).order_by(User.last_seen.desc()).all() allusers = User.query.filter_by(active=True).order_by(User.last_seen.desc()).all()
return render_template('admin/list_users.html', users=allusers) return render_template('admin/list_users.html', users=allusers)
@admin.route("/charge/<int:user_pid>", methods=['GET', 'POST']) @admin.route("/charge/<int:user_pid>", methods=['GET', 'POST'])
@login_required @fresh_login_required
@admin_required @admin_required
def charge(user_pid=0): def charge(user_pid=0):
cuser = User.query.filter_by(pid=user_pid).first() cuser = User.query.filter_by(pid=user_pid).first()
@ -118,14 +118,14 @@ def charge(user_pid=0):
return render_template('admin/charge.html', form=form, usr=cuser) return render_template('admin/charge.html', form=form, usr=cuser)
@admin.route("/listtransactions", methods=['GET']) @admin.route("/listtransactions", methods=['GET'])
@login_required @fresh_login_required
@admin_required @admin_required
def list_transactions(): def list_transactions():
alltransactions = Transaction.query.order_by(Transaction.date_created.desc()).all() alltransactions = Transaction.query.order_by(Transaction.date_created.desc()).all()
return render_template('admin/list_transactions.html', transactions=alltransactions) return render_template('admin/list_transactions.html', transactions=alltransactions)
@admin.route("/transaction/<int:user_pid>", methods=['GET']) @admin.route("/transaction/<int:user_pid>", methods=['GET'])
@login_required @fresh_login_required
@admin_required @admin_required
def transaction(user_pid=0): def transaction(user_pid=0):
cuser = User.query.filter_by(pid=user_pid).first() cuser = User.query.filter_by(pid=user_pid).first()
@ -147,7 +147,7 @@ def transaction(user_pid=0):
return render_template('uinvoice/transactions.html', transactions=transactions, translist=translist, labelslist=labelslist, cuser=cuser) return render_template('uinvoice/transactions.html', transactions=transactions, translist=translist, labelslist=labelslist, cuser=cuser)
@admin.route("/dashboard/<int:user_pid>", methods=['GET']) @admin.route("/dashboard/<int:user_pid>", methods=['GET'])
@login_required @fresh_login_required
@admin_required @admin_required
def dashboard(user_pid=0): def dashboard(user_pid=0):
cuser = User.query.filter_by(pid=user_pid).first() cuser = User.query.filter_by(pid=user_pid).first()

View file

@ -38,7 +38,7 @@ addEventListener("DOMContentLoaded", function() {
//alert(request.responseText); //alert(request.responseText);
}; };
// We point the request at the appropriate command // We point the request at the appropriate command
request.open("GET", "/vmanager/" + command + "/" + vmid, true); request.open("GET", "/vmanager/command/" + command + "/" + vmid, true);
// and then we send it off // and then we send it off
request.send(); request.send();
alert("command " + command + " executed."); alert("command " + command + " executed.");

View file

@ -116,7 +116,7 @@ addEventListener("DOMContentLoaded", function() {
//alert(request.responseText); //alert(request.responseText);
}; };
// We point the request at the appropriate command // We point the request at the appropriate command
request.open("GET", "/vmanager/" + command + "/" + vmid, true); request.open("GET", "/vmanager/command/" + command + "/" + vmid, true);
// and then we send it off // and then we send it off
request.send(); request.send();
alert("command " + command + " executed."); alert("command " + command + " executed.");
@ -185,7 +185,7 @@ addEventListener("DOMContentLoaded", function() {
</p> </p>
<p> <p>
<img class="icon icons8-Remote-Control" width="32" height="32" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAC+0lEQVRYhcWXz04aURTGZ+HCB+jCB2Dh0kWXXbBh7sREsPuuTBc+QB+A1MBctKBLgtGYVuPChYmuak2mDWXuBGfU0mpDhWCoKMb/KK0Q7pwuxmGGQflTBr3JJMNd3N93z/edAzBMFxbiRQfC0haLCUEBMs36xWGnV+jpBqvpcvliAxyWeISJwPrF/icRwTAMw/rFfoSJwGLxzZNVw+kVejgs8Swf89p6sMsXG3B6hV79s54BhKVlxJPXVhEIk6jLFxvoGDw4Hu9zB+Wdkdlk3hOS960eI150cFiaQAGyOjge79P3Wb/Yz2JCOrJicDze5w7Jmbcfz4/CMoWJL0XwTMlH9wUN8SKHAmTVvMdhaYzDsVe2wPWnkQgOSxOIJ6MmUQ4Ok0Xb4M1EDL2Tn1mrwGJCbIU3E2EFIkyEjuBLuxRiWRXiORXW0ipMbzYWYU1+y51wH/zHsQrWdfEXYGm3tUx0dPNothZeqhjvhRLATJNKtAcPbqR865cVs8fFsgY7LQIsfqcwvUkhnjNEfd5X6zLhDm38Ng+r/4Z/SNAqSMgYoIhCoVDS9hPHal0wR+fTJ4gXuY7gYZnCQoJWS64cGqClXQrXdwLkw1oBvvXLylBQ3mtp8j3UanPbxnv+xvBeOtA6IFcwcrD6yxAw9uni2hOSs+ZR3DY8c6H5u3WkVm9L65sAAADS5zbD338zPC+Wobq//JPC2R8DXKZa6SOKjXD92c6rUCwDxLL14Zrb1iqig9uGMwzDuIPyjjlwEYVC6kyFq9taP8MyBSGjQqF0f9L1wLmDG6mW4YgXHSOzybz5kJWkYXD2qhaktxoAwEKiQzjDaL9QPJPKwZR4Wz1oZpPCzR0oail74m4Enxahc7i+OCy9GJ5ScmYREUUbOmGZwlpahdSZCitJtToLzPC2PW9VhB6yCjXmvNVzW+DNKqH7bs2DrfBGIma3aN33fVfgjUR0/eatingU+EMiHhVuFvFyUjkYnU+fDAXlvUeF68vpFXpdga/Pu/Gn8h8Gr4IF2ejgSgAAAABJRU5ErkJggg=="> <img class="icon icons8-Remote-Control" width="32" height="32" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAC+0lEQVRYhcWXz04aURTGZ+HCB+jCB2Dh0kWXXbBh7sREsPuuTBc+QB+A1MBctKBLgtGYVuPChYmuak2mDWXuBGfU0mpDhWCoKMb/KK0Q7pwuxmGGQflTBr3JJMNd3N93z/edAzBMFxbiRQfC0haLCUEBMs36xWGnV+jpBqvpcvliAxyWeISJwPrF/icRwTAMw/rFfoSJwGLxzZNVw+kVejgs8Swf89p6sMsXG3B6hV79s54BhKVlxJPXVhEIk6jLFxvoGDw4Hu9zB+Wdkdlk3hOS960eI150cFiaQAGyOjge79P3Wb/Yz2JCOrJicDze5w7Jmbcfz4/CMoWJL0XwTMlH9wUN8SKHAmTVvMdhaYzDsVe2wPWnkQgOSxOIJ6MmUQ4Ok0Xb4M1EDL2Tn1mrwGJCbIU3E2EFIkyEjuBLuxRiWRXiORXW0ipMbzYWYU1+y51wH/zHsQrWdfEXYGm3tUx0dPNothZeqhjvhRLATJNKtAcPbqR865cVs8fFsgY7LQIsfqcwvUkhnjNEfd5X6zLhDm38Ng+r/4Z/SNAqSMgYoIhCoVDS9hPHal0wR+fTJ4gXuY7gYZnCQoJWS64cGqClXQrXdwLkw1oBvvXLylBQ3mtp8j3UanPbxnv+xvBeOtA6IFcwcrD6yxAw9uni2hOSs+ZR3DY8c6H5u3WkVm9L65sAAADS5zbD338zPC+Wobq//JPC2R8DXKZa6SOKjXD92c6rUCwDxLL14Zrb1iqig9uGMwzDuIPyjjlwEYVC6kyFq9taP8MyBSGjQqF0f9L1wLmDG6mW4YgXHSOzybz5kJWkYXD2qhaktxoAwEKiQzjDaL9QPJPKwZR4Wz1oZpPCzR0oail74m4Enxahc7i+OCy9GJ5ScmYREUUbOmGZwlpahdSZCitJtToLzPC2PW9VhB6yCjXmvNVzW+DNKqH7bs2DrfBGIma3aN33fVfgjUR0/eatingU+EMiHhVuFvFyUjkYnU+fDAXlvUeF68vpFXpdga/Pu/Gn8h8Gr4IF2ejgSgAAAABJRU5ErkJggg==">
<button class="btn btn-default btn-info" onclick="window.open('/vmanager/vmvnc/{{ deploy.machine_id }}', '_blank');"><span class="glyphicon glyphicon-console" aria-hidden="true"></span> Console</button> <button class="btn btn-default btn-info" onclick="window.open('/vmanager/command/vmvnc/{{ deploy.machine_id }}', '_blank');"><span class="glyphicon glyphicon-console" aria-hidden="true"></span> Console</button>
{% else %} {% else %}
<button class="command command-vmstart btn btn-default btn-success" value="vmstart" vmid="{{ deploy.machine_id }}"><span class="glyphicon glyphicon-play" aria-hidden="true"></span> Start</button> <button class="command command-vmstart btn btn-default btn-success" value="vmstart" vmid="{{ deploy.machine_id }}"><span class="glyphicon glyphicon-play" aria-hidden="true"></span> Start</button>
{% endif %} {% endif %}
@ -333,11 +333,11 @@ addEventListener("DOMContentLoaded", function() {
</div> </div>
{% endif %} {% endif %}
{% if inv_services != [] %}
<div class="col-md-12"> <div class="col-md-12">
<div class="panel panel-info" id="services"> <div class="panel panel-info" id="services">
<div class="panel-heading">Services</div> <div class="panel-heading">Services</div>
<div class="panel-body"> <div class="panel-body">
{% if inv_services != [] %}
<div id="no-more-tables"> <div id="no-more-tables">
<table class="table table-hover table-striped table-condensed cf"> <table class="table table-hover table-striped table-condensed cf">
<thead> <thead>
@ -377,7 +377,7 @@ addEventListener("DOMContentLoaded", function() {
</div> </div>
<button class="btn btn-default" onclick="window.open('{{ url_for('smanager.requestservice') }}','_self')"><img class="icon icons8-Key-2" width="32" height="32" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAADwUlEQVRYhdXYz0/bVhwA8Bz4I/Yn9A/gwKGHHApxiENwo8IG2rSqh/XUw267cRmJY8dOQpIGOq2cdtguFZNoUQQeiOBnm7h4iB+TRkJwkiJtdZ0GQzPLeTtU0bIQ0qQ8wP1K30sU6X3y/X7fs18cjk89Bsn1fjwEAgQj7nhpQXMFeeilBY1gpV2cFkgsCG7fCAwL8E5fWBQmk7IeX1bNTM6ASrkG83odKuUazOQMGF9WzYmEXPWFxd+xAO+8FphziuvzMRKDkcBKLKt/H2gWzOv1C/NAs2ByRdXdJDD9kc2oc4rru1LcSFj4dTIpn6z9edIR1pqZnAG/mt06GWXExStD+hiJ+SKR1ff/MnvCNVfz69mt1yOMOI8chwV4J0YCq9fKtSZ/aEA3Ccyh6Q0cKdAXFoUUVzJbK8IsFc4IVqoSrFSln+fffWgm83odpriSiVNgDxlukFzvn0zKeuvizFLhzEuL224SDLhJMOClBIlZKpx10+qJhFxBtrPHY9mZaLqgty5EsFLVTYKB5h9CsFK1m1ZH0wX9XlSaRQIkGHEnkzPOLXIZYCZnQIIRd5AAvbSgNQ7h5qSf59/hlCAOkuv9g+R6P06BNWoxf9oNUCnXoJcWNCRAV5C/cJaYFwWjsUmoxfxpN5ukka4gD5EAR8LtK3iZVMo1OBJGVMG7EWmv3QxeJjM5AxKstIsE+Hk8G4+mC29RAqPpo+pYbPMJEiAWBLe/fPyy0st8dXEO1rGQcA8J0OFwOPwRaT+5op47Cz8m51ZLcHwma92NSK+GQ+JnSIBYgHe6SWBedhb5QwN6KAEuKBqcXS1VkCL9kc1ou0deL6395sdt+OinAygfv/8MKdI5xfWNMuLigzmlyh/2Vkn+0IAPn27D737+A26+suDTl9aVIufdJDATK6rWzRv13GoJ4pQAv184gI3vy8f1/yF/WCtbPkYsImv30PTGKE6Bvc53kqI5kZTrY7GstaBo5/CtSOQz6XC83zweCrBtb3UUiLpIcN9LC5UUV2x7AlwL8kMxNL1xy0uLeoorvrE5UtBTvxU12yMfc6q9kZ4Q0FxBHjayExL57u412r1r2qKSnYC2Qg6HwOtPvt2/7P73tIqljyw/Kz2zDbA1t4//gTglnF7pn1AXRad2N+eDJ8obV4C/c+3A5ugEjKXVk7EZed62wPR+BfrCYvlGgZ4Q0GLpI6v1uquUa3A8nn07TPHf3ihwaHrjlp+VnuEUOL0/t6UnllVraVe3B645nFNcnyvA3/FQIOELi2Vb4bqJfwEpWpu91pyNygAAAABJRU5ErkJggg==">Request</button> <button class="btn btn-default" onclick="window.open('{{ url_for('smanager.requestservice') }}','_self')"><img class="icon icons8-Key-2" width="32" height="32" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAADwUlEQVRYhdXYz0/bVhwA8Bz4I/Yn9A/gwKGHHApxiENwo8IG2rSqh/XUw267cRmJY8dOQpIGOq2cdtguFZNoUQQeiOBnm7h4iB+TRkJwkiJtdZ0GQzPLeTtU0bIQ0qQ8wP1K30sU6X3y/X7fs18cjk89Bsn1fjwEAgQj7nhpQXMFeeilBY1gpV2cFkgsCG7fCAwL8E5fWBQmk7IeX1bNTM6ASrkG83odKuUazOQMGF9WzYmEXPWFxd+xAO+8FphziuvzMRKDkcBKLKt/H2gWzOv1C/NAs2ByRdXdJDD9kc2oc4rru1LcSFj4dTIpn6z9edIR1pqZnAG/mt06GWXExStD+hiJ+SKR1ff/MnvCNVfz69mt1yOMOI8chwV4J0YCq9fKtSZ/aEA3Ccyh6Q0cKdAXFoUUVzJbK8IsFc4IVqoSrFSln+fffWgm83odpriSiVNgDxlukFzvn0zKeuvizFLhzEuL224SDLhJMOClBIlZKpx10+qJhFxBtrPHY9mZaLqgty5EsFLVTYKB5h9CsFK1m1ZH0wX9XlSaRQIkGHEnkzPOLXIZYCZnQIIRd5AAvbSgNQ7h5qSf59/hlCAOkuv9g+R6P06BNWoxf9oNUCnXoJcWNCRAV5C/cJaYFwWjsUmoxfxpN5ukka4gD5EAR8LtK3iZVMo1OBJGVMG7EWmv3QxeJjM5AxKstIsE+Hk8G4+mC29RAqPpo+pYbPMJEiAWBLe/fPyy0st8dXEO1rGQcA8J0OFwOPwRaT+5op47Cz8m51ZLcHwma92NSK+GQ+JnSIBYgHe6SWBedhb5QwN6KAEuKBqcXS1VkCL9kc1ou0deL6395sdt+OinAygfv/8MKdI5xfWNMuLigzmlyh/2Vkn+0IAPn27D737+A26+suDTl9aVIufdJDATK6rWzRv13GoJ4pQAv184gI3vy8f1/yF/WCtbPkYsImv30PTGKE6Bvc53kqI5kZTrY7GstaBo5/CtSOQz6XC83zweCrBtb3UUiLpIcN9LC5UUV2x7AlwL8kMxNL1xy0uLeoorvrE5UtBTvxU12yMfc6q9kZ4Q0FxBHjayExL57u412r1r2qKSnYC2Qg6HwOtPvt2/7P73tIqljyw/Kz2zDbA1t4//gTglnF7pn1AXRad2N+eDJ8obV4C/c+3A5ugEjKXVk7EZed62wPR+BfrCYvlGgZ4Q0GLpI6v1uquUa3A8nn07TPHf3ihwaHrjlp+VnuEUOL0/t6UnllVraVe3B645nFNcnyvA3/FQIOELi2Vb4bqJfwEpWpu91pyNygAAAABJRU5ErkJggg==">Request</button>
{% else %} {% else %}
<button class="btn btn-default btn-lg btn-block" onclick="window.open('{{ url_for('smanager.requestservice') }}','_self')"><img class="icon icons8-Key-2" width="48" height="48" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAADwUlEQVRYhdXYz0/bVhwA8Bz4I/Yn9A/gwKGHHApxiENwo8IG2rSqh/XUw267cRmJY8dOQpIGOq2cdtguFZNoUQQeiOBnm7h4iB+TRkJwkiJtdZ0GQzPLeTtU0bIQ0qQ8wP1K30sU6X3y/X7fs18cjk89Bsn1fjwEAgQj7nhpQXMFeeilBY1gpV2cFkgsCG7fCAwL8E5fWBQmk7IeX1bNTM6ASrkG83odKuUazOQMGF9WzYmEXPWFxd+xAO+8FphziuvzMRKDkcBKLKt/H2gWzOv1C/NAs2ByRdXdJDD9kc2oc4rru1LcSFj4dTIpn6z9edIR1pqZnAG/mt06GWXExStD+hiJ+SKR1ff/MnvCNVfz69mt1yOMOI8chwV4J0YCq9fKtSZ/aEA3Ccyh6Q0cKdAXFoUUVzJbK8IsFc4IVqoSrFSln+fffWgm83odpriSiVNgDxlukFzvn0zKeuvizFLhzEuL224SDLhJMOClBIlZKpx10+qJhFxBtrPHY9mZaLqgty5EsFLVTYKB5h9CsFK1m1ZH0wX9XlSaRQIkGHEnkzPOLXIZYCZnQIIRd5AAvbSgNQ7h5qSf59/hlCAOkuv9g+R6P06BNWoxf9oNUCnXoJcWNCRAV5C/cJaYFwWjsUmoxfxpN5ukka4gD5EAR8LtK3iZVMo1OBJGVMG7EWmv3QxeJjM5AxKstIsE+Hk8G4+mC29RAqPpo+pYbPMJEiAWBLe/fPyy0st8dXEO1rGQcA8J0OFwOPwRaT+5op47Cz8m51ZLcHwma92NSK+GQ+JnSIBYgHe6SWBedhb5QwN6KAEuKBqcXS1VkCL9kc1ou0deL6395sdt+OinAygfv/8MKdI5xfWNMuLigzmlyh/2Vkn+0IAPn27D737+A26+suDTl9aVIufdJDATK6rWzRv13GoJ4pQAv184gI3vy8f1/yF/WCtbPkYsImv30PTGKE6Bvc53kqI5kZTrY7GstaBo5/CtSOQz6XC83zweCrBtb3UUiLpIcN9LC5UUV2x7AlwL8kMxNL1xy0uLeoorvrE5UtBTvxU12yMfc6q9kZ4Q0FxBHjayExL57u412r1r2qKSnYC2Qg6HwOtPvt2/7P73tIqljyw/Kz2zDbA1t4//gTglnF7pn1AXRad2N+eDJ8obV4C/c+3A5ugEjKXVk7EZed62wPR+BfrCYvlGgZ4Q0GLpI6v1uquUa3A8nn07TPHf3ihwaHrjlp+VnuEUOL0/t6UnllVraVe3B645nFNcnyvA3/FQIOELi2Vb4bqJfwEpWpu91pyNygAAAABJRU5ErkJggg==">Request</button> <!--<button class="btn btn-default btn-lg btn-block" onclick="window.open('{{ url_for('smanager.requestservice') }}','_self')"><img class="icon icons8-Key-2" width="48" height="48" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAADwUlEQVRYhdXYz0/bVhwA8Bz4I/Yn9A/gwKGHHApxiENwo8IG2rSqh/XUw267cRmJY8dOQpIGOq2cdtguFZNoUQQeiOBnm7h4iB+TRkJwkiJtdZ0GQzPLeTtU0bIQ0qQ8wP1K30sU6X3y/X7fs18cjk89Bsn1fjwEAgQj7nhpQXMFeeilBY1gpV2cFkgsCG7fCAwL8E5fWBQmk7IeX1bNTM6ASrkG83odKuUazOQMGF9WzYmEXPWFxd+xAO+8FphziuvzMRKDkcBKLKt/H2gWzOv1C/NAs2ByRdXdJDD9kc2oc4rru1LcSFj4dTIpn6z9edIR1pqZnAG/mt06GWXExStD+hiJ+SKR1ff/MnvCNVfz69mt1yOMOI8chwV4J0YCq9fKtSZ/aEA3Ccyh6Q0cKdAXFoUUVzJbK8IsFc4IVqoSrFSln+fffWgm83odpriSiVNgDxlukFzvn0zKeuvizFLhzEuL224SDLhJMOClBIlZKpx10+qJhFxBtrPHY9mZaLqgty5EsFLVTYKB5h9CsFK1m1ZH0wX9XlSaRQIkGHEnkzPOLXIZYCZnQIIRd5AAvbSgNQ7h5qSf59/hlCAOkuv9g+R6P06BNWoxf9oNUCnXoJcWNCRAV5C/cJaYFwWjsUmoxfxpN5ukka4gD5EAR8LtK3iZVMo1OBJGVMG7EWmv3QxeJjM5AxKstIsE+Hk8G4+mC29RAqPpo+pYbPMJEiAWBLe/fPyy0st8dXEO1rGQcA8J0OFwOPwRaT+5op47Cz8m51ZLcHwma92NSK+GQ+JnSIBYgHe6SWBedhb5QwN6KAEuKBqcXS1VkCL9kc1ou0deL6395sdt+OinAygfv/8MKdI5xfWNMuLigzmlyh/2Vkn+0IAPn27D737+A26+suDTl9aVIufdJDATK6rWzRv13GoJ4pQAv184gI3vy8f1/yF/WCtbPkYsImv30PTGKE6Bvc53kqI5kZTrY7GstaBo5/CtSOQz6XC83zweCrBtb3UUiLpIcN9LC5UUV2x7AlwL8kMxNL1xy0uLeoorvrE5UtBTvxU12yMfc6q9kZ4Q0FxBHjayExL57u412r1r2qKSnYC2Qg6HwOtPvt2/7P73tIqljyw/Kz2zDbA1t4//gTglnF7pn1AXRad2N+eDJ8obV4C/c+3A5ugEjKXVk7EZed62wPR+BfrCYvlGgZ4Q0GLpI6v1uquUa3A8nn07TPHf3ihwaHrjlp+VnuEUOL0/t6UnllVraVe3B645nFNcnyvA3/FQIOELi2Vb4bqJfwEpWpu91pyNygAAAABJRU5ErkJggg==">Request</button>-->
{% endif %} {% endif %}
</div> </div>
</div> </div>

View file

@ -12,7 +12,7 @@ class CreateForm(FlaskForm):
region = SelectField('Region:', choices=region_choices, coerce=int) region = SelectField('Region:', choices=region_choices, coerce=int)
invite_key = StringField('Invite Code:', [validators.DataRequired(), validators.Length(6,35)]) invite_key = StringField('Invite Code:', [validators.DataRequired(), validators.Length(6,35)])
def validate_invite_key(self, field): def validate_invite_key(self, field):
if field.data != 'inv1919': if field.data != 'invitation1919':
raise ValidationError('Denied') raise ValidationError('Denied')
submit = SubmitField('Create') submit = SubmitField('Create')

View file

@ -6,7 +6,7 @@ from . import vmanager
from .forms import CreateForm, ActivateForm from .forms import CreateForm, ActivateForm
from .. import db from .. import db
from ..email import send_email from ..email import send_email
from ..models import User, Permission, Transaction, Router, Deployment, Service, Region, Address, Domain, contact_proxmaster from ..models import User, Permission, Transaction, Bridge, Router, Deployment, Service, Region, Address, Domain, contact_proxmaster
from ..decorators import admin_required, permission_required from ..decorators import admin_required, permission_required
import base64 import base64
@ -43,55 +43,71 @@ def createvm():
if current_user.confirmed and form.validate_on_submit(): if current_user.confirmed and form.validate_on_submit():
selected_region = Region.query.filter_by(pid=int(form.region.data)).first() selected_region = Region.query.filter_by(pid=int(form.region.data)).first()
#TODO: Filter switches for the selected region only!
selected_bridge = current_user.inv_bridges.filter_by(deleted=False).all()
if selected_bridge == []:
#no switches in the account. create one...
data = { 'clientid': str(current_user.pid),
'clientemail': str(current_user.email),
'region': str(selected_region.name)
}
query = contact_proxmaster(data, 'brcreate')
if query is not None:
bridge = Bridge(user_id=int(current_user.pid))
db.session.add(bridge)
db.session.commit()
flash('New point created successfully in region "{}".'.format(str(selected_region.description)))
newbridge = True
else:
flash('Point could not be created! Please try again later...')
return redirect(url_for('main.dashboard'))
else:
#bridge found. lets see on which slave it is so we can create the instance on the same slave.
data = {}
query = contact_proxmaster(data, 'brquery', str(selected_bridge.bridge_id))
if query is not None:
newbridge = False
else:
flash('Point found but cannot be used1')
return redirect(url_for('main.dashboard'))
#machine will be installed where the switch physically is
slave_name = query['slave_name']
bridge_id = query['bridge_id']
#create new machine...
data = { 'clientid': str(current_user.pid), data = { 'clientid': str(current_user.pid),
'clientemail': str(current_user.email), 'clientemail': str(current_user.email),
'hostname': 'c' + str(current_user.pid) + str(form.servername.data), 'hostname': str(form.servername.data) + '-c' + str(current_user.pid),
'region': str(selected_region.name), 'region': str(selected_region.name),
'slave': str(slave_name),
'type': 'kvm', 'type': 'kvm',
'cpu': '1', 'cpu': '1',
'mem': '512', 'mem': '512',
'hdd': '20' 'hdd': '20',
'eth0br': str(bridge_id),
'eth0ip': 'AUTO'
} }
try: try:
query = contact_proxmaster(data, 'vmcreate') query = contact_proxmaster(data, 'vmcreate')
except: except:
flash('Region unreachable! Cannot create deployment. Please try again later...') flash('Region not available! Please try again later...')
return redirect(url_for('main.dashboard')) return redirect(url_for('main.dashboard'))
if query is not None: if query is not None:
deployment = Deployment(user_id=int(current_user.pid), machine_alias=query['hostname'], machine_id=query['cube'], machine_cpu=data['cpu'], machine_mem=data['mem'], machine_hdd=data['hdd'], enabled=True, protected=False, daysleft=15, warning=True, discount=0) deployment = Deployment(user_id=int(current_user.pid), machine_alias=query['hostname'], machine_id=query['cube'], machine_cpu=data['cpu'], machine_mem=data['mem'], machine_hdd=data['hdd'], enabled=True, protected=False, daysleft=15, warning=True, discount=0)
db.session.add(deployment) db.session.add(deployment)
db.session.commit() db.session.commit()
flash('Machine created successfully in region "{}".'.format(str(selected_region.description))) flash('New device created successfully in region "{}".'.format(str(selected_region.description)))
return redirect(url_for('main.dashboard'))
else: else:
flash('Machine creation cancelled! Please try again later...') flash('Device could not be created! Please try again later...')
#TODO: cleanup bridge if the machine is new and we were not be able to create it
return redirect(url_for('main.dashboard')) return redirect(url_for('main.dashboard'))
return render_template('vmanager/create.html', form=form) return render_template('vmanager/create.html', form=form)
@vmanager.route('/vmremove/<int:itemid>', methods=['GET', 'POST'])
@login_required
def remove(itemid=0):
data = {}
deploy = Deployment.query.filter_by(machine_id=int(itemid)).first()
if current_user.is_administrator():
if deploy.protected is not True:
try:
query = contact_proxmaster(data, 'vmremove', int(itemid))
flash('Machine {} terminated'.format(itemid))
deploy.deleted = True
deploy.enabled = False
deploy.warning = False
db.session.commit()
except:
flash('Cannot delete machine {}'.format(itemid))
return redirect(url_for('admin.list_recyclebin'))
else:
current_app.logger.warning('Deployment id:{} is protected! Cannot be removed'.format(itemid))
else:
current_app.logger.warning('[WARNING] Unauthorized attempt to remove Deployment id:{}'.format(itemid))
abort(404)
@vmanager.route('/activate/<int:itemid>', methods=['GET', 'POST']) @vmanager.route('/activate/<int:itemid>', methods=['GET', 'POST'])
@login_required @login_required
def activate(itemid=0): def activate(itemid=0):
@ -103,11 +119,13 @@ def activate(itemid=0):
current_app.logger.warning('[ADMIN] Access override for deployment id:{}'.format(itemid)) current_app.logger.warning('[ADMIN] Access override for deployment id:{}'.format(itemid))
elif not itemid in inventory: elif not itemid in inventory:
current_app.logger.error('[{}] Access violation with deployment id: {}'.format(current_user.email, itemid)) current_app.logger.error('[{}] Access violation with deployment id: {}'.format(current_user.email, itemid))
abort(404) abort(403)
deploy = Deployment.query.filter_by(machine_id=itemid).first() deploy = Deployment.query.filter_by(machine_id=itemid).first()
if deploy.enabled == True and deploy.warning == False: if deploy is None:
abort(404) abort(404)
if deploy.enabled == True and deploy.warning == False:
abort(403)
cpu_cost = deploy.machine_cpu * current_app.config['CPU_RATIO'] cpu_cost = deploy.machine_cpu * current_app.config['CPU_RATIO']
mem_cost = ( deploy.machine_mem / 1024 ) * current_app.config['MEM_RATIO'] mem_cost = ( deploy.machine_mem / 1024 ) * current_app.config['MEM_RATIO']
hdd_cost = deploy.machine_hdd * current_app.config['HDD_RATIO'] hdd_cost = deploy.machine_hdd * current_app.config['HDD_RATIO']
@ -133,6 +151,35 @@ def activate(itemid=0):
else: else:
return redirect(url_for('uinvoice.transactions')) return redirect(url_for('uinvoice.transactions'))
current_app.logger.info('[{}] Charge deployment: {}'.format(owner.email, deploy.machine_id)) current_app.logger.info('[{}] Charge deployment: {}'.format(owner.email, deploy.machine_id))
router = current_user.inv_routers.filter_by(deleted=False).all()
if router == []:
#no router. creating...
data = { 'clientid': str(current_user.pid),
'clientemail': str(current_user.email),
'hostname': 'c' + str(current_user.pid) + 'router',
'region': str(selected_region.name),
'slave': str(selected_slave),
'type': 'lxc',
'cpu': '1',
'mem': '128',
'hdd': '1',
'eth0br': str(bridge_id),
'eth0ip': '192.168.9.1',
'eth1br': 'vmbr0',
'eth1ip': str(selected_address.ip)
}
try:
query = contact_proxmaster(data, 'vmcreate')
except:
flash('Region unreachable! Cannot create router. Please try again later...')
return redirect(url_for('main.dashboard'))
if query is not None:
router = Router(user_id=int(current_user.pid), machine_id=query['cube'])
db.session.add(router)
db.session.commit()
today = datetime.utcnow() today = datetime.utcnow()
expiry = today + relativedelta(today, months=+(form.period.data)) expiry = today + relativedelta(today, months=+(form.period.data))
daysleft = expiry - today daysleft = expiry - today
@ -143,11 +190,7 @@ def activate(itemid=0):
deploy.warning = False deploy.warning = False
deploy.enabled = True deploy.enabled = True
deploy.protected = True deploy.protected = True
db.session.commit() db.session.commit()
#router = current_user.inv_routers.filter_by(deleted=False).all()
#if router == []:
transaction = Transaction(user_id=int(owner.pid), description='Deployment {} activated for {} month(s)'.format(str(deploy.machine_alias), form.period.data), value=-total) transaction = Transaction(user_id=int(owner.pid), description='Deployment {} activated for {} month(s)'.format(str(deploy.machine_alias), form.period.data), value=-total)
db.session.add(transaction) db.session.add(transaction)
@ -161,8 +204,30 @@ def activate(itemid=0):
return redirect(url_for('main.dashboard')) return redirect(url_for('main.dashboard'))
return render_template('vmanager/activate.html', form=form, deploy=deploy, cpu_cost=cpu_cost, mem_cost=mem_cost, hdd_cost=hdd_cost, ppm=ppm, discount=discount, total=total, currency=owner.currency) return render_template('vmanager/activate.html', form=form, deploy=deploy, cpu_cost=cpu_cost, mem_cost=mem_cost, hdd_cost=hdd_cost, ppm=ppm, discount=discount, total=total, currency=owner.currency)
@vmanager.route('/vmremove/<int:itemid>', methods=['GET', 'POST'])
@login_required
def remove(itemid=0):
data = {}
deploy = Deployment.query.filter_by(machine_id=int(itemid)).first()
if current_user.is_administrator():
if deploy.protected is not True:
try:
query = contact_proxmaster(data, 'vmremove', int(itemid))
flash('Machine {} terminated'.format(itemid))
deploy.deleted = True
deploy.enabled = False
deploy.warning = False
db.session.commit()
except:
flash('Cannot delete machine {}'.format(itemid))
return redirect(url_for('admin.list_recyclebin'))
else:
current_app.logger.warning('Deployment id:{} is protected! Cannot be removed'.format(itemid))
else:
current_app.logger.warning('[WARNING] Unauthorized attempt to remove Deployment id:{}'.format(itemid))
abort(404)
@vmanager.route('/<cmd>/<int:vmid>') @vmanager.route('/command/<cmd>/<int:vmid>')
@login_required @login_required
def command(cmd=None, vmid=0): def command(cmd=None, vmid=0):
#checks whether this is a valid command #checks whether this is a valid command