simplifying schema

This commit is contained in:
deflax 2017-06-02 01:27:17 +03:00
parent 18d3d8cec1
commit 31ab20e837
11 changed files with 281 additions and 353 deletions

69
.gitignore vendored Normal file
View file

@ -0,0 +1,69 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
# Sphinx documentation
docs/_build/
# PyBuilder
target/
#Ipython Notebook
.ipynb_checkpoints
#proxadmin custom ignores
*.sqlite
db_repository/
migrations/
alchemydumps/
config.py

View file

@ -84,7 +84,7 @@ class User(db.Model, UserMixin):
currency = db.Column(db.String(3), default='BGN') currency = db.Column(db.String(3), default='BGN')
inv_deployments = db.relationship('Deployment', backref='owner', lazy='dynamic') inv_deployments = db.relationship('Deployment', backref='owner', lazy='dynamic')
inv_contracts = db.relationship('Contract', backref='owner', lazy='dynamic') inv_services = db.relationship('Service', backref='owner', lazy='dynamic')
inv_domains = db.relationship('Domain', backref='owner', lazy='dynamic') inv_domains = db.relationship('Domain', backref='owner', lazy='dynamic')
inv_address = db.relationship('Address', backref='owner', lazy='dynamic') inv_address = db.relationship('Address', backref='owner', lazy='dynamic')
@ -219,104 +219,21 @@ def contact_proxmaster(data, method, cubeid=0):
except: except:
return None return None
#TEMPLATE CLASSES
class Product(db.Model):
__tablename__ = 'products'
pid = db.Column(db.Integer, primary_key=True) #PK
group = db.Column(db.Integer)
name = db.Column(db.String(64))
image = db.Column(db.String(128))
description = db.Column(db.String(128))
cpu = db.Column(db.Integer) #default cpu
mem = db.Column(db.Integer) #default mem
hdd = db.Column(db.Integer) #default hdd
recipe = db.Column(db.String(128)) #defaut template name
enabled = db.Column(db.Boolean)
@staticmethod
def insert_products():
products = current_app.config['PRODUCTS']
for p in products:
product = Product.query.filter_by(pid=p).first()
if product is None:
product = Product(name=p)
#insert default values
product.group = products[p][0]
product.name = products[p][1]
product.image = products[p][2]
product.description = products[p][3]
product.cpu = products[p][4]
product.mem = products[p][5]
product.hdd = products[p][6]
product.recipe = products[p][7]
product.enabled = products[p][8]
db.session.add(product)
db.session.commit()
@staticmethod
def get_products():
result = Product.query.all()
products = {}
for product in result:
if product.enabled == True:
products[int(product.pid)] = { 'group': product.group,
'img': '/static/images/' + product.image,
'name': product.name,
'description': product.description,
'cpu': product.cpu,
'mem': product.mem,
'hdd': product.hdd,
'recipe': product.recipe
}
return products
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
user_id = db.Column(db.Integer, db.ForeignKey('users.pid')) #FK
name = db.Column(db.String(64)) name = db.Column(db.String(64))
image = db.Column(db.String(128)) image = db.Column(db.String(128))
description = db.Column(db.Unicode(128)) description = db.Column(db.Unicode(128))
unit = db.Column(db.Integer)
unitprice = db.Column(db.Float) unitprice = db.Column(db.Float)
enabled = db.Column(db.Boolean) enabled = db.Column(db.Boolean)
@staticmethod
def insert_services():
services = current_app.config['SERVICES']
for s in services:
service = Service.query.filter_by(pid=p).first()
if service is None:
service = Service(name=s)
#insert default values
service.name = products[p][1]
service.image = products[p][2]
service.description = products[p][3]
service.unitprice = products[p][4]
service.enabled = products[p][5]
db.session.add(service)
db.session.commit()
@staticmethod
def get_services():
result = Service.query.all()
services = {}
for service in result:
if service.enabled == True:
services[int(service.pid)] = {'img': '/static/images/' + service.image,
'name': service.name,
'description': service.description,
'unitprice': service.unitprice
}
return services
#INVENTORY CLASSES
class Deployment(db.Model): class Deployment(db.Model):
__tablename__ = 'deployments' __tablename__ = 'deployments'
pid = db.Column(db.Integer, primary_key=True) pid = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.pid')) #FK user_id = db.Column(db.Integer, db.ForeignKey('users.pid')) #FK
product_id = db.Column(db.Integer, db.ForeignKey('products.pid')) #FK
date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow) date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow)
date_expire = db.Column(db.DateTime) date_expire = db.Column(db.DateTime)
enabled = db.Column(db.Boolean) enabled = db.Column(db.Boolean)
@ -326,6 +243,7 @@ class Deployment(db.Model):
machine_cpu = db.Column(db.Integer) machine_cpu = db.Column(db.Integer)
machine_mem = db.Column(db.Integer) machine_mem = db.Column(db.Integer)
machine_hdd = db.Column(db.Integer) machine_hdd = db.Column(db.Integer)
machine_ipv4list = db.Column(db.String)
def charge(): def charge():
result = Deployment.query.all() result = Deployment.query.all()
@ -347,33 +265,24 @@ class Deployment(db.Model):
#TODO: Send emails here. #TODO: Send emails here.
db.session.commit() db.session.commit()
class Contract(db.Model): #NAMESPACE
__tablename__ = 'contracts' class Region(db.Model):
__tablename__ = 'regions'
pid = db.Column(db.Integer, primary_key=True) pid = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64))
description = db.Column(db.String(128))
extraprice = db.Column(db.Float)
class Address(db.Model):
__tablename__ = 'address'
pid = db.Column(db.Integer, primary_key=True)
date_assigned = db.Column(db.DateTime, index=True, default=datetime.utcnow)
user_id = db.Column(db.Integer, db.ForeignKey('users.pid')) #FK user_id = db.Column(db.Integer, db.ForeignKey('users.pid')) #FK
service_id = db.Column(db.Integer, db.ForeignKey('services.pid')) #FK region_id = db.Column(db.Integer, db.ForeignKey('regions.pid')) #FK
date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow) ipv4 = db.Column(db.String(64))
date_expire = db.Column(db.DateTime) ipv6 = db.Column(db.String(256))
enabled = db.Column(db.Boolean) rdns = db.Column(db.String(256))
macaddr = db.Column(db.String(128))
description = db.Column(db.Unicode)
units = db.Column(db.Integer)
discount = db.Column(db.Integer) #percent
def charge():
result = Contract.query.all()
for contract in result:
managed_user = User.query.get(contract.user_id)
db.session.add(contract)
#if datetime.utcnow.date() > (contract.date_expire - timedelta(days=10)):
if contract.enabled == True:
print('{}> Contract {} will expire in 10 days at {}. Creating new order...'.format(managed_user.email, contract.pid, contract.date_expire))
current_service = Service.query.get(int(contract.product_id))
transaction = Transaction(user_id=managed_user.id, units=contract.units, unitvalue=(current_service.unitprice * contract.units), description=current_service.name)
db.session.add(transaction)
contract.data_expire = datetime.utcnow.date() + timedelta(days=30)
db.session.commit()
return True
class Domain(db.Model): class Domain(db.Model):
__tablename__ = 'domains' __tablename__ = 'domains'
@ -381,34 +290,9 @@ class Domain(db.Model):
user_id = db.Column(db.Integer, db.ForeignKey('users.pid')) #FK user_id = db.Column(db.Integer, db.ForeignKey('users.pid')) #FK
date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow) date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow)
date_expire = db.Column(db.DateTime) date_expire = db.Column(db.DateTime)
enabled = db.Column(db.Boolean)
fqdn = db.Column(db.String, unique=True) fqdn = db.Column(db.String, unique=True)
auto_update = db.Column(db.Boolean) auto_update = db.Column(db.Boolean)
def charge():
result = Domain.query.all()
for domain in result:
managed_user = User.query.get(domain.user_id)
db.session.add(domain)
#if datetime.utcnow.date() > (domain.date_expire - timedelta(days=60)):
if domain.enabled == True:
print('{}> Domain {} will expire in 60 days at {}. Creating new order...'.format(managed_user.email, domain.fqdn, domain.date_expire))
transaction = Transaction(user_id=managed_user.id, unitvalue=25, description=domain.fqdn)
db.session.add(transaction)
db.session.commit()
return True
class Address(db.Model):
__tablename__ = 'address'
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)
ipaddr = db.Column(db.String(128))
macaddr = db.Column(db.String(128))
#UINVOICE #UINVOICE
class Transaction(db.Model): class Transaction(db.Model):
__tablename__ = 'transaction' __tablename__ = 'transaction'

