Redirect VM console dynamically
Previously when a user accesses the network topology panel horizon resolves VM console URL when returning server data. This requires one API call to nova per VM, and this causes a scaling issue. Actually there is no need to resolves VM console URL when the network topology. A console URL corresponding to a requested VM can be resolved when a user actually accesses a console. This reduces the number of API calls drastically and addresses the scaling issue reported in the bug report. Change-Id: Icc667449e2988e6227012a6e899835a97ce0d738 Closes-Bug: #1723142
This commit is contained in:
parent
d46246d476
commit
974f0418ef
@ -1268,7 +1268,7 @@ class InstanceTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
|
||||
|
||||
self.assertContains(res, "Unable to get log for")
|
||||
|
||||
def test_instance_vnc(self):
|
||||
def test_instance_auto_console(self):
|
||||
server = self.servers.first()
|
||||
CONSOLE_OUTPUT = '/vncserver'
|
||||
CONSOLE_TITLE = '&title=%s(%s)' % (server.name, server.id)
|
||||
@ -1281,12 +1281,12 @@ class InstanceTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
|
||||
self.mox.StubOutWithMock(console, 'get_console')
|
||||
api.nova.server_get(IsA(http.HttpRequest), server.id) \
|
||||
.AndReturn(server)
|
||||
console.get_console(IgnoreArg(), 'VNC', server) \
|
||||
console.get_console(IgnoreArg(), 'AUTO', server) \
|
||||
.AndReturn(('VNC', CONSOLE_URL))
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
url = reverse('horizon:project:instances:vnc',
|
||||
url = reverse('horizon:project:instances:auto_console',
|
||||
args=[server.id])
|
||||
res = self.client.get(url)
|
||||
redirect = CONSOLE_URL
|
||||
|
@ -34,6 +34,7 @@ urlpatterns = [
|
||||
url(INSTANCES % 'serial', views.SerialConsoleView.as_view(),
|
||||
name='serial'),
|
||||
url(INSTANCES % 'console', views.console, name='console'),
|
||||
url(INSTANCES % 'auto_console', views.auto_console, name='auto_console'),
|
||||
url(INSTANCES % 'vnc', views.vnc, name='vnc'),
|
||||
url(INSTANCES % 'spice', views.spice, name='spice'),
|
||||
url(INSTANCES % 'rdp', views.rdp, name='rdp'),
|
||||
|
@ -198,6 +198,19 @@ def console(request, instance_id):
|
||||
return http.HttpResponse(data.encode('utf-8'), content_type='text/plain')
|
||||
|
||||
|
||||
def auto_console(request, instance_id):
|
||||
console_type = getattr(settings, 'CONSOLE_TYPE', 'AUTO')
|
||||
try:
|
||||
instance = api.nova.server_get(request, instance_id)
|
||||
console_url = project_console.get_console(request, console_type,
|
||||
instance)[1]
|
||||
return shortcuts.redirect(console_url)
|
||||
except Exception:
|
||||
redirect = reverse("horizon:project:instances:index")
|
||||
msg = _('Unable to get console for instance "%s".') % instance_id
|
||||
exceptions.handle(request, msg, redirect=redirect)
|
||||
|
||||
|
||||
def vnc(request, instance_id):
|
||||
try:
|
||||
instance = api.nova.server_get(request, instance_id)
|
||||
|
@ -20,7 +20,6 @@ from mox3.mox import IsA
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from openstack_dashboard import api
|
||||
from openstack_dashboard.dashboards.project.instances import console
|
||||
from openstack_dashboard.dashboards.project.network_topology.views import \
|
||||
TranslationHelper
|
||||
from openstack_dashboard.test import helpers as test
|
||||
@ -37,8 +36,7 @@ class NetworkTopologyTests(test.TestCase):
|
||||
api.neutron: ('network_list_for_tenant',
|
||||
'network_list',
|
||||
'router_list',
|
||||
'port_list',),
|
||||
console: ('get_console',)})
|
||||
'port_list')})
|
||||
def test_json_view(self):
|
||||
self._test_json_view()
|
||||
|
||||
@ -46,12 +44,20 @@ class NetworkTopologyTests(test.TestCase):
|
||||
OPENSTACK_NEUTRON_NETWORK={'enable_router': False})
|
||||
@test.create_stubs({api.nova: ('server_list',),
|
||||
api.neutron: ('network_list_for_tenant',
|
||||
'port_list'),
|
||||
console: ('get_console',)})
|
||||
'port_list')})
|
||||
def test_json_view_router_disabled(self):
|
||||
self._test_json_view(router_enable=False)
|
||||
|
||||
def _test_json_view(self, router_enable=True):
|
||||
@django.test.utils.override_settings(CONSOLE_TYPE=None)
|
||||
@test.create_stubs({api.nova: ('server_list',),
|
||||
api.neutron: ('network_list_for_tenant',
|
||||
'network_list',
|
||||
'router_list',
|
||||
'port_list')})
|
||||
def test_json_view_console_disabled(self):
|
||||
self._test_json_view(with_console=False)
|
||||
|
||||
def _test_json_view(self, router_enable=True, with_console=True):
|
||||
api.nova.server_list(
|
||||
IsA(http.HttpRequest)).AndReturn([self.servers.list(), False])
|
||||
|
||||
@ -63,17 +69,6 @@ class NetworkTopologyTests(test.TestCase):
|
||||
IsA(http.HttpRequest),
|
||||
self.tenant.id).AndReturn(tenant_networks)
|
||||
|
||||
for server in self.servers.list():
|
||||
if server.status != u'BUILD':
|
||||
CONSOLE_OUTPUT = '/vncserver'
|
||||
CONSOLE_TITLE = '&title=%s' % server.id
|
||||
CONSOLE_URL = CONSOLE_OUTPUT + CONSOLE_TITLE
|
||||
|
||||
console_mock = self.mox.CreateMock(api.nova.VNCConsole)
|
||||
console_mock.url = CONSOLE_OUTPUT
|
||||
console.get_console(IsA(http.HttpRequest), 'AUTO', server) \
|
||||
.AndReturn(('VNC', CONSOLE_URL))
|
||||
|
||||
# router1 : gateway port not in the port list
|
||||
# router2 : no gateway port
|
||||
# router3 : gateway port included in port list
|
||||
@ -109,8 +104,8 @@ class NetworkTopologyTests(test.TestCase):
|
||||
'task': None,
|
||||
'url': '/project/instances/%s/' % server.id
|
||||
}
|
||||
if server.status != 'BUILD':
|
||||
expect_server['console'] = 'vnc'
|
||||
if server.status != 'BUILD' and with_console:
|
||||
expect_server['console'] = 'auto_console'
|
||||
expect_server_urls.append(expect_server)
|
||||
self.assertEqual(expect_server_urls, data['servers'])
|
||||
|
||||
|
@ -45,8 +45,6 @@ from openstack_dashboard.dashboards.project.network_topology \
|
||||
import tabs as topology_tabs
|
||||
from openstack_dashboard.dashboards.project.network_topology import utils
|
||||
|
||||
from openstack_dashboard.dashboards.project.instances import\
|
||||
console as i_console
|
||||
from openstack_dashboard.dashboards.project.instances.tables import \
|
||||
STATUS_DISPLAY_CHOICES as instance_choices
|
||||
from openstack_dashboard.dashboards.project.instances import\
|
||||
@ -251,12 +249,8 @@ class JSONView(View):
|
||||
# Avoid doing extra calls for console if the server is in
|
||||
# a invalid status for console connection
|
||||
if server.status.lower() not in console_invalid_status:
|
||||
try:
|
||||
console = i_console.get_console(
|
||||
request, console_type, server)[0].lower()
|
||||
server_data['console'] = console
|
||||
except exceptions.NotAvailable:
|
||||
pass
|
||||
if console_type:
|
||||
server_data['console'] = 'auto_console'
|
||||
|
||||
data.append(server_data)
|
||||
self.add_resource_url('horizon:project:instances:detail', data)
|
||||
|
Loading…
x
Reference in New Issue
Block a user