# coding: utf-8 import uuid import validators from datetime import datetime from datetime import timedelta from flask import g from flask import render_template from flask import session from flask import redirect from flask import url_for from flask import request from flask import Blueprint from flask import jsonify from cloudnsru import CloudnsClient from app import models from app.cloud.controllers.common import ControllerCommon from app.cloud.controllers.common import ControllerMessagesEmail from app.cloud.controllers.users import ControllerUsers from app.cloud.controllers.users import ControllerSSHKey from app.cloud.controllers.billing import ControllerBilling from app.cloud.controllers.datacenters import ControllerDataCenters from app.cloud.controllers.containers import ControllerContainers from app.cloud.controllers.tasks import ControllerTasks viewContainers = Blueprint('containers', __name__, url_prefix='/containers') @viewContainers.route('/') def index(): # check session if not ControllerUsers().check_session(): return redirect(url_for("account.logout")) # auth user if not ControllerUsers().auth(session['email'], session['password']): return redirect(url_for("account.logout")) # get containers list containers = ControllerContainers(session['user_id']).get_items() return render_template( 'default/containers/index.html', containers=containers ) @viewContainers.route('/create', methods=['GET', 'POST']) def create(): # check session if not ControllerUsers().check_session(): return redirect(url_for("account.logout")) # auth user if not ControllerUsers().auth(session['email'], session['password']): return redirect(url_for("account.logout")) user_balance = ControllerBilling().balance_get(session['user_id']) user_ssh = ControllerSSHKey(session['user_id']) if request.method == "POST": # check user money if user_balance <= 0: g.errors['total'] += 1 g.errors['items'].append(u'No money') if g.errors['total'] == 0: # select server from selected region with available ip-addresses # select IP select_ip = models.Ips.select().where( models.Ips.datacenter == request.form['datacenter'] and models.Ips.status == 0 )[0] print 'select ip: %s' % select_ip.id # mark ip as busy (taken) up = models.Ips.update(status=1).where(models.Ips.id == select_ip.id) up.execute() # generate password for container user password = ControllerCommon().generate_password(size=14) new_container = { 'container_id': str(uuid.uuid4()), 'datacenter_id': str(select_ip.datacenter.id), 'server_id': str(select_ip.server.id), 'ipv4': select_ip.ipv4, 'ipv6': select_ip.ipv6, 'ipv4_gateway': select_ip.ipv4_gateway, 'ipv6_gateway': select_ip.ipv6_gateway, 'username': 'ubuntu', 'password': password, 'ssh_key': None, } # sshkey if user_ssh.check(): new_container['ssh_key'] = user_ssh.get() print "container data:" print new_container # create container record in database # status 4: creation status = 4 container_create = ControllerContainers(session['user_id']).create( new_container['container_id'], new_container['datacenter_id'], new_container['server_id'], new_container['ipv4'], new_container['ipv6'], status ) if container_create: # create task for create new container ControllerTasks(session['user_id']).create( new_container['datacenter_id'], new_container['server_id'], 'container_create', 0, container_id=new_container['container_id'], ipv4=new_container['ipv4'], ipv6=new_container['ipv6'], ipv4_gateway=new_container['ipv4_gateway'], ipv6_gateway=new_container['ipv6_gateway'], username=new_container['username'], password=new_container['password'], ssh_key=new_container['ssh_key'] ) # send mail message with recovery code message_parts = [] if new_container['ipv4']: message_parts.append(u"IPv4: %s" % new_container['ipv4']) if new_container['ipv6']: message_parts.append(u"IPv6: %s" % new_container['ipv6']) message_parts.append(u"Пользователь: %s" % new_container['username']) message_parts.append(u"Пароль: %s" % new_container['password']) if new_container['ssh_key']: message_parts.append(u"SSH ключ: добавлен") message = '
\n'.join(message_parts) subject = u'GoCloud.ru: Новый контейнер' lead = u"""Поздравляем с новым контейнером.""" callout = u""" Для входа в личный кабинет воспользуйтесь страницей авторизации. """ user_data = ControllerUsers(session['user_id']).get() email = ControllerMessagesEmail() email.send(title=subject, to=user_data.email, lead=lead, message=message, callout=callout) return redirect(url_for('containers.index')) else: # mark ip as busy (taken) up = models.Ips.update(status=0).where(models.Ips.id == select_ip.id) # print up up.execute() # Get datacenters list datacenters = ControllerDataCenters().get() return render_template( 'default/containers/create.html', datacenters=datacenters ) @viewContainers.route('/delete/', methods=['GET', 'POST']) def delete(container_id): # check session if not ControllerUsers().check_session(): return redirect(url_for("account.logout")) # auth user if not ControllerUsers().auth(session['email'], session['password']): return redirect(url_for("account.logout")) # containers = ControllerContainers(session['user_id']) # check the user have a selected rule # if user not have a container then redirect to the container list if not containers.check_exists_item(container_id): return redirect(url_for('containers.index')) # get container details container_details = ControllerContainers(session['user_id']).get_item(container_id) # POST if request.method == "POST": # Обновляем статус "5" для правила containers.set_status(container_id, 5) # Создание задания ControllerTasks(session['user_id']).create( container_details.datacenter.id, container_details.server.id, 'container_delete', 0, container_id=container_details.id ) # TODO: send email container was deleted about # Редиректим на страницу со всеми правилами return redirect(url_for('containers.index')) return render_template('default/containers/delete.html', containers=container_details) @viewContainers.route('/settings/', methods=['GET', 'POST']) def settings(container_id): # check session if not ControllerUsers().check_session(): return redirect(url_for("account.logout")) # auth user if not ControllerUsers().auth(session['email'], session['password']): return redirect(url_for("account.logout")) containers = ControllerContainers(session['user_id']) # check the user have a selected rule # if user not have a container then redirect to the container list if not containers.check_exists_item(container_id): return redirect(url_for('containers.index')) if request.method == 'POST': if request.form['action'] == 'set_status': if request.form['status'] == 'inactive': containers.set_status(container_id, 0) return redirect(url_for('rules.settings', container_id=container_id)) if request.form['status'] == 'active': balance = models.UsersBalance.select(models.UsersBalance.balance) \ .where(models.UsersBalance.user == session['user_id'])[0].balance if balance <= 0: g.errors['items'].append(u'Недостаточно средств на балансе.') g.errors['total'] += 1 else: # get container details container_details = ControllerContainers(session['user_id']).get_item(container_id) containers.set_status(container_id, 1) # Создание задания ControllerTasks(session['user_id']).create( container_details.datacenter.id, container_details.server.id, 'container_delete', 0, container_id=container_details.id ) return redirect(url_for('rules.settings', container_id=container_id)) # если обновление алиаса if request.form['action'] == 'set_alias': # валидация домена if validators.domain(request.form['alias']): # TODO: check exists host on the net containers.set_alias(container_id, request.form['alias']) else: g.errors['items'].append(u'Имя хоста некорректно.') g.errors['total'] += 1 # get rule details container_details = containers.get_item(container_id) return render_template('default/containers/settings.html', container=container_details) @viewContainers.route('/stats/') def stats(container_id): # check session if not ControllerUsers().check_session(): return redirect(url_for("account.logout")) # auth user if not ControllerUsers().auth(session['email'], session['password']): return redirect(url_for("account.logout")) rules = ControllerContainers(session['user_id']) # check the user have a selected rule # if user not have a container then redirect to the container list if not rules.check_exists_item(container_id): return redirect(url_for('rules.index')) rules_statistics = ControllerRulesStatistics(rule_id) stats_string = {'requests': '', 'traffic': ''} last_days = datetime.today() - timedelta(days=30) # get rule details rule_details = rules.get_item(rule_id) stats_string['traffic'] = rules_statistics.traffic_total_get(last_days) stats_string['requests'] = rules_statistics.requests_total_get(last_days) traffic_by_country = rules_statistics.traffic_by_country_get(last_days) if stats_string['traffic'] > 0: stats_string['cost'] = 0 elif stats_string['traffic'] > 50: stats_string['cost'] = 4 elif stats_string['traffic'] > 1000: stats_string['cost'] = 3 elif stats_string['traffic'] > 2000: stats_string['cost'] = 2.7 elif stats_string['traffic'] > 3000: stats_string['cost'] = 2.6 elif stats_string['traffic'] > 4000: stats_string['cost'] = 2.5 elif stats_string['traffic'] > 5000: stats_string['cost'] = 2.4 if request.args.get('format') == "json": return jsonify({ "summary": stats_string, "by_country": traffic_by_country }) return render_template('rules/stats.html', rule=rule_details, stats_string=stats_string, traffic_by_country=traffic_by_country)