Revision ce55f211 snf-cyclades-app/synnefo/api/servers.py
b/snf-cyclades-app/synnefo/api/servers.py | ||
---|---|---|
1 | 1 |
# Copyright 2011-2012 GRNET S.A. All rights reserved. |
2 |
#
|
|
2 |
# |
|
3 | 3 |
# Redistribution and use in source and binary forms, with or |
4 | 4 |
# without modification, are permitted provided that the following |
5 | 5 |
# conditions are met: |
6 |
#
|
|
6 |
# |
|
7 | 7 |
# 1. Redistributions of source code must retain the above |
8 | 8 |
# copyright notice, this list of conditions and the following |
9 | 9 |
# disclaimer. |
10 |
#
|
|
10 |
# |
|
11 | 11 |
# 2. Redistributions in binary form must reproduce the above |
12 | 12 |
# copyright notice, this list of conditions and the following |
13 | 13 |
# disclaimer in the documentation and/or other materials |
14 | 14 |
# provided with the distribution. |
15 |
#
|
|
15 |
# |
|
16 | 16 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
17 | 17 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | 18 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
... | ... | |
25 | 25 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
26 | 26 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
27 | 27 |
# POSSIBILITY OF SUCH DAMAGE. |
28 |
#
|
|
28 |
# |
|
29 | 29 |
# The views and conclusions contained in the software and |
30 | 30 |
# documentation are those of the authors and should not be |
31 | 31 |
# interpreted as representing official policies, either expressed |
... | ... | |
130 | 130 |
d['created'] = util.isoformat(vm.created) |
131 | 131 |
d['flavorRef'] = vm.flavor.id |
132 | 132 |
d['imageRef'] = vm.imageid |
133 |
|
|
133 |
|
|
134 | 134 |
metadata = dict((m.meta_key, m.meta_value) for m in vm.metadata.all()) |
135 | 135 |
if metadata: |
136 | 136 |
d['metadata'] = {'values': metadata} |
... | ... | |
159 | 159 |
# unauthorized (401), |
160 | 160 |
# badRequest (400), |
161 | 161 |
# overLimit (413) |
162 |
|
|
162 |
|
|
163 | 163 |
log.debug('list_servers detail=%s', detail) |
164 | 164 |
user_vms = VirtualMachine.objects.filter(userid=request.user_uniq) |
165 | 165 |
since = util.isoparse(request.GET.get('changes-since')) |
166 |
|
|
166 |
|
|
167 | 167 |
if since: |
168 | 168 |
user_vms = user_vms.filter(updated__gte=since) |
169 | 169 |
if not user_vms: |
170 | 170 |
return HttpResponse(status=304) |
171 | 171 |
else: |
172 | 172 |
user_vms = user_vms.filter(deleted=False) |
173 |
|
|
173 |
|
|
174 | 174 |
servers = [vm_to_dict(server, detail) for server in user_vms] |
175 | 175 |
|
176 | 176 |
if request.serialization == 'xml': |
... | ... | |
197 | 197 |
|
198 | 198 |
req = util.get_request_dict(request) |
199 | 199 |
log.debug('create_server %s', req) |
200 |
|
|
200 |
|
|
201 | 201 |
try: |
202 | 202 |
server = req['server'] |
203 | 203 |
name = server['name'] |
... | ... | |
209 | 209 |
assert isinstance(personality, list) |
210 | 210 |
except (KeyError, AssertionError): |
211 | 211 |
raise faults.BadRequest("Malformed request") |
212 |
|
|
212 |
|
|
213 | 213 |
if len(personality) > settings.MAX_PERSONALITY: |
214 | 214 |
raise faults.OverLimit("Maximum number of personalities exceeded") |
215 |
|
|
215 |
|
|
216 | 216 |
for p in personality: |
217 | 217 |
# Verify that personalities are well-formed |
218 | 218 |
try: |
... | ... | |
228 | 228 |
raise faults.OverLimit("Maximum size of personality exceeded") |
229 | 229 |
except AssertionError: |
230 | 230 |
raise faults.BadRequest("Malformed personality in request") |
231 |
|
|
231 |
|
|
232 | 232 |
image = {} |
233 | 233 |
img = util.get_image(image_id, request.user_uniq) |
234 | 234 |
properties = img.get('properties', {}) |
... | ... | |
236 | 236 |
image['format'] = img['disk_format'] |
237 | 237 |
image['metadata'] = dict((key.upper(), val) \ |
238 | 238 |
for key, val in properties.items()) |
239 |
|
|
239 |
|
|
240 | 240 |
flavor = util.get_flavor(flavor_id) |
241 | 241 |
password = util.random_password() |
242 |
|
|
242 |
|
|
243 | 243 |
count = VirtualMachine.objects.filter(userid=request.user_uniq, |
244 | 244 |
deleted=False).count() |
245 |
if count >= settings.MAX_VMS_PER_USER: |
|
245 |
|
|
246 |
# get user limit |
|
247 |
vms_limit_for_user = \ |
|
248 |
settings.VMS_USER_QUOTA.get(request.user_uniq, |
|
249 |
settings.MAX_VMS_PER_USER) |
|
250 |
|
|
251 |
if count >= vms_limit_for_user: |
|
246 | 252 |
raise faults.OverLimit("Server count limit exceeded for your account.") |
247 |
|
|
253 |
|
|
248 | 254 |
# We must save the VM instance now, so that it gets a valid vm.backend_id. |
249 | 255 |
vm = VirtualMachine.objects.create( |
250 | 256 |
name=name, |
251 | 257 |
userid=request.user_uniq, |
252 | 258 |
imageid=image_id, |
253 | 259 |
flavor=flavor) |
254 |
|
|
260 |
|
|
255 | 261 |
try: |
256 | 262 |
create_instance(vm, flavor, image, password, personality) |
257 | 263 |
except GanetiApiError: |
... | ... | |
263 | 269 |
meta_key=key, |
264 | 270 |
meta_value=val, |
265 | 271 |
vm=vm) |
266 |
|
|
272 |
|
|
267 | 273 |
log.info('User %s created vm with %s cpus, %s ram and %s storage', |
268 | 274 |
request.user_uniq, flavor.cpu, flavor.ram, flavor.disk) |
269 |
|
|
275 |
|
|
270 | 276 |
server = vm_to_dict(vm, detail=True) |
271 | 277 |
server['status'] = 'BUILD' |
272 | 278 |
server['adminPass'] = password |
... | ... | |
282 | 288 |
# badRequest (400), |
283 | 289 |
# itemNotFound (404), |
284 | 290 |
# overLimit (413) |
285 |
|
|
291 |
|
|
286 | 292 |
log.debug('get_server_details %s', server_id) |
287 | 293 |
vm = util.get_vm(server_id, request.user_uniq) |
288 | 294 |
server = vm_to_dict(vm, detail=True) |
... | ... | |
303 | 309 |
|
304 | 310 |
req = util.get_request_dict(request) |
305 | 311 |
log.debug('update_server_name %s %s', server_id, req) |
306 |
|
|
312 |
|
|
307 | 313 |
try: |
308 | 314 |
name = req['server']['name'] |
309 | 315 |
except (TypeError, KeyError): |
... | ... | |
326 | 332 |
# unauthorized (401), |
327 | 333 |
# buildInProgress (409), |
328 | 334 |
# overLimit (413) |
329 |
|
|
335 |
|
|
330 | 336 |
log.debug('delete_server %s', server_id) |
331 | 337 |
vm = util.get_vm(server_id, request.user_uniq) |
332 | 338 |
delete_instance(vm) |
... | ... | |
361 | 367 |
# unauthorized (401), |
362 | 368 |
# badRequest (400), |
363 | 369 |
# overLimit (413) |
364 |
|
|
370 |
|
|
365 | 371 |
log.debug('list_addresses %s', server_id) |
366 | 372 |
vm = util.get_vm(server_id, request.user_uniq) |
367 | 373 |
addresses = [nic_to_dict(nic) for nic in vm.nics.all()] |
368 |
|
|
374 |
|
|
369 | 375 |
if request.serialization == 'xml': |
370 | 376 |
data = render_to_string('list_addresses.xml', {'addresses': addresses}) |
371 | 377 |
else: |
... | ... | |
383 | 389 |
# badRequest (400), |
384 | 390 |
# itemNotFound (404), |
385 | 391 |
# overLimit (413) |
386 |
|
|
392 |
|
|
387 | 393 |
log.debug('list_addresses_by_network %s %s', server_id, network_id) |
388 | 394 |
machine = util.get_vm(server_id, request.user_uniq) |
389 | 395 |
network = util.get_network(network_id, request.user_uniq) |
390 | 396 |
nic = util.get_nic(machine, network) |
391 | 397 |
address = nic_to_dict(nic) |
392 |
|
|
398 |
|
|
393 | 399 |
if request.serialization == 'xml': |
394 | 400 |
data = render_to_string('address.xml', {'address': address}) |
395 | 401 |
else: |
... | ... | |
406 | 412 |
# unauthorized (401), |
407 | 413 |
# badRequest (400), |
408 | 414 |
# overLimit (413) |
409 |
|
|
415 |
|
|
410 | 416 |
log.debug('list_server_metadata %s', server_id) |
411 | 417 |
vm = util.get_vm(server_id, request.user_uniq) |
412 | 418 |
metadata = dict((m.meta_key, m.meta_value) for m in vm.metadata.all()) |
... | ... | |
423 | 429 |
# buildInProgress (409), |
424 | 430 |
# badMediaType(415), |
425 | 431 |
# overLimit (413) |
426 |
|
|
432 |
|
|
427 | 433 |
req = util.get_request_dict(request) |
428 | 434 |
log.debug('update_server_metadata %s %s', server_id, req) |
429 | 435 |
vm = util.get_vm(server_id, request.user_uniq) |
... | ... | |
432 | 438 |
assert isinstance(metadata, dict) |
433 | 439 |
except (KeyError, AssertionError): |
434 | 440 |
raise faults.BadRequest("Malformed request") |
435 |
|
|
441 |
|
|
436 | 442 |
for key, val in metadata.items(): |
437 | 443 |
meta, created = vm.metadata.get_or_create(meta_key=key) |
438 | 444 |
meta.meta_value = val |
439 | 445 |
meta.save() |
440 |
|
|
446 |
|
|
441 | 447 |
vm.save() |
442 | 448 |
vm_meta = dict((m.meta_key, m.meta_value) for m in vm.metadata.all()) |
443 | 449 |
return util.render_metadata(request, vm_meta, status=201) |
... | ... | |
452 | 458 |
# itemNotFound (404), |
453 | 459 |
# badRequest (400), |
454 | 460 |
# overLimit (413) |
455 |
|
|
461 |
|
|
456 | 462 |
log.debug('get_server_metadata_item %s %s', server_id, key) |
457 | 463 |
vm = util.get_vm(server_id, request.user_uniq) |
458 | 464 |
meta = util.get_vm_meta(vm, key) |
... | ... | |
471 | 477 |
# buildInProgress (409), |
472 | 478 |
# badMediaType(415), |
473 | 479 |
# overLimit (413) |
474 |
|
|
480 |
|
|
475 | 481 |
req = util.get_request_dict(request) |
476 | 482 |
log.debug('create_server_metadata_item %s %s %s', server_id, key, req) |
477 | 483 |
vm = util.get_vm(server_id, request.user_uniq) |
... | ... | |
482 | 488 |
assert key in metadict |
483 | 489 |
except (KeyError, AssertionError): |
484 | 490 |
raise faults.BadRequest("Malformed request") |
485 |
|
|
491 |
|
|
486 | 492 |
meta, created = VirtualMachineMetadata.objects.get_or_create( |
487 | 493 |
meta_key=key, |
488 | 494 |
vm=vm) |
489 |
|
|
495 |
|
|
490 | 496 |
meta.meta_value = metadict[key] |
491 | 497 |
meta.save() |
492 | 498 |
vm.save() |
... | ... | |
505 | 511 |
# buildInProgress (409), |
506 | 512 |
# badMediaType(415), |
507 | 513 |
# overLimit (413), |
508 |
|
|
514 |
|
|
509 | 515 |
log.debug('delete_server_metadata_item %s %s', server_id, key) |
510 | 516 |
vm = util.get_vm(server_id, request.user_uniq) |
511 | 517 |
meta = util.get_vm_meta(vm, key) |
... | ... | |
523 | 529 |
# badRequest (400), |
524 | 530 |
# itemNotFound (404), |
525 | 531 |
# overLimit (413) |
526 |
|
|
532 |
|
|
527 | 533 |
log.debug('server_stats %s', server_id) |
528 | 534 |
vm = util.get_vm(server_id, request.user_uniq) |
529 | 535 |
#secret = util.encrypt(vm.backend_id) |
530 | 536 |
secret = vm.backend_id # XXX disable backend id encryption |
531 |
|
|
537 |
|
|
532 | 538 |
stats = { |
533 | 539 |
'serverRef': vm.id, |
534 | 540 |
'refresh': settings.STATS_REFRESH_PERIOD, |
... | ... | |
536 | 542 |
'cpuTimeSeries': settings.CPU_TIMESERIES_GRAPH_URL % secret, |
537 | 543 |
'netBar': settings.NET_BAR_GRAPH_URL % secret, |
538 | 544 |
'netTimeSeries': settings.NET_TIMESERIES_GRAPH_URL % secret} |
539 |
|
|
545 |
|
|
540 | 546 |
if request.serialization == 'xml': |
541 | 547 |
data = render_to_string('server_stats.xml', stats) |
542 | 548 |
else: |
Also available in: Unified diff