2018-01-11 08:19:59 -05:00
from flask import render_template , abort , redirect , url_for , abort , flash , request , current_app , make_response , g
from flask_login import login_required , login_user , logout_user , current_user
from flask_sqlalchemy import get_debug_queries
from . import panel
2018-04-22 18:00:05 -04:00
from . forms import OrderForm , MessageForm
2018-01-11 08:19:59 -05:00
from . . import db
from . . email import send_email
2018-04-22 18:00:05 -04:00
from . . models import User , Permission , Recipe , Order , Server , Deployment , Service , Region , Address , Domain , SupportTopic , SupportLine , contact_proxmaster
2018-01-11 08:19:59 -05:00
import base64
2018-04-21 20:29:54 -04:00
from datetime import date , time , datetime
from dateutil . relativedelta import relativedelta
2018-01-11 08:19:59 -05:00
@panel.after_app_request
def after_request ( response ) :
for query in get_debug_queries ( ) :
if query . duration > = current_app . config [ ' SLOW_DB_QUERY_TIME ' ] :
current_app . logger . warning ( ' Slow query: %s \n Parameters: %s \n Duration: %f s \n Context: %s \n ' % ( query . statement , query . parameters , query . duration , query . context ) )
return response
2018-02-21 11:01:35 -05:00
@panel.route ( " /deploy " , methods = [ ' GET ' , ' POST ' ] )
2018-02-07 11:19:55 -05:00
@login_required
2018-02-21 11:01:35 -05:00
def deploy ( ) :
if current_user . name is None :
return redirect ( url_for ( ' settings.profile ' ) )
2018-02-20 05:17:28 -05:00
form = OrderForm ( )
2018-01-11 08:19:59 -05:00
if form . validate_on_submit ( ) :
2018-04-01 09:29:17 -04:00
region = Region . query . filter_by ( pid = int ( form . region . data ) ) . first ( )
recipe = Recipe . query . filter_by ( pid = int ( form . recipe . data ) ) . first ( )
new_order = Order ( user_id = int ( current_user . pid ) , region_id = int ( region . pid ) , recipe_id = int ( recipe . pid ) , parameter1 = str ( form . alias . data ) , parameter2 = str ( form . cpu . data ) , parameter3 = str ( form . memory . data ) , parameter4 = str ( form . storage . data ) , status = ' new ' )
2018-02-21 11:01:35 -05:00
db . session . add ( new_order )
db . session . commit ( )
send_email ( current_app . config [ ' MAIL_USERNAME ' ] , ' New order from {} ' . format ( current_user . email ) ,
' panel/email/adm_neworder ' , user = current_user )
return redirect ( request . args . get ( ' next ' ) or url_for ( ' panel.dashboard ' ) )
return render_template ( ' panel/deploy.html ' , form = form )
2018-01-11 08:19:59 -05:00
#DASHBOARD
2018-03-31 20:10:57 -04:00
@panel.route ( " /dashboard " , defaults = { ' user_pid ' : 0 } , methods = [ ' GET ' ] )
@panel.route ( " /dashboard/<int:user_pid> " , methods = [ ' GET ' ] )
2018-01-11 08:19:59 -05:00
@login_required
2018-03-31 20:10:57 -04:00
def dashboard ( user_pid ) :
2018-01-11 08:19:59 -05:00
sys_regions = Region . query . all ( )
2018-03-31 20:10:57 -04:00
if user_pid == 0 :
cuser = current_user
else :
cuser = User . query . filter_by ( pid = user_pid ) . first ( )
if cuser == None :
abort ( 404 )
if not current_user . is_administrator ( ) :
abort ( 404 ) #hidden 403
2018-01-11 08:19:59 -05:00
inv_addresses = cuser . inv_addresses . order_by ( Address . ip . asc ( ) ) . all ( )
2018-05-22 08:28:06 -04:00
inv_deployments = cuser . inv_deployments . filter_by ( deleted = False ) . order_by ( Deployment . machine_alias . asc ( ) ) . all ( )
2018-01-11 08:19:59 -05:00
regions = { }
for region in sys_regions :
regions [ region . pid ] = region . description
inv_deploycubeids = [ ]
2018-03-31 20:10:57 -04:00
warnflag = False
2018-01-11 08:19:59 -05:00
for invcls in inv_deployments :
if invcls . user_id == cuser . pid :
2018-02-03 13:40:03 -05:00
inv_deploycubeids . extend ( [ invcls . machine_id ] )
2018-03-25 08:09:10 -04:00
#warning detector
if invcls . warning == True or invcls . enabled == False :
warnflag = True
2018-03-31 20:10:57 -04:00
2018-01-11 08:19:59 -05:00
inv_services = cuser . inv_services . filter_by ( deleted = False ) . order_by ( Service . date_last_charge . asc ( ) ) . all ( )
inv_domains = cuser . inv_domains . filter_by ( deleted = False ) . order_by ( Domain . date_created . desc ( ) ) . all ( )
#extract rrd and status from the deployments
rrd = { }
statuses = { }
#current_app.logger.warning(str(inv_deploycubeids))
for unit_id in inv_deploycubeids :
data = { ' unit_id ' : int ( unit_id ) ,
' type ' : ' kvm ' }
try :
query = contact_proxmaster ( data , ' vmrrd ' )
2018-04-07 08:55:24 -04:00
graphs_list = [ ' net ' , ' cpu ' , ' mem ' , ' hdd ' ]
rrd [ unit_id ] = { }
2018-01-11 08:19:59 -05:00
for graph in graphs_list :
raw = query [ graph ] [ ' image ' ] . encode ( ' raw_unicode_escape ' )
rrd [ unit_id ] [ graph ] = base64 . b64encode ( raw ) . decode ( )
status = { unit_id : query [ ' status ' ] }
statuses . update ( status )
except Exception as e :
current_app . logger . error ( e )
2018-04-07 08:55:24 -04:00
for invcls in inv_deployments :
if invcls . machine_id == unit_id :
inv_deployments . remove ( invcls )
2018-02-03 13:40:03 -05:00
flash ( ' Support is notified about {} . ' . format ( str ( cuser . inv_deployments . filter_by ( machine_id = unit_id ) . first ( ) . machine_alias ) ) )
2018-04-07 09:41:02 -04:00
if not current_user . is_administrator ( ) :
send_email ( current_app . config [ ' MAIL_USERNAME ' ] , ' {} experienced an error ' . format ( cuser . email ) , ' vmanager/email/adm_unreachable ' , user = current_user , unit_id = unit_id , error = repr ( e ) )
2018-04-07 08:55:24 -04:00
continue
2018-05-06 12:13:02 -04:00
supportform = MessageForm ( )
return render_template ( ' panel/dashboard.html ' , sys_regions = sys_regions , inv_deployments = inv_deployments , inv_services = inv_services , inv_domains = inv_domains , inv_addresses = inv_addresses , rrd = rrd , status = statuses , warnflag = warnflag , regions = regions , form = supportform )
2018-01-11 08:19:59 -05:00
2018-04-22 18:00:05 -04:00
#SUPPORT
@panel.route ( " /list " , methods = [ ' GET ' ] )
@login_required
def support_list ( ) :
""" general enquiry and list all open support tasks """
cuser = current_user
form = MessageForm ( )
alltopics = cuser . inv_topics . all ( )
return render_template ( ' panel/support_list.html ' , form = form , inv_topics = alltopics )
@panel.route ( " /topic/<string:topic>/ " , methods = [ ' GET ' , ' POST ' ] )
@login_required
def support ( topic ) :
""" block item for support chatbox. invoked from vdc_pool or supportlist """
cuser = current_user
form = MessageForm ( )
if request . method == " GET " :
support_topic = SupportTopic . query . filter_by ( hashtag = str ( topic ) ) . first ( )
if support_topic == None :
class EmptySupport ( ) :
hashtag = str ( topic )
timestamp = datetime . utcnow ( )
support_topic = EmptySupport ( )
return render_template ( ' panel/support_item.html ' , form = form , support = support_topic )
else :
if support_topic . user_id != cuser . pid :
abort ( 403 ) #TODO: hidden 403. there is a topic like that but its not yours!
else :
#topic is yours. show it.
return render_template ( ' panel/support_item.html ' , form = form , support = support_topic )
if request . method == " POST " and form . validate_on_submit ( ) :
support_topic = SupportTopic . query . filter_by ( hashtag = str ( topic ) ) . first ( )
if support_topic == None :
#no topic. create one?
if cuser . inv_topics . all ( ) != [ ] :
#check if other topics exist, and ratelimit
last_topic = cuser . inv_topics . order_by ( SupportTopic . timestamp . desc ( ) ) . first ( )
now = datetime . utcnow ( )
time_last_topic = last_topic . timestamp
expiry = time_last_topic + relativedelta ( time_last_topic , minutes = + 5 )
if now < expiry :
flash ( ' ratelimit. try again later ' )
return redirect ( url_for ( ' panel.support_list ' ) )
#create new topic
new_topic = SupportTopic ( user_id = cuser . pid , hashtag = str ( topic ) )
db . session . add ( new_topic )
new_line = SupportLine ( topic_id = new_topic . pid , line = str ( form . line . data ) )
db . session . add ( new_line )
else :
if support_topic . user_id == cuser . pid :
new_line = SupportLine ( topic_id = support_topic . pid , line = form . line . data )
db . session . add ( new_line )
else :
abort ( 403 ) #TODO: hidden 404
db . session . commit ( )
return redirect ( url_for ( ' panel.support_list ' ) )