From 2116d1033e1d87e64f2cc80784711467d89cc4aa Mon Sep 17 00:00:00 2001 From: Gary Kotton Date: Thu, 22 Aug 2013 03:29:30 -0700 Subject: [PATCH] VMware: enable VNC access without user having to enter password When the vnc_password was not configured in the 'vmware' section the user was unable to access the VNC console. The user would be requested to enter a password but all attempts would fail. The 'vnc_password' was added as a workaround to the problem above. The fix ensures that the VMware driver behaves like all of the other virt drivers when it comes to the VNC access, that is, the user will not have to enter a password. The password support will be deprecated and removed in the next version. Fixes bug: 1215352 Change-Id: I728861b8965ee3d3b8444a0440ddd0a8e5bb9021 --- etc/nova/nova.conf.sample | 5 ++- nova/tests/virt/vmwareapi/test_vmwareapi.py | 22 +++++------ .../virt/vmwareapi/test_vmwareapi_vm_util.py | 37 +++++++++++++++++++ nova/virt/vmwareapi/driver.py | 6 ++- nova/virt/vmwareapi/vm_util.py | 16 +++++--- 5 files changed, 68 insertions(+), 18 deletions(-) diff --git a/etc/nova/nova.conf.sample b/etc/nova/nova.conf.sample index b6df481a5ba4..46dd4d938510 100644 --- a/etc/nova/nova.conf.sample +++ b/etc/nova/nova.conf.sample @@ -3287,7 +3287,10 @@ # Total number of VNC ports (integer value) #vnc_port_total=10000 -# VNC password (string value) +# DEPRECATED. VNC password. The password-based access to VNC +# consoles will be removed in the next release. The default +# value will disable password protection on the VNC console. +# (string value) #vnc_password= # Whether to use linked clone (boolean value) diff --git a/nova/tests/virt/vmwareapi/test_vmwareapi.py b/nova/tests/virt/vmwareapi/test_vmwareapi.py index 3ea6005ef5cd..d6e179fbd505 100644 --- a/nova/tests/virt/vmwareapi/test_vmwareapi.py +++ b/nova/tests/virt/vmwareapi/test_vmwareapi.py @@ -136,6 +136,7 @@ class VMwareAPIVMTestCase(test.NoDBTestCase): 'size': 512, } nova.tests.image.fake.stub_out_image_service(self.stubs) + self.vnc_host = 'test_url' def tearDown(self): super(VMwareAPIVMTestCase, self).tearDown() @@ -669,15 +670,22 @@ class VMwareAPIVMTestCase(test.NoDBTestCase): self.conn.get_vnc_console, self.instance) - def test_get_vnc_console(self): + def _test_get_vnc_console(self): self._create_vm() fake_vm = vmwareapi_fake._get_objects("VirtualMachine").objects[0] fake_vm_id = int(fake_vm.obj.value.replace('vm-', '')) vnc_dict = self.conn.get_vnc_console(self.instance) - self.assertEquals(vnc_dict['host'], 'test_url') + self.assertEquals(vnc_dict['host'], self.vnc_host) self.assertEquals(vnc_dict['port'], cfg.CONF.vmware.vnc_port + fake_vm_id % cfg.CONF.vmware.vnc_port_total) + def test_get_vnc_console(self): + self._test_get_vnc_console() + + def test_get_vnc_console_with_password(self): + self.flags(vnc_password='vmware', group='vmware') + self._test_get_vnc_console() + def test_host_ip_addr(self): self.assertEquals(self.conn.get_host_ip_addr(), "test_url") @@ -916,6 +924,7 @@ class VMwareAPIVCDriverTestCase(VMwareAPIVMTestCase): self.conn = driver.VMwareVCDriver(None, False) self.node_name = self.conn._resources.keys()[0] self.node_name2 = self.conn._resources.keys()[1] + self.vnc_host = 'ha-host' def tearDown(self): super(VMwareAPIVCDriverTestCase, self).tearDown() @@ -982,15 +991,6 @@ class VMwareAPIVCDriverTestCase(VMwareAPIVMTestCase): self._test_finish_revert_migration(power_on=False) self.assertEquals(False, self.power_on_called) - def test_get_vnc_console(self): - self._create_vm() - fake_vm = vmwareapi_fake._get_objects("VirtualMachine").objects[0] - fake_vm_id = int(fake_vm.obj.value.replace('vm-', '')) - vnc_dict = self.conn.get_vnc_console(self.instance) - self.assertEquals(vnc_dict['host'], "ha-host") - self.assertEquals(vnc_dict['port'], cfg.CONF.vmware.vnc_port + - fake_vm_id % cfg.CONF.vmware.vnc_port_total) - def test_snapshot(self): # Ensure VMwareVCVMOps's _get_copy_virtual_disk_spec is getting called self.mox.StubOutWithMock(vmops.VMwareVCVMOps, diff --git a/nova/tests/virt/vmwareapi/test_vmwareapi_vm_util.py b/nova/tests/virt/vmwareapi/test_vmwareapi_vm_util.py index c2922a1dad28..8dcdfc00f2bd 100644 --- a/nova/tests/virt/vmwareapi/test_vmwareapi_vm_util.py +++ b/nova/tests/virt/vmwareapi/test_vmwareapi_vm_util.py @@ -281,3 +281,40 @@ class VMwareVMUtilTestCase(test.NoDBTestCase): self.assertEqual("lsiLogic", vmdk_adapter_type) vmdk_adapter_type = vm_util.get_vmdk_adapter_type("dummyAdapter") self.assertEqual("dummyAdapter", vmdk_adapter_type) + + def _test_get_vnc_config_spec(self, port, password): + + result = vm_util.get_vnc_config_spec(fake.FakeFactory(), + port, password) + return result + + def test_get_vnc_config_spec(self): + result = self._test_get_vnc_config_spec(7, None) + expected = """{'extraConfig': [ + {'value': 'true', + 'key': 'RemoteDisplay.vnc.enabled', + 'obj_name': 'ns0:OptionValue'}, + {'value': 7, + 'key': 'RemoteDisplay.vnc.port', + 'obj_name': 'ns0:OptionValue'}], + 'obj_name': 'ns0:VirtualMachineConfigSpec'}""" + expected = re.sub(r'\s+', '', expected) + result = re.sub(r'\s+', '', repr(result)) + self.assertEqual(expected, result) + + def test_get_vnc_config_spec_password(self): + result = self._test_get_vnc_config_spec(7, 'password') + expected = """{'extraConfig': [ + {'value': 'true', + 'key': 'RemoteDisplay.vnc.enabled', + 'obj_name': 'ns0:OptionValue'}, + {'value': 7, + 'key': 'RemoteDisplay.vnc.port', + 'obj_name': 'ns0:OptionValue'}, + {'value':'password', + 'key':'RemoteDisplay.vnc.password', + 'obj_name':'ns0:OptionValue'}], + 'obj_name': 'ns0:VirtualMachineConfigSpec'}""" + expected = re.sub(r'\s+', '', expected) + result = re.sub(r'\s+', '', repr(result)) + self.assertEqual(expected, result) diff --git a/nova/virt/vmwareapi/driver.py b/nova/virt/vmwareapi/driver.py index bd9d45e389a3..b6276a1f5127 100644 --- a/nova/virt/vmwareapi/driver.py +++ b/nova/virt/vmwareapi/driver.py @@ -99,10 +99,14 @@ vmwareapi_opts = [ deprecated_name='vnc_port_total', deprecated_group='DEFAULT', help='Total number of VNC ports'), + # Deprecated, remove in Icehouse cfg.StrOpt('vnc_password', deprecated_name='vnc_password', deprecated_group='DEFAULT', - help='VNC password', + help='DEPRECATED. VNC password. The password-based access to ' + 'VNC consoles will be removed in the next release. The ' + 'default value will disable password protection on the ' + 'VNC console.', secret=True), cfg.BoolOpt('use_linked_clone', default=True, diff --git a/nova/virt/vmwareapi/vm_util.py b/nova/virt/vmwareapi/vm_util.py index c909970a0a4b..6fe97dd83954 100644 --- a/nova/virt/vmwareapi/vm_util.py +++ b/nova/virt/vmwareapi/vm_util.py @@ -27,7 +27,6 @@ from nova.openstack.common.gettextutils import _ from nova.openstack.common import log as logging from nova.virt.vmwareapi import vim_util - LOG = logging.getLogger(__name__) @@ -569,10 +568,17 @@ def get_vnc_config_spec(client_factory, port, password): opt_port = client_factory.create('ns0:OptionValue') opt_port.key = "RemoteDisplay.vnc.port" opt_port.value = port - opt_pass = client_factory.create('ns0:OptionValue') - opt_pass.key = "RemoteDisplay.vnc.password" - opt_pass.value = password - virtual_machine_config_spec.extraConfig = [opt_enabled, opt_port, opt_pass] + extras = [opt_enabled, opt_port] + if password: + LOG.deprecated(_("The password-based access to VNC consoles will be " + "removed in the next release. Please, switch to " + "using the default value (this will disable password " + "protection on the VNC console).")) + opt_pass = client_factory.create('ns0:OptionValue') + opt_pass.key = "RemoteDisplay.vnc.password" + opt_pass.value = password + extras.append(opt_pass) + virtual_machine_config_spec.extraConfig = extras return virtual_machine_config_spec