This commit is contained in:
Vyacheslav Anzhiganov 2016-04-20 03:39:13 +03:00
parent ad1aca5838
commit 4813152679
11 changed files with 232 additions and 72 deletions

View file

@ -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"'`

View file

@ -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

View file

@ -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(

View file

@ -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,

View file

@ -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()

View file

@ -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 %}

View file

@ -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

View file

@ -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)

View file

@ -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']
)

View file

@ -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')

View file

@ -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)
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'
)