Commit 0aab33af authored by Christos Stavrakakis's avatar Christos Stavrakakis
Browse files

cyclades: Various fixes to volume views

Fix a number of views in the volume views. Also use the 'get_attribute'
helper function to parse the request body.
parent 5c65c0d1
......@@ -17,6 +17,7 @@ from itertools import ifilter
from logging import getLogger
from django.http import HttpResponse
from django.utils import simplejson as json
from django.utils.encoding import smart_unicode
from dateutil.parser import parse as date_parse
......@@ -34,7 +35,7 @@ def display_null_field(field):
if field is None:
return None
return smart_unicode(field)
def volume_to_dict(volume, detail=True):
......@@ -84,48 +85,44 @@ def create_volume(request):
log.debug("create_volume %s", req)
user_id = request.user_uniq
new_volume = req.get("volume")
if new_volume is None:
raise faults.BadRequest("Missing 'volume' attribute.")
vol_dict = utils.get_attribute(req, "volume", attr_type=dict,
name = utils.get_attribute(vol_dict, "display_name",
attr_type=basestring, required=True)
# Get and validate 'name' parameter
# TODO: auto generate name
name = new_volume.get("display_name", None)
if name is None:
raise faults.BadRequest("Volume 'name' is needed.")
# Get and validate 'size' parameter
size = new_volume.get("size")
if size is None:
raise faults.BadRequest("Volume 'size' is needed.")
size = utils.get_attribute(vol_dict, "size",
attr_type=(basestring, int), required=True)
size = int(size)
if size <= 0:
raise ValueError
except ValueError:
except (TypeError, ValueError):
raise faults.BadRequest("Volume 'size' needs to be a positive integer"
" value. '%s' cannot be accepted." % size)
volume_type_id = new_volume.get("volume_type", None)
# Optional parameters
description = new_volume.get("display_description", "")
metadata = new_volume.get("metadata", {})
if not isinstance(metadata, dict):
msg = "Volume 'metadata' needs to be a dictionary of key-value pairs."\
" '%s' can not be accepted." % metadata
raise faults.BadRequest(msg)
volume_type_id = utils.get_attribute(vol_dict, "volume_type",
attr_type=(basestring, int),
description = utils.get_attribute(vol_dict, "display_description",
attr_type=basestring, required=False,
metadata = utils.get_attribute(vol_dict, "metadata", attr_type=dict,
required=False, default={})
# Id of the volume to clone from
source_volume_id = new_volume.get("source_volid")
source_volume_id = utils.get_attribute(vol_dict, "source_volid",
# Id of the snapshot to create the volume from
source_snapshot_id = new_volume.get("snapshot_id")
source_snapshot_id = utils.get_attribute(vol_dict, "snapshot_id",
# Reference to an Image stored in Glance
source_image_id = new_volume.get("imageRef")
# TODO: Check that not all of them are used
source_image_id = utils.get_attribute(vol_dict, "imageRef", required=False)
server_id = new_volume.get("server_id")
if server_id is None:
raise faults.BadRequest("Attribute 'server_id' is mandatory")
# Get server ID to attach the volume. Since we currently do not supported
# detached volumes, server_id attribute is mandatory.
server_id = utils.get_attribute(vol_dict, "server_id", required=True)
# Create the volume
volume = volumes.create(user_id=user_id, size=size, name=name,
......@@ -134,11 +131,12 @@ def create_volume(request):
metadata=metadata, server_id=server_id)
# Render response
data = json.dumps(dict(volume=volume_to_dict(volume, detail=False)))
return HttpResponse(data, status=200)
return HttpResponse(data, status=202)
@api.api_method(http_method="GET", user_required=True, logger=log)
......@@ -170,7 +168,7 @@ def delete_volume(request, volume_id):
def get_volume(request, volume_id):
log.debug('get_volume volume_id: %s', volume_id)
volume = util.get.volume(request.user_uniq, volume_id)
volume = util.get_volume(request.user_uniq, volume_id)
data = json.dumps({'volume': volume_to_dict(volume, detail=True)})
return HttpResponse(data, content_type="application/json", status=200)
......@@ -181,17 +179,23 @@ def update_volume(request, volume_id):
req = utils.get_json_body(request)
log.debug('update_volume volume_id: %s, request: %s', volume_id, req)
volume = util.get.volume(request.user_uniq, volume_id, for_update=True)
new_name = req.get("display_name")
description = req.get("display_description")
delete_on_termination = req.get("delete_on_termination")
volume = util.get_volume(request.user_uniq, volume_id, for_update=True)
if new_name is None and description is None and\
vol_req = utils.get_attribute(req, "volume", attr_type=dict,
name = utils.get_attribute(vol_req, "display_name", required=False)
description = utils.get_attribute(vol_req, "display_description",
delete_on_termination = utils.get_attribute(vol_req,
if name is None and description is None and\
delete_on_termination is None:
raise faults.BadRequest("Nothing to update.")
volume = volumes.update(volume, new_name, description,
volume = volumes.update(volume, name, description,
data = json.dumps({'volume': volume_to_dict(volume, detail=True)})
......@@ -201,13 +205,13 @@ def update_volume(request, volume_id):
def snapshot_to_dict(snapshot, detail=True):
owner = snapshot['owner']
status = snapshot['status']
progress = "%s%%" % 100 if status == "ACTIVE" else 0
progress = "%s%%" % 100 if status == "AVAILABLE" else 0
data = {
"id": snapshot["id"],
"size": int(snapshot["size"]) >> 30, # gigabytes
"display_name": snapshot["name"],
"display_description": snapshot["description"],
"display_description": snapshot.get("description", ""),
"status": status,
"user_id": owner,
"tenant_id": owner,
......@@ -229,33 +233,24 @@ def create_snapshot(request):
log.debug("create_snapshot %s", req)
user_id = request.user_uniq
new_snapshot = req.get("snapshot")
if new_snapshot is None:
raise faults.BadRequest("Missing 'snapshot' attribute.")
# Get and validate 'name' parameter
# TODO: auto generate name
metadata = new_snapshot.get("metadata", {})
if not isinstance(metadata, dict):
msg = "Snapshot 'metadata' needs to be a dictionary of key-value"\
" pairs. '%s' can not be accepted." % metadata
raise faults.BadRequest(msg)
volume_id = new_snapshot.get("volume_id", None)
if volume_id is None:
raise faults.BadRequest("'volume_id' attribute is missing.")
snap_dict = utils.get_attribute(req, "snapshot", required=True,
volume_id = utils.get_attribute(snap_dict, "volume_id", required=True)
volume = util.get_volume(user_id, volume_id, for_update=True,
name = new_snapshot.get("display_name", None)
if name is None:
raise faults.BadRequest("Snapshot 'name' is required")
description = new_snapshot.get("display_description", "")
metadata = utils.get_attribute(snap_dict, "metadata", required=False,
attr_type=dict, default={})
name = utils.get_attribute(snap_dict, "display_name", required=False,
default="Snapshot of volume '%s'" % volume_id)
description = utils.get_attribute(snap_dict, "display_description",
attr_type=basestring, default="")
# TODO: What to do with force ?
force = new_snapshot.get("force", False)
if not isinstance(force, bool):
raise faults.BadRequest("Invalid value for 'force' attribute.")
force = utils.get_attribute(req, "force", required=False, attr_type=bool,
snapshot = snapshots.create(user_id=user_id, volume=volume, name=name,
description=description, metadata=metadata,
......@@ -313,8 +308,13 @@ def update_snapshot(request, snapshot_id):
log.debug('update_snapshot snapshot_id: %s, request: %s', snapshot_id, req)
snapshot = util.get_snapshot(request.user_uniq, snapshot_id)
new_name = req.get("display_name")
new_description = req.get("display_description")
snap_dict = utils.get_attribute(req, "snapshot", attr_type=dict,
new_name = utils.get_attribute(snap_dict, "display_name", required=False,
new_description = utils.get_attribute(snap_dict, "display_description",
required=False, attr_type=basestring)
if new_name is None and new_description is None:
raise faults.BadRequest("Nothing to update.")
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment