/
api.py
135 lines (110 loc) · 3.75 KB
/
api.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# Copyright 2014 varnishapi authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
import inspect
import json
import os
from flask import Flask, Response, request
from . import auth, plugin, storage
from .managers import cloudstack, ec2
api = Flask(__name__)
api.debug = os.environ.get("API_DEBUG", "0") in ("True", "true", "1")
managers = {
"ec2": ec2.EC2Manager,
"cloudstack": cloudstack.CloudStackManager,
}
@api.route("/resources", methods=["POST"])
@auth.required
def add_instance():
name = request.form.get("name")
if not name:
return "name is required", 400
manager = get_manager()
manager.new_instance(name)
return "", 201
@api.route("/resources/<name>", methods=["DELETE"])
@auth.required
def remove_instance(name):
manager = get_manager()
try:
manager.remove_instance(name)
except storage.InstanceNotFoundError:
return "Instance not found", 404
return "", 200
@api.route("/resources/<name>", methods=["POST"])
@auth.required
def bind(name):
app_host = request.form.get("app-host")
if not app_host:
return "app-host is required", 400
manager = get_manager()
try:
manager.bind(name, app_host)
except storage.InstanceNotFoundError:
return "Instance not found", 404
return Response(response="null", status=201,
mimetype="application/json")
@api.route("/resources/<name>/hostname/<host>", methods=["DELETE"])
@auth.required
def unbind(name, host):
manager = get_manager()
try:
manager.unbind(name, host)
except storage.InstanceNotFoundError:
return "Instance not found", 404
return "", 200
@api.route("/resources/<name>", methods=["GET"])
@auth.required
def info(name):
manager = get_manager()
try:
info = manager.info(name)
if "secret" in info:
del info["secret"]
return Response(response=json.dumps(info), status=200,
mimetype="application/json")
except storage.InstanceNotFoundError:
return "Instance not found", 404
@api.route("/resources/<name>/status", methods=["GET"])
@auth.required
def status(name):
states = {"started": 204, "pending": 202, "scaling": 204}
manager = get_manager()
try:
status = manager.status(name)
except storage.InstanceNotFoundError:
return "Instance not found", 404
return status, states.get(status, 500)
@api.route("/resources/<name>/scale", methods=["POST"])
@auth.required
def scale_instance(name):
quantity = request.form.get("quantity")
if not quantity:
return "missing quantity", 400
manager = get_manager()
try:
manager.scale_instance(name, int(quantity))
except ValueError as e:
msg = " ".join(e.args)
if "invalid literal" in msg:
return "invalid quantity: %s" % quantity, 400
return msg, 400
except storage.InstanceNotFoundError:
return "Instance not found", 404
return "", 201
@api.route("/plugin", methods=["GET"])
def get_plugin():
return inspect.getsource(plugin)
def register_manager(name, obj, override=False):
if not override and name in managers:
raise ValueError("Manager already registered")
managers[name] = obj
def get_manager():
manager = os.environ.get("API_MANAGER", "ec2")
manager_class = managers.get(manager)
if not manager_class:
raise ValueError("{0} is not a valid manager".format(manager))
mongodb_uri = os.environ.get("API_MONGODB_URI")
mongodb_database = os.environ.get("API_MONGODB_DATABASE_NAME")
return manager_class(storage.MongoDBStorage(mongo_uri=mongodb_uri,
dbname=mongodb_database))