Merge "Add Group and Group Snapshot colunm"

This commit is contained in:
Zuul 2019-03-19 10:57:15 +00:00 committed by Gerrit Code Review
commit 4c82dda11c
8 changed files with 167 additions and 7 deletions

View File

@ -63,6 +63,10 @@ class VolumeSnapshotsTable(volumes_tables.VolumesTableBase):
link="horizon:admin:volumes:detail")
host = tables.Column("host_name", verbose_name=_("Host"))
tenant = tables.Column("tenant_name", verbose_name=_("Project"))
group_snapshot = snapshots_tables.GroupSnapshotNameColumn(
"name",
verbose_name=_("Group Snapshot"),
link="horizon:admin:vg_snapshots:detail")
class Meta(object):
name = "volume_snapshots"
@ -77,7 +81,7 @@ class VolumeSnapshotsTable(volumes_tables.VolumesTableBase):
row_class = UpdateRow
status_columns = ("status",)
columns = ('tenant', 'host', 'name', 'description', 'size', 'status',
'volume_name',)
'group_snapshot', 'volume_name',)
class VolumeDetailsSnapshotsTable(VolumeSnapshotsTable):

View File

@ -37,6 +37,7 @@ class SnapshotsView(tables.PagedTableMixin, tables.DataTableView):
page_title = _("Volume Snapshots")
def get_data(self):
needs_gs = False
if cinder.is_volume_service_enabled(self.request):
try:
marker, sort_dir = self._get_marker()
@ -54,6 +55,18 @@ class SnapshotsView(tables.PagedTableMixin, tables.DataTableView):
exceptions.handle(self.request, _("Unable to retrieve "
"volume snapshots."))
needs_gs = any(getattr(snapshot, 'group_snapshot_id', None)
for snapshot in snapshots)
if needs_gs:
try:
group_snapshots = cinder.group_snapshot_list(
self.request, search_opts={'all_tenants': True})
group_snapshots = dict((gs.id, gs) for gs
in group_snapshots)
except Exception:
group_snapshots = {}
exceptions.handle(self.request,
_("Unable to retrieve group snapshots."))
# Gather our tenants to correlate against volume IDs
try:
tenants, has_more = keystone.tenant_list(self.request)
@ -66,6 +79,12 @@ class SnapshotsView(tables.PagedTableMixin, tables.DataTableView):
tenant_dict = dict((t.id, t) for t in tenants)
for snapshot in snapshots:
volume = volumes.get(snapshot.volume_id)
if needs_gs:
group_snapshot = group_snapshots.get(
snapshot.group_snapshot_id)
snapshot.group_snapshot = group_snapshot
else:
snapshot.group_snapshot = None
tenant_id = snapshot.project_id
tenant = tenant_dict.get(tenant_id, None)
snapshot._volume = volume

View File

@ -105,6 +105,10 @@ class VolumesTable(volumes_tables.VolumesTable):
host = tables.Column("os-vol-host-attr:host", verbose_name=_("Host"))
tenant = tables.Column(lambda obj: getattr(obj, 'tenant_name', None),
verbose_name=_("Project"))
group = volumes_tables.GroupNameColumn(
"name",
verbose_name=_("Group"),
link="horizon:admin:volume_groups:detail")
class Meta(object):
name = "volumes"
@ -119,5 +123,5 @@ class VolumesTable(volumes_tables.VolumesTable):
UnmanageVolumeAction,
MigrateVolume,
volumes_tables.UpdateMetadata)
columns = ('tenant', 'host', 'name', 'size', 'status', 'volume_type',
'attachments', 'bootable', 'encryption',)
columns = ('tenant', 'host', 'name', 'size', 'status', 'group',
'volume_type', 'attachments', 'bootable', 'encryption',)

View File

