diff --git a/ironic_inspector/common/ironic.py b/ironic_inspector/common/ironic.py index 5397aa038..6693b460d 100644 --- a/ironic_inspector/common/ironic.py +++ b/ironic_inspector/common/ironic.py @@ -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,16 +145,24 @@ def get_ipmi_address(node): return for name in ipmi_fields: value = node.driver_info.get(name) - if value: - try: - ip = socket.gethostbyname(value) - return ip - except socket.gaierror: - msg = _('Failed to resolve the hostname (%(value)s)' - ' for node %(uuid)s') - raise utils.Error(msg % {'value': value, - 'uuid': node.uuid}, - node_info=node) + if not value: + continue + + try: + ip = socket.gethostbyname(value) + except socket.gaierror: + msg = _('Failed to resolve the hostname (%(value)s)' + ' for node %(uuid)s') + raise utils.Error(msg % {'value': value, + '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, diff --git a/ironic_inspector/test/unit/test_common_ironic.py b/ironic_inspector/test/unit/test_common_ironic.py index b7a332d0c..12c69e071 100644 --- a/ironic_inspector/test/unit/test_common_ironic.py +++ b/ironic_inspector/test/unit/test_common_ironic.py @@ -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): diff --git a/ironic_inspector/test/unit/test_introspect.py b/ironic_inspector/test/unit/test_introspect.py index ec79e4837..4e988cc25 100644 --- a/ironic_inspector/test/unit/test_introspect.py +++ b/ironic_inspector/test/unit/test_introspect.py @@ -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 diff --git a/releasenotes/notes/loopback-bmc-e60d64fe74bdf142.yaml b/releasenotes/notes/loopback-bmc-e60d64fe74bdf142.yaml new file mode 100644 index 000000000..472756cfe --- /dev/null +++ b/releasenotes/notes/loopback-bmc-e60d64fe74bdf142.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Loopback BMC addresses (useful e.g. with virtualbmc) are no longer used + for lookup.