diff --git a/openstack_dashboard/dashboards/admin/volumes/snapshots/forms.py b/openstack_dashboard/dashboards/admin/volumes/snapshots/forms.py index 7205cfe6ba..00b52e111e 100644 --- a/openstack_dashboard/dashboards/admin/volumes/snapshots/forms.py +++ b/openstack_dashboard/dashboards/admin/volumes/snapshots/forms.py @@ -30,8 +30,24 @@ STATUS_CHOICES = ( ) +def populate_status_choices(initial, status_choices): + current_status = initial.get('status') + status_choices = [status for status in status_choices + if status[0] != current_status] + status_choices.insert(0, ("", _("Select a new status"))) + + return status_choices + + class UpdateStatus(forms.SelfHandlingForm): - status = forms.ChoiceField(label=_("Status"), choices=STATUS_CHOICES) + status = forms.ChoiceField(label=_("Status")) + + def __init__(self, request, *args, **kwargs): + super(UpdateStatus, self).__init__(request, *args, **kwargs) + + initial = kwargs.get('initial', {}) + self.fields['status'].choices = populate_status_choices( + initial, STATUS_CHOICES) def handle(self, request, data): try: diff --git a/openstack_dashboard/dashboards/admin/volumes/snapshots/tests.py b/openstack_dashboard/dashboards/admin/volumes/snapshots/tests.py index e6443feafc..0c3d40d618 100644 --- a/openstack_dashboard/dashboards/admin/volumes/snapshots/tests.py +++ b/openstack_dashboard/dashboards/admin/volumes/snapshots/tests.py @@ -17,6 +17,7 @@ from mox3.mox import IsA # noqa from openstack_dashboard.api import cinder from openstack_dashboard.test import helpers as test +from openstack_dashboard.dashboards.admin.volumes.snapshots import forms INDEX_URL = reverse('horizon:admin:volumes:index') @@ -106,3 +107,25 @@ class VolumeSnapshotsViewTests(test.BaseAdminViewTests): self.assertNoFormErrors(res) self.assertMessageCount(error=1) self.assertRedirectsNoFollow(res, INDEX_URL) + + def test_get_snapshot_status_choices_without_current(self): + current_status = {'status': 'available'} + status_choices = forms.populate_status_choices(current_status, + forms.STATUS_CHOICES) + self.assertEqual(len(status_choices), len(forms.STATUS_CHOICES)) + self.assertNotIn(current_status['status'], + [status[0] for status in status_choices]) + + @test.create_stubs({cinder: ('volume_snapshot_get',)}) + def test_update_volume_status_get(self): + snapshot = self.cinder_volume_snapshots.first() + cinder.volume_snapshot_get(IsA(http.HttpRequest), snapshot.id). \ + AndReturn(snapshot) + + self.mox.ReplayAll() + + url = reverse('horizon:admin:volumes:snapshots:update_status', + args=[snapshot.id]) + res = self.client.get(url) + status_option = "" % snapshot.status + self.assertNotContains(res, status_option) diff --git a/openstack_dashboard/dashboards/admin/volumes/volumes/forms.py b/openstack_dashboard/dashboards/admin/volumes/volumes/forms.py index d6158d52b9..de51f2a7d0 100644 --- a/openstack_dashboard/dashboards/admin/volumes/volumes/forms.py +++ b/openstack_dashboard/dashboards/admin/volumes/volumes/forms.py @@ -26,10 +26,25 @@ from horizon import messages from horizon.utils import validators as utils_validators from openstack_dashboard.api import cinder +from openstack_dashboard.dashboards.admin.volumes.snapshots.forms \ + import populate_status_choices from openstack_dashboard.dashboards.project.volumes.volumes \ import forms as project_forms +# This set of states was pulled from cinder's admin_actions.py +STATUS_CHOICES = ( + ('attaching', _('Attaching')), + ('available', _('Available')), + ('creating', _('Creating')), + ('deleting', _('Deleting')), + ('detaching', _('Detaching')), + ('error', _('Error')), + ('error_deleting', _('Error Deleting')), + ('in-use', _('In Use')), +) + + class ManageVolume(forms.SelfHandlingForm): identifier = forms.CharField( max_length=255, @@ -239,17 +254,9 @@ class UpdateStatus(forms.SelfHandlingForm): def __init__(self, request, *args, **kwargs): super(UpdateStatus, self).__init__(request, *args, **kwargs) - # This set of states was culled from cinder's admin_actions.py + initial = kwargs.get('initial', {}) self.fields['status'].choices = ( - ('attaching', _('Attaching')), - ('available', _('Available')), - ('creating', _('Creating')), - ('deleting', _('Deleting')), - ('detaching', _('Detaching')), - ('error', _('Error')), - ('error_deleting', _('Error Deleting')), - ('in-use', _('In Use')), - ) + populate_status_choices(initial, STATUS_CHOICES)) def handle(self, request, data): # Obtain the localized status for including in the message diff --git a/openstack_dashboard/dashboards/admin/volumes/volumes/tests.py b/openstack_dashboard/dashboards/admin/volumes/volumes/tests.py index 9ac81ede46..f13b41a316 100644 --- a/openstack_dashboard/dashboards/admin/volumes/volumes/tests.py +++ b/openstack_dashboard/dashboards/admin/volumes/volumes/tests.py @@ -18,6 +18,7 @@ from mox3.mox import IsA # noqa from openstack_dashboard.api import cinder from openstack_dashboard.test import helpers as test +from openstack_dashboard.dashboards.admin.volumes.snapshots import forms INDEX_URL = reverse('horizon:admin:volumes:volumes_tab') @@ -201,3 +202,25 @@ class VolumeViewTests(test.BaseAdminViewTests): args=[volume.id]) res = self.client.post(url, {'host': host, 'volume_id': volume.id}) self.assertRedirectsNoFollow(res, INDEX_URL) + + def test_get_volume_status_choices_without_current(self): + current_status = {'status': 'available'} + status_choices = forms.populate_status_choices(current_status, + forms.STATUS_CHOICES) + self.assertEqual(len(status_choices), len(forms.STATUS_CHOICES)) + self.assertNotIn(current_status['status'], + [status[0] for status in status_choices]) + + @test.create_stubs({cinder: ('volume_get',)}) + def test_update_volume_status_get(self): + volume = self.cinder_volumes.get(name='v2_volume') + cinder.volume_get(IsA(http.HttpRequest), volume.id) \ + .AndReturn(volume) + + self.mox.ReplayAll() + + url = reverse('horizon:admin:volumes:volumes:update_status', + args=[volume.id]) + res = self.client.get(url) + status_option = "" % volume.status + self.assertNotContains(res, status_option)