charge script, template and vmanager cmds refactoring
This commit is contained in:
parent
98f41a5533
commit
4ae398a499
12 changed files with 103 additions and 55 deletions
|
@ -48,7 +48,7 @@ def list_items():
|
||||||
@login_required
|
@login_required
|
||||||
@admin_required
|
@admin_required
|
||||||
def list_users():
|
def list_users():
|
||||||
allusers = User.query.order_by(User.last_seen.desc()).all()
|
allusers = User.query.filter_by(active=True).order_by(User.last_seen.desc()).all()
|
||||||
return render_template('admin/list_users.html', users=allusers)
|
return render_template('admin/list_users.html', users=allusers)
|
||||||
|
|
||||||
@admin.route("/charge/<int:user_pid>", methods=['GET', 'POST'])
|
@admin.route("/charge/<int:user_pid>", methods=['GET', 'POST'])
|
||||||
|
|
|
@ -150,7 +150,7 @@ def register():
|
||||||
db.session.add(transaction)
|
db.session.add(transaction)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
token = user.generate_confirmation_token()
|
token = user.generate_confirmation_token()
|
||||||
send_email(user.email, 'Потвърдете_вашият_акаунт', 'auth/email/confirm', user=user, token=token)
|
send_email(user.email, 'Потвърдете Вашата регистрация', 'auth/email/confirm', user=user, token=token)
|
||||||
#notify admin
|
#notify admin
|
||||||
newip = request.remote_addr
|
newip = request.remote_addr
|
||||||
if request.headers.getlist("X-Forwarded-For"):
|
if request.headers.getlist("X-Forwarded-For"):
|
||||||
|
|
|
@ -254,26 +254,6 @@ class Deployment(db.Model):
|
||||||
machine_hdd = db.Column(db.Integer)
|
machine_hdd = db.Column(db.Integer)
|
||||||
machine_addresses = db.relationship('Address', backref='deployments', lazy='dynamic')
|
machine_addresses = db.relationship('Address', backref='deployments', lazy='dynamic')
|
||||||
|
|
||||||
def charge():
|
|
||||||
result = Deployment.query.all()
|
|
||||||
for deploy in result:
|
|
||||||
if deploy.enabled == True:
|
|
||||||
managed_user = User.query.get(deploy.user_id)
|
|
||||||
db.session.add(managed_user)
|
|
||||||
current_product = Product.query.get(int(deploy.product_id))
|
|
||||||
cpu_cost = deploy.machine_cpu * current_app.config['CPU_RATIO']
|
|
||||||
mem_cost = ( deploy.machine_mem / 1024 ) * current_app.config['MEM_RATIO']
|
|
||||||
hdd_cost = deploy.machine_hdd * current_app.config['HDD_RATIO']
|
|
||||||
total = cpu_cost + mem_cost + hdd_cost
|
|
||||||
|
|
||||||
if managed_user.wallet - total > 0:
|
|
||||||
managed_user.wallet -= total
|
|
||||||
print('{}> Charging deployment #{} with {}. Wallet now is: {}'.format(managed_user.email, deploy.machine_id, total, managed_user.walet))
|
|
||||||
else:
|
|
||||||
print('{}> Deployment #{} cannot be charged with {}. Not enough money in the wallet ({}). Notifying admin...'.format(managed_user.email, deploy.machine_id, total, managed_user.wallet))
|
|
||||||
#TODO: Send emails here.
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
#NAMESPACE
|
#NAMESPACE
|
||||||
class Region(db.Model):
|
class Region(db.Model):
|
||||||
__tablename__ = 'regions'
|
__tablename__ = 'regions'
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<div class="panel panel-warning" id="users">
|
<div class="panel panel-warning" id="users">
|
||||||
<div class="panel-heading">Users</div>
|
<div class="panel-heading">List Active Users</div>
|
||||||
<div class="panel-body"><p>
|
<div class="panel-body"><p>
|
||||||
<table class="table table-hover table-striped table-condensed cf">
|
<table class="table table-hover table-striped table-condensed cf">
|
||||||
<thead>
|
<thead>
|
||||||
|
|
|
@ -5,9 +5,6 @@
|
||||||
|
|
||||||
{% block page_content %}
|
{% block page_content %}
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h1>
|
|
||||||
Здравейте, {{ current_user.email }}!
|
|
||||||
</h1>
|
|
||||||
<h3>Вашият акаунт е вече потвърден.</h3>
|
<h3>Вашият акаунт е вече потвърден.</h3>
|
||||||
<p>
|
<p>
|
||||||
Моля напуснете тази страница :)
|
Моля напуснете тази страница :)
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
{% block page_content %}
|
{% block page_content %}
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h1>Change Your Password</h1>
|
<h3>Change Your Password</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<p>Dear {{ user.name }},</p>
|
<p>Dear Customer,</p>
|
||||||
<p>Welcome to <b>Proxadmin</b>!</p>
|
|
||||||
<p>To confirm your account please <a href="{{ url_for('auth.confirm', token=token, _external=True) }}">click here</a>.</p>
|
<p>To confirm your account please <a href="{{ url_for('auth.confirm', token=token, _external=True) }}">click here</a>.</p>
|
||||||
<p>Alternatively, you can paste the following link in your browser's address bar:</p>
|
<p>Alternatively, you can paste the following link in your browser's address bar:</p>
|
||||||
<p>{{ url_for('auth.confirm', token=token, _external=True) }}</p>
|
<p>{{ url_for('auth.confirm', token=token, _external=True) }}</p>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Dear {{ user.name }},
|
Dear Customer,
|
||||||
|
|
||||||
Welcome to Datapoint!
|
Welcome to Datapoint!
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,6 @@
|
||||||
|
|
||||||
{% block page_content %}
|
{% block page_content %}
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h1>
|
|
||||||
Hello, {{ current_user.username }}!
|
|
||||||
</h1>
|
|
||||||
<h3>You have not confirmed your account yet.</h3>
|
<h3>You have not confirmed your account yet.</h3>
|
||||||
<p>
|
<p>
|
||||||
Before you can access this site you need to confirm your account.
|
Before you can access this site you need to confirm your account.
|
||||||
|
|
|
@ -136,7 +136,7 @@ addEventListener("DOMContentLoaded", function() {
|
||||||
<th>CPU</th>
|
<th>CPU</th>
|
||||||
<th>Mem</th>
|
<th>Mem</th>
|
||||||
<th>HDD</th>
|
<th>HDD</th>
|
||||||
<th>IPv4</th>
|
<th>Network</th>
|
||||||
<th>Control</th>
|
<th>Control</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -150,7 +150,8 @@ addEventListener("DOMContentLoaded", function() {
|
||||||
<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="Network">{% for addr in deploy.machine_addresses %} {{ addr.ip }}<br /> {% endfor %}</td>
|
||||||
|
<td data-title="Control"><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</td>
|
||||||
|
<td> </td>
|
||||||
{% else %}
|
{% else %}
|
||||||
<tr>
|
<tr>
|
||||||
<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="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>
|
||||||
|
|
|
@ -183,6 +183,23 @@ def dashboard():
|
||||||
current_app.logger.info('[{}] Enabled deployments: {}, services: {}, domains: {}, addresses: {}'.format(current_user.email, inv_deployments_list, inv_services_list, inv_domains_list, inv_addresses_list ))
|
current_app.logger.info('[{}] Enabled deployments: {}, services: {}, domains: {}, addresses: {}'.format(current_user.email, inv_deployments_list, inv_services_list, inv_domains_list, inv_addresses_list ))
|
||||||
return render_template('vmanager/dashboard.html', rrd=rrd, status=statuses, inv_deployments=inv_deployments, inv_services=inv_services, inv_domains=inv_domains, inv_addresses=inv_addresses, region=regions)
|
return render_template('vmanager/dashboard.html', rrd=rrd, status=statuses, inv_deployments=inv_deployments, inv_services=inv_services, inv_domains=inv_domains, inv_addresses=inv_addresses, region=regions)
|
||||||
|
|
||||||
|
@vmanager.route('/activate/<int:vmid>')
|
||||||
|
@login_required
|
||||||
|
def activate(vmid=0):
|
||||||
|
#work with disabled deploys only
|
||||||
|
result = current_user.inv_deployments.filter_by(enabled=False)
|
||||||
|
inventory = []
|
||||||
|
for invcls in result:
|
||||||
|
inventory.extend([invcls.machine_id])
|
||||||
|
#checks if current user owns this vmid
|
||||||
|
if not vmid in inventory:
|
||||||
|
current_app.logger.warning('[{}] Access violation with cube id: {}'.format(current_user.email, vmid))
|
||||||
|
#TODO: log ips
|
||||||
|
abort(404)
|
||||||
|
else:
|
||||||
|
current_app.logger.info('[{}] Disabled deployments: {}'.format(current_user.email, inventory))
|
||||||
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@vmanager.route('/<cmd>/<int:vmid>')
|
@vmanager.route('/<cmd>/<int:vmid>')
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -198,11 +215,17 @@ def command(cmd=None, vmid=0):
|
||||||
# return redirect(url_for('uinvoice.addfunds'))
|
# return redirect(url_for('uinvoice.addfunds'))
|
||||||
|
|
||||||
#work with enabled deploys only
|
#work with enabled deploys only
|
||||||
result = current_user.inv_deployments.filter_by(enabled=True).order_by(Deployment.date_created.desc())
|
result = current_user.inv_deployments.filter_by(enabled=True)
|
||||||
inventory = []
|
inventory = []
|
||||||
for invcls in result:
|
for invcls in result:
|
||||||
inventory.extend([invcls.machine_id])
|
inventory.extend([invcls.machine_id])
|
||||||
|
|
||||||
|
if current_user.is_administrator():
|
||||||
|
current_app.logger.info('[ADMIN] Access override for cube id:{}'.format(vmid))
|
||||||
|
db_result = contact_proxmaster({}, cmd, vmid)
|
||||||
|
if cmd == 'vmvnc':
|
||||||
|
return redirect(db_result['url'])
|
||||||
|
else:
|
||||||
#checks if current user owns this vmid
|
#checks if current user owns this vmid
|
||||||
if not vmid in inventory:
|
if not vmid in inventory:
|
||||||
current_app.logger.warning('[{}] Access violation with cube id: {}'.format(current_user.email, vmid))
|
current_app.logger.warning('[{}] Access violation with cube id: {}'.format(current_user.email, vmid))
|
||||||
|
@ -210,14 +233,7 @@ def command(cmd=None, vmid=0):
|
||||||
else:
|
else:
|
||||||
db_result = contact_proxmaster({}, cmd, vmid)
|
db_result = contact_proxmaster({}, cmd, vmid)
|
||||||
#print(db_result)
|
#print(db_result)
|
||||||
|
|
||||||
#admin override
|
|
||||||
if current_user.is_administrator():
|
|
||||||
current_app.logger.info('[ADMIN] Access override for cube id:{}'.format(vmid))
|
|
||||||
db_result = contact_proxmaster({}, cmd, vmid)
|
|
||||||
|
|
||||||
if cmd == 'vmvnc':
|
if cmd == 'vmvnc':
|
||||||
return redirect(db_result['url'])
|
return redirect(db_result['url'])
|
||||||
|
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
|
|
70
manage.py
70
manage.py
|
@ -1,12 +1,16 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os, sys
|
||||||
import subprocess, shlex
|
import subprocess, shlex
|
||||||
|
from datetime import date, time, datetime
|
||||||
|
from dateutil.relativedelta import relativedelta
|
||||||
|
|
||||||
from app import app, db
|
from app import app, db
|
||||||
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
|
||||||
|
|
||||||
def make_shell_context():
|
def make_shell_context():
|
||||||
|
from app.models import User, Role, Permission, Deployment
|
||||||
return dict(app=app,
|
return dict(app=app,
|
||||||
db=db,
|
db=db,
|
||||||
User=User,
|
User=User,
|
||||||
|
@ -34,11 +38,65 @@ def deploy():
|
||||||
|
|
||||||
@manager.command
|
@manager.command
|
||||||
def charge():
|
def charge():
|
||||||
print('charge')
|
from app.models import User, Deployment, Service, Domain
|
||||||
from app.models import Deployment, Service, Domain
|
|
||||||
#Deployment.charge()
|
today = datetime.utcnow()
|
||||||
#Service.charge()
|
print('[1] Scan for active expired items and set them as inactive {}\n'.format(today))
|
||||||
#Domain.charge()
|
deployments_ena = Deployment.query.filter_by(enabled=True).all()
|
||||||
|
for deploy in deployments_ena:
|
||||||
|
lastcharge = deploy.date_last_charge
|
||||||
|
expiry = lastcharge + relativedelta(lastcharge, months=+(deploy.period))
|
||||||
|
if today > expiry:
|
||||||
|
print('last charged: ' + lastcharge.strftime('%c') + 'expiry date: ' + expiry.strftime('%c'))
|
||||||
|
print(deploy.machine_alias + ' is past expiration date and will be marked INACTIVE')
|
||||||
|
services_ena = Service.query.filter_by(enabled=True).all()
|
||||||
|
for service in services_ena:
|
||||||
|
lastcharge = service.date_last_charge
|
||||||
|
expiry = lastcharge + relativedelta(lastcharge, months=+(service.period))
|
||||||
|
if today > expiry:
|
||||||
|
print('last charged: ' + lastcharge.strftime('%c') + 'expiry date: ' + expiry.strftime('%c'))
|
||||||
|
print('Service "' + service.description + '" is past expiration date and will be marked INACTIVE')
|
||||||
|
for domain in domains_ena:
|
||||||
|
expiry = domain.date_expire
|
||||||
|
if today > expiry:
|
||||||
|
print('last charged: ' + lastcharge.strftime('%c') + 'expiry date: ' + expiry.strftime('%c'))
|
||||||
|
print('Domain "' + domain.fqdn + '" is past expiration date and will be marked as INACTIVE')
|
||||||
|
|
||||||
|
today = datetime.utcnow()
|
||||||
|
print('[2] Scan for items that will expire soon and try to autocharge them if they are not active. {}\n'.format(today))
|
||||||
|
deployments_ena = Deployment.query.filter_by(enabled=True).all()
|
||||||
|
for deploy in deployments_ena:
|
||||||
|
lastcharge = deploy.date_last_charge
|
||||||
|
expiry = lastcharge + relativedelta(lastcharge, months=+(deploy.period))
|
||||||
|
daysleft = relativedelta(today, expiry).days()
|
||||||
|
warn = deploy.period * 5
|
||||||
|
print(daysleft)
|
||||||
|
if daysleft < 10:
|
||||||
|
print(deploy.machine_alias + ' is eligible for charging')
|
||||||
|
print('last charged: ' + lastcharge.strftime('%c'))
|
||||||
|
print('expiry date: ' + expiry.strftime('%c'))
|
||||||
|
cpu_cost = deploy.machine_cpu * app.config['CPU_RATIO']
|
||||||
|
mem_cost = ( deploy.machine_mem / 1024 ) * app.config['MEM_RATIO']
|
||||||
|
hdd_cost = deploy.machine_hdd * app.config['HDD_RATIO']
|
||||||
|
total = cpu_cost + mem_cost + hdd_cost
|
||||||
|
print('total: ' + str(total))
|
||||||
|
services_ena = Service.query.filter_by(enabled=True).all()
|
||||||
|
for service in services_ena:
|
||||||
|
lastcharge = service.date_last_charge
|
||||||
|
expiry = lastcharge + relativedelta(lastcharge, months=+(service.period))
|
||||||
|
if today > expiry:
|
||||||
|
print(service.description + ' is eligible for charging')
|
||||||
|
print('last charged: ' + lastcharge.strftime('%c'))
|
||||||
|
print('expiry date: ' + expiry.strftime('%c'))
|
||||||
|
cost = service.price
|
||||||
|
print('total: ' + str(cost))
|
||||||
|
domains_ena = Domain.query.filter_by(enabled=True).all()
|
||||||
|
for domain in domains_ena:
|
||||||
|
expire = domain.date_expire
|
||||||
|
if expire - today < 60:
|
||||||
|
daysleft = relativedelta(now, expire).days
|
||||||
|
print(domain.fqdn + ' is expiring after ' + daysleft + ' for charging')
|
||||||
|
print('expiry date: ' + expire.strftime('%c'))
|
||||||
|
|
||||||
@manager.command
|
@manager.command
|
||||||
def runserver():
|
def runserver():
|
||||||
|
|
Loading…
Reference in a new issue