From 39a8c131c59c02820ae3e22e040ab7559ebdb580 Mon Sep 17 00:00:00 2001 From: vanzhiganov Date: Tue, 11 Oct 2016 03:37:04 +0300 Subject: [PATCH] update --- .../Administrator/__init__.py | 198 ++--------- SWSCloudAdministrator/Administrator/common.py | 17 + .../Administrator/compute/__init__.py | 2 + .../Administrator/compute/containers.py | 21 ++ .../Administrator/compute/vms.py | 52 +++ SWSCloudAdministrator/Administrator/tasks.py | 26 +- SWSCloudAdministrator/Administrator/users.py | 13 - SWSCloudAdministrator/application.py | 5 +- .../templates/administrator/_layout.auth.html | 4 +- .../templates/administrator/vms/details.html | 54 +++ .../templates/administrator/vms/index.html | 4 +- .../controllers/administrators/__init__.py | 40 +-- SWSCloudCore/controllers/vms/manage.py | 28 -- SWSCloudCore/models.py | 67 ++++ SWSCloudWeb/templates/default/id/sshkey.html | 2 - SWSCloudWeb/views/compute/vms/__init__.py | 329 ++++++++++++++++++ 16 files changed, 592 insertions(+), 270 deletions(-) create mode 100644 SWSCloudAdministrator/Administrator/common.py create mode 100644 SWSCloudAdministrator/Administrator/compute/__init__.py create mode 100644 SWSCloudAdministrator/Administrator/compute/containers.py create mode 100644 SWSCloudAdministrator/Administrator/compute/vms.py create mode 100644 SWSCloudAdministrator/templates/administrator/vms/details.html create mode 100644 SWSCloudWeb/views/compute/vms/__init__.py diff --git a/SWSCloudAdministrator/Administrator/__init__.py b/SWSCloudAdministrator/Administrator/__init__.py index 1e53292..20f0456 100644 --- a/SWSCloudAdministrator/Administrator/__init__.py +++ b/SWSCloudAdministrator/Administrator/__init__.py @@ -4,17 +4,17 @@ from uuid import uuid4 import validators from flask import Blueprint, flash, g, jsonify, redirect, render_template, request, session, url_for +from SWSCloudAdministrator.Administrator.common import requires_login + from SWSCloudCore.controllers.administrators import ControllerAdministrators -from SWSCloudCore.controllers.billing import ControllerBilling +# from SWSCloudCore.controllers.billing import ControllerBilling from SWSCloudCore.controllers.common import ControllerMessagesEmail -from SWSCloudCore.controllers.containers.manage import ControllerManageContainers -from SWSCloudCore.controllers.vms.manage import ControllerVMSManage from SWSCloudCore.controllers.datacenters.manage import ControllerManageDatacenters from SWSCloudCore.controllers.ips.manage import ControllerManageIPs from SWSCloudCore.controllers.servers.manage import ControllerManageServer -from SWSCloudCore.controllers.users.manage import ControllerManageUsers -from SWSCloudCore.controllers.users.manage import ControllerManageUsersBalance -from SWSCloudCore.controllers.users.manage import ControllerManageUsersDetails +# from SWSCloudCore.controllers.users.manage import ControllerManageUsers +# from SWSCloudCore.controllers.users.manage import ControllerManageUsersBalance +# from SWSCloudCore.controllers.users.manage import ControllerManageUsersDetails from SWSCloudCore.controllers.plans import ControllerPlans from SWSCloudCore import models @@ -59,14 +59,8 @@ def logout(): @viewAdministrator.route('/dashboard.html') +@requires_login def dashboard(): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - # auth user - if not ControllerAdministrators().auth(session['admin_email'], session['admin_password']): - return redirect(url_for("administrator.logout")) - # stats = { 'users': models.Users.select().count(), 'datacenters': models.DataCenters.select().count(), @@ -78,51 +72,12 @@ def dashboard(): } # return render_template( - 'administrator/dashboard.html', - stats=stats - ) - - -@viewAdministrator.route('/containers/') -def containers(): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - # auth user - if not ControllerAdministrators().auth(session['admin_email'], session['admin_password']): - return redirect(url_for("administrator.logout")) - # формируем список правил - rules_items = ControllerManageContainers().get_all_items() - return render_template( - 'administrator/containers/index.html', - containers=rules_items - ) - - -@viewAdministrator.route('/vms/') -def vms(): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - # auth user - if not ControllerAdministrators().auth(session['admin_email'], session['admin_password']): - return redirect(url_for("administrator.logout")) - # формируем список правил - vms_items = ControllerVMSManage().get() - return render_template( - 'administrator/vms/index.html', - vms=vms_items - ) + 'administrator/dashboard.html', stats=stats) @viewAdministrator.route('/payments') +@requires_login def payments(): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - # auth user - if not ControllerAdministrators().auth(session['admin_email'], session['admin_password']): - return redirect(url_for("administrator.logout")) payments_items = { 'total': models.UsersBalanceTransactions.select().count(), 'items': models.UsersBalanceTransactions.select() @@ -134,29 +89,16 @@ def payments(): @viewAdministrator.route('/datacenters') +@requires_login def datacenters(): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - # auth user - if not ControllerAdministrators().auth(session['admin_email'], session['admin_password']): - return redirect(url_for("administrator.logout")) - # return render_template( 'administrator/datacenters/index.html', - datacenters=ControllerManageDatacenters().items_get() - ) + datacenters=ControllerManageDatacenters().items_get()) @viewAdministrator.route('/datacenters/create', methods=['GET', 'POST']) +@requires_login def datacenters_create(): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - # auth user - if not ControllerAdministrators().auth(session.get('admin_email'), session.get('admin_password')): - return redirect(url_for("administrator.logout")) - if request.method == "POST": # TODO: validate dc_name = request.form.get('name') @@ -179,13 +121,8 @@ def datacenters_create(): @viewAdministrator.route('/datacenters/edit/', methods=['GET', 'POST']) +@requires_login def datacenters_edit(dc_id): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - # auth user - if not ControllerAdministrators().auth(session['admin_email'], session['admin_password']): - return redirect(url_for("administrator.logout")) # check exists datacenter if not ControllerManageDatacenters().check_exists(dc_id): return redirect(url_for('administrator.datacenters')) @@ -203,45 +140,28 @@ def datacenters_edit(dc_id): @viewAdministrator.route('/servers/') +@requires_login def servers_index(): - ca = ControllerAdministrators() + # ca = ControllerAdministrators() cms = ControllerManageServer() - # check session - if not ca.check_session(): - return redirect(url_for("administrator.logout")) - # auth user - if not ca.auth(session.get('admin_email'), session.get('admin_password')): - return redirect(url_for("administrator.logout")) # return render_template( 'administrator/servers/index.html', - servers=cms.items_get() - ) + servers=cms.items_get()) @viewAdministrator.route('/ips/') +@requires_login def ips_index(): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - # auth user - if not ControllerAdministrators().auth(session['admin_email'], session['admin_password']): - return redirect(url_for("administrator.logout")) # return render_template( 'administrator/ips/index.html', - ips=ControllerManageIPs().items_get() - ) + ips=ControllerManageIPs().items_get()) @viewAdministrator.route('/ips/create', methods=['POST', 'GET']) +@requires_login def ips_create(): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - # auth user - if not ControllerAdministrators().auth(session['admin_email'], session['admin_password']): - return redirect(url_for("administrator.logout")) # if request.method == "POST": print request.form @@ -276,13 +196,8 @@ def ips_create(): @viewAdministrator.route('/ips/edit/', methods=['GET', 'POST']) +@requires_login def ips_edit(ip_id): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - # auth user - if not ControllerAdministrators().auth(session['admin_email'], session['admin_password']): - return redirect(url_for("administrator.logout")) # if request.method == 'POST': print request.form @@ -314,14 +229,8 @@ def ips_delete(): @viewAdministrator.route('/servers/create', methods=['GET', 'POST']) +@requires_login def servers_create(): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - # auth user - if not ControllerAdministrators().auth(session['admin_email'], session['admin_password']): - return redirect(url_for("administrator.logout")) - if request.method == "POST": print request.form params = { @@ -352,13 +261,8 @@ def servers_create(): @viewAdministrator.route('/servers/edit/.html', methods=['GET', 'POST']) +@requires_login def server_edit(server_id): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - # auth user - if not ControllerAdministrators().auth(session.get('admin_email'), session.get('admin_password')): - return redirect(url_for("administrator.logout")) # check exists server if models.Servers.select().where(models.Servers.id == server_id).count() == 0: return redirect(url_for('administrator.servers')) @@ -374,14 +278,8 @@ def server_edit(server_id): @viewAdministrator.route('/settings/') +@requires_login def settings_index(): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - # auth user - if not ControllerAdministrators().auth(session['admin_email'], session['admin_password']): - return redirect(url_for("administrator.logout")) - settings_list = { 'total': models.Settings.select().count(), 'items': models.Settings.select() @@ -391,13 +289,8 @@ def settings_index(): @viewAdministrator.route('/settings/create', methods=['GET', 'POST']) +@requires_login def settings_create(): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - # auth user - if not ControllerAdministrators().auth(session['admin_email'], session['admin_password']): - return redirect(url_for("administrator.logout")) # Обрабатываем POST-запрос if request.method == 'POST': # check exists `key` @@ -414,13 +307,8 @@ def settings_create(): @viewAdministrator.route('/settings/delete', methods=['GET', 'POST']) +@requires_login def settings_delete(): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - # - if models.Settings.select().where(models.Settings.id == request.args['id']).count() == 0: - return redirect(url_for('administrator.settings_index')) # if request.method == 'POST': delete_set = models.Settings.delete().where(models.Settings.id == request.form['id']) @@ -433,13 +321,8 @@ def settings_delete(): @viewAdministrator.route('/settings/update', methods=['GET', 'POST']) +@requires_login def settings_update(): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - - if models.Settings.select().where(models.Settings.id == request.args['id']).count() == 0: - return redirect(url_for('administrator.settings_index')) # if request.method == 'POST': uq = models.Settings.update(val=request.form['val']).where(models.Settings.id == request.form['id']) @@ -451,11 +334,8 @@ def settings_update(): @viewAdministrator.route('/settings/messages/email_test.html', methods=['GET', 'POST']) +@requires_login def settings_messages_email_test(): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - email = ControllerMessagesEmail() email.send(title='test', to='vanzhiganov@ya.ru', lead='qwdqwd', message='qwdqwd', callout='qwdqwd') # if request.method == 'POST': @@ -463,33 +343,27 @@ def settings_messages_email_test(): # uq.execute() # return redirect(url_for('administrator.settings_index')) # get setting parameter by ID - setting = models.Settings.select().where(models.Settings.id == request.args['id']).limit(1)[0] + # setting = models.Settings.select().where(models.Settings.id == request.args['id']).limit(1)[0] return render_template('administrator/settings/messages/email.html') @viewAdministrator.route('/json/datacenter/list', methods=['GET']) +@requires_login def json_datacenter_list(): return jsonify(ControllerManageDatacenters().items_get()) @viewAdministrator.route('/plans/', methods=['GET']) +@requires_login def plans_index(): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - return render_template( 'administrator/plans/index.html', - plans=ControllerPlans().get() - ) + plans=ControllerPlans().get()) @viewAdministrator.route('/plans/create.html', methods=['GET', 'POST']) +@requires_login def plans_create(): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - if request.method == "POST": plan_id = str(uuid4()) models.PlansVMs.create( @@ -509,11 +383,8 @@ def plans_create(): @viewAdministrator.route('/plans//edit.html', methods=['GET', 'POST']) +@requires_login def plan_edit(plan_id): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - # check exists plan if models.PlansVMs.select().where(models.PlansVMs.id == plan_id).count() == 0: return redirect(url_for('administrator.plans_index')) @@ -533,5 +404,4 @@ def plan_edit(plan_id): return render_template( 'administrator/plans/edit.html', - plan_details=models.PlansVMs.select().where(models.PlansVMs.id == plan_id).get() - ) + plan_details=models.PlansVMs.select().where(models.PlansVMs.id == plan_id).get()) diff --git a/SWSCloudAdministrator/Administrator/common.py b/SWSCloudAdministrator/Administrator/common.py new file mode 100644 index 0000000..7839aba --- /dev/null +++ b/SWSCloudAdministrator/Administrator/common.py @@ -0,0 +1,17 @@ +from functools import wraps +from flask import redirect, url_for, request, session +from SWSCloudCore.models import Admins + + +def requires_login(f): + @wraps(f) + def decorated_function(*args, **kwargs): + if 'admin_email' not in session or 'admin_id' not in session or 'admin_password' not in session: + # flash(u'You need to be signed in for this page.') + return redirect(url_for('administrator.logout', next=request.path)) + # auth user + if not Admins.auth(session.get('admin_email'), session.get('admin_password')): + return redirect(url_for("administrator.logout")) + + return f(*args, **kwargs) + return decorated_function diff --git a/SWSCloudAdministrator/Administrator/compute/__init__.py b/SWSCloudAdministrator/Administrator/compute/__init__.py new file mode 100644 index 0000000..d4befa1 --- /dev/null +++ b/SWSCloudAdministrator/Administrator/compute/__init__.py @@ -0,0 +1,2 @@ +from .vms import view_administrator_compute_vms +from .containers import view_administrator_compute_containers diff --git a/SWSCloudAdministrator/Administrator/compute/containers.py b/SWSCloudAdministrator/Administrator/compute/containers.py new file mode 100644 index 0000000..28429f2 --- /dev/null +++ b/SWSCloudAdministrator/Administrator/compute/containers.py @@ -0,0 +1,21 @@ +# coding: utf-8 + +from flask import Blueprint, flash, g, jsonify, redirect, render_template, request, session, url_for +from SWSCloudCore.controllers.administrators import ControllerAdministrators +from SWSCloudCore.controllers.tasks.manage import ControllerManageTasks +from SWSCloudCore.controllers.containers.manage import ControllerManageContainers +from SWSCloudCore.controllers.tasks import ControllerTasks +from SWSCloudCore import models +from SWSCloudAdministrator.Administrator.common import requires_login + +view_administrator_compute_containers = Blueprint( + 'administrator_compute_containers', __name__, url_prefix='/administrator/compute/containers') + + +@view_administrator_compute_containers.route('/') +@requires_login +def index(): + # формируем список правил + return render_template( + 'administrator/containers/index.html', + containers=models.Containers.get_items()) diff --git a/SWSCloudAdministrator/Administrator/compute/vms.py b/SWSCloudAdministrator/Administrator/compute/vms.py new file mode 100644 index 0000000..ca2ff20 --- /dev/null +++ b/SWSCloudAdministrator/Administrator/compute/vms.py @@ -0,0 +1,52 @@ +# coding: utf-8 + +from flask import Blueprint, flash, g, jsonify, redirect, render_template, request, session, url_for +from SWSCloudCore.controllers.administrators import ControllerAdministrators +from SWSCloudCore.controllers.tasks.manage import ControllerManageTasks +from SWSCloudCore.controllers.tasks import ControllerTasks +from SWSCloudCore import models +from SWSCloudAdministrator.Administrator.common import requires_login + +view_administrator_compute_vms = Blueprint('administrator_compute_vms', __name__, url_prefix='/administrator/compute/vms') + + +@view_administrator_compute_vms.route('/', methods=['GET']) +@requires_login +def index(): + # формируем список правил + return render_template( + 'administrator/vms/index.html', vms=models.Vms.get_items()) + + +@view_administrator_compute_vms.route('/', methods=['GET']) +@requires_login +def details(vm_id): + if not models.Vms.exists(vm_id): + return redirect(url_for('.index')) + # формируем список правил + return render_template( + 'administrator/vms/details.html', vm=models.Vms.get_item(vm_id)) + + +@view_administrator_compute_vms.route('//delete', methods=['POST']) +@requires_login +def delete(vm_id): + vm_details = models.Vms.get_item(vm_id) + # vm_details.user.id + # Обновляем статус "5" для правила + models.Vms.set_status(vm_id, 5) + + # Создание задания + tasks = ControllerTasks(vm_details.user.id) + tasks.create( + datacenter_id=vm_details.datacenter.id, + server_id=vm_details.server.id, + task='vm_delete', + status=0, + vm_id=vm_id + ) + # TODO: send email container was deleted about + # Редиректим на страницу со всеми правилами + flash(u'Виртуальная машина будет удалена') + return redirect(url_for('.index')) + diff --git a/SWSCloudAdministrator/Administrator/tasks.py b/SWSCloudAdministrator/Administrator/tasks.py index 21aa1a5..5c2a639 100644 --- a/SWSCloudAdministrator/Administrator/tasks.py +++ b/SWSCloudAdministrator/Administrator/tasks.py @@ -7,17 +7,15 @@ from flask import Blueprint, flash, g, jsonify, redirect, render_template, reque from SWSCloudCore.controllers.administrators import ControllerAdministrators from SWSCloudCore.controllers.tasks.manage import ControllerManageTasks +from SWSCloudAdministrator.Administrator.common import requires_login from SWSCloudCore import models view_administrator_tasks = Blueprint('administrator_tasks', __name__, url_prefix='/administrator/tasks') @view_administrator_tasks.route('/', methods=['GET']) +@requires_login def index(): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - return render_template( 'administrator/tasks/index.html', # tasks=ControllerManageTasks().get_by_server().get() @@ -26,11 +24,8 @@ def index(): @view_administrator_tasks.route('/edit.html', methods=['GET']) +@requires_login def edit(): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - task_id = request.args.get('task_id') # TODO: check exists @@ -42,11 +37,8 @@ def edit(): @view_administrator_tasks.route('/edit.html', methods=['POST']) +@requires_login def edit_post(): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - task_id = request.form.get('task_id') # TODO: check exists @@ -57,11 +49,8 @@ def edit_post(): @view_administrator_tasks.route('/delete.html', methods=['GET']) +@requires_login def delete(): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - task_id = request.args.get('task_id') # TODO: check exists @@ -73,11 +62,8 @@ def delete(): @view_administrator_tasks.route('/delete.html', methods=['POST']) +@requires_login def delete_post(): - # check session - if not ControllerAdministrators().check_session(): - return redirect(url_for("administrator.logout")) - task_id = request.form.get('task_id') # TODO: check exists diff --git a/SWSCloudAdministrator/Administrator/users.py b/SWSCloudAdministrator/Administrator/users.py index 83c1eb8..c61cac8 100644 --- a/SWSCloudAdministrator/Administrator/users.py +++ b/SWSCloudAdministrator/Administrator/users.py @@ -1,31 +1,18 @@ # coding: utf-8 -from uuid import uuid4 -import validators - from flask import Blueprint, flash from flask import g -from flask import jsonify from flask import redirect from flask import render_template from flask import request from flask import session from flask import url_for -from SWSCloudAdministrator.Administrator.tasks import view_administrator_tasks from SWSCloudCore.controllers.administrators import ControllerAdministrators from SWSCloudCore.controllers.billing import ControllerBilling -from SWSCloudCore.controllers.common import ControllerMessagesEmail -from SWSCloudCore.controllers.containers.manage import ControllerManageContainers -from SWSCloudCore.controllers.vms.manage import ControllerVMSManage -from SWSCloudCore.controllers.datacenters.manage import ControllerManageDatacenters -from SWSCloudCore.controllers.ips.manage import ControllerManageIPs -from SWSCloudCore.controllers.servers.manage import ControllerManageServer from SWSCloudCore.controllers.users.manage import ControllerManageUsers from SWSCloudCore.controllers.users.manage import ControllerManageUsersBalance from SWSCloudCore.controllers.users.manage import ControllerManageUsersDetails -from SWSCloudCore.controllers.plans import ControllerPlans -from SWSCloudCore import models view_administrator_users = Blueprint('administrator_users', __name__, url_prefix='/administrator/users') diff --git a/SWSCloudAdministrator/application.py b/SWSCloudAdministrator/application.py index 18c75c9..a549e8c 100644 --- a/SWSCloudAdministrator/application.py +++ b/SWSCloudAdministrator/application.py @@ -10,6 +10,8 @@ from SWSCloudCore.models import database from SWSCloudAdministrator.Administrator import viewAdministrator from SWSCloudAdministrator.Administrator.users import view_administrator_users from SWSCloudAdministrator.Administrator.tasks import view_administrator_tasks +from SWSCloudAdministrator.Administrator.compute import view_administrator_compute_vms +from SWSCloudAdministrator.Administrator.compute import view_administrator_compute_containers app = Flask(__name__, static_folder='static', static_url_path='') # app.config['SERVER_NAME'] = settings.get('Application', 'SERVER_NAME') @@ -21,7 +23,8 @@ babel = Babel(app) app.register_blueprint(viewAdministrator) app.register_blueprint(view_administrator_tasks) app.register_blueprint(view_administrator_users) - +app.register_blueprint(view_administrator_compute_vms) +app.register_blueprint(view_administrator_compute_containers) # @app.errorhandler(404) # def page_not_found(e): diff --git a/SWSCloudAdministrator/templates/administrator/_layout.auth.html b/SWSCloudAdministrator/templates/administrator/_layout.auth.html index 4ec5ead..be82675 100644 --- a/SWSCloudAdministrator/templates/administrator/_layout.auth.html +++ b/SWSCloudAdministrator/templates/administrator/_layout.auth.html @@ -27,8 +27,8 @@
  • Services
  • Infrastructure diff --git a/SWSCloudAdministrator/templates/administrator/vms/details.html b/SWSCloudAdministrator/templates/administrator/vms/details.html new file mode 100644 index 0000000..79e08df --- /dev/null +++ b/SWSCloudAdministrator/templates/administrator/vms/details.html @@ -0,0 +1,54 @@ +{% extends 'administrator/_layout.auth.html' %} + +{% block title %}Virtual machines{% endblock %} + +{% block subtitle %}Details{% endblock %} + +{% block content %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Id{{ vm.id }}
    Datacenter{{ vm.datacenter.name }}
    Server{{ vm.server.hostname }}
    User{{ vm.user.email }}
    IPv4{{ vm.ipv4 }}
    IPv6{{ vm.ipv6 }}
    Status{{ vm.status }}
      + Cancel +
    +
    +
    +

    Delete instance

    +
    + +
    +
    +
    +{% endblock %} diff --git a/SWSCloudAdministrator/templates/administrator/vms/index.html b/SWSCloudAdministrator/templates/administrator/vms/index.html index 072868d..f7f2736 100644 --- a/SWSCloudAdministrator/templates/administrator/vms/index.html +++ b/SWSCloudAdministrator/templates/administrator/vms/index.html @@ -34,7 +34,9 @@ {{ vm.ipv4 }} {{ vm.ipv6 }} {{ vm.status }} - Edit + + Edit + {% endfor %} {% endif %} diff --git a/SWSCloudCore/controllers/administrators/__init__.py b/SWSCloudCore/controllers/administrators/__init__.py index 7b5a1d4..7b53148 100644 --- a/SWSCloudCore/controllers/administrators/__init__.py +++ b/SWSCloudCore/controllers/administrators/__init__.py @@ -1,46 +1,8 @@ # coding: utf-8 -from hashlib import md5 -from flask import session from SWSCloudCore import models -class ControllerAdministrators: - def __init__(self): - pass - - def auth(self, email, password, status=1): - """ - - :param email: - :param password: - :param status: - :return: - """ - result = models.Admins.select().where( - models.Admins.email == email, - models.Admins.password == md5(password).hexdigest(), - models.Admins.status == status - ).count() - - if result == 0: - return False - return True - +class ControllerAdministrators(object): def get_id_by_email(self, email): return models.Admins.get(models.Admins.email == email).id - - def check_session(self): - """ - Check session for contain a required keys - :return: bool - """ - required = ['admin_email', 'admin_password', 'admin_id'] - success = True - - for r in required: - if r in session and success: - continue - else: - success = False - return success diff --git a/SWSCloudCore/controllers/vms/manage.py b/SWSCloudCore/controllers/vms/manage.py index 8561e6c..57d631c 100644 --- a/SWSCloudCore/controllers/vms/manage.py +++ b/SWSCloudCore/controllers/vms/manage.py @@ -1,29 +1 @@ # coding: utf-8 - -from SWSCloudCore.models import Vms - - -class ControllerVMSManage(object): - def __init__(self): - pass - - def get(self, vm_id=None): - if vm_id: - return Vms.select().where(Vms.id == vm_id).get() - return Vms.select() - - def exists(self, vm_id): - if Vms.select().where(Vms.id == vm_id).count() == 0: - return False - return True - - def status_set(self, vm_id, status): - """ - - :param vm_id: - :param status: - :return: - """ - x = Vms.update(status=status).where(Vms.id == vm_id) - x.execute() - return True diff --git a/SWSCloudCore/models.py b/SWSCloudCore/models.py index 27ed625..af54c2a 100644 --- a/SWSCloudCore/models.py +++ b/SWSCloudCore/models.py @@ -1,6 +1,8 @@ # coding: utf-8 +from hashlib import md5 import datetime +import uuid from peewee import * from playhouse.shortcuts import RetryOperationalError @@ -175,6 +177,10 @@ class Containers(PgSQLModel): # 0: inactive, 1: active, 2: ..., 3: ..., 4: ..., 5: ... status = IntegerField() + @staticmethod + def get_items(): + return Containers.select().execute() + class ContainersStatistics(PgSQLModel): container = ForeignKeyField(Containers) @@ -214,6 +220,32 @@ class Vms(PgSQLModel): # 0: inactive, 1: active, 2: ..., 3: ..., 4: ..., 5: ... status = IntegerField() + @staticmethod + def get_items(): + return Vms.select() + + @staticmethod + def get_item(vm_id): + return Vms.select().where(Vms.id == vm_id).first() + + @staticmethod + def exists(vm_id): + if Vms.select().where(Vms.id == vm_id).count() == 0: + return False + return True + + @staticmethod + def set_status(vm_id, status): + """ + + :param vm_id: + :param status: + :return: + """ + x = Vms.update(status=status).where(Vms.id == vm_id) + x.execute() + return True + class Tasks(PgSQLModel): id = UUIDField(primary_key=True, unique=True) @@ -226,6 +258,23 @@ class Tasks(PgSQLModel): status = IntegerField(null=False, default=0) plain = TextField() + # @staticmethod + # def set_task(datacenter_id, server_id, task, status, **args): + # task_id = uuid.uuid4() + # plain = dict() + # for arg in args: + # plain[arg] = str(args[arg]) + # + # Tasks.create( + # id=task_id, + # datacenter=datacenter_id, + # server=server_id, + # task=task, + # status=status, + # user=self.user_id, + # plain=json.dumps(plain) + # ) + class Settings(PgSQLModel): """ @@ -241,6 +290,24 @@ class Admins(PgSQLModel): password = CharField() status = IntegerField() + @staticmethod + def auth(email, password, status=1): + """ + + :param email: + :param password: + :param status: + :return: + """ + password_hash = md5(password).hexdigest() + + if Admins.select().where( + Admins.email == email, + Admins.password == password_hash, + Admins.status == status).count() == 0: + return False + return True + class Notifications(PgSQLModel): user = ForeignKeyField(Users) diff --git a/SWSCloudWeb/templates/default/id/sshkey.html b/SWSCloudWeb/templates/default/id/sshkey.html index 75d0fd7..672e935 100644 --- a/SWSCloudWeb/templates/default/id/sshkey.html +++ b/SWSCloudWeb/templates/default/id/sshkey.html @@ -7,8 +7,6 @@

    Учётная запись

    -
    - {% include "default/id/_menu.html" %}
    diff --git a/SWSCloudWeb/views/compute/vms/__init__.py b/SWSCloudWeb/views/compute/vms/__init__.py new file mode 100644 index 0000000..89c2ebc --- /dev/null +++ b/SWSCloudWeb/views/compute/vms/__init__.py @@ -0,0 +1,329 @@ +# coding: utf-8 + +import uuid +from flask import Blueprint, g, redirect, render_template, request, session +from flask import url_for, flash + +from SWSCloudCore.controllers.billing import ControllerBilling +from SWSCloudCore.controllers.common import ControllerCommon +from SWSCloudCore.controllers.common import ControllerMessagesEmail +from SWSCloudCore.controllers.vms import ControllerVMS +from SWSCloudCore.controllers.datacenters import ControllerDataCenters +from SWSCloudCore.controllers.ips import ControllerIps +from SWSCloudCore.controllers.tasks import ControllerTasks +from SWSCloudCore.controllers.users import ControllerSSHKey +from SWSCloudCore.controllers.users import ControllerUsers +from SWSCloudCore.controllers.plans import ControllerPlans + +viewVMs = Blueprint('vms', __name__, url_prefix='/compute/vms') + + +@viewVMs.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")) + return render_template( + 'default/vms/index.html', + # get containers list + vms=ControllerVMS(session['user_id']).get()) + + +@viewVMs.route('/create.html', 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.get('email'), session.get('password')): + return redirect(url_for("account.logout")) + + user_balance = ControllerBilling().get(session.get('user_id')) + user_ssh = ControllerSSHKey(session.get('user_id')) + controller_plans = ControllerPlans() + + if request.method == "POST": + # check user money + if user_balance <= 0: + flash(u'Недостаточно средств на аккаунте') + return redirect(url_for('vms.create')) + + new_vm = dict() + new_vm['vm_id'] = str(uuid.uuid4()) + + # check exists plan + if not controller_plans.exists(request.form.get('plan')): + flash(u'Необходимо выбрать план') + return redirect(url_for('vms.create')) + + # load plan details + plan_details = controller_plans.plan_get(request.form.get('plan')) + + new_vm['plan'] = request.form.get('plan') + + # select server from selected region with available ip-addresses + # select IP + select_ip = ControllerIps().getfree(request.form['datacenter']) + # mark ip as busy (taken) + ControllerIps().setbusy(select_ip.id) + + # generate password for container user + new_vm['password'] = ControllerCommon().generate_password(size=14) + new_vm['hostname'] = ControllerCommon().generate_password(size=7) + + new_vm['datacenter_id'] = str(select_ip.datacenter.id) + new_vm['server_id'] = str(select_ip.server.id) + + new_vm['platform'] = 'x86_64' + new_vm['ipv4'] = select_ip.ipv4 + new_vm['ipv6'] = select_ip.ipv6 + + new_vm['ipv4_gateway'] = select_ip.ipv4_gateway + new_vm['ipv6_gateway'] = select_ip.ipv6_gateway + + # TODO: remove hardcore + new_vm['dns1'] = '8.8.8.8' + new_vm['dns2'] = '8.8.4.4' + + new_vm['cores'] = plan_details.cores + new_vm['storage'] = plan_details.storage + new_vm['swap'] = plan_details.swap + new_vm['memory'] = plan_details.memory + + new_vm['os_name'] = 'ubuntu' + new_vm['os_suite'] = 'trusty' + + # sshkey + new_vm['ssh_key'] = None + if user_ssh.check(): + new_vm['ssh_key'] = user_ssh.get() + + # create container record in database + # status 4: creation + status = 4 + container_create = ControllerVMS(session['user_id']).create( + vm_id=new_vm['vm_id'], + datacenter_id=new_vm['datacenter_id'], + server_id=new_vm['server_id'], + hostname=new_vm['hostname'], + ipv4=new_vm['ipv4'], + ipv6=new_vm['ipv6'], + plan=new_vm['plan'], + platform=new_vm['platform'], + os_name=new_vm['os_name'], + os_suite=new_vm['os_suite'], + status=status + ) + # create default state data + # ControllerContainersStatisticsState().set(new_container['container_id'], dict()) + if container_create: + # create task for create new container + ControllerTasks(session['user_id']).create( + new_vm['datacenter_id'], + new_vm['server_id'], + 'vm_create', + 0, + vm_id=new_vm['vm_id'], + ipv4=new_vm['ipv4'], + ipv4_gateway=new_vm['ipv4_gateway'], + ipv6=new_vm['ipv6'], + ipv6_gateway=new_vm['ipv6_gateway'], + password=new_vm['password'], + hostname=new_vm['hostname'], + platform=new_vm['platform'], + # TODO: remove hardcore + dns1=new_vm['dns1'], + dns2=new_vm['dns2'], + + cores=new_vm['cores'], + storage=new_vm['storage'], + swap=new_vm['swap'], + memory=new_vm['memory'], + + os_name=new_vm['os_name'], + os_suite=new_vm['os_suite'], + + ssh_key=new_vm['ssh_key'], + ) + + # Show login/password on page + flash(u'Виртуальный сервер будет доступен через несколько минут.') + + # send mail message with recovery code + message_parts = [] + + if new_vm['ipv4']: + message_parts.append(u"IPv4: %s" % new_vm['ipv4']) + if new_vm['ipv6']: + message_parts.append(u"IPv6: %s" % new_vm['ipv6']) + message_parts.append(u"Пользователь: %s" % 'administrator') + # message_parts.append(u"Пользователь: %s" % new_vm['username']) + message_parts.append(u"Пароль: %s" % new_vm['password']) + if new_vm['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('vms.index')) + else: + # mark ip as free + ControllerIps().setfree(select_ip.id) + + # Get datacenters list + datacenters = ControllerDataCenters().get() + plans = ControllerPlans().get('active') + # + return render_template( + 'default/vms/create.html', + datacenters=datacenters, + plans=plans, + ) + + +@viewVMs.route('/delete/.html', methods=['GET', 'POST']) +def delete(vm_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")) + # + vms = ControllerVMS(session['user_id']) + tasks = ControllerTasks(session['user_id']) + # check the user have a selected rule + # if user not have a container then redirect to the container list + if not vms.exists(vm_id): + return redirect(url_for('vms.index')) + + # get container details + vm_details = vms.get(vm_id) + # POST + if request.method == "POST": + # Обновляем статус "5" для правила + vms.set_status(vm_id, 5) + # Создание задания + tasks.create( + datacenter_id=vm_details.datacenter.id, + server_id=vm_details.server.id, + task='vm_delete', + status=0, + vm_id=vm_id, + # hostname=vm_details.hostname + ) + # TODO: send email container was deleted about + # Редиректим на страницу со всеми правилами + flash(u'Виртуальная машина будет удалена') + return redirect(url_for('vms.index')) + return render_template('default/vms/delete.html', vm=vm_details) + + +@viewVMs.route('/settings/.html', methods=['GET', 'POST']) +def settings(vm_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")) + + vm = ControllerVMS(session['user_id']) + + # check the user have a selected rule + # if user not have a container then redirect to the container list + if not vm.exists(vm_id): + return redirect(url_for('vms.index')) + + # get container details + vm_details = vm.get(vm_id=vm_id) + + if request.method == 'POST': + if request.form['action'] == 'set_status': + if request.form['action'] == 'stop': + vm.status_set(vm_id, 3) + # Создание задания + ControllerTasks(session['user_id']).create( + vm_details.datacenter.id, + vm_details.server.id, + 'vm_stop', + 0, + vm_id=vm_id + ) + return redirect(url_for('vms.settings', vm_id=vm_id)) + + if request.form.get('action') == 'start': + balance = ControllerBilling().get(session['user_id']) + + if balance <= 0: + flash(u'Недостаточно средств на балансе.') + return redirect(url_for('vms.settings', vm_id=vm_id)) + + vm.set_status(vm_id, 2) + # Создание задания + ControllerTasks(session.get('user_id')).create( + vm_details.datacenter.id, + vm_details.server.id, + 'vm_start', + 0, + vm_id=vm_details.id + ) + return redirect(url_for('vms.settings', vm_id=vm_id)) + + return render_template( + 'default/vms/settings.html', + vm=vm_details + ) + + +@viewVMs.route('/stats/.html') +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")) + # init + 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 = containers.get_item(container_id) + # print ControllerContainersStatisticsState().get(container_id) + + statistics = [] + for s in ControllerContainersStatistics(container_id).size_get(1): + # print time.strftime(s.created, '%Y') + # print datetime.datetime.strptime(s.created, '%Y') + # print time.strftime("%B %d %Y", s.created) + created = s.created + statistics.append({ + 'year': created.strftime('%Y'), + 'month': created.strftime('%m'), + 'day': created.strftime('%d'), + 'hour': created.strftime('%H'), + 'minute': created.strftime('%M'), + 'data': s.memory + }) + # return + return render_template( + 'default/containers/stats.html', + container=container_details, + stats_memory=statistics + )