From 3b0f4cf6bea33e6ee1893f6e872d968b0c309f88 Mon Sep 17 00:00:00 2001 From: John Herndon Date: Tue, 19 Feb 2013 22:53:49 +0000 Subject: Flush tokens on instance delete Force console auth service to flush all tokens associated with an instance when it is deleted. This will fix bug 1125378, where the console for the wrong instance can be connected to via the console if the correct circumstances occur. This change also adds a call to validate the token when it is used. This check will ensure that all tokens are valid for their target instances. Tokens can become scrambled when a compute node is restarted, because the virt driver may not assign ports in the same way. Change-Id: I0d83ec6c4dbfef1af912a200ee15f8052f72da96 fixes: bug 1125378 --- nova/compute/api.py | 12 +++++++----- nova/compute/cells_api.py | 6 ++++-- nova/compute/manager.py | 19 ++++++++++++++++++- nova/compute/rpcapi.py | 10 ++++++++++ 4 files changed, 39 insertions(+), 8 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index cc07a998a..f917e379d 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -2189,8 +2189,9 @@ class API(base.Base): instance=instance, console_type=console_type) self.consoleauth_rpcapi.authorize_console(context, - connect_info['token'], console_type, connect_info['host'], - connect_info['port'], connect_info['internal_access_path']) + connect_info['token'], console_type, + connect_info['host'], connect_info['port'], + connect_info['internal_access_path'], instance['uuid']) return {'url': connect_info['access_url']} @@ -2207,10 +2208,11 @@ class API(base.Base): """Get a url to an instance Console.""" connect_info = self.compute_rpcapi.get_spice_console(context, instance=instance, console_type=console_type) - + print connect_info self.consoleauth_rpcapi.authorize_console(context, - connect_info['token'], console_type, connect_info['host'], - connect_info['port'], connect_info['internal_access_path']) + connect_info['token'], console_type, + connect_info['host'], connect_info['port'], + connect_info['internal_access_path'], instance['uuid']) return {'url': connect_info['access_url']} diff --git a/nova/compute/cells_api.py b/nova/compute/cells_api.py index 1e30331bc..22e31a8e1 100644 --- a/nova/compute/cells_api.py +++ b/nova/compute/cells_api.py @@ -465,7 +465,8 @@ class ComputeCellsAPI(compute_api.API): self.consoleauth_rpcapi.authorize_console(context, connect_info['token'], console_type, connect_info['host'], - connect_info['port'], connect_info['internal_access_path']) + connect_info['port'], connect_info['internal_access_path'], + instance_uuid=instance['uuid']) return {'url': connect_info['access_url']} @wrap_check_policy @@ -480,7 +481,8 @@ class ComputeCellsAPI(compute_api.API): self.consoleauth_rpcapi.authorize_console(context, connect_info['token'], console_type, connect_info['host'], - connect_info['port'], connect_info['internal_access_path']) + connect_info['port'], connect_info['internal_access_path'], + instance_uuid=instance['uuid']) return {'url': connect_info['access_url']} @validate_cell diff --git a/nova/compute/manager.py b/nova/compute/manager.py index afeb9f02e..4a6ab8eb5 100755 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -50,6 +50,7 @@ from nova.compute import task_states from nova.compute import utils as compute_utils from nova.compute import vm_states from nova import conductor +from nova import consoleauth import nova.context from nova import exception from nova import hooks @@ -317,7 +318,7 @@ class ComputeVirtAPI(virtapi.VirtAPI): class ComputeManager(manager.SchedulerDependentManager): """Manages the running instances from creation to destruction.""" - RPC_API_VERSION = '2.25' + RPC_API_VERSION = '2.26' def __init__(self, compute_driver=None, *args, **kwargs): """Load configuration options and connect to the hypervisor.""" @@ -335,6 +336,8 @@ class ComputeManager(manager.SchedulerDependentManager): self.conductor_api = conductor.API() self.is_quantum_security_groups = ( openstack_driver.is_quantum_security_groups()) + self.consoleauth_rpcapi = consoleauth.rpcapi.ConsoleAuthAPI() + super(ComputeManager, self).__init__(service_name="compute", *args, **kwargs) @@ -1223,6 +1226,10 @@ class ComputeManager(manager.SchedulerDependentManager): self._notify_about_instance_usage(context, instance, "delete.end", system_metadata=system_meta) + if CONF.vnc_enabled or CONF.spice.enabled: + self.consoleauth_rpcapi.delete_tokens_for_instance(context, + instance['uuid']) + @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @wrap_instance_event @wrap_instance_fault @@ -2555,6 +2562,16 @@ class ComputeManager(manager.SchedulerDependentManager): return connect_info + @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) + @wrap_instance_fault + def validate_console_port(self, ctxt, instance, port, console_type): + if console_type == "spice-html5": + console_info = self.driver.get_spice_console(instance) + else: + console_info = self.driver.get_vnc_console(instance) + + return console_info['port'] == port + def _attach_volume_boot(self, context, instance, volume, mountpoint): """Attach a volume to an instance at boot time. So actual attach is done by instance creation""" diff --git a/nova/compute/rpcapi.py b/nova/compute/rpcapi.py index 0be9972da..67dfc6a6b 100644 --- a/nova/compute/rpcapi.py +++ b/nova/compute/rpcapi.py @@ -161,6 +161,8 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): 2.23 - Remove network_info from reboot_instance 2.24 - Added get_spice_console method 2.25 - Add attach_interface() and detach_interface() + 2.26 - Add validate_console_token to ensure the service connects to + vnc on the correct port ''' # @@ -321,6 +323,14 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): topic=_compute_topic(self.topic, ctxt, None, instance), version='2.24') + def validate_console_port(self, ctxt, instance, port, console_type): + instance_p = jsonutils.to_primitive(instance) + return self.call(ctxt, self.make_msg('validate_console_port', + instance=instance_p, port=port, console_type=console_type), + topic=_compute_topic(self.topic, ctxt, + None, instance), + version='2.26') + def host_maintenance_mode(self, ctxt, host_param, mode, host): '''Set host maintenance mode -- cgit