Do not use loopback BMC addresses for lookup

With virtualbmc it's possible to have loopback as IPMI address for several
nodes, which breaks introspection. This change make ironic-inspector
ignore loopback addresses.

Change-Id: Idf141c027e9aa08aaed014398fe8b3506a287afa
Partial-Bug: #1651719
This commit is contained in:
Dmitry Tantsur 2017-01-12 16:36:19 +01:00
parent e8dcb40921
commit 51015b17c8
4 changed files with 59 additions and 11 deletions

View File

@ -15,13 +15,15 @@ import socket
from ironicclient import client
from ironicclient import exceptions as ironic_exc
import netaddr
from oslo_config import cfg
from ironic_inspector.common.i18n import _
from ironic_inspector.common.i18n import _, _LW
from ironic_inspector.common import keystone
from ironic_inspector import utils
CONF = cfg.CONF
LOG = utils.getProcessingLogger(__name__)
# See http://specs.openstack.org/openstack/ironic-specs/specs/kilo/new-ironic-state-machine.html # noqa
VALID_STATES = {'enroll', 'manageable', 'inspecting', 'inspectfail'}
@ -143,10 +145,11 @@ def get_ipmi_address(node):
return
for name in ipmi_fields:
value = node.driver_info.get(name)
if value:
if not value:
continue
try:
ip = socket.gethostbyname(value)
return ip
except socket.gaierror:
msg = _('Failed to resolve the hostname (%(value)s)'
' for node %(uuid)s')
@ -154,6 +157,13 @@ def get_ipmi_address(node):
'uuid': node.uuid},
node_info=node)
if netaddr.IPAddress(ip).is_loopback():
LOG.warning(_LW('Ignoring loopback BMC address %s'), ip,
node_info=node)
ip = None
return ip
def get_client(token=None,
api_version=DEFAULT_IRONIC_API_VERSION): # pragma: no cover

View File

@ -109,6 +109,12 @@ class TestGetIpmiAddress(base.BaseTest):
'ipmi_bridging': 'single'})
self.assertIsNone(ir_utils.get_ipmi_address(node))
def test_loopback_address(self):
node = mock.Mock(spec=['driver_info', 'uuid'],
driver_info={'ipmi_address': '127.0.0.2'})
ip = ir_utils.get_ipmi_address(node)
self.assertIsNone(ip)
class TestCapabilities(unittest.TestCase):

View File

@ -79,6 +79,33 @@ class TestIntrospect(BaseTest):
self.node_info.acquire_lock.assert_called_once_with()
self.node_info.release_lock.assert_called_once_with()
def test_loopback_bmc_address(self, client_mock, start_mock, filters_mock):
self.node.driver_info['ipmi_address'] = '127.0.0.1'
cli = self._prepare(client_mock)
start_mock.return_value = self.node_info
introspect.introspect(self.node.uuid)
cli.node.get.assert_called_once_with(self.uuid)
cli.node.validate.assert_called_once_with(self.uuid)
start_mock.assert_called_once_with(self.uuid,
bmc_address=None,
ironic=cli)
self.node_info.ports.assert_called_once_with()
self.node_info.add_attribute.assert_called_once_with('mac',
self.macs)
filters_mock.assert_called_with(cli)
cli.node.set_boot_device.assert_called_once_with(self.uuid,
'pxe',
persistent=False)
cli.node.set_power_state.assert_called_once_with(self.uuid,
'reboot')
self.node_info.set_option.assert_called_once_with(
'new_ipmi_credentials', None)
self.node_info.acquire_lock.assert_called_once_with()
self.node_info.release_lock.assert_called_once_with()
def test_ok_ilo_and_drac(self, client_mock, start_mock, filters_mock):
cli = self._prepare(client_mock)
start_mock.return_value = self.node_info

View File

@ -0,0 +1,5 @@
---
fixes:
- |
Loopback BMC addresses (useful e.g. with virtualbmc) are no longer used
for lookup.