root / api / handlers.py @ 9eef701d
History | View | Annotate | Download (16.1 kB)
1 | 00b4f1be | Faidon Liambotis | # vim: ts=4 sts=4 et ai sw=4 fileencoding=utf-8
|
---|---|---|---|
2 | 00b4f1be | Faidon Liambotis | #
|
3 | 8b78d1a5 | Markos Gogoulos | # Copyright © 2010 Greek Research and Technology Network
|
4 | 8b78d1a5 | Markos Gogoulos | |
5 | debeeec9 | Markos Gogoulos | import json |
6 | 2c089b77 | Faidon Liambotis | from django.conf import settings |
7 | 00b4f1be | Faidon Liambotis | from piston.handler import BaseHandler, AnonymousBaseHandler |
8 | 635cfd6e | Faidon Liambotis | from synnefo.api.faults import fault, noContent, accepted, created |
9 | 2c089b77 | Faidon Liambotis | from synnefo.api.helpers import instance_to_server, paginator |
10 | 909f415b | Faidon Liambotis | from synnefo.util.rapi import GanetiRapiClient, GanetiApiError |
11 | a31ff6cb | Markos Gogoulos | from synnefo.db.models import * |
12 | ccbd9f9b | Markos Gogoulos | from util.rapi import GanetiRapiClient |
13 | 2ed31bce | Markos Gogoulos | |
14 | 253f0c82 | Faidon Liambotis | |
15 | c5e38339 | Markos Gogoulos | try:
|
16 | ec06b07c | Dimitris Moraitis | rapi = GanetiRapiClient(*settings.GANETI_CLUSTER_INFO) |
17 | c5e38339 | Markos Gogoulos | rapi.GetVersion() |
18 | c5e38339 | Markos Gogoulos | except:
|
19 | c5e38339 | Markos Gogoulos | raise fault.serviceUnavailable
|
20 | c5e38339 | Markos Gogoulos | #If we can't connect to the rapi successfully, don't do anything
|
21 | c5e38339 | Markos Gogoulos | #TODO: add logging/admin alerting
|
22 | 00b4f1be | Faidon Liambotis | |
23 | f5ad2956 | Markos Gogoulos | backend_prefix_id = settings.BACKEND_PREFIX_ID |
24 | ccbd9f9b | Markos Gogoulos | |
25 | 00b4f1be | Faidon Liambotis | VERSIONS = [ |
26 | 00b4f1be | Faidon Liambotis | { |
27 | 00b4f1be | Faidon Liambotis | "status": "CURRENT", |
28 | 00b4f1be | Faidon Liambotis | "id": "v1.0", |
29 | 00b4f1be | Faidon Liambotis | "docURL" : "http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20090714.pdf ", |
30 | 00b4f1be | Faidon Liambotis | "wadl" : "http://docs.rackspacecloud.com/servers/api/v1.0/application.wadl" |
31 | 00b4f1be | Faidon Liambotis | }, |
32 | 9071888e | Constantinos Venetsanopoulos | { |
33 | 9071888e | Constantinos Venetsanopoulos | "status": "CURRENT", |
34 | 9071888e | Constantinos Venetsanopoulos | "id": "v1.0grnet1", |
35 | 9071888e | Constantinos Venetsanopoulos | "docURL" : "None yet", |
36 | 9071888e | Constantinos Venetsanopoulos | "wad1" : "None yet" |
37 | 9071888e | Constantinos Venetsanopoulos | } |
38 | 00b4f1be | Faidon Liambotis | ] |
39 | 00b4f1be | Faidon Liambotis | |
40 | ccbd9f9b | Markos Gogoulos | |
41 | 00b4f1be | Faidon Liambotis | class VersionHandler(AnonymousBaseHandler): |
42 | 00b4f1be | Faidon Liambotis | allowed_methods = ('GET',)
|
43 | 00b4f1be | Faidon Liambotis | |
44 | 00b4f1be | Faidon Liambotis | def read(self, request, number=None): |
45 | 00b4f1be | Faidon Liambotis | if number is None: |
46 | 00b4f1be | Faidon Liambotis | versions = map(lambda v: { |
47 | 00b4f1be | Faidon Liambotis | "status": v["status"], |
48 | 00b4f1be | Faidon Liambotis | "id": v["id"], |
49 | 00b4f1be | Faidon Liambotis | }, VERSIONS) |
50 | 00b4f1be | Faidon Liambotis | return { "versions": versions } |
51 | 00b4f1be | Faidon Liambotis | else:
|
52 | 00b4f1be | Faidon Liambotis | for version in VERSIONS: |
53 | 00b4f1be | Faidon Liambotis | if version["id"] == number: |
54 | 00b4f1be | Faidon Liambotis | return { "version": version } |
55 | 635cfd6e | Faidon Liambotis | raise fault.itemNotFound
|
56 | 00b4f1be | Faidon Liambotis | |
57 | 00b4f1be | Faidon Liambotis | |
58 | 00b4f1be | Faidon Liambotis | class ServerHandler(BaseHandler): |
59 | fd4828ce | Faidon Liambotis | allowed_methods = ('GET', 'POST', 'PUT', 'DELETE') |
60 | fd4828ce | Faidon Liambotis | |
61 | 00b4f1be | Faidon Liambotis | def read(self, request, id=None): |
62 | 38e2c5ed | Christodoulos Psaltis | from time import sleep |
63 | dc8b976e | Markos Gogoulos | sleep(0.5)
|
64 | ccbd9f9b | Markos Gogoulos | #TODO: delete the sleep once the mock objects are removed
|
65 | 00b4f1be | Faidon Liambotis | if id is None: |
66 | 00b4f1be | Faidon Liambotis | return self.read_all(request) |
67 | 253f0c82 | Faidon Liambotis | elif id == "detail": |
68 | 00b4f1be | Faidon Liambotis | return self.read_all(request, detail=True) |
69 | 00b4f1be | Faidon Liambotis | else:
|
70 | 00b4f1be | Faidon Liambotis | return self.read_one(request, id) |
71 | 00b4f1be | Faidon Liambotis | |
72 | 00b4f1be | Faidon Liambotis | def read_one(self, request, id): |
73 | 909f415b | Faidon Liambotis | try:
|
74 | dc8b976e | Markos Gogoulos | instance = VirtualMachine.objects.get(id=id)
|
75 | dc8b976e | Markos Gogoulos | return { "server": instance } #FIXME |
76 | dc8b976e | Markos Gogoulos | except:
|
77 | 909f415b | Faidon Liambotis | raise fault.itemNotFound
|
78 | 00b4f1be | Faidon Liambotis | |
79 | 2c089b77 | Faidon Liambotis | @paginator
|
80 | 00b4f1be | Faidon Liambotis | def read_all(self, request, detail=False): |
81 | 12827073 | Markos Gogoulos | virtual_servers = VirtualMachine.objects.all() |
82 | dc8b976e | Markos Gogoulos | virtual_servers = [virtual_server for virtual_server in virtual_servers if virtual_server.rsapi_state !="DELETED"] |
83 | dc8b976e | Markos Gogoulos | #get all VM's for now, FIX it to take the user's VMs only yet. also don't get deleted VM's
|
84 | 12827073 | Markos Gogoulos | |
85 | 00b4f1be | Faidon Liambotis | if not detail: |
86 | e107ee57 | Markos Gogoulos | return { "servers": [ { "id": s.id, "name": s.name } for s in virtual_servers ] } |
87 | 00b4f1be | Faidon Liambotis | else:
|
88 | c6959a35 | Dimitris Moraitis | virtual_servers_list = [{'status': server.rsapi_state,
|
89 | 12827073 | Markos Gogoulos | 'flavorId': server.flavor.id,
|
90 | 12827073 | Markos Gogoulos | 'name': server.name,
|
91 | 12827073 | Markos Gogoulos | 'id': server.id,
|
92 | 12827073 | Markos Gogoulos | 'imageId': server.sourceimage.id,
|
93 | 12827073 | Markos Gogoulos | 'metadata': {'Server_Label': server.description, |
94 | 12827073 | Markos Gogoulos | 'hostId': '9e107d9d372bb6826bd81d3542a419d6', |
95 | 12827073 | Markos Gogoulos | 'addresses': {'public': ['67.23.10.133'], |
96 | 12827073 | Markos Gogoulos | 'private': ['10.176.42.17'], |
97 | 12827073 | Markos Gogoulos | } |
98 | 12827073 | Markos Gogoulos | } |
99 | 12827073 | Markos Gogoulos | } for server in virtual_servers] |
100 | e107ee57 | Markos Gogoulos | #pass some fake data regarding ip, since we don't have any such data
|
101 | e107ee57 | Markos Gogoulos | return { "servers": virtual_servers_list } |
102 | e107ee57 | Markos Gogoulos | |
103 | 00b4f1be | Faidon Liambotis | |
104 | 00b4f1be | Faidon Liambotis | def create(self, request): |
105 | 8400e1a5 | Markos Gogoulos | print 'create machine was called' |
106 | debeeec9 | Markos Gogoulos | #TODO: add random pass, metadata
|
107 | debeeec9 | Markos Gogoulos | try:
|
108 | debeeec9 | Markos Gogoulos | options_request = json.loads(request.POST.get('create', None)) #here we have the options for cpu, ram etc |
109 | debeeec9 | Markos Gogoulos | cpu = options_request.get('cpu','') |
110 | debeeec9 | Markos Gogoulos | ram = options_request.get('ram','') |
111 | debeeec9 | Markos Gogoulos | name = options_request.get('name','') |
112 | debeeec9 | Markos Gogoulos | storage = options_request.get('storage','') |
113 | debeeec9 | Markos Gogoulos | pnode = rapi.GetNodes()[0]
|
114 | debeeec9 | Markos Gogoulos | rapi.CreateInstance('create', name, 'plain', [{"size": storage}], [{}], os='debootstrap+default', ip_check=False, name_check=False,pnode=pnode, beparams={'auto_balance': True, 'vcpus': cpu, 'memory': ram}) |
115 | debeeec9 | Markos Gogoulos | return accepted
|
116 | debeeec9 | Markos Gogoulos | except: # something bad happened. FIXME: return code |
117 | debeeec9 | Markos Gogoulos | return noContent
|
118 | debeeec9 | Markos Gogoulos | |
119 | 8400e1a5 | Markos Gogoulos | #TODO: replace with real data from request.POST
|
120 | debeeec9 | Markos Gogoulos | #TODO: create the VM in the database
|
121 | 00b4f1be | Faidon Liambotis | |
122 | 00b4f1be | Faidon Liambotis | def update(self, request, id): |
123 | 00b4f1be | Faidon Liambotis | return noContent
|
124 | 00b4f1be | Faidon Liambotis | |
125 | 00b4f1be | Faidon Liambotis | def delete(self, request, id): |
126 | 9eef701d | Markos Gogoulos | try:
|
127 | 9eef701d | Markos Gogoulos | instance = VirtualMachine.objects.get(id=id)
|
128 | 9eef701d | Markos Gogoulos | print 'deleting machine %s' % instance.name |
129 | 9eef701d | Markos Gogoulos | instance._operstate = 'DESTROYED'
|
130 | 9eef701d | Markos Gogoulos | return accepted
|
131 | 9eef701d | Markos Gogoulos | #rapi.DeleteInstance(instance.name)
|
132 | 9eef701d | Markos Gogoulos | except:
|
133 | 9eef701d | Markos Gogoulos | raise fault.itemNotFound
|
134 | 00b4f1be | Faidon Liambotis | |
135 | 00b4f1be | Faidon Liambotis | |
136 | 00b4f1be | Faidon Liambotis | class ServerAddressHandler(BaseHandler): |
137 | 00b4f1be | Faidon Liambotis | allowed_methods = ('GET', 'PUT', 'DELETE') |
138 | 00b4f1be | Faidon Liambotis | |
139 | 00b4f1be | Faidon Liambotis | def read(self, request, id, type=None): |
140 | 00b4f1be | Faidon Liambotis | """List IP addresses for a server"""
|
141 | ccbd9f9b | Markos Gogoulos | |
142 | 00b4f1be | Faidon Liambotis | if type is None: |
143 | 00b4f1be | Faidon Liambotis | pass
|
144 | 00b4f1be | Faidon Liambotis | elif type == "private": |
145 | 00b4f1be | Faidon Liambotis | pass
|
146 | 00b4f1be | Faidon Liambotis | elif type == "public": |
147 | 00b4f1be | Faidon Liambotis | pass
|
148 | 00b4f1be | Faidon Liambotis | return {}
|
149 | 00b4f1be | Faidon Liambotis | |
150 | 00b4f1be | Faidon Liambotis | def update(self, request, id, address): |
151 | 00b4f1be | Faidon Liambotis | """Share an IP address to another in the group"""
|
152 | 00b4f1be | Faidon Liambotis | return accepted
|
153 | 00b4f1be | Faidon Liambotis | |
154 | 00b4f1be | Faidon Liambotis | def delete(self, request, id, address): |
155 | 00b4f1be | Faidon Liambotis | """Unshare an IP address"""
|
156 | 00b4f1be | Faidon Liambotis | return accepted
|
157 | 00b4f1be | Faidon Liambotis | |
158 | 00b4f1be | Faidon Liambotis | |
159 | 00b4f1be | Faidon Liambotis | class ServerActionHandler(BaseHandler): |
160 | ccbd9f9b | Markos Gogoulos | allowed_methods = ('POST', 'DELETE', 'GET', 'PUT') |
161 | ccbd9f9b | Markos Gogoulos | #TODO: remove GET/PUT
|
162 | ccbd9f9b | Markos Gogoulos | |
163 | ccbd9f9b | Markos Gogoulos | def read(self, request, id): |
164 | ccbd9f9b | Markos Gogoulos | return accepted
|
165 | 00b4f1be | Faidon Liambotis | |
166 | 00b4f1be | Faidon Liambotis | def create(self, request, id): |
167 | 00b4f1be | Faidon Liambotis | """Reboot, rebuild, resize, confirm resized, revert resized"""
|
168 | c5e38339 | Markos Gogoulos | try:
|
169 | c5e38339 | Markos Gogoulos | machine = VirtualMachine.objects.get(id=id)
|
170 | c5e38339 | Markos Gogoulos | except:
|
171 | c21a0a84 | Markos Gogoulos | return noContent
|
172 | c21a0a84 | Markos Gogoulos | #FIXME: for now make a list with only one machine. This will be a list of machines (for the list view)
|
173 | d66446ce | Markos Gogoulos | reboot_request = request.POST.get('reboot', None) |
174 | d66446ce | Markos Gogoulos | shutdown_request = request.POST.get('shutdown', None) |
175 | e98852ba | Markos Gogoulos | start_request = request.POST.get('start', None) |
176 | d66446ce | Markos Gogoulos | if reboot_request:
|
177 | c21a0a84 | Markos Gogoulos | return self.action_start([machine], 'reboot') |
178 | d66446ce | Markos Gogoulos | elif shutdown_request:
|
179 | c21a0a84 | Markos Gogoulos | return self.action_start([machine], 'shutdown') |
180 | e98852ba | Markos Gogoulos | elif start_request:
|
181 | e98852ba | Markos Gogoulos | return self.action_start([machine], 'start') |
182 | c21a0a84 | Markos Gogoulos | return noContent #FIXME: when does this happen? |
183 | 427a9220 | Faidon Liambotis | |
184 | 427a9220 | Faidon Liambotis | |
185 | ccbd9f9b | Markos Gogoulos | def delete(self, request, id): |
186 | ccbd9f9b | Markos Gogoulos | """Delete an Instance"""
|
187 | ccbd9f9b | Markos Gogoulos | return accepted
|
188 | ccbd9f9b | Markos Gogoulos | |
189 | ccbd9f9b | Markos Gogoulos | def update(self, request, id): |
190 | ccbd9f9b | Markos Gogoulos | return noContent
|
191 | ccbd9f9b | Markos Gogoulos | |
192 | c21a0a84 | Markos Gogoulos | def action_start(self, list_of_machines, action): |
193 | c21a0a84 | Markos Gogoulos | if action == 'reboot': |
194 | c21a0a84 | Markos Gogoulos | try:
|
195 | c21a0a84 | Markos Gogoulos | for machine in list_of_machines: |
196 | c21a0a84 | Markos Gogoulos | rapi.RebootInstance(machine) |
197 | c21a0a84 | Markos Gogoulos | return accepted
|
198 | e98852ba | Markos Gogoulos | except: # something bad happened. |
199 | e98852ba | Markos Gogoulos | #FIXME: return code. Rackspace error response code(s): cloudServersFault (400, 500), serviceUnavailable (503), unauthorized(401), badRequest (400), badMediaType(415), itemNotFound (404), buildInProgress (409), overLimit (413)
|
200 | c21a0a84 | Markos Gogoulos | return noContent
|
201 | c21a0a84 | Markos Gogoulos | if action == 'shutdown': |
202 | c21a0a84 | Markos Gogoulos | try:
|
203 | c21a0a84 | Markos Gogoulos | for machine in list_of_machines: |
204 | c21a0a84 | Markos Gogoulos | rapi.ShutdownInstance(machine) |
205 | c21a0a84 | Markos Gogoulos | return accepted
|
206 | c21a0a84 | Markos Gogoulos | except: # something bad happened. FIXME: return code |
207 | c21a0a84 | Markos Gogoulos | return noContent
|
208 | e98852ba | Markos Gogoulos | if action == 'start': |
209 | e98852ba | Markos Gogoulos | try:
|
210 | e98852ba | Markos Gogoulos | for machine in list_of_machines: |
211 | e98852ba | Markos Gogoulos | rapi.StartupInstance(machine) |
212 | e98852ba | Markos Gogoulos | return accepted
|
213 | e98852ba | Markos Gogoulos | except: # something bad happened. FIXME: return code |
214 | e98852ba | Markos Gogoulos | return noContent
|
215 | e98852ba | Markos Gogoulos | |
216 | ccbd9f9b | Markos Gogoulos | |
217 | ccbd9f9b | Markos Gogoulos | |
218 | ccbd9f9b | Markos Gogoulos | #read is called on GET requests
|
219 | ccbd9f9b | Markos Gogoulos | #create is called on POST, and creates new objects, and should return them (or rc.CREATED.)
|
220 | ccbd9f9b | Markos Gogoulos | #update is called on PUT, and should update an existing product and return them (or rc.ALL_OK.)
|
221 | ccbd9f9b | Markos Gogoulos | #delete is called on DELETE, and should delete an existing object. Should not return anything, just rc.DELETED.'''
|
222 | ccbd9f9b | Markos Gogoulos | |
223 | ccbd9f9b | Markos Gogoulos | |
224 | c99adc90 | Faidon Liambotis | class ServerBackupHandler(BaseHandler): |
225 | c99adc90 | Faidon Liambotis | """ Backup Schedules are not implemented yet, return notImplemented """
|
226 | c99adc90 | Faidon Liambotis | allowed_methods = ('GET', 'POST', 'DELETE') |
227 | c99adc90 | Faidon Liambotis | |
228 | c99adc90 | Faidon Liambotis | def read(self, request, id): |
229 | 635cfd6e | Faidon Liambotis | raise fault.notImplemented
|
230 | c99adc90 | Faidon Liambotis | |
231 | c99adc90 | Faidon Liambotis | def create(self, request, id): |
232 | 635cfd6e | Faidon Liambotis | raise fault.notImplemented
|
233 | c99adc90 | Faidon Liambotis | |
234 | c99adc90 | Faidon Liambotis | def delete(self, request, id): |
235 | 635cfd6e | Faidon Liambotis | raise fault.notImplemented
|
236 | c99adc90 | Faidon Liambotis | |
237 | c99adc90 | Faidon Liambotis | |
238 | 427a9220 | Faidon Liambotis | class FlavorHandler(BaseHandler): |
239 | 427a9220 | Faidon Liambotis | allowed_methods = ('GET',)
|
240 | b8d16d68 | Markos Gogoulos | flavors = Flavor.objects.all() |
241 | b8d16d68 | Markos Gogoulos | flavors = [ {'id': flavor.id, 'name': flavor.name, 'ram': flavor.ram, \ |
242 | b8d16d68 | Markos Gogoulos | 'disk': flavor.disk} for flavor in flavors] |
243 | 427a9220 | Faidon Liambotis | |
244 | 427a9220 | Faidon Liambotis | def read(self, request, id=None): |
245 | dcc6a862 | Faidon Liambotis | """
|
246 | dcc6a862 | Faidon Liambotis | List flavors or retrieve one
|
247 | 427a9220 | Faidon Liambotis |
|
248 | 427a9220 | Faidon Liambotis | Returns: OK
|
249 | dcc6a862 | Faidon Liambotis | Faults: cloudServersFault, serviceUnavailable, unauthorized,
|
250 | dcc6a862 | Faidon Liambotis | badRequest, itemNotFound
|
251 | 427a9220 | Faidon Liambotis | """
|
252 | 427a9220 | Faidon Liambotis | if id is None: |
253 | 427a9220 | Faidon Liambotis | simple = map(lambda v: { |
254 | b8d16d68 | Markos Gogoulos | "id": v['id'], |
255 | b8d16d68 | Markos Gogoulos | "name": v['name'], |
256 | 427a9220 | Faidon Liambotis | }, self.flavors)
|
257 | 427a9220 | Faidon Liambotis | return { "flavors": simple } |
258 | 427a9220 | Faidon Liambotis | elif id == "detail": |
259 | 427a9220 | Faidon Liambotis | return { "flavors": self.flavors } |
260 | 427a9220 | Faidon Liambotis | else:
|
261 | 427a9220 | Faidon Liambotis | for flavor in self.flavors: |
262 | b8d16d68 | Markos Gogoulos | if str(flavor['id']) == id: |
263 | 427a9220 | Faidon Liambotis | return { "flavor": flavor } |
264 | 635cfd6e | Faidon Liambotis | raise fault.itemNotFound
|
265 | dcc6a862 | Faidon Liambotis | |
266 | dcc6a862 | Faidon Liambotis | |
267 | dcc6a862 | Faidon Liambotis | class ImageHandler(BaseHandler): |
268 | dcc6a862 | Faidon Liambotis | allowed_methods = ('GET', 'POST') |
269 | dcc6a862 | Faidon Liambotis | |
270 | dcc6a862 | Faidon Liambotis | def read(self, request, id=None): |
271 | dcc6a862 | Faidon Liambotis | """
|
272 | dcc6a862 | Faidon Liambotis | List images or retrieve one
|
273 | dcc6a862 | Faidon Liambotis |
|
274 | dcc6a862 | Faidon Liambotis | Returns: OK
|
275 | dcc6a862 | Faidon Liambotis | Faults: cloudServersFault, serviceUnavailable, unauthorized,
|
276 | dcc6a862 | Faidon Liambotis | badRequest, itemNotFound
|
277 | dcc6a862 | Faidon Liambotis | """
|
278 | 2cc9d3a5 | Markos Gogoulos | images = Image.objects.all() |
279 | c5e38339 | Markos Gogoulos | images_list = [ {'created': image.created.isoformat(),
|
280 | 12827073 | Markos Gogoulos | 'id': image.id,
|
281 | 12827073 | Markos Gogoulos | 'name': image.name,
|
282 | 12827073 | Markos Gogoulos | 'updated': image.updated.isoformat(),
|
283 | 12827073 | Markos Gogoulos | 'description': image.description,
|
284 | 12827073 | Markos Gogoulos | 'state': image.state,
|
285 | 12827073 | Markos Gogoulos | 'vm_id': image.vm_id
|
286 | 12827073 | Markos Gogoulos | } for image in images] |
287 | e107ee57 | Markos Gogoulos | if rapi: # Images info is stored in the DB. Ganeti is not aware of this |
288 | ec06b07c | Dimitris Moraitis | if id == "detail": |
289 | c5e38339 | Markos Gogoulos | return { "images": images_list } |
290 | ec06b07c | Dimitris Moraitis | elif id is None: |
291 | c5e38339 | Markos Gogoulos | return { "images": [ { "id": s['id'], "name": s['name'] } for s in images_list ] } |
292 | ec06b07c | Dimitris Moraitis | else:
|
293 | c5e38339 | Markos Gogoulos | try:
|
294 | c5e38339 | Markos Gogoulos | image = images.get(id=id)
|
295 | c5e38339 | Markos Gogoulos | return { "image": {'created': image.created.isoformat(), |
296 | c5e38339 | Markos Gogoulos | 'id': image.id,
|
297 | c5e38339 | Markos Gogoulos | 'name': image.name,
|
298 | c5e38339 | Markos Gogoulos | 'updated': image.updated.isoformat(),
|
299 | c5e38339 | Markos Gogoulos | 'description': image.description,
|
300 | c5e38339 | Markos Gogoulos | 'state': image.state,
|
301 | c5e38339 | Markos Gogoulos | 'vm_id': image.vm_id
|
302 | c5e38339 | Markos Gogoulos | } } |
303 | c5e38339 | Markos Gogoulos | except:
|
304 | c5e38339 | Markos Gogoulos | raise fault.itemNotFound
|
305 | 00d83c42 | Markos Gogoulos | else:
|
306 | c5e38339 | Markos Gogoulos | raise fault.serviceUnavailable
|
307 | dcc6a862 | Faidon Liambotis | |
308 | dcc6a862 | Faidon Liambotis | def create(self, request): |
309 | dcc6a862 | Faidon Liambotis | """Create a new image"""
|
310 | dcc6a862 | Faidon Liambotis | return accepted
|
311 | ed66d976 | Faidon Liambotis | |
312 | ed66d976 | Faidon Liambotis | |
313 | ed66d976 | Faidon Liambotis | class SharedIPGroupHandler(BaseHandler): |
314 | ed66d976 | Faidon Liambotis | allowed_methods = ('GET', 'POST', 'DELETE') |
315 | ed66d976 | Faidon Liambotis | |
316 | ed66d976 | Faidon Liambotis | def read(self, request, id=None): |
317 | ed66d976 | Faidon Liambotis | """List Shared IP Groups"""
|
318 | ed66d976 | Faidon Liambotis | if id is None: |
319 | ed66d976 | Faidon Liambotis | return {}
|
320 | ed66d976 | Faidon Liambotis | elif id == "detail": |
321 | ed66d976 | Faidon Liambotis | return {}
|
322 | ed66d976 | Faidon Liambotis | else:
|
323 | 635cfd6e | Faidon Liambotis | raise fault.itemNotFound
|
324 | ed66d976 | Faidon Liambotis | |
325 | ed66d976 | Faidon Liambotis | def create(self, request, id): |
326 | ed66d976 | Faidon Liambotis | """Creates a new Shared IP Group"""
|
327 | ed66d976 | Faidon Liambotis | return created
|
328 | ed66d976 | Faidon Liambotis | |
329 | ed66d976 | Faidon Liambotis | def delete(self, request, id): |
330 | ed66d976 | Faidon Liambotis | """Deletes a Shared IP Group"""
|
331 | ed66d976 | Faidon Liambotis | return noContent
|
332 | beb79c95 | Faidon Liambotis | |
333 | beb79c95 | Faidon Liambotis | |
334 | a31ff6cb | Markos Gogoulos | class VirtualMachineGroupHandler(BaseHandler): |
335 | a31ff6cb | Markos Gogoulos | allowed_methods = ('GET', 'POST', 'DELETE') |
336 | a31ff6cb | Markos Gogoulos | |
337 | a31ff6cb | Markos Gogoulos | def read(self, request, id=None): |
338 | a31ff6cb | Markos Gogoulos | """List Groups"""
|
339 | a31ff6cb | Markos Gogoulos | vmgroups = VirtualMachineGroup.objects.all() |
340 | a31ff6cb | Markos Gogoulos | vmgroups = [ {'id': vmgroup.id, \
|
341 | a31ff6cb | Markos Gogoulos | 'name': vmgroup.name, \
|
342 | a31ff6cb | Markos Gogoulos | 'server_id': [machine.id for machine in vmgroup.machines.all()] \ |
343 | a31ff6cb | Markos Gogoulos | } for vmgroup in vmgroups] |
344 | a31ff6cb | Markos Gogoulos | if rapi: # Group info is stored in the DB. Ganeti is not aware of this |
345 | a31ff6cb | Markos Gogoulos | if id == "detail": |
346 | a31ff6cb | Markos Gogoulos | return { "groups": vmgroups } |
347 | a31ff6cb | Markos Gogoulos | elif id is None: |
348 | a31ff6cb | Markos Gogoulos | return { "groups": [ { "id": s['id'], "name": s['name'] } for s in vmgroups ] } |
349 | a31ff6cb | Markos Gogoulos | else:
|
350 | a31ff6cb | Markos Gogoulos | return { "groups": vmgroups[0] } |
351 | a31ff6cb | Markos Gogoulos | |
352 | a31ff6cb | Markos Gogoulos | |
353 | a31ff6cb | Markos Gogoulos | def create(self, request, id): |
354 | a31ff6cb | Markos Gogoulos | """Creates a Group"""
|
355 | a31ff6cb | Markos Gogoulos | return created
|
356 | a31ff6cb | Markos Gogoulos | |
357 | a31ff6cb | Markos Gogoulos | def delete(self, request, id): |
358 | a31ff6cb | Markos Gogoulos | """Deletes a Group"""
|
359 | a31ff6cb | Markos Gogoulos | return noContent
|
360 | a31ff6cb | Markos Gogoulos | |
361 | a31ff6cb | Markos Gogoulos | |
362 | beb79c95 | Faidon Liambotis | class LimitHandler(BaseHandler): |
363 | beb79c95 | Faidon Liambotis | allowed_methods = ('GET',)
|
364 | beb79c95 | Faidon Liambotis | |
365 | beb79c95 | Faidon Liambotis | # XXX: hookup with @throttle
|
366 | beb79c95 | Faidon Liambotis | |
367 | beb79c95 | Faidon Liambotis | rate = [ |
368 | beb79c95 | Faidon Liambotis | { |
369 | beb79c95 | Faidon Liambotis | "verb" : "POST", |
370 | beb79c95 | Faidon Liambotis | "URI" : "*", |
371 | beb79c95 | Faidon Liambotis | "regex" : ".*", |
372 | beb79c95 | Faidon Liambotis | "value" : 10, |
373 | beb79c95 | Faidon Liambotis | "remaining" : 2, |
374 | beb79c95 | Faidon Liambotis | "unit" : "MINUTE", |
375 | beb79c95 | Faidon Liambotis | "resetTime" : 1244425439 |
376 | beb79c95 | Faidon Liambotis | }, |
377 | beb79c95 | Faidon Liambotis | { |
378 | beb79c95 | Faidon Liambotis | "verb" : "POST", |
379 | beb79c95 | Faidon Liambotis | "URI" : "*/servers", |
380 | beb79c95 | Faidon Liambotis | "regex" : "^/servers", |
381 | beb79c95 | Faidon Liambotis | "value" : 25, |
382 | beb79c95 | Faidon Liambotis | "remaining" : 24, |
383 | beb79c95 | Faidon Liambotis | "unit" : "DAY", |
384 | beb79c95 | Faidon Liambotis | "resetTime" : 1244511839 |
385 | beb79c95 | Faidon Liambotis | }, |
386 | beb79c95 | Faidon Liambotis | { |
387 | beb79c95 | Faidon Liambotis | "verb" : "PUT", |
388 | beb79c95 | Faidon Liambotis | "URI" : "*", |
389 | beb79c95 | Faidon Liambotis | "regex" : ".*", |
390 | beb79c95 | Faidon Liambotis | "value" : 10, |
391 | beb79c95 | Faidon Liambotis | "remaining" : 2, |
392 | beb79c95 | Faidon Liambotis | "unit" : "MINUTE", |
393 | beb79c95 | Faidon Liambotis | "resetTime" : 1244425439 |
394 | beb79c95 | Faidon Liambotis | }, |
395 | beb79c95 | Faidon Liambotis | { |
396 | beb79c95 | Faidon Liambotis | "verb" : "GET", |
397 | beb79c95 | Faidon Liambotis | "URI" : "*", |
398 | beb79c95 | Faidon Liambotis | "regex" : ".*", |
399 | beb79c95 | Faidon Liambotis | "value" : 3, |
400 | beb79c95 | Faidon Liambotis | "remaining" : 3, |
401 | beb79c95 | Faidon Liambotis | "unit" : "MINUTE", |
402 | beb79c95 | Faidon Liambotis | "resetTime" : 1244425439 |
403 | beb79c95 | Faidon Liambotis | }, |
404 | beb79c95 | Faidon Liambotis | { |
405 | beb79c95 | Faidon Liambotis | "verb" : "DELETE", |
406 | beb79c95 | Faidon Liambotis | "URI" : "*", |
407 | beb79c95 | Faidon Liambotis | "regex" : ".*", |
408 | beb79c95 | Faidon Liambotis | "value" : 100, |
409 | beb79c95 | Faidon Liambotis | "remaining" : 100, |
410 | beb79c95 | Faidon Liambotis | "unit" : "MINUTE", |
411 | beb79c95 | Faidon Liambotis | "resetTime" : 1244425439 |
412 | beb79c95 | Faidon Liambotis | } |
413 | beb79c95 | Faidon Liambotis | ] |
414 | beb79c95 | Faidon Liambotis | |
415 | beb79c95 | Faidon Liambotis | absolute = { |
416 | beb79c95 | Faidon Liambotis | "maxTotalRAMSize" : 51200, |
417 | beb79c95 | Faidon Liambotis | "maxIPGroups" : 50, |
418 | beb79c95 | Faidon Liambotis | "maxIPGroupMembers" : 25 |
419 | beb79c95 | Faidon Liambotis | } |
420 | beb79c95 | Faidon Liambotis | |
421 | beb79c95 | Faidon Liambotis | def read(self, request): |
422 | beb79c95 | Faidon Liambotis | return { "limits": { |
423 | beb79c95 | Faidon Liambotis | "rate": self.rate, |
424 | beb79c95 | Faidon Liambotis | "absolute": self.absolute, |
425 | beb79c95 | Faidon Liambotis | } |
426 | beb79c95 | Faidon Liambotis | } |
427 | 9071888e | Constantinos Venetsanopoulos | |
428 | 9071888e | Constantinos Venetsanopoulos | |
429 | 9071888e | Constantinos Venetsanopoulos | class DiskHandler(BaseHandler): |
430 | 9071888e | Constantinos Venetsanopoulos | allowed_methods = ('GET', 'POST', 'PUT', 'DELETE') |
431 | 9071888e | Constantinos Venetsanopoulos | |
432 | 9071888e | Constantinos Venetsanopoulos | def read(self, request, id=None): |
433 | 9071888e | Constantinos Venetsanopoulos | """List Disks"""
|
434 | 9071888e | Constantinos Venetsanopoulos | if id is None: |
435 | 9071888e | Constantinos Venetsanopoulos | return self.read_all(request) |
436 | 9071888e | Constantinos Venetsanopoulos | elif id == "detail": |
437 | 9071888e | Constantinos Venetsanopoulos | return self.read_all(request, detail=True) |
438 | 9071888e | Constantinos Venetsanopoulos | else:
|
439 | 9071888e | Constantinos Venetsanopoulos | return self.read_one(request, id) |
440 | 9071888e | Constantinos Venetsanopoulos | |
441 | 9071888e | Constantinos Venetsanopoulos | def read_one(self, request, id): |
442 | 9071888e | Constantinos Venetsanopoulos | """List one Disk with the specified id with all details"""
|
443 | 9071888e | Constantinos Venetsanopoulos | # FIXME Get detailed info from the DB
|
444 | 9071888e | Constantinos Venetsanopoulos | # for the Disk with the specified id
|
445 | 9071888e | Constantinos Venetsanopoulos | try:
|
446 | 9071888e | Constantinos Venetsanopoulos | disk = Disk.objects.get(pk=id)
|
447 | 9071888e | Constantinos Venetsanopoulos | disk_details = { |
448 | 9071888e | Constantinos Venetsanopoulos | "id" : disk.id,
|
449 | 9071888e | Constantinos Venetsanopoulos | "name" : disk.name,
|
450 | 9071888e | Constantinos Venetsanopoulos | "size" : disk.size,
|
451 | 9071888e | Constantinos Venetsanopoulos | "created" : disk.created,
|
452 | 9071888e | Constantinos Venetsanopoulos | "serverId" : disk.vm.id
|
453 | 9071888e | Constantinos Venetsanopoulos | } |
454 | 9071888e | Constantinos Venetsanopoulos | return { "disks" : disk_details } |
455 | 9071888e | Constantinos Venetsanopoulos | except:
|
456 | 9071888e | Constantinos Venetsanopoulos | raise fault.itemNotFound
|
457 | 9071888e | Constantinos Venetsanopoulos | |
458 | 9071888e | Constantinos Venetsanopoulos | @paginator
|
459 | 9071888e | Constantinos Venetsanopoulos | def read_all(self, request, detail=False): |
460 | 9071888e | Constantinos Venetsanopoulos | """List all Disks. If -detail- is set list them with all details"""
|
461 | 9071888e | Constantinos Venetsanopoulos | if not detail: |
462 | 9071888e | Constantinos Venetsanopoulos | disks = Disk.objects.filter(owner=SynnefoUser.objects.all()[0])
|
463 | 9071888e | Constantinos Venetsanopoulos | return { "disks": [ { "id": disk.id, "name": disk.name } for disk in disks ] } |
464 | 9071888e | Constantinos Venetsanopoulos | else:
|
465 | 9071888e | Constantinos Venetsanopoulos | disks = Disk.objects.filter(owner=SynnefoUser.objects.all()[0])
|
466 | 9071888e | Constantinos Venetsanopoulos | disks_details = [ { |
467 | 9071888e | Constantinos Venetsanopoulos | "id" : disk.id,
|
468 | 9071888e | Constantinos Venetsanopoulos | "name" : disk.name,
|
469 | 9071888e | Constantinos Venetsanopoulos | "size" : disk.size,
|
470 | 9071888e | Constantinos Venetsanopoulos | "created" : disk.created,
|
471 | 9071888e | Constantinos Venetsanopoulos | "serverId" : disk.vm.id,
|
472 | 9071888e | Constantinos Venetsanopoulos | } for disk in disks ] |
473 | 9071888e | Constantinos Venetsanopoulos | return { "disks": disks_details } |
474 | 9071888e | Constantinos Venetsanopoulos | |
475 | 9071888e | Constantinos Venetsanopoulos | def create(self, request): |
476 | 9071888e | Constantinos Venetsanopoulos | """Create a new Disk"""
|
477 | 9071888e | Constantinos Venetsanopoulos | # FIXME Create a partial DB entry,
|
478 | 9071888e | Constantinos Venetsanopoulos | # then call the backend for actual creation
|
479 | 9071888e | Constantinos Venetsanopoulos | pass
|
480 | 9071888e | Constantinos Venetsanopoulos | |
481 | 9071888e | Constantinos Venetsanopoulos | def update(self, request, id): |
482 | 9071888e | Constantinos Venetsanopoulos | """Rename the Disk with the specified id"""
|
483 | 9071888e | Constantinos Venetsanopoulos | # FIXME Change the Disk's name in the DB
|
484 | 9071888e | Constantinos Venetsanopoulos | pass
|
485 | 9071888e | Constantinos Venetsanopoulos | |
486 | 9071888e | Constantinos Venetsanopoulos | def delete(self, request, id): |
487 | 9071888e | Constantinos Venetsanopoulos | """Destroy the Disk with the specified id"""
|
488 | 9071888e | Constantinos Venetsanopoulos | # Call the backend for actual destruction
|
489 | 9071888e | Constantinos Venetsanopoulos | pass |