diff --git a/horizon/dashboards/nova/images_and_snapshots/snapshots/forms.py b/horizon/dashboards/nova/images_and_snapshots/snapshots/forms.py index 536da13ab..7ff117130 100644 --- a/horizon/dashboards/nova/images_and_snapshots/snapshots/forms.py +++ b/horizon/dashboards/nova/images_and_snapshots/snapshots/forms.py @@ -34,8 +34,8 @@ LOG = logging.getLogger(__name__) class CreateSnapshot(forms.SelfHandlingForm): instance_id = forms.CharField(label=_("Instance ID"), - widget=forms.TextInput( - attrs={'readonly': 'readonly'})) + widget=forms.HiddenInput(), + required=False) name = forms.CharField(max_length="20", label=_("Snapshot Name")) def handle(self, request, data): diff --git a/horizon/dashboards/nova/images_and_snapshots/tests.py b/horizon/dashboards/nova/images_and_snapshots/tests.py index 12f70d75d..d2d4324a5 100644 --- a/horizon/dashboards/nova/images_and_snapshots/tests.py +++ b/horizon/dashboards/nova/images_and_snapshots/tests.py @@ -31,14 +31,25 @@ INDEX_URL = reverse('horizon:nova:images_and_snapshots:index') class ImagesAndSnapshotsTests(test.TestCase): + @test.create_stubs({api: ('image_list_detailed', 'snapshot_list_detailed', + 'volume_snapshot_list', 'volume_get',)}) def test_index(self): images = self.images.list() snapshots = self.snapshots.list() - self.mox.StubOutWithMock(api, 'image_list_detailed') - self.mox.StubOutWithMock(api, 'snapshot_list_detailed') - self.mox.StubOutWithMock(api, 'volume_snapshot_list') + volumes = self.volumes.list() + + for volume in volumes: + volume.volume_id = volume.id + for volume in volumes: + api.volume_get(IsA(http.HttpRequest), volume.volume_id) \ + .AndReturn(volume) + for volume in volumes: + api.volume_get(IsA(http.HttpRequest), volume.volume_id) \ + .AndReturn(volume) + api.volume_get(IsA(http.HttpRequest), volume.volume_id) + api.volume_snapshot_list(IsA(http.HttpRequest)) \ - .AndReturn(self.volumes.list()) + .AndReturn(volumes) api.image_list_detailed(IsA(http.HttpRequest), marker=None).AndReturn([images, False]) api.snapshot_list_detailed(IsA(http.HttpRequest), @@ -53,12 +64,23 @@ class ImagesAndSnapshotsTests(test.TestCase): filtered_images = filter(filter_func, images) self.assertItemsEqual(images, filtered_images) + @test.create_stubs({api: ('image_list_detailed', 'snapshot_list_detailed', + 'volume_snapshot_list', 'volume_get',)}) def test_index_no_images(self): - self.mox.StubOutWithMock(api, 'snapshot_list_detailed') - self.mox.StubOutWithMock(api, 'image_list_detailed') - self.mox.StubOutWithMock(api, 'volume_snapshot_list') + volumes = self.volumes.list() + + for volume in volumes: + volume.volume_id = volume.id + for volume in volumes: + api.volume_get(IsA(http.HttpRequest), volume.volume_id) \ + .AndReturn(volume) + for volume in volumes: + api.volume_get(IsA(http.HttpRequest), volume.volume_id) \ + .AndReturn(volume) + api.volume_get(IsA(http.HttpRequest), volume.volume_id) + api.volume_snapshot_list(IsA(http.HttpRequest)) \ - .AndReturn(self.volumes.list()) + .AndReturn(volumes) api.image_list_detailed(IsA(http.HttpRequest), marker=None).AndReturn([(), False]) api.snapshot_list_detailed(IsA(http.HttpRequest), marker=None) \ @@ -68,12 +90,23 @@ class ImagesAndSnapshotsTests(test.TestCase): res = self.client.get(INDEX_URL) self.assertTemplateUsed(res, 'nova/images_and_snapshots/index.html') + @test.create_stubs({api: ('image_list_detailed', 'snapshot_list_detailed', + 'volume_snapshot_list', 'volume_get',)}) def test_index_error(self): - self.mox.StubOutWithMock(api, 'image_list_detailed') - self.mox.StubOutWithMock(api, 'snapshot_list_detailed') - self.mox.StubOutWithMock(api, 'volume_snapshot_list') + volumes = self.volumes.list() + + for volume in volumes: + volume.volume_id = volume.id + for volume in volumes: + api.volume_get(IsA(http.HttpRequest), volume.volume_id) \ + .AndReturn(volume) + for volume in volumes: + api.volume_get(IsA(http.HttpRequest), volume.volume_id) \ + .AndReturn(volume) + api.volume_get(IsA(http.HttpRequest), volume.volume_id) + api.volume_snapshot_list(IsA(http.HttpRequest)) \ - .AndReturn(self.volumes.list()) + .AndReturn(volumes) api.image_list_detailed(IsA(http.HttpRequest), marker=None).AndRaise(self.exceptions.glance) api.snapshot_list_detailed(IsA(http.HttpRequest), marker=None) \ @@ -84,14 +117,24 @@ class ImagesAndSnapshotsTests(test.TestCase): self.assertTemplateUsed(res, 'nova/images_and_snapshots/index.html') @test.create_stubs({api: ('image_list_detailed', 'snapshot_list_detailed', - 'volume_snapshot_list')}) + 'volume_snapshot_list', 'volume_get',)}) def test_queued_snapshot_actions(self): images = self.images.list() - snapshots = self.snapshots.list() + volumes = self.volumes.list() + + for volume in volumes: + volume.volume_id = volume.id + for volume in volumes: + api.volume_get(IsA(http.HttpRequest), volume.volume_id) \ + .AndReturn(volume) + for volume in volumes: + api.volume_get(IsA(http.HttpRequest), volume.volume_id) \ + .AndReturn(volume) + api.volume_get(IsA(http.HttpRequest), volume.volume_id) api.volume_snapshot_list(IsA(http.HttpRequest)) \ - .AndReturn(self.volumes.list()) + .AndReturn(volumes) api.image_list_detailed(IsA(http.HttpRequest), marker=None).AndReturn([images, False]) api.snapshot_list_detailed(IsA(http.HttpRequest), marker=None) \ 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 417eacddd..2fef65d8a 100644 --- a/horizon/dashboards/nova/images_and_snapshots/volume_snapshots/tables.py +++ b/horizon/dashboards/nova/images_and_snapshots/volume_snapshots/tables.py @@ -17,6 +17,7 @@ import logging from django.core.urlresolvers import reverse +from django.utils import safestring from django.utils.http import urlencode from django.utils.translation import ugettext_lazy as _ @@ -59,10 +60,26 @@ class UpdateRow(tables.Row): return snapshot +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 + return safestring.mark_safe(volume_name) + + def get_link_url(self, snapshot): + volume_id = api.volume_get(self.table.request, snapshot.volume_id).id + return reverse(self.link, args=(volume_id,)) + + class VolumeSnapshotsTable(volume_tables.VolumesTableBase): name = tables.Column("display_name", verbose_name=_("Name")) - volume_id = tables.Column("volume_id", - verbose_name=_("Volume ID")) + volume_name = SnapshotVolumeNameColumn("display_name", + verbose_name=_("Volume Name"), + link="horizon:nova:volumes:detail") class Meta: name = "volume_snapshots"