up
This commit is contained in:
parent
ad1aca5838
commit
4813152679
11 changed files with 232 additions and 72 deletions
31
README.md
31
README.md
|
@ -1,7 +1,38 @@
|
|||
# GoCloud
|
||||
|
||||
_Containers_
|
||||
|
||||
Statuses:
|
||||
|
||||
- 0: Неактивен
|
||||
- 1: Активен
|
||||
- 2: Процесс активации
|
||||
- 3: Процесс деактивации
|
||||
- 4: Создание...
|
||||
- 5: Удаление...
|
||||
|
||||
_Tasks_
|
||||
|
||||
Statuses:
|
||||
|
||||
- 0: new
|
||||
- 1: working
|
||||
- 2: completed
|
||||
|
||||
## Develop
|
||||
|
||||
### Public to local PyPI server
|
||||
|
||||
`python setup.py sdist upload -r local`
|
||||
|
||||
## Test
|
||||
|
||||
### User API
|
||||
|
||||
### Server API
|
||||
|
||||
_Get containers status_
|
||||
|
||||
`curl -X GET http://127.0.0.1:5000/server_api/containers/status/ -u f411b7d6-bf93-4fcd-91ee-03e5343d0187:b3c9a8b0-95ca-11e5-bec1-28d244e159e9`
|
||||
|
||||
`curl -X POST http://127.0.0.1:5000/server_api/containers/status/663b31b4-22b1-4846-bfaf-27d6389beef4 -u f411b7d6-bf93-4fcd-91ee-03e5343d0187:b3c9a8b0-95ca-11e5-bec1-28d244e159e9 -d 'status=0&message="test"'`
|
|
@ -5,6 +5,9 @@ from SWSCloudCore import models
|
|||
|
||||
class ControllerContainersServer:
|
||||
def status_set(self, container_id, status):
|
||||
return self.set_container_status(container_id, status)
|
||||
|
||||
def set_container_status(self, container_id, status):
|
||||
ns = models.Containers.update(status=status).where(
|
||||
models.Containers.id == container_id
|
||||
)
|
||||
|
@ -12,6 +15,40 @@ class ControllerContainersServer:
|
|||
return True
|
||||
|
||||
def exists(self, container_id):
|
||||
if models.Containers.select().where(models.Containers.id == container_id).count() == 0:
|
||||
if models.Containers.select().where(
|
||||
models.Containers.id == container_id
|
||||
).count() == 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_container(self, container_id):
|
||||
x = models.Containers.select().where(
|
||||
models.Containers.id == container_id
|
||||
).get()
|
||||
|
||||
return {
|
||||
'id': str(x.id),
|
||||
'datacenter_id': str(x.datacenter.id),
|
||||
'server_id': str(x.server.id),
|
||||
'ipv4': x.ipv4,
|
||||
'ipv6': x.ipv6,
|
||||
'status': x.status
|
||||
}
|
||||
|
||||
def get_containers_by_server(self, server_id):
|
||||
x = models.Containers.select().where(
|
||||
models.Containers.server == server_id
|
||||
).execute()
|
||||
containers = list()
|
||||
for i in x:
|
||||
containers.append({
|
||||
'id': str(i.id),
|
||||
'datacenter_id': str(i.datacenter.id),
|
||||
'server_id': str(i.server.id),
|
||||
'ipv4': i.ipv4,
|
||||
'ipv6': i.ipv6,
|
||||
'status': i.status
|
||||
})
|
||||
return containers
|
||||
|
||||
|
||||
|
|
|
@ -3,6 +3,20 @@ import datetime
|
|||
from SWSCloudCore import models
|
||||
|
||||
|
||||
class ControllerServerServers:
|
||||
def get_secret(self, server_id):
|
||||
return models.Servers.select(models.Servers.secret).where(models.Servers.id == server_id).get().secret
|
||||
|
||||
def exists(self, server_id):
|
||||
try:
|
||||
if models.Servers.select().where(models.Servers.id == server_id).count() == 0:
|
||||
return False
|
||||
except Exception as e:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
class ControllerServerStatistics:
|
||||
def write(self, container_id, cpu, memory, size, net_tx, net_rx, net_total):
|
||||
models.ContainersStatistics.create(
|
||||
|
|
|
@ -1,31 +1,29 @@
|
|||
# coding: utf-8
|
||||
|
||||
import json
|
||||
|
||||
from SWSCloudCore import models
|
||||
from SWSCloudCore.controllers.containers.server import ControllerContainersServer
|
||||
|
||||
|
||||
# from peewee import fn
|
||||
|
||||
|
||||
class ControllerTasksServer:
|
||||
def __init__(self, server_id, secret):
|
||||
def __init__(self, server_id):
|
||||
self.server_id = server_id
|
||||
self.secret = secret
|
||||
|
||||
def auth(self):
|
||||
if models.Servers.select().where(
|
||||
models.Servers.id == self.server_id,
|
||||
models.Servers.secret == self.secret
|
||||
).count() == 0:
|
||||
return False
|
||||
return True
|
||||
def queue_item_oldest_get(self, status=0):
|
||||
"""
|
||||
Вытащить самую старую задачу из всех активных
|
||||
:param status:
|
||||
:return:
|
||||
"""
|
||||
return models.Tasks.select().where(
|
||||
models.Tasks.server == self.server_id,
|
||||
models.Tasks.status == status
|
||||
).order_by(models.Tasks.created.asc()).get()
|
||||
|
||||
def count(self):
|
||||
return models.Tasks.select(
|
||||
models.Servers.id == self.server_id,
|
||||
models.Servers.secret == self.secret
|
||||
def count(self, status=0):
|
||||
return models.Tasks.select().where(
|
||||
models.Tasks.server == self.server_id,
|
||||
models.Tasks.status == status
|
||||
).count()
|
||||
|
||||
def get(self, status=0):
|
||||
|
@ -106,7 +104,7 @@ class ControllerTasksServer:
|
|||
return True
|
||||
|
||||
def get_item(self, task_id):
|
||||
get_task = models.Tasks.select().where(models.Tasks.id == task_id)[0]
|
||||
get_task = models.Tasks.select().where(models.Tasks.id == task_id).get()
|
||||
return {
|
||||
'id': get_task.id,
|
||||
'datacenter': get_task.datacenter.id,
|
||||
|
|
|
@ -171,9 +171,7 @@ class Tasks(PgSQLModel):
|
|||
user = ForeignKeyField(Users)
|
||||
created = DateTimeField(default=datetime.datetime.now)
|
||||
task = CharField(null=False)
|
||||
# 0 - new
|
||||
# 1 - working
|
||||
# 2 - completed
|
||||
# 0 - new, 1 - working, 2 - completed
|
||||
status = IntegerField(null=False, default=0)
|
||||
plain = TextField()
|
||||
|
||||
|
|
|
@ -26,6 +26,10 @@
|
|||
<th>Hostname</th>
|
||||
<td><input type="text" name="hostname" value="{{ server.hostname }}" class="form-control" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Secret</th>
|
||||
<td nowrap><input type="text" name="secret" id="secret" value="{{ server.secret }}" class="form-control" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Status</th>
|
||||
<td>
|
||||
|
@ -37,5 +41,5 @@
|
|||
</tr>
|
||||
</table>
|
||||
<input type="submit" value="Save changes" class="btn btn-success" />
|
||||
<a href="{{ url_for('administrator.servers') }}">Cancel</a>
|
||||
<a href="{{ url_for('administrator.servers_index') }}">Cancel</a>
|
||||
{% endblock %}
|
|
@ -6,7 +6,6 @@ from flask import request, flash
|
|||
from sshpubkeys import SSHKey
|
||||
from SWSCloudCore.controllers.billing import ControllerBilling
|
||||
from SWSCloudCore.controllers.common import ControllerMessagesEmail
|
||||
from SWSCloudCore.controllers.common import special_match
|
||||
from SWSCloudCore.controllers.users import ControllerAPI
|
||||
from SWSCloudCore.controllers.users import ControllerSSHKey
|
||||
from SWSCloudCore.controllers.users import ControllerUsers
|
||||
|
|
|
@ -371,7 +371,7 @@ def servers_create():
|
|||
)
|
||||
|
||||
|
||||
@viewAdministrator.route('/servers/edit/<uuid:server_id>', methods=['GET', 'POST'])
|
||||
@viewAdministrator.route('/servers/edit/<uuid:server_id>.html', methods=['GET', 'POST'])
|
||||
def servers_edit(server_id):
|
||||
# check session
|
||||
if not ControllerAdministrators().check_session():
|
||||
|
@ -383,7 +383,7 @@ def servers_edit(server_id):
|
|||
if models.Servers.select().where(models.Servers.id == server_id).count() == 0:
|
||||
return redirect(url_for('administrator.servers'))
|
||||
|
||||
server_details = models.Servers.select().where(models.Servers.id == server_id).limit(1)[0]
|
||||
server_details = models.Servers.select().where(models.Servers.id == server_id).get()
|
||||
|
||||
return render_template('administrator/servers/edit.html', server=server_details)
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# coding: utf-8
|
||||
|
||||
|
||||
from flask import Blueprint, jsonify, request
|
||||
from SWSCloudCore.controllers.containers import ControllerContainers
|
||||
from SWSCloudCore.controllers.datacenters import ControllerDataCenters
|
||||
|
@ -24,7 +23,6 @@ def auth():
|
|||
"""
|
||||
email = request.form['email']
|
||||
secret = request.form['secret']
|
||||
# expire = request.form['expire']
|
||||
|
||||
if not ControllerAPI().auth(email, secret):
|
||||
return jsonify(status=1)
|
||||
|
@ -44,14 +42,13 @@ def datacenter_list():
|
|||
secret = request.form['secret']
|
||||
#
|
||||
if not ControllerAPI().auth(email, secret):
|
||||
return jsonify(status=1)
|
||||
return jsonify(status=403), 403
|
||||
#
|
||||
user_id = ControllerUsers().get_id_by_email(email)
|
||||
# get containers list
|
||||
datacenters = ControllerDataCenters().get()
|
||||
#
|
||||
return jsonify(
|
||||
status=0,
|
||||
total=datacenters['total'],
|
||||
items=datacenters['items']
|
||||
)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import uuid
|
||||
from flask import Blueprint, g, redirect, render_template, request, session
|
||||
from flask import url_for
|
||||
from flask import url_for, flash
|
||||
|
||||
from SWSCloudCore.controllers.billing import ControllerBilling
|
||||
from SWSCloudCore.controllers.common import ControllerCommon
|
||||
|
@ -15,7 +15,6 @@ 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 import models
|
||||
|
||||
viewContainers = Blueprint('containers', __name__, url_prefix='/containers')
|
||||
|
||||
|
|
|
@ -1,28 +1,48 @@
|
|||
# coding: utf-8
|
||||
|
||||
import json
|
||||
from flask import Blueprint, jsonify, request
|
||||
from flask import Blueprint, jsonify, request, g
|
||||
from flask_httpauth import HTTPBasicAuth
|
||||
from SWSCloudCore.controllers.servers.server import ControllerServerStatistics
|
||||
from SWSCloudCore.controllers.servers.server import ControllerServerServers
|
||||
from SWSCloudCore.controllers.tasks.server import ControllerTasksServer
|
||||
from SWSCloudCore.controllers.containers.server import ControllerContainersServer
|
||||
|
||||
api_auth = HTTPBasicAuth()
|
||||
viewServerAPI = Blueprint('server_api', __name__, url_prefix='/server_api')
|
||||
|
||||
|
||||
@api_auth.get_password
|
||||
def get_pw(server_id):
|
||||
if ControllerServerServers().exists(server_id):
|
||||
g.server_id = server_id
|
||||
return ControllerServerServers().get_secret(g.server_id)
|
||||
return None
|
||||
|
||||
|
||||
@api_auth.error_handler
|
||||
def auth_error():
|
||||
return jsonify(status='error', description='Unauthorized'), 403
|
||||
|
||||
|
||||
@viewServerAPI.route('/ping')
|
||||
@api_auth.login_required
|
||||
def ping():
|
||||
"""
|
||||
Тест. Проверка соединения и авторизации
|
||||
"""
|
||||
return jsonify(ping='pong', server_id=g.server_id), 200
|
||||
|
||||
|
||||
# TASKS
|
||||
@viewServerAPI.route('/tasks', methods=['GET'])
|
||||
@api_auth.login_required
|
||||
def tasks_list():
|
||||
node_id = request.args.get('node_id')
|
||||
node_secret = request.args.get('node_secret')
|
||||
server_api = ControllerTasksServer(node_id, node_secret)
|
||||
|
||||
# auth request
|
||||
if not server_api.auth():
|
||||
# status: 403 - access denied
|
||||
return jsonify({'status': 403})
|
||||
|
||||
result = dict()
|
||||
result['status'] = 0
|
||||
result['results'] = []
|
||||
"""
|
||||
Список
|
||||
"""
|
||||
server_api = ControllerTasksServer(g.server_id)
|
||||
result = dict(tasks=list())
|
||||
|
||||
for task in server_api.get():
|
||||
result['results'].append({
|
||||
|
@ -38,39 +58,56 @@ def tasks_list():
|
|||
return jsonify(result)
|
||||
|
||||
|
||||
@viewServerAPI.route('/task_status_update', methods=['GET'])
|
||||
def task_status_update():
|
||||
node_id = request.args.get('node_id')
|
||||
node_secret = request.args.get('node_secret')
|
||||
server_api = ControllerTasksServer(node_id, node_secret)
|
||||
@viewServerAPI.route('/task', methods=['GET'])
|
||||
@api_auth.login_required
|
||||
def task_item():
|
||||
"""
|
||||
Самая первая задача в очереди
|
||||
"""
|
||||
sapi = ControllerTasksServer(g.server_id)
|
||||
|
||||
# auth request
|
||||
if not server_api.auth():
|
||||
# status: 403 - access denied
|
||||
return jsonify({'status': 403})
|
||||
# Если задач нет, то надо вернуть ответ с кодом 204 (no content)
|
||||
if sapi.count() == 0:
|
||||
return '', 204
|
||||
|
||||
task_id = request.args.get('task_id')
|
||||
status = int(request.args.get('status'))
|
||||
task = sapi.queue_item_oldest_get(status=0)
|
||||
|
||||
server_api.update(task_id, status)
|
||||
result = dict(
|
||||
id=task.id,
|
||||
datacenter=task.datacenter.id,
|
||||
server=task.server.id,
|
||||
user=task.user.id,
|
||||
task=task.task,
|
||||
created=task.created,
|
||||
status=task.status,
|
||||
plain=json.loads(task.plain),
|
||||
)
|
||||
return jsonify(
|
||||
task=result,
|
||||
status='success'
|
||||
)
|
||||
|
||||
|
||||
@viewServerAPI.route('/tasks/<task_id>', methods=['PUT'])
|
||||
@api_auth.login_required
|
||||
def task_update(task_id):
|
||||
"""
|
||||
Обновление статуса задачи
|
||||
"""
|
||||
server_api = ControllerTasksServer(g.server_id)
|
||||
|
||||
if 'status' in request.form:
|
||||
status = int(request.form['status'])
|
||||
server_api.update(task_id, status)
|
||||
return jsonify({'status': 0})
|
||||
|
||||
|
||||
@viewServerAPI.route('/report/container_status', methods=['POST'])
|
||||
def report_container_status():
|
||||
node_id = request.form['node_id']
|
||||
node_secret = request.form['node_secret']
|
||||
|
||||
# print request.form['node_id']
|
||||
# auth request
|
||||
if not ControllerTasksServer(node_id, node_secret).auth():
|
||||
# status: 403 - access denied
|
||||
return jsonify({'status': 403})
|
||||
|
||||
# CONTAINERS
|
||||
@viewServerAPI.route('/containers/stats/<uuid:container_id>', methods=['POST'])
|
||||
@api_auth.login_required
|
||||
def report_container_status(container_id):
|
||||
"""
|
||||
{
|
||||
"container_id": "16459f60-a1ee-11e5-9108-28d244e159e9",
|
||||
"cpu_use": 644394623336,
|
||||
"memory_use": 614473728,
|
||||
"link": "vethB2RLMU"
|
||||
|
@ -79,9 +116,8 @@ def report_container_status():
|
|||
"total_bytes": 1097776429
|
||||
}
|
||||
"""
|
||||
|
||||
statistics = json.loads(request.form['status'])
|
||||
# print statistics
|
||||
container_id = statistics['container_id']
|
||||
|
||||
if 'cpu_use' not in statistics:
|
||||
return jsonify({})
|
||||
|
@ -110,5 +146,52 @@ def report_container_status():
|
|||
int(statistics['rx_bytes']),
|
||||
int(statistics['total_bytes'])
|
||||
)
|
||||
return jsonify(status='success')
|
||||
|
||||
return jsonify({})
|
||||
|
||||
@viewServerAPI.route('/containers/status/', methods=['GET'])
|
||||
@api_auth.login_required
|
||||
def containers_status():
|
||||
"""
|
||||
Состояние всех контейнеров в биллинге, и привести контейнеры к указанному состоянию
|
||||
На случай, когда нода была перезагружена.
|
||||
"""
|
||||
# Get container list (with status) located on node
|
||||
return jsonify(
|
||||
status='success',
|
||||
containers=ControllerContainersServer().get_containers_by_server(g.server_id)
|
||||
)
|
||||
|
||||
|
||||
@viewServerAPI.route('/containers/status/<uuid:container_id>', methods=['GET', 'POST'])
|
||||
@api_auth.login_required
|
||||
def container_status_update(container_id):
|
||||
"""
|
||||
Если на ноде при работе с контейнером что-то поло не так,
|
||||
то нода отправляет сообщение об ошибке и изменяет статус контейнера.
|
||||
Отправленное сообщение может быть прочитано администратором или владельцем контейнера
|
||||
"""
|
||||
# Check exists container
|
||||
if not ControllerContainersServer().exists(container_id):
|
||||
return '', 404
|
||||
|
||||
# Get information about container
|
||||
if request.method == 'GET':
|
||||
return jsonify(
|
||||
status='success',
|
||||
container=ControllerContainersServer().get_container(container_id)
|
||||
)
|
||||
|
||||
# Set container status
|
||||
if 'status' in request.form:
|
||||
ControllerContainersServer().set_container_status(
|
||||
container_id,
|
||||
request.form['status']
|
||||
)
|
||||
# TODO: 0000001
|
||||
|
||||
return jsonify(status='success')
|
||||
return jsonify(
|
||||
status='error',
|
||||
message='must contain parameter: status'
|
||||
)
|
||||
|
|
Loading…
Add table
Reference in a new issue