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')
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_address = db.relationship('Address', backref='owner', lazy='dynamic')
@ -219,104 +219,21 @@ def contact_proxmaster(data, method, cubeid=0):
except:
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):
__tablename__ = 'services'
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))
image = db.Column(db.String(128))
description = db.Column(db.Unicode(128))
unit = db.Column(db.Integer)
unitprice = db.Column(db.Float)
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):
__tablename__ = 'deployments'
pid = db.Column(db.Integer, primary_key=True)
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_expire = db.Column(db.DateTime)
enabled = db.Column(db.Boolean)
@ -326,6 +243,7 @@ class Deployment(db.Model):
machine_cpu = db.Column(db.Integer)
machine_mem = db.Column(db.Integer)
machine_hdd = db.Column(db.Integer)
machine_ipv4list = db.Column(db.String)
def charge():
result = Deployment.query.all()
@ -347,33 +265,24 @@ class Deployment(db.Model):
#TODO: Send emails here.
db.session.commit()
class Contract(db.Model):
__tablename__ = 'contracts'
#NAMESPACE
class Region(db.Model):
__tablename__ = 'regions'
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
service_id = db.Column(db.Integer, db.ForeignKey('services.pid')) #FK
date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow)
date_expire = db.Column(db.DateTime)
enabled = db.Column(db.Boolean)
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
region_id = db.Column(db.Integer, db.ForeignKey('regions.pid')) #FK
ipv4 = db.Column(db.String(64))
ipv6 = db.Column(db.String(256))
rdns = db.Column(db.String(256))
macaddr = db.Column(db.String(128))
class Domain(db.Model):
__tablename__ = 'domains'
@ -381,34 +290,9 @@ class Domain(db.Model):
user_id = db.Column(db.Integer, db.ForeignKey('users.pid')) #FK
date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow)
date_expire = db.Column(db.DateTime)
enabled = db.Column(db.Boolean)
fqdn = db.Column(db.String, unique=True)
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
class Transaction(db.Model):
__tablename__ = 'transaction'

View file

@ -177,10 +177,14 @@ a:active {
padding-left: 16px;
}
.container {
width: 100%;
}
.container-fluid {
position: relative;
max-width: 1170px;
min-width: 480px;
max-width: 100%;
min-width: 280px;
}
.container-fluid-index {
@ -252,9 +256,15 @@ a:active {
border-color: #070;
}
.panel > .panel-heading {
.panel-heading {
padding: 6px 15px;
border-bottom: 1px solid transparent;
border-top-left-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" %}
{% block head %}
{{ super() }}
{% endblock %}
{% block styles %}
{{ super() }}
<link href="/static/css/simple-slideshow-styles.css" type="text/css" rel="stylesheet" media="screen">
{% endblock %}
{% block head %}
{{ super() }}
<style>
body {
background-image: url('/static/images/cloudsbg.jpeg');

View file

@ -1,18 +1,76 @@
{% 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 %}
{{ super() }}
<script type="text/javascript">
//$(function() {
// $('.confirm').click(function() {
// return window.confirm("Are you sure?");
// });
//});
$('a[data-toggle="tooltip"]').tooltip({
animated: 'fade',
placement: 'bottom',
html: true
});
</script>
{% endblock %}
{% block page_content %}
<script>
// Only run what comes next *after* the page has loaded
addEventListener("DOMContentLoaded", function() {
@ -53,31 +111,72 @@ addEventListener("DOMContentLoaded", function() {
}
}, true);
</script>
{% endblock %}
<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>
{% block page_content %}
<div class="container-fluid">
<br />
<div class="row">
{% block sidebar %}
<div class="col-md-4">
<div class="row">
<div class="col-md-12">
{% include "/settings/acc_avatar.html" %}
</div>
</div>
</div>
{% endblock %}
<div class="col-md-12">
<div class="panel panel-info" id="dashboard">
<div class="panel-heading">Deployments</div>
<div class="panel-body"><p>
{% if inv_deploymens == None %}
<table class="table table-hover table-striped table-condensed cf">
<thead>
<tr>
<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="panel panel-default" id="contracts">
<div class="col-md-12">
<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-body"><p>
{% for contract in inv_contracts %}
@ -85,115 +184,15 @@ addEventListener("DOMContentLoaded", function() {
{{ contract.units }}<br />
{% if not contract.discount == 0 %}
Discount %{{ contract.discount }}<br />
Credit: {{ contract.credit }}<br /><br />
Credit: {{ contract.credit }}<br />
{% endif %}
{% 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 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>

View file

@ -83,6 +83,7 @@
{{ 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 />

View file

@ -12,7 +12,7 @@ class DeployForm(FlaskForm):
mem = StringField('Памет:')
hdd = StringField('Дисково пространство:')
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)])
def validate_invite_key(self, field):

View file

@ -6,13 +6,14 @@ from . import vmanager
from .forms import DeployForm
from .. import db
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
import base64
import string
import random
from datetime import datetime, timedelta, date, time
import ast
def randstr(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_mem': form.mem.data,
'vps_hdd': form.hdd.data,
'vps_ipv4': '1' }
'vps_ipv4': form.ipv4.data }
try:
query = contact_proxmaster(data, 'vmcreate')
except:
flash('Region unreachable! Please try again later...')
return redirect(url_for('vmanager.index'))
return redirect(url_for('vmanager.dashboard'))
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=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)
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)
db.session.add(deployment)
db.session.commit()
@ -113,7 +113,7 @@ def deploy(product_id=None):
else:
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)
@ -130,11 +130,11 @@ def dashboard():
inv_deploycubeids.extend([invcls.machine_id])
inv_deploynames.extend([invcls.machine_alias])
contracts = current_user.inv_contracts.order_by(Contract.date_created.desc()).all()
inv_contracts = []
for invcls in contracts:
services = current_user.inv_services.order_by(Service.date_created.desc()).all()
inv_services = []
for invcls in services:
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()
inv_domains = []
@ -221,4 +221,3 @@ def command(cmd=None, vmid=0):
#TODO: log ips
abort(404)

View file

@ -1,36 +1,48 @@
alembic==0.9.0
Babel==2.3.4
alembic==0.9.2
appdirs==1.4.3
Babel==2.4.0
blinker==1.4
certifi==2017.4.17
chardet==3.0.3
click==6.7
dnspython==1.15.0
dnspython3==1.15.0
dominate==2.3.1
Flask==0.12
Flask-Babel==0.11.1
facepy==1.0.9
Flask==0.12.2
Flask-AlchemyDumps==0.0.10
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-Migrate==2.0.4
Flask-Moment==0.5.1
Flask-Script==2.0.5
Flask-SQLAlchemy==2.2
Flask-WTF==0.14.2
gunicorn==19.7.0
gunicorn==19.7.1
idna==2.5
iso3166==0.8
itsdangerous==0.24
Jinja2==2.9.5
Jinja2==2.9.6
Mako==1.0.6
MarkupSafe==0.23
MarkupSafe==1.0
onetimepass==1.0.1
pkg-resources==0.0.0
psycopg2==2.6.2
psycopg2==2.7.1
Pygments==2.2.0
PyQRCode==1.2.1
python-dateutil==2.6.0
python-editor==1.0.3
pytz==2016.10
requests==2.13.0
pytz==2017.2
requests==2.17.3
schedule==0.4.2
six==1.10.0
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
Werkzeug==0.11.15
Werkzeug==0.12.2
WTForms==2.1

View file

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