Allow hypervisor IPs in configuration file

Previously, hypervisor IPs would be obtained from the nova API by essentially
doing a 'nova hypervisor-show'. The IP address thus obtained isn't always
reachable from the node running tempest. For example, in a tripleo-deployed
OSP12, the control plane IP should be used instead. This patch allows
hypervisor IPs to be defined in the configuration file.

Change-Id: I403fa5fd000fe29f6449f77c12a1c6b63efb713f
This commit is contained in:
Artom Lifshitz 2017-11-07 15:16:26 -05:00 committed by Gerrit Code Review
parent b94712204f
commit fe19cf8fa1
7 changed files with 127 additions and 25 deletions

View File

@ -21,6 +21,7 @@ commands =
flake8 {posargs}
[flake8]
ignore = H405
enable-extensions = H106,H203,H904
show-source = True
exclude = .git,.venv,.tox,dist,doc,*egg

View File

@ -0,0 +1,57 @@
# Copyright 2017 Red Hat
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_log import log as logging
from tempest import config
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):
"""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

View File

@ -37,4 +37,11 @@ opts = [
'containers',
default=False,
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."),
]

View File

@ -13,7 +13,15 @@
# under the License.
from oslotest import base
from tempest import config
CONF = config.CONF
class WhiteboxPluginTestCase(base.BaseTestCase):
pass
def flags(self, **kw):
"""Override flag variables for a test."""
group = kw.pop('group', None)
for k, v in kw.items():
CONF.set_override(k, v, group)

View File

@ -1,24 +0,0 @@
# Copyright 2018 Red Hat
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from whitebox_tempest_plugin.tests.unit import base
class PlaceholderTestCase(base.WhiteboxPluginTestCase):
# TODO(artom) Remove this class when we add actual unit tests. This class
# is only necessary to to avoid stestr complaining about not finding any
# tests.
def test_placeholder(self):
pass

View File

@ -0,0 +1,53 @@
# Copyright 2018 Red Hat
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import mock
from whitebox_tempest_plugin.common import utils
from whitebox_tempest_plugin.tests.unit import base
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)
def test_get_hypervisor_ip_hv_in_config(self):
self.flags(hypervisors={'1': '10.0.0.1'}, group='whitebox')
self.assertEqual('10.0.0.1',
utils.get_hypervisor_ip(self.client, 'host1'))
def test_get_hypervisor_ip_hv_not_in_config(self):
self.flags(hypervisors={'1': '10.0.0.1'}, group='whitebox')
self.assertEqual('192.168.0.2',
utils.get_hypervisor_ip(self.client, 'host2'))
def test_get_hypervisor_ip_no_hvs_in_config(self):
self.assertEqual('192.168.0.3',
utils.get_hypervisor_ip(self.client, 'host3'))