Collect IPv6 address during introspection
This patch adds support to retrieve IPv6 address. A new field ``ipv6_address`` is added to NetworkInterface and store the assigned IPv6 address (if any). Co-Authored-By: Kaifeng Wang <kaifeng.w@gmail.com> Change-Id: Ia527a5aa48e3daf66d2be190e43935b38b3bd6f9 Closes-Bug: #1744064 Story: #1744064 Task: #11604
This commit is contained in:
parent
9008a5cd30
commit
561be77303
@ -260,15 +260,17 @@ class BlockDevice(encoding.SerializableComparable):
|
||||
|
||||
class NetworkInterface(encoding.SerializableComparable):
|
||||
serializable_fields = ('name', 'mac_address', 'ipv4_address',
|
||||
'has_carrier', 'lldp', 'vendor', 'product',
|
||||
'client_id', 'biosdevname')
|
||||
'ipv6_address', 'has_carrier', 'lldp',
|
||||
'vendor', 'product', 'client_id',
|
||||
'biosdevname')
|
||||
|
||||
def __init__(self, name, mac_addr, ipv4_address=None, has_carrier=True,
|
||||
lldp=None, vendor=None, product=None, client_id=None,
|
||||
biosdevname=None):
|
||||
def __init__(self, name, mac_addr, ipv4_address=None, ipv6_address=None,
|
||||
has_carrier=True, lldp=None, vendor=None, product=None,
|
||||
client_id=None, biosdevname=None):
|
||||
self.name = name
|
||||
self.mac_address = mac_addr
|
||||
self.ipv4_address = ipv4_address
|
||||
self.ipv6_address = ipv6_address
|
||||
self.has_carrier = has_carrier
|
||||
self.lldp = lldp
|
||||
self.vendor = vendor
|
||||
@ -582,6 +584,7 @@ class GenericHardwareManager(HardwareManager):
|
||||
return NetworkInterface(
|
||||
interface_name, mac_addr,
|
||||
ipv4_address=self.get_ipv4_addr(interface_name),
|
||||
ipv6_address=self.get_ipv6_addr(interface_name),
|
||||
has_carrier=netutils.interface_has_carrier(interface_name),
|
||||
vendor=_get_device_info(interface_name, 'net', 'vendor'),
|
||||
product=_get_device_info(interface_name, 'net', 'device'),
|
||||
@ -590,6 +593,14 @@ class GenericHardwareManager(HardwareManager):
|
||||
def get_ipv4_addr(self, interface_id):
|
||||
return netutils.get_ipv4_addr(interface_id)
|
||||
|
||||
def get_ipv6_addr(self, interface_id):
|
||||
"""Get the default IPv6 address assigned to the interface.
|
||||
|
||||
With different networking environment, the address could be a
|
||||
link-local address, ULA or something else.
|
||||
"""
|
||||
return netutils.get_ipv6_addr(interface_id)
|
||||
|
||||
def get_bios_given_nic_name(self, interface_name):
|
||||
"""Collect the BIOS given NICs name.
|
||||
|
||||
|
@ -203,15 +203,24 @@ def _get_lldp_info(interfaces):
|
||||
return lldp_info
|
||||
|
||||
|
||||
def get_ipv4_addr(interface_id):
|
||||
def get_default_ip_addr(type, interface_id):
|
||||
"""Retrieve default IPv4 or IPv6 address."""
|
||||
try:
|
||||
addrs = netifaces.ifaddresses(interface_id)
|
||||
return addrs[netifaces.AF_INET][0]['addr']
|
||||
return addrs[type][0]['addr']
|
||||
except (ValueError, IndexError, KeyError):
|
||||
# No default IPv4 address found
|
||||
# No default IP address found
|
||||
return None
|
||||
|
||||
|
||||
def get_ipv4_addr(interface_id):
|
||||
return get_default_ip_addr(netifaces.AF_INET, interface_id)
|
||||
|
||||
|
||||
def get_ipv6_addr(interface_id):
|
||||
return get_default_ip_addr(netifaces.AF_INET6, interface_id)
|
||||
|
||||
|
||||
def get_mac_addr(interface_id):
|
||||
try:
|
||||
addrs = netifaces.ifaddresses(interface_id)
|
||||
|
@ -513,7 +513,8 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
||||
read_mock = mocked_open.return_value.read
|
||||
read_mock.side_effect = ['1']
|
||||
mocked_ifaddresses.return_value = {
|
||||
netifaces.AF_INET: [{'addr': '192.168.1.2'}]
|
||||
netifaces.AF_INET: [{'addr': '192.168.1.2'}],
|
||||
netifaces.AF_INET6: [{'addr': 'fd00::101'}]
|
||||
}
|
||||
mocked_execute.return_value = ('em0\n', '')
|
||||
mock_get_mac.mock_has_carrier = True
|
||||
@ -523,6 +524,7 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
||||
self.assertEqual('eth0', interfaces[0].name)
|
||||
self.assertEqual('00:0c:29:8c:11:b1', interfaces[0].mac_address)
|
||||
self.assertEqual('192.168.1.2', interfaces[0].ipv4_address)
|
||||
self.assertEqual('fd00::101', interfaces[0].ipv6_address)
|
||||
self.assertIsNone(interfaces[0].lldp)
|
||||
self.assertTrue(interfaces[0].has_carrier)
|
||||
self.assertEqual('em0', interfaces[0].biosdevname)
|
||||
@ -552,7 +554,8 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
||||
read_mock = mocked_open.return_value.read
|
||||
read_mock.side_effect = ['1']
|
||||
mocked_ifaddresses.return_value = {
|
||||
netifaces.AF_INET: [{'addr': '192.168.1.2'}]
|
||||
netifaces.AF_INET: [{'addr': '192.168.1.2'}],
|
||||
netifaces.AF_INET6: [{'addr': 'fd00::101'}]
|
||||
}
|
||||
mocked_execute.return_value = ('em0\n', '')
|
||||
mock_get_mac.return_value = '00:0c:29:8c:11:b1'
|
||||
@ -562,6 +565,7 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
||||
self.assertEqual('eth0', interfaces[0].name)
|
||||
self.assertEqual('00:0c:29:8c:11:b1', interfaces[0].mac_address)
|
||||
self.assertEqual('192.168.1.2', interfaces[0].ipv4_address)
|
||||
self.assertEqual('fd00::101', interfaces[0].ipv6_address)
|
||||
self.assertIsNone(interfaces[0].lldp)
|
||||
self.assertTrue(interfaces[0].has_carrier)
|
||||
self.assertEqual('em0', interfaces[0].biosdevname)
|
||||
@ -645,7 +649,8 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
||||
read_mock = mocked_open.return_value.read
|
||||
read_mock.side_effect = ['1']
|
||||
mocked_ifaddresses.return_value = {
|
||||
netifaces.AF_INET: [{'addr': '192.168.1.2'}]
|
||||
netifaces.AF_INET: [{'addr': '192.168.1.2'}],
|
||||
netifaces.AF_INET6: [{'addr': 'fd00::101'}]
|
||||
}
|
||||
mocked_lldp_info.return_value = {'eth0': [
|
||||
(0, b''),
|
||||
@ -661,6 +666,7 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
||||
self.assertEqual('eth0', interfaces[0].name)
|
||||
self.assertEqual('00:0c:29:8c:11:b1', interfaces[0].mac_address)
|
||||
self.assertEqual('192.168.1.2', interfaces[0].ipv4_address)
|
||||
self.assertEqual('fd00::101', interfaces[0].ipv6_address)
|
||||
expected_lldp_info = [
|
||||
(0, ''),
|
||||
(1, '04885a92ec5459'),
|
||||
@ -693,7 +699,8 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
||||
read_mock = mocked_open.return_value.read
|
||||
read_mock.side_effect = ['1']
|
||||
mocked_ifaddresses.return_value = {
|
||||
netifaces.AF_INET: [{'addr': '192.168.1.2'}]
|
||||
netifaces.AF_INET: [{'addr': '192.168.1.2'}],
|
||||
netifaces.AF_INET6: [{'addr': 'fd00::101'}]
|
||||
}
|
||||
mocked_lldp_info.side_effect = Exception('Boom!')
|
||||
mocked_execute.return_value = ('em0\n', '')
|
||||
@ -704,6 +711,7 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
||||
self.assertEqual('eth0', interfaces[0].name)
|
||||
self.assertEqual('00:0c:29:8c:11:b1', interfaces[0].mac_address)
|
||||
self.assertEqual('192.168.1.2', interfaces[0].ipv4_address)
|
||||
self.assertEqual('fd00::101', interfaces[0].ipv6_address)
|
||||
self.assertIsNone(interfaces[0].lldp)
|
||||
self.assertTrue(interfaces[0].has_carrier)
|
||||
self.assertEqual('em0', interfaces[0].biosdevname)
|
||||
@ -734,7 +742,8 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
||||
read_mock = mocked_open.return_value.read
|
||||
read_mock.side_effect = [OSError('boom')]
|
||||
mocked_ifaddresses.return_value = {
|
||||
netifaces.AF_INET: [{'addr': '192.168.1.2'}]
|
||||
netifaces.AF_INET: [{'addr': '192.168.1.2'}],
|
||||
netifaces.AF_INET6: [{'addr': 'fd00::101'}]
|
||||
}
|
||||
mocked_execute.return_value = ('em0\n', '')
|
||||
mock_has_carrier.return_value = False
|
||||
@ -744,6 +753,7 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
||||
self.assertEqual('eth0', interfaces[0].name)
|
||||
self.assertEqual('00:0c:29:8c:11:b1', interfaces[0].mac_address)
|
||||
self.assertEqual('192.168.1.2', interfaces[0].ipv4_address)
|
||||
self.assertEqual('fd00::101', interfaces[0].ipv6_address)
|
||||
self.assertFalse(interfaces[0].has_carrier)
|
||||
self.assertIsNone(interfaces[0].vendor)
|
||||
self.assertEqual('em0', interfaces[0].biosdevname)
|
||||
@ -774,7 +784,8 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
||||
mac = '00:0c:29:8c:11:b1'
|
||||
read_mock.side_effect = ['0x15b3\n', '0x1014\n']
|
||||
mocked_ifaddresses.return_value = {
|
||||
netifaces.AF_INET: [{'addr': '192.168.1.2'}]
|
||||
netifaces.AF_INET: [{'addr': '192.168.1.2'}],
|
||||
netifaces.AF_INET6: [{'addr': 'fd00::101'}]
|
||||
}
|
||||
mocked_execute.return_value = ('em0\n', '')
|
||||
mock_has_carrier.return_value = True
|
||||
@ -784,6 +795,7 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
||||
self.assertEqual('eth0', interfaces[0].name)
|
||||
self.assertEqual(mac, interfaces[0].mac_address)
|
||||
self.assertEqual('192.168.1.2', interfaces[0].ipv4_address)
|
||||
self.assertEqual('fd00::101', interfaces[0].ipv6_address)
|
||||
self.assertTrue(interfaces[0].has_carrier)
|
||||
self.assertEqual('0x15b3', interfaces[0].vendor)
|
||||
self.assertEqual('0x1014', interfaces[0].product)
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
fixes:
|
||||
- Adds support to collect the default IPv6 address for interfaces. With
|
||||
different networking environment, the address could be a link-local
|
||||
address, ULA or something else.
|
Loading…
Reference in New Issue
Block a user