Make auto console type in network topology work

The "open console" link in "Network Topology" does not autodetect
console type. This can be reproduced by setting CONSOLE_TYPE="AUTO" (or
ommiting the setting as AUTO is default value) while using SPICE
console.

Autodetection is correctly implemented in Instances view
(openstack_dashboard/dashboards/project/instances/console.py), but in
network topology
(openstack_dashboard/dashboards/project/network_topology/views.py in
JSONView) is only simple check, that ignore "RDP" and "AUTO".

Refactor get_console method, to return a tuple of console type and
console url, so other places can also use the method.

Change-Id: I064db5f1e5d363c9e6736703b66e78ad4e3de4d0
Closes-bug: #1403922
This commit is contained in:
liyingjun 2014-12-23 16:05:09 +08:00 committed by Randy Bertram
parent 2d2428e113
commit a9b2f7b3cc
6 changed files with 56 additions and 36 deletions

View File

@ -31,22 +31,23 @@ CONSOLES = SortedDict([('VNC', api.nova.server_vnc_console),
def get_console(request, console_type, instance):
"""Get a console url based on console type."""
"""Get a tuple of console url and console type."""
if console_type == 'AUTO':
check_consoles = CONSOLES
else:
try:
check_consoles = {'console_type': CONSOLES[console_type]}
check_consoles = {console_type: CONSOLES[console_type]}
except KeyError:
msg = _('Console type "%s" not supported.') % console_type
raise exceptions.NotAvailable(msg)
for api_call in check_consoles.values():
# Ugly workaround due novaclient API change from 2.17 to 2.18.
try:
httpnotimplemented = nova_exception.HttpNotImplemented
except AttributeError:
httpnotimplemented = nova_exception.HTTPNotImplemented
# Ugly workaround due novaclient API change from 2.17 to 2.18.
try:
httpnotimplemented = nova_exception.HttpNotImplemented
except AttributeError:
httpnotimplemented = nova_exception.HTTPNotImplemented
for con_type, api_call in check_consoles.iteritems():
try:
console = api_call(request, instance.id)
# If not supported, don't log it to avoid lot of errors in case
@ -61,6 +62,6 @@ def get_console(request, console_type, instance):
console.url,
urlencode({'title': getattr(instance, "name", "")}),
instance.id)
return console_url
return (con_type, console_url)
raise exceptions.NotAvailable(_('No available console found.'))

View File

@ -68,7 +68,8 @@ class ConsoleTab(tabs.Tab):
console_type = getattr(settings, 'CONSOLE_TYPE', 'AUTO')
console_url = None
try:
console_url = console.get_console(request, console_type, instance)
console_url = console.get_console(request, console_type,
instance)[1]
except exceptions.NotAvailable:
exceptions.handle(request, ignore=True, force_log=True)

View File

@ -1014,7 +1014,7 @@ class InstanceTests(helpers.TestCase):
api.nova.server_get(IsA(http.HttpRequest), server.id) \
.AndReturn(server)
console.get_console(IgnoreArg(), 'VNC', server) \
.AndReturn(CONSOLE_URL)
.AndReturn(('VNC', CONSOLE_URL))
self.mox.ReplayAll()
@ -1055,7 +1055,7 @@ class InstanceTests(helpers.TestCase):
api.nova.server_get(IsA(http.HttpRequest), server.id) \
.AndReturn(server)
console.get_console(IgnoreArg(), 'SPICE', server) \
.AndReturn(CONSOLE_URL)
.AndReturn(('SPICE', CONSOLE_URL))
self.mox.ReplayAll()
@ -1096,7 +1096,7 @@ class InstanceTests(helpers.TestCase):
api.nova.server_get(IsA(http.HttpRequest), server.id) \
.AndReturn(server)
console.get_console(IgnoreArg(), 'RDP', server) \
.AndReturn(CONSOLE_URL)
.AndReturn(('RDP', CONSOLE_URL))
self.mox.ReplayAll()
@ -4254,8 +4254,7 @@ class ConsoleManagerTests(helpers.TestCase):
('SPICE', api.nova.server_spice_console),
('RDP', api.nova.server_rdp_console)])
def test_get_console_vnc(self):
server = self.servers.first()
def _get_console_vnc(self, server):
console_mock = self.mox.CreateMock(api.nova.VNCConsole)
console_mock.url = '/VNC'
@ -4266,12 +4265,14 @@ class ConsoleManagerTests(helpers.TestCase):
self.mox.ReplayAll()
self.setup_consoles()
def test_get_console_vnc(self):
server = self.servers.first()
self._get_console_vnc(server)
url = '/VNC&title=%s(%s)' % (server.name, server.id)
data = console.get_console(self.request, 'VNC', server)
data = console.get_console(self.request, 'VNC', server)[1]
self.assertEqual(data, url)
def test_get_console_spice(self):
server = self.servers.first()
def _get_console_spice(self, server):
console_mock = self.mox.CreateMock(api.nova.SPICEConsole)
console_mock.url = '/SPICE'
@ -4282,12 +4283,14 @@ class ConsoleManagerTests(helpers.TestCase):
self.mox.ReplayAll()
self.setup_consoles()
def test_get_console_spice(self):
server = self.servers.first()
self._get_console_spice(server)
url = '/SPICE&title=%s(%s)' % (server.name, server.id)
data = console.get_console(self.request, 'SPICE', server)
data = console.get_console(self.request, 'SPICE', server)[1]
self.assertEqual(data, url)
def test_get_console_rdp(self):
server = self.servers.first()
def _get_console_rdp(self, server):
console_mock = self.mox.CreateMock(api.nova.RDPConsole)
console_mock.url = '/RDP'
@ -4298,8 +4301,11 @@ class ConsoleManagerTests(helpers.TestCase):
self.mox.ReplayAll()
self.setup_consoles()
def test_get_console_rdp(self):
server = self.servers.first()
self._get_console_rdp(server)
url = '/RDP&title=%s(%s)' % (server.name, server.id)
data = console.get_console(self.request, 'RDP', server)
data = console.get_console(self.request, 'RDP', server)[1]
self.assertEqual(data, url)
def test_get_console_auto_iterate_available(self):
@ -4324,7 +4330,7 @@ class ConsoleManagerTests(helpers.TestCase):
self.setup_consoles()
url = '/RDP&title=%s(%s)' % (server.name, server.id)
data = console.get_console(self.request, 'AUTO', server)
data = console.get_console(self.request, 'AUTO', server)[1]
self.assertEqual(data, url)
def test_invalid_console_type_raise_value_error(self):

