diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py index 4eea7b0b3364..ba87644218db 100644 --- a/nova/tests/test_libvirt.py +++ b/nova/tests/test_libvirt.py @@ -241,6 +241,59 @@ class LibvirtVolumeTestCase(test.TestCase): self.assertEqual(tree.find('./source').get('protocol'), 'rbd') rbd_name = '%s/%s' % (FLAGS.rbd_pool, name) self.assertEqual(tree.find('./source').get('name'), rbd_name) + self.assertEqual(tree.find('./source/auth'), None) + libvirt_driver.disconnect_volume(connection_info, mount_device) + connection_info = vol_driver.terminate_connection(vol, self.connr) + + def test_libvirt_rbd_driver_auth_enabled(self): + vol_driver = volume_driver.RBDDriver() + libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn) + name = 'volume-00000001' + vol = {'id': 1, 'name': name} + connection_info = vol_driver.initialize_connection(vol, self.connr) + uuid = '875a8070-d0b9-4949-8b31-104d125c9a64' + user = 'foo' + secret_type = 'ceph' + connection_info['data']['auth_enabled'] = True + connection_info['data']['auth_username'] = user + connection_info['data']['secret_type'] = secret_type + connection_info['data']['secret_uuid'] = uuid + + mount_device = "vde" + conf = libvirt_driver.connect_volume(connection_info, mount_device) + tree = conf.format_dom() + self.assertEqual(tree.get('type'), 'network') + self.assertEqual(tree.find('./source').get('protocol'), 'rbd') + rbd_name = '%s/%s' % (FLAGS.rbd_pool, name) + self.assertEqual(tree.find('./source').get('name'), rbd_name) + self.assertEqual(tree.find('./auth').get('username'), user) + self.assertEqual(tree.find('./auth/secret').get('type'), secret_type) + self.assertEqual(tree.find('./auth/secret').get('uuid'), uuid) + libvirt_driver.disconnect_volume(connection_info, mount_device) + connection_info = vol_driver.terminate_connection(vol, self.connr) + + def test_libvirt_rbd_driver_auth_disabled(self): + vol_driver = volume_driver.RBDDriver() + libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn) + name = 'volume-00000001' + vol = {'id': 1, 'name': name} + connection_info = vol_driver.initialize_connection(vol, self.connr) + uuid = '875a8070-d0b9-4949-8b31-104d125c9a64' + user = 'foo' + secret_type = 'ceph' + connection_info['data']['auth_enabled'] = False + connection_info['data']['auth_username'] = user + connection_info['data']['secret_type'] = secret_type + connection_info['data']['secret_uuid'] = uuid + + mount_device = "vde" + conf = libvirt_driver.connect_volume(connection_info, mount_device) + tree = conf.format_dom() + self.assertEqual(tree.get('type'), 'network') + self.assertEqual(tree.find('./source').get('protocol'), 'rbd') + rbd_name = '%s/%s' % (FLAGS.rbd_pool, name) + self.assertEqual(tree.find('./source').get('name'), rbd_name) + self.assertEqual(tree.find('./auth'), None) libvirt_driver.disconnect_volume(connection_info, mount_device) connection_info = vol_driver.terminate_connection(vol, self.connr) diff --git a/nova/tests/test_libvirt_config.py b/nova/tests/test_libvirt_config.py index b910849a5fdc..df435690f24b 100644 --- a/nova/tests/test_libvirt_config.py +++ b/nova/tests/test_libvirt_config.py @@ -105,6 +105,31 @@ class LibvirtConfigGuestDiskTest(LibvirtConfigBaseTest): """) + def test_config_network_auth(self): + obj = config.LibvirtConfigGuestDisk() + obj.source_type = "network" + obj.source_protocol = "rbd" + obj.source_host = "pool/image" + obj.driver_name = "qemu" + obj.driver_format = "raw" + obj.target_dev = "/dev/vda" + obj.target_bus = "virtio" + obj.auth_username = "foo" + obj.auth_secret_type = "ceph" + obj.auth_secret_uuid = "b38a3f43-4be2-4046-897f-b67c2f5e0147" + + xml = obj.to_xml() + self.assertXmlEqual(xml, """ + + + + + + + + """) + class LibvirtConfigGuestFilesysTest(LibvirtConfigBaseTest): diff --git a/nova/virt/libvirt/config.py b/nova/virt/libvirt/config.py index 63499eaf8a60..2ccfd35fb97c 100644 --- a/nova/virt/libvirt/config.py +++ b/nova/virt/libvirt/config.py @@ -86,6 +86,9 @@ class LibvirtConfigGuestDisk(LibvirtConfigGuestDevice): self.target_dev = None self.target_path = None self.target_bus = None + self.auth_username = None + self.auth_secret_type = None + self.auth_secret_uuid = None def format_dom(self): dev = super(LibvirtConfigGuestDisk, self).format_dom() @@ -114,6 +117,13 @@ class LibvirtConfigGuestDisk(LibvirtConfigGuestDevice): dev.append(etree.Element("source", protocol=self.source_protocol, name=self.source_host)) + if self.auth_secret_type is not None: + auth = etree.Element("auth") + auth.set("username", self.auth_username) + auth.append(etree.Element("secret", type=self.auth_secret_type, + uuid=self.auth_secret_uuid)) + dev.append(auth) + if self.source_type == "mount": dev.append(etree.Element("target", dir=self.target_path)) else: diff --git a/nova/virt/libvirt/volume.py b/nova/virt/libvirt/volume.py index 38f8c2dd09d2..23cf3390ea6c 100644 --- a/nova/virt/libvirt/volume.py +++ b/nova/virt/libvirt/volume.py @@ -86,6 +86,11 @@ class LibvirtNetVolumeDriver(LibvirtVolumeDriver): conf.source_host = connection_info['data']['name'] conf.target_dev = mount_device conf.target_bus = "virtio" + netdisk_properties = connection_info['data'] + if netdisk_properties.get('auth_enabled'): + conf.auth_username = netdisk_properties['auth_username'] + conf.auth_secret_type = netdisk_properties['secret_type'] + conf.auth_secret_uuid = netdisk_properties['secret_uuid'] return conf diff --git a/nova/volume/driver.py b/nova/volume/driver.py index ffdd1f520618..8b316befca53 100644 --- a/nova/volume/driver.py +++ b/nova/volume/driver.py @@ -56,7 +56,14 @@ volume_opts = [ help='The port that the iSCSI daemon is listening on'), cfg.StrOpt('rbd_pool', default='rbd', - help='the rbd pool in which volumes are stored'), + help='the RADOS pool in which rbd volumes are stored'), + cfg.StrOpt('rbd_user', + default=None, + help='the RADOS client name for accessing rbd volumes'), + cfg.StrOpt('rbd_secret_uuid', + default=None, + help='the libvirt uuid of the secret for the rbd_user' + 'volumes'), ] FLAGS = flags.FLAGS @@ -546,7 +553,11 @@ class RBDDriver(VolumeDriver): return { 'driver_volume_type': 'rbd', 'data': { - 'name': '%s/%s' % (FLAGS.rbd_pool, volume['name']) + 'name': '%s/%s' % (FLAGS.rbd_pool, volume['name']), + 'auth_enabled': FLAGS.rbd_secret_uuid is not None, + 'auth_username': FLAGS.rbd_user, + 'secret_type': 'ceph', + 'secret_uuid': FLAGS.rbd_secret_uuid, } }