Statistics
| Branch: | Tag: | Revision:

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