39 QEMU virtual machines
This commit is contained in:
parent
56dd407b57
commit
93ccb6f7c2
21 changed files with 661 additions and 27 deletions
|
@ -9,6 +9,7 @@ from SWSCloudCore.views.account import viewAccount
|
||||||
from SWSCloudCore.views.administrator import viewAdministrator
|
from SWSCloudCore.views.administrator import viewAdministrator
|
||||||
from SWSCloudCore.views.api import viewAPI
|
from SWSCloudCore.views.api import viewAPI
|
||||||
from SWSCloudCore.views.containers import viewContainers
|
from SWSCloudCore.views.containers import viewContainers
|
||||||
|
from SWSCloudCore.views.vms import viewVMs
|
||||||
from SWSCloudCore.views.documents import viewDocuments
|
from SWSCloudCore.views.documents import viewDocuments
|
||||||
from SWSCloudCore.views.kb import viewKB
|
from SWSCloudCore.views.kb import viewKB
|
||||||
from SWSCloudCore.views.server_api import viewServerAPI
|
from SWSCloudCore.views.server_api import viewServerAPI
|
||||||
|
@ -38,6 +39,7 @@ app.register_blueprint(viewAPI)
|
||||||
app.register_blueprint(viewTasks)
|
app.register_blueprint(viewTasks)
|
||||||
# /containers
|
# /containers
|
||||||
app.register_blueprint(viewContainers)
|
app.register_blueprint(viewContainers)
|
||||||
|
app.register_blueprint(viewVMs)
|
||||||
# /id
|
# /id
|
||||||
app.register_blueprint(viewAccount)
|
app.register_blueprint(viewAccount)
|
||||||
# /payments
|
# /payments
|
||||||
|
|
15
SWSCloudCore/controllers/plans/__init__.py
Normal file
15
SWSCloudCore/controllers/plans/__init__.py
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
from SWSCloudCore.models import PlansVMs
|
||||||
|
|
||||||
|
|
||||||
|
class ControllerPlans(object):
|
||||||
|
def get(self, status=None):
|
||||||
|
"""
|
||||||
|
Тарифные планы
|
||||||
|
:param status:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
if status:
|
||||||
|
return PlansVMs.select().where(PlansVMs.status == status)
|
||||||
|
return PlansVMs.select()
|
|
@ -10,9 +10,8 @@ class ControllerManageTasks:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def items_get(self, limit=100):
|
def get(self, limit=100):
|
||||||
models.Tasks.select().limit(limit)
|
return models.Tasks.select().limit(limit)
|
||||||
return None
|
|
||||||
|
|
||||||
def get_by_server(self, server_id):
|
def get_by_server(self, server_id):
|
||||||
task = models.Tasks.select(models.Tasks.plain).\
|
task = models.Tasks.select(models.Tasks.plain).\
|
||||||
|
|
29
SWSCloudCore/controllers/vms/__init__.py
Normal file
29
SWSCloudCore/controllers/vms/__init__.py
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
from SWSCloudCore.models import Vms
|
||||||
|
|
||||||
|
|
||||||
|
class ControllerVMS(object):
|
||||||
|
def __init__(self, user_id):
|
||||||
|
self.user_id = user_id
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
return Vms.select().where(Vms.user == self.user_id)
|
||||||
|
|
||||||
|
def create(self, datacenter_id, server_id, vm_id,
|
||||||
|
hostname, ipv4, ipv6, plan, platform,
|
||||||
|
os_name, os_suite, status):
|
||||||
|
Vms.create(
|
||||||
|
id=vm_id,
|
||||||
|
datacenter=datacenter_id,
|
||||||
|
server=server_id,
|
||||||
|
user=self.user_id,
|
||||||
|
hostname=hostname,
|
||||||
|
ipv4=ipv4,
|
||||||
|
ipv6=ipv6,
|
||||||
|
plan=plan,
|
||||||
|
platform=platform,
|
||||||
|
os_name=os_name,
|
||||||
|
os_suite=os_suite,
|
||||||
|
status=status
|
||||||
|
)
|
||||||
|
return True
|
|
@ -64,6 +64,27 @@ class Ips(PgSQLModel):
|
||||||
status = IntegerField()
|
status = IntegerField()
|
||||||
|
|
||||||
|
|
||||||
|
class Plans(PgSQLModel):
|
||||||
|
id = UUIDField(primary_key=True, unique=True)
|
||||||
|
name = CharField(unique=True, null=False)
|
||||||
|
status = CharField(null=False, default='active')
|
||||||
|
storage = IntegerField(null=False)
|
||||||
|
swap = IntegerField(null=False)
|
||||||
|
memory = IntegerField(null=False)
|
||||||
|
cores = IntegerField(null=False)
|
||||||
|
|
||||||
|
|
||||||
|
class PlansVMs(PgSQLModel):
|
||||||
|
id = UUIDField(primary_key=True, unique=True)
|
||||||
|
name = CharField(unique=True, null=False)
|
||||||
|
status = CharField(null=False, default='active')
|
||||||
|
price = FloatField(null=False)
|
||||||
|
storage = IntegerField(null=False)
|
||||||
|
swap = IntegerField(null=False)
|
||||||
|
memory = IntegerField(null=False)
|
||||||
|
cores = IntegerField(null=False)
|
||||||
|
|
||||||
|
|
||||||
class Users(PgSQLModel):
|
class Users(PgSQLModel):
|
||||||
id = UUIDField(primary_key=True, unique=True)
|
id = UUIDField(primary_key=True, unique=True)
|
||||||
email = CharField(unique=True, null=False)
|
email = CharField(unique=True, null=False)
|
||||||
|
@ -164,6 +185,23 @@ class ContainersStatisticsState(PgSQLModel):
|
||||||
net_total = BigIntegerField(default=0, null=False)
|
net_total = BigIntegerField(default=0, null=False)
|
||||||
|
|
||||||
|
|
||||||
|
class Vms(PgSQLModel):
|
||||||
|
id = UUIDField(primary_key=True, unique=True)
|
||||||
|
datacenter = ForeignKeyField(DataCenters)
|
||||||
|
server = ForeignKeyField(Servers)
|
||||||
|
user = ForeignKeyField(Users)
|
||||||
|
plan = ForeignKeyField(PlansVMs)
|
||||||
|
# 386, x86_64
|
||||||
|
hostname = CharField()
|
||||||
|
platform = CharField()
|
||||||
|
os_name = CharField()
|
||||||
|
os_suite = CharField()
|
||||||
|
ipv4 = CharField()
|
||||||
|
ipv6 = CharField()
|
||||||
|
# 0: inactive, 1: active, 2: ..., 3: ..., 4: ..., 5: ...
|
||||||
|
status = IntegerField()
|
||||||
|
|
||||||
|
|
||||||
class Tasks(PgSQLModel):
|
class Tasks(PgSQLModel):
|
||||||
id = UUIDField(primary_key=True, unique=True)
|
id = UUIDField(primary_key=True, unique=True)
|
||||||
datacenter = ForeignKeyField(DataCenters)
|
datacenter = ForeignKeyField(DataCenters)
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="{{ url_for('administrator.users') }}">Users</a></li>
|
<li><a href="{{ url_for('administrator.users') }}">Users</a></li>
|
||||||
<li><a href="{{ url_for('administrator.payments') }}">Payments</a></li>
|
<li><a href="{{ url_for('administrator.payments') }}">Payments</a></li>
|
||||||
|
<li><a href="{{ url_for('administrator.plans_index') }}">Plans</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<li>Services
|
<li>Services
|
||||||
<ul>
|
<ul>
|
||||||
|
|
|
@ -1,32 +1,32 @@
|
||||||
{% extends 'administrator/_layout.auth.html' %}
|
{% extends 'administrator/_layout.auth.html' %}
|
||||||
|
|
||||||
{% block title %}IPs{% endblock %}
|
{% set title="Infrastructure" %}
|
||||||
|
|
||||||
{% block subtitle %}New IP{% endblock %}
|
{% set subtitle="New IP" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form method="post" action="{{ url_for('administrator.ips_create') }}">
|
<form method="post" action="{{ url_for('administrator.ips_create') }}">
|
||||||
<table class="table table-bordered">
|
<table class="table table-bordered">
|
||||||
<thead>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Data center</th>
|
<th>Data center</th>
|
||||||
<th>
|
<th>
|
||||||
<select name="datacenter">
|
<select name="datacenter">
|
||||||
{% for item in datacenters['items'] %}
|
{% for item in datacenters['items'] %}
|
||||||
<option name="{{ item.id }}">{{ item.name }}</option>
|
<option value="{{ item.id }}">{{ item.name }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Server</th>
|
<td>Server</td>
|
||||||
<th>
|
<td>
|
||||||
<select name="server">
|
<select name="server">
|
||||||
{% for item in servers['items'] %}
|
{% for item in servers['items'] %}
|
||||||
<option value="{{ item.id }}">{{ item.hostname }}</option>
|
<option value="{{ item.id }}">{{ item.hostname }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</th>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>IPv4</th>
|
<th>IPv4</th>
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
<input type="reset" />
|
<input type="reset" />
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
{% extends 'administrator/_layout.auth.html' %}
|
{% extends 'administrator/_layout.auth.html' %}
|
||||||
|
|
||||||
{% block title %}IPs{% endblock %}
|
{% set title="Infrastructure" %}
|
||||||
|
|
||||||
{% block subtitle %}Edit IP{% endblock %}
|
{% set subtitle="Edit IP" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form method="post" action="{{ url_for('administrator.ips_edit', ip_id=ip.id) }}">
|
<form method="post" action="{{ url_for('administrator.ips_edit', ip_id=ip.id) }}">
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
{% extends 'administrator/_layout.auth.html' %}
|
{% extends 'administrator/_layout.auth.html' %}
|
||||||
|
|
||||||
{% block title %}IPs{% endblock %}
|
{% set title="Infrastructure" %}
|
||||||
|
|
||||||
{% block subtitle %}IPs list <label><a href="{{ url_for('administrator.ips_create') }}">New IP</a></label>{% endblock %}
|
{% set subtitle="IPs list" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
Total: {{ ips['total'] }}
|
<p>
|
||||||
<table class="table table-bordered">
|
Total: {{ ips['total'] }}
|
||||||
|
<a href="{{ url_for('administrator.ips_create') }}">New IP</a>
|
||||||
|
</p>
|
||||||
|
<table class="table table-bordered" width="100%">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Id</th>
|
<th>Id</th>
|
||||||
|
|
43
SWSCloudCore/templates/administrator/plans/create.html
Normal file
43
SWSCloudCore/templates/administrator/plans/create.html
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
{% extends 'administrator/_layout.auth.html' %}
|
||||||
|
|
||||||
|
{% set title="Billing" %}
|
||||||
|
{% set subtitle="New Plan" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form action="{{ url_for('administrator.plans_create') }}" method="POST">
|
||||||
|
<table class="table table-bordered" width="100%">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Name</td>
|
||||||
|
<td><input type="text" name="name" value="" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Status</td>
|
||||||
|
<td>
|
||||||
|
<select name="status">
|
||||||
|
<option>inactive</option>
|
||||||
|
<option>active</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Storage (Mb)</td>
|
||||||
|
<td><input type="text" name="storage" value="" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>SWAP (Mb)</td>
|
||||||
|
<td><input type="text" name="swap" value="" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Memory (Mb)</td>
|
||||||
|
<td><input type="text" name="memory" value="" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Cores (int)</td>
|
||||||
|
<td><input type="text" name="cores" value="" /></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<input type="submit" value="Create"/>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
42
SWSCloudCore/templates/administrator/plans/index.html
Normal file
42
SWSCloudCore/templates/administrator/plans/index.html
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
{% extends 'administrator/_layout.auth.html' %}
|
||||||
|
|
||||||
|
{% set title="Billing" %}
|
||||||
|
{% set subtitle="Plans" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<p>Total: {{ plans|length }} <a href="{{ url_for('administrator.plans_create') }}">Create one</a></p>
|
||||||
|
<table class="table table-bordered" width="100%">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Price</th>
|
||||||
|
<th>Cores</th>
|
||||||
|
<th>Storage</th>
|
||||||
|
<th>Swap</th>
|
||||||
|
<th>Memory</th>
|
||||||
|
<th> </th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% if plans|length == 0 %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="7">No plans.</td>
|
||||||
|
</tr>
|
||||||
|
{% else %}
|
||||||
|
{% for plan in plans %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ plan.id }}</td>
|
||||||
|
<td>{{ plan.name }}</td>
|
||||||
|
<td>{{ plan.price }}</td>
|
||||||
|
<td>{{ plan.cores }}</td>
|
||||||
|
<td>{{ plan.storage }}</td>
|
||||||
|
<td>{{ plan.swap }}</td>
|
||||||
|
<td>{{ plan.memory }}</td>
|
||||||
|
<td><a href="">Edit</a></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endblock %}
|
|
@ -1,8 +1,8 @@
|
||||||
{% extends 'administrator/_layout.auth.html' %}
|
{% extends 'administrator/_layout.auth.html' %}
|
||||||
|
|
||||||
{% block title %}Servers{% endblock %}
|
{% set title="Servers" %}
|
||||||
|
|
||||||
{% block subtitle %}Edit server{% endblock %}
|
{% set subtitle="Edit server" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<table class="table table-bordered">
|
<table class="table table-bordered">
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="left">
|
<ul class="left">
|
||||||
<li><a href="{{ url_for('containers.index') }}">Контейнеры</a></li>
|
<li><a href="{{ url_for('containers.index') }}">Контейнеры</a></li>
|
||||||
|
<li><a href="{{ url_for('vms.index') }}">Виртуальные машины</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
{% else %}
|
{% else %}
|
||||||
<ul class="right">
|
<ul class="right">
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="large-12 columns">
|
<div class="large-12 columns">
|
||||||
<h3>Список <a href="{{ url_for('containers.create') }}">+</a></h3>
|
<h3>Список контейнеров <a href="{{ url_for('containers.create') }}">+</a></h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
{% extends "default/_layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}Новый виртуальный сервер{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="large-12 columns">
|
||||||
|
<h3>Новый виртуальный сервер</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="large-12 columns">
|
||||||
|
{% if datacenters['total'] == 0 %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="small-12 columns">
|
||||||
|
Нет возможности создать виртуальный сервер.
|
||||||
|
Обратитесь в <a href="mailto:support@gocloud.ru">поддержку</a>.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="row">
|
||||||
|
<form action="{{ url_for('vms.create') }}" method="post" id="vmcreateform">
|
||||||
|
<div class="small-12 columns">
|
||||||
|
<label for="datacenter">
|
||||||
|
Датацентр
|
||||||
|
<select name="datacenter" class="form" id="datacenter">
|
||||||
|
{% for datacenter in datacenters['items'] %}
|
||||||
|
<option value="{{ datacenter.id }}">{{ datacenter.name }}: {{ datacenter.country }}, {{ datacenter.city }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="small-12 columns">
|
||||||
|
<label for="plan">
|
||||||
|
Датацентр
|
||||||
|
<select name="plan" class="form" id="plan">
|
||||||
|
{% for plan in plans %}
|
||||||
|
<option value="{{ plan.id }}">{{ plan.name }}: {{ plan.price }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="small-12 columns">
|
||||||
|
<input type="submit" value="Создать" class="button success" id="submitform" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -1 +1,66 @@
|
||||||
<!-- list virtual machines -->
|
{% extends "default/_layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}Виртуальные машины{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="large-12 columns">
|
||||||
|
<h3>Список виртуальных машин <a href="{{ url_for('vms.create') }}">+</a></h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="large-12 columns">
|
||||||
|
<table id="zones" width="100%">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th width="45%">ID</th>
|
||||||
|
<th>IP</th>
|
||||||
|
<th>Диск</th>
|
||||||
|
<th>Память</th>
|
||||||
|
<th>Ядра</th>
|
||||||
|
<th>Статус</th>
|
||||||
|
<th width="10%"> </th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% if vms|length == 0 %}
|
||||||
|
<tr>
|
||||||
|
<td>Нет ни одной виртуальной машины. <a href="{{ url_for('vms.create') }}">Добавить</a>.</td>
|
||||||
|
</tr>
|
||||||
|
{% else %}
|
||||||
|
{% for vm in vms %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ vm.id }}</td>
|
||||||
|
<td>
|
||||||
|
{% if vm['ipv4'] %}IPv4: {{ vm['ipv4'] }}{% endif %}
|
||||||
|
{% if vm['ipv6'] %}IPv6: {{ vm['ipv6'] }}{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>{{ vm.plan.storage }}</td>
|
||||||
|
<td>{{ vm.plan.memory }}</td>
|
||||||
|
<td>{{ vm.plan.cores }}</td>
|
||||||
|
<td>
|
||||||
|
{% 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 %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="{# { url_for('vm.settings', vm_id=vm.id) } #}">Настройки</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -22,12 +22,14 @@ from SWSCloudCore.controllers.servers.manage import ControllerManageServer
|
||||||
from SWSCloudCore.controllers.users.manage import ControllerManageUsers
|
from SWSCloudCore.controllers.users.manage import ControllerManageUsers
|
||||||
from SWSCloudCore.controllers.users.manage import ControllerManageUsersBalance
|
from SWSCloudCore.controllers.users.manage import ControllerManageUsersBalance
|
||||||
from SWSCloudCore.controllers.users.manage import ControllerManageUsersDetails
|
from SWSCloudCore.controllers.users.manage import ControllerManageUsersDetails
|
||||||
|
from SWSCloudCore.controllers.tasks.manage import ControllerManageTasks
|
||||||
|
from SWSCloudCore.controllers.plans import ControllerPlans
|
||||||
from SWSCloudCore import models
|
from SWSCloudCore import models
|
||||||
|
|
||||||
viewAdministrator = Blueprint('administrator', __name__, url_prefix='/administrator')
|
viewAdministrator = Blueprint('administrator', __name__, url_prefix='/administrator')
|
||||||
|
|
||||||
|
|
||||||
@viewAdministrator.route('/login', methods=['GET', 'POST'])
|
@viewAdministrator.route('/login.html', methods=['GET', 'POST'])
|
||||||
def login():
|
def login():
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
admin_email = request.form['email'].encode('utf-8')
|
admin_email = request.form['email'].encode('utf-8')
|
||||||
|
@ -56,7 +58,7 @@ def login():
|
||||||
return render_template('administrator/login.html')
|
return render_template('administrator/login.html')
|
||||||
|
|
||||||
|
|
||||||
@viewAdministrator.route('/logout')
|
@viewAdministrator.route('/logout.html')
|
||||||
def logout():
|
def logout():
|
||||||
session.pop('admin_id', None)
|
session.pop('admin_id', None)
|
||||||
session.pop('admin_email', None)
|
session.pop('admin_email', None)
|
||||||
|
@ -64,7 +66,7 @@ def logout():
|
||||||
return redirect(url_for('administrator.login'))
|
return redirect(url_for('administrator.login'))
|
||||||
|
|
||||||
|
|
||||||
@viewAdministrator.route('/dashboard')
|
@viewAdministrator.route('/dashboard.html')
|
||||||
def dashboard():
|
def dashboard():
|
||||||
# check session
|
# check session
|
||||||
if not ControllerAdministrators().check_session():
|
if not ControllerAdministrators().check_session():
|
||||||
|
@ -493,9 +495,35 @@ def json_datacenter_list():
|
||||||
|
|
||||||
@viewAdministrator.route('/tasks/', methods=['GET'])
|
@viewAdministrator.route('/tasks/', methods=['GET'])
|
||||||
def tasks_index():
|
def tasks_index():
|
||||||
from SWSCloudCore.controllers.tasks.manage import ControllerManageTasks
|
|
||||||
return render_template(
|
return render_template(
|
||||||
'administrator/tasks/index.html',
|
'administrator/tasks/index.html',
|
||||||
# tasks=ControllerManageTasks().get_by_server().get()
|
# tasks=ControllerManageTasks().get_by_server().get()
|
||||||
tasks=ControllerManageTasks().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')
|
||||||
|
|
315
SWSCloudCore/views/vms/__init__.py
Normal file
315
SWSCloudCore/views/vms/__init__.py
Normal file
|
@ -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 = '<br/>\n'.join(message_parts)
|
||||||
|
# subject = u'GoCloud.ru: Новый контейнер'
|
||||||
|
# lead = u"""Поздравляем с новым контейнером."""
|
||||||
|
# callout = u"""
|
||||||
|
# Для входа в личный кабинет воспользуйтесь
|
||||||
|
# <a href="https://gocloud.ru/account/login">страницей авторизации</a>.
|
||||||
|
# """
|
||||||
|
#
|
||||||
|
# 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/<uuid:container_id>.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/<uuid:container_id>', 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/<uuid:container_id>.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
|
||||||
|
)
|
|
@ -19,6 +19,8 @@ tables = [
|
||||||
models.Containers,
|
models.Containers,
|
||||||
models.ContainersStatistics,
|
models.ContainersStatistics,
|
||||||
models.ContainersStatisticsState,
|
models.ContainersStatisticsState,
|
||||||
|
models.PlansVMs,
|
||||||
|
models.Vms,
|
||||||
models.Tasks,
|
models.Tasks,
|
||||||
models.Settings,
|
models.Settings,
|
||||||
models.Admins,
|
models.Admins,
|
||||||
|
|
|
@ -4,4 +4,4 @@
|
||||||
from SWSCloudCore import app
|
from SWSCloudCore import app
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run()
|
app.run(host='0.0.0.0', port=5000, debug=True)
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -4,7 +4,7 @@ from setuptools import setup
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='SWSCloudCore',
|
name='SWSCloudCore',
|
||||||
version='2.1.7',
|
version='2.2.7',
|
||||||
author='Vyacheslav Anzhiganov',
|
author='Vyacheslav Anzhiganov',
|
||||||
author_email='hello@anzhiganov.com',
|
author_email='hello@anzhiganov.com',
|
||||||
packages=[
|
packages=[
|
||||||
|
|
Loading…
Add table
Reference in a new issue