Revision bd40abfa snf-cyclades-app/synnefo/api/util.py
b/snf-cyclades-app/synnefo/api/util.py | ||
---|---|---|
56 | 56 |
from django.utils.cache import add_never_cache_headers |
57 | 57 |
from django.db.models import Q |
58 | 58 |
|
59 |
from synnefo.api.faults import (Fault, BadRequest, BuildInProgress, |
|
60 |
ItemNotFound, ServiceUnavailable, Unauthorized, |
|
61 |
BadMediaType, Forbidden, OverLimit) |
|
59 |
from snf_django.lib.api import faults |
|
62 | 60 |
from synnefo.db.models import (Flavor, VirtualMachine, VirtualMachineMetadata, |
63 | 61 |
Network, BackendNetwork, NetworkInterface, |
64 | 62 |
BridgePoolTable, MacPrefixPoolTable) |
... | ... | |
99 | 97 |
since = dateutil.parser.parse(s) |
100 | 98 |
utc_since = since.astimezone(UTC()).replace(tzinfo=None) |
101 | 99 |
except ValueError: |
102 |
raise BadRequest('Invalid changes-since parameter.') |
|
100 |
raise faults.BadRequest('Invalid changes-since parameter.')
|
|
103 | 101 |
|
104 | 102 |
now = datetime.datetime.now() |
105 | 103 |
if utc_since > now: |
106 |
raise BadRequest('changes-since value set in the future.') |
|
104 |
raise faults.BadRequest('changes-since value set in the future.')
|
|
107 | 105 |
|
108 | 106 |
if now - utc_since > timedelta(seconds=settings.POLL_LIMIT): |
109 |
raise BadRequest('Too old changes-since value.') |
|
107 |
raise faults.BadRequest('Too old changes-since value.')
|
|
110 | 108 |
|
111 | 109 |
return utc_since |
112 | 110 |
|
... | ... | |
171 | 169 |
if non_deleted and vm.deleted: |
172 | 170 |
raise VirtualMachine.DeletedError |
173 | 171 |
if non_suspended and vm.suspended: |
174 |
raise Forbidden("Administratively Suspended VM") |
|
172 |
raise faults.Forbidden("Administratively Suspended VM")
|
|
175 | 173 |
return vm |
176 | 174 |
except ValueError: |
177 |
raise BadRequest('Invalid server ID.') |
|
175 |
raise faults.BadRequest('Invalid server ID.')
|
|
178 | 176 |
except VirtualMachine.DoesNotExist: |
179 |
raise ItemNotFound('Server not found.') |
|
177 |
raise faults.ItemNotFound('Server not found.')
|
|
180 | 178 |
|
181 | 179 |
|
182 | 180 |
def get_vm_meta(vm, key): |
... | ... | |
185 | 183 |
try: |
186 | 184 |
return VirtualMachineMetadata.objects.get(meta_key=key, vm=vm) |
187 | 185 |
except VirtualMachineMetadata.DoesNotExist: |
188 |
raise ItemNotFound('Metadata key not found.') |
|
186 |
raise faults.ItemNotFound('Metadata key not found.')
|
|
189 | 187 |
|
190 | 188 |
|
191 | 189 |
def get_image(image_id, user_id): |
... | ... | |
195 | 193 |
try: |
196 | 194 |
image = backend.get_image(image_id) |
197 | 195 |
if not image: |
198 |
raise ItemNotFound('Image not found.') |
|
196 |
raise faults.ItemNotFound('Image not found.')
|
|
199 | 197 |
return image |
200 | 198 |
finally: |
201 | 199 |
backend.close() |
... | ... | |
224 | 222 |
else: |
225 | 223 |
return Flavor.objects.get(id=flavor_id, deleted=include_deleted) |
226 | 224 |
except (ValueError, Flavor.DoesNotExist): |
227 |
raise ItemNotFound('Flavor not found.') |
|
225 |
raise faults.ItemNotFound('Flavor not found.')
|
|
228 | 226 |
|
229 | 227 |
|
230 | 228 |
def get_network(network_id, user_id, for_update=False): |
... | ... | |
237 | 235 |
objects = objects.select_for_update() |
238 | 236 |
return objects.get(Q(userid=user_id) | Q(public=True), id=network_id) |
239 | 237 |
except (ValueError, Network.DoesNotExist): |
240 |
raise ItemNotFound('Network not found.') |
|
238 |
raise faults.ItemNotFound('Network not found.')
|
|
241 | 239 |
|
242 | 240 |
|
243 | 241 |
def validate_network_params(subnet, gateway=None, subnet6=None, gateway6=None): |
... | ... | |
245 | 243 |
# Use strict option to not all subnets with host bits set |
246 | 244 |
network = ipaddr.IPv4Network(subnet, strict=True) |
247 | 245 |
except ValueError: |
248 |
raise BadRequest("Invalid network IPv4 subnet") |
|
246 |
raise faults.BadRequest("Invalid network IPv4 subnet")
|
|
249 | 247 |
|
250 | 248 |
# Check that network size is allowed! |
251 | 249 |
if not validate_network_size(network.prefixlen): |
252 |
raise OverLimit(message="Unsupported network size", |
|
250 |
raise faults.OverLimit(message="Unsupported network size",
|
|
253 | 251 |
details="Network mask must be in range (%s, 29]" % |
254 | 252 |
MAX_CIDR_BLOCK) |
255 | 253 |
|
... | ... | |
258 | 256 |
try: |
259 | 257 |
gateway = ipaddr.IPv4Address(gateway) |
260 | 258 |
except ValueError: |
261 |
raise BadRequest("Invalid network IPv4 gateway") |
|
259 |
raise faults.BadRequest("Invalid network IPv4 gateway")
|
|
262 | 260 |
if not gateway in network: |
263 |
raise BadRequest("Invalid network IPv4 gateway") |
|
261 |
raise faults.BadRequest("Invalid network IPv4 gateway")
|
|
264 | 262 |
|
265 | 263 |
if subnet6: |
266 | 264 |
try: |
267 | 265 |
# Use strict option to not all subnets with host bits set |
268 | 266 |
network6 = ipaddr.IPv6Network(subnet6, strict=True) |
269 | 267 |
except ValueError: |
270 |
raise BadRequest("Invalid network IPv6 subnet") |
|
268 |
raise faults.BadRequest("Invalid network IPv6 subnet")
|
|
271 | 269 |
if gateway6: |
272 | 270 |
try: |
273 | 271 |
gateway6 = ipaddr.IPv6Address(gateway6) |
274 | 272 |
except ValueError: |
275 |
raise BadRequest("Invalid network IPv6 gateway") |
|
273 |
raise faults.BadRequest("Invalid network IPv6 gateway")
|
|
276 | 274 |
if not gateway6 in network6: |
277 |
raise BadRequest("Invalid network IPv6 gateway") |
|
275 |
raise faults.BadRequest("Invalid network IPv6 gateway")
|
|
278 | 276 |
|
279 | 277 |
|
280 | 278 |
def validate_network_size(cidr_block): |
... | ... | |
311 | 309 |
break |
312 | 310 |
if address is None: |
313 | 311 |
log.error("Public networks of backend %s are full", backend) |
314 |
raise OverLimit("Can not allocate IP for new machine." |
|
312 |
raise faults.OverLimit("Can not allocate IP for new machine."
|
|
315 | 313 |
" Public networks are full.") |
316 | 314 |
return (network, address) |
317 | 315 |
|
... | ... | |
346 | 344 |
try: |
347 | 345 |
return NetworkInterface.objects.get(machine=machine, network=network) |
348 | 346 |
except NetworkInterface.DoesNotExist: |
349 |
raise ItemNotFound('Server not connected to this network.') |
|
347 |
raise faults.ItemNotFound('Server not connected to this network.')
|
|
350 | 348 |
|
351 | 349 |
|
352 | 350 |
def get_nic_from_index(vm, nic_index): |
... | ... | |
356 | 354 |
matching_nics = vm.nics.filter(index=nic_index) |
357 | 355 |
matching_nics_len = len(matching_nics) |
358 | 356 |
if matching_nics_len < 1: |
359 |
raise ItemNotFound('NIC not found on VM') |
|
357 |
raise faults.ItemNotFound('NIC not found on VM')
|
|
360 | 358 |
elif matching_nics_len > 1: |
361 |
raise BadMediaType('NIC index conflict on VM') |
|
359 |
raise faults.BadMediaType('NIC index conflict on VM')
|
|
362 | 360 |
nic = matching_nics[0] |
363 | 361 |
return nic |
364 | 362 |
|
... | ... | |
371 | 369 |
try: |
372 | 370 |
return json.loads(data) |
373 | 371 |
except ValueError: |
374 |
raise BadRequest('Invalid JSON data.') |
|
372 |
raise faults.BadRequest('Invalid JSON data.')
|
|
375 | 373 |
else: |
376 |
raise BadRequest('Unsupported Content-Type.') |
|
374 |
raise faults.BadRequest('Unsupported Content-Type.')
|
|
377 | 375 |
|
378 | 376 |
|
379 | 377 |
def update_response_headers(request, response): |
... | ... | |
465 | 463 |
atom_allowed) |
466 | 464 |
get_user(request, settings.ASTAKOS_URL) |
467 | 465 |
if not request.user_uniq: |
468 |
raise Unauthorized('No user found.') |
|
466 |
raise faults.Unauthorized('No user found.')
|
|
469 | 467 |
if http_method and request.method != http_method: |
470 |
raise BadRequest('Method not allowed.') |
|
468 |
raise faults.BadRequest('Method not allowed.')
|
|
471 | 469 |
|
472 | 470 |
resp = func(request, *args, **kwargs) |
473 | 471 |
update_response_headers(request, resp) |
474 | 472 |
return resp |
475 | 473 |
except VirtualMachine.DeletedError: |
476 |
fault = BadRequest('Server has been deleted.') |
|
474 |
fault = faults.BadRequest('Server has been deleted.')
|
|
477 | 475 |
return render_fault(request, fault) |
478 | 476 |
except Network.DeletedError: |
479 |
fault = BadRequest('Network has been deleted.') |
|
477 |
fault = faults.BadRequest('Network has been deleted.')
|
|
480 | 478 |
return render_fault(request, fault) |
481 | 479 |
except VirtualMachine.BuildingError: |
482 |
fault = BuildInProgress('Server is being built.') |
|
480 |
fault = faults.BuildInProgress('Server is being built.')
|
|
483 | 481 |
return render_fault(request, fault) |
484 | 482 |
except NotAllowedError: |
485 | 483 |
# Image Backend Unathorized |
486 |
fault = Forbidden('Request not allowed.') |
|
484 |
fault = faults.Forbidden('Request not allowed.')
|
|
487 | 485 |
return render_fault(request, fault) |
488 |
except Fault, fault: |
|
486 |
except faults.Fault, fault:
|
|
489 | 487 |
if fault.code >= 500: |
490 | 488 |
log.exception('API fault') |
491 | 489 |
return render_fault(request, fault) |
492 | 490 |
except BaseException: |
493 | 491 |
log.exception('Unexpected error') |
494 |
fault = ServiceUnavailable('Unexpected error.') |
|
492 |
fault = faults.ServiceUnavailable('Unexpected error.')
|
|
495 | 493 |
return render_fault(request, fault) |
496 | 494 |
return wrapper |
497 | 495 |
return decorator |
... | ... | |
504 | 502 |
def verify_personality(personality): |
505 | 503 |
"""Verify that a a list of personalities is well formed""" |
506 | 504 |
if len(personality) > settings.MAX_PERSONALITY: |
507 |
raise OverLimit("Maximum number of personalities" |
|
505 |
raise faults.OverLimit("Maximum number of personalities"
|
|
508 | 506 |
" exceeded") |
509 | 507 |
for p in personality: |
510 | 508 |
# Verify that personalities are well-formed |
... | ... | |
516 | 514 |
contents = p['contents'] |
517 | 515 |
if len(contents) > settings.MAX_PERSONALITY_SIZE: |
518 | 516 |
# No need to decode if contents already exceed limit |
519 |
raise OverLimit("Maximum size of personality exceeded") |
|
517 |
raise faults.OverLimit("Maximum size of personality exceeded")
|
|
520 | 518 |
if len(b64decode(contents)) > settings.MAX_PERSONALITY_SIZE: |
521 |
raise OverLimit("Maximum size of personality exceeded") |
|
519 |
raise faults.OverLimit("Maximum size of personality exceeded")
|
|
522 | 520 |
except AssertionError: |
523 |
raise BadRequest("Malformed personality in request") |
|
521 |
raise faults.BadRequest("Malformed personality in request")
|
|
524 | 522 |
|
525 | 523 |
|
526 | 524 |
def get_flavor_provider(flavor): |
... | ... | |
548 | 546 |
try: |
549 | 547 |
flavor = Network.FLAVORS[flavor] |
550 | 548 |
except KeyError: |
551 |
raise BadRequest("Unknown network flavor") |
|
549 |
raise faults.BadRequest("Unknown network flavor")
|
|
552 | 550 |
|
553 | 551 |
mode = flavor.get("mode") |
554 | 552 |
|
Also available in: Unified diff