diff --git a/SWSCloudCore/templates/default/vms/create.html b/SWSCloudCore/templates/default/vms/create.html
index e69de29..e57e96b 100644
--- a/SWSCloudCore/templates/default/vms/create.html
+++ b/SWSCloudCore/templates/default/vms/create.html
@@ -0,0 +1,51 @@
+{% extends "default/_layout.html" %}
+
+{% block title %}Новый виртуальный сервер{% endblock %}
+
+{% block content %}
+
+
+
Новый виртуальный сервер
+
+
+
+
+ {% if datacenters['total'] == 0 %}
+
+
+ Нет возможности создать виртуальный сервер.
+ Обратитесь в
поддержку.
+
+
+ {% else %}
+
+ {% endif %}
+
+
+{% endblock %}
diff --git a/SWSCloudCore/templates/default/vms/index.html b/SWSCloudCore/templates/default/vms/index.html
index e31bbd7..0a67d39 100644
--- a/SWSCloudCore/templates/default/vms/index.html
+++ b/SWSCloudCore/templates/default/vms/index.html
@@ -1 +1,66 @@
-
\ No newline at end of file
+{% extends "default/_layout.html" %}
+
+{% block title %}Виртуальные машины{% endblock %}
+
+{% block content %}
+
+
+
Список виртуальных машин +
+
+
+
+
+
+
+
+ ID |
+ IP |
+ Диск |
+ Память |
+ Ядра |
+ Статус |
+ |
+
+
+
+ {% if vms|length == 0 %}
+
+ Нет ни одной виртуальной машины. Добавить. |
+
+ {% else %}
+ {% for vm in vms %}
+
+ {{ vm.id }} |
+
+ {% if vm['ipv4'] %}IPv4: {{ vm['ipv4'] }}{% endif %}
+ {% if vm['ipv6'] %}IPv6: {{ vm['ipv6'] }}{% endif %}
+ |
+ {{ vm.plan.storage }} |
+ {{ vm.plan.memory }} |
+ {{ vm.plan.cores }} |
+
+ {% if vm['status'] == 0 %}
+ Неактивно
+ {% elif vm['status'] == 1 %}
+ Активно
+ {% elif vm['status'] == 2 %}
+ Процесс активации
+ {% elif vm['status'] == 3 %}
+ Процесс деактивации
+ {% elif vm['status'] == 4 %}
+ Создание...
+ {% elif vm['status'] == 5 %}
+ Удаление...
+ {% endif %}
+ |
+
+ Настройки
+ |
+
+ {% endfor %}
+ {% endif %}
+
+
+
+
+{% endblock %}
diff --git a/SWSCloudCore/views/administrator/__init__.py b/SWSCloudCore/views/administrator/__init__.py
index dc11bf0..46539f4 100644
--- a/SWSCloudCore/views/administrator/__init__.py
+++ b/SWSCloudCore/views/administrator/__init__.py
@@ -22,12 +22,14 @@ 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.tasks.manage import ControllerManageTasks
+from SWSCloudCore.controllers.plans import ControllerPlans
from SWSCloudCore import models
viewAdministrator = Blueprint('administrator', __name__, url_prefix='/administrator')
-@viewAdministrator.route('/login', methods=['GET', 'POST'])
+@viewAdministrator.route('/login.html', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
admin_email = request.form['email'].encode('utf-8')
@@ -56,7 +58,7 @@ def login():
return render_template('administrator/login.html')
-@viewAdministrator.route('/logout')
+@viewAdministrator.route('/logout.html')
def logout():
session.pop('admin_id', None)
session.pop('admin_email', None)
@@ -64,7 +66,7 @@ def logout():
return redirect(url_for('administrator.login'))
-@viewAdministrator.route('/dashboard')
+@viewAdministrator.route('/dashboard.html')
def dashboard():
# check session
if not ControllerAdministrators().check_session():
@@ -493,9 +495,35 @@ def json_datacenter_list():
@viewAdministrator.route('/tasks/', methods=['GET'])
def tasks_index():
- from SWSCloudCore.controllers.tasks.manage import ControllerManageTasks
return render_template(
'administrator/tasks/index.html',
# tasks=ControllerManageTasks().get_by_server().get()
tasks=ControllerManageTasks().get()
)
+
+
+@viewAdministrator.route('/plans/', methods=['GET'])
+def plans_index():
+ return render_template(
+ 'administrator/plans/index.html',
+ plans=ControllerPlans().get()
+ )
+
+
+@viewAdministrator.route('/plans/create.html', methods=['GET', 'POST'])
+def plans_create():
+ if request.method == "POST":
+ plan_id = str(uuid4())
+ models.PlansVMs.create(
+ id=plan_id,
+ name=request.form.get('name'),
+ status=request.form.get('status'),
+ storage=request.form.get('storage'),
+ swap=request.form.get('swap'),
+ memory=request.form.get('memory'),
+ cores=request.form.get('cores'),
+ )
+
+ flash('Plan has been created')
+ return redirect(url_for('administrator.plans_index'))
+ return render_template('administrator/plans/create.html')
diff --git a/SWSCloudCore/views/vms/__init__.py b/SWSCloudCore/views/vms/__init__.py
new file mode 100644
index 0000000..6286f40
--- /dev/null
+++ b/SWSCloudCore/views/vms/__init__.py
@@ -0,0 +1,315 @@
+# 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='/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['email'], session['password']):
+ return redirect(url_for("account.logout"))
+
+ user_balance = ControllerBilling().get(session['user_id'])
+ user_ssh = ControllerSSHKey(session['user_id'])
+
+ 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())
+
+ 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'] = 1
+ new_vm['storage'] = 20000
+ new_vm['swap'] = 512
+ new_vm['memory'] = 512
+
+ 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'],
+ ipv6=new_vm['ipv6'],
+ 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'],
+ )
+ #
+ # # 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 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(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_id
+ )
+ # TODO: send email container was deleted about
+ # Редиректим на страницу со всеми правилами
+ flash(u'Контейнер был удалён')
+ return redirect(url_for('containers.index'))
+ return render_template(
+ 'default/containers/delete.html',
+ container=container_details
+ )
+
+
+@viewVMs.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'))
+
+ # get container details
+ container_details = containers.get_item(container_id)
+
+ if request.method == 'POST':
+ if request.form['action'] == 'set_status':
+ if request.form['status'] == 'inactive':
+ containers.set_status(container_id, 3)
+ # Создание задания
+ ControllerTasks(session['user_id']).create(
+ container_details.datacenter.id,
+ container_details.server.id,
+ 'container_stop',
+ 0,
+ container_id=container_id
+ )
+ return redirect(url_for('containers.settings', container_id=container_id))
+
+ if request.form['status'] == 'active':
+ balance = ControllerBilling().get(session['user_id'])
+
+ if balance <= 0:
+ flash(u'Недостаточно средств на балансе.')
+ return redirect(url_for('containers.settings', container_id=container_id))
+
+ containers.set_status(container_id, 2)
+ # Создание задания
+ ControllerTasks(session['user_id']).create(
+ container_details.datacenter.id,
+ container_details.server.id,
+ 'container_start',
+ 0,
+ container_id=container_details.id
+ )
+ return redirect(url_for('containers.settings', container_id=container_id))
+
+ return render_template(
+ 'default/containers/settings.html',
+ container=container_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
+ )
diff --git a/cloud-db-init.py b/cloud-db-init.py
index 3cee2d8..3f4e5e4 100644
--- a/cloud-db-init.py
+++ b/cloud-db-init.py
@@ -19,6 +19,8 @@ tables = [
models.Containers,
models.ContainersStatistics,
models.ContainersStatisticsState,
+ models.PlansVMs,
+ models.Vms,
models.Tasks,
models.Settings,
models.Admins,
diff --git a/cloud-runserver.py b/cloud-runserver.py
index a771076..fa7280f 100644
--- a/cloud-runserver.py
+++ b/cloud-runserver.py
@@ -4,4 +4,4 @@
from SWSCloudCore import app
if __name__ == '__main__':
- app.run()
+ app.run(host='0.0.0.0', port=5000, debug=True)
diff --git a/setup.py b/setup.py
index 54f815e..1b29c17 100644
--- a/setup.py
+++ b/setup.py
@@ -4,7 +4,7 @@ from setuptools import setup
setup(
name='SWSCloudCore',
- version='2.1.7',
+ version='2.2.7',
author='Vyacheslav Anzhiganov',
author_email='hello@anzhiganov.com',
packages=[