Basic support for Cinder v2
Change-Id: I6540720866c9005cf9537fe5b3a241f769529b3a Implements blueprint: cinder-v2-horizon Closes-Bug: #1226944
This commit is contained in:
parent
898ccff4c9
commit
77dcd64341
|
@ -6,7 +6,7 @@ horizon.forms = {
|
|||
var $form = $(this).closest('form');
|
||||
var $volName = $form.find('input#id_name');
|
||||
if ($volName.val() == "") {
|
||||
$volName.val($option.data("display_name"));
|
||||
$volName.val($option.data("name"));
|
||||
}
|
||||
var $volSize = $form.find('input#id_size');
|
||||
var volSize = parseInt($volSize.val(), 10) || -1;
|
||||
|
@ -23,7 +23,7 @@ horizon.forms = {
|
|||
var $form = $(this).closest('form');
|
||||
var $volName = $form.find('input#id_name');
|
||||
if ($volName.val() == "") {
|
||||
$volName.val($option.data("display_name"));
|
||||
$volName.val($option.data("name"));
|
||||
}
|
||||
var $volSize = $form.find('input#id_size');
|
||||
var volSize = parseInt($volSize.val(), 10) || -1;
|
||||
|
|
|
@ -27,7 +27,6 @@ import logging
|
|||
from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from cinderclient.v1 import client as cinder_client
|
||||
from cinderclient.v1.contrib import list_extensions as cinder_list_extensions
|
||||
|
||||
from horizon import exceptions
|
||||
|
@ -44,18 +43,80 @@ VOLUME_STATE_AVAILABLE = "available"
|
|||
DEFAULT_QUOTA_NAME = 'default'
|
||||
|
||||
|
||||
VERSIONS = base.APIVersionManager("volume", preferred_version=1)
|
||||
|
||||
try:
|
||||
from cinderclient.v1 import client as cinder_client_v1
|
||||
VERSIONS.load_supported_version(1, {"client": cinder_client_v1,
|
||||
"version": 1})
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
from cinderclient.v2 import client as cinder_client_v2
|
||||
VERSIONS.load_supported_version(2, {"client": cinder_client_v2,
|
||||
"version": 2})
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
class BaseCinderAPIResourceWrapper(base.APIResourceWrapper):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
# If a volume doesn't have a name, use its id.
|
||||
return (getattr(self._apiresource, 'name', None) or
|
||||
getattr(self._apiresource, 'display_name', None) or
|
||||
getattr(self._apiresource, 'id', None))
|
||||
|
||||
@property
|
||||
def description(self):
|
||||
return (getattr(self._apiresource, 'description', None) or
|
||||
getattr(self._apiresource, 'display_description', None))
|
||||
|
||||
|
||||
class Volume(BaseCinderAPIResourceWrapper):
|
||||
|
||||
_attrs = ['id', 'name', 'description', 'size', 'status', 'created_at',
|
||||
'volume_type', 'availability_zone', 'imageRef', 'bootable'
|
||||
'snapshot_id', 'source_volid', 'attachments', 'tenant_name',
|
||||
'os-vol-host-attr:host', 'os-vol-tenant-attr:tenant_id',
|
||||
'metadata']
|
||||
|
||||
|
||||
class VolumeSnapshot(BaseCinderAPIResourceWrapper):
|
||||
|
||||
_attrs = ['id', 'name', 'description', 'size', 'status',
|
||||
'created_at', 'volume_id',
|
||||
'os-extended-snapshot-attributes:project_id']
|
||||
|
||||
|
||||
def cinderclient(request):
|
||||
api_version = VERSIONS.get_active_version()
|
||||
|
||||
insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
|
||||
cacert = getattr(settings, 'OPENSTACK_SSL_CACERT', None)
|
||||
cinder_url = ""
|
||||
try:
|
||||
# The cinder client assumes that the v2 endpoint type will be
|
||||
# 'volumev2'. However it also allows 'volume' type as a
|
||||
# fallback if the requested version is 2 and there is no
|
||||
# 'volumev2' endpoint.
|
||||
if api_version['version'] == 2:
|
||||
try:
|
||||
cinder_url = base.url_for(request, 'volumev2')
|
||||
except exceptions.ServiceCatalogException:
|
||||
LOG.warning("Cinder v2 requested but no 'volumev2' service "
|
||||
"type available in Keystone catalog. Falling back "
|
||||
"to 'volume'.")
|
||||
if cinder_url == "":
|
||||
cinder_url = base.url_for(request, 'volume')
|
||||
except exceptions.ServiceCatalogException:
|
||||
LOG.debug('no volume service configured.')
|
||||
return None
|
||||
LOG.debug('cinderclient connection created using token "%s" and url "%s"' %
|
||||
(request.user.token.id, cinder_url))
|
||||
c = cinder_client.Client(request.user.username,
|
||||
c = api_version['client'].Client(request.user.username,
|
||||
request.user.token.id,
|
||||
project_id=request.user.tenant_id,
|
||||
auth_url=cinder_url,
|
||||
|
@ -67,6 +128,15 @@ def cinderclient(request):
|
|||
return c
|
||||
|
||||
|
||||
def _replace_v2_parameters(data):
|
||||
if VERSIONS.active < 2:
|
||||
data['display_name'] = data['name']
|
||||
data['display_description'] = data['description']
|
||||
del data['name']
|
||||
del data['description']
|
||||
return data
|
||||
|
||||
|
||||
def volume_list(request, search_opts=None):
|
||||
"""To see all volumes in the cloud as an admin you can pass in a special
|
||||
search option: {'all_tenants': 1}
|
||||
|
@ -74,7 +144,7 @@ def volume_list(request, search_opts=None):
|
|||
c_client = cinderclient(request)
|
||||
if c_client is None:
|
||||
return []
|
||||
return c_client.volumes.list(search_opts=search_opts)
|
||||
return [Volume(v) for v in c_client.volumes.list(search_opts=search_opts)]
|
||||
|
||||
|
||||
def volume_get(request, volume_id):
|
||||
|
@ -89,16 +159,24 @@ def volume_get(request, volume_id):
|
|||
# the lack a server_id property; to work around that we'll
|
||||
# give the attached instance a generic name.
|
||||
attachment['instance_name'] = _("Unknown instance")
|
||||
return volume_data
|
||||
return Volume(volume_data)
|
||||
|
||||
|
||||
def volume_create(request, size, name, description, volume_type,
|
||||
snapshot_id=None, metadata=None, image_id=None,
|
||||
availability_zone=None, source_volid=None):
|
||||
return cinderclient(request).volumes.create(size, display_name=name,
|
||||
display_description=description, volume_type=volume_type,
|
||||
snapshot_id=snapshot_id, metadata=metadata, imageRef=image_id,
|
||||
availability_zone=availability_zone, source_volid=source_volid)
|
||||
data = {'name': name,
|
||||
'description': description,
|
||||
'volume_type': volume_type,
|
||||
'snapshot_id': snapshot_id,
|
||||
'metadata': metadata,
|
||||
'imageRef': image_id,
|
||||
'availability_zone': availability_zone,
|
||||
'source_volid': source_volid}
|
||||
data = _replace_v2_parameters(data)
|
||||
|
||||
volume = cinderclient(request).volumes.create(size, **data)
|
||||
return Volume(volume)
|
||||
|
||||
|
||||
def volume_extend(request, volume_id, new_size):
|
||||
|
@ -110,28 +188,34 @@ def volume_delete(request, volume_id):
|
|||
|
||||
|
||||
def volume_update(request, volume_id, name, description):
|
||||
vol_data = {'display_name': name,
|
||||
'display_description': description}
|
||||
vol_data = {'name': name,
|
||||
'description': description}
|
||||
vol_data = _replace_v2_parameters(vol_data)
|
||||
return cinderclient(request).volumes.update(volume_id,
|
||||
**vol_data)
|
||||
|
||||
|
||||
def volume_snapshot_get(request, snapshot_id):
|
||||
return cinderclient(request).volume_snapshots.get(snapshot_id)
|
||||
snapshot = cinderclient(request).volume_snapshots.get(snapshot_id)
|
||||
return VolumeSnapshot(snapshot)
|
||||
|
||||
|
||||
def volume_snapshot_list(request):
|
||||
c_client = cinderclient(request)
|
||||
if c_client is None:
|
||||
return []
|
||||
return c_client.volume_snapshots.list()
|
||||
return [VolumeSnapshot(s) for s in c_client.volume_snapshots.list()]
|
||||
|
||||
|
||||
def volume_snapshot_create(request, volume_id, name,
|
||||
description=None, force=False):
|
||||
return cinderclient(request).volume_snapshots.create(
|
||||
volume_id, force=force, display_name=name,
|
||||
display_description=description)
|
||||
data = {'name': name,
|
||||
'description': description,
|
||||
'force': force}
|
||||
data = _replace_v2_parameters(data)
|
||||
|
||||
return VolumeSnapshot(cinderclient(request).volume_snapshots.create(
|
||||
volume_id, **data))
|
||||
|
||||
|
||||
def volume_snapshot_delete(request, snapshot_id):
|
||||
|
|
|
@ -41,11 +41,11 @@ class VolumesFilterAction(tables.FilterAction):
|
|||
"""Naive case-insensitive search."""
|
||||
q = filter_string.lower()
|
||||
return [volume for volume in volumes
|
||||
if q in volume.display_name.lower()]
|
||||
if q in volume.name.lower()]
|
||||
|
||||
|
||||
class VolumesTable(project_tables.VolumesTable):
|
||||
name = tables.Column("display_name",
|
||||
name = tables.Column("name",
|
||||
verbose_name=_("Name"),
|
||||
link="horizon:admin:volumes:detail")
|
||||
host = tables.Column("os-vol-host-attr:host", verbose_name=_("Host"))
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
{% block title %}{% trans "Volume Details" %}{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Volume Details: ")|add:volume.display_name|default:_("Volume Details:") %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Volume Details: ")|add:volume.name|default:_("Volume Details:") %}
|
||||
{% endblock page_header %}
|
||||
|
||||
{% block main %}
|
||||
|
|
|
@ -31,7 +31,7 @@ class VolumeTests(test.BaseAdminViewTests):
|
|||
keystone: ('tenant_list',)})
|
||||
def test_index(self):
|
||||
cinder.volume_list(IsA(http.HttpRequest), search_opts={
|
||||
'all_tenants': True}).AndReturn(self.volumes.list())
|
||||
'all_tenants': True}).AndReturn(self.cinder_volumes.list())
|
||||
api.nova.server_list(IsA(http.HttpRequest), search_opts={
|
||||
'all_tenants': True}) \
|
||||
.AndReturn([self.servers.list(), False])
|
||||
|
@ -47,7 +47,7 @@ class VolumeTests(test.BaseAdminViewTests):
|
|||
self.assertTemplateUsed(res, 'admin/volumes/index.html')
|
||||
volumes = res.context['volumes_table'].data
|
||||
|
||||
self.assertItemsEqual(volumes, self.volumes.list())
|
||||
self.assertItemsEqual(volumes, self.cinder_volumes.list())
|
||||
|
||||
@test.create_stubs({cinder: ('volume_type_create',)})
|
||||
def test_create_volume_type(self):
|
||||
|
@ -74,7 +74,7 @@ class VolumeTests(test.BaseAdminViewTests):
|
|||
formData = {'action': 'volume_types__delete__%s' % volume_type.id}
|
||||
|
||||
cinder.volume_list(IsA(http.HttpRequest), search_opts={
|
||||
'all_tenants': True}).AndReturn(self.volumes.list())
|
||||
'all_tenants': True}).AndReturn(self.cinder_volumes.list())
|
||||
api.nova.server_list(IsA(http.HttpRequest), search_opts={
|
||||
'all_tenants': True}) \
|
||||
.AndReturn([self.servers.list(), False])
|
||||
|
|
|
@ -48,7 +48,6 @@ class IndexView(tables.MultiTableView, project_tabs.VolumeTableMixIn):
|
|||
def get_volumes_data(self):
|
||||
volumes = self._get_volumes(search_opts={'all_tenants': True})
|
||||
instances = self._get_instances(search_opts={'all_tenants': True})
|
||||
self._set_id_if_nameless(volumes)
|
||||
self._set_attachments_string(volumes, instances)
|
||||
|
||||
# Gather our tenants to correlate against IDs
|
||||
|
|
|
@ -342,7 +342,7 @@ class SetInstanceDetailsAction(workflows.Action):
|
|||
visible_label = _("Volume")
|
||||
return (("%s:%s" % (volume.id, vol_type)),
|
||||
(_("%(name)s - %(size)s GB (%(label)s)") %
|
||||
{'name': volume.display_name or volume.id,
|
||||
{'name': volume.name,
|
||||
'size': volume.size,
|
||||
'label': visible_label}))
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ class SnapshotVolumeNameColumn(tables.Column):
|
|||
def get_raw_data(self, snapshot):
|
||||
volume = snapshot._volume
|
||||
if volume:
|
||||
volume_name = volume.display_name or volume.id
|
||||
volume_name = volume.name
|
||||
volume_name = html.escape(volume_name)
|
||||
else:
|
||||
volume_name = _("Unknown")
|
||||
|
@ -93,11 +93,10 @@ class SnapshotVolumeNameColumn(tables.Column):
|
|||
|
||||
|
||||
class VolumeSnapshotsTable(volume_tables.VolumesTableBase):
|
||||
name = tables.Column("display_name",
|
||||
name = tables.Column("name",
|
||||
verbose_name=_("Name"),
|
||||
link="horizon:project:volumes:detail")
|
||||
volume_name = SnapshotVolumeNameColumn(
|
||||
"display_name",
|
||||
volume_name = SnapshotVolumeNameColumn("name",
|
||||
verbose_name=_("Volume Name"),
|
||||
link="horizon:project:volumes:volumes:detail")
|
||||
|
||||
|
|
|
@ -35,12 +35,12 @@ class VolumeSnapshotsViewTests(test.TestCase):
|
|||
@test.create_stubs({cinder: ('volume_get',),
|
||||
quotas: ('tenant_limit_usages',)})
|
||||
def test_create_snapshot_get(self):
|
||||
volume = self.volumes.first()
|
||||
volume = self.cinder_volumes.first()
|
||||
cinder.volume_get(IsA(http.HttpRequest), volume.id) \
|
||||
.AndReturn(volume)
|
||||
usage_limit = {'maxTotalVolumeGigabytes': 250,
|
||||
'gigabytesUsed': 20,
|
||||
'volumesUsed': len(self.volumes.list()),
|
||||
'volumesUsed': len(self.cinder_volumes.list()),
|
||||
'maxTotalVolumes': 6}
|
||||
quotas.tenant_limit_usages(IsA(http.HttpRequest)).\
|
||||
AndReturn(usage_limit)
|
||||
|
@ -56,15 +56,15 @@ class VolumeSnapshotsViewTests(test.TestCase):
|
|||
@test.create_stubs({cinder: ('volume_get',
|
||||
'volume_snapshot_create',)})
|
||||
def test_create_snapshot_post(self):
|
||||
volume = self.volumes.first()
|
||||
snapshot = self.volume_snapshots.first()
|
||||
volume = self.cinder_volumes.first()
|
||||
snapshot = self.cinder_volume_snapshots.first()
|
||||
|
||||
cinder.volume_get(IsA(http.HttpRequest), volume.id) \
|
||||
.AndReturn(volume)
|
||||
cinder.volume_snapshot_create(IsA(http.HttpRequest),
|
||||
volume.id,
|
||||
snapshot.display_name,
|
||||
snapshot.display_description,
|
||||
snapshot.name,
|
||||
snapshot.description,
|
||||
force=False) \
|
||||
.AndReturn(snapshot)
|
||||
self.mox.ReplayAll()
|
||||
|
@ -72,8 +72,8 @@ class VolumeSnapshotsViewTests(test.TestCase):
|
|||
formData = {'method': 'CreateSnapshotForm',
|
||||
'tenant_id': self.tenant.id,
|
||||
'volume_id': volume.id,
|
||||
'name': snapshot.display_name,
|
||||
'description': snapshot.display_description}
|
||||
'name': snapshot.name,
|
||||
'description': snapshot.description}
|
||||
url = reverse('horizon:project:volumes:volumes:create_snapshot',
|
||||
args=[volume.id])
|
||||
res = self.client.post(url, formData)
|
||||
|
@ -82,15 +82,15 @@ class VolumeSnapshotsViewTests(test.TestCase):
|
|||
@test.create_stubs({cinder: ('volume_get',
|
||||
'volume_snapshot_create',)})
|
||||
def test_force_create_snapshot(self):
|
||||
volume = self.volumes.get(name='my_volume')
|
||||
snapshot = self.volume_snapshots.first()
|
||||
volume = self.cinder_volumes.get(name='my_volume')
|
||||
snapshot = self.cinder_volume_snapshots.first()
|
||||
|
||||
cinder.volume_get(IsA(http.HttpRequest), volume.id) \
|
||||
.AndReturn(volume)
|
||||
cinder.volume_snapshot_create(IsA(http.HttpRequest),
|
||||
volume.id,
|
||||
snapshot.display_name,
|
||||
snapshot.display_description,
|
||||
snapshot.name,
|
||||
snapshot.description,
|
||||
force=True) \
|
||||
.AndReturn(snapshot)
|
||||
self.mox.ReplayAll()
|
||||
|
@ -98,8 +98,8 @@ class VolumeSnapshotsViewTests(test.TestCase):
|
|||
formData = {'method': 'CreateSnapshotForm',
|
||||
'tenant_id': self.tenant.id,
|
||||
'volume_id': volume.id,
|
||||
'name': snapshot.display_name,
|
||||
'description': snapshot.display_description}
|
||||
'name': snapshot.name,
|
||||
'description': snapshot.description}
|
||||
url = reverse('horizon:project:volumes:volumes:create_snapshot',
|
||||
args=[volume.id])
|
||||
res = self.client.post(url, formData)
|
||||
|
@ -111,9 +111,9 @@ class VolumeSnapshotsViewTests(test.TestCase):
|
|||
'volume_snapshot_delete'),
|
||||
quotas: ('tenant_quota_usages',)})
|
||||
def test_delete_volume_snapshot(self):
|
||||
vol_snapshots = self.volume_snapshots.list()
|
||||
volumes = self.volumes.list()
|
||||
snapshot = self.volume_snapshots.first()
|
||||
vol_snapshots = self.cinder_volume_snapshots.list()
|
||||
volumes = self.cinder_volumes.list()
|
||||
snapshot = self.cinder_volume_snapshots.first()
|
||||
|
||||
api.cinder.volume_snapshot_list(IsA(http.HttpRequest)). \
|
||||
AndReturn(vol_snapshots)
|
||||
|
@ -142,8 +142,8 @@ class VolumeSnapshotsViewTests(test.TestCase):
|
|||
|
||||
@test.create_stubs({api.cinder: ('volume_snapshot_get', 'volume_get')})
|
||||
def test_volume_snapshot_detail_get(self):
|
||||
volume = self.volumes.first()
|
||||
snapshot = self.volume_snapshots.first()
|
||||
volume = self.cinder_volumes.first()
|
||||
snapshot = self.cinder_volume_snapshots.first()
|
||||
|
||||
api.cinder.volume_get(IsA(http.HttpRequest), volume.id). \
|
||||
AndReturn(volume)
|
||||
|
@ -158,19 +158,16 @@ class VolumeSnapshotsViewTests(test.TestCase):
|
|||
|
||||
self.assertContains(res,
|
||||
"<h2>Volume Snapshot Details: %s</h2>" %
|
||||
snapshot.display_name,
|
||||
snapshot.name,
|
||||
1, 200)
|
||||
self.assertContains(res, "<dd>test snapshot</dd>", 1, 200)
|
||||
self.assertContains(res,
|
||||
"<dd>40f3fabf-3613-4f5e-90e5-6c9a08333fc3</dd>",
|
||||
1,
|
||||
200)
|
||||
self.assertContains(res, "<dd>%s</dd>" % snapshot.id, 1, 200)
|
||||
self.assertContains(res, "<dd>Available</dd>", 1, 200)
|
||||
|
||||
@test.create_stubs({api.cinder: ('volume_snapshot_get',)})
|
||||
def test_volume_snapshot_detail_get_with_exception(self):
|
||||
# Test to verify redirect if get volume snapshot fails
|
||||
snapshot = self.volume_snapshots.first()
|
||||
snapshot = self.cinder_volume_snapshots.first()
|
||||
|
||||
api.cinder.volume_snapshot_get(IsA(http.HttpRequest), snapshot.id).\
|
||||
AndRaise(self.exceptions.cinder)
|
||||
|
@ -185,8 +182,8 @@ class VolumeSnapshotsViewTests(test.TestCase):
|
|||
@test.create_stubs({api.cinder: ('volume_snapshot_get', 'volume_get')})
|
||||
def test_volume_snapshot_detail_with_volume_get_exception(self):
|
||||
# Test to verify redirect if get volume fails
|
||||
volume = self.volumes.first()
|
||||
snapshot = self.volume_snapshots.first()
|
||||
volume = self.cinder_volumes.first()
|
||||
snapshot = self.cinder_volume_snapshots.first()
|
||||
|
||||
api.cinder.volume_get(IsA(http.HttpRequest), volume.id). \
|
||||
AndRaise(self.exceptions.cinder)
|
||||
|
|
|
@ -49,13 +49,6 @@ class VolumeTableMixIn(object):
|
|||
"attachment information"))
|
||||
return []
|
||||
|
||||
def _set_id_if_nameless(self, volumes):
|
||||
for volume in volumes:
|
||||
# It is possible to create a volume with no name through the
|
||||
# EC2 API, use the ID in those cases.
|
||||
if not volume.display_name:
|
||||
volume.display_name = volume.id
|
||||
|
||||
def _set_attachments_string(self, volumes, instances):
|
||||
instances = SortedDict([(inst.id, inst) for inst in instances])
|
||||
for volume in volumes:
|
||||
|
@ -73,7 +66,6 @@ class VolumeTab(tabs.TableTab, VolumeTableMixIn):
|
|||
def get_volumes_data(self):
|
||||
volumes = self._get_volumes()
|
||||
instances = self._get_instances()
|
||||
self._set_id_if_nameless(volumes)
|
||||
self._set_attachments_string(volumes, instances)
|
||||
return volumes
|
||||
|
||||
|
|
|
@ -8,20 +8,20 @@
|
|||
<hr class="header_rule">
|
||||
<dl>
|
||||
<dt>{% trans "Name" %}</dt>
|
||||
<dd>{{ snapshot.display_name }}</dd>
|
||||
<dd>{{ snapshot.name }}</dd>
|
||||
<dt>{% trans "ID" %}</dt>
|
||||
<dd>{{ snapshot.id }}</dd>
|
||||
{% if snapshot.display_description %}
|
||||
{% if snapshot.description %}
|
||||
<dt>{% trans "Description" %}</dt>
|
||||
<dd>{{ snapshot.display_description }}</dd>
|
||||
<dd>{{ snapshot.description }}</dd>
|
||||
{% endif %}
|
||||
<dt>{% trans "Status" %}</dt>
|
||||
<dd>{{ snapshot.status|capfirst }}</dd>
|
||||
<dt>{% trans "Volume" %}</dt>
|
||||
<dd>
|
||||
<a href="{% url 'horizon:project:volumes:volumes:detail' snapshot.volume_id %}">
|
||||
{% if volume.display_name %}
|
||||
{{ volume.display_name }}
|
||||
{% if volume.name %}
|
||||
{{ volume.name }}
|
||||
{% else %}
|
||||
{{ snapshot.volume_id }}
|
||||
{% endif %}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
{% block title %}{% trans "Volume Snapshot Details" %}{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Volume Snapshot Details: ")|add:snapshot.display_name|default:_("Volume Snapshot Details:") %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Volume Snapshot Details: ")|add:snapshot.name|default:_("Volume Snapshot Details:") %}
|
||||
{% endblock page_header %}
|
||||
{% block main %}
|
||||
<div class="row-fluid">
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
<hr class="header_rule">
|
||||
<dl>
|
||||
<dt>{% trans "Name" %}</dt>
|
||||
<dd>{{ volume.display_name }}</dd>
|
||||
<dd>{{ volume.name }}</dd>
|
||||
<dt>{% trans "ID" %}</dt>
|
||||
<dd>{{ volume.id }}</dd>
|
||||
{% if volume.display_description %}
|
||||
{% if volume.description %}
|
||||
<dt>{% trans "Description" %}</dt>
|
||||
<dd>{{ volume.display_description }}</dd>
|
||||
<dd>{{ volume.description }}</dd>
|
||||
{% endif %}
|
||||
<dt>{% trans "Status" %}</dt>
|
||||
<dd>{{ volume.status|capfirst }}</dd>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
{% block title %}{% trans "Volume Details" %}{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Volume Details: ")|add:volume.display_name|default:_("Volume Details:") %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Volume Details: ")|add:volume.name|default:_("Volume Details:") %}
|
||||
{% endblock page_header %}
|
||||
|
||||
{% block main %}
|
||||
|
|
|
@ -33,8 +33,8 @@ class VolumeAndSnapshotsTests(test.TestCase):
|
|||
api.nova: ('server_list',),
|
||||
quotas: ('tenant_quota_usages',)})
|
||||
def test_index(self):
|
||||
vol_snaps = self.volume_snapshots.list()
|
||||
volumes = self.volumes.list()
|
||||
vol_snaps = self.cinder_volume_snapshots.list()
|
||||
volumes = self.cinder_volumes.list()
|
||||
|
||||
api.cinder.volume_list(IsA(http.HttpRequest), search_opts=None).\
|
||||
AndReturn(volumes)
|
||||
|
@ -48,4 +48,5 @@ class VolumeAndSnapshotsTests(test.TestCase):
|
|||
self.mox.ReplayAll()
|
||||
|
||||
res = self.client.get(INDEX_URL)
|
||||
self.assertEqual(res.status_code, 200)
|
||||
self.assertTemplateUsed(res, 'project/volumes/index.html')
|
||||
|
|
|
@ -56,8 +56,8 @@ class CreateForm(forms.SelfHandlingForm):
|
|||
label=_("Use snapshot as a source"),
|
||||
widget=fields.SelectWidget(
|
||||
attrs={'class': 'snapshot-selector'},
|
||||
data_attrs=('size', 'display_name'),
|
||||
transform=lambda x: "%s (%sGB)" % (x.display_name, x.size)),
|
||||
data_attrs=('size', 'name'),
|
||||
transform=lambda x: "%s (%sGB)" % (x.name, x.size)),
|
||||
required=False)
|
||||
image_source = forms.ChoiceField(
|
||||
label=_("Use image as a source"),
|
||||
|
@ -70,8 +70,8 @@ class CreateForm(forms.SelfHandlingForm):
|
|||
label=_("Use a volume as source"),
|
||||
widget=fields.SelectWidget(
|
||||
attrs={'class': 'image-selector'},
|
||||
data_attrs=('size', 'display_name'),
|
||||
transform=lambda x: "%s (%s)" % (x.display_name,
|
||||
data_attrs=('size', 'name'),
|
||||
transform=lambda x: "%s (%s)" % (x.name,
|
||||
filesizeformat(x.size * 1024 * 1024 * 1024))),
|
||||
required=False)
|
||||
availability_zone = forms.ChoiceField(
|
||||
|
@ -94,7 +94,7 @@ class CreateForm(forms.SelfHandlingForm):
|
|||
try:
|
||||
snapshot = self.get_snapshot(request,
|
||||
request.GET["snapshot_id"])
|
||||
self.fields['name'].initial = snapshot.display_name
|
||||
self.fields['name'].initial = snapshot.name
|
||||
self.fields['size'].initial = snapshot.size
|
||||
self.fields['snapshot_source'].choices = ((snapshot.id,
|
||||
snapshot),)
|
||||
|
@ -153,8 +153,8 @@ class CreateForm(forms.SelfHandlingForm):
|
|||
exceptions.handle(request, msg % request.GET['volume_id'])
|
||||
|
||||
if volume is not None:
|
||||
self.fields['name'].initial = volume.display_name
|
||||
self.fields['description'].initial = volume.display_description
|
||||
self.fields['name'].initial = volume.name
|
||||
self.fields['description'].initial = volume.description
|
||||
min_vol_size = volume.size
|
||||
size_help_text = _('Volume size must be equal to or greater '
|
||||
'than the origin volume size (%s)') \
|
||||
|
@ -417,12 +417,8 @@ class AttachForm(forms.SelfHandlingForm):
|
|||
data['instance'],
|
||||
data.get('device', ''))
|
||||
volume = cinder.volume_get(request, data['volume_id'])
|
||||
if not volume.display_name:
|
||||
volume_name = volume.id
|
||||
else:
|
||||
volume_name = volume.display_name
|
||||
message = _('Attaching volume %(vol)s to instance '
|
||||
'%(inst)s on %(dev)s.') % {"vol": volume_name,
|
||||
'%(inst)s on %(dev)s.') % {"vol": volume.name,
|
||||
"inst": instance_name,
|
||||
"dev": attach.device}
|
||||
messages.info(request, message)
|
||||
|
|
|
@ -165,8 +165,6 @@ class UpdateRow(tables.Row):
|
|||
|
||||
def get_data(self, request, volume_id):
|
||||
volume = cinder.volume_get(request, volume_id)
|
||||
if not volume.display_name:
|
||||
volume.display_name = volume_id
|
||||
return volume
|
||||
|
||||
|
||||
|
@ -226,10 +224,10 @@ class VolumesTableBase(tables.DataTable):
|
|||
("creating", None),
|
||||
("error", False),
|
||||
)
|
||||
name = tables.Column("display_name",
|
||||
name = tables.Column("name",
|
||||
verbose_name=_("Name"),
|
||||
link="horizon:project:volumes:volumes:detail")
|
||||
description = tables.Column("display_description",
|
||||
description = tables.Column("description",
|
||||
verbose_name=_("Description"),
|
||||
truncate=40)
|
||||
size = tables.Column(get_size,
|
||||
|
@ -242,7 +240,7 @@ class VolumesTableBase(tables.DataTable):
|
|||
status_choices=STATUS_CHOICES)
|
||||
|
||||
def get_object_display(self, obj):
|
||||
return obj.display_name
|
||||
return obj.name
|
||||
|
||||
|
||||
class VolumesFilterAction(tables.FilterAction):
|
||||
|
@ -251,11 +249,11 @@ class VolumesFilterAction(tables.FilterAction):
|
|||
"""Naive case-insensitive search."""
|
||||
q = filter_string.lower()
|
||||
return [volume for volume in volumes
|
||||
if q in volume.display_name.lower()]
|
||||
if q in volume.name.lower()]
|
||||
|
||||
|
||||
class VolumesTable(VolumesTableBase):
|
||||
name = tables.Column("display_name",
|
||||
name = tables.Column("name",
|
||||
verbose_name=_("Name"),
|
||||
link="horizon:project:volumes:volumes:detail")
|
||||
volume_type = tables.Column(get_volume_type,
|
||||
|
|
|
@ -47,12 +47,12 @@ class VolumeViewTests(test.TestCase):
|
|||
api.glance: ('image_list_detailed',),
|
||||
quotas: ('tenant_limit_usages',)})
|
||||
def test_create_volume(self):
|
||||
volume = self.volumes.first()
|
||||
volume = self.cinder_volumes.first()
|
||||
volume_type = self.volume_types.first()
|
||||
az = self.cinder_availability_zones.first().zoneName
|
||||
usage_limit = {'maxTotalVolumeGigabytes': 250,
|
||||
'gigabytesUsed': 20,
|
||||
'volumesUsed': len(self.volumes.list()),
|
||||
'volumesUsed': len(self.cinder_volumes.list()),
|
||||
'maxTotalVolumes': 6}
|
||||
formData = {'name': u'A Volume I Am Making',
|
||||
'description': u'This is a volume I am making for a test.',
|
||||
|
@ -67,7 +67,7 @@ class VolumeViewTests(test.TestCase):
|
|||
quotas.tenant_limit_usages(IsA(http.HttpRequest)).\
|
||||
AndReturn(usage_limit)
|
||||
cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
|
||||
AndReturn(self.volume_snapshots.list())
|
||||
AndReturn(self.cinder_volume_snapshots.list())
|
||||
api.glance.image_list_detailed(IsA(http.HttpRequest),
|
||||
filters={'is_public': True,
|
||||
'status': 'active'}) \
|
||||
|
@ -82,7 +82,7 @@ class VolumeViewTests(test.TestCase):
|
|||
cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones')\
|
||||
.AndReturn(True)
|
||||
cinder.volume_list(IsA(
|
||||
http.HttpRequest)).AndReturn(self.volumes.list())
|
||||
http.HttpRequest)).AndReturn(self.cinder_volumes.list())
|
||||
|
||||
cinder.volume_create(IsA(http.HttpRequest),
|
||||
formData['size'],
|
||||
|
@ -113,10 +113,10 @@ class VolumeViewTests(test.TestCase):
|
|||
api.glance: ('image_list_detailed',),
|
||||
quotas: ('tenant_limit_usages',)})
|
||||
def test_create_volume_dropdown(self):
|
||||
volume = self.volumes.first()
|
||||
volume = self.cinder_volumes.first()
|
||||
usage_limit = {'maxTotalVolumeGigabytes': 250,
|
||||
'gigabytesUsed': 20,
|
||||
'volumesUsed': len(self.volumes.list()),
|
||||
'volumesUsed': len(self.cinder_volumes.list()),
|
||||
'maxTotalVolumes': 6}
|
||||
formData = {'name': u'A Volume I Am Making',
|
||||
'description': u'This is a volume I am making for a test.',
|
||||
|
@ -124,13 +124,13 @@ class VolumeViewTests(test.TestCase):
|
|||
'size': 50,
|
||||
'type': '',
|
||||
'volume_source_type': 'no_source_type',
|
||||
'snapshot_source': self.volume_snapshots.first().id,
|
||||
'snapshot_source': self.cinder_volume_snapshots.first().id,
|
||||
'image_source': self.images.first().id}
|
||||
|
||||
cinder.volume_type_list(IsA(http.HttpRequest)).\
|
||||
AndReturn(self.volume_types.list())
|
||||
cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
|
||||
AndReturn(self.volume_snapshots.list())
|
||||
AndReturn(self.cinder_volume_snapshots.list())
|
||||
api.glance.image_list_detailed(IsA(http.HttpRequest),
|
||||
filters={'is_public': True,
|
||||
'status': 'active'}) \
|
||||
|
@ -140,7 +140,7 @@ class VolumeViewTests(test.TestCase):
|
|||
'status': 'active'}) \
|
||||
.AndReturn([[], False])
|
||||
cinder.volume_list(IsA(
|
||||
http.HttpRequest)).AndReturn(self.volumes.list())
|
||||
http.HttpRequest)).AndReturn(self.cinder_volumes.list())
|
||||
quotas.tenant_limit_usages(IsA(http.HttpRequest)).\
|
||||
AndReturn(usage_limit)
|
||||
|
||||
|
@ -174,12 +174,12 @@ class VolumeViewTests(test.TestCase):
|
|||
'volume_type_list'),
|
||||
quotas: ('tenant_limit_usages',)})
|
||||
def test_create_volume_from_snapshot(self):
|
||||
volume = self.volumes.first()
|
||||
volume = self.cinder_volumes.first()
|
||||
usage_limit = {'maxTotalVolumeGigabytes': 250,
|
||||
'gigabytesUsed': 20,
|
||||
'volumesUsed': len(self.volumes.list()),
|
||||
'volumesUsed': len(self.cinder_volumes.list()),
|
||||
'maxTotalVolumes': 6}
|
||||
snapshot = self.volume_snapshots.first()
|
||||
snapshot = self.cinder_volume_snapshots.first()
|
||||
formData = {'name': u'A Volume I Am Making',
|
||||
'description': u'This is a volume I am making for a test.',
|
||||
'method': u'CreateForm',
|
||||
|
@ -194,7 +194,7 @@ class VolumeViewTests(test.TestCase):
|
|||
cinder.volume_snapshot_get(IsA(http.HttpRequest),
|
||||
str(snapshot.id)).AndReturn(snapshot)
|
||||
cinder.volume_get(IsA(http.HttpRequest), snapshot.volume_id).\
|
||||
AndReturn(self.volumes.first())
|
||||
AndReturn(self.cinder_volumes.first())
|
||||
|
||||
cinder.volume_create(IsA(http.HttpRequest),
|
||||
formData['size'],
|
||||
|
@ -228,10 +228,10 @@ class VolumeViewTests(test.TestCase):
|
|||
api.glance: ('image_list_detailed',),
|
||||
quotas: ('tenant_limit_usages',)})
|
||||
def test_create_volume_from_volume(self):
|
||||
volume = self.volumes.first()
|
||||
volume = self.cinder_volumes.first()
|
||||
usage_limit = {'maxTotalVolumeGigabytes': 250,
|
||||
'gigabytesUsed': 20,
|
||||
'volumesUsed': len(self.volumes.list()),
|
||||
'volumesUsed': len(self.cinder_volumes.list()),
|
||||
'maxTotalVolumes': 6}
|
||||
|
||||
formData = {'name': u'A copy of a volume',
|
||||
|
@ -243,16 +243,16 @@ class VolumeViewTests(test.TestCase):
|
|||
'volume_source': volume.id}
|
||||
|
||||
cinder.volume_list(IsA(http.HttpRequest)).\
|
||||
AndReturn(self.volumes.list())
|
||||
AndReturn(self.cinder_volumes.list())
|
||||
cinder.volume_type_list(IsA(http.HttpRequest)).\
|
||||
AndReturn(self.volume_types.list())
|
||||
cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
|
||||
AndReturn(self.volume_snapshots.list())
|
||||
AndReturn(self.cinder_volume_snapshots.list())
|
||||
quotas.tenant_limit_usages(IsA(http.HttpRequest)).\
|
||||
AndReturn(usage_limit)
|
||||
|
||||
cinder.volume_get(IsA(http.HttpRequest),
|
||||
volume.id).AndReturn(self.volumes.first())
|
||||
volume.id).AndReturn(self.cinder_volumes.first())
|
||||
cinder.extension_supported(IsA(http.HttpRequest),
|
||||
'AvailabilityZones').AndReturn(True)
|
||||
cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn(
|
||||
|
@ -296,12 +296,12 @@ class VolumeViewTests(test.TestCase):
|
|||
api.glance: ('image_list_detailed',),
|
||||
quotas: ('tenant_limit_usages',)})
|
||||
def test_create_volume_from_snapshot_dropdown(self):
|
||||
volume = self.volumes.first()
|
||||
volume = self.cinder_volumes.first()
|
||||
usage_limit = {'maxTotalVolumeGigabytes': 250,
|
||||
'gigabytesUsed': 20,
|
||||
'volumesUsed': len(self.volumes.list()),
|
||||
'volumesUsed': len(self.cinder_volumes.list()),
|
||||
'maxTotalVolumes': 6}
|
||||
snapshot = self.volume_snapshots.first()
|
||||
snapshot = self.cinder_volume_snapshots.first()
|
||||
formData = {'name': u'A Volume I Am Making',
|
||||
'description': u'This is a volume I am making for a test.',
|
||||
'method': u'CreateForm',
|
||||
|
@ -313,7 +313,7 @@ class VolumeViewTests(test.TestCase):
|
|||
cinder.volume_type_list(IsA(http.HttpRequest)).\
|
||||
AndReturn(self.volume_types.list())
|
||||
cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
|
||||
AndReturn(self.volume_snapshots.list())
|
||||
AndReturn(self.cinder_volume_snapshots.list())
|
||||
api.glance.image_list_detailed(IsA(http.HttpRequest),
|
||||
filters={'is_public': True,
|
||||
'status': 'active'}) \
|
||||
|
@ -323,7 +323,7 @@ class VolumeViewTests(test.TestCase):
|
|||
'status': 'active'}) \
|
||||
.AndReturn([[], False])
|
||||
cinder.volume_list(IsA(
|
||||
http.HttpRequest)).AndReturn(self.volumes.list())
|
||||
http.HttpRequest)).AndReturn(self.cinder_volumes.list())
|
||||
quotas.tenant_limit_usages(IsA(http.HttpRequest)).\
|
||||
AndReturn(usage_limit)
|
||||
cinder.volume_snapshot_get(IsA(http.HttpRequest),
|
||||
|
@ -362,9 +362,9 @@ class VolumeViewTests(test.TestCase):
|
|||
def test_create_volume_from_snapshot_invalid_size(self):
|
||||
usage_limit = {'maxTotalVolumeGigabytes': 100,
|
||||
'gigabytesUsed': 20,
|
||||
'volumesUsed': len(self.volumes.list()),
|
||||
'volumesUsed': len(self.cinder_volumes.list()),
|
||||
'maxTotalVolumes': 6}
|
||||
snapshot = self.volume_snapshots.first()
|
||||
snapshot = self.cinder_volume_snapshots.first()
|
||||
formData = {'name': u'A Volume I Am Making',
|
||||
'description': u'This is a volume I am making for a test.',
|
||||
'method': u'CreateForm',
|
||||
|
@ -377,7 +377,7 @@ class VolumeViewTests(test.TestCase):
|
|||
cinder.volume_snapshot_get(IsA(http.HttpRequest),
|
||||
str(snapshot.id)).AndReturn(snapshot)
|
||||
cinder.volume_get(IsA(http.HttpRequest), snapshot.volume_id).\
|
||||
AndReturn(self.volumes.first())
|
||||
AndReturn(self.cinder_volumes.first())
|
||||
|
||||
quotas.tenant_limit_usages(IsA(http.HttpRequest)).\
|
||||
AndReturn(usage_limit)
|
||||
|
@ -400,10 +400,10 @@ class VolumeViewTests(test.TestCase):
|
|||
api.glance: ('image_get',),
|
||||
quotas: ('tenant_limit_usages',)})
|
||||
def test_create_volume_from_image(self):
|
||||
volume = self.volumes.first()
|
||||
volume = self.cinder_volumes.first()
|
||||
usage_limit = {'maxTotalVolumeGigabytes': 200,
|
||||
'gigabytesUsed': 20,
|
||||
'volumesUsed': len(self.volumes.list()),
|
||||
'volumesUsed': len(self.cinder_volumes.list()),
|
||||
'maxTotalVolumes': 6}
|
||||
image = self.images.first()
|
||||
formData = {'name': u'A Volume I Am Making',
|
||||
|
@ -457,10 +457,10 @@ class VolumeViewTests(test.TestCase):
|
|||
'image_list_detailed'),
|
||||
quotas: ('tenant_limit_usages',)})
|
||||
def test_create_volume_from_image_dropdown(self):
|
||||
volume = self.volumes.first()
|
||||
volume = self.cinder_volumes.first()
|
||||
usage_limit = {'maxTotalVolumeGigabytes': 200,
|
||||
'gigabytesUsed': 20,
|
||||
'volumesUsed': len(self.volumes.list()),
|
||||
'volumesUsed': len(self.cinder_volumes.list()),
|
||||
'maxTotalVolumes': 6}
|
||||
image = self.images.first()
|
||||
formData = {'name': u'A Volume I Am Making',
|
||||
|
@ -469,13 +469,13 @@ class VolumeViewTests(test.TestCase):
|
|||
'size': 30,
|
||||
'type': '',
|
||||
'volume_source_type': 'image_source',
|
||||
'snapshot_source': self.volume_snapshots.first().id,
|
||||
'snapshot_source': self.cinder_volume_snapshots.first().id,
|
||||
'image_source': image.id}
|
||||
|
||||
cinder.volume_type_list(IsA(http.HttpRequest)).\
|
||||
AndReturn(self.volume_types.list())
|
||||
cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
|
||||
AndReturn(self.volume_snapshots.list())
|
||||
AndReturn(self.cinder_volume_snapshots.list())
|
||||
api.glance.image_list_detailed(IsA(http.HttpRequest),
|
||||
filters={'is_public': True,
|
||||
'status': 'active'}) \
|
||||
|
@ -485,7 +485,7 @@ class VolumeViewTests(test.TestCase):
|
|||
'status': 'active'}) \
|
||||
.AndReturn([[], False])
|
||||
cinder.volume_list(IsA(
|
||||
http.HttpRequest)).AndReturn(self.volumes.list())
|
||||
http.HttpRequest)).AndReturn(self.cinder_volumes.list())
|
||||
quotas.tenant_limit_usages(IsA(http.HttpRequest)) \
|
||||
.AndReturn(usage_limit)
|
||||
api.glance.image_get(IsA(http.HttpRequest),
|
||||
|
@ -525,7 +525,7 @@ class VolumeViewTests(test.TestCase):
|
|||
def test_create_volume_from_image_under_image_size(self):
|
||||
usage_limit = {'maxTotalVolumeGigabytes': 100,
|
||||
'gigabytesUsed': 20,
|
||||
'volumesUsed': len(self.volumes.list()),
|
||||
'volumesUsed': len(self.cinder_volumes.list()),
|
||||
'maxTotalVolumes': 6}
|
||||
image = self.images.first()
|
||||
formData = {'name': u'A Volume I Am Making',
|
||||
|
@ -574,7 +574,7 @@ class VolumeViewTests(test.TestCase):
|
|||
def test_create_volume_from_image_under_image_min_disk_size(self):
|
||||
usage_limit = {'maxTotalVolumeGigabytes': 100,
|
||||
'gigabytesUsed': 20,
|
||||
'volumesUsed': len(self.volumes.list()),
|
||||
'volumesUsed': len(self.cinder_volumes.list()),
|
||||
'maxTotalVolumes': 6}
|
||||
image = self.images.get(name="protected_images")
|
||||
image.min_disk = 30
|
||||
|
@ -617,7 +617,7 @@ class VolumeViewTests(test.TestCase):
|
|||
def test_create_volume_gb_used_over_alloted_quota(self):
|
||||
usage_limit = {'maxTotalVolumeGigabytes': 100,
|
||||
'gigabytesUsed': 80,
|
||||
'volumesUsed': len(self.volumes.list()),
|
||||
'volumesUsed': len(self.cinder_volumes.list()),
|
||||
'maxTotalVolumes': 6}
|
||||
formData = {'name': u'This Volume Is Huge!',
|
||||
'description': u'This is a volume that is just too big!',
|
||||
|
@ -629,7 +629,7 @@ class VolumeViewTests(test.TestCase):
|
|||
quotas.tenant_limit_usages(IsA(http.HttpRequest)).\
|
||||
AndReturn(usage_limit)
|
||||
cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
|
||||
AndReturn(self.volume_snapshots.list())
|
||||
AndReturn(self.cinder_volume_snapshots.list())
|
||||
api.glance.image_list_detailed(IsA(http.HttpRequest),
|
||||
filters={'is_public': True,
|
||||
'status': 'active'}) \
|
||||
|
@ -639,7 +639,7 @@ class VolumeViewTests(test.TestCase):
|
|||
'status': 'active'}) \
|
||||
.AndReturn([[], False])
|
||||
cinder.volume_list(IsA(
|
||||
http.HttpRequest)).AndReturn(self.volumes.list())
|
||||
http.HttpRequest)).AndReturn(self.cinder_volumes.list())
|
||||
cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones')\
|
||||
.AndReturn(True)
|
||||
cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn(
|
||||
|
@ -666,8 +666,8 @@ class VolumeViewTests(test.TestCase):
|
|||
def test_create_volume_number_over_alloted_quota(self):
|
||||
usage_limit = {'maxTotalVolumeGigabytes': 100,
|
||||
'gigabytesUsed': 20,
|
||||
'volumesUsed': len(self.volumes.list()),
|
||||
'maxTotalVolumes': len(self.volumes.list())}
|
||||
'volumesUsed': len(self.cinder_volumes.list()),
|
||||
'maxTotalVolumes': len(self.cinder_volumes.list())}
|
||||
formData = {'name': u'Too Many...',
|
||||
'description': u'We have no volumes left!',
|
||||
'method': u'CreateForm',
|
||||
|
@ -678,7 +678,7 @@ class VolumeViewTests(test.TestCase):
|
|||
quotas.tenant_limit_usages(IsA(http.HttpRequest)).\
|
||||
AndReturn(usage_limit)
|
||||
cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
|
||||
AndReturn(self.volume_snapshots.list())
|
||||
AndReturn(self.cinder_volume_snapshots.list())
|
||||
api.glance.image_list_detailed(IsA(http.HttpRequest),
|
||||
filters={'is_public': True,
|
||||
'status': 'active'}) \
|
||||
|
@ -688,7 +688,7 @@ class VolumeViewTests(test.TestCase):
|
|||
'status': 'active'}) \
|
||||
.AndReturn([[], False])
|
||||
cinder.volume_list(IsA(
|
||||
http.HttpRequest)).AndReturn(self.volumes.list())
|
||||
http.HttpRequest)).AndReturn(self.cinder_volumes.list())
|
||||
cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones')\
|
||||
.AndReturn(True)
|
||||
cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn(
|
||||
|
@ -711,8 +711,8 @@ class VolumeViewTests(test.TestCase):
|
|||
api.nova: ('server_list',),
|
||||
quotas: ('tenant_quota_usages',)})
|
||||
def test_delete_volume(self):
|
||||
volumes = self.volumes.list()
|
||||
volume = self.volumes.first()
|
||||
volumes = self.cinder_volumes.list()
|
||||
volume = self.cinder_volumes.first()
|
||||
formData = {'action':
|
||||
'volumes__delete__%s' % volume.id}
|
||||
|
||||
|
@ -722,7 +722,7 @@ class VolumeViewTests(test.TestCase):
|
|||
api.nova.server_list(IsA(http.HttpRequest), search_opts=None).\
|
||||
AndReturn([self.servers.list(), False])
|
||||
cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
|
||||
AndReturn(self.volume_snapshots.list())
|
||||
AndReturn(self.cinder_volume_snapshots.list())
|
||||
cinder.volume_list(IsA(http.HttpRequest), search_opts=None).\
|
||||
AndReturn(volumes)
|
||||
api.nova.server_list(IsA(http.HttpRequest), search_opts=None).\
|
||||
|
@ -744,8 +744,8 @@ class VolumeViewTests(test.TestCase):
|
|||
api.nova: ('server_list',),
|
||||
quotas: ('tenant_quota_usages',)})
|
||||
def test_delete_volume_error_existing_snapshot(self):
|
||||
volume = self.volumes.first()
|
||||
volumes = self.volumes.list()
|
||||
volume = self.cinder_volumes.first()
|
||||
volumes = self.cinder_volumes.list()
|
||||
formData = {'action':
|
||||
'volumes__delete__%s' % volume.id}
|
||||
exc = self.exceptions.cinder.__class__(400,
|
||||
|
@ -762,7 +762,7 @@ class VolumeViewTests(test.TestCase):
|
|||
api.nova.server_list(IsA(http.HttpRequest), search_opts=None).\
|
||||
AndReturn([self.servers.list(), False])
|
||||
cinder.volume_snapshot_list(IsA(http.HttpRequest))\
|
||||
.AndReturn(self.volume_snapshots.list())
|
||||
.AndReturn(self.cinder_volume_snapshots.list())
|
||||
cinder.volume_list(IsA(http.HttpRequest)).AndReturn(volumes)
|
||||
quotas.tenant_quota_usages(IsA(http.HttpRequest)).MultipleTimes().\
|
||||
AndReturn(self.quota_usages.first())
|
||||
|
@ -774,14 +774,14 @@ class VolumeViewTests(test.TestCase):
|
|||
self.assertEqual(list(res.context['messages'])[0].message,
|
||||
u'Unable to delete volume "%s". '
|
||||
u'One or more snapshots depend on it.' %
|
||||
volume.display_name)
|
||||
volume.name)
|
||||
|
||||
@test.create_stubs({cinder: ('volume_get',), api.nova: ('server_list',)})
|
||||
def test_edit_attachments(self):
|
||||
PREV = settings.OPENSTACK_HYPERVISOR_FEATURES['can_set_mount_point']
|
||||
settings.OPENSTACK_HYPERVISOR_FEATURES['can_set_mount_point'] = True
|
||||
|
||||
volume = self.volumes.first()
|
||||
volume = self.cinder_volumes.first()
|
||||
servers = [s for s in self.servers.list()
|
||||
if s.tenant_id == self.request.user.tenant_id]
|
||||
|
||||
|
@ -805,7 +805,7 @@ class VolumeViewTests(test.TestCase):
|
|||
@test.create_stubs({cinder: ('volume_get',), api.nova: ('server_list',)})
|
||||
def test_edit_attachments_cannot_set_mount_point(self):
|
||||
|
||||
volume = self.volumes.first()
|
||||
volume = self.cinder_volumes.first()
|
||||
servers = [s for s in self.servers.list()
|
||||
if s.tenant_id == self.request.user.tenant_id]
|
||||
|
||||
|
@ -828,7 +828,7 @@ class VolumeViewTests(test.TestCase):
|
|||
servers = [s for s in self.servers.list()
|
||||
if s.tenant_id == self.request.user.tenant_id]
|
||||
server = servers[0]
|
||||
volume = self.volumes.list()[0]
|
||||
volume = self.cinder_volumes.list()[0]
|
||||
|
||||
cinder.volume_get(IsA(http.HttpRequest), volume.id) \
|
||||
.AndReturn(volume)
|
||||
|
@ -856,14 +856,14 @@ class VolumeViewTests(test.TestCase):
|
|||
def test_create_button_disabled_when_quota_exceeded(self):
|
||||
quota_usages = self.quota_usages.first()
|
||||
quota_usages['volumes']['available'] = 0
|
||||
volumes = self.volumes.list()
|
||||
volumes = self.cinder_volumes.list()
|
||||
|
||||
cinder.volume_list(IsA(http.HttpRequest), search_opts=None)\
|
||||
.AndReturn(volumes)
|
||||
api.nova.server_list(IsA(http.HttpRequest), search_opts=None)\
|
||||
.AndReturn([self.servers.list(), False])
|
||||
cinder.volume_snapshot_list(IsA(http.HttpRequest))\
|
||||
.AndReturn(self.volume_snapshots.list())
|
||||
.AndReturn(self.cinder_volume_snapshots.list())
|
||||
cinder.volume_list(IsA(http.HttpRequest)).AndReturn(volumes)
|
||||
quotas.tenant_quota_usages(IsA(http.HttpRequest))\
|
||||
.MultipleTimes().AndReturn(quota_usages)
|
||||
|
@ -874,7 +874,7 @@ class VolumeViewTests(test.TestCase):
|
|||
self.assertTemplateUsed(res, 'project/volumes/index.html')
|
||||
|
||||
volumes = res.context['volumes_table'].data
|
||||
self.assertItemsEqual(volumes, self.volumes.list())
|
||||
self.assertItemsEqual(volumes, self.cinder_volumes.list())
|
||||
|
||||
create_link = tables.CreateVolume()
|
||||
url = create_link.get_link_url()
|
||||
|
@ -891,7 +891,7 @@ class VolumeViewTests(test.TestCase):
|
|||
@test.create_stubs({cinder: ('volume_get',),
|
||||
api.nova: ('server_get',)})
|
||||
def test_detail_view(self):
|
||||
volume = self.volumes.first()
|
||||
volume = self.cinder_volumes.first()
|
||||
server = self.servers.first()
|
||||
|
||||
volume.attachments = [{"server_id": server.id}]
|
||||
|
@ -908,10 +908,7 @@ class VolumeViewTests(test.TestCase):
|
|||
self.assertContains(res, "<h2>Volume Details: Volume name</h2>",
|
||||
1, 200)
|
||||
self.assertContains(res, "<dd>Volume name</dd>", 1, 200)
|
||||
self.assertContains(res,
|
||||
"<dd>41023e92-8008-4c8b-8059-7f2293ff3775</dd>",
|
||||
1,
|
||||
200)
|
||||
self.assertContains(res, "<dd>%s</dd>" % volume.id, 1, 200)
|
||||
self.assertContains(res, "<dd>Available</dd>", 1, 200)
|
||||
self.assertContains(res, "<dd>40 GB</dd>", 1, 200)
|
||||
self.assertContains(res,
|
||||
|
@ -924,8 +921,8 @@ class VolumeViewTests(test.TestCase):
|
|||
|
||||
@test.create_stubs({cinder: ('volume_get',)})
|
||||
def test_get_data(self):
|
||||
volume = self.volumes.first()
|
||||
volume.display_name = ''
|
||||
volume = self.cinder_volumes.get(name='v2_volume')
|
||||
volume._apiresource.name = ""
|
||||
|
||||
cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume)
|
||||
|
||||
|
@ -938,11 +935,11 @@ class VolumeViewTests(test.TestCase):
|
|||
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
|
||||
self.assertEqual(res.status_code, 200)
|
||||
self.assertEqual(volume.display_name, volume.id)
|
||||
self.assertEqual(volume.name, volume.id)
|
||||
|
||||
@test.create_stubs({cinder: ('volume_get',)})
|
||||
def test_detail_view_with_exception(self):
|
||||
volume = self.volumes.first()
|
||||
volume = self.cinder_volumes.first()
|
||||
server = self.servers.first()
|
||||
|
||||
volume.attachments = [{"server_id": server.id}]
|
||||
|
@ -961,19 +958,19 @@ class VolumeViewTests(test.TestCase):
|
|||
@test.create_stubs({cinder: ('volume_update',
|
||||
'volume_get',)})
|
||||
def test_update_volume(self):
|
||||
volume = self.volumes.get(name="my_volume")
|
||||
volume = self.cinder_volumes.get(name="my_volume")
|
||||
|
||||
cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume)
|
||||
cinder.volume_update(IsA(http.HttpRequest),
|
||||
volume.id,
|
||||
volume.display_name,
|
||||
volume.display_description)
|
||||
volume.name,
|
||||
volume.description)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
formData = {'method': 'UpdateForm',
|
||||
'name': volume.display_name,
|
||||
'description': volume.display_description}
|
||||
'name': volume.name,
|
||||
'description': volume.description}
|
||||
|
||||
url = reverse('horizon:project:volumes:volumes:update',
|
||||
args=[volume.id])
|
||||
|
@ -983,13 +980,13 @@ class VolumeViewTests(test.TestCase):
|
|||
@test.create_stubs({cinder: ('volume_get',
|
||||
'volume_extend')})
|
||||
def test_extend_volume(self):
|
||||
volume = self.volumes.first()
|
||||
volume = self.cinder_volumes.first()
|
||||
formData = {'name': u'A Volume I Am Making',
|
||||
'orig_size': volume.size,
|
||||
'new_size': 100}
|
||||
|
||||
cinder.volume_get(IsA(http.HttpRequest), volume.id).\
|
||||
AndReturn(self.volumes.first())
|
||||
AndReturn(self.cinder_volumes.first())
|
||||
|
||||
cinder.volume_extend(IsA(http.HttpRequest),
|
||||
volume.id,
|
||||
|
@ -1007,17 +1004,17 @@ class VolumeViewTests(test.TestCase):
|
|||
@test.create_stubs({cinder: ('volume_get',),
|
||||
quotas: ('tenant_limit_usages',)})
|
||||
def test_extend_volume_with_wrong_size(self):
|
||||
volume = self.volumes.first()
|
||||
volume = self.cinder_volumes.first()
|
||||
usage_limit = {'maxTotalVolumeGigabytes': 100,
|
||||
'gigabytesUsed': 20,
|
||||
'volumesUsed': len(self.volumes.list()),
|
||||
'volumesUsed': len(self.cinder_volumes.list()),
|
||||
'maxTotalVolumes': 6}
|
||||
formData = {'name': u'A Volume I Am Making',
|
||||
'orig_size': volume.size,
|
||||
'new_size': 10}
|
||||
|
||||
cinder.volume_get(IsA(http.HttpRequest), volume.id).\
|
||||
AndReturn(self.volumes.first())
|
||||
AndReturn(self.cinder_volumes.first())
|
||||
quotas.tenant_limit_usages(IsA(http.HttpRequest)).\
|
||||
AndReturn(usage_limit)
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ class ExtendView(forms.ModalFormView):
|
|||
def get_initial(self):
|
||||
volume = self.get_object()
|
||||
return {'id': self.kwargs['volume_id'],
|
||||
'name': volume.display_name,
|
||||
'name': volume.name,
|
||||
'orig_size': volume.size}
|
||||
|
||||
|
||||
|
@ -171,8 +171,8 @@ class UpdateView(forms.ModalFormView):
|
|||
def get_initial(self):
|
||||
volume = self.get_object()
|
||||
return {'volume_id': self.kwargs["volume_id"],
|
||||
'name': volume.display_name,
|
||||
'description': volume.display_description}
|
||||
'name': volume.name,
|
||||
'description': volume.description}
|
||||
|
||||
|
||||
class EditAttachmentsView(tables.DataTableView, forms.ModalFormView):
|
||||
|
|
|
@ -32,7 +32,8 @@ TEMPLATE_DEBUG = DEBUG
|
|||
# service API. For example, The identity service APIs have inconsistent
|
||||
# use of the decimal point, so valid options would be "2.0" or "3".
|
||||
# OPENSTACK_API_VERSIONS = {
|
||||
# "identity": 3
|
||||
# "identity": 3,
|
||||
# "volume": 2
|
||||
# }
|
||||
|
||||
# Set this to True if running on multi-domain model. When this is enabled, it
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from django.test.utils import override_settings
|
||||
|
||||
import cinderclient as cinder_client
|
||||
|
||||
from openstack_dashboard import api
|
||||
from openstack_dashboard.test import helpers as test
|
||||
|
@ -22,7 +25,7 @@ from openstack_dashboard.test import helpers as test
|
|||
class CinderApiTests(test.APITestCase):
|
||||
def test_volume_list(self):
|
||||
search_opts = {'all_tenants': 1}
|
||||
volumes = self.volumes.list()
|
||||
volumes = self.cinder_volumes.list()
|
||||
cinderclient = self.stub_cinderclient()
|
||||
cinderclient.volumes = self.mox.CreateMockAnything()
|
||||
cinderclient.volumes.list(search_opts=search_opts,).AndReturn(volumes)
|
||||
|
@ -32,7 +35,7 @@ class CinderApiTests(test.APITestCase):
|
|||
api.cinder.volume_list(self.request, search_opts=search_opts)
|
||||
|
||||
def test_volume_snapshot_list(self):
|
||||
volume_snapshots = self.volume_snapshots.list()
|
||||
volume_snapshots = self.cinder_volume_snapshots.list()
|
||||
cinderclient = self.stub_cinderclient()
|
||||
cinderclient.volume_snapshots = self.mox.CreateMockAnything()
|
||||
cinderclient.volume_snapshots.list().AndReturn(volume_snapshots)
|
||||
|
@ -46,7 +49,7 @@ class CinderApiTests(test.APITestCase):
|
|||
for service in catalog:
|
||||
if service["type"] == "volume":
|
||||
self.service_catalog.remove(service)
|
||||
volume_snapshots = self.volume_snapshots.list()
|
||||
volume_snapshots = self.cinder_volume_snapshots.list()
|
||||
|
||||
cinderclient = self.stub_cinderclient()
|
||||
cinderclient.volume_snapshots = self.mox.CreateMockAnything()
|
||||
|
@ -54,3 +57,109 @@ class CinderApiTests(test.APITestCase):
|
|||
self.mox.ReplayAll()
|
||||
|
||||
api.cinder.volume_snapshot_list(self.request)
|
||||
|
||||
|
||||
class CinderApiVersionTests(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(CinderApiVersionTests, self).setUp()
|
||||
# The version is set when the module is loaded. Reset the
|
||||
# active version each time so that we can test with different
|
||||
# versions.
|
||||
api.cinder.VERSIONS._active = None
|
||||
|
||||
def test_default_client_is_v1(self):
|
||||
client = api.cinder.cinderclient(self.request)
|
||||
self.assertIsInstance(client, cinder_client.v1.client.Client)
|
||||
|
||||
@override_settings(OPENSTACK_API_VERSIONS={'volume': 1})
|
||||
def test_v1_setting_returns_v1_client(self):
|
||||
client = api.cinder.cinderclient(self.request)
|
||||
self.assertIsInstance(client, cinder_client.v1.client.Client)
|
||||
|
||||
@override_settings(OPENSTACK_API_VERSIONS={'volume': 2})
|
||||
def test_v2_setting_returns_v2_client(self):
|
||||
client = api.cinder.cinderclient(self.request)
|
||||
self.assertIsInstance(client, cinder_client.v2.client.Client)
|
||||
|
||||
def test_get_v1_volume_attributes(self):
|
||||
# Get a v1 volume
|
||||
volume = self.cinder_volumes.first()
|
||||
self.assertTrue(hasattr(volume._apiresource, 'display_name'))
|
||||
self.assertFalse(hasattr(volume._apiresource, 'name'))
|
||||
|
||||
name = "A test volume name"
|
||||
description = "A volume description"
|
||||
setattr(volume._apiresource, 'display_name', name)
|
||||
setattr(volume._apiresource, 'display_description', description)
|
||||
self.assertEqual(volume.name, name)
|
||||
self.assertEqual(volume.description, description)
|
||||
|
||||
def test_get_v2_volume_attributes(self):
|
||||
# Get a v2 volume
|
||||
volume = self.cinder_volumes.get(name="v2_volume")
|
||||
self.assertTrue(hasattr(volume._apiresource, 'name'))
|
||||
self.assertFalse(hasattr(volume._apiresource, 'display_name'))
|
||||
|
||||
name = "A v2 test volume name"
|
||||
description = "A v2 volume description"
|
||||
setattr(volume._apiresource, 'name', name)
|
||||
setattr(volume._apiresource, 'description', description)
|
||||
self.assertEqual(volume.name, name)
|
||||
self.assertEqual(volume.description, description)
|
||||
|
||||
def test_get_v1_snapshot_attributes(self):
|
||||
# Get a v1 snapshot
|
||||
snapshot = self.cinder_volume_snapshots.first()
|
||||
self.assertFalse(hasattr(snapshot._apiresource, 'name'))
|
||||
|
||||
name = "A test snapshot name"
|
||||
description = "A snapshot description"
|
||||
setattr(snapshot._apiresource, 'display_name', name)
|
||||
setattr(snapshot._apiresource, 'display_description', description)
|
||||
self.assertEqual(snapshot.name, name)
|
||||
self.assertEqual(snapshot.description, description)
|
||||
|
||||
def test_get_v2_snapshot_attributes(self):
|
||||
# Get a v2 snapshot
|
||||
snapshot = self.cinder_volume_snapshots.get(
|
||||
description="v2 volume snapshot description")
|
||||
self.assertFalse(hasattr(snapshot._apiresource, 'display_name'))
|
||||
|
||||
name = "A v2 test snapshot name"
|
||||
description = "A v2 snapshot description"
|
||||
setattr(snapshot._apiresource, 'name', name)
|
||||
setattr(snapshot._apiresource, 'description', description)
|
||||
self.assertEqual(snapshot.name, name)
|
||||
self.assertEqual(snapshot.description, description)
|
||||
|
||||
def test_get_id_for_nameless_volume(self):
|
||||
volume = self.cinder_volumes.first()
|
||||
setattr(volume._apiresource, 'display_name', "")
|
||||
self.assertEqual(volume.name, volume.id)
|
||||
|
||||
@override_settings(OPENSTACK_API_VERSIONS={'volume': 1})
|
||||
def test_adapt_dictionary_to_v1(self):
|
||||
volume = self.cinder_volumes.first()
|
||||
data = {'name': volume.name,
|
||||
'description': volume.description,
|
||||
'size': volume.size}
|
||||
|
||||
ret_data = api.cinder._replace_v2_parameters(data)
|
||||
self.assertIn('display_name', ret_data.keys())
|
||||
self.assertIn('display_description', ret_data.keys())
|
||||
self.assertNotIn('name', ret_data.keys())
|
||||
self.assertNotIn('description', ret_data.keys())
|
||||
|
||||
@override_settings(OPENSTACK_API_VERSIONS={'volume': 2})
|
||||
def test_adapt_dictionary_to_v2(self):
|
||||
volume = self.cinder_volumes.first()
|
||||
data = {'name': volume.name,
|
||||
'description': volume.description,
|
||||
'size': volume.size}
|
||||
|
||||
ret_data = api.cinder._replace_v2_parameters(data)
|
||||
self.assertIn('name', ret_data.keys())
|
||||
self.assertIn('description', ret_data.keys())
|
||||
self.assertNotIn('display_name', ret_data.keys())
|
||||
self.assertNotIn('display_description', ret_data.keys())
|
||||
|
|
|
@ -14,25 +14,94 @@
|
|||
|
||||
from cinderclient.v1 import availability_zones
|
||||
from cinderclient.v1 import quotas
|
||||
from cinderclient.v1 import volume_snapshots as vol_snaps
|
||||
from cinderclient.v1 import volumes
|
||||
from cinderclient.v2 import volume_snapshots as vol_snaps_v2
|
||||
from cinderclient.v2 import volumes as volumes_v2
|
||||
|
||||
from openstack_dashboard.api import base
|
||||
from openstack_dashboard import api
|
||||
from openstack_dashboard.usage import quotas as usage_quotas
|
||||
|
||||
from openstack_dashboard.test.test_data import utils
|
||||
|
||||
|
||||
def data(TEST):
|
||||
TEST.cinder_volumes = utils.TestDataContainer()
|
||||
TEST.cinder_volume_snapshots = utils.TestDataContainer()
|
||||
TEST.cinder_quotas = utils.TestDataContainer()
|
||||
TEST.cinder_quota_usages = utils.TestDataContainer()
|
||||
TEST.cinder_availability_zones = utils.TestDataContainer()
|
||||
|
||||
# Volumes - Cinder v1
|
||||
volume = volumes.Volume(volumes.VolumeManager(None),
|
||||
{'id': "11023e92-8008-4c8b-8059-7f2293ff3887",
|
||||
'status': 'available',
|
||||
'size': 40,
|
||||
'display_name': 'Volume name',
|
||||
'display_description': 'Volume description',
|
||||
'created_at': '2014-01-27 10:30:00',
|
||||
'volume_type': None,
|
||||
'attachments': []})
|
||||
nameless_volume = volumes.Volume(volumes.VolumeManager(None),
|
||||
dict(id="4b069dd0-6eaa-4272-8abc-5448a68f1cce",
|
||||
status='available',
|
||||
size=10,
|
||||
display_name='',
|
||||
display_description='',
|
||||
device="/dev/hda",
|
||||
created_at='2010-11-21 18:34:25',
|
||||
volume_type='vol_type_1',
|
||||
attachments=[]))
|
||||
other_volume = volumes.Volume(volumes.VolumeManager(None),
|
||||
{'id': "21023e92-8008-1234-8059-7f2293ff3889",
|
||||
'status': 'in-use',
|
||||
'size': 10,
|
||||
'display_name': u'my_volume',
|
||||
'display_description': '',
|
||||
'created_at': '2013-04-01 10:30:00',
|
||||
'volume_type': None,
|
||||
'attachments': [{"id": "1", "server_id": '1',
|
||||
"device": "/dev/hda"}]})
|
||||
TEST.cinder_volumes.add(api.cinder.Volume(volume))
|
||||
TEST.cinder_volumes.add(api.cinder.Volume(nameless_volume))
|
||||
TEST.cinder_volumes.add(api.cinder.Volume(other_volume))
|
||||
|
||||
# Volumes - Cinder v2
|
||||
volume_v2 = volumes_v2.Volume(volumes_v2.VolumeManager(None),
|
||||
{'id': "31023e92-8008-4c8b-8059-7f2293ff1234",
|
||||
'name': 'v2_volume',
|
||||
'description': "v2 Volume Description",
|
||||
'status': 'available',
|
||||
'size': 20,
|
||||
'created_at': '2014-01-27 10:30:00',
|
||||
'volume_type': None,
|
||||
'attachments': []})
|
||||
TEST.cinder_volumes.add(api.cinder.Volume(volume_v2))
|
||||
|
||||
snapshot = vol_snaps.Snapshot(vol_snaps.SnapshotManager(None),
|
||||
{'id': '5f3d1c33-7d00-4511-99df-a2def31f3b5d',
|
||||
'display_name': 'test snapshot',
|
||||
'display_description': 'volume snapshot',
|
||||
'size': 40,
|
||||
'status': 'available',
|
||||
'volume_id': '11023e92-8008-4c8b-8059-7f2293ff3887'})
|
||||
snapshot2 = vol_snaps_v2.Snapshot(vol_snaps_v2.SnapshotManager(None),
|
||||
{'id': 'c9d0881a-4c0b-4158-a212-ad27e11c2b0f',
|
||||
'name': '',
|
||||
'description': 'v2 volume snapshot description',
|
||||
'size': 80,
|
||||
'status': 'available',
|
||||
'volume_id': '31023e92-8008-4c8b-8059-7f2293ff1234'})
|
||||
|
||||
TEST.cinder_volume_snapshots.add(api.cinder.VolumeSnapshot(snapshot))
|
||||
TEST.cinder_volume_snapshots.add(api.cinder.VolumeSnapshot(snapshot2))
|
||||
|
||||
# Quota Sets
|
||||
quota_data = dict(volumes='1',
|
||||
snapshots='1',
|
||||
gigabytes='1000')
|
||||
quota = quotas.QuotaSet(quotas.QuotaSetManager(None), quota_data)
|
||||
#TEST.quotas.cinder = QuotaSetWrapper(quota)
|
||||
TEST.cinder_quotas.add(base.QuotaSet(quota))
|
||||
TEST.cinder_quotas.add(api.base.QuotaSet(quota))
|
||||
|
||||
# Quota Usages
|
||||
quota_usage_data = {'gigabytes': {'used': 0,
|
||||
|
@ -43,7 +112,7 @@ def data(TEST):
|
|||
'quota': 10}}
|
||||
quota_usage = usage_quotas.QuotaUsage()
|
||||
for k, v in quota_usage_data.items():
|
||||
quota_usage.add_quota(base.Quota(k, v['quota']))
|
||||
quota_usage.add_quota(api.base.Quota(k, v['quota']))
|
||||
quota_usage.tally(k, v['used'])
|
||||
|
||||
TEST.cinder_quota_usages.add(quota_usage)
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
from datetime import timedelta # noqa
|
||||
|
||||
from django.conf import settings
|
||||
|
@ -47,7 +48,7 @@ SERVICE_CATALOG = [
|
|||
"internalURL": "http://int.nova2.example.com:8774/v2",
|
||||
"publicURL": "http://public.nova2.example.com:8774/v2"}]},
|
||||
{"type": "volume",
|
||||
"name": "nova",
|
||||
"name": "cinder",
|
||||
"endpoints_links": [],
|
||||
"endpoints": [
|
||||
{"region": "RegionOne",
|
||||
|
@ -126,7 +127,9 @@ SERVICE_CATALOG = [
|
|||
|
||||
|
||||
def data(TEST):
|
||||
TEST.service_catalog = SERVICE_CATALOG
|
||||
# Make a deep copy of the catalog to avoid persisting side-effects
|
||||
# when tests modify the catalog.
|
||||
TEST.service_catalog = copy.deepcopy(SERVICE_CATALOG)
|
||||
TEST.tokens = utils.TestDataContainer()
|
||||
TEST.domains = utils.TestDataContainer()
|
||||
TEST.users = utils.TestDataContainer()
|
||||
|
@ -205,7 +208,7 @@ def data(TEST):
|
|||
user5 = users.User(users.UserManager(None), user_dict)
|
||||
TEST.users.add(user, user2, user3, user4, user5)
|
||||
TEST.user = user # Your "current" user
|
||||
TEST.user.service_catalog = SERVICE_CATALOG
|
||||
TEST.user.service_catalog = copy.deepcopy(SERVICE_CATALOG)
|
||||
|
||||
group_dict = {'id': "1",
|
||||
'name': 'group_one',
|
||||
|
|
Loading…
Reference in New Issue