From a2d308991e33276a5904d3cc4cd1b2d4f33ecf75 Mon Sep 17 00:00:00 2001 From: Artom Lifshitz Date: Mon, 16 Jul 2018 13:15:03 -0400 Subject: [PATCH] Convert get_hypervisor_ip to use hostnames Instead of using ID to lookup hypervisor IPs, use hostnames. IDs are different in undercloud and overcloud (a compute node's Ironic node UUID in the undercloud isn't the same as its hypervisor UUID in the overcloud). In addition, Nova uses both integer IDs (before 2.53) and UUIDs (2.53 and later) for hypervisors. Hostnames are common to both undercloud and overcloud, and don't change depending on the microversion. Change-Id: I34445e0f566dd48271740c357f74f632152776ed --- .../api/compute/test_pointer_device_type.py | 4 +- whitebox_tempest_plugin/common/utils.py | 44 ++++-------------- whitebox_tempest_plugin/config.py | 12 +++-- whitebox_tempest_plugin/tests/test_utils.py | 46 +++++++------------ 4 files changed, 32 insertions(+), 74 deletions(-) diff --git a/whitebox_tempest_plugin/api/compute/test_pointer_device_type.py b/whitebox_tempest_plugin/api/compute/test_pointer_device_type.py index c4610b69..b84c47a1 100644 --- a/whitebox_tempest_plugin/api/compute/test_pointer_device_type.py +++ b/whitebox_tempest_plugin/api/compute/test_pointer_device_type.py @@ -50,10 +50,8 @@ class PointerDeviceTypeFromImages(base.BaseTest): def _verify_pointer_device_type_from_images(self, server_id): # Retrieve the server's hypervizor hostname - server = self.servers_client.show_server(server_id)['server'] - hostname = server['OS-EXT-SRV-ATTR:host'] compute_node_address = whitebox_utils.get_hypervisor_ip( - self.hypervisor_client, hostname) + self.servers_client, server_id) self.assertIsNotNone(compute_node_address) # Retrieve input device from virsh dumpxml diff --git a/whitebox_tempest_plugin/common/utils.py b/whitebox_tempest_plugin/common/utils.py index dc6f9d12..90105b83 100644 --- a/whitebox_tempest_plugin/common/utils.py +++ b/whitebox_tempest_plugin/common/utils.py @@ -21,39 +21,11 @@ CONF = config.CONF LOG = logging.getLogger(__name__) -def _get_hv_ip_from_conf(id): - conf_hvs = CONF.whitebox.hypervisors - if conf_hvs: - return conf_hvs.get(id) - - -def get_hypervisor_ip(client, hostname): - """Get the IP for a comute node's hypervisor. - - Finds the IP address of a compute node based on its hostname. This is - necessary in case a compute node isn't accessible by its IP address as it - appears in the nova API. Such a situation arises in infrared deployments of - OSP12, for example. - - :param client: The hypervisors client to use. - :param hostname: The compute node's hostname, from the instance's - ``OS-EXT-SRV-ATTR:host`` attribute. - :return: The IP address of the compute node - either as configuired in the - hypervisors section of our config file, or as returned by the nova API - as fallback. - """ - hvs = client.list_hypervisors(detail=True)['hypervisors'] - compute_node_address = None - for hv in hvs: - if hv['service']['host'] == hostname: - hv_ip = _get_hv_ip_from_conf(str(hv['id'])) - if hv_ip: - compute_node_address = hv_ip - LOG.info('Using %s for hypervisor %s from config file', - hv_ip, hv['id']) - else: - compute_node_address = hv['host_ip'] - LOG.info('Using %s as fallback since hypervisor %s not in ' - 'config file', compute_node_address, hv['id']) - - return compute_node_address +def get_hypervisor_ip(admin_servers_client, server_id): + server = admin_servers_client.show_server(server_id) + host = server['server']['OS-EXT-SRV-ATTR:host'] + try: + return CONF.whitebox.hypervisors[host] + except KeyError: + LOG.error('Unable to find IP in conf. Server: %s, host: %s.', + (server_id, host)) diff --git a/whitebox_tempest_plugin/config.py b/whitebox_tempest_plugin/config.py index 763c46e0..c7bd3d5d 100644 --- a/whitebox_tempest_plugin/config.py +++ b/whitebox_tempest_plugin/config.py @@ -39,9 +39,11 @@ opts = [ help='Deployment is containerized.'), cfg.DictOpt( 'hypervisors', - help="Dictionary of hypervisor IP addresses, in the " - "id => IP format. Should be used when the IP returned " - "by 'nova hypervisor-show' isn't reachable from the " - "node running tempest. Starting with microversion " - "2.53, the id is a UUID."), + help="Dictionary of hypervisor IP addresses. The keys are the " + "hostnames as they appear in the OS-EXT-SRV-ATTR:host field of " + "Nova's show server details API. The values are the ctlplane IP " + "addresses. For example:" + "" + " hypervisors = compute-0.localdomain:172.16.42.11," + " controller-0.localdomain:172.16.42.10"), ] diff --git a/whitebox_tempest_plugin/tests/test_utils.py b/whitebox_tempest_plugin/tests/test_utils.py index 952c3eff..7e801eae 100644 --- a/whitebox_tempest_plugin/tests/test_utils.py +++ b/whitebox_tempest_plugin/tests/test_utils.py @@ -18,40 +18,26 @@ from whitebox_tempest_plugin.common import utils from whitebox_tempest_plugin.tests import base +def fake_show_server(server_id): + if server_id == 'fake-id': + return {'server': {'OS-EXT-SRV-ATTR:host': 'fake-host'}} + else: + return {'server': {'OS-EXT-SRV-ATTR:host': 'missing-host'}} + + class UtilsTestCase(base.WhiteboxPluginTestCase): def setUp(self): super(UtilsTestCase, self).setUp() self.client = mock.Mock() - fake_hvs = { - 'hypervisors': [ - {'service': {'host': 'host1'}, - 'host_ip': '192.168.0.1', - 'id': 1}, - {'service': {'host': 'host2'}, - 'host_ip': '192.168.0.2', - 'id': 2}, - {'service': {'host': 'host3'}, - 'host_ip': '192.168.0.3', - 'id': 3} - ] - } - self.client.list_hypervisors = mock.Mock(return_value=fake_hvs) + self.client.show_server = fake_show_server + self.flags(hypervisors={'fake-host': 'fake-ip'}, group='whitebox') - @mock.patch.object(utils.LOG, 'info') - def test_get_hypervisor_ip_hv_in_config(self, mock_log): - self.flags(hypervisors={'1': '10.0.0.1'}, group='whitebox') - self.assertEqual('10.0.0.1', - utils.get_hypervisor_ip(self.client, 'host1')) - self.assertIn('from config file', mock_log.call_args_list[0][0][0]) + def test_get_hypervisor_ip(self): + self.assertEqual('fake-ip', + utils.get_hypervisor_ip(self.client, 'fake-id')) - @mock.patch.object(utils.LOG, 'info') - def test_get_hypervisor_ip_hv_not_in_config(self, mock_log): - self.flags(hypervisors={'1': '10.0.0.1'}, group='whitebox') - self.assertEqual('192.168.0.2', - utils.get_hypervisor_ip(self.client, 'host2')) - self.assertIn('not in config file', mock_log.call_args_list[0][0][0]) - - def test_get_hypervisor_ip_no_hvs_in_config(self): - self.assertEqual('192.168.0.3', - utils.get_hypervisor_ip(self.client, 'host3')) + @mock.patch.object(utils.LOG, 'error') + def test_get_hypervisor_ip_keyerror(self, mock_log): + self.assertIsNone(utils.get_hypervisor_ip(self.client, 'missing-id')) + self.assertIn('Unable', mock_log.call_args_list[0][0][0])