root / api / servers.py @ 7584d408
History | View | Annotate | Download (14.1 kB)
1 | 7e2f9d4b | Giorgos Verigakis | #
|
---|---|---|---|
2 | 7e2f9d4b | Giorgos Verigakis | # Copyright (c) 2010 Greek Research and Technology Network
|
3 | 7e2f9d4b | Giorgos Verigakis | #
|
4 | 7e2f9d4b | Giorgos Verigakis | |
5 | b016b476 | Giorgos Verigakis | from django.conf import settings |
6 | d8e50a39 | Giorgos Verigakis | from django.conf.urls.defaults import patterns |
7 | 7e2f9d4b | Giorgos Verigakis | from django.http import HttpResponse |
8 | 7e2f9d4b | Giorgos Verigakis | from django.template.loader import render_to_string |
9 | 29a59bc1 | Giorgos Verigakis | from django.utils import simplejson as json |
10 | 7e2f9d4b | Giorgos Verigakis | |
11 | 0971fa71 | Markos Gogoulos | from synnefo.api.actions import server_actions |
12 | d8e50a39 | Giorgos Verigakis | from synnefo.api.common import method_not_allowed |
13 | d8e50a39 | Giorgos Verigakis | from synnefo.api.faults import BadRequest, ItemNotFound |
14 | 0971fa71 | Markos Gogoulos | from synnefo.api.util import * |
15 | d8e50a39 | Giorgos Verigakis | from synnefo.db.models import Image, Flavor, VirtualMachine, VirtualMachineMetadata |
16 | d8e50a39 | Giorgos Verigakis | from synnefo.logic.utils import get_rsapi_state |
17 | 0971fa71 | Markos Gogoulos | from synnefo.util.rapi import GanetiRapiClient |
18 | d8e50a39 | Giorgos Verigakis | from synnefo.logic import backend |
19 | d8e50a39 | Giorgos Verigakis | |
20 | d8e50a39 | Giorgos Verigakis | import logging |
21 | d8e50a39 | Giorgos Verigakis | |
22 | 7e2f9d4b | Giorgos Verigakis | |
23 | 7e2f9d4b | Giorgos Verigakis | rapi = GanetiRapiClient(*settings.GANETI_CLUSTER_INFO) |
24 | 7e2f9d4b | Giorgos Verigakis | |
25 | 7e2f9d4b | Giorgos Verigakis | urlpatterns = patterns('synnefo.api.servers',
|
26 | 7e2f9d4b | Giorgos Verigakis | (r'^(?:/|.json|.xml)?$', 'demux'), |
27 | 7e2f9d4b | Giorgos Verigakis | (r'^/detail(?:.json|.xml)?$', 'list_servers', {'detail': True}), |
28 | 7e2f9d4b | Giorgos Verigakis | (r'^/(\d+)(?:.json|.xml)?$', 'server_demux'), |
29 | b016b476 | Giorgos Verigakis | (r'^/(\d+)/action(?:.json|.xml)?$', 'server_action'), |
30 | b016b476 | Giorgos Verigakis | (r'^/(\d+)/ips(?:.json|.xml)?$', 'list_addresses'), |
31 | b016b476 | Giorgos Verigakis | (r'^/(\d+)/ips/(.+?)(?:.json|.xml)?$', 'list_addresses_by_network'), |
32 | d8e50a39 | Giorgos Verigakis | (r'^/(\d+)/meta(?:.json|.xml)?$', 'metadata_demux'), |
33 | d8e50a39 | Giorgos Verigakis | (r'^/(\d+)/meta/(.+?)(?:.json|.xml)?$', 'metadata_item_demux'), |
34 | 7e2f9d4b | Giorgos Verigakis | ) |
35 | 7e2f9d4b | Giorgos Verigakis | |
36 | 7e2f9d4b | Giorgos Verigakis | |
37 | 7e2f9d4b | Giorgos Verigakis | def demux(request): |
38 | 7e2f9d4b | Giorgos Verigakis | if request.method == 'GET': |
39 | 7e2f9d4b | Giorgos Verigakis | return list_servers(request)
|
40 | 7e2f9d4b | Giorgos Verigakis | elif request.method == 'POST': |
41 | 7e2f9d4b | Giorgos Verigakis | return create_server(request)
|
42 | 7e2f9d4b | Giorgos Verigakis | else:
|
43 | d8e50a39 | Giorgos Verigakis | return method_not_allowed(request)
|
44 | 7e2f9d4b | Giorgos Verigakis | |
45 | 7e2f9d4b | Giorgos Verigakis | def server_demux(request, server_id): |
46 | 7e2f9d4b | Giorgos Verigakis | if request.method == 'GET': |
47 | 7e2f9d4b | Giorgos Verigakis | return get_server_details(request, server_id)
|
48 | 7e2f9d4b | Giorgos Verigakis | elif request.method == 'PUT': |
49 | 7e2f9d4b | Giorgos Verigakis | return update_server_name(request, server_id)
|
50 | 7e2f9d4b | Giorgos Verigakis | elif request.method == 'DELETE': |
51 | 7e2f9d4b | Giorgos Verigakis | return delete_server(request, server_id)
|
52 | 7e2f9d4b | Giorgos Verigakis | else:
|
53 | d8e50a39 | Giorgos Verigakis | return method_not_allowed(request)
|
54 | d8e50a39 | Giorgos Verigakis | |
55 | d8e50a39 | Giorgos Verigakis | def metadata_demux(request, server_id): |
56 | d8e50a39 | Giorgos Verigakis | if request.method == 'GET': |
57 | d8e50a39 | Giorgos Verigakis | return list_metadata(request, server_id)
|
58 | d8e50a39 | Giorgos Verigakis | elif request.method == 'POST': |
59 | d8e50a39 | Giorgos Verigakis | return update_metadata(request, server_id)
|
60 | d8e50a39 | Giorgos Verigakis | else:
|
61 | d8e50a39 | Giorgos Verigakis | return method_not_allowed(request)
|
62 | d8e50a39 | Giorgos Verigakis | |
63 | d8e50a39 | Giorgos Verigakis | def metadata_item_demux(request, server_id, key): |
64 | d8e50a39 | Giorgos Verigakis | if request.method == 'GET': |
65 | d8e50a39 | Giorgos Verigakis | return get_metadata_item(request, server_id, key)
|
66 | d8e50a39 | Giorgos Verigakis | elif request.method == 'PUT': |
67 | d8e50a39 | Giorgos Verigakis | return create_metadata_item(request, server_id, key)
|
68 | d8e50a39 | Giorgos Verigakis | elif request.method == 'DELETE': |
69 | d8e50a39 | Giorgos Verigakis | return delete_metadata_item(request, server_id, key)
|
70 | d8e50a39 | Giorgos Verigakis | else:
|
71 | d8e50a39 | Giorgos Verigakis | return method_not_allowed(request)
|
72 | 7e2f9d4b | Giorgos Verigakis | |
73 | c36934a7 | Giorgos Verigakis | |
74 | b016b476 | Giorgos Verigakis | def address_to_dict(ipfour, ipsix): |
75 | b016b476 | Giorgos Verigakis | return {'id': 'public', |
76 | b016b476 | Giorgos Verigakis | 'values': [{'version': 4, 'addr': ipfour}, {'version': 6, 'addr': ipsix}]} |
77 | b016b476 | Giorgos Verigakis | |
78 | d8e50a39 | Giorgos Verigakis | def metadata_to_dict(vm): |
79 | d8e50a39 | Giorgos Verigakis | vm_meta = vm.virtualmachinemetadata_set.all() |
80 | d8e50a39 | Giorgos Verigakis | return dict((meta.meta_key, meta.meta_value) for meta in vm_meta) |
81 | d8e50a39 | Giorgos Verigakis | |
82 | d8e50a39 | Giorgos Verigakis | def vm_to_dict(vm, detail=False): |
83 | d8e50a39 | Giorgos Verigakis | d = dict(id=vm.id, name=vm.name)
|
84 | 7e2f9d4b | Giorgos Verigakis | if detail:
|
85 | d8e50a39 | Giorgos Verigakis | d['status'] = get_rsapi_state(vm)
|
86 | d8e50a39 | Giorgos Verigakis | d['progress'] = 100 if get_rsapi_state(vm) == 'ACTIVE' else 0 |
87 | d8e50a39 | Giorgos Verigakis | d['hostId'] = vm.hostid
|
88 | d8e50a39 | Giorgos Verigakis | d['updated'] = isoformat(vm.updated)
|
89 | d8e50a39 | Giorgos Verigakis | d['created'] = isoformat(vm.created)
|
90 | d8e50a39 | Giorgos Verigakis | d['flavorRef'] = vm.flavor.id
|
91 | d8e50a39 | Giorgos Verigakis | d['imageRef'] = vm.sourceimage.id
|
92 | 7e2f9d4b | Giorgos Verigakis | |
93 | d8e50a39 | Giorgos Verigakis | metadata = metadata_to_dict(vm) |
94 | 7e2f9d4b | Giorgos Verigakis | if metadata:
|
95 | b9a77976 | Giorgos Verigakis | d['metadata'] = {'values': metadata} |
96 | 7e2f9d4b | Giorgos Verigakis | |
97 | d8e50a39 | Giorgos Verigakis | addresses = [address_to_dict(vm.ipfour, vm.ipsix)] |
98 | b9a77976 | Giorgos Verigakis | d['addresses'] = {'values': addresses} |
99 | 7e2f9d4b | Giorgos Verigakis | return d
|
100 | 7e2f9d4b | Giorgos Verigakis | |
101 | d8e50a39 | Giorgos Verigakis | |
102 | d8e50a39 | Giorgos Verigakis | def render_server(request, server, status=200): |
103 | d8e50a39 | Giorgos Verigakis | if request.serialization == 'xml': |
104 | d8e50a39 | Giorgos Verigakis | data = render_to_string('server.xml', {'server': server, 'is_root': True}) |
105 | 7e2f9d4b | Giorgos Verigakis | else:
|
106 | d8e50a39 | Giorgos Verigakis | data = json.dumps({'server': server})
|
107 | c36934a7 | Giorgos Verigakis | return HttpResponse(data, status=status)
|
108 | d8e50a39 | Giorgos Verigakis | |
109 | 7e2f9d4b | Giorgos Verigakis | |
110 | c36934a7 | Giorgos Verigakis | @api_method('GET') |
111 | 7e2f9d4b | Giorgos Verigakis | def list_servers(request, detail=False): |
112 | 7e2f9d4b | Giorgos Verigakis | # Normal Response Codes: 200, 203
|
113 | 7e2f9d4b | Giorgos Verigakis | # Error Response Codes: computeFault (400, 500),
|
114 | 7e2f9d4b | Giorgos Verigakis | # serviceUnavailable (503),
|
115 | 7e2f9d4b | Giorgos Verigakis | # unauthorized (401),
|
116 | 7e2f9d4b | Giorgos Verigakis | # badRequest (400),
|
117 | 7e2f9d4b | Giorgos Verigakis | # overLimit (413)
|
118 | c36934a7 | Giorgos Verigakis | |
119 | 7e2f9d4b | Giorgos Verigakis | owner = get_user() |
120 | d8e50a39 | Giorgos Verigakis | since = isoparse(request.GET.get('changes-since'))
|
121 | d8e50a39 | Giorgos Verigakis | |
122 | d8e50a39 | Giorgos Verigakis | if since:
|
123 | d8e50a39 | Giorgos Verigakis | user_vms = VirtualMachine.objects.filter(updated__gt=since) |
124 | d8e50a39 | Giorgos Verigakis | if not user_vms: |
125 | d8e50a39 | Giorgos Verigakis | return HttpResponse(status=304) |
126 | d8e50a39 | Giorgos Verigakis | else:
|
127 | d8e50a39 | Giorgos Verigakis | user_vms = VirtualMachine.objects.filter(owner=owner, deleted=False)
|
128 | d8e50a39 | Giorgos Verigakis | servers = [vm_to_dict(server, detail) for server in user_vms] |
129 | c36934a7 | Giorgos Verigakis | |
130 | d8e50a39 | Giorgos Verigakis | if request.serialization == 'xml': |
131 | d8e50a39 | Giorgos Verigakis | data = render_to_string('list_servers.xml', {'servers': servers, 'detail': detail}) |
132 | 7e2f9d4b | Giorgos Verigakis | else:
|
133 | c36934a7 | Giorgos Verigakis | data = json.dumps({'servers': {'values': servers}}) |
134 | c36934a7 | Giorgos Verigakis | |
135 | c36934a7 | Giorgos Verigakis | return HttpResponse(data, status=200) |
136 | 7e2f9d4b | Giorgos Verigakis | |
137 | c36934a7 | Giorgos Verigakis | @api_method('POST') |
138 | 7e2f9d4b | Giorgos Verigakis | def create_server(request): |
139 | 7e2f9d4b | Giorgos Verigakis | # Normal Response Code: 202
|
140 | 7e2f9d4b | Giorgos Verigakis | # Error Response Codes: computeFault (400, 500),
|
141 | 7e2f9d4b | Giorgos Verigakis | # serviceUnavailable (503),
|
142 | 7e2f9d4b | Giorgos Verigakis | # unauthorized (401),
|
143 | 7e2f9d4b | Giorgos Verigakis | # badMediaType(415),
|
144 | 7e2f9d4b | Giorgos Verigakis | # itemNotFound (404),
|
145 | 7e2f9d4b | Giorgos Verigakis | # badRequest (400),
|
146 | 7e2f9d4b | Giorgos Verigakis | # serverCapacityUnavailable (503),
|
147 | 7e2f9d4b | Giorgos Verigakis | # overLimit (413)
|
148 | 7e2f9d4b | Giorgos Verigakis | |
149 | 7e2f9d4b | Giorgos Verigakis | req = get_request_dict(request) |
150 | 7e2f9d4b | Giorgos Verigakis | |
151 | 7e2f9d4b | Giorgos Verigakis | try:
|
152 | 7e2f9d4b | Giorgos Verigakis | server = req['server']
|
153 | 7e2f9d4b | Giorgos Verigakis | name = server['name']
|
154 | bc855ce7 | Giorgos Verigakis | metadata = server.get('metadata', {})
|
155 | bc855ce7 | Giorgos Verigakis | assert isinstance(metadata, dict) |
156 | 90d90bd2 | Giorgos Verigakis | sourceimage = Image.objects.get(id=server['imageRef'])
|
157 | 90d90bd2 | Giorgos Verigakis | flavor = Flavor.objects.get(id=server['flavorRef'])
|
158 | bc855ce7 | Giorgos Verigakis | except (KeyError, AssertionError): |
159 | d8e50a39 | Giorgos Verigakis | raise BadRequest('Malformed request.') |
160 | 7e2f9d4b | Giorgos Verigakis | except Image.DoesNotExist:
|
161 | 7e2f9d4b | Giorgos Verigakis | raise ItemNotFound
|
162 | 7e2f9d4b | Giorgos Verigakis | except Flavor.DoesNotExist:
|
163 | 7e2f9d4b | Giorgos Verigakis | raise ItemNotFound
|
164 | 7e2f9d4b | Giorgos Verigakis | |
165 | bc855ce7 | Giorgos Verigakis | vm = VirtualMachine( |
166 | 7e2f9d4b | Giorgos Verigakis | name=name, |
167 | 7e2f9d4b | Giorgos Verigakis | owner=get_user(), |
168 | 7e2f9d4b | Giorgos Verigakis | sourceimage=sourceimage, |
169 | 7e2f9d4b | Giorgos Verigakis | ipfour='0.0.0.0',
|
170 | 7e2f9d4b | Giorgos Verigakis | ipsix='::1',
|
171 | 7e2f9d4b | Giorgos Verigakis | flavor=flavor) |
172 | 7e2f9d4b | Giorgos Verigakis | |
173 | 7e2f9d4b | Giorgos Verigakis | if request.META.get('SERVER_NAME', None) == 'testserver': |
174 | 7e2f9d4b | Giorgos Verigakis | name = 'test-server'
|
175 | 7e2f9d4b | Giorgos Verigakis | dry_run = True
|
176 | 7e2f9d4b | Giorgos Verigakis | else:
|
177 | d8e50a39 | Giorgos Verigakis | name = vm.backend_id |
178 | 7e2f9d4b | Giorgos Verigakis | dry_run = False
|
179 | 7e2f9d4b | Giorgos Verigakis | |
180 | 7e2f9d4b | Giorgos Verigakis | jobId = rapi.CreateInstance( |
181 | 7e2f9d4b | Giorgos Verigakis | mode='create',
|
182 | 7e2f9d4b | Giorgos Verigakis | name=name, |
183 | 7e2f9d4b | Giorgos Verigakis | disk_template='plain',
|
184 | 7e2f9d4b | Giorgos Verigakis | disks=[{"size": 2000}], #FIXME: Always ask for a 2GB disk for now |
185 | 7e2f9d4b | Giorgos Verigakis | nics=[{}], |
186 | 90d90bd2 | Giorgos Verigakis | os='debootstrap+default', #TODO: select OS from imageRef |
187 | 7e2f9d4b | Giorgos Verigakis | ip_check=False,
|
188 | 90d90bd2 | Giorgos Verigakis | name_check=False,
|
189 | 7e2f9d4b | Giorgos Verigakis | pnode=rapi.GetNodes()[0], #TODO: verify if this is necessary |
190 | 7e2f9d4b | Giorgos Verigakis | dry_run=dry_run, |
191 | 7e2f9d4b | Giorgos Verigakis | beparams=dict(auto_balance=True, vcpus=flavor.cpu, memory=flavor.ram)) |
192 | 7e2f9d4b | Giorgos Verigakis | |
193 | d8e50a39 | Giorgos Verigakis | vm.save() |
194 | bc855ce7 | Giorgos Verigakis | |
195 | bc855ce7 | Giorgos Verigakis | for key, val in metadata.items(): |
196 | bc855ce7 | Giorgos Verigakis | VirtualMachineMetadata.objects.create(meta_key=key, meta_value=val, vm=vm) |
197 | bc855ce7 | Giorgos Verigakis | |
198 | d8e50a39 | Giorgos Verigakis | logging.info('created vm with %s cpus, %s ram and %s storage' % (flavor.cpu, flavor.ram, flavor.disk))
|
199 | 7e2f9d4b | Giorgos Verigakis | |
200 | d8e50a39 | Giorgos Verigakis | server = vm_to_dict(vm, detail=True)
|
201 | d8e50a39 | Giorgos Verigakis | server['status'] = 'BUILD' |
202 | d8e50a39 | Giorgos Verigakis | server['adminPass'] = random_password()
|
203 | d8e50a39 | Giorgos Verigakis | return render_server(request, server, status=202) |
204 | 7e2f9d4b | Giorgos Verigakis | |
205 | c36934a7 | Giorgos Verigakis | @api_method('GET') |
206 | 7e2f9d4b | Giorgos Verigakis | def get_server_details(request, server_id): |
207 | c36934a7 | Giorgos Verigakis | # Normal Response Codes: 200, 203
|
208 | c36934a7 | Giorgos Verigakis | # Error Response Codes: computeFault (400, 500),
|
209 | c36934a7 | Giorgos Verigakis | # serviceUnavailable (503),
|
210 | c36934a7 | Giorgos Verigakis | # unauthorized (401),
|
211 | c36934a7 | Giorgos Verigakis | # badRequest (400),
|
212 | c36934a7 | Giorgos Verigakis | # itemNotFound (404),
|
213 | c36934a7 | Giorgos Verigakis | # overLimit (413)
|
214 | c36934a7 | Giorgos Verigakis | |
215 | d8e50a39 | Giorgos Verigakis | vm = get_vm(server_id) |
216 | d8e50a39 | Giorgos Verigakis | server = vm_to_dict(vm, detail=True)
|
217 | d8e50a39 | Giorgos Verigakis | return render_server(request, server)
|
218 | 7e2f9d4b | Giorgos Verigakis | |
219 | c36934a7 | Giorgos Verigakis | @api_method('PUT') |
220 | c36934a7 | Giorgos Verigakis | def update_server_name(request, server_id): |
221 | c36934a7 | Giorgos Verigakis | # Normal Response Code: 204
|
222 | c36934a7 | Giorgos Verigakis | # Error Response Codes: computeFault (400, 500),
|
223 | c36934a7 | Giorgos Verigakis | # serviceUnavailable (503),
|
224 | c36934a7 | Giorgos Verigakis | # unauthorized (401),
|
225 | c36934a7 | Giorgos Verigakis | # badRequest (400),
|
226 | c36934a7 | Giorgos Verigakis | # badMediaType(415),
|
227 | c36934a7 | Giorgos Verigakis | # itemNotFound (404),
|
228 | c36934a7 | Giorgos Verigakis | # buildInProgress (409),
|
229 | c36934a7 | Giorgos Verigakis | # overLimit (413)
|
230 | c36934a7 | Giorgos Verigakis | |
231 | 7e2f9d4b | Giorgos Verigakis | req = get_request_dict(request) |
232 | 7e2f9d4b | Giorgos Verigakis | |
233 | 7e2f9d4b | Giorgos Verigakis | try:
|
234 | 7e2f9d4b | Giorgos Verigakis | name = req['server']['name'] |
235 | 7e2f9d4b | Giorgos Verigakis | except KeyError: |
236 | d8e50a39 | Giorgos Verigakis | raise BadRequest('Malformed request.') |
237 | 7e2f9d4b | Giorgos Verigakis | |
238 | d8e50a39 | Giorgos Verigakis | vm = get_vm(server_id) |
239 | d8e50a39 | Giorgos Verigakis | vm.name = name |
240 | d8e50a39 | Giorgos Verigakis | vm.save() |
241 | 7e2f9d4b | Giorgos Verigakis | |
242 | 7e2f9d4b | Giorgos Verigakis | return HttpResponse(status=204) |
243 | 7e2f9d4b | Giorgos Verigakis | |
244 | c36934a7 | Giorgos Verigakis | @api_method('DELETE') |
245 | 7e2f9d4b | Giorgos Verigakis | def delete_server(request, server_id): |
246 | c36934a7 | Giorgos Verigakis | # Normal Response Codes: 204
|
247 | c36934a7 | Giorgos Verigakis | # Error Response Codes: computeFault (400, 500),
|
248 | c36934a7 | Giorgos Verigakis | # serviceUnavailable (503),
|
249 | c36934a7 | Giorgos Verigakis | # unauthorized (401),
|
250 | c36934a7 | Giorgos Verigakis | # itemNotFound (404),
|
251 | c36934a7 | Giorgos Verigakis | # unauthorized (401),
|
252 | c36934a7 | Giorgos Verigakis | # buildInProgress (409),
|
253 | c36934a7 | Giorgos Verigakis | # overLimit (413)
|
254 | c36934a7 | Giorgos Verigakis | |
255 | d8e50a39 | Giorgos Verigakis | vm = get_vm(server_id) |
256 | d8e50a39 | Giorgos Verigakis | backend.start_action(vm, 'DESTROY')
|
257 | d8e50a39 | Giorgos Verigakis | rapi.DeleteInstance(vm.backend_id) |
258 | 7e2f9d4b | Giorgos Verigakis | return HttpResponse(status=204) |
259 | b016b476 | Giorgos Verigakis | |
260 | b016b476 | Giorgos Verigakis | @api_method('POST') |
261 | b016b476 | Giorgos Verigakis | def server_action(request, server_id): |
262 | d8e50a39 | Giorgos Verigakis | vm = get_vm(server_id) |
263 | b016b476 | Giorgos Verigakis | req = get_request_dict(request) |
264 | b016b476 | Giorgos Verigakis | if len(req) != 1: |
265 | d8e50a39 | Giorgos Verigakis | raise BadRequest('Malformed request.') |
266 | b016b476 | Giorgos Verigakis | |
267 | b016b476 | Giorgos Verigakis | key = req.keys()[0]
|
268 | d8e50a39 | Giorgos Verigakis | val = req[key] |
269 | b016b476 | Giorgos Verigakis | |
270 | d8e50a39 | Giorgos Verigakis | try:
|
271 | d8e50a39 | Giorgos Verigakis | assert isinstance(val, dict) |
272 | 20a51b1e | Giorgos Verigakis | return server_actions[key](request, vm, req[key])
|
273 | d8e50a39 | Giorgos Verigakis | except KeyError: |
274 | d8e50a39 | Giorgos Verigakis | raise BadRequest('Unknown action.') |
275 | d8e50a39 | Giorgos Verigakis | except AssertionError: |
276 | d8e50a39 | Giorgos Verigakis | raise BadRequest('Invalid argument.') |
277 | b016b476 | Giorgos Verigakis | |
278 | b016b476 | Giorgos Verigakis | @api_method('GET') |
279 | b016b476 | Giorgos Verigakis | def list_addresses(request, server_id): |
280 | b016b476 | Giorgos Verigakis | # Normal Response Codes: 200, 203
|
281 | b016b476 | Giorgos Verigakis | # Error Response Codes: computeFault (400, 500),
|
282 | b016b476 | Giorgos Verigakis | # serviceUnavailable (503),
|
283 | b016b476 | Giorgos Verigakis | # unauthorized (401),
|
284 | b016b476 | Giorgos Verigakis | # badRequest (400),
|
285 | b016b476 | Giorgos Verigakis | # overLimit (413)
|
286 | b016b476 | Giorgos Verigakis | |
287 | d8e50a39 | Giorgos Verigakis | vm = get_vm(server_id) |
288 | d8e50a39 | Giorgos Verigakis | addresses = [address_to_dict(vm.ipfour, vm.ipsix)] |
289 | b016b476 | Giorgos Verigakis | |
290 | d8e50a39 | Giorgos Verigakis | if request.serialization == 'xml': |
291 | b016b476 | Giorgos Verigakis | data = render_to_string('list_addresses.xml', {'addresses': addresses}) |
292 | b016b476 | Giorgos Verigakis | else:
|
293 | b016b476 | Giorgos Verigakis | data = json.dumps({'addresses': {'values': addresses}}) |
294 | b016b476 | Giorgos Verigakis | |
295 | b016b476 | Giorgos Verigakis | return HttpResponse(data, status=200) |
296 | b016b476 | Giorgos Verigakis | |
297 | b016b476 | Giorgos Verigakis | @api_method('GET') |
298 | b016b476 | Giorgos Verigakis | def list_addresses_by_network(request, server_id, network_id): |
299 | b016b476 | Giorgos Verigakis | # Normal Response Codes: 200, 203
|
300 | b016b476 | Giorgos Verigakis | # Error Response Codes: computeFault (400, 500),
|
301 | b016b476 | Giorgos Verigakis | # serviceUnavailable (503),
|
302 | b016b476 | Giorgos Verigakis | # unauthorized (401),
|
303 | b016b476 | Giorgos Verigakis | # badRequest (400),
|
304 | b016b476 | Giorgos Verigakis | # itemNotFound (404),
|
305 | b016b476 | Giorgos Verigakis | # overLimit (413)
|
306 | b016b476 | Giorgos Verigakis | |
307 | d8e50a39 | Giorgos Verigakis | vm = get_vm(server_id) |
308 | b016b476 | Giorgos Verigakis | if network_id != 'public': |
309 | d8e50a39 | Giorgos Verigakis | raise ItemNotFound('Unknown network.') |
310 | b016b476 | Giorgos Verigakis | |
311 | d8e50a39 | Giorgos Verigakis | address = address_to_dict(vm.ipfour, vm.ipsix) |
312 | b016b476 | Giorgos Verigakis | |
313 | d8e50a39 | Giorgos Verigakis | if request.serialization == 'xml': |
314 | b016b476 | Giorgos Verigakis | data = render_to_string('address.xml', {'address': address}) |
315 | b016b476 | Giorgos Verigakis | else:
|
316 | b016b476 | Giorgos Verigakis | data = json.dumps({'network': address})
|
317 | b016b476 | Giorgos Verigakis | |
318 | b016b476 | Giorgos Verigakis | return HttpResponse(data, status=200) |
319 | d8e50a39 | Giorgos Verigakis | |
320 | d8e50a39 | Giorgos Verigakis | @api_method('GET') |
321 | d8e50a39 | Giorgos Verigakis | def list_metadata(request, server_id): |
322 | d8e50a39 | Giorgos Verigakis | # Normal Response Codes: 200, 203
|
323 | d8e50a39 | Giorgos Verigakis | # Error Response Codes: computeFault (400, 500),
|
324 | d8e50a39 | Giorgos Verigakis | # serviceUnavailable (503),
|
325 | d8e50a39 | Giorgos Verigakis | # unauthorized (401),
|
326 | d8e50a39 | Giorgos Verigakis | # badRequest (400),
|
327 | d8e50a39 | Giorgos Verigakis | # overLimit (413)
|
328 | d8e50a39 | Giorgos Verigakis | |
329 | d8e50a39 | Giorgos Verigakis | vm = get_vm(server_id) |
330 | d8e50a39 | Giorgos Verigakis | metadata = metadata_to_dict(vm) |
331 | 432fc8c3 | Giorgos Verigakis | return render_metadata(request, metadata, use_values=True, status=200) |
332 | d8e50a39 | Giorgos Verigakis | |
333 | d8e50a39 | Giorgos Verigakis | @api_method('POST') |
334 | d8e50a39 | Giorgos Verigakis | def update_metadata(request, server_id): |
335 | d8e50a39 | Giorgos Verigakis | # Normal Response Code: 201
|
336 | d8e50a39 | Giorgos Verigakis | # Error Response Codes: computeFault (400, 500),
|
337 | d8e50a39 | Giorgos Verigakis | # serviceUnavailable (503),
|
338 | d8e50a39 | Giorgos Verigakis | # unauthorized (401),
|
339 | d8e50a39 | Giorgos Verigakis | # badRequest (400),
|
340 | d8e50a39 | Giorgos Verigakis | # buildInProgress (409),
|
341 | d8e50a39 | Giorgos Verigakis | # badMediaType(415),
|
342 | d8e50a39 | Giorgos Verigakis | # overLimit (413)
|
343 | d8e50a39 | Giorgos Verigakis | |
344 | d8e50a39 | Giorgos Verigakis | vm = get_vm(server_id) |
345 | d8e50a39 | Giorgos Verigakis | req = get_request_dict(request) |
346 | d8e50a39 | Giorgos Verigakis | try:
|
347 | d8e50a39 | Giorgos Verigakis | metadata = req['metadata']
|
348 | d8e50a39 | Giorgos Verigakis | assert isinstance(metadata, dict) |
349 | d8e50a39 | Giorgos Verigakis | except (KeyError, AssertionError): |
350 | d8e50a39 | Giorgos Verigakis | raise BadRequest('Malformed request.') |
351 | d8e50a39 | Giorgos Verigakis | |
352 | d8e50a39 | Giorgos Verigakis | updated = {} |
353 | d8e50a39 | Giorgos Verigakis | |
354 | d8e50a39 | Giorgos Verigakis | for key, val in metadata.items(): |
355 | d8e50a39 | Giorgos Verigakis | try:
|
356 | d8e50a39 | Giorgos Verigakis | meta = VirtualMachineMetadata.objects.get(meta_key=key, vm=vm) |
357 | d8e50a39 | Giorgos Verigakis | meta.meta_value = val |
358 | d8e50a39 | Giorgos Verigakis | meta.save() |
359 | d8e50a39 | Giorgos Verigakis | updated[key] = val |
360 | d8e50a39 | Giorgos Verigakis | except VirtualMachineMetadata.DoesNotExist:
|
361 | d8e50a39 | Giorgos Verigakis | pass # Ignore non-existent metadata |
362 | d8e50a39 | Giorgos Verigakis | |
363 | 432fc8c3 | Giorgos Verigakis | return render_metadata(request, metadata, status=201) |
364 | d8e50a39 | Giorgos Verigakis | |
365 | d8e50a39 | Giorgos Verigakis | @api_method('GET') |
366 | d8e50a39 | Giorgos Verigakis | def get_metadata_item(request, server_id, key): |
367 | d8e50a39 | Giorgos Verigakis | # Normal Response Codes: 200, 203
|
368 | d8e50a39 | Giorgos Verigakis | # Error Response Codes: computeFault (400, 500),
|
369 | d8e50a39 | Giorgos Verigakis | # serviceUnavailable (503),
|
370 | d8e50a39 | Giorgos Verigakis | # unauthorized (401),
|
371 | d8e50a39 | Giorgos Verigakis | # itemNotFound (404),
|
372 | d8e50a39 | Giorgos Verigakis | # badRequest (400),
|
373 | d8e50a39 | Giorgos Verigakis | # overLimit (413)
|
374 | d8e50a39 | Giorgos Verigakis | |
375 | d8e50a39 | Giorgos Verigakis | meta = get_vm_meta(server_id, key) |
376 | 432fc8c3 | Giorgos Verigakis | return render_meta(request, meta, status=200) |
377 | d8e50a39 | Giorgos Verigakis | |
378 | d8e50a39 | Giorgos Verigakis | @api_method('PUT') |
379 | d8e50a39 | Giorgos Verigakis | def create_metadata_item(request, server_id, key): |
380 | d8e50a39 | Giorgos Verigakis | # Normal Response Code: 201
|
381 | d8e50a39 | Giorgos Verigakis | # Error Response Codes: computeFault (400, 500),
|
382 | d8e50a39 | Giorgos Verigakis | # serviceUnavailable (503),
|
383 | d8e50a39 | Giorgos Verigakis | # unauthorized (401),
|
384 | d8e50a39 | Giorgos Verigakis | # itemNotFound (404),
|
385 | d8e50a39 | Giorgos Verigakis | # badRequest (400),
|
386 | d8e50a39 | Giorgos Verigakis | # buildInProgress (409),
|
387 | d8e50a39 | Giorgos Verigakis | # badMediaType(415),
|
388 | d8e50a39 | Giorgos Verigakis | # overLimit (413)
|
389 | d8e50a39 | Giorgos Verigakis | |
390 | d8e50a39 | Giorgos Verigakis | vm = get_vm(server_id) |
391 | d8e50a39 | Giorgos Verigakis | req = get_request_dict(request) |
392 | d8e50a39 | Giorgos Verigakis | try:
|
393 | d8e50a39 | Giorgos Verigakis | metadict = req['meta']
|
394 | d8e50a39 | Giorgos Verigakis | assert isinstance(metadict, dict) |
395 | d8e50a39 | Giorgos Verigakis | assert len(metadict) == 1 |
396 | d8e50a39 | Giorgos Verigakis | assert key in metadict |
397 | d8e50a39 | Giorgos Verigakis | except (KeyError, AssertionError): |
398 | d8e50a39 | Giorgos Verigakis | raise BadRequest('Malformed request.') |
399 | d8e50a39 | Giorgos Verigakis | |
400 | d8e50a39 | Giorgos Verigakis | meta, created = VirtualMachineMetadata.objects.get_or_create(meta_key=key, vm=vm) |
401 | d8e50a39 | Giorgos Verigakis | meta.meta_value = metadict[key] |
402 | d8e50a39 | Giorgos Verigakis | meta.save() |
403 | 432fc8c3 | Giorgos Verigakis | return render_meta(request, meta, status=201) |
404 | d8e50a39 | Giorgos Verigakis | |
405 | d8e50a39 | Giorgos Verigakis | @api_method('DELETE') |
406 | d8e50a39 | Giorgos Verigakis | def delete_metadata_item(request, server_id, key): |
407 | d8e50a39 | Giorgos Verigakis | # Normal Response Code: 204
|
408 | d8e50a39 | Giorgos Verigakis | # Error Response Codes: computeFault (400, 500),
|
409 | d8e50a39 | Giorgos Verigakis | # serviceUnavailable (503),
|
410 | d8e50a39 | Giorgos Verigakis | # unauthorized (401),
|
411 | d8e50a39 | Giorgos Verigakis | # itemNotFound (404),
|
412 | d8e50a39 | Giorgos Verigakis | # badRequest (400),
|
413 | d8e50a39 | Giorgos Verigakis | # buildInProgress (409),
|
414 | d8e50a39 | Giorgos Verigakis | # badMediaType(415),
|
415 | d8e50a39 | Giorgos Verigakis | # overLimit (413),
|
416 | d8e50a39 | Giorgos Verigakis | |
417 | d8e50a39 | Giorgos Verigakis | meta = get_vm_meta(server_id, key) |
418 | d8e50a39 | Giorgos Verigakis | meta.delete() |
419 | d8e50a39 | Giorgos Verigakis | return HttpResponse(status=204) |