Merge "Fix actions inside instance details view page"

This commit is contained in:
Jenkins 2017-09-21 13:29:40 +00:00 committed by Gerrit Code Review
commit 20eaa03174
7 changed files with 149 additions and 9 deletions

View File

@ -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):

View File

@ -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"))

View File

@ -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"))

View File

@ -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',

View File

@ -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

View File

@ -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)

View File

@ -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