193 lines
5.9 KiB
Python
193 lines
5.9 KiB
Python
# coding: utf-8
|
||
|
||
import json
|
||
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('ServerAPI', __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():
|
||
"""
|
||
Список
|
||
"""
|
||
server_api = ControllerTasksServer(g.server_id)
|
||
result = dict(tasks=list())
|
||
|
||
for task in server_api.get():
|
||
result['results'].append(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(result)
|
||
|
||
|
||
@viewServerAPI.route('/task', methods=['GET'])
|
||
@api_auth.login_required
|
||
def task_item():
|
||
"""
|
||
Самая первая задача в очереди
|
||
"""
|
||
sapi = ControllerTasksServer(g.server_id)
|
||
|
||
# Если задач нет, то надо вернуть ответ с кодом 204 (no content)
|
||
if sapi.count() == 0:
|
||
return '', 204
|
||
|
||
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.get('status'))
|
||
server_api.update(task_id, status)
|
||
return jsonify(status=0)
|
||
|
||
|
||
# CONTAINERS
|
||
@viewServerAPI.route('/containers/stats/<uuid:container_id>', methods=['POST'])
|
||
@api_auth.login_required
|
||
def report_container_status(container_id):
|
||
"""
|
||
{
|
||
"cpu_use": 644394623336,
|
||
"memory_use": 614473728,
|
||
"link": "vethB2RLMU"
|
||
"tx_bytes": 48337383,
|
||
"rx_bytes": 1049439046,
|
||
"total_bytes": 1097776429
|
||
}
|
||
"""
|
||
|
||
statistics = json.loads(request.form['status'])
|
||
|
||
if 'cpu_use' not in statistics:
|
||
return jsonify({})
|
||
if 'memory_use' not in statistics:
|
||
return jsonify({})
|
||
if 'tx_bytes' not in statistics:
|
||
return jsonify({})
|
||
if 'rx_bytes' not in statistics:
|
||
return jsonify({})
|
||
if 'total_bytes' not in statistics:
|
||
return jsonify({})
|
||
|
||
# create or update state
|
||
if ControllerServerStatistics().state_exists(container_id):
|
||
ControllerServerStatistics().state_update(container_id, statistics)
|
||
else:
|
||
ControllerServerStatistics().state_create(container_id, statistics)
|
||
|
||
if ControllerContainersServer().exists(container_id):
|
||
ControllerServerStatistics().write(
|
||
container_id,
|
||
statistics['cpu_use'],
|
||
statistics['memory_use'],
|
||
int(statistics['size']),
|
||
int(statistics['tx_bytes']),
|
||
int(statistics['rx_bytes']),
|
||
int(statistics['total_bytes'])
|
||
)
|
||
return jsonify(status='success')
|
||
|
||
|
||
@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'
|
||
)
|