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