44
43
DEFAULT_QUOTA_NAME = 'default'
46
VERSIONS = base.APIVersionManager("volume", preferred_version=1)
49
from cinderclient.v1 import client as cinder_client_v1
50
VERSIONS.load_supported_version(1, {"client": cinder_client_v1,
56
from cinderclient.v2 import client as cinder_client_v2
57
VERSIONS.load_supported_version(2, {"client": cinder_client_v2,
63
class BaseCinderAPIResourceWrapper(base.APIResourceWrapper):
67
# If a volume doesn't have a name, use its id.
68
return (getattr(self._apiresource, 'name', None) or
69
getattr(self._apiresource, 'display_name', None) or
70
getattr(self._apiresource, 'id', None))
73
def description(self):
74
return (getattr(self._apiresource, 'description', None) or
75
getattr(self._apiresource, 'display_description', None))
78
class Volume(BaseCinderAPIResourceWrapper):
80
_attrs = ['id', 'name', 'description', 'size', 'status', 'created_at',
81
'volume_type', 'availability_zone', 'imageRef', 'bootable'
82
'snapshot_id', 'source_volid', 'attachments', 'tenant_name',
83
'os-vol-host-attr:host', 'os-vol-tenant-attr:tenant_id',
87
class VolumeSnapshot(BaseCinderAPIResourceWrapper):
89
_attrs = ['id', 'name', 'description', 'size', 'status',
90
'created_at', 'volume_id',
91
'os-extended-snapshot-attributes:project_id']
47
94
def cinderclient(request):
95
api_version = VERSIONS.get_active_version()
48
97
insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
49
98
cacert = getattr(settings, 'OPENSTACK_SSL_CACERT', None)
52
cinder_url = base.url_for(request, 'volume')
101
# The cinder client assumes that the v2 endpoint type will be
102
# 'volumev2'. However it also allows 'volume' type as a
103
# fallback if the requested version is 2 and there is no
104
# 'volumev2' endpoint.
105
if api_version['version'] == 2:
107
cinder_url = base.url_for(request, 'volumev2')
108
except exceptions.ServiceCatalogException:
109
LOG.warning("Cinder v2 requested but no 'volumev2' service "
110
"type available in Keystone catalog. Falling back "
113
cinder_url = base.url_for(request, 'volume')
53
114
except exceptions.ServiceCatalogException:
54
115
LOG.debug('no volume service configured.')
56
117
LOG.debug('cinderclient connection created using token "%s" and url "%s"' %
57
118
(request.user.token.id, cinder_url))
58
c = cinder_client.Client(request.user.username,
59
request.user.token.id,
60
project_id=request.user.tenant_id,
64
http_log_debug=settings.DEBUG)
119
c = api_version['client'].Client(request.user.username,
120
request.user.token.id,
121
project_id=request.user.tenant_id,
125
http_log_debug=settings.DEBUG)
65
126
c.client.auth_token = request.user.token.id
66
127
c.client.management_url = cinder_url
131
def _replace_v2_parameters(data):
132
if VERSIONS.active < 2:
133
data['display_name'] = data['name']
134
data['display_description'] = data['description']
136
del data['description']
70
140
def volume_list(request, search_opts=None):
71
141
"""To see all volumes in the cloud as an admin you can pass in a special
72
142
search option: {'all_tenants': 1}
89
159
# the lack a server_id property; to work around that we'll
90
160
# give the attached instance a generic name.
91
161
attachment['instance_name'] = _("Unknown instance")
162
return Volume(volume_data)
95
165
def volume_create(request, size, name, description, volume_type,
96
166
snapshot_id=None, metadata=None, image_id=None,
97
availability_zone=None):
98
return cinderclient(request).volumes.create(size, display_name=name,
99
display_description=description, volume_type=volume_type,
100
snapshot_id=snapshot_id, metadata=metadata, imageRef=image_id,
101
availability_zone=availability_zone)
167
availability_zone=None, source_volid=None):
168
data = {'name': name,
169
'description': description,
170
'volume_type': volume_type,
171
'snapshot_id': snapshot_id,
172
'metadata': metadata,
173
'imageRef': image_id,
174
'availability_zone': availability_zone,
175
'source_volid': source_volid}
176
data = _replace_v2_parameters(data)
178
volume = cinderclient(request).volumes.create(size, **data)
179
return Volume(volume)
182
def volume_extend(request, volume_id, new_size):
183
return cinderclient(request).volumes.extend(volume_id, new_size)
104
186
def volume_delete(request, volume_id):
108
190
def volume_update(request, volume_id, name, description):
109
vol_data = {'display_name': name,
110
'display_description': description}
191
vol_data = {'name': name,
192
'description': description}
193
vol_data = _replace_v2_parameters(vol_data)
111
194
return cinderclient(request).volumes.update(volume_id,
115
198
def volume_snapshot_get(request, snapshot_id):
116
return cinderclient(request).volume_snapshots.get(snapshot_id)
199
snapshot = cinderclient(request).volume_snapshots.get(snapshot_id)
200
return VolumeSnapshot(snapshot)
119
203
def volume_snapshot_list(request):
120
204
c_client = cinderclient(request)
121
205
if c_client is None:
123
return c_client.volume_snapshots.list()
207
return [VolumeSnapshot(s) for s in c_client.volume_snapshots.list()]
126
210
def volume_snapshot_create(request, volume_id, name,
127
211
description=None, force=False):
128
return cinderclient(request).volume_snapshots.create(
129
volume_id, force=force, display_name=name,
130
display_description=description)
212
data = {'name': name,
213
'description': description,
215
data = _replace_v2_parameters(data)
217
return VolumeSnapshot(cinderclient(request).volume_snapshots.create(
133
221
def volume_snapshot_delete(request, snapshot_id):