66 API
This commit is contained in:
parent
966d0c77d6
commit
707ed651fb
3 changed files with 381 additions and 0 deletions
313
SWSCloudAPI/API/__init__.py
Normal file
313
SWSCloudAPI/API/__init__.py
Normal file
|
@ -0,0 +1,313 @@
|
|||
# coding: utf-8
|
||||
|
||||
from uuid import uuid4
|
||||
from flask import Blueprint, jsonify, request, g
|
||||
from flask_httpauth import HTTPBasicAuth
|
||||
from SWSCloudCore.controllers.datacenters import ControllerDataCenters
|
||||
from SWSCloudCore.controllers.ips import ControllerIps
|
||||
from SWSCloudCore.controllers.plans import ControllerPlans
|
||||
from SWSCloudCore.controllers.containers import ControllerContainers
|
||||
from SWSCloudCore.controllers.vms import ControllerVMS
|
||||
from SWSCloudCore.controllers.users import ControllerAPI
|
||||
from SWSCloudCore.controllers.users import ControllerUsers
|
||||
from SWSCloudCore.controllers.users import ControllerSSHKey
|
||||
from SWSCloudCore.controllers.billing import ControllerBilling
|
||||
from SWSCloudCore.controllers.common import ControllerCommon, ControllerMessagesEmail
|
||||
from SWSCloudCore.controllers.containers import ControllerContainersStatisticsState, ControllerContainersStatistics
|
||||
from SWSCloudCore.controllers.tasks import ControllerTasks
|
||||
|
||||
|
||||
api = Blueprint('api', __name__, url_prefix='/api/v1')
|
||||
auth = HTTPBasicAuth()
|
||||
|
||||
"""
|
||||
TODO: Реализовать Процесс авторизации в версии API 2.0
|
||||
- получаем емейл и секретный ключ
|
||||
- создаём временный токен
|
||||
- выдаём токен
|
||||
"""
|
||||
|
||||
|
||||
@auth.verify_password
|
||||
def verify_password(username, password):
|
||||
if not ControllerAPI().auth(username, password):
|
||||
return False
|
||||
g.user_id = ControllerUsers().get_id_by_email(username)
|
||||
return True
|
||||
|
||||
|
||||
@api.route('/')
|
||||
@auth.login_required
|
||||
def index():
|
||||
"""
|
||||
curl -X POST http://localhost:5000/api/v1/ -u <email>:<secret>
|
||||
:return:
|
||||
"""
|
||||
return jsonify(user_id=g.user_id)
|
||||
|
||||
|
||||
@api.route('/datacenters/')
|
||||
@auth.login_required
|
||||
def datacenters_index():
|
||||
"""
|
||||
get containers list
|
||||
curl -X http://localhost:5000/api/v1/datacenters/ -u <email>:<secret>
|
||||
:return:
|
||||
"""
|
||||
dc_list = ControllerDataCenters().get()
|
||||
return jsonify(total=dc_list.get('total'), items=dc_list.get('items'))
|
||||
|
||||
|
||||
@api.route('/pricing/vms/')
|
||||
@auth.login_required
|
||||
def pricing_vms():
|
||||
"""
|
||||
get pricing list
|
||||
curl -X http://localhost:5000/api/v1/pricing/vms/ -u <email>:<secret>
|
||||
:return:
|
||||
"""
|
||||
return jsonify(pricing=ControllerPlans().get_plans(status='active'))
|
||||
|
||||
|
||||
@api.route('/pricing/containers/')
|
||||
@auth.login_required
|
||||
def pricing_containers():
|
||||
"""
|
||||
get pricing list
|
||||
curl -X GET http://localhost:5000/api/v1/pricing/containers/ -u <email>:<secret>
|
||||
:return:
|
||||
"""
|
||||
return jsonify(pricing=100)
|
||||
|
||||
|
||||
@api.route('/containers/', methods=['GET'])
|
||||
@auth.login_required
|
||||
def containers_list():
|
||||
"""
|
||||
curl -X GET http://localhost:5000/api/v1/containers/ -u <email>:<secret>
|
||||
:return:
|
||||
"""
|
||||
# get containers list
|
||||
containers = ControllerContainers(g.user_id).get_items()
|
||||
#
|
||||
return jsonify(total=containers['total'], items=containers['items'])
|
||||
|
||||
|
||||
@api.route('/containers/', methods=['POST'])
|
||||
@auth.login_required
|
||||
def container_create():
|
||||
"""
|
||||
curl -X POST http://localhost:5000/api/v1/containers/ -u <email>:<secret> -d "datacenter_id=123"
|
||||
:return:
|
||||
"""
|
||||
# Check exists data center
|
||||
if not ControllerDataCenters().exists(request.form.get('datacenter')):
|
||||
return jsonify(message='datacenter not exists')
|
||||
# Check money
|
||||
if ControllerBilling().get(g.user_id) <= 0:
|
||||
return jsonify(message='no money')
|
||||
|
||||
# select server from selected region with available ip-addresses
|
||||
# select IP
|
||||
select_ip = ControllerIps().getfree(request.form.get('datacenter'))
|
||||
# mark ip as busy (taken)
|
||||
ControllerIps().setbusy(select_ip.id)
|
||||
# generate password for container user
|
||||
password = ControllerCommon().generate_password(size=14)
|
||||
|
||||
user_ssh = ControllerSSHKey(g.user_id)
|
||||
|
||||
new_container = dict(
|
||||
container_id=str(uuid4()),
|
||||
datacenter_id=str(select_ip.datacenter.id),
|
||||
server_id=str(select_ip.server.id),
|
||||
ipv4=select_ip.ipv4,
|
||||
ipv6=select_ip.ipv6,
|
||||
ipv4_gateway=select_ip.ipv4_gateway,
|
||||
ipv6_gateway=select_ip.ipv6_gateway,
|
||||
username='ubuntu',
|
||||
password=password,
|
||||
ssh_key='',
|
||||
)
|
||||
|
||||
# sshkey
|
||||
if user_ssh.check():
|
||||
new_container['ssh_key'] = user_ssh.get()
|
||||
|
||||
# create container record in database
|
||||
# status 4: creation
|
||||
status = 4
|
||||
container_create = ControllerContainers(g.user_id).create(
|
||||
new_container['container_id'],
|
||||
new_container['datacenter_id'],
|
||||
new_container['server_id'],
|
||||
new_container['ipv4'],
|
||||
new_container['ipv6'],
|
||||
status
|
||||
)
|
||||
# create default state data
|
||||
ControllerContainersStatisticsState().set(new_container['container_id'], dict())
|
||||
if container_create:
|
||||
# create task for create new container
|
||||
ControllerTasks(g.user_id).create(
|
||||
new_container['datacenter_id'],
|
||||
new_container['server_id'],
|
||||
'container_create',
|
||||
0,
|
||||
container_id=new_container['container_id'],
|
||||
ipv4=new_container['ipv4'],
|
||||
ipv6=new_container['ipv6'],
|
||||
ipv4_gateway=new_container['ipv4_gateway'],
|
||||
ipv6_gateway=new_container['ipv6_gateway'],
|
||||
username=new_container['username'],
|
||||
password=new_container['password'],
|
||||
ssh_key=new_container['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(g.user_id).get()
|
||||
|
||||
email = ControllerMessagesEmail()
|
||||
email.send(title=subject, to=user_data.email, lead=lead, message=message, callout=callout)
|
||||
|
||||
#
|
||||
return jsonify(message='ok')
|
||||
|
||||
|
||||
@api.route('/container/<uuid:container_id>', methods=['DELETE'])
|
||||
@auth.login_required
|
||||
def container_delete(container_id):
|
||||
"""
|
||||
curl -X DELETE http://localhost:5000/api/v1/container/<uuid:container_id> -u <email>:<secret> -d "container_id=<uuid:container_id>"
|
||||
:return:
|
||||
"""
|
||||
containers = ControllerContainers(g.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 jsonify(message='container_not_exists')
|
||||
|
||||
# get container details
|
||||
container_details = ControllerContainers(g.user_id).get_item(container_id)
|
||||
|
||||
# Обновляем статус "5" для правила
|
||||
containers.set_status(container_id, 5)
|
||||
# Создание задания
|
||||
ControllerTasks(g.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
|
||||
return jsonify(status=0, message='container has been deleted')
|
||||
|
||||
|
||||
@api.route('/container/<uuid:container_id>', methods=['GET'])
|
||||
@auth.login_required
|
||||
def container_info(container_id):
|
||||
"""
|
||||
curl -X GET http://localhost:5000/api/v1/container/<uuid:container_id> -u <email>:<secret>
|
||||
:return:
|
||||
"""
|
||||
# init
|
||||
containers = ControllerContainers(g.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 jsonify(message='container_not_found')
|
||||
# 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):
|
||||
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 jsonify(container=container_details, stats_memory=statistics)
|
||||
|
||||
|
||||
@api.route('/container/<uuid:container_id>', methods=['POST'])
|
||||
@auth.login_required
|
||||
def container_actions(container_id):
|
||||
"""
|
||||
curl -X POST http://localhost:5000/api/v1/container/<uuid:container_id> -u <email>:<secret> -d "status=inactive"
|
||||
curl -X POST http://localhost:5000/api/v1/container/<uuid:container_id> -u <email>:<secret> -d "action=active"
|
||||
:return:
|
||||
"""
|
||||
containers = ControllerContainers(g.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 jsonify(message='container_not_found')
|
||||
|
||||
# get container details
|
||||
container_details = containers.get_item(container_id)
|
||||
|
||||
if request.form.get('status') == "inactive":
|
||||
containers.set_status(container_id, 3)
|
||||
# Создание задания
|
||||
ControllerTasks(g.user_id).create(
|
||||
container_details.datacenter.id,
|
||||
container_details.server.id,
|
||||
'container_stop',
|
||||
0,
|
||||
container_id=container_id
|
||||
)
|
||||
elif request.form.get('status') == 'active':
|
||||
balance = ControllerBilling().get(g.user_id)
|
||||
|
||||
if balance <= 0:
|
||||
return jsonify(message='no money')
|
||||
|
||||
containers.set_status(container_id, 2)
|
||||
# Создание задания
|
||||
ControllerTasks(g.user_id).create(
|
||||
container_details.datacenter.id,
|
||||
container_details.server.id,
|
||||
'container_start',
|
||||
0,
|
||||
container_id=container_details.id
|
||||
)
|
||||
return jsonify(message='ok')
|
||||
else:
|
||||
return jsonify(status=1, message='require action')
|
||||
|
||||
|
||||
@api.route('/vms/')
|
||||
@auth.login_required
|
||||
def vms_list():
|
||||
"""
|
||||
get virtual servers list
|
||||
curl -X POST http://localhost:5000/api/v1/vms/ -u <email>:<secret>
|
||||
:return:
|
||||
"""
|
||||
return jsonify(vms=ControllerVMS(g.user_id).get_items())
|
3
SWSCloudAPI/__init__.py
Normal file
3
SWSCloudAPI/__init__.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
# coding: utf-8
|
||||
|
||||
from application import app
|
65
SWSCloudAPI/application.py
Normal file
65
SWSCloudAPI/application.py
Normal file
|
@ -0,0 +1,65 @@
|
|||
# coding: utf-8
|
||||
|
||||
from flask import Flask, g, jsonify
|
||||
from SWSCloudAPI.API import api
|
||||
from SWSCloudCore import models
|
||||
from SWSCloudCore.models import database
|
||||
from SWSCloudCore.config import config
|
||||
|
||||
app = Flask(__name__)
|
||||
# app.config['SERVER_NAME'] = settings.get('Application', 'SERVER_NAME')
|
||||
app.config['DEBUG'] = config.getboolean('Application', 'DEBUG')
|
||||
app.config['SECRET_KEY'] = config.get("Application", "SECRET_KEY")
|
||||
|
||||
app.register_blueprint(api)
|
||||
|
||||
|
||||
@app.errorhandler(404)
|
||||
def page_not_found(e):
|
||||
app.logger.error(e)
|
||||
return jsonify(dict(message='resource not found')), 404
|
||||
|
||||
|
||||
@app.errorhandler(403)
|
||||
def access_deny(e):
|
||||
app.logger.error(e)
|
||||
return jsonify(dict(message='access deny')), 403
|
||||
|
||||
|
||||
@app.errorhandler(410)
|
||||
def page_not_found(e):
|
||||
app.logger.error(e)
|
||||
return jsonify(dict()), 410
|
||||
|
||||
|
||||
@app.errorhandler(500)
|
||||
def page_not_found(e):
|
||||
app.logger.error(e)
|
||||
return jsonify(dict(message='maintenance')), 500
|
||||
|
||||
|
||||
@app.before_request
|
||||
def before_request():
|
||||
g.settings = dict()
|
||||
# извлекаем настройки и определяем их в глобальную переменную
|
||||
for setting in models.Settings.select(models.Settings.key, models.Settings.val).execute():
|
||||
g.settings[setting.key] = setting.val
|
||||
|
||||
|
||||
@app.before_first_request
|
||||
def before_first_request():
|
||||
try:
|
||||
database.connect()
|
||||
except Exception as e:
|
||||
app.logger.error(e)
|
||||
return jsonify({}), 500
|
||||
|
||||
|
||||
@app.after_request
|
||||
def after_request(response):
|
||||
# TODO: report about access
|
||||
return response
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='0.0.0.0', port=5001, debug=True)
|
Loading…
Add table
Reference in a new issue