@ -15,10 +15,13 @@ from openstack_dashboard.dashboards.project.volumes import tabs as project_tabs
class OverviewTab(project_tabs.OverviewTab):
template_name = ("admin/volumes/_detail_overview.html")
def get_context_data(self, request):
volume = self.tab_group.kwargs['volume']
return {
'volume': self.tab_group.kwargs['volume'],
'volume': volume,
'group': volume.group,
'detail_url': {
'instance': 'horizon:admin:instances:detail',
'image': 'horizon:admin:images:detail',

View File

@ -0,0 +1,126 @@
{% load i18n sizeformat parse_date %}
<div class="detail">
<dl class="dl-horizontal">
<dt>{% trans "Name" %}</dt>
<dd data-display="{{ volume.name|default:volume.id }}" class="word-wrap">{{ volume.name }}</dd>
<dt>{% trans "ID" %}</dt>
<dd>{{ volume.id }}</dd>
{% if volume.description %}
<dt>{% trans "Description" %}</dt>
<dd>{{ volume.description }}</dd>
{% endif %}
<dt>{% trans "Project ID" %}</dt>
<dd>{{ volume.tenant_id|default:_("-") }}</dd>
<dt>{% trans "Status" %}</dt>
<dd>{{ volume.status_label|capfirst }}</dd>
<dt>{% trans "Group" %}</dt>
{% if group %}
<dd><a href="{% url 'horizon:admin:volume_groups:detail' volume.group_id %}">{{ group.name_or_id }}</a></dd>
{% else %}
<dd>{% trans "-" %}</dd>
{% endif %}
</dl>
<h4>{% trans "Specs" %}</h4>
<hr class="header_rule">
<dl class="dl-horizontal">
<dt>{% trans "Size" %}</dt>
<dd>{{ volume.size }} {% trans "GiB" %}</dd>
{% if volume.volume_type %}
<dt>{% trans "Type" %}</dt>
<dd>{{ volume.volume_type }}</dd>
{% endif %}
{% if volume.availabilty_zone %}
<dt>{% trans "Availability zone" %}</dt>
<dd>{{ volume.availability_zone }}</dd>
{% endif %}
<dt>{% trans "Bootable" %}</dt>
<dd>{{ volume.is_bootable|yesno|capfirst }}</dd>
<dt>{% trans "Encrypted" %}</dt>
{% if volume.encrypted %}
<dd><a href="{% url detail_url.encryption volume.id %}">{% trans "Yes" %}</a></dd>
{% else %}
<dd>{% trans "No" %}</dd>
{% endif %}
<dt>{% trans "Created" context "Created time" %}</dt>
<dd>{{ volume.created_at|parse_date }}</dd>
</dl>
<h4>{% trans "Attachments" %}</h4>
<hr class="header_rule">
<dl class="dl-horizontal">
{% for attachment in volume.attachments %}
<dt>{% trans "Attached To" %}</dt>
<dd class="word-wrap">
{% url detail_url.instance attachment.server_id as instance_url %}
{% blocktrans trimmed with instance_name=attachment.instance.name device=attachment.device %}
<a href="{{ instance_url }}">{{ instance_name }}</a> on {{ device }}
{% endblocktrans %}
</dd>
{% empty %}
<dt>{% trans "Attached To" %}</dt>
<dd><em>{% trans "Not attached" %}</em></dd>
{% endfor %}
</dl>
{% if volume.volume_image_metadata %}
<h4>{% trans "Volume Source" %}</h4>
<hr class="header_rule">
<dl class="dl-horizontal">
<dt>{% trans "Image" %}</dt>
<dd class="word-wrap">
{% url detail_url.image volume.volume_image_metadata.image_id as image_url %}
<a href="{{ image_url }}">{{ volume.volume_image_metadata.image_name }}</a>
</dd>
</dl>
{% endif %}
<h4>{% trans "Metadata" %}</h4>
<hr class="header_rule">
<dl class="dl-horizontal">
{% if volume.metadata.items %}
{% for key, value in volume.metadata.items %}
<dt>{{ key }}</dt>
<dd>{{ value }}</dd>
{% endfor %}
{% else %}
<dd>{% trans "None" %}</dd>
{% endif %}
</dl>
{% if volume.transfer %}
<h4>{% trans "Volume Transfer" %}</h4>
<hr class="header_rule">
<dl>
<dt>{% trans "ID" %}</dt>
<dd>{{ volume.transfer.id }}</dd>
</dl>
<dl>
<dt>{% trans "Name" %}</dt>
<dd class="word-wrap">{{ volume.transfer.name }}</dd>
</dl>
<dl>
<dt>{% trans "Created" context "Created time" %}</dt>
<dd>{{ volume.transfer.created_at|parse_date }}</dd>
</dl>
{% endif %}
{% if volume.messages %}
<h4>{% trans "Messages" %}</h4>
<hr class="header_rule">
<div>
{% for m in volume.messages %}
<div class="alert
{% if m.message_level == 'ERROR' %}alert-danger
{% elif m.message_level == 'WARNING' %}alert-warning
{% elif m.message_level == 'INFO' %}alert-info
{% else %}alert-success
{% endif %}
">
{{ m.user_message }}
</div>
{% endfor %}
</div>
{% endif %}
</div>

View File

@ -100,6 +100,8 @@ class VolumesView(tables.PagedTableMixin, volumes_views.VolumeTableMixIn,
def _task_get_volumes():
volumes.extend(self._get_volumes(search_opts=filters))
# update group name for volumes
self._get_groups(volumes, search_opts={'all_tenants': True})
attached_instance_ids.extend(
self._get_attached_instance_ids(volumes))

View File

@ -79,7 +79,8 @@ class VolumeIndexViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
self.mock_volume_snapshot_list.assert_called_once()
if with_groups:
self.mock_group_list.assert_called_once_with(test.IsHttpRequest())
self.mock_group_list.assert_called_once_with(test.IsHttpRequest(),
search_opts=None)
self.mock_volume_backup_supported.assert_called_with(
test.IsHttpRequest())

View File

@ -104,13 +104,14 @@ class VolumeTableMixIn(object):
attached_instance_ids.append(server_id)
return attached_instance_ids
def _get_groups(self, volumes):
def _get_groups(self, volumes, search_opts=None):
needs_group = False
if volumes and hasattr(volumes[0], 'group_id'):
needs_group = True
if needs_group:
try:
groups_list = cinder.group_list(self.request)
groups_list = cinder.group_list(self.request,
search_opts=search_opts)
groups = dict((g.id, g) for g in groups_list)
except Exception:
groups = {}