Merge "Add a None option to the CONSOLE_TYPE setting"
This commit is contained in:
commit
6be6755dfa
@ -667,6 +667,17 @@ This setting notifies the Data Processing (Sahara) system whether or not
|
||||
automatic IP allocation is enabled. You would want to set this to True
|
||||
if you were running Nova Networking with auto_assign_floating_ip = True.
|
||||
|
||||
``CONSOLE_TYPE``
|
||||
-------------------------------------
|
||||
|
||||
Default: ``"AUTO"``
|
||||
|
||||
This settings specifies the type of in-browser VNC console used to access the
|
||||
VMs.
|
||||
Valid values are ``"AUTO"``(default), ``"VNC"``, ``"SPICE"``, ``"RDP"`` and
|
||||
``None``(this latest value is available in version 2014.2(Juno) to allow
|
||||
deactivating the in-browser console).
|
||||
|
||||
|
||||
Django Settings (Partial)
|
||||
=========================
|
||||
@ -971,3 +982,4 @@ following content::
|
||||
PANEL_GROUP = 'plugin_panel_group'
|
||||
PANEL_GROUP_NAME = 'Plugin Panel Group'
|
||||
PANEL_GROUP_DASHBOARD = 'admin'
|
||||
|
||||
|
@ -333,7 +333,10 @@ class ConsoleLink(tables.LinkAction):
|
||||
return {"project_id": project_id}
|
||||
|
||||
def allowed(self, request, instance=None):
|
||||
return instance.status in ACTIVE_STATES and not is_deleting(instance)
|
||||
# We check if ConsoleLink is allowed only if settings.CONSOLE_TYPE is
|
||||
# not set at all, or if it's set to any value other than None or False.
|
||||
return bool(getattr(settings, 'CONSOLE_TYPE', True)) and \
|
||||
instance.status in ACTIVE_STATES and not is_deleting(instance)
|
||||
|
||||
def get_link_url(self, datum):
|
||||
base_url = super(ConsoleLink, self).get_link_url(datum)
|
||||
|
@ -71,6 +71,11 @@ class ConsoleTab(tabs.Tab):
|
||||
|
||||
return {'console_url': console_url, 'instance_id': instance.id}
|
||||
|
||||
def allowed(self, request):
|
||||
# The ConsoleTab is available if settings.CONSOLE_TYPE is not set at
|
||||
# all, or if it's set to any value other than None or False.
|
||||
return bool(getattr(settings, 'CONSOLE_TYPE', True))
|
||||
|
||||
|
||||
class AuditTab(tabs.TableTab):
|
||||
name = _("Action Log")
|
||||
|
@ -61,7 +61,7 @@ class InstanceTests(helpers.TestCase):
|
||||
'servers_update_addresses',
|
||||
),
|
||||
})
|
||||
def test_index(self):
|
||||
def _get_index(self):
|
||||
servers = self.servers.list()
|
||||
api.nova.extension_supported('AdminActions',
|
||||
IsA(http.HttpRequest)) \
|
||||
@ -83,7 +83,11 @@ class InstanceTests(helpers.TestCase):
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
res = self.client.get(INDEX_URL)
|
||||
return self.client.get(INDEX_URL)
|
||||
|
||||
def test_index(self):
|
||||
|
||||
res = self._get_index()
|
||||
|
||||
self.assertTemplateUsed(res,
|
||||
'project/instances/index.html')
|
||||
@ -239,11 +243,36 @@ class InstanceTests(helpers.TestCase):
|
||||
self.assertEqual(len(instances), len(servers))
|
||||
self.assertContains(res, "(not found)")
|
||||
|
||||
def test_index_with_console_link(self):
|
||||
res = self._get_index()
|
||||
|
||||
instances_table = res.context['instances_table']
|
||||
instances = res.context['instances_table'].data
|
||||
console_link_rendered = False
|
||||
for instance in instances:
|
||||
for action in instances_table.get_row_actions(instance):
|
||||
if isinstance(action, tables.ConsoleLink):
|
||||
console_link_rendered = True
|
||||
break
|
||||
if console_link_rendered:
|
||||
break
|
||||
self.assertTrue(console_link_rendered)
|
||||
|
||||
@django.test.utils.override_settings(CONSOLE_TYPE=None)
|
||||
def test_index_without_console_link(self):
|
||||
res = self._get_index()
|
||||
|
||||
instances_table = res.context['instances_table']
|
||||
instances = res.context['instances_table'].data
|
||||
for instance in instances:
|
||||
for action in instances_table.get_row_actions(instance):
|
||||
self.assertNotIsInstance(action, tables.ConsoleLink)
|
||||
|
||||
@helpers.create_stubs({api.nova: ('server_list',
|
||||
'flavor_list',
|
||||
'server_delete',),
|
||||
api.glance: ('image_list_detailed',),
|
||||
api.network: ('servers_update_addresses',)})
|
||||
'flavor_list',
|
||||
'server_delete',),
|
||||
api.glance: ('image_list_detailed',),
|
||||
api.network: ('servers_update_addresses',)})
|
||||
def test_terminate_instance(self):
|
||||
servers = self.servers.list()
|
||||
server = servers[0]
|
||||
@ -623,52 +652,56 @@ class InstanceTests(helpers.TestCase):
|
||||
"flavor_get"),
|
||||
api.network: ("server_security_groups",
|
||||
"servers_update_addresses")})
|
||||
def _get_instance_details(self, server, qs=None,
|
||||
flavor_return=None, volumes_return=None,
|
||||
security_groups_return=None, ):
|
||||
|
||||
url = reverse('horizon:project:instances:detail', args=[server.id])
|
||||
if qs:
|
||||
url += qs
|
||||
|
||||
if flavor_return is None:
|
||||
flavor_return = self.flavors.first()
|
||||
|
||||
if volumes_return is None:
|
||||
volumes_return = []
|
||||
|
||||
if security_groups_return is None:
|
||||
security_groups_return = self.security_groups.list()
|
||||
|
||||
api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
|
||||
api.network.servers_update_addresses(IsA(http.HttpRequest),
|
||||
IgnoreArg())
|
||||
api.nova.instance_volumes_list(IsA(http.HttpRequest),
|
||||
server.id).AndReturn(volumes_return)
|
||||
api.nova.flavor_get(IsA(http.HttpRequest), server.flavor['id']) \
|
||||
.AndReturn(flavor_return)
|
||||
api.network.server_security_groups(IsA(http.HttpRequest), server.id) \
|
||||
.AndReturn(security_groups_return)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
return self.client.get(url)
|
||||
|
||||
def test_instance_details_volumes(self):
|
||||
server = self.servers.first()
|
||||
volumes = [self.volumes.list()[1]]
|
||||
security_group = self.security_groups.first()
|
||||
|
||||
api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
|
||||
api.network.servers_update_addresses(IsA(http.HttpRequest),
|
||||
IgnoreArg())
|
||||
api.nova.instance_volumes_list(IsA(http.HttpRequest),
|
||||
server.id).AndReturn(volumes)
|
||||
api.nova.flavor_get(IsA(http.HttpRequest), server.flavor['id']) \
|
||||
.AndReturn(self.flavors.first())
|
||||
api.network.server_security_groups(IsA(http.HttpRequest), server.id) \
|
||||
.AndReturn(self.security_groups.list())
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
url = reverse('horizon:project:instances:detail',
|
||||
args=[server.id])
|
||||
res = self.client.get(url)
|
||||
res = self._get_instance_details(server, volumes_return=volumes,
|
||||
security_groups_return=security_group)
|
||||
|
||||
self.assertItemsEqual(res.context['instance'].volumes, volumes)
|
||||
|
||||
self.assertItemsEqual(res.context['instance'].volumes, volumes)
|
||||
|
||||
@helpers.create_stubs({api.nova: ("server_get",
|
||||
"instance_volumes_list",
|
||||
"flavor_get"),
|
||||
api.network: ("server_security_groups",
|
||||
"servers_update_addresses")})
|
||||
def test_instance_details_volume_sorting(self):
|
||||
server = self.servers.first()
|
||||
volumes = self.volumes.list()[1:3]
|
||||
security_group = self.security_groups.first()
|
||||
|
||||
api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
|
||||
api.network.servers_update_addresses(IsA(http.HttpRequest),
|
||||
IgnoreArg())
|
||||
api.nova.instance_volumes_list(IsA(http.HttpRequest),
|
||||
server.id).AndReturn(volumes)
|
||||
api.nova.flavor_get(IsA(http.HttpRequest), server.flavor['id']) \
|
||||
.AndReturn(self.flavors.first())
|
||||
api.network.server_security_groups(IsA(http.HttpRequest), server.id) \
|
||||
.AndReturn(self.security_groups.list())
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
url = reverse('horizon:project:instances:detail',
|
||||
args=[server.id])
|
||||
res = self.client.get(url)
|
||||
res = self._get_instance_details(server, volumes_return=volumes,
|
||||
security_groups_return=security_group)
|
||||
|
||||
self.assertItemsEqual(res.context['instance'].volumes, volumes)
|
||||
self.assertEqual(res.context['instance'].volumes[0].device,
|
||||
@ -676,31 +709,12 @@ class InstanceTests(helpers.TestCase):
|
||||
self.assertEqual(res.context['instance'].volumes[1].device,
|
||||
"/dev/hdk")
|
||||
|
||||
@helpers.create_stubs({api.nova: ("server_get",
|
||||
"instance_volumes_list",
|
||||
"flavor_get"),
|
||||
api.network: ("server_security_groups",
|
||||
"servers_update_addresses")})
|
||||
def test_instance_details_metadata(self):
|
||||
server = self.servers.first()
|
||||
|
||||
api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
|
||||
api.network.servers_update_addresses(IsA(http.HttpRequest),
|
||||
IgnoreArg())
|
||||
api.nova.instance_volumes_list(IsA(http.HttpRequest),
|
||||
server.id).AndReturn([])
|
||||
api.nova.flavor_get(IsA(http.HttpRequest), server.flavor['id']) \
|
||||
.AndReturn(self.flavors.first())
|
||||
api.network.server_security_groups(IsA(http.HttpRequest), server.id) \
|
||||
.AndReturn(self.security_groups.list())
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
url = reverse('horizon:project:instances:detail',
|
||||
args=[server.id])
|
||||
tg = tabs.InstanceDetailTabs(self.request, instance=server)
|
||||
qs = "?%s=%s" % (tg.param_name, tg.get_tab("overview").get_id())
|
||||
res = self.client.get(url + qs)
|
||||
res = self._get_instance_details(server, qs)
|
||||
|
||||
self.assertContains(res, "<dd>keyName</dd>", 1)
|
||||
self.assertContains(res, "<dt>someMetaLabel</dt>", 1)
|
||||
@ -712,11 +726,6 @@ class InstanceTests(helpers.TestCase):
|
||||
# TODO(david-lyle): uncomment when fixed with Django 1.6
|
||||
# self.assertContains(res, "<dd><em>N/A</em></dd>", 1)
|
||||
|
||||
@helpers.create_stubs({api.nova: ("server_get",
|
||||
"instance_volumes_list",
|
||||
"flavor_get"),
|
||||
api.network: ("server_security_groups",
|
||||
"servers_update_addresses")})
|
||||
def test_instance_details_fault(self):
|
||||
server = self.servers.first()
|
||||
|
||||
@ -731,23 +740,37 @@ class InstanceTests(helpers.TestCase):
|
||||
"(reason=\"\")\n",
|
||||
"created": "2013-10-07T00:08:32Z"}
|
||||
|
||||
api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
|
||||
api.network.servers_update_addresses(IsA(http.HttpRequest),
|
||||
IgnoreArg())
|
||||
api.nova.instance_volumes_list(IsA(http.HttpRequest),
|
||||
server.id).AndReturn([])
|
||||
api.nova.flavor_get(IsA(http.HttpRequest), server.flavor['id']) \
|
||||
.AndReturn(self.flavors.first())
|
||||
api.network.server_security_groups(IsA(http.HttpRequest), server.id) \
|
||||
.AndReturn(self.security_groups.list())
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
url = reverse('horizon:project:instances:detail',
|
||||
args=[server.id])
|
||||
res = self.client.get(url)
|
||||
res = self._get_instance_details(server)
|
||||
self.assertItemsEqual(res.context['instance'].fault, server.fault)
|
||||
|
||||
def test_instance_details_console_tab(self):
|
||||
server = self.servers.first()
|
||||
|
||||
tg = tabs.InstanceDetailTabs(self.request, instance=server)
|
||||
qs = "?%s=%s" % (tg.param_name, tg.get_tab("console").get_id())
|
||||
res = self._get_instance_details(server, qs)
|
||||
self.assertIn(tabs.ConsoleTab, res.context_data['tab_group'].tabs)
|
||||
self.assertTemplateUsed(res,
|
||||
'project/instances/_detail_console.html')
|
||||
console_tab_rendered = False
|
||||
for tab in res.context_data['tab_group'].get_loaded_tabs():
|
||||
if isinstance(tab, tabs.ConsoleTab):
|
||||
console_tab_rendered = True
|
||||
break
|
||||
self.assertTrue(console_tab_rendered)
|
||||
|
||||
@django.test.utils.override_settings(CONSOLE_TYPE=None)
|
||||
def test_instance_details_console_tab_deactivated(self):
|
||||
server = self.servers.first()
|
||||
|
||||
tg = tabs.InstanceDetailTabs(self.request, instance=server)
|
||||
self.assertIsNone(tg.get_tab("console"))
|
||||
res = self._get_instance_details(server)
|
||||
self.assertTemplateNotUsed(res,
|
||||
'project/instances/_detail_console.html')
|
||||
for tab in res.context_data['tab_group'].get_loaded_tabs():
|
||||
self.assertNotIsInstance(tab, tabs.ConsoleTab)
|
||||
|
||||
@helpers.create_stubs({api.nova: ('server_get',)})
|
||||
def test_instance_details_exception(self):
|
||||
server = self.servers.first()
|
||||
|
@ -15,9 +15,12 @@
|
||||
<div class="footerInner">
|
||||
<div class="cell link">
|
||||
<a href="[[url]]">» [[view_details_label]]</a>
|
||||
[[#console_id]]
|
||||
<a href="[[url]][[console]]" class="vnc_window">» [[open_console_label]]</a>
|
||||
[[/console_id]]
|
||||
{% comment %}The Console link is available if settings.CONSOLE_TYPE is not set at all, or if it's set to any value other than None or False.{% endcomment %}
|
||||
{% if console_type %}
|
||||
[[#console_id]]
|
||||
<a href="[[url]][[console]]" class="vnc_window">» [[open_console_label]]</a>
|
||||
[[/console_id]]
|
||||
{% endif %}
|
||||
</div>
|
||||
<a class="add-interface btn btn-primary btn-xs ajax-modal [[type]]" href="[[add_interface_url]]">[[add_interface_label]]</a>
|
||||
<div class="cell delete">
|
||||
|
@ -112,6 +112,8 @@ class NetworkTopologyView(TemplateView):
|
||||
context['create_router_allowed'] = (
|
||||
network_config.get('enable_router', True) and
|
||||
self._has_permission((("network", "create_router"),)))
|
||||
context['console_type'] = getattr(
|
||||
settings, 'CONSOLE_TYPE', 'AUTO')
|
||||
return context
|
||||
|
||||
|
||||
|
@ -46,7 +46,8 @@ TEMPLATE_DEBUG = DEBUG
|
||||
# OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = 'Default'
|
||||
|
||||
# Set Console type:
|
||||
# valid options would be "AUTO", "VNC", "SPICE" or "RDP"
|
||||
# valid options would be "AUTO"(default), "VNC", "SPICE", "RDP" or None
|
||||
# Set to None explicitly if you want to deactivate the console.
|
||||
# CONSOLE_TYPE = "AUTO"
|
||||
|
||||
# Default OpenStack Dashboard configuration.
|
||||
|
Loading…
x
Reference in New Issue
Block a user