From f2d27f6a8afb62815fb6a885bd4f8ae4ed287fd3 Mon Sep 17 00:00:00 2001 From: Matt Riedemann Date: Thu, 8 Jun 2017 09:35:42 -0400 Subject: [PATCH] libvirt: handle missing rbd_secret_uuid from old connection info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change Idcbada705c1d38ac5fd7c600141c2de7020eae25 in Ocata started preferring Cinder connection info for getting RBD auth values since Nova needs to be using the same settings as Cinder for volume auth. However, that introduced a problem for guest connections made before that change, where the secret_uuid might not have been configured on the Cinder side and that's what is stored in the block_device_mappings.connection_info column and is what we're checking in _set_auth_config_rbd. Before Ocata this wasn't a problem because we'd use the Nova configuration values for the rbd_secret_uuid if set. But since Ocata it is a problem since we don't consult nova.conf if auth was enabled, but not completely configured, on the Cinder side. So this adds a fallback check to set the secret_uuid from nova.conf if it wasn't set in the connection_info via Cinder originally. A note is also added to caution about removing any fallback mechanism on the nova side - something we'd need to consider before we could likely drop this code. Co-Authored-By: Tadas Ustinavičius Change-Id: I6fc7108817fcd9df4a342c9dabbf14ab7911d06a Closes-Bug: #1687581 --- .../unit/virt/libvirt/volume/test_net.py | 33 +++++++++++++++++++ nova/virt/libvirt/volume/net.py | 14 +++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/nova/tests/unit/virt/libvirt/volume/test_net.py b/nova/tests/unit/virt/libvirt/volume/test_net.py index d422e8fffb80..6f104314b300 100644 --- a/nova/tests/unit/virt/libvirt/volume/test_net.py +++ b/nova/tests/unit/virt/libvirt/volume/test_net.py @@ -144,6 +144,39 @@ class LibvirtNetVolumeDriverTestCase( libvirt_driver.disconnect_volume(connection_info, "vde", mock.sentinel.instance) + def test_libvirt_rbd_driver_auth_enabled_flags_secret_uuid_fallback(self): + """The values from the cinder connection_info take precedence over + nova.conf values, unless it's old connection data where the + secret_uuid wasn't set on the cinder side for the original connection + which is now persisted in the + nova.block_device_mappings.connection_info column and used here. In + this case we fallback to use the local config for secret_uuid. + """ + libvirt_driver = net.LibvirtNetVolumeDriver(self.fake_host) + connection_info = self.rbd_connection(self.vol) + secret_type = 'ceph' + connection_info['data']['auth_enabled'] = True + connection_info['data']['auth_username'] = self.user + connection_info['data']['secret_type'] = secret_type + # Fake out cinder not setting the secret_uuid in the old connection. + connection_info['data']['secret_uuid'] = None + + flags_uuid = '37152720-1785-11e2-a740-af0c1d8b8e4b' + flags_user = 'bar' + self.flags(rbd_user=flags_user, + rbd_secret_uuid=flags_uuid, + group='libvirt') + + conf = libvirt_driver.get_config(connection_info, self.disk_info) + tree = conf.format_dom() + self._assertNetworkAndProtocolEquals(tree) + self.assertEqual(self.user, tree.find('./auth').get('username')) + self.assertEqual(secret_type, tree.find('./auth/secret').get('type')) + # Assert that the secret_uuid comes from CONF.libvirt.rbd_secret_uuid. + self.assertEqual(flags_uuid, tree.find('./auth/secret').get('uuid')) + libvirt_driver.disconnect_volume(connection_info, "vde", + mock.sentinel.instance) + def test_libvirt_rbd_driver_auth_disabled(self): libvirt_driver = net.LibvirtNetVolumeDriver(self.fake_host) connection_info = self.rbd_connection(self.vol) diff --git a/nova/virt/libvirt/volume/net.py b/nova/virt/libvirt/volume/net.py index e01e6ceb80a6..94120ddc91a1 100644 --- a/nova/virt/libvirt/volume/net.py +++ b/nova/virt/libvirt/volume/net.py @@ -62,13 +62,25 @@ class LibvirtNetVolumeDriver(libvirt_volume.LibvirtBaseVolumeDriver): auth_enabled = netdisk_properties.get('auth_enabled') if auth_enabled: conf.auth_username = netdisk_properties['auth_username'] - conf.auth_secret_uuid = netdisk_properties['secret_uuid'] + # We started preferring Cinder config for rbd auth values starting + # in Ocata, but if we have a guest connection from before that when + # secret_uuid wasn't configured in Cinder, we need to fallback to + # get it from local nova.conf. + if netdisk_properties['secret_uuid'] is not None: + conf.auth_secret_uuid = netdisk_properties['secret_uuid'] + else: + LOG.debug('Falling back to Nova configuration for RBD auth ' + 'secret_uuid value.') + conf.auth_secret_uuid = CONF.libvirt.rbd_secret_uuid # secret_type is always hard-coded to 'ceph' in cinder conf.auth_secret_type = netdisk_properties['secret_type'] elif CONF.libvirt.rbd_secret_uuid: # Anyone relying on falling back to nova config is probably having # this work accidentally and we'll remove that support in the # 16.0.0 Pike release. + # NOTE(mriedem): We'll have to be extra careful about this in case + # the reason we got here is due to an old volume connection created + # before we started preferring the Cinder settings in Ocata. LOG.warning(_LW('Falling back to Nova configuration values for ' 'RBD authentication. Cinder should be configured ' 'for auth with Ceph volumes. This fallback will '