diff --git a/ironic_inspector/common/ironic.py b/ironic_inspector/common/ironic.py index 6e44c35bc..7d8f4f922 100644 --- a/ironic_inspector/common/ironic.py +++ b/ironic_inspector/common/ironic.py @@ -12,6 +12,7 @@ # limitations under the License. import socket +import urllib import netaddr import openstack @@ -101,6 +102,9 @@ def get_ipmi_address(node): ipv4 = None ipv6 = None + if '//' in value: + url = urllib.parse.urlparse(value) + value = url.hostname try: addrinfo = socket.getaddrinfo(value, None, 0, 0, socket.SOL_TCP) for family, socket_type, proto, canon_name, sockaddr in addrinfo: @@ -234,6 +238,10 @@ def lookup_node_by_bmc_addresses(addresses, introspection_data=None, # FIXME(aarefiev): it's not effective to fetch all nodes, and may # impact on performance on big clusters + # TODO(TheJulia): We should likely first loop through nodes being + # inspected, i.e. inspect wait, and then fallback + # to the rest of the physical nodes so we limit + # overall-impact of the operation. nodes = ironic.nodes(fields=('id', 'driver_info'), limit=None) found = set() for node in nodes: diff --git a/ironic_inspector/conf/default.py b/ironic_inspector/conf/default.py index 921ac191d..91ac45ae8 100644 --- a/ironic_inspector/conf/default.py +++ b/ironic_inspector/conf/default.py @@ -79,7 +79,8 @@ _OPTS = [ 'applies when boot is managed by ironic-inspector (i.e. ' 'manage_boot==True).')), cfg.ListOpt('ipmi_address_fields', - default=['ilo_address', 'drac_host', 'drac_address'], + default=['redfish_address', 'ilo_address', 'drac_host', + 'drac_address'], help=_('Ironic driver_info fields that are equivalent ' 'to ipmi_address.')), cfg.StrOpt('rootwrap_config', diff --git a/ironic_inspector/test/unit/test_common_ironic.py b/ironic_inspector/test/unit/test_common_ironic.py index c3eaa8cab..d8c30dcd5 100644 --- a/ironic_inspector/test/unit/test_common_ironic.py +++ b/ironic_inspector/test/unit/test_common_ironic.py @@ -98,6 +98,43 @@ class TestGetIpmiAddress(base.BaseTest): self.assertEqual((None, None, None), ir_utils.get_ipmi_address(node)) + @mock.patch.object(socket, 'getaddrinfo', autospec=True) + def test_redfish_bmc_address(self, mock_socket): + self.cfg.config(ipmi_address_fields=['redfish_address']) + url = 'http://{}/path'.format(self.ipmi_address) + node = mock.Mock(spec=['driver_info', 'uuid'], + driver_info={'redfish_address': url}) + mock_socket.return_value = [ + (socket.AF_INET, None, None, None, (self.ipmi_ipv4,)), + (socket.AF_INET6, None, None, None, (self.ipmi_ipv6,))] + self.assertEqual((self.ipmi_address, self.ipmi_ipv4, self.ipmi_ipv6), + ir_utils.get_ipmi_address(node)) + mock_socket.assert_called_once_with(self.ipmi_address, None, 0, 0, 6) + + @mock.patch.object(socket, 'getaddrinfo', autospec=True) + def test_redfish_bmc_address_ipv4(self, mock_socket): + self.cfg.config(ipmi_address_fields=['redfish_address']) + url = 'http://{}:8080/path'.format(self.ipmi_ipv4) + node = mock.Mock(spec=['driver_info', 'uuid'], + driver_info={'redfish_address': url}) + mock_socket.return_value = [ + (socket.AF_INET, None, None, None, (self.ipmi_ipv4,))] + self.assertEqual((self.ipmi_ipv4, self.ipmi_ipv4, None), + ir_utils.get_ipmi_address(node)) + mock_socket.assert_called_once_with(self.ipmi_ipv4, None, 0, 0, 6) + + @mock.patch.object(socket, 'getaddrinfo', autospec=True) + def test_redfish_bmc_address_ipv6(self, mock_socket): + self.cfg.config(ipmi_address_fields=['redfish_address']) + url = 'https://[{}]::443/path'.format(self.ipmi_ipv6) + node = mock.Mock(spec=['driver_info', 'uuid'], + driver_info={'redfish_address': url}) + mock_socket.return_value = [ + (socket.AF_INET6, None, None, None, (self.ipmi_ipv6,))] + self.assertEqual((self.ipmi_ipv6, None, self.ipmi_ipv6), + ir_utils.get_ipmi_address(node)) + mock_socket.assert_called_once_with(self.ipmi_ipv6, None, 0, 0, 6) + class TestCapabilities(unittest.TestCase): diff --git a/releasenotes/notes/support_redfish_address-94eae2c0d2879f53.yaml b/releasenotes/notes/support_redfish_address-94eae2c0d2879f53.yaml new file mode 100644 index 000000000..3fa0a2f17 --- /dev/null +++ b/releasenotes/notes/support_redfish_address-94eae2c0d2879f53.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + Fixes the node identification logic to enable a user to list + the ``redfish_address`` label for ``driver_info`` field values for + identification of a machine using the ``[DEFAULT]ipmi_address_fields`` + configuration option. Previously the host would just not be matched as + the full URL would be evaluated instead of what the URL may resolve to.