Merge "Fix URL parsing to enable redfish_address matching"

This commit is contained in:
Zuul 2020-08-17 15:52:39 +00:00 committed by Gerrit Code Review
commit 2c38173fbf
4 changed files with 55 additions and 1 deletions

View File

@ -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:

View File

@ -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',

View File

@ -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):

View File

@ -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.