# 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/', 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/', 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/', 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' )