craete seed function phase 3
This commit is contained in:
parent
c970f0d82a
commit
a5a594a980
11 changed files with 194 additions and 140 deletions
|
@ -39,28 +39,37 @@ def index():
|
||||||
@login_required
|
@login_required
|
||||||
@admin_required
|
@admin_required
|
||||||
def list_deployments():
|
def list_deployments():
|
||||||
alldeployments = Deployment.query.order_by(Deployment.daysleft.asc()).all()
|
alldeployments = Deployment.query.filter_by(cancelled=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
|
@login_required
|
||||||
@admin_required
|
@admin_required
|
||||||
def list_services():
|
def list_services():
|
||||||
allservices = Service.query.order_by(Service.daysleft.asc()).all()
|
allservices = Service.query.filter_by(cancelled=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
|
@login_required
|
||||||
@admin_required
|
@admin_required
|
||||||
def list_domains():
|
def list_domains():
|
||||||
alldomains = Domain.query.order_by(Domain.daysleft.asc()).all()
|
alldomains = Domain.query.filter_by(cancelled=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("/listcancelled", methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
@admin_required
|
||||||
|
def list_cancelled():
|
||||||
|
expdeployments = Deployment.query.filter_by(cancelled=True).all()
|
||||||
|
expservices = Service.query.filter_by(cancelled=True).all()
|
||||||
|
expdomains = Domain.query.filter_by(cancelled=True).all()
|
||||||
|
return render_template('admin/list_cancelled.html', deployments=expdeployments, services=expservices, domains=expdomains)
|
||||||
|
|
||||||
@admin.route("/listaddresses", methods=['GET'])
|
@admin.route("/listaddresses", methods=['GET'])
|
||||||
@login_required
|
@login_required
|
||||||
@admin_required
|
@admin_required
|
||||||
def list_addresses():
|
def list_addresses():
|
||||||
alladdresses = Address.query.order_by(Address.ip.asc()).all()
|
alladdresses = Address.query.filter_by(cancelled=False).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'])
|
||||||
|
@ -143,7 +152,7 @@ def transaction(user_pid=0):
|
||||||
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()
|
||||||
|
|
||||||
inv_deployments = cuser.inv_deployments.order_by(Deployment.date_created.desc()).all()
|
inv_deployments = cuser.inv_deployments.filter_by(cancelled=False).order_by(Deployment.date_created.desc()).all()
|
||||||
inv_deploycubeids = []
|
inv_deploycubeids = []
|
||||||
inv_deployments_list = []
|
inv_deployments_list = []
|
||||||
for invcls in inv_deployments:
|
for invcls in inv_deployments:
|
||||||
|
@ -151,13 +160,13 @@ def dashboard(user_pid=0):
|
||||||
inv_deploycubeids.extend([invcls.machine_id])
|
inv_deploycubeids.extend([invcls.machine_id])
|
||||||
inv_deployments_list.extend([invcls.machine_alias])
|
inv_deployments_list.extend([invcls.machine_alias])
|
||||||
|
|
||||||
inv_services = cuser.inv_services.order_by(Service.date_last_charge.asc()).all()
|
inv_services = cuser.inv_services.filter_by(cancelled=False).order_by(Service.date_last_charge.asc()).all()
|
||||||
inv_services_list = []
|
inv_services_list = []
|
||||||
for invcls in inv_services:
|
for invcls in inv_services:
|
||||||
if invcls.user_id == cuser.pid and invcls.enabled == True:
|
if invcls.user_id == cuser.pid and invcls.enabled == True:
|
||||||
inv_services_list.extend([invcls.description])
|
inv_services_list.extend([invcls.description])
|
||||||
|
|
||||||
inv_domains = cuser.inv_domains.order_by(Domain.date_created.desc()).all()
|
inv_domains = cuser.inv_domains.filter_by(cancelled=False).order_by(Domain.date_created.desc()).all()
|
||||||
inv_domains_list = []
|
inv_domains_list = []
|
||||||
for invcls in inv_domains:
|
for invcls in inv_domains:
|
||||||
if invcls.user_id == cuser.pid and invcls.enabled == True:
|
if invcls.user_id == cuser.pid and invcls.enabled == True:
|
||||||
|
|
|
@ -39,7 +39,7 @@ def terms():
|
||||||
def dashboard():
|
def dashboard():
|
||||||
cuser = current_user
|
cuser = current_user
|
||||||
|
|
||||||
inv_deployments = cuser.inv_deployments.order_by(Deployment.date_created.desc()).all()
|
inv_deployments = cuser.inv_deployments.filter_by(cancelled=False).order_by(Deployment.date_created.desc()).all()
|
||||||
inv_deploycubeids = []
|
inv_deploycubeids = []
|
||||||
inv_deployments_list = []
|
inv_deployments_list = []
|
||||||
for invcls in inv_deployments:
|
for invcls in inv_deployments:
|
||||||
|
@ -47,13 +47,13 @@ def dashboard():
|
||||||
inv_deploycubeids.extend([invcls.machine_id])
|
inv_deploycubeids.extend([invcls.machine_id])
|
||||||
inv_deployments_list.extend([invcls.machine_alias])
|
inv_deployments_list.extend([invcls.machine_alias])
|
||||||
|
|
||||||
inv_services = cuser.inv_services.order_by(Service.date_last_charge.asc()).all()
|
inv_services = cuser.inv_services.filter_by(cancelled=False).order_by(Service.date_last_charge.asc()).all()
|
||||||
inv_services_list = []
|
inv_services_list = []
|
||||||
for invcls in inv_services:
|
for invcls in inv_services:
|
||||||
if invcls.user_id == cuser.pid and invcls.enabled == True:
|
if invcls.user_id == cuser.pid and invcls.enabled == True:
|
||||||
inv_services_list.extend([invcls.description])
|
inv_services_list.extend([invcls.description])
|
||||||
|
|
||||||
inv_domains = cuser.inv_domains.order_by(Domain.date_created.desc()).all()
|
inv_domains = cuser.inv_domains.filter_by(cancelled=False).order_by(Domain.date_created.desc()).all()
|
||||||
inv_domains_list = []
|
inv_domains_list = []
|
||||||
for invcls in inv_domains:
|
for invcls in inv_domains:
|
||||||
if invcls.user_id == cuser.pid and invcls.enabled == True:
|
if invcls.user_id == cuser.pid and invcls.enabled == True:
|
||||||
|
|
|
@ -208,19 +208,38 @@ def contact_proxmaster(data, method, cubeid=0):
|
||||||
url = current_app.config['PROXMASTER_URL']
|
url = current_app.config['PROXMASTER_URL']
|
||||||
data['apikey'] = current_app.config['APIKEY']
|
data['apikey'] = current_app.config['APIKEY']
|
||||||
data_json = json.dumps(data)
|
data_json = json.dumps(data)
|
||||||
|
|
||||||
if method == 'vmcreate':
|
if method == 'vmcreate':
|
||||||
url = '{}/{}'.format(url, method)
|
url = '{}/{}'.format(url, method)
|
||||||
else:
|
else:
|
||||||
url = '{}/{}/{}'.format(url, method, cubeid)
|
url = '{}/{}/{}'.format(url, method, cubeid)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
db_result = requests.post( url, data=data_json, headers={"content-type": "application/json"}, timeout=30 )
|
||||||
proxjson = db_result.json()
|
proxjson = db_result.json()
|
||||||
#print('proxmaster query {}'.format(str(proxjson)))
|
|
||||||
return proxjson
|
return proxjson
|
||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
class Deployment(db.Model):
|
||||||
|
__tablename__ = 'deployments'
|
||||||
|
pid = db.Column(db.Integer, primary_key=True)
|
||||||
|
user_id = db.Column(db.Integer, db.ForeignKey('users.pid')) #FK
|
||||||
|
date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow)
|
||||||
|
date_last_charge = db.Column(db.DateTime)
|
||||||
|
period = db.Column(db.Integer)
|
||||||
|
daysleft = db.Column(db.Integer)
|
||||||
|
warning = db.Column(db.Boolean, default=False)
|
||||||
|
enabled = db.Column(db.Boolean, default=True)
|
||||||
|
cancelled = db.Column(db.Boolean, default=False)
|
||||||
|
|
||||||
|
protected = db.Column(db.Boolean, default=False) #machines with this False will be autodeleted after the warning period is over.
|
||||||
|
connected = db.Column(db.Boolean, default=False) #requires: protected=True, indicate that a connection is enabled
|
||||||
|
machine_id = db.Column(db.BigInteger) #cubeid
|
||||||
|
machine_alias = db.Column(db.String) #dns name
|
||||||
|
machine_cpu = db.Column(db.Integer)
|
||||||
|
machine_mem = db.Column(db.Integer)
|
||||||
|
machine_hdd = db.Column(db.Integer)
|
||||||
|
machine_addresses = db.relationship('Address', backref='deployments', lazy='dynamic')
|
||||||
|
|
||||||
class Service(db.Model):
|
class Service(db.Model):
|
||||||
__tablename__ = 'services'
|
__tablename__ = 'services'
|
||||||
pid = db.Column(db.Integer, primary_key=True) #PK
|
pid = db.Column(db.Integer, primary_key=True) #PK
|
||||||
|
@ -237,27 +256,6 @@ class Service(db.Model):
|
||||||
description = db.Column(db.Unicode)
|
description = db.Column(db.Unicode)
|
||||||
price = db.Column(db.Float)
|
price = db.Column(db.Float)
|
||||||
|
|
||||||
class Deployment(db.Model):
|
|
||||||
__tablename__ = 'deployments'
|
|
||||||
pid = db.Column(db.Integer, primary_key=True)
|
|
||||||
user_id = db.Column(db.Integer, db.ForeignKey('users.pid')) #FK
|
|
||||||
date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow)
|
|
||||||
date_last_charge = db.Column(db.DateTime)
|
|
||||||
period = db.Column(db.Integer)
|
|
||||||
daysleft = db.Column(db.Integer)
|
|
||||||
warning = db.Column(db.Boolean, default=False)
|
|
||||||
enabled = db.Column(db.Boolean, default=True)
|
|
||||||
protected = db.Column(db.Boolean, default=False) #machines with this False will be autodeleted after the warning period is over.
|
|
||||||
cancelled = db.Column(db.Boolean, default=False)
|
|
||||||
|
|
||||||
machine_id = db.Column(db.BigInteger) #cubeid
|
|
||||||
machine_alias = db.Column(db.String) #dns name
|
|
||||||
machine_cpu = db.Column(db.Integer)
|
|
||||||
machine_mem = db.Column(db.Integer)
|
|
||||||
machine_hdd = db.Column(db.Integer)
|
|
||||||
machine_addresses = db.relationship('Address', backref='deployments', lazy='dynamic')
|
|
||||||
|
|
||||||
#NAMESPACE
|
|
||||||
class Region(db.Model):
|
class Region(db.Model):
|
||||||
__tablename__ = 'regions'
|
__tablename__ = 'regions'
|
||||||
pid = db.Column(db.Integer, primary_key=True)
|
pid = db.Column(db.Integer, primary_key=True)
|
||||||
|
|
|
@ -61,7 +61,7 @@ def activate(itemid=0):
|
||||||
service.enabled = True
|
service.enabled = True
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
transaction = Transaction(user_id=int(owner.pid), description='Deployment {} activated for {} month(s)'.format(str(service.description), form.period.data), value=-price)
|
transaction = Transaction(user_id=int(owner.pid), description='Deployment {} activated for {} month(s)'.format(str(service.description), form.period.data), value=-total)
|
||||||
db.session.add(transaction)
|
db.session.add(transaction)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
|
65
app/templates/admin/list_cancelled.html
Normal file
65
app/templates/admin/list_cancelled.html
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block styles %}
|
||||||
|
{{ super() }}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block page_content %}
|
||||||
|
<div class="row">
|
||||||
|
{% include "admin/admin_tasks.html" %}
|
||||||
|
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="panel panel-info" id="deployments">
|
||||||
|
<div class="panel-heading">Deployments</div>
|
||||||
|
<div class="panel-body"><p>
|
||||||
|
<table class="table table-hover table-striped table-condensed cf">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Owner</th>
|
||||||
|
<th>Cube ID</th>
|
||||||
|
<th>Alias</th>
|
||||||
|
<th>CPU</th>
|
||||||
|
<th>Mem</th>
|
||||||
|
<th>HDD</th>
|
||||||
|
<th>Price</th>
|
||||||
|
<th>Last Charged</th>
|
||||||
|
<th>Days Left</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for deploy in deployments %}
|
||||||
|
{% if deploy.enabled == False %}
|
||||||
|
<tr class="danger">
|
||||||
|
{% else %}
|
||||||
|
{% if deploy.warning == True %}
|
||||||
|
<tr class="warning">
|
||||||
|
{% else %}
|
||||||
|
<tr>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
<td><a href="{{ url_for('admin.dashboard', user_pid=deploy.user_id) }}">{{ deploy.owner.email }}</a></td>
|
||||||
|
<td>{{ deploy.machine_id }}</td>
|
||||||
|
<td>{{ deploy.machine_alias }}</font></td>
|
||||||
|
<td>{{ deploy.machine_cpu }}</td>
|
||||||
|
<td>{{ deploy.machine_mem }} MB</td>
|
||||||
|
<td>{{ deploy.machine_hdd }} GB</td>
|
||||||
|
<td>{{ deploy.price }}</td>
|
||||||
|
<td>{{ moment(deploy.date_last_charge).format('lll') }} ({{ moment(deploy.date_last_charge).fromNow() }})</td>
|
||||||
|
<td>{{ deploy.daysleft }}</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -133,27 +133,33 @@ addEventListener("DOMContentLoaded", function() {
|
||||||
<table class="table table-hover table-striped table-condensed cf">
|
<table class="table table-hover table-striped table-condensed cf">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th><!-- Computer icon by Icons8 -->
|
||||||
<th>CPU</th>
|
<img class="icon icons8-Computer" width="32" height="32" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACCklEQVRYhe3XzWvaYADHcf+MHXrYP9XLLuuhyNBFYXQuKwYfoezg20Z8UruWBuu0o25gYc6i2FGGynC+LWw6a22X6tJuYVA8SFk7frula7F1LUZa8IHvIQSSD8/zBPIYDNdhmB66bjFEmGMI3WccVNU7C6HipI0f0wAMEeZ84upRqd6C1FR0rVRvIbCcOLYQIfoPgO6X6i3IamcoVRptMA6qngAcVM1XdyCrHXiiFTD+jC55ohXIagdSU4HJznd7Aqw0AyNfwFRwc6AZ+QIYf6Y/4NH8B0wFN+FeOxhobHh7BBgBRoARYAS4IQArzWCcpHBnJj3QxkkKVvofgGx1D+lyS5ey1b3eAIszUNsofh3aD0lO2oLFKWxrAKPNc9fE8YeP3eLvabd4pHdmzn9o4p7d1wAmzs+yLrEbW8/jzUZR12Lredh9oa6Z470ne4BQOSdtDW0JCjUZDBG+99yEelT+JiP9paxdX/gVvPtYvfS0NpRfF758YpGFOeLEi9xaf8DLRAY0HNfyiTHYvUE8mHkO1rWIJ4GVU/dpOI7a7s9zAanPRZgjBNOrbniTof6As+38OEAk/h7uhdeYX0mi0mhfegmWsm/hTYbwSd49H3CVB181qamcOZgQYSmwnDiuNNq6H82kpoKFaOqP1Tkb1wCTNn7MQgKvhnEwZRxUtTpn4/fYp7cN12H8BeroKDHKz3I9AAAAAElFTkSuQmCC"></th>
|
||||||
<th>Mem</th>
|
<th><!-- Flow Chart icon by Icons8 -->
|
||||||
<th>HDD</th>
|
<img class="icon icons8-Flow-Chart" width="32" height="32" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABlElEQVRYhe2Xz0vCUBzA35/g0T/Bo3+Ah13UIWQgSzQhjE4RHhPq5EHdENSGGkqEdAnpINhliNBOOnU/aBhlp4qIYTA2vNc6JfJ46gQLqX3hA9vjw9vn3d4AMDG+TN+OkxxmFk+64zCzr+nBSS4aLMl69HyoLCJcHqibebGx8oDj65FRFj4WkmxpRoCWGCvACvh7AbHas5FsaQs5rL/9QADVdQVoiYHx53getb6RF2IrDZg1Xopjf+VDVsD/CvBSHGsWD9XRlvHdqbZzpada0q3iJIdZAVbA+gV40h1HsCA2IiWJiZQkhjjh+ckzLdRhn6CFOsoNFsQGfBveosXk1F7dcFG8+X7Hqa4LAAAATnLYfnWgNu91A2b7VFLhgFBRfEe5Bxd3Y/iEoYL4gHJzzRcDJ7noJCBeGypP+qcBs1uRFThgp3L7inKPrh5VVADKveyNrAArYM0CCFrQ4rWhAuPP9sZwgD/bG6NcghY0OICgBRnl7p3J+iQAS7C2eb/acMA8F0uwtmnXnWo7Z7m+TN8OAABf+SW5Q83GlOAAAAAASUVORK5CYII="></th>
|
||||||
<th>Network</th>
|
<th><!-- Electronics icon by Icons8 -->
|
||||||
<th>Control</th>
|
<img class="icon icons8-Electronics" width="32" height="32" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABPUlEQVRYheWXMWuDQBiG/Tn+DCdxNFpdBDtLh0L2rjrW4yIEF+lPcJJMnapL7jy4krXQpN2E0KUuyXUSQlNpGr1+lL5wwze9D7zHx/cqSo/0sFSNqNKMqNL0sFSHzn0+vXIxyYOMN0HGGxeTfOh8FsBitRWL1VZ4CS2Gzn8HwET1tRXTzQVmrZ9y4adcODPWDp3NmLxOEJ1+C2DFdDNf7oSMZ6F6fWSoh6XqYpJ7CS28hBYOZu+yAJwZazsfF5NcD0tVMaJKCzLedHldplyK+Xy5E37KRedzdff4ZkSVBg8AHgE4AHgEpwDcP+3FT/XwvB/vD4wFcPYfkAoAHgE4AHgE4ADgEYAvIvBVDA4AHgE4AHgEnzVB9EUWgI3Z8VH6BcDURvXoZ7mN2dq8pTenlQPlPzejQwDQcvpb9fwDkojR+HkAxLYAAAAASUVORK5CYII="></th>
|
||||||
<th>Remote</th>
|
<th><!-- Memory Slot icon by Icons8 -->
|
||||||
<th>Time Left</th>
|
<!-- Memory Slot icon by Icons8 -->
|
||||||
|
<img class="icon icons8-Memory-Slot" width="32" height="32" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABpklEQVRYhe2XzUsCURTF35/Ssj/DVQ20c9EXBrrJNrVokdQyoUHcRGUfkAViIbbIbNEyF+VDsKmsqVG0RIhxGgdKUCyYOS3MbPogRJhmMRcOD8595/JbXHg8QqyyihDiCHDLjlVOdG1cGqKxtQtxNHAeJoQQwrC0x711Jd4/aTBSkyG+3LeQ7CUMS20zEcFwgNloVmFYajMfwHpa1anlH+X1fqLYHnZS0ucOs+3cb/MsAAvAArAAzAtwUtKr5XNlvc/L7R4v63tcWQ/30zzzvgXGA/iofXj5rD5/kIeRGglwDcZH7YTxUfvgykV9Li7BSA0FMu8ALLU5g4L4dVv/0hJ9wUS4II2H8o+LyUZH2fW0CmdQED92wBkUxERRQ6UGhC5VVF+AeFbDtaThVtawf6ui9grsZFRUasBpScNkpPjM+OhUP0sn3OGC0mn+G0BG0gAAezcqgOalhypQqQHH981ePNs8hYoG15agMCy1dZs3B8CAP1Wd3hVkb+xOcW1el72xO8W9zUueaE72RHOye5uXPvemdwV5wJ+qtgC6yf/vh8QqM9QbwskG2n58EgAAAAAASUVORK5CYII="></th>
|
||||||
|
<th><!-- HDD icon by Icons8 -->
|
||||||
|
<!-- SSD icon by Icons8 -->
|
||||||
|
<img class="icon icons8-SSD" width="32" height="32" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADMElEQVRYhcWXy0/TcADHe/DgwQNHDhz8Izx44LCD0gHycBiDjygcFjV6UfFCohKdrAPdA4JMkZfxrcEgvkdcjLiOrSuPAQ4HTAQdMLYOcWRutF8PphOyTUlc6y/5HLvPp02/yUoQKY6ixrpJSdlzlVpakREoe66ixro5lSvpkFR/4dGOsdnGN3PhTHKkfXSuWO8s/2vAweah6Y9BAb5wZpnkBFS2uGf+KFdq6a2655+DmZaLNPR+DSu19Na0AXm1tl03+4PfpAp4NLgUyau17UobUKJnzr30rMSlCrBORgWVia1NG7DbyHb3z8QlkfvCAlj/KsoaBl6lDVCZXBNjAV6yAG9IwMHmoem0AUc7RkJSyUWq7n4MpJQX1DmyL/Z8kmwBIobXs6GUSyC19I52OrAkdcA9lltOuYRiveP0s9HvMakDeieiq6UG5kJSQKnRdc82HZNU7gsLYL6sQmVyPU2eoIEZGV2QbgEi40EB5U0DU0kB6taRgNRykZO3x+fXyRU11qzzj32SL0Ck7sVMsKDOkZ0IyNfZt1/vWwjLFXDLEfpGam3KNQH9J7rd36NyBbzyrMSL9K7q3y+gaaDt3acfssh9YQGO2ThUJlfX7wAj63DPS78AkQ+LAsoa2IlEQGXL8MIUJ49c5FjHaFBcwJbqhxOcnHJfWMClp9O/lrBT17ft1P3JQM84DzmpejC1oNTSCkKppRUVrR6/meEhJ5VtnmDKAI2FQ/3bCMwMD511GTrrMswMj/q3EWgsHMwMD6MtCo2FQ6M9hkZ7DBoLB6MtmnT9WjoGNxhAUjTUnV6YGR4Hro1gb9MQzAyP43d8ICkaZoZH9ZN5kBQNjYWDzroMkqJxputL0vUiPk4AAAz4hY0FqEws1J1eFOsZFF1xQt3pxZ7GwcSP7ze7QVI0DrWM4fCNDyApGuVXh6Hu9IKkaOxrdidEN4d4iCcSw8YC/hWViV33BAbnBERiwPvPqZ4AZc/9Hy9hRavHr9TSCkJRY80qvOxYanLEZZM3O1dRYmAW83X2HIIgCKJI7zxZdIUJVbR6/HJQoncGSw3s2XX/CfJ19pyMfY7/hcSdEwTxE6x7GguhLb0ZAAAAAElFTkSuQmCC"></th>
|
||||||
|
<th><!-- Services icon by Icons8 -->
|
||||||
|
<img class="icon icons8-Services" width="32" height="32" src="data:image/png;base64,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"></th>
|
||||||
|
<th><!-- Time icon by Icons8 -->
|
||||||
|
<img class="icon icons8-Time" width="32" height="32" src="data:image/png;base64,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"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for deploy in inv_deployments %}
|
{% for deploy in inv_deployments %}
|
||||||
{% if deploy.enabled == False %}
|
{% if deploy.enabled == False %}
|
||||||
<tr class="danger">
|
<tr class="danger">
|
||||||
<td data-title="Name"><b>{% if status[deploy.machine_id] == 'running' %}<font color="green">{% else %}<font color="red">{% endif %}{{ deploy.machine_alias }}</font></b></td>
|
<td data-title="Name"><b>{% if deploy.enabled == True %}<font color="green">{% else %}<font color="red">{% endif %} {{ deploy.machine_alias }}</font></b></td>
|
||||||
<td data-title="CPU">{{ deploy.machine_cpu }} Cores</td>
|
<td data-title="CPU">{{ deploy.machine_cpu }} {% if deploy.machine_cpu > 1 %}cores{% else %}core{% endif %}</td>
|
||||||
<td data-title="Memory">{{ deploy.machine_mem }} MB</td>
|
<td data-title="Memory">{{ deploy.machine_mem }} MB</td>
|
||||||
<td data-title="Disk">{{ deploy.machine_hdd }} GB</td>
|
<td data-title="Disk">{{ deploy.machine_hdd }} GB</td>
|
||||||
<td data-title="Network">{% for addr in deploy.machine_addresses %} {{ addr.ip }}<br /> {% endfor %}</td>
|
|
||||||
<td data-title="Control"> </td>
|
<td data-title="Control"> </td>
|
||||||
<td data-title="Remote"> </td>
|
|
||||||
<td data-title="Time Left"><button class="btn btn-default btn-success" onclick="window.open('/vmanager/activate/{{ deploy.machine_id }}','_self');"><span class="glyphicon glyphicon-bell" aria-hidden="true"></span> Activate</td>
|
<td data-title="Time Left"><button class="btn btn-default btn-success" onclick="window.open('/vmanager/activate/{{ deploy.machine_id }}','_self');"><span class="glyphicon glyphicon-bell" aria-hidden="true"></span> Activate</td>
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if deploy.warning == True %}
|
{% if deploy.warning == True %}
|
||||||
|
@ -161,25 +167,23 @@ addEventListener("DOMContentLoaded", function() {
|
||||||
{% else %}
|
{% else %}
|
||||||
<tr>
|
<tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<td data-title="Name"><a class="rrd" data-toggle="tooltip" title="ID# {{ deploy.machine_id }}<br />Deployment state: {{ status[deploy.machine_id] }}"><b>{% if status[deploy.machine_id] == 'running' %}<font color="green">{% else %}<font color="red">{% endif %}{{ deploy.machine_alias }}</font></b></a></td>
|
<td data-title="Name"><a class="rrd" data-toggle="tooltip" title="Protected: {{ deploy.protected }}<br />Online: {{ deploy.connected }}<br />State: {{ status[deploy.machine_id] }}<br />ID: {{ deploy.machine_id }}"><b>{% if deploy.protected == True %}<font color="green">{% else %}<font color="red">{% endif %}{{ deploy.machine_alias }}</font></b></a></td>
|
||||||
<td data-title="CPU"><a class="rrd" data-toggle="tooltip" title="<img src='data:image/png;base64,{{ rrd[deploy.machine_id]['cpu'] }}' />">{{ deploy.machine_cpu }} Cores</a></td>
|
<td data-title="Network">{% for addr in deploy.machine_addresses %}<a class="rrd" data-toggle="tooltip" title="<img src='data:image/png;base64,{{ rrd[deploy.machine_id]['net'] }}' />"><img class="icon icons8-GPS-Signal" width="24" height="24" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAEW0lEQVRYhe3YT0zbVhwH8HfgwKGHHnrYYYcddkBVT7t0kybNh8kvgTiBJlTdhCba0R03qVo3NBUtUkv88sdOgtapYu0mFQ1tY4BGK9qKaZmYkud/BFzKyBYYGmgRNCGBjf+ovB0SVyklJHEM7aR9pafIVmJ//Ht5z34G4P8AAJHQDxHegm48bkJCj4nFzZQzdPRZux4nByT5jUYRGbK4xZATmFhM1XmFXsoZqtJ7DMoZOkK7IjWQxS0Q4aE87FcVVdPE4pdsnJQ816muWznxViXIXcdthm4hk0PO6EJSzlB1PS/9cX04kYwlt8m7nWr6dFD5qVwkREI/jfBa9jPSSjlDRwAAwOwWXoQI/6JVsmyg2YM/uvD15N8zSztkZmmHxJLb5L0b6lq5ldzjPxiiUfgMAACYXOHXIItViPAWdIXPloyjnKGjFq+4oiY2iQbUkHoqyfiUY7QrYoEIh3LIbbNbeBWAXHdn981p1S0ae0DmP/5mcj4fVykyd+FVJiRczoEmKWeoGgAANLgJhZtKvGIxNTy18hSu0u7WooFoFPkQAABoFL6U3cZdRX9Mt4dPnO4YyRTClVPJWq9ykuHlGMPLMRMSXn8MZAU7RJhAt9ANAAC0O+zQ5seiQCsntbX1xVPFgKUgrbwS//ROirQNJomVV6a1/WbX8PFcNy9lt4Xj2S7Ga0WBjR3K3R4lWRSXjzx/4z6xeEWya7QShpPJXkAAsqPbhISeQtsF4wgq6lBsuWTgfpU0e6Q3LD6JMJwchyx+s+jJS4mNl+aVufWygPshIcLEEJgWq09MR//aKBtYaHQbDmzwywk9FSxUScOBjqCi3vt1STdwN9JwoN0vD3SLCxUB87vb4hWJUU9BAAAAGjtGLl76/veiE3WpyLOdY0TPbbFgIBt52cqJ60YAS5nMdaWeFxfKnQsPFfn2ZyPtH9ycWDQKaDiScoaqGU5c3u+J5pkjzR7h3PtdE8tGAvNHd8VrHMoZqmoMKqP+e7MPDwJpSCUZn3KsnpcWeqPJjecWCT34FYYTdwbUtKFADXn+C3XNwol9uoH24AjfdO1++q2ro6TjxzlDgX3R5GqDX868cy3q0IWjXZGaWo+4/t34Bumd2CItX06QC92TpNLRrSY2ibM/vmnjpFnaFanRXT0bL09eGUxkBqd2yODUDrkdf0TYuwli5UTS+u1vD8uFqolNcuWH6bTFK643XY1er+i1RwMvXzzz+dji7fgjogG1BhEmFo9wmfGJaUdQXnXdmt4aUNPk5/g/RHtUG5/fItKfa+TOgwwJDs1uN3eOZWo94gbjE27WeqQXdMMAyL6WqPOKK13R1adwGlD7Lt0ePmH24E/sAQWf8stxGyclIcKE8YnL9bw0eyogR+s8gtfEYsqwe3GDXxlu7Z1J7YXbDTyU2ALKSXtAju1ele3X7IEn17oHmsYOJd4/uljWH743miKO4JNLyQMLRFjXdHFoXf2fAOpthwJ8XvMve9hz7NcDU4IAAAAASUVORK5CYII="></a> {% endfor %}</td>
|
||||||
|
<td data-title="CPU"><a class="rrd" data-toggle="tooltip" title="<img src='data:image/png;base64,{{ rrd[deploy.machine_id]['cpu'] }}' />">{{ deploy.machine_cpu }} {% if deploy.machine_cpu > 1 %}cores{% else %}core{% endif %}</a></td>
|
||||||
<td data-title="Memory"><a class="rrd" data-toggle="tooltip" title="<img src='data:image/png;base64,{{ rrd[deploy.machine_id]['mem'] }}' />">{{ deploy.machine_mem }} MB</a></td>
|
<td data-title="Memory"><a class="rrd" data-toggle="tooltip" title="<img src='data:image/png;base64,{{ rrd[deploy.machine_id]['mem'] }}' />">{{ deploy.machine_mem }} MB</a></td>
|
||||||
<td data-title="Disk"><a class="rrd" data-toggle="tooltip" title="<img src='data:image/png;base64,{{ rrd[deploy.machine_id]['hdd'] }}' />">{{ deploy.machine_hdd }} GB</a></td>
|
<td data-title="Disk"><a class="rrd" data-toggle="tooltip" title="<img src='data:image/png;base64,{{ rrd[deploy.machine_id]['hdd'] }}' />">{{ deploy.machine_hdd }} GB</a></td>
|
||||||
<td data-title="Network">{% for addr in deploy.machine_addresses %}<a class="rrd" data-toggle="tooltip" title="<img src='data:image/png;base64,{{ rrd[deploy.machine_id]['net'] }}' />">{{ addr.ip }}</a><br />{% endfor %}</td>
|
|
||||||
<td data-title="Control">{% if status[deploy.machine_id] == 'running' %}
|
<td data-title="Control">{% if status[deploy.machine_id] == 'running' %}
|
||||||
<button class="confirm command command-vmshutdown btn btn-default btn-warning" value="vmshutdown" vmid="{{ deploy.machine_id }}"><span class="glyphicon glyphicon-off" aria-hidden="true"></span> Shutdown</button>
|
<button class="confirm command command-vmshutdown btn btn-default btn-warning" value="vmshutdown" vmid="{{ deploy.machine_id }}"><span class="glyphicon glyphicon-off" aria-hidden="true"></span> Shutdown</button>
|
||||||
<button class="confirm command command-vmstop btn btn-default btn-danger" value="vmstop" vmid="{{ deploy.machine_id }}"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> Force Stop</button>
|
<button class="confirm command command-vmstop btn btn-default btn-danger" value="vmstop" vmid="{{ deploy.machine_id }}"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> Force Stop</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 %}</td>
|
{% endif %}
|
||||||
<td data-title="Remote">{% if status[deploy.machine_id] == 'running' %}
|
{% if status[deploy.machine_id] == 'running' %}<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>{% endif %}</td>
|
||||||
<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>{% endif %}
|
|
||||||
{% if deploy.warning == True %}
|
{% if deploy.warning == True %}
|
||||||
<td data-title="Time Left"><button class="btn btn-default btn-success" onclick="window.open('/vmanager/activate/{{ deploy.machine_id }}');"><span class="glyphicon glyphicon-bell" aria-hidden="true"></span> Renew ({{ deploy.daysleft }} days left)</button></td>
|
<td data-title="Time Left"><button class="btn btn-default btn-success" onclick="window.open('/vmanager/activate/{{ deploy.machine_id }}');"><span class="glyphicon glyphicon-bell" aria-hidden="true"></span> Activate ({{ deploy.daysleft }} days left)</button></td>
|
||||||
{% else %}
|
{% else %}
|
||||||
<td data-title="Time Left">{{ deploy.daysleft }} day(s)</td>
|
<td data-title="Time Left">{{ deploy.daysleft }} day(s)</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block title %}Deploy{% endblock %}
|
{% block title %}Create{% endblock %}
|
||||||
|
|
||||||
{% block page_content %}
|
{% block page_content %}
|
||||||
|
|
||||||
|
@ -33,79 +33,37 @@
|
||||||
<br />
|
<br />
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
||||||
<div class="col-md-4">
|
<div class="col-md-12">
|
||||||
<div class="panel panel-info">
|
|
||||||
<div class="panel-heading">{{ product_name }}</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<img src="{{ product_pic }}"></img><br />
|
|
||||||
{{ product_description }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-8">
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">Настройки</div>
|
<div class="panel-heading">Настройки</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<form method="POST" action="{{ url_for('vmanager.deploy', product_id=product_id) }}">
|
<form method="POST" action="{{ url_for('vmanager.createvm') }}">
|
||||||
<p>
|
<p>
|
||||||
{{ form.servername.label }}<br />{{ form.servername(size=42) }}<br />
|
{{ form.servername.label }}<br />{{ form.servername(size=42) }}<br />
|
||||||
{% for error in form.servername.errors %}
|
{% for error in form.servername.errors %}
|
||||||
{{ error }}<br />
|
{{ error }}<br />
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
{{ form.region.label }}<br /> {{ form.region }}<br />
|
{{ form.region.label }}<br /> {{ form.region }}<br />
|
||||||
{% for error in form.region.errors %}
|
{% for error in form.region.errors %}
|
||||||
{{ error }}<br />
|
{{ error }}<br />
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<p>
|
|
||||||
{{ form.vmpassword.label }}<br /> {{ form.vmpassword }}<br />
|
|
||||||
{% for error in form.vmpassword.errors %}
|
|
||||||
{{ error }}<br />
|
|
||||||
{% endfor %}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<div id="noUiSlider" class="noUiSlider"></div>
|
{{ form.invite_key.label }}<br /> {{ form.invite_key }}<br />
|
||||||
<div id="valueInput">
|
|
||||||
{{ form.cpu.label }} {{ form.cpu(class_="noUiSluder") }}<br />
|
|
||||||
</div>
|
|
||||||
{{ form.mem.label }} {{ form.mem }}<br />
|
|
||||||
{{ form.hdd.label }} {{ form.hdd }}<br />
|
|
||||||
{{ form.recipe.label }} {{ form.recipe }}<br />
|
|
||||||
{{ form.ipv4.label }} {{ form.ipv4 }}<br />
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
{{ form.invite_key.label }} {{ form.invite_key }}<br />
|
|
||||||
{% for error in form.invite_key.errors %}
|
{% for error in form.invite_key.errors %}
|
||||||
{{ error }}<br />
|
{{ error }}<br />
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
{{ form.csrf_token() }}
|
{{ form.csrf_token() }}
|
||||||
{{ form.submit }}
|
{{ form.submit }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -3,24 +3,20 @@ from wtforms import StringField, PasswordField, BooleanField, SubmitField, Selec
|
||||||
from wtforms import validators, ValidationError
|
from wtforms import validators, ValidationError
|
||||||
from wtforms.fields.html5 import EmailField
|
from wtforms.fields.html5 import EmailField
|
||||||
|
|
||||||
|
from .. import db
|
||||||
|
|
||||||
class DeployForm(FlaskForm):
|
|
||||||
servername = StringField('Име/Домейн:', [validators.Regexp(message='пример: myservice1.com, myservice2.local', regex='^[a-zA-Z0-9][a-zA-Z0-9-_]{0,61}[a-zA-Z0-9]{0,1}\.([a-zA-Z]{1,6}|[a-zA-Z0-9-]{1,30}\.[a-zA-Z]{2,3})$')])
|
|
||||||
region = SelectField('Регион:')
|
|
||||||
vmpassword = StringField('Парола:', [validators.DataRequired()])
|
|
||||||
cpu = StringField('Процесорни ядра:')
|
|
||||||
mem = StringField('Памет:')
|
|
||||||
hdd = StringField('Дисково пространство:')
|
|
||||||
recipe = SelectField('Рецепта')
|
|
||||||
ipv4 = SelectField('Брой публични IP адреса', choices=[('1', '1'),('2', '2' ), ('3', '3')])
|
|
||||||
invite_key = StringField('Покана', [validators.DataRequired(), validators.Length(6,35)])
|
|
||||||
|
|
||||||
|
class CreateForm(FlaskForm):
|
||||||
|
region_choices = [(1, 'Plovdiv, Bulgaria')]
|
||||||
|
servername = StringField('Domain Name:', [validators.Regexp(message='ex.: myservice1.com, myservice2.local', regex='^[a-zA-Z0-9][a-zA-Z0-9-_]{0,61}[a-zA-Z0-9]{0,1}\.([a-zA-Z]{1,6}|[a-zA-Z0-9-]{1,30}\.[a-zA-Z]{2,3})$'), validators.Length(6,64)])
|
||||||
|
region = SelectField('Region:', choices=region_choices, coerce=int)
|
||||||
|
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 != 'inv1919':
|
||||||
raise ValidationError('Denied')
|
raise ValidationError('Denied')
|
||||||
|
submit = SubmitField('Create')
|
||||||
submit = SubmitField('Deploy')
|
|
||||||
|
|
||||||
class ActivateForm(FlaskForm):
|
class ActivateForm(FlaskForm):
|
||||||
period = SelectField('Deploy Period', choices=[(1, '1 Month'), (3, '3 Months'), (6, '6 Months'), (12, '1 Year'), (24, '2 Years')], coerce=int)
|
period = SelectField('Deploy Period', choices=[(1, '1 Month'), (3, '3 Months'), (6, '6 Months'), (12, '1 Year'), (24, '2 Years')], coerce=int)
|
||||||
submit = SubmitField('Activate')
|
submit = SubmitField('Activate')
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ from flask_login import login_required, login_user, logout_user, current_user
|
||||||
from flask_sqlalchemy import get_debug_queries
|
from flask_sqlalchemy import get_debug_queries
|
||||||
|
|
||||||
from . import vmanager
|
from . import vmanager
|
||||||
from .forms import DeployForm, 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, Deployment, Service, Region, Address, Domain, contact_proxmaster
|
from ..models import User, Permission, Transaction, Deployment, Service, Region, Address, Domain, contact_proxmaster
|
||||||
|
@ -34,17 +34,22 @@ def createvm():
|
||||||
flash('Please update profile info for this operation.')
|
flash('Please update profile info for this operation.')
|
||||||
return redirect(url_for('settings.profile'))
|
return redirect(url_for('settings.profile'))
|
||||||
|
|
||||||
deployment_seeds = Deployment.query.filter_by(protected=False).all()
|
deployment_seeds = current_user.inv_deployments.filter_by(cancelled=False).filter_by(protected=False).all()
|
||||||
if deployment_seeds != []:
|
if deployment_seeds != []:
|
||||||
flash('Offline deployments exist.')
|
flash('Offline deployments still exist.')
|
||||||
return redirect(url_for('main.dashboard'))
|
return redirect(url_for('main.dashboard'))
|
||||||
|
|
||||||
|
form = CreateForm()
|
||||||
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()
|
||||||
|
###
|
||||||
|
#flash('Region: {}'.format(str(selected_region.description)))
|
||||||
|
#return redirect(url_for('main.dashboard'))
|
||||||
|
|
||||||
data = { 'clientid': str(current_user.pid),
|
data = { 'clientid': str(current_user.pid),
|
||||||
'clientname': str(current_user.name),
|
|
||||||
'clientemail': str(current_user.email),
|
'clientemail': str(current_user.email),
|
||||||
'hostname': str(form.deployname.data),
|
'hostname': str(form.servername.data),
|
||||||
'region': form.region.data,
|
'region': str(selected_region.name),
|
||||||
'type': 'kvm',
|
'type': 'kvm',
|
||||||
'cpu': '1',
|
'cpu': '1',
|
||||||
'mem': '512',
|
'mem': '512',
|
||||||
|
@ -57,21 +62,20 @@ def createvm():
|
||||||
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=client_id, product_id=product_id, machine_alias=form.servername.data, machine_id=query['cube'], machine_cpu=form.cpu.data, machine_mem=form.mem.data, machine_hdd=form.hdd.data, enabled=True)
|
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)
|
||||||
db.session.add(deployment)
|
db.session.add(deployment)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
flash('Deploy created successfully in region "{}".'.format(str(selected_region.description)))
|
||||||
flash('Deploy requested.')
|
|
||||||
else:
|
else:
|
||||||
flash('Deploy cancelled! Please try again later...')
|
flash('Deploy cancelled! Please try again later...')
|
||||||
|
|
||||||
return redirect(url_for('main.dashboard'))
|
return redirect(url_for('main.dashboard'))
|
||||||
|
return render_template('vmanager/create.html', form=form)
|
||||||
|
|
||||||
@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):
|
||||||
result = current_user.inv_deployments.all()
|
result = current_user.inv_deployments.filter_by(cancelled=False).all()
|
||||||
inventory = []
|
inventory = []
|
||||||
for invcls in result:
|
for invcls in result:
|
||||||
inventory.extend([invcls.machine_id])
|
inventory.extend([invcls.machine_id])
|
||||||
|
@ -88,7 +92,13 @@ def activate(itemid=0):
|
||||||
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']
|
||||||
ppm = round(cpu_cost + mem_cost + hdd_cost)
|
ppm = round(cpu_cost + mem_cost + hdd_cost)
|
||||||
form = ActivateForm(period=int(deploy.period))
|
|
||||||
|
if deploy.period is None:
|
||||||
|
form = ActivateForm(period=1)
|
||||||
|
total = ppm * 1
|
||||||
|
else:
|
||||||
|
form = ActivateForm(period=int(deploy.period))
|
||||||
|
total = ppm * deploy.period
|
||||||
|
|
||||||
owner = deploy.owner
|
owner = deploy.owner
|
||||||
if owner.confirmed and form.validate_on_submit():
|
if owner.confirmed and form.validate_on_submit():
|
||||||
|
@ -106,21 +116,20 @@ def activate(itemid=0):
|
||||||
deploy.daysleft = daysleft.days + extradays.days
|
deploy.daysleft = daysleft.days + extradays.days
|
||||||
deploy.warning = False
|
deploy.warning = False
|
||||||
deploy.enabled = True
|
deploy.enabled = True
|
||||||
|
deploy.protected = True
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
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)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
owner.wallet = owner.wallet - total
|
owner.wallet = owner.wallet - total
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
flash('Deployment {} activated for {} month(s)'.format(str(deploy.machine_alias), form.period.data))
|
flash('Deployment {} activated for {} month(s)'.format(str(deploy.machine_alias), form.period.data))
|
||||||
if owner.is_administrator:
|
if owner.is_administrator:
|
||||||
return redirect(url_for('admin.list_deployments'))
|
return redirect(url_for('admin.list_deployments'))
|
||||||
else:
|
else:
|
||||||
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, total=(ppm * deploy.period), 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, total=total, currency=owner.currency)
|
||||||
|
|
||||||
|
|
||||||
@vmanager.route('/<cmd>/<int:vmid>')
|
@vmanager.route('/<cmd>/<int:vmid>')
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
scriptdir=`dirname $0`
|
scriptdir=`dirname $0`
|
||||||
cd $scriptdir
|
cd $scriptdir
|
||||||
/bin/bash -c "source ../bin/activate; python3 manage.py autodisable ; python3 manage.py autowarn"
|
/bin/bash -c "source ../bin/activate; python3 manage.py autodisable ; python3 manage.py autowarn ; python3 manage.py autoremove"
|
||||||
|
|
29
manage.py
29
manage.py
|
@ -36,16 +36,31 @@ def deploy():
|
||||||
# create user roles
|
# create user roles
|
||||||
Role.insert_roles()
|
Role.insert_roles()
|
||||||
|
|
||||||
|
@manager.command
|
||||||
|
def autoremove():
|
||||||
|
from app.models import User, Deployment
|
||||||
|
today = datetime.utcnow()
|
||||||
|
print('\nScan for unprotected deployments, lower their days left by 1 and autodelete them if expired. Script Started at {}'.format(today))
|
||||||
|
drafts = Deployment.query.filter_by(cancelled=False).filter_by(protected=False).all()
|
||||||
|
for draft in drafts:
|
||||||
|
daysleft = draft.daysleft
|
||||||
|
daysleft -= 1
|
||||||
|
draft.daysleft = daysleft
|
||||||
|
print('Draft {} will be autoremoved after {} days.'.format(draft.machine_alias, daysleft))
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
@manager.command
|
@manager.command
|
||||||
def autodisable():
|
def autodisable():
|
||||||
from app.models import User, Deployment, Service, Domain
|
from app.models import User, Deployment, Service, Domain
|
||||||
|
from sqlalchemy import and_, or_, not_
|
||||||
today = datetime.utcnow()
|
today = datetime.utcnow()
|
||||||
print('\nScan for active expired items and set them as inactive. Script started at {}'.format(today))
|
print('\nScan for active expired items and set them as inactive. Script started at {}'.format(today))
|
||||||
dep_c = 0
|
dep_c = 0
|
||||||
srv_c = 0
|
srv_c = 0
|
||||||
dom_c = 0
|
dom_c = 0
|
||||||
deployments_ena = Deployment.query.filter_by(enabled=True).all()
|
deployments = Deployment.query.filter_by(cancelled=False).filter_by(enabled=True).filter_by(protected=True).all()
|
||||||
for deploy in deployments_ena:
|
for deploy in deployments:
|
||||||
|
#print('Found {}.'.format(str(deploy.machine_alias)))
|
||||||
lastcharge = deploy.date_last_charge
|
lastcharge = deploy.date_last_charge
|
||||||
expiry = lastcharge + relativedelta(lastcharge, months=+(deploy.period))
|
expiry = lastcharge + relativedelta(lastcharge, months=+(deploy.period))
|
||||||
if today > expiry:
|
if today > expiry:
|
||||||
|
@ -56,7 +71,7 @@ def autodisable():
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
else:
|
else:
|
||||||
dep_c += 1
|
dep_c += 1
|
||||||
services_ena = Service.query.filter_by(enabled=True).all()
|
services_ena = Service.query.filter_by(cancelled=False).filter_by(enabled=True).all()
|
||||||
for service in services_ena:
|
for service in services_ena:
|
||||||
lastcharge = service.date_last_charge
|
lastcharge = service.date_last_charge
|
||||||
expiry = lastcharge + relativedelta(lastcharge, months=+(service.period))
|
expiry = lastcharge + relativedelta(lastcharge, months=+(service.period))
|
||||||
|
@ -68,7 +83,7 @@ def autodisable():
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
else:
|
else:
|
||||||
srv_c += 1
|
srv_c += 1
|
||||||
domains_ena = Domain.query.filter_by(enabled=True).all()
|
domains_ena = Domain.query.filter_by(cancelled=False).filter_by(enabled=True).all()
|
||||||
for domain in domains_ena:
|
for domain in domains_ena:
|
||||||
expiry = domain.date_expire
|
expiry = domain.date_expire
|
||||||
if today > expiry:
|
if today > expiry:
|
||||||
|
@ -86,7 +101,7 @@ def autowarn():
|
||||||
from app.models import User, Deployment, Service, Domain, Transaction
|
from app.models import User, Deployment, Service, Domain, Transaction
|
||||||
today = datetime.utcnow()
|
today = datetime.utcnow()
|
||||||
print('\nScan for items that will expire soon and enable the warning flag. Script started at {}'.format(today))
|
print('\nScan for items that will expire soon and enable the warning flag. Script started at {}'.format(today))
|
||||||
deployments_ena = Deployment.query.filter_by(enabled=True).all()
|
deployments_ena = Deployment.query.filter_by(cancelled=False).filter_by(enabled=True).filter_by(protected=True).all()
|
||||||
for deploy in deployments_ena:
|
for deploy in deployments_ena:
|
||||||
lastcharge = deploy.date_last_charge
|
lastcharge = deploy.date_last_charge
|
||||||
expiry = lastcharge + relativedelta(lastcharge, months=+(deploy.period))
|
expiry = lastcharge + relativedelta(lastcharge, months=+(deploy.period))
|
||||||
|
@ -102,7 +117,7 @@ def autowarn():
|
||||||
deploy.warning = False
|
deploy.warning = False
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
services_ena = Service.query.filter_by(enabled=True).all()
|
services_ena = Service.query.filter_by(cancelled=False).filter_by(enabled=True).all()
|
||||||
for service in services_ena:
|
for service in services_ena:
|
||||||
lastcharge = service.date_last_charge
|
lastcharge = service.date_last_charge
|
||||||
expiry = lastcharge + relativedelta(lastcharge, months=+(service.period))
|
expiry = lastcharge + relativedelta(lastcharge, months=+(service.period))
|
||||||
|
@ -118,7 +133,7 @@ def autowarn():
|
||||||
service.warning = False
|
service.warning = False
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
domains_ena = Domain.query.filter_by(enabled=True).all()
|
domains_ena = Domain.query.filter_by(cancelled=False).filter_by(enabled=True).all()
|
||||||
for domain in domains_ena:
|
for domain in domains_ena:
|
||||||
expiry = domain.date_expire
|
expiry = domain.date_expire
|
||||||
daysleft = expiry - today
|
daysleft = expiry - today
|
||||||
|
|
Loading…
Reference in a new issue