Merge "Save admin password to sysmeta in libvirt driver"
This commit is contained in:
commit
c1716490cd
|
@ -1337,6 +1337,39 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
|
||||
mock_guest.set_user_password.assert_called_once_with("root", "123")
|
||||
|
||||
@mock.patch('nova.objects.Instance.save')
|
||||
@mock.patch('oslo_serialization.base64.encode_as_text')
|
||||
@mock.patch('nova.api.metadata.password.convert_password')
|
||||
@mock.patch('nova.crypto.ssh_encrypt_text')
|
||||
@mock.patch('nova.utils.get_image_from_system_metadata')
|
||||
@mock.patch.object(host.Host,
|
||||
'has_min_version', return_value=True)
|
||||
@mock.patch('nova.virt.libvirt.host.Host.get_guest')
|
||||
def test_set_admin_password_saves_sysmeta(self, mock_get_guest,
|
||||
ver, mock_image, mock_encrypt,
|
||||
mock_convert, mock_encode,
|
||||
mock_save):
|
||||
self.flags(virt_type='kvm', group='libvirt')
|
||||
instance = objects.Instance(**self.test_instance)
|
||||
# Password will only be saved in sysmeta if the key_data is present
|
||||
instance.key_data = 'ssh-rsa ABCFEFG'
|
||||
mock_image.return_value = {"properties": {
|
||||
"hw_qemu_guest_agent": "yes"}}
|
||||
mock_guest = mock.Mock(spec=libvirt_guest.Guest)
|
||||
mock_get_guest.return_value = mock_guest
|
||||
mock_convert.return_value = {'password_0': 'converted-password'}
|
||||
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
drvr.set_admin_password(instance, "123")
|
||||
|
||||
mock_guest.set_user_password.assert_called_once_with("root", "123")
|
||||
mock_encrypt.assert_called_once_with(instance.key_data, '123')
|
||||
mock_encode.assert_called_once_with(mock_encrypt.return_value)
|
||||
mock_convert.assert_called_once_with(None, mock_encode.return_value)
|
||||
self.assertEqual('converted-password',
|
||||
instance.system_metadata['password_0'])
|
||||
mock_save.assert_called_once_with()
|
||||
|
||||
@mock.patch.object(host.Host,
|
||||
'has_min_version', return_value=True)
|
||||
@mock.patch('nova.virt.libvirt.host.Host.get_guest')
|
||||
|
@ -1439,8 +1472,11 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
mock_get_guest.return_value = mock_guest
|
||||
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
self.assertRaises(exception.NovaException,
|
||||
drvr.set_admin_password, instance, "123")
|
||||
with mock.patch.object(
|
||||
drvr, '_save_instance_password_if_sshkey_present') as save_p:
|
||||
self.assertRaises(exception.NovaException,
|
||||
drvr.set_admin_password, instance, "123")
|
||||
save_p.assert_not_called()
|
||||
|
||||
@mock.patch('nova.utils.get_image_from_system_metadata')
|
||||
@mock.patch.object(host.Host,
|
||||
|
|
|
@ -52,6 +52,7 @@ from os_brick import exception as brick_exception
|
|||
from os_brick.initiator import connector
|
||||
from oslo_concurrency import processutils
|
||||
from oslo_log import log as logging
|
||||
from oslo_serialization import base64
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_service import loopingcall
|
||||
from oslo_utils import encodeutils
|
||||
|
@ -66,6 +67,7 @@ import six
|
|||
from six.moves import range
|
||||
|
||||
from nova.api.metadata import base as instance_metadata
|
||||
from nova.api.metadata import password
|
||||
from nova import block_device
|
||||
from nova.compute import power_state
|
||||
from nova.compute import task_states
|
||||
|
@ -74,6 +76,7 @@ import nova.conf
|
|||
from nova.console import serial as serial_console
|
||||
from nova.console import type as ctype
|
||||
from nova import context as nova_context
|
||||
from nova import crypto
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
from nova import image
|
||||
|
@ -2025,6 +2028,17 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
else:
|
||||
raise exception.SetAdminPasswdNotSupported()
|
||||
|
||||
# TODO(melwitt): Combine this with the similar xenapi code at some point.
|
||||
def _save_instance_password_if_sshkey_present(self, instance, new_pass):
|
||||
sshkey = instance.key_data if 'key_data' in instance else None
|
||||
if sshkey and sshkey.startswith("ssh-rsa"):
|
||||
enc = crypto.ssh_encrypt_text(sshkey, new_pass)
|
||||
# NOTE(melwitt): The convert_password method doesn't actually do
|
||||
# anything with the context argument, so we can pass None.
|
||||
instance.system_metadata.update(
|
||||
password.convert_password(None, base64.encode_as_text(enc)))
|
||||
instance.save()
|
||||
|
||||
def set_admin_password(self, instance, new_pass):
|
||||
self._can_set_admin_password(instance.image_meta)
|
||||
|
||||
|
@ -2049,6 +2063,10 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
'"%(user)s": [Error Code %(error_code)s] %(ex)s')
|
||||
% {'user': user, 'error_code': error_code, 'ex': err_msg})
|
||||
raise exception.InternalError(msg)
|
||||
else:
|
||||
# Save the password in sysmeta so it may be retrieved from the
|
||||
# metadata service.
|
||||
self._save_instance_password_if_sshkey_present(instance, new_pass)
|
||||
|
||||
def _can_quiesce(self, instance, image_meta):
|
||||
if CONF.libvirt.virt_type not in ('kvm', 'qemu'):
|
||||
|
|
Loading…
Reference in New Issue