Fix URL parsing to enable redfish_address matching
Fixes the ironic utilities logic to parse URLs in driver_info properly. Also adds ``redfish_address`` to the default list of fields to evaluate for host matching. Previously an operator could add the field to the list, but the matching logic would not match the URL as it did not know to decompose the url and identify the hostname portion of the url. Resolves: rhbz#1670336 Story: 2008010 Task: 40660 Change-Id: Ice86e9ab3efb98b649141bdf7e1e2febdc9203a8
This commit is contained in:
parent
e5841dfd2b
commit
bbc5cd7da5
@ -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:
|
||||
|
@ -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',
|
||||
|
@ -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):
|
||||
|
||||
|
@ -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.
|
Loading…
Reference in New Issue
Block a user