View file

@ -177,10 +177,14 @@ a:active {
padding-left: 16px; padding-left: 16px;
} }
.container {
width: 100%;
}
.container-fluid { .container-fluid {
position: relative; position: relative;
max-width: 1170px; max-width: 100%;
min-width: 480px; min-width: 280px;
} }
.container-fluid-index { .container-fluid-index {
@ -252,9 +256,15 @@ a:active {
border-color: #070; border-color: #070;
} }
.panel > .panel-heading { .panel-heading {
padding: 6px 15px; padding: 6px 15px;
border-bottom: 1px solid transparent; border-bottom: 1px solid transparent;
border-top-left-radius: 3px; border-top-left-radius: 3px;
border-top-right-radius: 3px; border-top-right-radius: 3px;
} }
.tooltip-inner {
max-width: 350px;
/* If max-width does not work, try using width instead */
width: 350px;
}

View file

@ -1,12 +1,12 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block head %}
{{ super() }}
{% endblock %}
{% block styles %} {% block styles %}
{{ super() }} {{ super() }}
<link href="/static/css/simple-slideshow-styles.css" type="text/css" rel="stylesheet" media="screen"> <link href="/static/css/simple-slideshow-styles.css" type="text/css" rel="stylesheet" media="screen">
{% endblock %}
{% block head %}
{{ super() }}
<style> <style>
body { body {
background-image: url('/static/images/cloudsbg.jpeg'); background-image: url('/static/images/cloudsbg.jpeg');

View file

@ -1,18 +1,76 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block styles %}
{{ super() }}
<style type="text/css">
.tg {border-collapse:collapse;border-spacing:0;}
.tg td{font-family:Arial, sans-serif;font-size:14px;padding:1px 1px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
.tg th{font-family:Arial, sans-serif;font-size:14px;padding:1px 1px;font-weight:normal;padding:border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
.tg .tg-yw4l{vertical-align:top}
</style>
<style type="text/css">
@media only screen and (max-width: 768px) {
/* Force table to not be like tables anymore */
#no-more-tables table,
#no-more-tables thead,
#no-more-tables tbody,
#no-more-tables th,
#no-more-tables td,
#no-more-tables tr {
display: block;
}
/* Hide table headers (but not display: none;, for accessibility) */
#no-more-tables thead tr {
position: absolute;
top: -9999px;
left: -9999px;
}
#no-more-tables tr { border: 1px solid #ccc; }
#no-more-tables td {
/* Behave like a "row" */
border: none;
border-bottom: 1px solid #eee;
position: relative;
padding-left: 50%;
white-space: normal;
text-align:left;
}
#no-more-tables td:before {
/* Now like a table header */
position: absolute;
/* Top/left values mimic padding */
top: 6px;
left: 6px;
width: 45%;
padding-right: 10px;
white-space: nowrap;
text-align:left;
font-weight: bold;
}
/*
Label the data
*/
#no-more-tables td:before { content: attr(data-title); }
}
</style>
{% endblock %}
{% block scripts %} {% block scripts %}
{{ super() }} {{ super() }}
<script type="text/javascript"> <script type="text/javascript">
//$(function() { $('a[data-toggle="tooltip"]').tooltip({
// $('.confirm').click(function() { animated: 'fade',
// return window.confirm("Are you sure?"); placement: 'bottom',
// }); html: true
//}); });
</script> </script>
{% endblock %}
{% block page_content %}
<script> <script>
// Only run what comes next *after* the page has loaded // Only run what comes next *after* the page has loaded
addEventListener("DOMContentLoaded", function() { addEventListener("DOMContentLoaded", function() {
@ -53,31 +111,72 @@ addEventListener("DOMContentLoaded", function() {
} }
}, true); }, true);
</script> </script>
{% endblock %}
<style type="text/css"> {% block page_content %}
.tg {border-collapse:collapse;border-spacing:0;}
.tg td{font-family:Arial, sans-serif;font-size:14px;padding:1px 1px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
.tg th{font-family:Arial, sans-serif;font-size:14px;padding:1px 1px;font-weight:normal;padding:border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
.tg .tg-yw4l{vertical-align:top}
</style>
<div class="container-fluid"> <div class="container-fluid">
<br /> <br />
<div class="row"> <div class="row">
{% block sidebar %} <div class="col-md-12">
<div class="col-md-4"> <div class="panel panel-info" id="dashboard">
<div class="row"> <div class="panel-heading">Deployments</div>
<div class="col-md-12"> <div class="panel-body"><p>
{% include "/settings/acc_avatar.html" %} {% if inv_deploymens == None %}
</div> <table class="table table-hover table-striped table-condensed cf">
</div> <thead>
</div> <tr>
{% endblock %} <th>Name</th>
<th>CPU</th>
<th>Mem</th>
<th>HDD</th>
<th>IPv4</th>
<th>Control</th>
<th></th>
</tr>
<tbody>
{% for deploy in inv_deployments %}
<tr>
<td>
<a 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><a data-toggle="tooltip" title="<img src='data:image/png;base64,{{ rrd[deploy.machine_id]['cpu'] }}' />">{{ deploy.machine_cpu }} Cores</a></td>
<td><a data-toggle="tooltip" title="<img src='data:image/png;base64,{{ rrd[deploy.machine_id]['mem'] }}' />">{{ deploy.machine_mem }} MB</a></td>
<td><a data-toggle="tooltip" title="<img src='data:image/png;base64,{{ rrd[deploy.machine_id]['hdd'] }}' />">{{ deploy.machine_hdd }} GB</a></td>
<td><a data-toggle="tooltip" title="<img src='data:image/png;base64,{{ rrd[deploy.machine_id]['net'] }}' />">{% for ip in deploy.machine_ipv4list %}{{ ip }}{% endfor %}</a></td>
<td>{% 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-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 %}
<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>
<td>{% 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>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
<button class="btn btn-default"><span class="glyphicon glyphicon-plus" aria-hiddent="true"></span> Create</button>
</div>
</div>
</div>
<div class="col-md-8"> <div class="col-md-12">
<div class="panel panel-default" id="contracts"> <div class="panel panel-info" id="dashboard">
<div class="panel-heading">Domains</div>
<div class="panel-body"><p>
{% for domain in inv_domains %}
{{ fqdn }}
{% endfor %}
<button class="btn btn-default" onclick="window.open('{{ url_for('main.index') }}')"><span class="glyphicon glyphicon-plus" aria-hiddent="true"></span> Create</button>
</div>
</div>
</div>
<div class="col-md-12">
<div class="panel panel-info" id="dashboard">
<div class="panel-heading">Services</div> <div class="panel-heading">Services</div>
<div class="panel-body"><p> <div class="panel-body"><p>
{% for contract in inv_contracts %} {% for contract in inv_contracts %}
@ -85,115 +184,15 @@ addEventListener("DOMContentLoaded", function() {
{{ contract.units }}<br /> {{ contract.units }}<br />
{% if not contract.discount == 0 %} {% if not contract.discount == 0 %}
Discount %{{ contract.discount }}<br /> Discount %{{ contract.discount }}<br />
Credit: {{ contract.credit }}<br /><br /> Credit: {{ contract.credit }}<br />
{% endif %} {% endif %}
{% endfor %} {% endfor %}
<p> <button class="btn btn-default" onclick="window.open('{{ url_for('main.index') }}')"><span class="glyphicon glyphicon-plus" aria-hiddent="true"></span> Create</button>
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-4">
<div class="panel panel-default" id="contracts">
<div class="panel-heading">Domains</div>
<div class="panel-body"><p>
{% for domain in inv_domains %}
{{ fqdn }}<br />
{% endfor %}
<p>
</div>
</div>
</div>
<div class="col-md-8">
<div class="panel-group">
<div class="panel panel-default" id="deploys">
<div class="panel-heading">Deployments</div>
<div class="panel-body"><p>
{% for deploy in inv_deployments %}
<ul class="nav nav-pills">
<li class="active"><a data-toggle="pill" href="#home{{ deploy.machine_id }}">{{ deploy.machine_alias }}</a></li>
<li><a data-toggle="pill" href="#control{{ deploy.machine_id }}">Control</a></li>
<li><a data-toggle="pill" href="#stats{{ deploy.machine_id }}">Stats</a></li>
<li><a data-toggle="pill" href="#keys{{ deploy.machine_id }}">Keys</a></li>
</ul>
<div class="tab-content">
<div id="home{{ deploy.machine_id}}" class="tab-pane fade in active">
<br />
</div>
<div id="control{{ deploy.machine_id}}" class="tab-pane fade">
<br />
{% 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>
<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>
{% 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>
{% endif %}
<br /><br />
Grid ID# {{ deploy.machine_id }}<br >
CPU: {{ deploy.machine_cpu }} cores</br >
Memory: {{ deploy.machine_mem }} MB</br >
Disk Space: {{ deploy.machine_hdd }} GB</br >
<br />
Expiry date: {{ deploy.date_expire }}</br >
Credit: {{ deploy.credit }}
</div>
<div id="stats{{ deploy.machine_id}}" class="tab-pane fade">
<table class="tg">
<tr>
<th class="tg-yw4l">Network Bandwidth</th>
</tr>
<tr>
<td class="tg-yw4l"><img src="data:image/png;base64,{{ rrd[deploy.machine_id]['net'] }}" class="img-responsive"><br></td>
</tr>
</table>
<table class="tg">
<tr>
<th class="tg-yw4l">CPU Load</th>
</tr>
<tr>
<td class="tg-yw4l"><img src="data:image/png;base64,{{ rrd[deploy.machine_id]['cpu'] }}" class="img-responsive"><br></td>
</tr>
</table>
<table class="tg">
<tr>
<th class="tg-yw4l">Memory Usage</th>
</tr>
<tr>
<td class="tg-yw4l"><img src="data:image/png;base64,{{ rrd[deploy.machine_id]['mem'] }}" class="img-responsive"><br></td>
</tr>
</table>
<table class="tg">
<tr>
<th class="tg-yw4l">Disk Input/Output</th>
</tr>
<tr>
<td class="tg-yw4l"><img src="data:image/png;base64,{{ rrd[deploy.machine_id]['hdd'] }}" class="img-responsive"><br></td>
</tr>
</table>
</div>
<div id="keys{{ deploy.machine_id}}" class="tab-pane fade">
Not yet implemented.
</div>
</div>
<br />
{% endfor %}
</div>
</div>
</div>
</div>
</div> </div>

View file

@ -83,6 +83,7 @@
{{ form.mem.label }} {{ form.mem }}<br /> {{ form.mem.label }} {{ form.mem }}<br />
{{ form.hdd.label }} {{ form.hdd }}<br /> {{ form.hdd.label }} {{ form.hdd }}<br />
{{ form.recipe.label }} {{ form.recipe }}<br /> {{ form.recipe.label }} {{ form.recipe }}<br />
{{ form.ipv4.label }} {{ form.ipv4 }}<br />
<p> <p>
<br /> <br />

View file

@ -12,7 +12,7 @@ class DeployForm(FlaskForm):
mem = StringField('Памет:') mem = StringField('Памет:')
hdd = StringField('Дисково пространство:') hdd = StringField('Дисково пространство:')
recipe = SelectField('Рецепта') recipe = SelectField('Рецепта')
#ipv4 = SelectField('Брой публични IP адреса', choices=[('1', '1'),('2', '2' ), ('3', '3')]) ipv4 = SelectField('Брой публични IP адреса', choices=[('1', '1'),('2', '2' ), ('3', '3')])
invite_key = StringField('Покана', [validators.DataRequired(), validators.Length(6,35)]) invite_key = StringField('Покана', [validators.DataRequired(), validators.Length(6,35)])
def validate_invite_key(self, field): def validate_invite_key(self, field):

View file

@ -6,13 +6,14 @@ from . import vmanager
from .forms import DeployForm from .forms import DeployForm
from .. import db from .. import db
from ..email import send_email from ..email import send_email
from ..models import User, Role, Product, Deployment, contact_proxmaster, Contract, Domain from ..models import User, Role, 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
import string import string
import random import random
from datetime import datetime, timedelta, date, time from datetime import datetime, timedelta, date, time
import ast
def randstr(n): def randstr(n):
return ''.join(random.SystemRandom().choice(string.ascii_lowercase + string.digits) for _ in range(n)) return ''.join(random.SystemRandom().choice(string.ascii_lowercase + string.digits) for _ in range(n))
@ -95,17 +96,16 @@ def deploy(product_id=None):
'vps_cpu': form.cpu.data, 'vps_cpu': form.cpu.data,
'vps_mem': form.mem.data, 'vps_mem': form.mem.data,
'vps_hdd': form.hdd.data, 'vps_hdd': form.hdd.data,
'vps_ipv4': '1' } 'vps_ipv4': form.ipv4.data }
try: try:
query = contact_proxmaster(data, 'vmcreate') query = contact_proxmaster(data, 'vmcreate')
except: except:
flash('Region unreachable! Please try again later...') flash('Region unreachable! Please try again later...')
return redirect(url_for('vmanager.index')) return redirect(url_for('vmanager.dashboard'))
if query is not None: if query is not None:
cubeid = query['cube'] 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, date_expire=(datetime.utcnow() + timedelta(days=30)), enabled=True)
deployment = Deployment(user_id=client_id, product_id=product_id, machine_alias=form.servername.data, machine_id=cubeid, machine_cpu=form.cpu.data, machine_mem=form.mem.data, machine_hdd=form.hdd.data, date_expire=(datetime.utcnow() + timedelta(days=30)), enabled=True)
db.session.add(deployment) db.session.add(deployment)
db.session.commit() db.session.commit()
@ -113,7 +113,7 @@ def deploy(product_id=None):
else: else:
flash('Deploy cancelled! Please try again later...') flash('Deploy cancelled! Please try again later...')
return redirect(url_for('vmanager.index')) return redirect(url_for('vmanager.dashboard'))
return render_template('vmanager/deploy.html', page=page, form=form, product_id=product_id, product_pic=product_pic, product_name=product_name, product_description=product_description, product_recipe=product_recipe) return render_template('vmanager/deploy.html', page=page, form=form, product_id=product_id, product_pic=product_pic, product_name=product_name, product_description=product_description, product_recipe=product_recipe)
@ -130,11 +130,11 @@ def dashboard():
inv_deploycubeids.extend([invcls.machine_id]) inv_deploycubeids.extend([invcls.machine_id])
inv_deploynames.extend([invcls.machine_alias]) inv_deploynames.extend([invcls.machine_alias])
contracts = current_user.inv_contracts.order_by(Contract.date_created.desc()).all() services = current_user.inv_services.order_by(Service.date_created.desc()).all()
inv_contracts = [] inv_services = []
for invcls in contracts: for invcls in services:
if invcls.enabled == True: if invcls.enabled == True:
inv_contracts.extend([invcls.template]) inv_services.extend([invcls.description])
domains = current_user.inv_domains.order_by(Domain.date_created.desc()).all() domains = current_user.inv_domains.order_by(Domain.date_created.desc()).all()
inv_domains = [] inv_domains = []
@ -221,4 +221,3 @@ def command(cmd=None, vmid=0):
#TODO: log ips #TODO: log ips
abort(404) abort(404)

View file

@ -1,36 +1,48 @@
alembic==0.9.0 alembic==0.9.2
Babel==2.3.4 appdirs==1.4.3
Babel==2.4.0
blinker==1.4 blinker==1.4
certifi==2017.4.17
chardet==3.0.3
click==6.7 click==6.7
dnspython==1.15.0 dnspython==1.15.0
dnspython3==1.15.0 dnspython3==1.15.0
dominate==2.3.1 dominate==2.3.1
Flask==0.12 facepy==1.0.9
Flask-Babel==0.11.1 Flask==0.12.2
Flask-AlchemyDumps==0.0.10
Flask-Babel==0.11.2
Flask-Bootstrap==3.3.7.1 Flask-Bootstrap==3.3.7.1
Flask-Login==0.4.0 Flask-Login==0.4.0
Flask-Mail==0.9.1 Flask-Mail==0.9.1
Flask-Migrate==2.0.3 Flask-Migrate==2.0.4
Flask-Moment==0.5.1
Flask-Script==2.0.5 Flask-Script==2.0.5
Flask-SQLAlchemy==2.2 Flask-SQLAlchemy==2.2
Flask-WTF==0.14.2 Flask-WTF==0.14.2
gunicorn==19.7.0 gunicorn==19.7.1
idna==2.5
iso3166==0.8 iso3166==0.8
itsdangerous==0.24 itsdangerous==0.24
Jinja2==2.9.5 Jinja2==2.9.6
Mako==1.0.6 Mako==1.0.6
MarkupSafe==0.23 MarkupSafe==1.0
onetimepass==1.0.1 onetimepass==1.0.1
pkg-resources==0.0.0 pkg-resources==0.0.0
psycopg2==2.6.2 psycopg2==2.7.1
Pygments==2.2.0
PyQRCode==1.2.1 PyQRCode==1.2.1
python-dateutil==2.6.0
python-editor==1.0.3 python-editor==1.0.3
pytz==2016.10 pytz==2017.2
requests==2.13.0 requests==2.17.3
schedule==0.4.2 schedule==0.4.2
six==1.10.0 six==1.10.0
sortedcontainers==1.5.7 sortedcontainers==1.5.7
SQLAlchemy==1.1.6 SQLAlchemy==1.1.10
traits==4.6.0
Unipath==1.1
urllib3==1.21.1
visitor==0.1.3 visitor==0.1.3
Werkzeug==0.11.15 Werkzeug==0.12.2
WTForms==2.1 WTForms==2.1

View file

@ -3,6 +3,7 @@
import os import os
import subprocess, shlex import subprocess, shlex
from app import app, db from app import app, db
from flask_alchemydumps import AlchemyDumps, AlchemyDumpsCommand
from flask_script import Manager, Shell, Command from flask_script import Manager, Shell, Command
from flask_migrate import Migrate, MigrateCommand from flask_migrate import Migrate, MigrateCommand
@ -15,33 +16,29 @@ def make_shell_context():
Deployment=Deployment) Deployment=Deployment)
migrate = Migrate(app, db) migrate = Migrate(app, db)
dump = AlchemyDumps(app, db)
manager = Manager(app) manager = Manager(app)
manager.add_command('shell', Shell(make_context=make_shell_context)) manager.add_command('shell', Shell(make_context=make_shell_context))
manager.add_command('db', MigrateCommand) manager.add_command('db', MigrateCommand)
manager.add_command('dump', AlchemyDumpsCommand)
@manager.command @manager.command
def deploy(): def deploy():
"""Run deployment tasks.""" """Run deployment tasks."""
from flask_migrate import upgrade from flask_migrate import upgrade
from app.models import Role, User, Deployment, Product from app.models import Role, User
# migrate database to latest revision # migrate database to latest revision
upgrade() upgrade()
# create user roles # create user roles
Role.insert_roles() Role.insert_roles()
Product.insert_products()
@manager.command @manager.command
@manager.option('-r' '--restore_file', help='Restore from grid dump file') def sampledata():
def restore(restore_file): """Deploy Sample Data"""
""" recreate db from grid export with python3 manage.py restore /path/grid.tar.bz2 """ pass
print(str(restore_file))
#TODO
from app.models import User
db.session.add(User(email=str(user), password=str(password), confirmed=True, confirmed_on=datetime.datetime.now()))
db.session.commit()
def run_scheduler(): def run_scheduler():
command_line = 'python3 /home/proxadmin/appserver/proxmaster-panel/schedulerd.py' command_line = 'python3 /home/proxadmin/appserver/proxmaster-panel/schedulerd.py'
@ -65,7 +62,7 @@ def charge_domains():
@manager.command @manager.command
def runserver(): def runserver():
print('Starting Scheduler...') #print('Starting Scheduler...')
#run_scheduler() #run_scheduler()
print('Starting Flask...') print('Starting Flask...')
@ -74,4 +71,3 @@ def runserver():
if __name__ == '__main__': if __name__ == '__main__':
manager.run() manager.run()

View file

@ -1,42 +0,0 @@
alembic==0.9.2
appdirs==1.4.3
Babel==2.4.0
blinker==1.4
click==6.7
dnspython==1.15.0
dnspython3==1.15.0
dominate==2.3.1
facepy==1.0.8
Flask==0.12.2
Flask-Babel==0.11.2
Flask-Bootstrap==3.3.7.1
Flask-Login==0.4.0
Flask-Mail==0.9.1
Flask-Migrate==2.0.3
Flask-Moment==0.5.1
Flask-Script==2.0.5
Flask-SQLAlchemy==2.2
Flask-WTF==0.14.2
gunicorn==19.7.1
iso3166==0.8
itsdangerous==0.24
Jinja2==2.9.6
Mako==1.0.6
MarkupSafe==1.0
onetimepass==1.0.1
pkg-resources==0.0.0
psycopg2==2.7.1
Pygments==2.2.0
PyQRCode==1.2.1
python-dateutil==2.6.0
python-editor==1.0.3
pytz==2017.2
requests==2.14.2
schedule==0.4.2
six==1.10.0
sortedcontainers==1.5.7
SQLAlchemy==1.1.10
traits==4.6.0
visitor==0.1.3
Werkzeug==0.12.2
WTForms==2.1