1
# Copyright 2011 Justin Santa Barbara
4
# Licensed under the Apache License, Version 2.0 (the "License"); you may
5
# not use this file except in compliance with the License. You may obtain
6
# a copy of the License at
8
# http://www.apache.org/licenses/LICENSE-2.0
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
# License for the specific language governing permissions and limitations
16
"""The volumes snapshots api."""
21
from cinder.api.openstack import common
22
from cinder.api.openstack import wsgi
23
from cinder.api.openstack import xmlutil
24
from cinder import exception
25
from cinder import flags
26
from cinder import log as logging
27
from cinder import volume
30
LOG = logging.getLogger(__name__)
36
def _translate_snapshot_detail_view(context, vol):
37
"""Maps keys for snapshots details view."""
39
d = _translate_snapshot_summary_view(context, vol)
41
# NOTE(gagupta): No additional data / lookups at the moment
45
def _translate_snapshot_summary_view(context, vol):
46
"""Maps keys for snapshots summary view."""
49
# TODO(bcwaldon): remove str cast once we use uuids
50
d['id'] = str(vol['id'])
51
d['volume_id'] = str(vol['volume_id'])
52
d['status'] = vol['status']
53
# NOTE(gagupta): We map volume_size as the snapshot size
54
d['size'] = vol['volume_size']
55
d['created_at'] = vol['created_at']
56
d['display_name'] = vol['display_name']
57
d['display_description'] = vol['display_description']
61
def make_snapshot(elem):
65
elem.set('created_at')
66
elem.set('display_name')
67
elem.set('display_description')
71
class SnapshotTemplate(xmlutil.TemplateBuilder):
73
root = xmlutil.TemplateElement('snapshot', selector='snapshot')
75
return xmlutil.MasterTemplate(root, 1)
78
class SnapshotsTemplate(xmlutil.TemplateBuilder):
80
root = xmlutil.TemplateElement('snapshots')
81
elem = xmlutil.SubTemplateElement(root, 'snapshot',
84
return xmlutil.MasterTemplate(root, 1)
87
class SnapshotsController(object):
88
"""The Volumes API controller for the OpenStack API."""
91
self.volume_api = volume.API()
92
super(SnapshotsController, self).__init__()
94
@wsgi.serializers(xml=SnapshotTemplate)
95
def show(self, req, id):
96
"""Return data about the given snapshot."""
97
context = req.environ['cinder.context']
100
vol = self.volume_api.get_snapshot(context, id)
101
except exception.NotFound:
102
raise exc.HTTPNotFound()
104
return {'snapshot': _translate_snapshot_detail_view(context, vol)}
106
def delete(self, req, id):
107
"""Delete a snapshot."""
108
context = req.environ['cinder.context']
110
LOG.audit(_("Delete snapshot with id: %s"), id, context=context)
113
snapshot = self.volume_api.get_snapshot(context, id)
114
self.volume_api.delete_snapshot(context, snapshot)
115
except exception.NotFound:
116
raise exc.HTTPNotFound()
117
return webob.Response(status_int=202)
119
@wsgi.serializers(xml=SnapshotsTemplate)
120
def index(self, req):
121
"""Returns a summary list of snapshots."""
122
return self._items(req, entity_maker=_translate_snapshot_summary_view)
124
@wsgi.serializers(xml=SnapshotsTemplate)
125
def detail(self, req):
126
"""Returns a detailed list of snapshots."""
127
return self._items(req, entity_maker=_translate_snapshot_detail_view)
129
def _items(self, req, entity_maker):
130
"""Returns a list of snapshots, transformed through entity_maker."""
131
context = req.environ['cinder.context']
133
snapshots = self.volume_api.get_all_snapshots(context)
134
limited_list = common.limited(snapshots, req)
135
res = [entity_maker(context, snapshot) for snapshot in limited_list]
136
return {'snapshots': res}
138
@wsgi.serializers(xml=SnapshotTemplate)
139
def create(self, req, body):
140
"""Creates a new snapshot."""
141
context = req.environ['cinder.context']
144
return exc.HTTPUnprocessableEntity()
146
snapshot = body['snapshot']
147
volume_id = snapshot['volume_id']
148
volume = self.volume_api.get(context, volume_id)
149
force = snapshot.get('force', False)
150
msg = _("Create snapshot from volume %s")
151
LOG.audit(msg, volume_id, context=context)
154
new_snapshot = self.volume_api.create_snapshot_force(context,
156
snapshot.get('display_name'),
157
snapshot.get('display_description'))
159
new_snapshot = self.volume_api.create_snapshot(context,
161
snapshot.get('display_name'),
162
snapshot.get('display_description'))
164
retval = _translate_snapshot_detail_view(context, new_snapshot)
166
return {'snapshot': retval}
169
def create_resource():
170
return wsgi.Resource(SnapshotsController())