View File

@ -161,7 +161,7 @@ def console(request, instance_id):
def vnc(request, instance_id):
try:
instance = api.nova.server_get(request, instance_id)
console_url = project_console.get_console(request, 'VNC', instance)
console_url = project_console.get_console(request, 'VNC', instance)[1]
return shortcuts.redirect(console_url)
except Exception:
redirect = reverse("horizon:project:instances:index")
@ -172,7 +172,8 @@ def vnc(request, instance_id):
def spice(request, instance_id):
try:
instance = api.nova.server_get(request, instance_id)
console_url = project_console.get_console(request, 'SPICE', instance)
console_url = project_console.get_console(request, 'SPICE',
instance)[1]
return shortcuts.redirect(console_url)
except Exception:
redirect = reverse("horizon:project:instances:index")
@ -183,7 +184,7 @@ def spice(request, instance_id):
def rdp(request, instance_id):
try:
instance = api.nova.server_get(request, instance_id)
console_url = project_console.get_console(request, 'RDP', instance)
console_url = project_console.get_console(request, 'RDP', instance)[1]
return shortcuts.redirect(console_url)
except Exception:
redirect = reverse("horizon:project:instances:index")

View File

@ -86,7 +86,6 @@ class NetworkTopologyTests(test.TestCase):
'name': server.name,
'status': server.status,
'task': None,
'console': 'vnc',
'url': '/project/instances/%s/' % server.id}
for server in self.servers.list()]
self.assertEqual(expect_server_urls, data['servers'])

View File

@ -22,9 +22,12 @@ from django.conf import settings
from django.core.urlresolvers import reverse
from django.core.urlresolvers import reverse_lazy
from django.http import HttpResponse # noqa
from django.utils.translation import ugettext_lazy as _
from django.views.generic import TemplateView # noqa
from django.views.generic import View # noqa
from horizon import exceptions
from openstack_dashboard import api
from openstack_dashboard.usage import quotas
@ -35,6 +38,8 @@ from openstack_dashboard.dashboards.project.network_topology.ports \
from openstack_dashboard.dashboards.project.network_topology.routers \
import tables as routers_tables
from openstack_dashboard.dashboards.project.instances import\
console as i_console
from openstack_dashboard.dashboards.project.instances import\
views as i_views
from openstack_dashboard.dashboards.project.instances.workflows import\
@ -154,16 +159,23 @@ class JSONView(View):
servers, more = api.nova.server_list(request)
except Exception:
servers = []
data = []
console_type = getattr(settings, 'CONSOLE_TYPE', 'AUTO')
if console_type == 'SPICE':
console = 'spice'
else:
console = 'vnc'
data = [{'name': server.name,
'status': server.status,
'console': console,
'task': getattr(server, 'OS-EXT-STS:task_state'),
'id': server.id} for server in servers]
# lowercase of the keys will be used at the end of the console URL.
for server in servers:
try:
console = i_console.get_console(
request, console_type, server)[0].lower()
except exceptions.NotAvailable:
console = None
exceptions.handle(request, _('No console available.'))
server_data = {'name': server.name,
'status': server.status,
'task': getattr(server, 'OS-EXT-STS:task_state'),
'id': server.id}
if console:
server_data['console'] = console
data.append(server_data)
self.add_resource_url('horizon:project:instances:detail', data)
return data