diff options
| author | Josh Durgin <joshd@hq.newdream.net> | 2012-04-02 16:41:07 -0700 |
|---|---|---|
| committer | Josh Durgin <joshd@hq.newdream.net> | 2012-04-02 16:59:51 -0700 |
| commit | 01f24caba86c987b0109f743979a4e99e8afed11 (patch) | |
| tree | bdf33b12d34fcf976afc03c74a26e2f41446b1da | |
| parent | 276716e790b4f240347ae81357f58beeb4faf7a7 (diff) | |
| download | nova-01f24caba86c987b0109f743979a4e99e8afed11.tar.gz nova-01f24caba86c987b0109f743979a4e99e8afed11.tar.xz nova-01f24caba86c987b0109f743979a4e99e8afed11.zip | |
Allow unprivileged RADOS users to access rbd volumes.
This makes it possible to access rbd volumes with RADOS users with
restricted privileges. Previously, the admin user was always used.
This requires libvirt 0.9.8 or higher.
Change-Id: Ia4665c2a93a58a1c1290f467a3d9cd6cd22d7bd5
| -rw-r--r-- | nova/tests/test_libvirt.py | 53 | ||||
| -rw-r--r-- | nova/tests/test_libvirt_config.py | 25 | ||||
| -rw-r--r-- | nova/virt/libvirt/config.py | 10 | ||||
| -rw-r--r-- | nova/virt/libvirt/volume.py | 5 | ||||
| -rw-r--r-- | nova/volume/driver.py | 15 |
5 files changed, 106 insertions, 2 deletions
diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py index 4eea7b0b3..ba8764421 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 b910849a5..df435690f 100644 --- a/nova/tests/test_libvirt_config.py +++ b/nova/tests/test_libvirt_config.py @@ -105,6 +105,31 @@ class LibvirtConfigGuestDiskTest(LibvirtConfigBaseTest): <target bus="ide" dev="/dev/hda"/> </disk>""") + 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, """ + <disk type="network" device="disk"> + <driver name="qemu" type="raw"/> + <source protocol="rbd" name="pool/image"/> + <auth username="foo"> + <secret type="ceph" + uuid="b38a3f43-4be2-4046-897f-b67c2f5e0147"/> + </auth> + <target bus="virtio" dev="/dev/vda"/> + </disk>""") + class LibvirtConfigGuestFilesysTest(LibvirtConfigBaseTest): diff --git a/nova/virt/libvirt/config.py b/nova/virt/libvirt/config.py index 63499eaf8..2ccfd35fb 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 38f8c2dd0..23cf3390e 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 ffdd1f520..8b316befc 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, } } |
