diff --git a/horizon/dashboards/nova/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html b/horizon/dashboards/nova/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html
new file mode 100644
index 000000000..499d10998
--- /dev/null
+++ b/horizon/dashboards/nova/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html
@@ -0,0 +1,42 @@
+{% load i18n sizeformat parse_date %}
+{% load url from future %}
+
+
{{snapshot.display_name }}
+
+
+
+
+
{% trans "Specs" %}
+
+
+ - {% trans "Size" %}
+ - {{ snapshot.size }} {% trans "GB" %}
+ - {% trans "Created" %}
+ - {{ snapshot.created_at|parse_date }}
+
+
diff --git a/horizon/dashboards/nova/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html b/horizon/dashboards/nova/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html
new file mode 100644
index 000000000..72d8dc668
--- /dev/null
+++ b/horizon/dashboards/nova/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html
@@ -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 %}
+
+
+ {{ tab_group.render }}
+
+
+{% endblock %}
diff --git a/horizon/dashboards/nova/images_and_snapshots/urls.py b/horizon/dashboards/nova/images_and_snapshots/urls.py
index b657ceacb..d763deace 100644
--- a/horizon/dashboards/nova/images_and_snapshots/urls.py
+++ b/horizon/dashboards/nova/images_and_snapshots/urls.py
@@ -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[^/]+)/$',
+ DetailView.as_view(),
+ name='detail'),
)
diff --git a/horizon/dashboards/nova/images_and_snapshots/views.py b/horizon/dashboards/nova/images_and_snapshots/views.py
index 01052c430..bade47e4e 100644
--- a/horizon/dashboards/nova/images_and_snapshots/views.py
+++ b/horizon/dashboards/nova/images_and_snapshots/views.py
@@ -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'
diff --git a/horizon/dashboards/nova/images_and_snapshots/volume_snapshots/tables.py b/horizon/dashboards/nova/images_and_snapshots/volume_snapshots/tables.py
index 2fef65d8a..b782d4109 100644
--- a/horizon/dashboards/nova/images_and_snapshots/volume_snapshots/tables.py
+++ b/horizon/dashboards/nova/images_and_snapshots/volume_snapshots/tables.py
@@ -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")
diff --git a/horizon/dashboards/nova/images_and_snapshots/volume_snapshots/tabs.py b/horizon/dashboards/nova/images_and_snapshots/volume_snapshots/tabs.py
new file mode 100644
index 000000000..6aa87877d
--- /dev/null
+++ b/horizon/dashboards/nova/images_and_snapshots/volume_snapshots/tabs.py
@@ -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,)