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 .snapshots import urls as snapshot_urls
from .views import IndexView
from .views import IndexView, DetailView
urlpatterns = patterns('',
url(r'^$', IndexView.as_view(), name='index'),
url(r'', include(image_urls, namespace='images')),
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 exceptions
from horizon import tables
from horizon import tabs
from .images.tables import ImagesTable
from .snapshots.tables import SnapshotsTable
from .volume_snapshots.tables import VolumeSnapshotsTable
from .volume_snapshots.tabs import SnapshotDetailTabs
LOG = logging.getLogger(__name__)
@ -78,5 +79,10 @@ class IndexView(tables.MultiTableView):
except:
snapshots = []
exceptions.handle(self.request, _("Unable to retrieve "
"volume snapshots."))
"volume 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):
"""
Customized column class that does complex processing on the attachments
for a volume instance.
"""
def get_raw_data(self, snapshot):
request = self.table.request
volume_name = api.volume_get(request, snapshot.volume_id).display_name
@ -76,7 +72,9 @@ class SnapshotVolumeNameColumn(tables.Column):
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",
verbose_name=_("Volume Name"),
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,)