root / api / handlers.py @ 2c089b77
History | View | Annotate | Download (7 kB)
1 |
# vim: ts=4 sts=4 et ai sw=4 fileencoding=utf-8
|
---|---|
2 |
#
|
3 |
# Copyright © 2010 Greek Research and Technology Network
|
4 |
#
|
5 |
|
6 |
from django.conf import settings |
7 |
from piston.handler import BaseHandler, AnonymousBaseHandler |
8 |
from synnefo.api.faults import fault, noContent, accepted, created |
9 |
from synnefo.api.helpers import instance_to_server, paginator |
10 |
from synnefo.util.rapi import GanetiRapiClient |
11 |
|
12 |
rapi = GanetiRapiClient(*settings.GANETI_CLUSTER_INFO) |
13 |
|
14 |
VERSIONS = [ |
15 |
{ |
16 |
"status": "CURRENT", |
17 |
"id": "v1.0", |
18 |
"docURL" : "http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20090714.pdf ", |
19 |
"wadl" : "http://docs.rackspacecloud.com/servers/api/v1.0/application.wadl" |
20 |
}, |
21 |
] |
22 |
|
23 |
class VersionHandler(AnonymousBaseHandler): |
24 |
allowed_methods = ('GET',)
|
25 |
|
26 |
def read(self, request, number=None): |
27 |
if number is None: |
28 |
versions = map(lambda v: { |
29 |
"status": v["status"], |
30 |
"id": v["id"], |
31 |
}, VERSIONS) |
32 |
return { "versions": versions } |
33 |
else:
|
34 |
for version in VERSIONS: |
35 |
if version["id"] == number: |
36 |
return { "version": version } |
37 |
raise fault.itemNotFound
|
38 |
|
39 |
|
40 |
class ServerHandler(BaseHandler): |
41 |
allowed_methods = ('GET', 'POST', 'PUT', 'DELETE') |
42 |
|
43 |
def read(self, request, id=None): |
44 |
if id is None: |
45 |
return self.read_all(request) |
46 |
elif id == "detail": |
47 |
return self.read_all(request, detail=True) |
48 |
else:
|
49 |
return self.read_one(request, id) |
50 |
|
51 |
def read_one(self, request, id): |
52 |
instance = rapi.GetInstance(id)
|
53 |
return { "server": instance_to_server(instance) } |
54 |
|
55 |
@paginator
|
56 |
def read_all(self, request, detail=False): |
57 |
if not detail: |
58 |
instances = rapi.GetInstances(bulk=False)
|
59 |
servers = [ { "id": id, "name": id } for id in instances ] |
60 |
else:
|
61 |
instances = rapi.GetInstances(bulk=True)
|
62 |
servers = [] |
63 |
for instance in instances: |
64 |
servers.append(instance_to_server(instance)) |
65 |
return { "servers": servers } |
66 |
|
67 |
def create(self, request): |
68 |
return accepted
|
69 |
|
70 |
def update(self, request, id): |
71 |
return noContent
|
72 |
|
73 |
def delete(self, request, id): |
74 |
return accepted
|
75 |
|
76 |
|
77 |
class ServerAddressHandler(BaseHandler): |
78 |
allowed_methods = ('GET', 'PUT', 'DELETE') |
79 |
|
80 |
def read(self, request, id, type=None): |
81 |
"""List IP addresses for a server"""
|
82 |
if type is None: |
83 |
pass
|
84 |
elif type == "private": |
85 |
pass
|
86 |
elif type == "public": |
87 |
pass
|
88 |
return {}
|
89 |
|
90 |
def update(self, request, id, address): |
91 |
"""Share an IP address to another in the group"""
|
92 |
return accepted
|
93 |
|
94 |
def delete(self, request, id, address): |
95 |
"""Unshare an IP address"""
|
96 |
return accepted
|
97 |
|
98 |
|
99 |
class ServerActionHandler(BaseHandler): |
100 |
allowed_methods = ('POST',)
|
101 |
|
102 |
def create(self, request, id): |
103 |
"""Reboot, rebuild, resize, confirm resized, revert resized"""
|
104 |
print ("server action %s" % id) |
105 |
return accepted
|
106 |
|
107 |
|
108 |
class ServerBackupHandler(BaseHandler): |
109 |
""" Backup Schedules are not implemented yet, return notImplemented """
|
110 |
allowed_methods = ('GET', 'POST', 'DELETE') |
111 |
|
112 |
def read(self, request, id): |
113 |
raise fault.notImplemented
|
114 |
|
115 |
def create(self, request, id): |
116 |
raise fault.notImplemented
|
117 |
|
118 |
def delete(self, request, id): |
119 |
raise fault.notImplemented
|
120 |
|
121 |
|
122 |
class FlavorHandler(BaseHandler): |
123 |
allowed_methods = ('GET',)
|
124 |
flavors = [ |
125 |
{ |
126 |
"id" : 1, |
127 |
"name" : "256 MB Server", |
128 |
"ram" : 256, |
129 |
"disk" : 10 |
130 |
}, |
131 |
{ |
132 |
"id" : 2, |
133 |
"name" : "512 MB Server", |
134 |
"ram" : 512, |
135 |
"disk" : 20 |
136 |
} |
137 |
] |
138 |
|
139 |
def read(self, request, id=None): |
140 |
"""
|
141 |
List flavors or retrieve one
|
142 |
|
143 |
Returns: OK
|
144 |
Faults: cloudServersFault, serviceUnavailable, unauthorized,
|
145 |
badRequest, itemNotFound
|
146 |
"""
|
147 |
if id is None: |
148 |
simple = map(lambda v: { |
149 |
"id": v["id"], |
150 |
"name": v["name"], |
151 |
}, self.flavors)
|
152 |
return { "flavors": simple } |
153 |
elif id == "detail": |
154 |
return { "flavors": self.flavors } |
155 |
else:
|
156 |
for flavor in self.flavors: |
157 |
if str(flavor["id"]) == id: |
158 |
return { "flavor": flavor } |
159 |
raise fault.itemNotFound
|
160 |
|
161 |
|
162 |
class ImageHandler(BaseHandler): |
163 |
allowed_methods = ('GET', 'POST') |
164 |
|
165 |
def read(self, request, id=None): |
166 |
"""
|
167 |
List images or retrieve one
|
168 |
|
169 |
Returns: OK
|
170 |
Faults: cloudServersFault, serviceUnavailable, unauthorized,
|
171 |
badRequest, itemNotFound
|
172 |
"""
|
173 |
if id is None: |
174 |
return {}
|
175 |
elif id == "detail": |
176 |
return {}
|
177 |
else:
|
178 |
raise fault.itemNotFound
|
179 |
|
180 |
def create(self, request): |
181 |
"""Create a new image"""
|
182 |
return accepted
|
183 |
|
184 |
|
185 |
class SharedIPGroupHandler(BaseHandler): |
186 |
allowed_methods = ('GET', 'POST', 'DELETE') |
187 |
|
188 |
def read(self, request, id=None): |
189 |
"""List Shared IP Groups"""
|
190 |
if id is None: |
191 |
return {}
|
192 |
elif id == "detail": |
193 |
return {}
|
194 |
else:
|
195 |
raise fault.itemNotFound
|
196 |
|
197 |
def create(self, request, id): |
198 |
"""Creates a new Shared IP Group"""
|
199 |
return created
|
200 |
|
201 |
def delete(self, request, id): |
202 |
"""Deletes a Shared IP Group"""
|
203 |
return noContent
|
204 |
|
205 |
|
206 |
class LimitHandler(BaseHandler): |
207 |
allowed_methods = ('GET',)
|
208 |
|
209 |
# XXX: hookup with @throttle
|
210 |
|
211 |
rate = [ |
212 |
{ |
213 |
"verb" : "POST", |
214 |
"URI" : "*", |
215 |
"regex" : ".*", |
216 |
"value" : 10, |
217 |
"remaining" : 2, |
218 |
"unit" : "MINUTE", |
219 |
"resetTime" : 1244425439 |
220 |
}, |
221 |
{ |
222 |
"verb" : "POST", |
223 |
"URI" : "*/servers", |
224 |
"regex" : "^/servers", |
225 |
"value" : 25, |
226 |
"remaining" : 24, |
227 |
"unit" : "DAY", |
228 |
"resetTime" : 1244511839 |
229 |
}, |
230 |
{ |
231 |
"verb" : "PUT", |
232 |
"URI" : "*", |
233 |
"regex" : ".*", |
234 |
"value" : 10, |
235 |
"remaining" : 2, |
236 |
"unit" : "MINUTE", |
237 |
"resetTime" : 1244425439 |
238 |
}, |
239 |
{ |
240 |
"verb" : "GET", |
241 |
"URI" : "*", |
242 |
"regex" : ".*", |
243 |
"value" : 3, |
244 |
"remaining" : 3, |
245 |
"unit" : "MINUTE", |
246 |
"resetTime" : 1244425439 |
247 |
}, |
248 |
{ |
249 |
"verb" : "DELETE", |
250 |
"URI" : "*", |
251 |
"regex" : ".*", |
252 |
"value" : 100, |
253 |
"remaining" : 100, |
254 |
"unit" : "MINUTE", |
255 |
"resetTime" : 1244425439 |
256 |
} |
257 |
] |
258 |
|
259 |
absolute = { |
260 |
"maxTotalRAMSize" : 51200, |
261 |
"maxIPGroups" : 50, |
262 |
"maxIPGroupMembers" : 25 |
263 |
} |
264 |
|
265 |
def read(self, request): |
266 |
return { "limits": { |
267 |
"rate": self.rate, |
268 |
"absolute": self.absolute, |
269 |
} |
270 |
} |