Merge "Inventoried MAC address for only ipv6 addresses"
This commit is contained in:
commit
06077cb88e
@ -2473,7 +2473,33 @@ class GenericHardwareManager(HardwareManager):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
if ip == "0.0.0.0":
|
if ip == "0.0.0.0":
|
||||||
# disabled, ignore
|
# Check if we have IPv6 address configured
|
||||||
|
out, e = il_utils.execute(
|
||||||
|
"ipmitool lan6 print {} | awk '/^IPv6"
|
||||||
|
" (Dynamic|Static) Address [0-9]+:/"
|
||||||
|
" {{in_section=1; next}} /^IPv6 / {{in_section=0}}"
|
||||||
|
" in_section && /Address:/ {{print $2}}'".
|
||||||
|
format(channel), shell=True)
|
||||||
|
if e.startswith("Invalid channel"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
valid_ipv6_found = False
|
||||||
|
try:
|
||||||
|
ipv6_list = out.strip().split("\n")
|
||||||
|
# Skip auto-configured link-local addresses
|
||||||
|
# and ignore "::/255", which indicates unconfigured
|
||||||
|
# addresses returned by ipmitool.
|
||||||
|
valid_ipv6_found = any(
|
||||||
|
not ipv6.startswith("::")
|
||||||
|
and not ipv6.startswith("fe80")
|
||||||
|
for ipv6 in ipv6_list
|
||||||
|
)
|
||||||
|
except ValueError:
|
||||||
|
LOG.warning('Invalid ipmitool output %(output)s',
|
||||||
|
{'output': out})
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not valid_ipv6_found:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if not re.match("^[0-9a-f]{2}(:[0-9a-f]{2}){5}$", mac, re.I):
|
if not re.match("^[0-9a-f]{2}(:[0-9a-f]{2}){5}$", mac, re.I):
|
||||||
|
@ -3185,16 +3185,125 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
|||||||
return '', 'Invalid channel 1\n'
|
return '', 'Invalid channel 1\n'
|
||||||
elif args[0].startswith("ipmitool lan print 2"):
|
elif args[0].startswith("ipmitool lan print 2"):
|
||||||
return '0.0.0.0\n00:00:00:00:23:42', ''
|
return '0.0.0.0\n00:00:00:00:23:42', ''
|
||||||
|
elif args[0].startswith("ipmitool lan6 print"):
|
||||||
|
return '::/255', ''
|
||||||
elif args[0].startswith("ipmitool lan print 3"):
|
elif args[0].startswith("ipmitool lan print 3"):
|
||||||
return 'meow', ''
|
return 'meow', ''
|
||||||
elif args[0].startswith("ipmitool lan print 4"):
|
elif args[0].startswith("ipmitool lan print 4"):
|
||||||
return '192.1.2.3\n01:02:03:04:05:06', ''
|
return '192.1.2.3\n01:02:03:04:05:06', ''
|
||||||
else:
|
else:
|
||||||
# this should never happen because the previous one was good
|
|
||||||
raise AssertionError
|
raise AssertionError
|
||||||
mocked_execute.side_effect = side_effect
|
mocked_execute.side_effect = side_effect
|
||||||
self.assertEqual('01:02:03:04:05:06', self.hardware.get_bmc_mac())
|
self.assertEqual('01:02:03:04:05:06', self.hardware.get_bmc_mac())
|
||||||
|
|
||||||
|
@mock.patch.object(hardware.GenericHardwareManager,
|
||||||
|
'any_ipmi_device_exists', autospec=True)
|
||||||
|
@mock.patch.object(il_utils, 'execute', autospec=True)
|
||||||
|
def test_get_bmc_mac_for_ipv6(self, mocked_execute,
|
||||||
|
mock_ipmi_device_exists):
|
||||||
|
mock_ipmi_device_exists.return_value = True
|
||||||
|
|
||||||
|
def side_effect(*args, **kwargs):
|
||||||
|
if args[0].startswith("ipmitool lan print"):
|
||||||
|
return '0.0.0.0\n01:02:03:04:05:06', ''
|
||||||
|
elif args[0].startswith("ipmitool lan6 print"):
|
||||||
|
return '2001:db8::/32', ''
|
||||||
|
else:
|
||||||
|
raise AssertionError
|
||||||
|
|
||||||
|
mocked_execute.side_effect = side_effect
|
||||||
|
self.assertEqual('01:02:03:04:05:06', self.hardware.get_bmc_mac())
|
||||||
|
|
||||||
|
@mock.patch.object(hardware.GenericHardwareManager,
|
||||||
|
'any_ipmi_device_exists', autospec=True)
|
||||||
|
@mock.patch.object(il_utils, 'execute', autospec=True)
|
||||||
|
def test_get_bmc_mac_with_invalid_ipv6(self, mocked_execute,
|
||||||
|
mock_ipmi_device_exists):
|
||||||
|
mock_ipmi_device_exists.return_value = True
|
||||||
|
|
||||||
|
def side_effect(*args, **kwargs):
|
||||||
|
if args[0].startswith("ipmitool lan print"):
|
||||||
|
return '0.0.0.0\n01:02:03:04:05:06', ''
|
||||||
|
elif args[0].startswith("ipmitool lan6 print"):
|
||||||
|
return '::/255', ''
|
||||||
|
else:
|
||||||
|
raise AssertionError
|
||||||
|
|
||||||
|
mocked_execute.side_effect = side_effect
|
||||||
|
self.assertRaises(errors.IncompatibleHardwareMethodError,
|
||||||
|
self.hardware.get_bmc_mac)
|
||||||
|
|
||||||
|
@mock.patch.object(hardware.GenericHardwareManager,
|
||||||
|
'any_ipmi_device_exists', autospec=True)
|
||||||
|
@mock.patch.object(il_utils, 'execute', autospec=True)
|
||||||
|
def test_get_bmc_mac_with_valid_ipv6_and_invalid_mac(
|
||||||
|
self, mocked_execute, mock_ipmi_device_exists):
|
||||||
|
mock_ipmi_device_exists.return_value = True
|
||||||
|
|
||||||
|
def side_effect(*args, **kwargs):
|
||||||
|
if args[0].startswith("ipmitool lan print"):
|
||||||
|
return '0.0.0.0\n00:00:00:00:00:00', ''
|
||||||
|
elif args[0].startswith("ipmitool lan6 print"):
|
||||||
|
return '2001:db8::/32', ''
|
||||||
|
else:
|
||||||
|
raise AssertionError
|
||||||
|
|
||||||
|
mocked_execute.side_effect = side_effect
|
||||||
|
self.assertRaises(errors.IncompatibleHardwareMethodError,
|
||||||
|
self.hardware.get_bmc_mac)
|
||||||
|
|
||||||
|
@mock.patch.object(hardware.GenericHardwareManager,
|
||||||
|
'any_ipmi_device_exists', autospec=True)
|
||||||
|
@mock.patch.object(il_utils, 'execute', autospec=True)
|
||||||
|
def test_get_bmc_mac_no_valid_ip_or_ipv6(self,
|
||||||
|
mocked_execute,
|
||||||
|
mock_ipmi_device_exists):
|
||||||
|
mock_ipmi_device_exists.return_value = True
|
||||||
|
|
||||||
|
def side_effect(*args, **kwargs):
|
||||||
|
if args[0].startswith("ipmitool lan print"):
|
||||||
|
return '0.0.0.0\n00:00:00:00:00:00', ''
|
||||||
|
elif args[0].startswith("ipmitool lan6 print"):
|
||||||
|
return '::/255', ''
|
||||||
|
else:
|
||||||
|
raise AssertionError
|
||||||
|
|
||||||
|
mocked_execute.side_effect = side_effect
|
||||||
|
self.assertRaises(errors.IncompatibleHardwareMethodError,
|
||||||
|
self.hardware.get_bmc_mac)
|
||||||
|
|
||||||
|
@mock.patch.object(hardware.GenericHardwareManager,
|
||||||
|
'any_ipmi_device_exists', autospec=True)
|
||||||
|
@mock.patch.object(il_utils, 'execute', autospec=True)
|
||||||
|
def test_get_bmc_mac_iterate_channels_ipv6(self,
|
||||||
|
mocked_execute,
|
||||||
|
mock_ipmi_device_exists):
|
||||||
|
mock_ipmi_device_exists.return_value = True
|
||||||
|
# For channel 4 we simulate configured IPv6 and MAC
|
||||||
|
|
||||||
|
def side_effect(*args, **kwargs):
|
||||||
|
if args[0].startswith("ipmitool lan print 1"):
|
||||||
|
return '', 'Invalid channel 1\n'
|
||||||
|
elif args[0].startswith("ipmitool lan print 2"):
|
||||||
|
return 'meow', ''
|
||||||
|
elif args[0].startswith("ipmitool lan6 print 1"):
|
||||||
|
return '', 'Invalid channel 1\n'
|
||||||
|
elif args[0].startswith("ipmitool lan6 print 2"):
|
||||||
|
return 'meow', ''
|
||||||
|
elif args[0].startswith("ipmitool lan print 3"):
|
||||||
|
return '0.0.0.0\n00:00:00:00:01:02', ''
|
||||||
|
elif args[0].startswith("ipmitool lan6 print 3"):
|
||||||
|
return 'fe80::/64', ''
|
||||||
|
elif args[0].startswith("ipmitool lan print 4"):
|
||||||
|
return '0.0.0.0\n01:02:03:04:05:06', ''
|
||||||
|
elif args[0].startswith("ipmitool lan6 print 4"):
|
||||||
|
return '2001:db8::/32', ''
|
||||||
|
else:
|
||||||
|
raise AssertionError
|
||||||
|
|
||||||
|
mocked_execute.side_effect = side_effect
|
||||||
|
self.assertEqual('01:02:03:04:05:06', self.hardware.get_bmc_mac())
|
||||||
|
|
||||||
@mock.patch.object(hardware.GenericHardwareManager,
|
@mock.patch.object(hardware.GenericHardwareManager,
|
||||||
'any_ipmi_device_exists', autospec=True)
|
'any_ipmi_device_exists', autospec=True)
|
||||||
@mock.patch.object(il_utils, 'execute', autospec=True)
|
@mock.patch.object(il_utils, 'execute', autospec=True)
|
||||||
|
5
releasenotes/notes/ipv6-bmc-mac-6133fb30c0d4cc5e.yaml
Normal file
5
releasenotes/notes/ipv6-bmc-mac-6133fb30c0d4cc5e.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds support for detecting MAC addresses for interfaces with
|
||||||
|
only a IPv6 address.
|
Loading…
Reference in New Issue
Block a user