1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
3
# Copyright 2011 OpenStack LLC.
6
# Licensed under the Apache License, Version 2.0 (the "License"); you may
7
# not use this file except in compliance with the License. You may obtain
8
# a copy of the License at
10
# http://www.apache.org/licenses/LICENSE-2.0
12
# Unless required by applicable law or agreed to in writing, software
13
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
# License for the specific language governing permissions and limitations
20
from cinder.api import common
21
from cinder.api.openstack import wsgi
22
from cinder import exception
23
from cinder import volume
27
class Controller(object):
28
""" The volume metadata API controller for the OpenStack API """
31
self.volume_api = volume.API()
32
super(Controller, self).__init__()
34
def _get_metadata(self, context, volume_id):
36
volume = self.volume_api.get(context, volume_id)
37
meta = self.volume_api.get_volume_metadata(context, volume)
38
except exception.VolumeNotFound:
39
msg = _('volume does not exist')
40
raise exc.HTTPNotFound(explanation=msg)
43
@wsgi.serializers(xml=common.MetadataTemplate)
44
def index(self, req, volume_id):
45
""" Returns the list of metadata for a given volume"""
46
context = req.environ['cinder.context']
47
return {'metadata': self._get_metadata(context, volume_id)}
49
@wsgi.serializers(xml=common.MetadataTemplate)
50
@wsgi.deserializers(xml=common.MetadataDeserializer)
51
def create(self, req, volume_id, body):
53
metadata = body['metadata']
54
except (KeyError, TypeError):
55
msg = _("Malformed request body")
56
raise exc.HTTPBadRequest(explanation=msg)
58
context = req.environ['cinder.context']
60
new_metadata = self._update_volume_metadata(context,
65
return {'metadata': new_metadata}
67
@wsgi.serializers(xml=common.MetaItemTemplate)
68
@wsgi.deserializers(xml=common.MetaItemDeserializer)
69
def update(self, req, volume_id, id, body):
71
meta_item = body['meta']
72
except (TypeError, KeyError):
73
expl = _('Malformed request body')
74
raise exc.HTTPBadRequest(explanation=expl)
76
if id not in meta_item:
77
expl = _('Request body and URI mismatch')
78
raise exc.HTTPBadRequest(explanation=expl)
80
if len(meta_item) > 1:
81
expl = _('Request body contains too many items')
82
raise exc.HTTPBadRequest(explanation=expl)
84
context = req.environ['cinder.context']
85
self._update_volume_metadata(context,
90
return {'meta': meta_item}
92
@wsgi.serializers(xml=common.MetadataTemplate)
93
@wsgi.deserializers(xml=common.MetadataDeserializer)
94
def update_all(self, req, volume_id, body):
96
metadata = body['metadata']
97
except (TypeError, KeyError):
98
expl = _('Malformed request body')
99
raise exc.HTTPBadRequest(explanation=expl)
101
context = req.environ['cinder.context']
102
new_metadata = self._update_volume_metadata(context,
107
return {'metadata': new_metadata}
109
def _update_volume_metadata(self, context,
113
volume = self.volume_api.get(context, volume_id)
114
return self.volume_api.update_volume_metadata(context,
118
except exception.VolumeNotFound:
119
msg = _('volume does not exist')
120
raise exc.HTTPNotFound(explanation=msg)
122
except (ValueError, AttributeError):
123
msg = _("Malformed request body")
124
raise exc.HTTPBadRequest(explanation=msg)
126
except exception.InvalidVolumeMetadata as error:
127
raise exc.HTTPBadRequest(explanation=unicode(error))
129
except exception.InvalidVolumeMetadataSize as error:
130
raise exc.HTTPRequestEntityTooLarge(explanation=unicode(error))
132
@wsgi.serializers(xml=common.MetaItemTemplate)
133
def show(self, req, volume_id, id):
134
""" Return a single metadata item """
135
context = req.environ['cinder.context']
136
data = self._get_metadata(context, volume_id)
139
return {'meta': {id: data[id]}}
141
msg = _("Metadata item was not found")
142
raise exc.HTTPNotFound(explanation=msg)
144
def delete(self, req, volume_id, id):
145
""" Deletes an existing metadata """
146
context = req.environ['cinder.context']
148
metadata = self._get_metadata(context, volume_id)
150
if id not in metadata:
151
msg = _("Metadata item was not found")
152
raise exc.HTTPNotFound(explanation=msg)
155
volume = self.volume_api.get(context, volume_id)
156
self.volume_api.delete_volume_metadata(context, volume, id)
157
except exception.VolumeNotFound:
158
msg = _('volume does not exist')
159
raise exc.HTTPNotFound(explanation=msg)
160
return webob.Response(status_int=200)
163
def create_resource():
164
return wsgi.Resource(Controller())