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 title %}{% trans "Volume Details" %}{% endblock %}
|
||||||
|
|
||||||
{% block page_header %}
|
{% 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 %}
|
{% endblock page_header %}
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
@@ -17,11 +17,8 @@
|
|||||||
from django.core.urlresolvers import reverse # noqa
|
from django.core.urlresolvers import reverse # noqa
|
||||||
from django.utils.translation import ugettext_lazy as _ # noqa
|
from django.utils.translation import ugettext_lazy as _ # noqa
|
||||||
|
|
||||||
from horizon import exceptions
|
|
||||||
from horizon import tabs
|
from horizon import tabs
|
||||||
|
|
||||||
from openstack_dashboard import api
|
|
||||||
|
|
||||||
|
|
||||||
class OverviewTab(tabs.Tab):
|
class OverviewTab(tabs.Tab):
|
||||||
name = _("Overview")
|
name = _("Overview")
|
||||||
@@ -29,15 +26,7 @@ class OverviewTab(tabs.Tab):
|
|||||||
template_name = "project/images_and_snapshots/images/_detail_overview.html"
|
template_name = "project/images_and_snapshots/images/_detail_overview.html"
|
||||||
|
|
||||||
def get_context_data(self, request):
|
def get_context_data(self, request):
|
||||||
image_id = self.tab_group.kwargs['image_id']
|
return {"image": self.tab_group.kwargs['image']}
|
||||||
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}
|
|
||||||
|
|
||||||
|
|
||||||
class ImageDetailTabs(tabs.TabGroup):
|
class ImageDetailTabs(tabs.TabGroup):
|
||||||
|
@@ -163,10 +163,13 @@ class ImageViewTests(test.TestCase):
|
|||||||
res = self.client.get(
|
res = self.client.get(
|
||||||
reverse('horizon:project:images_and_snapshots:images:detail',
|
reverse('horizon:project:images_and_snapshots:images:detail',
|
||||||
args=[image.id]))
|
args=[image.id]))
|
||||||
|
|
||||||
self.assertTemplateUsed(res,
|
self.assertTemplateUsed(res,
|
||||||
'project/images_and_snapshots/images/detail.html')
|
'project/images_and_snapshots/images/detail.html')
|
||||||
self.assertEqual(res.context['image'].name, image.name)
|
self.assertEqual(res.context['image'].name, image.name)
|
||||||
self.assertEqual(res.context['image'].protected, image.protected)
|
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',)})
|
@test.create_stubs({api.glance: ('image_get',)})
|
||||||
def test_protected_image_detail_get(self):
|
def test_protected_image_detail_get(self):
|
||||||
|
@@ -82,3 +82,25 @@ class UpdateView(forms.ModalFormView):
|
|||||||
class DetailView(tabs.TabView):
|
class DetailView(tabs.TabView):
|
||||||
tab_group_class = project_tabs.ImageDetailTabs
|
tab_group_class = project_tabs.ImageDetailTabs
|
||||||
template_name = 'project/images_and_snapshots/images/detail.html'
|
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' %}
|
{% extends 'base.html' %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block title %}{% trans "Image Detail "%}{% endblock %}
|
{% block title %}{% trans "Image Details"%}{% endblock %}
|
||||||
|
|
||||||
{% block page_header %}
|
{% 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 %}
|
{% endblock page_header %}
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
{% load i18n sizeformat parse_date %}
|
{% load i18n sizeformat parse_date %}
|
||||||
{% load url from future %}
|
{% load url from future %}
|
||||||
|
|
||||||
<h3>{{snapshot.display_name }}</h3>
|
<h3>{% trans "Volume Snapshot Overview" %}</h3>
|
||||||
|
|
||||||
<div class="info row-fluid detail">
|
<div class="info row-fluid detail">
|
||||||
<h4>{% trans "Info" %}</h4>
|
<h4>{% trans "Info" %}</h4>
|
||||||
|
@@ -3,9 +3,8 @@
|
|||||||
{% block title %}{% trans "Volume Snapshot Details" %}{% endblock %}
|
{% block title %}{% trans "Volume Snapshot Details" %}{% endblock %}
|
||||||
|
|
||||||
{% block page_header %}
|
{% 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 %}
|
{% endblock page_header %}
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
<div class="row-fluid">
|
<div class="row-fluid">
|
||||||
<div class="span12">
|
<div class="span12">
|
||||||
|
@@ -22,6 +22,8 @@
|
|||||||
"""
|
"""
|
||||||
Views for managing Images and Snapshots.
|
Views for managing Images and Snapshots.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from django.core.urlresolvers import reverse # noqa
|
||||||
from django.utils.translation import ugettext_lazy as _ # noqa
|
from django.utils.translation import ugettext_lazy as _ # noqa
|
||||||
|
|
||||||
from horizon import exceptions
|
from horizon import exceptions
|
||||||
@@ -87,3 +89,26 @@ class IndexView(tables.MultiTableView):
|
|||||||
class DetailView(tabs.TabView):
|
class DetailView(tabs.TabView):
|
||||||
tab_group_class = vol_snsh_tabs.SnapshotDetailTabs
|
tab_group_class = vol_snsh_tabs.SnapshotDetailTabs
|
||||||
template_name = 'project/images_and_snapshots/snapshots/detail.html'
|
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")
|
"_detail_overview.html")
|
||||||
|
|
||||||
def get_context_data(self, request):
|
def get_context_data(self, request):
|
||||||
snapshot_id = self.tab_group.kwargs['snapshot_id']
|
|
||||||
try:
|
try:
|
||||||
snapshot = cinder.volume_snapshot_get(request, snapshot_id)
|
snapshot = self.tab_group.kwargs['snapshot']
|
||||||
volume = cinder.volume_get(request, snapshot.volume_id)
|
volume = cinder.volume_get(request, snapshot.volume_id)
|
||||||
volume.display_name = None
|
|
||||||
except Exception:
|
except Exception:
|
||||||
redirect = reverse('horizon:project:images_and_snapshots:index')
|
redirect = reverse('horizon:project:images_and_snapshots:index')
|
||||||
exceptions.handle(self.request,
|
exceptions.handle(self.request,
|
||||||
_('Unable to retrieve snapshot details.'),
|
_('Unable to retrieve snapshot details.'),
|
||||||
redirect=redirect)
|
redirect=redirect)
|
||||||
return {'snapshot': snapshot,
|
return {"snapshot": snapshot,
|
||||||
'volume': volume}
|
"volume": volume}
|
||||||
|
|
||||||
|
|
||||||
class SnapshotDetailTabs(tabs.TabGroup):
|
class SnapshotDetailTabs(tabs.TabGroup):
|
||||||
|
@@ -40,7 +40,7 @@ class VolumeSnapshotsViewTests(test.TestCase):
|
|||||||
'volumesUsed': len(self.volumes.list()),
|
'volumesUsed': len(self.volumes.list()),
|
||||||
'maxTotalVolumes': 6}
|
'maxTotalVolumes': 6}
|
||||||
quotas.tenant_limit_usages(IsA(http.HttpRequest)).\
|
quotas.tenant_limit_usages(IsA(http.HttpRequest)).\
|
||||||
AndReturn(usage_limit)
|
AndReturn(usage_limit)
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
url = reverse('horizon:project:volumes:create_snapshot',
|
url = reverse('horizon:project:volumes:create_snapshot',
|
||||||
@@ -58,7 +58,7 @@ class VolumeSnapshotsViewTests(test.TestCase):
|
|||||||
volume.id,
|
volume.id,
|
||||||
snapshot.display_name,
|
snapshot.display_name,
|
||||||
snapshot.display_description) \
|
snapshot.display_description) \
|
||||||
.AndReturn(snapshot)
|
.AndReturn(snapshot)
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
formData = {'method': 'CreateSnapshotForm',
|
formData = {'method': 'CreateSnapshotForm',
|
||||||
@@ -102,3 +102,64 @@ class VolumeSnapshotsViewTests(test.TestCase):
|
|||||||
|
|
||||||
self.assertIn("Scheduled deletion of Volume Snapshot: test snapshot",
|
self.assertIn("Scheduled deletion of Volume Snapshot: test snapshot",
|
||||||
[m.message for m in res.context['messages']])
|
[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' %}
|
{% extends 'base.html' %}
|
||||||
{% load i18n sizeformat %}
|
{% load i18n sizeformat %}
|
||||||
{% block title %}{% trans "Instance Detail" %}{% endblock %}
|
{% block title %}{% trans "Instance Details" %}{% endblock %}
|
||||||
|
|
||||||
{% block page_header %}
|
{% 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 %}
|
{% endblock page_header %}
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
@@ -17,12 +17,8 @@
|
|||||||
from django.core.urlresolvers import reverse # noqa
|
from django.core.urlresolvers import reverse # noqa
|
||||||
from django.utils.translation import ugettext_lazy as _ # noqa
|
from django.utils.translation import ugettext_lazy as _ # noqa
|
||||||
|
|
||||||
from horizon import exceptions
|
|
||||||
from horizon import tabs
|
from horizon import tabs
|
||||||
|
|
||||||
from openstack_dashboard.api import cinder
|
|
||||||
from openstack_dashboard.api import nova
|
|
||||||
|
|
||||||
|
|
||||||
class OverviewTab(tabs.Tab):
|
class OverviewTab(tabs.Tab):
|
||||||
name = _("Overview")
|
name = _("Overview")
|
||||||
@@ -31,17 +27,7 @@ class OverviewTab(tabs.Tab):
|
|||||||
"_detail_overview.html")
|
"_detail_overview.html")
|
||||||
|
|
||||||
def get_context_data(self, request):
|
def get_context_data(self, request):
|
||||||
volume_id = self.tab_group.kwargs['volume_id']
|
return {"volume": self.tab_group.kwargs['volume']}
|
||||||
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}
|
|
||||||
|
|
||||||
|
|
||||||
class VolumeDetailTabs(tabs.TabGroup):
|
class VolumeDetailTabs(tabs.TabGroup):
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
{% load i18n sizeformat parse_date %}
|
{% load i18n sizeformat parse_date %}
|
||||||
{% load url from future %}
|
{% load url from future %}
|
||||||
|
|
||||||
<h3>{% trans "Volume Overview" %}: {{volume.display_name }}</h3>
|
<h3>{% trans "Volume Overview" %}</h3>
|
||||||
|
|
||||||
<div class="info row-fluid detail">
|
<div class="info row-fluid detail">
|
||||||
<h4>{% trans "Info" %}</h4>
|
<h4>{% trans "Info" %}</h4>
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
{% block title %}{% trans "Volume Details" %}{% endblock %}
|
{% block title %}{% trans "Volume Details" %}{% endblock %}
|
||||||
|
|
||||||
{% block page_header %}
|
{% 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 %}
|
{% endblock page_header %}
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
@@ -32,6 +32,9 @@ from openstack_dashboard.test import helpers as test
|
|||||||
from openstack_dashboard.usage import quotas
|
from openstack_dashboard.usage import quotas
|
||||||
|
|
||||||
|
|
||||||
|
VOLUME_INDEX_URL = reverse('horizon:project:volumes:index')
|
||||||
|
|
||||||
|
|
||||||
class VolumeViewTests(test.TestCase):
|
class VolumeViewTests(test.TestCase):
|
||||||
@test.create_stubs({cinder: ('volume_create',
|
@test.create_stubs({cinder: ('volume_create',
|
||||||
'volume_snapshot_list',
|
'volume_snapshot_list',
|
||||||
@@ -674,6 +677,8 @@ class VolumeViewTests(test.TestCase):
|
|||||||
args=[volume.id])
|
args=[volume.id])
|
||||||
res = self.client.get(url)
|
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>Volume name</dd>", 1, 200)
|
||||||
self.assertContains(res,
|
self.assertContains(res,
|
||||||
"<dd>41023e92-8008-4c8b-8059-7f2293ff3775</dd>",
|
"<dd>41023e92-8008-4c8b-8059-7f2293ff3775</dd>",
|
||||||
@@ -706,3 +711,21 @@ class VolumeViewTests(test.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(res.status_code, 200)
|
self.assertEqual(res.status_code, 200)
|
||||||
self.assertEqual(volume.display_name, volume.id)
|
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.
|
Views for managing volumes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from django.core.urlresolvers import reverse # noqa
|
||||||
from django.core.urlresolvers import reverse_lazy # noqa
|
from django.core.urlresolvers import reverse_lazy # noqa
|
||||||
from django.utils.datastructures import SortedDict # noqa
|
from django.utils.datastructures import SortedDict # noqa
|
||||||
from django.utils.translation import ugettext_lazy as _ # noqa
|
from django.utils.translation import ugettext_lazy as _ # noqa
|
||||||
@@ -91,6 +92,31 @@ class DetailView(tabs.TabView):
|
|||||||
tab_group_class = project_tabs.VolumeDetailTabs
|
tab_group_class = project_tabs.VolumeDetailTabs
|
||||||
template_name = 'project/volumes/detail.html'
|
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):
|
class CreateView(forms.ModalFormView):
|
||||||
form_class = project_forms.CreateForm
|
form_class = project_forms.CreateForm
|
||||||
|
Reference in New Issue
Block a user