Merge "Show volume snapshots in admin volume detail page"
This commit is contained in:
commit
9d159da4af
@ -78,3 +78,8 @@ class VolumeSnapshotsTable(volumes_tables.VolumesTableBase):
|
||||
status_columns = ("status",)
|
||||
columns = ('tenant', 'host', 'name', 'description', 'size', 'status',
|
||||
'volume_name',)
|
||||
|
||||
|
||||
class VolumeDetailsSnapshotsTable(VolumeSnapshotsTable):
|
||||
class Meta(VolumeSnapshotsTable.Meta):
|
||||
columns = ('name', 'description', 'size', 'status', 'volume_name',)
|
||||
|
@ -10,6 +10,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from openstack_dashboard.dashboards.admin.snapshots import tables
|
||||
from openstack_dashboard.dashboards.project.volumes import tabs as project_tabs
|
||||
|
||||
|
||||
@ -27,8 +28,8 @@ class OverviewTab(project_tabs.OverviewTab):
|
||||
|
||||
|
||||
class SnapshotTab(project_tabs.SnapshotTab):
|
||||
pass
|
||||
table_classes = (tables.VolumeDetailsSnapshotsTable,)
|
||||
|
||||
|
||||
class VolumeDetailTabs(project_tabs.VolumeDetailTabs):
|
||||
tabs = (OverviewTab, project_tabs.SnapshotTab)
|
||||
tabs = (OverviewTab, SnapshotTab)
|
||||
|
@ -30,6 +30,7 @@ from openstack_dashboard.test import helpers as test
|
||||
from openstack_dashboard.dashboards.admin.snapshots import forms
|
||||
|
||||
|
||||
DETAIL_URL = ('horizon:admin:volumes:detail')
|
||||
INDEX_URL = reverse('horizon:admin:volumes:index')
|
||||
|
||||
|
||||
@ -385,3 +386,52 @@ class VolumeTests(test.BaseAdminViewTests):
|
||||
|
||||
mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)
|
||||
self.assertNotContains(res, status_option)
|
||||
|
||||
def test_detail_view_snapshot_tab(self):
|
||||
volume = self.cinder_volumes.first()
|
||||
server = self.servers.first()
|
||||
snapshots = self.cinder_volume_snapshots.list()
|
||||
this_volume_snapshots = [snapshot for snapshot in snapshots
|
||||
if snapshot.volume_id == volume.id]
|
||||
volume.attachments = [{"server_id": server.id}]
|
||||
volume_limits = self.cinder_limits['absolute']
|
||||
with mock.patch.object(api.nova, 'server_get',
|
||||
return_value=server) as mock_server_get, \
|
||||
mock.patch.object(
|
||||
cinder, 'tenant_absolute_limits',
|
||||
return_value=volume_limits) as mock_limits, \
|
||||
mock.patch.object(
|
||||
cinder, 'volume_get',
|
||||
return_value=volume) as mock_volume_get, \
|
||||
mock.patch.object(
|
||||
cinder, 'volume_snapshot_list',
|
||||
return_value=this_volume_snapshots) \
|
||||
as mock_snapshot_list, \
|
||||
mock.patch.object(
|
||||
cinder, 'message_list',
|
||||
return_value=[]) as mock_message_list:
|
||||
|
||||
url = (reverse(DETAIL_URL, args=[volume.id]) + '?' +
|
||||
'='.join(['tab', 'volume_details__snapshots_tab']))
|
||||
res = self.client.get(url)
|
||||
|
||||
self.assertTemplateUsed(res, 'horizon/common/_detail.html')
|
||||
self.assertEqual(res.context['volume'].id, volume.id)
|
||||
self.assertEqual(len(res.context['table'].data),
|
||||
len(this_volume_snapshots))
|
||||
self.assertNoMessages()
|
||||
|
||||
mock_server_get.assert_called_once_with(test.IsHttpRequest(),
|
||||
server.id)
|
||||
mock_volume_get.assert_called_once_with(test.IsHttpRequest(),
|
||||
volume.id)
|
||||
mock_snapshot_list.assert_called_once_with(
|
||||
test.IsHttpRequest(),
|
||||
search_opts={'volume_id': volume.id, 'all_tenants': True})
|
||||
mock_limits.assert_called_once()
|
||||
mock_message_list.assert_called_once_with(
|
||||
test.IsHttpRequest(),
|
||||
{
|
||||
'resource_uuid': volume.id,
|
||||
'resource_type': 'volume'
|
||||
})
|
||||
|
@ -118,6 +118,11 @@ class DetailView(volumes_views.DetailView):
|
||||
context["actions"] = table.render_row_actions(context["volume"])
|
||||
return context
|
||||
|
||||
def get_search_opts(self, volume):
|
||||
search_opts = super(DetailView, self).get_search_opts(volume)
|
||||
search_opts['all_tenants'] = True
|
||||
return search_opts
|
||||
|
||||
def get_redirect_url(self):
|
||||
return reverse('horizon:admin:volumes:index')
|
||||
|
||||
|
@ -14,10 +14,8 @@
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import tabs
|
||||
|
||||
from openstack_dashboard.api import cinder
|
||||
from openstack_dashboard.dashboards.project.snapshots import tables
|
||||
|
||||
|
||||
@ -42,26 +40,12 @@ class SnapshotTab(tabs.TableTab):
|
||||
name = _("Snapshots")
|
||||
slug = "snapshots_tab"
|
||||
template_name = "horizon/common/_detail_table.html"
|
||||
dashboard = 'project'
|
||||
preload = False
|
||||
|
||||
def get_volume_snapshots_data(self):
|
||||
volume_id = self.tab_group.kwargs['volume_id']
|
||||
try:
|
||||
snapshots = cinder.volume_snapshot_list(
|
||||
self.request, search_opts={'volume_id': volume_id})
|
||||
except Exception:
|
||||
snapshots = []
|
||||
exceptions.handle(self.request,
|
||||
_("Unable to retrieve volume snapshots for "
|
||||
"volume %s.") % volume_id)
|
||||
|
||||
try:
|
||||
volume = cinder.volume_get(self.request, volume_id)
|
||||
except Exception:
|
||||
volume = None
|
||||
exceptions.handle(self.request,
|
||||
_("Unable to retrieve volume details for "
|
||||
"volume %s.") % volume_id)
|
||||
snapshots = self.tab_group.kwargs['snapshots']
|
||||
volume = self.tab_group.kwargs['volume']
|
||||
|
||||
if volume is not None:
|
||||
for snapshot in snapshots:
|
||||
|
@ -1423,8 +1423,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
||||
len(this_volume_snapshots))
|
||||
self.assertNoMessages()
|
||||
|
||||
mock_get.assert_called_with(test.IsHttpRequest(), volume.id)
|
||||
mock_snapshot_list.assert_called_with(
|
||||
mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)
|
||||
mock_snapshot_list.assert_called_once_with(
|
||||
test.IsHttpRequest(), search_opts={'volume_id': volume.id})
|
||||
mock_limits.assert_called_once()
|
||||
mock_message.assert_called_once_with(
|
||||
|
@ -147,7 +147,7 @@ class DetailView(tabs.TabbedTableView):
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(DetailView, self).get_context_data(**kwargs)
|
||||
volume = self.get_data()
|
||||
volume, snapshots = self.get_data()
|
||||
table = volume_tables.VolumesTable(self.request)
|
||||
context["volume"] = volume
|
||||
context["url"] = self.get_redirect_url()
|
||||
@ -156,13 +156,17 @@ class DetailView(tabs.TabbedTableView):
|
||||
volume.status_label = filters.get_display_label(choices, volume.status)
|
||||
return context
|
||||
|
||||
def get_search_opts(self, volume):
|
||||
return {'volume_id': volume.id}
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_data(self):
|
||||
try:
|
||||
volume_id = self.kwargs['volume_id']
|
||||
volume = cinder.volume_get(self.request, volume_id)
|
||||
search_opts = self.get_search_opts(volume)
|
||||
snapshots = cinder.volume_snapshot_list(
|
||||
self.request, search_opts={'volume_id': volume.id})
|
||||
self.request, search_opts=search_opts)
|
||||
if snapshots:
|
||||
setattr(volume, 'has_snapshot', True)
|
||||
for att in volume.attachments:
|
||||
@ -185,14 +189,15 @@ class DetailView(tabs.TabbedTableView):
|
||||
_('Unable to retrieve volume messages.'),
|
||||
ignore=True,
|
||||
)
|
||||
return volume
|
||||
return volume, snapshots
|
||||
|
||||
def get_redirect_url(self):
|
||||
return reverse('horizon:project:volumes:index')
|
||||
|
||||
def get_tabs(self, request, *args, **kwargs):
|
||||
volume = self.get_data()
|
||||
return self.tab_group_class(request, volume=volume, **kwargs)
|
||||
volume, snapshots = self.get_data()
|
||||
return self.tab_group_class(
|
||||
request, volume=volume, snapshots=snapshots, **kwargs)
|
||||
|
||||
|
||||
class CreateView(forms.ModalFormView):
|
||||
|
Loading…
Reference in New Issue
Block a user