Standardize display name on detail pages
* Standardized overview pages for volume, image and snapshot as per the instance overview page. Fixes bug #1207770 Change-Id: I7ae48542f4c8732c92dc4393dbaaea81158d34d6
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
{% block title %}{% trans "Volume Details" %}{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Volume Detail") %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Volume Details: ")|add:volume.display_name|default:_("Volume Details:") %}
|
||||
{% endblock page_header %}
|
||||
|
||||
{% block main %}
|
||||
|
@@ -17,11 +17,8 @@
|
||||
from django.core.urlresolvers import reverse # noqa
|
||||
from django.utils.translation import ugettext_lazy as _ # noqa
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import tabs
|
||||
|
||||
from openstack_dashboard import api
|
||||
|
||||
|
||||
class OverviewTab(tabs.Tab):
|
||||
name = _("Overview")
|
||||
@@ -29,15 +26,7 @@ class OverviewTab(tabs.Tab):
|
||||
template_name = "project/images_and_snapshots/images/_detail_overview.html"
|
||||
|
||||
def get_context_data(self, request):
|
||||
image_id = self.tab_group.kwargs['image_id']
|
||||
try:
|
||||
image = api.glance.image_get(self.request, image_id)
|
||||
except Exception:
|
||||
redirect = reverse('horizon:project:images_and_snapshots:index')
|
||||
exceptions.handle(request,
|
||||
_('Unable to retrieve image details.'),
|
||||
redirect=redirect)
|
||||
return {'image': image}
|
||||
return {"image": self.tab_group.kwargs['image']}
|
||||
|
||||
|
||||
class ImageDetailTabs(tabs.TabGroup):
|
||||
|
@@ -163,10 +163,13 @@ class ImageViewTests(test.TestCase):
|
||||
res = self.client.get(
|
||||
reverse('horizon:project:images_and_snapshots:images:detail',
|
||||
args=[image.id]))
|
||||
|
||||
self.assertTemplateUsed(res,
|
||||
'project/images_and_snapshots/images/detail.html')
|
||||
self.assertEqual(res.context['image'].name, image.name)
|
||||
self.assertEqual(res.context['image'].protected, image.protected)
|
||||
self.assertContains(res, "<h2>Image Details: %s</h2>" % image.name,
|
||||
1, 200)
|
||||
|
||||
@test.create_stubs({api.glance: ('image_get',)})
|
||||
def test_protected_image_detail_get(self):
|
||||
|
@@ -82,3 +82,25 @@ class UpdateView(forms.ModalFormView):
|
||||
class DetailView(tabs.TabView):
|
||||
tab_group_class = project_tabs.ImageDetailTabs
|
||||
template_name = 'project/images_and_snapshots/images/detail.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(DetailView, self).get_context_data(**kwargs)
|
||||
context["image"] = self.get_data()
|
||||
return context
|
||||
|
||||
def get_data(self):
|
||||
if not hasattr(self, "_image"):
|
||||
try:
|
||||
image_id = self.kwargs['image_id']
|
||||
self._image = api.glance.image_get(self.request, image_id)
|
||||
except Exception:
|
||||
url = reverse('horizon:project:images_and_snapshots:index')
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to retrieve image details.'),
|
||||
redirect=url)
|
||||
|
||||
return self._image
|
||||
|
||||
def get_tabs(self, request, *args, **kwargs):
|
||||
image = self.get_data()
|
||||
return self.tab_group_class(request, image=image, **kwargs)
|
||||
|
@@ -1,10 +1,10 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "Image Detail "%}{% endblock %}
|
||||
{% block title %}{% trans "Image Details"%}{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
{% include "horizon/common/_page_header.html" with title="Image Detail" %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Image Details: ")|add:image.name|default:_("Image Details:") %}
|
||||
{% endblock page_header %}
|
||||
|
||||
{% block main %}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{% load i18n sizeformat parse_date %}
|
||||
{% load url from future %}
|
||||
|
||||
<h3>{{snapshot.display_name }}</h3>
|
||||
<h3>{% trans "Volume Snapshot Overview" %}</h3>
|
||||
|
||||
<div class="info row-fluid detail">
|
||||
<h4>{% trans "Info" %}</h4>
|
||||
|
@@ -3,9 +3,8 @@
|
||||
{% block title %}{% trans "Volume Snapshot Details" %}{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Volume Snapshot Detail") %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Volume Snapshot Details: ")|add:snapshot.display_name|default:_("Volume Snapshot Details:") %}
|
||||
{% endblock page_header %}
|
||||
|
||||
{% block main %}
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
|
@@ -22,6 +22,8 @@
|
||||
"""
|
||||
Views for managing Images and Snapshots.
|
||||
"""
|
||||
|
||||
from django.core.urlresolvers import reverse # noqa
|
||||
from django.utils.translation import ugettext_lazy as _ # noqa
|
||||
|
||||
from horizon import exceptions
|
||||
@@ -87,3 +89,26 @@ class IndexView(tables.MultiTableView):
|
||||
class DetailView(tabs.TabView):
|
||||
tab_group_class = vol_snsh_tabs.SnapshotDetailTabs
|
||||
template_name = 'project/images_and_snapshots/snapshots/detail.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(DetailView, self).get_context_data(**kwargs)
|
||||
context["snapshot"] = self.get_data()
|
||||
return context
|
||||
|
||||
def get_data(self):
|
||||
if not hasattr(self, "_snapshot"):
|
||||
try:
|
||||
snapshot_id = self.kwargs['snapshot_id']
|
||||
self._snapshot = api.cinder.volume_snapshot_get(self.request,
|
||||
snapshot_id)
|
||||
except Exception:
|
||||
url = reverse('horizon:project:images_and_snapshots:index')
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to retrieve snapshot details.'),
|
||||
redirect=url)
|
||||
|
||||
return self._snapshot
|
||||
|
||||
def get_tabs(self, request, *args, **kwargs):
|
||||
snapshot = self.get_data()
|
||||
return self.tab_group_class(request, snapshot=snapshot, **kwargs)
|
||||
|
@@ -30,18 +30,16 @@ class OverviewTab(tabs.Tab):
|
||||
"_detail_overview.html")
|
||||
|
||||
def get_context_data(self, request):
|
||||
snapshot_id = self.tab_group.kwargs['snapshot_id']
|
||||
try:
|
||||
snapshot = cinder.volume_snapshot_get(request, snapshot_id)
|
||||
snapshot = self.tab_group.kwargs['snapshot']
|
||||
volume = cinder.volume_get(request, snapshot.volume_id)
|
||||
volume.display_name = None
|
||||
except Exception:
|
||||
redirect = reverse('horizon:project:images_and_snapshots:index')
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to retrieve snapshot details.'),
|
||||
redirect=redirect)
|
||||
return {'snapshot': snapshot,
|
||||
'volume': volume}
|
||||
return {"snapshot": snapshot,
|
||||
"volume": volume}
|
||||
|
||||
|
||||
class SnapshotDetailTabs(tabs.TabGroup):
|
||||
|
@@ -40,7 +40,7 @@ class VolumeSnapshotsViewTests(test.TestCase):
|
||||
'volumesUsed': len(self.volumes.list()),
|
||||
'maxTotalVolumes': 6}
|
||||
quotas.tenant_limit_usages(IsA(http.HttpRequest)).\
|
||||
AndReturn(usage_limit)
|
||||
AndReturn(usage_limit)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
url = reverse('horizon:project:volumes:create_snapshot',
|
||||
@@ -58,7 +58,7 @@ class VolumeSnapshotsViewTests(test.TestCase):
|
||||
volume.id,
|
||||
snapshot.display_name,
|
||||
snapshot.display_description) \
|
||||
.AndReturn(snapshot)
|
||||
.AndReturn(snapshot)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
formData = {'method': 'CreateSnapshotForm',
|
||||
@@ -102,3 +102,64 @@ class VolumeSnapshotsViewTests(test.TestCase):
|
||||
|
||||
self.assertIn("Scheduled deletion of Volume Snapshot: test snapshot",
|
||||
[m.message for m in res.context['messages']])
|
||||
|
||||
@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()
|
||||
|
||||
api.cinder.volume_get(IsA(http.HttpRequest), volume.id). \
|
||||
AndReturn(volume)
|
||||
api.cinder.volume_snapshot_get(IsA(http.HttpRequest), snapshot.id). \
|
||||
AndReturn(snapshot)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
url = reverse('horizon:project:images_and_snapshots:detail',
|
||||
args=[snapshot.id])
|
||||
res = self.client.get(url)
|
||||
|
||||
self.assertContains(res,
|
||||
"<h2>Volume Snapshot Details: %s</h2>" %
|
||||
snapshot.display_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>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()
|
||||
|
||||
api.cinder.volume_snapshot_get(IsA(http.HttpRequest), snapshot.id).\
|
||||
AndRaise(self.exceptions.cinder)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
url = reverse('horizon:project:images_and_snapshots:detail',
|
||||
args=[snapshot.id])
|
||||
res = self.client.get(url)
|
||||
|
||||
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||
|
||||
@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()
|
||||
|
||||
api.cinder.volume_get(IsA(http.HttpRequest), volume.id). \
|
||||
AndRaise(self.exceptions.cinder)
|
||||
api.cinder.volume_snapshot_get(IsA(http.HttpRequest), snapshot.id). \
|
||||
AndReturn(snapshot)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
url = reverse('horizon:project:images_and_snapshots:detail',
|
||||
args=[snapshot.id])
|
||||
res = self.client.get(url)
|
||||
|
||||
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||
|
@@ -1,9 +1,9 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n sizeformat %}
|
||||
{% block title %}{% trans "Instance Detail" %}{% endblock %}
|
||||
{% block title %}{% trans "Instance Details" %}{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
{% include "horizon/common/_page_header.html" with title="Instance Detail: "|add:instance.name %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Instance Details: ")|add:instance.name %}
|
||||
{% endblock page_header %}
|
||||
|
||||
{% block main %}
|
||||
|
@@ -17,12 +17,8 @@
|
||||
from django.core.urlresolvers import reverse # noqa
|
||||
from django.utils.translation import ugettext_lazy as _ # noqa
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import tabs
|
||||
|
||||
from openstack_dashboard.api import cinder
|
||||
from openstack_dashboard.api import nova
|
||||
|
||||
|
||||
class OverviewTab(tabs.Tab):
|
||||
name = _("Overview")
|
||||
@@ -31,17 +27,7 @@ class OverviewTab(tabs.Tab):
|
||||
"_detail_overview.html")
|
||||
|
||||
def get_context_data(self, request):
|
||||
volume_id = self.tab_group.kwargs['volume_id']
|
||||
try:
|
||||
volume = cinder.volume_get(request, volume_id)
|
||||
for att in volume.attachments:
|
||||
att['instance'] = nova.server_get(request, att['server_id'])
|
||||
except Exception:
|
||||
redirect = reverse('horizon:project:volumes:index')
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to retrieve volume details.'),
|
||||
redirect=redirect)
|
||||
return {'volume': volume}
|
||||
return {"volume": self.tab_group.kwargs['volume']}
|
||||
|
||||
|
||||
class VolumeDetailTabs(tabs.TabGroup):
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{% load i18n sizeformat parse_date %}
|
||||
{% load url from future %}
|
||||
|
||||
<h3>{% trans "Volume Overview" %}: {{volume.display_name }}</h3>
|
||||
<h3>{% trans "Volume Overview" %}</h3>
|
||||
|
||||
<div class="info row-fluid detail">
|
||||
<h4>{% trans "Info" %}</h4>
|
||||
|
@@ -3,7 +3,7 @@
|
||||
{% block title %}{% trans "Volume Details" %}{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Volume Detail") %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Volume Details: ")|add:volume.display_name|default:_("Volume Details:") %}
|
||||
{% endblock page_header %}
|
||||
|
||||
{% block main %}
|
||||
|
@@ -32,6 +32,9 @@ from openstack_dashboard.test import helpers as test
|
||||
from openstack_dashboard.usage import quotas
|
||||
|
||||
|
||||
VOLUME_INDEX_URL = reverse('horizon:project:volumes:index')
|
||||
|
||||
|
||||
class VolumeViewTests(test.TestCase):
|
||||
@test.create_stubs({cinder: ('volume_create',
|
||||
'volume_snapshot_list',
|
||||
@@ -674,6 +677,8 @@ class VolumeViewTests(test.TestCase):
|
||||
args=[volume.id])
|
||||
res = self.client.get(url)
|
||||
|
||||
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>",
|
||||
@@ -706,3 +711,21 @@ class VolumeViewTests(test.TestCase):
|
||||
|
||||
self.assertEqual(res.status_code, 200)
|
||||
self.assertEqual(volume.display_name, volume.id)
|
||||
|
||||
@test.create_stubs({cinder: ('volume_get',)})
|
||||
def test_detail_view_with_exception(self):
|
||||
volume = self.volumes.first()
|
||||
server = self.servers.first()
|
||||
|
||||
volume.attachments = [{"server_id": server.id}]
|
||||
|
||||
cinder.volume_get(IsA(http.HttpRequest), volume.id).\
|
||||
AndRaise(self.exceptions.cinder)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
url = reverse('horizon:project:volumes:detail',
|
||||
args=[volume.id])
|
||||
res = self.client.get(url)
|
||||
|
||||
self.assertRedirectsNoFollow(res, VOLUME_INDEX_URL)
|
||||
|
@@ -18,6 +18,7 @@
|
||||
Views for managing volumes.
|
||||
"""
|
||||
|
||||
from django.core.urlresolvers import reverse # noqa
|
||||
from django.core.urlresolvers import reverse_lazy # noqa
|
||||
from django.utils.datastructures import SortedDict # noqa
|
||||
from django.utils.translation import ugettext_lazy as _ # noqa
|
||||
@@ -91,6 +92,31 @@ class DetailView(tabs.TabView):
|
||||
tab_group_class = project_tabs.VolumeDetailTabs
|
||||
template_name = 'project/volumes/detail.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(DetailView, self).get_context_data(**kwargs)
|
||||
context["volume"] = self.get_data()
|
||||
return context
|
||||
|
||||
def get_data(self):
|
||||
if not hasattr(self, "_volume"):
|
||||
try:
|
||||
volume_id = self.kwargs['volume_id']
|
||||
self._volume = cinder.volume_get(self.request, volume_id)
|
||||
for att in self._volume.attachments:
|
||||
att['instance'] = api.nova.server_get(self.request,
|
||||
att['server_id'])
|
||||
except Exception:
|
||||
redirect = reverse('horizon:project:volumes:index')
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to retrieve volume details.'),
|
||||
redirect=redirect)
|
||||
|
||||
return self._volume
|
||||
|
||||
def get_tabs(self, request, *args, **kwargs):
|
||||
volume = self.get_data()
|
||||
return self.tab_group_class(request, volume=volume, **kwargs)
|
||||
|
||||
|
||||
class CreateView(forms.ModalFormView):
|
||||
form_class = project_forms.CreateForm
|
||||
|
Reference in New Issue
Block a user