Creates volume snapshot detail page and links to it via the Name column

in the Volume Snapshots table

Fixes launchpad bug #1039089

Change-Id: Id3852e2ee2caecc14a561e3089940f8dd50c0bd4
This commit is contained in:
Kelsey Tripp 2012-08-21 11:49:01 -07:00
parent a9604ef6b5
commit 66d7d99b37
6 changed files with 120 additions and 8 deletions

View File

@ -0,0 +1,42 @@
{% load i18n sizeformat parse_date %}
{% load url from future %}
<h3>{{snapshot.display_name }}</h3>
<div class="info row-fluid detail">
<h4>{% trans "Info" %}</h4>
<hr class="header_rule">
<dl>
<dt>{% trans "Name" %}</dt>
<dd>{{ snapshot.display_name }}</dd>
<dt>{% trans "ID" %}</dt>
<dd>{{ snapshot.id }}</dd>
{% if snapshot.display_description %}
<dt>{% trans "Description" %}</dt>
<dd>{{ snapshot.display_description }}</dd>
{% endif %}
<dt>{% trans "Status" %}</dt>
<dd>{{ snapshot.status|capfirst }}</dd>
<dt>{% trans "Volume" %}</dt>
<dd>
<a href="{% url 'horizon:nova:volumes:detail' snapshot.volume_id %}">
{% if volume.display_name %}
{{ volume.display_name }}
{% else %}
{{ snapshot.volume_id }}
{% endif %}
</a>
</dd>
</dl>
</div>
<div class="specs row-fluid detail">
<h4>{% trans "Specs" %}</h4>
<hr class="header_rule">
<dl>
<dt>{% trans "Size" %}</dt>
<dd>{{ snapshot.size }} {% trans "GB" %}</dd>
<dt>{% trans "Created" %}</dt>
<dd>{{ snapshot.created_at|parse_date }}</dd>
</dl>
</div>

View File

@ -0,0 +1,15 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Volume Snapshot Details" %}{% endblock %}
{% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Volume Snapshot Detail") %}
{% endblock page_header %}
{% block main %}
<div class="row-fluid">
<div class="span12">
{{ tab_group.render }}
</div>
</div>
{% endblock %}

View File

@ -22,11 +22,14 @@ from django.conf.urls.defaults import *
from .images import urls as image_urls from .images import urls as image_urls
from .snapshots import urls as snapshot_urls from .snapshots import urls as snapshot_urls
from .views import IndexView from .views import IndexView, DetailView
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'^$', IndexView.as_view(), name='index'), url(r'^$', IndexView.as_view(), name='index'),
url(r'', include(image_urls, namespace='images')), url(r'', include(image_urls, namespace='images')),
url(r'', include(snapshot_urls, namespace='snapshots')), url(r'', include(snapshot_urls, namespace='snapshots')),
url(r'^snapshots/(?P<snapshot_id>[^/]+)/$',
DetailView.as_view(),
name='detail'),
) )

View File

@ -30,10 +30,11 @@ from django.utils.translation import ugettext_lazy as _
from horizon import api from horizon import api
from horizon import exceptions from horizon import exceptions
from horizon import tables from horizon import tables
from horizon import tabs
from .images.tables import ImagesTable from .images.tables import ImagesTable
from .snapshots.tables import SnapshotsTable from .snapshots.tables import SnapshotsTable
from .volume_snapshots.tables import VolumeSnapshotsTable from .volume_snapshots.tables import VolumeSnapshotsTable
from .volume_snapshots.tabs import SnapshotDetailTabs
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -78,5 +79,10 @@ class IndexView(tables.MultiTableView):
except: except:
snapshots = [] snapshots = []
exceptions.handle(self.request, _("Unable to retrieve " exceptions.handle(self.request, _("Unable to retrieve "
"volume snapshots.")) "volume snapshots."))
return snapshots return snapshots
class DetailView(tabs.TabView):
tab_group_class = SnapshotDetailTabs
template_name = 'nova/images_and_snapshots/snapshots/detail.html'

View File

@ -61,10 +61,6 @@ class UpdateRow(tables.Row):
class SnapshotVolumeNameColumn(tables.Column): class SnapshotVolumeNameColumn(tables.Column):
"""
Customized column class that does complex processing on the attachments
for a volume instance.
"""
def get_raw_data(self, snapshot): def get_raw_data(self, snapshot):
request = self.table.request request = self.table.request
volume_name = api.volume_get(request, snapshot.volume_id).display_name volume_name = api.volume_get(request, snapshot.volume_id).display_name
@ -76,7 +72,9 @@ class SnapshotVolumeNameColumn(tables.Column):
class VolumeSnapshotsTable(volume_tables.VolumesTableBase): class VolumeSnapshotsTable(volume_tables.VolumesTableBase):
name = tables.Column("display_name", verbose_name=_("Name")) name = tables.Column("display_name",
verbose_name=_("Name"),
link="horizon:nova:images_and_snapshots:detail")
volume_name = SnapshotVolumeNameColumn("display_name", volume_name = SnapshotVolumeNameColumn("display_name",
verbose_name=_("Volume Name"), verbose_name=_("Volume Name"),
link="horizon:nova:volumes:detail") link="horizon:nova:volumes:detail")

View File

@ -0,0 +1,48 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 Nebula, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from horizon import api
from horizon import exceptions
from horizon import tabs
class OverviewTab(tabs.Tab):
name = _("Overview")
slug = "overview"
template_name = ("nova/images_and_snapshots/snapshots/"
"_detail_overview.html")
def get_context_data(self, request):
snapshot_id = self.tab_group.kwargs['snapshot_id']
try:
snapshot = api.nova.volume_snapshot_get(request, snapshot_id)
volume = api.nova.volume_get(request, snapshot.volume_id)
volume.display_name = None
except:
redirect = reverse('horizon:nova:images_and_snapshots:index')
exceptions.handle(self.request,
_('Unable to retrieve snapshot details.'),
redirect=redirect)
return {'snapshot': snapshot,
'volume': volume}
class SnapshotDetailTabs(tabs.TabGroup):
slug = "snapshot_details"
tabs = (OverviewTab,)