Merge "Fix actions inside instance details view page"
This commit is contained in:
commit
20eaa03174
|
@ -14,6 +14,7 @@
|
|||
|
||||
import collections
|
||||
import copy
|
||||
import inspect
|
||||
import json
|
||||
import logging
|
||||
from operator import attrgetter
|
||||
|
@ -466,6 +467,8 @@ class Column(html.HTMLElement):
|
|||
return None
|
||||
obj_id = self.table.get_object_id(datum)
|
||||
if callable(self.link):
|
||||
if 'request' in inspect.getargspec(self.link).args:
|
||||
return self.link(datum, request=self.table.request)
|
||||
return self.link(datum)
|
||||
try:
|
||||
return urlresolvers.reverse(self.link, args=(obj_id,))
|
||||
|
@ -670,11 +673,19 @@ class Row(html.HTMLElement):
|
|||
|
||||
def get_ajax_update_url(self):
|
||||
table_url = self.table.get_absolute_url()
|
||||
params = urlencode(collections.OrderedDict([
|
||||
marker_name = self.table._meta.pagination_param
|
||||
marker = self.table.request.GET.get(marker_name, None)
|
||||
if not marker:
|
||||
marker_name = self.table._meta.prev_pagination_param
|
||||
marker = self.table.request.GET.get(marker_name, None)
|
||||
request_params = [
|
||||
("action", self.ajax_action_name),
|
||||
("table", self.table.name),
|
||||
("obj_id", self.table.get_object_id(self.datum))
|
||||
]))
|
||||
("obj_id", self.table.get_object_id(self.datum)),
|
||||
]
|
||||
if marker:
|
||||
request_params.append((marker_name, marker))
|
||||
params = urlencode(collections.OrderedDict(request_params))
|
||||
return "%s?%s" % (table_url, params)
|
||||
|
||||
def can_be_selected(self, datum):
|
||||
|
|
|
@ -26,6 +26,7 @@ from openstack_dashboard.dashboards.project.instances import audit_tables
|
|||
from openstack_dashboard.dashboards.project.instances \
|
||||
import tables as project_tables
|
||||
from openstack_dashboard import policy
|
||||
from openstack_dashboard.views import get_url_with_pagination
|
||||
|
||||
|
||||
class AdminEditInstance(project_tables.EditInstance):
|
||||
|
@ -109,6 +110,13 @@ class AdminInstanceFilterAction(tables.FilterAction):
|
|||
) + project_tables.INSTANCE_FILTER_CHOICES
|
||||
|
||||
|
||||
def get_server_detail_link(obj, request):
|
||||
return get_url_with_pagination(
|
||||
request, AdminInstancesTable._meta.pagination_param,
|
||||
AdminInstancesTable._meta.prev_pagination_param,
|
||||
"horizon:admin:instances:detail", obj.id)
|
||||
|
||||
|
||||
class AdminInstancesTable(tables.DataTable):
|
||||
TASK_STATUS_CHOICES = (
|
||||
(None, True),
|
||||
|
@ -134,7 +142,7 @@ class AdminInstancesTable(tables.DataTable):
|
|||
verbose_name=_("Host"),
|
||||
classes=('nowrap-col',))
|
||||
name = tables.WrappingColumn("name",
|
||||
link="horizon:admin:instances:detail",
|
||||
link=get_server_detail_link,
|
||||
verbose_name=_("Name"))
|
||||
image_name = tables.Column("image_name",
|
||||
verbose_name=_("Image Name"))
|
||||
|
|
|
@ -44,7 +44,7 @@ from openstack_dashboard.dashboards.project.instances.workflows \
|
|||
from openstack_dashboard.dashboards.project.instances.workflows \
|
||||
import update_instance
|
||||
from openstack_dashboard import policy
|
||||
|
||||
from openstack_dashboard.views import get_url_with_pagination
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
@ -1207,6 +1207,14 @@ def render_locked(instance):
|
|||
return mark_safe(locked_status)
|
||||
|
||||
|
||||
def get_server_detail_link(obj, request):
|
||||
return get_url_with_pagination(request,
|
||||
InstancesTable._meta.pagination_param,
|
||||
InstancesTable._meta.prev_pagination_param,
|
||||
'horizon:project:instances:detail',
|
||||
obj.id)
|
||||
|
||||
|
||||
class InstancesTable(tables.DataTable):
|
||||
TASK_STATUS_CHOICES = (
|
||||
(None, True),
|
||||
|
@ -1223,7 +1231,7 @@ class InstancesTable(tables.DataTable):
|
|||
("shelved_offloaded", True),
|
||||
)
|
||||
name = tables.WrappingColumn("name",
|
||||
link="horizon:project:instances:detail",
|
||||
link=get_server_detail_link,
|
||||
verbose_name=_("Instance Name"))
|
||||
image_name = tables.WrappingColumn("image_name",
|
||||
verbose_name=_("Image Name"))
|
||||
|
|
|
@ -44,6 +44,7 @@ from openstack_dashboard.dashboards.project.instances import tabs
|
|||
from openstack_dashboard.dashboards.project.instances import workflows
|
||||
from openstack_dashboard.test import helpers
|
||||
from openstack_dashboard.usage import quotas
|
||||
from openstack_dashboard.views import get_url_with_pagination
|
||||
|
||||
|
||||
INDEX_TEMPLATE = 'horizon/common/_data_table_view.html'
|
||||
|
@ -611,12 +612,51 @@ class InstanceTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
|
|||
six.text_type(server.id))
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
formData = {'action': 'instances__suspend__%s' % server.id}
|
||||
res = self.client.post(INDEX_URL, formData)
|
||||
url = get_url_with_pagination(
|
||||
self.request, 'next', 'prev', 'horizon:project:instances:index')
|
||||
res = self.client.post(url, formData)
|
||||
|
||||
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||
|
||||
@django.test.utils.override_settings(API_RESULT_PAGE_SIZE=2)
|
||||
@helpers.create_stubs({api.nova: ('server_suspend',
|
||||
'server_list',
|
||||
'flavor_list',
|
||||
'extension_supported',
|
||||
'is_feature_available',),
|
||||
api.glance: ('image_list_detailed',),
|
||||
api.network: ('servers_update_addresses',)})
|
||||
def test_suspend_instance_if_placed_on_2nd_page(self):
|
||||
page_size = getattr(settings, 'API_RESULT_PAGE_SIZE', 2)
|
||||
servers = self.servers.list()[:3]
|
||||
|
||||
api.nova.extension_supported('AdminActions', IsA(http.HttpRequest)) \
|
||||
.MultipleTimes().AndReturn(True)
|
||||
api.nova.flavor_list(IsA(http.HttpRequest)) \
|
||||
.AndReturn(self.flavors.list())
|
||||
api.glance.image_list_detailed(IgnoreArg()) \
|
||||
.AndReturn((self.images.list(), False, False))
|
||||
|
||||
api.nova.server_list(IsA(http.HttpRequest), search_opts={
|
||||
'marker': servers[page_size - 1].id, 'paginate': True}) \
|
||||
.AndReturn([servers[page_size:], False])
|
||||
api.network.servers_update_addresses(
|
||||
IsA(http.HttpRequest), servers[page_size:])
|
||||
api.nova.server_suspend(IsA(http.HttpRequest),
|
||||
six.text_type(servers[-1].id))
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
self.request.GET['marker'] = servers[-2].id
|
||||
params = "=".join([tables.InstancesTable._meta.pagination_param,
|
||||
servers[page_size - 1].id])
|
||||
url = "?".join([reverse('horizon:project:instances:index'),
|
||||
params])
|
||||
formData = {'action': 'instances__suspend__%s' % servers[-1].id}
|
||||
|
||||
self.client.post(url, formData)
|
||||
|
||||
@helpers.create_stubs({api.nova: ('server_suspend',
|
||||
'server_list',
|
||||
'flavor_list',
|
||||
|
|
|
@ -53,6 +53,7 @@ from openstack_dashboard.dashboards.project.instances \
|
|||
import tabs as project_tabs
|
||||
from openstack_dashboard.dashboards.project.instances \
|
||||
import workflows as project_workflows
|
||||
from openstack_dashboard.views import get_url_with_pagination
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
@ -322,7 +323,12 @@ class DetailView(tabs.TabView):
|
|||
args=[instance.image['id']])
|
||||
instance.volume_url = self.volume_url
|
||||
context["instance"] = instance
|
||||
context["url"] = reverse(self.redirect_url)
|
||||
context["url"] = get_url_with_pagination(
|
||||
self.request,
|
||||
project_tables.InstancesTable._meta.pagination_param,
|
||||
project_tables.InstancesTable._meta.prev_pagination_param,
|
||||
self.redirect_url)
|
||||
|
||||
context["actions"] = self._get_actions(instance)
|
||||
return context
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
# 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.
|
||||
|
||||
import six
|
||||
|
||||
from openstack_dashboard.test import helpers as test
|
||||
from openstack_dashboard import views
|
||||
|
||||
|
||||
class DashboardViewsTest(test.TestCase):
|
||||
def test_get_url_with_pagination(self):
|
||||
req = self.request
|
||||
url_string = 'horizon:project:instances:index'
|
||||
url = views.get_url_with_pagination(req, None, None, url_string, None)
|
||||
self.assertEqual(six.text_type('/project/instances/'), url)
|
||||
|
||||
def test_get_url_with_pagination_with_if(self):
|
||||
req = self.request
|
||||
url_string = 'horizon:project:instances:detail'
|
||||
url = views.get_url_with_pagination(req, None, None, url_string, 'id')
|
||||
self.assertEqual(six.text_type('/project/instances/id/'), url)
|
||||
|
||||
def test_get_url_with_pagination_next(self):
|
||||
req = self.request
|
||||
url_string = 'horizon:project:instances:index'
|
||||
req.GET.update({'next': 'id'})
|
||||
url = views.get_url_with_pagination(
|
||||
req, 'next', None, url_string, None)
|
||||
self.assertEqual(six.text_type('/project/instances/?next=id'), url)
|
||||
|
||||
def test_get_url_with_pagination_prev(self):
|
||||
req = self.request
|
||||
url_string = 'horizon:project:instances:index'
|
||||
req.GET.update({'prev': 'id'})
|
||||
url = views.get_url_with_pagination(
|
||||
req, None, 'prev', url_string, None)
|
||||
self.assertEqual(six.text_type('/project/instances/?prev=id'), url)
|
|
@ -13,8 +13,10 @@
|
|||
# under the License.
|
||||
|
||||
from django.conf import settings
|
||||
from django.core import urlresolvers
|
||||
from django import shortcuts
|
||||
import django.views.decorators.vary
|
||||
from six.moves import urllib
|
||||
|
||||
import horizon
|
||||
from horizon import base
|
||||
|
@ -59,3 +61,22 @@ def splash(request):
|
|||
if MESSAGES_PATH:
|
||||
notifications.process_message_notification(request, MESSAGES_PATH)
|
||||
return response
|
||||
|
||||
|
||||
def get_url_with_pagination(request, marker_name, prev_marker_name, url_string,
|
||||
object_id=None):
|
||||
if object_id:
|
||||
url = urlresolvers.reverse(url_string, args=(object_id,))
|
||||
else:
|
||||
url = urlresolvers.reverse(url_string)
|
||||
marker = request.GET.get(marker_name, None)
|
||||
if marker:
|
||||
return "{}?{}".format(url,
|
||||
urllib.parse.urlencode({marker_name: marker}))
|
||||
|
||||
prev_marker = request.GET.get(prev_marker_name, None)
|
||||
if prev_marker:
|
||||
return "{}?{}".format(url,
|
||||
urllib.parse.urlencode({prev_marker_name:
|
||||
prev_marker}))
|
||||
return url
|
||||
|
|
Loading…
Reference in New Issue