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:
@@ -260,15 +260,17 @@ class BlockDevice(encoding.SerializableComparable):
|
|||||||
|
|
||||||
class NetworkInterface(encoding.SerializableComparable):
|
class NetworkInterface(encoding.SerializableComparable):
|
||||||
serializable_fields = ('name', 'mac_address', 'ipv4_address',
|
serializable_fields = ('name', 'mac_address', 'ipv4_address',
|
||||||
'has_carrier', 'lldp', 'vendor', 'product',
|
'ipv6_address', 'has_carrier', 'lldp',
|
||||||
'client_id', 'biosdevname')
|
'vendor', 'product', 'client_id',
|
||||||
|
'biosdevname')
|
||||||
|
|
||||||
def __init__(self, name, mac_addr, ipv4_address=None, has_carrier=True,
|
def __init__(self, name, mac_addr, ipv4_address=None, ipv6_address=None,
|
||||||
lldp=None, vendor=None, product=None, client_id=None,
|
has_carrier=True, lldp=None, vendor=None, product=None,
|
||||||
biosdevname=None):
|
client_id=None, biosdevname=None):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.mac_address = mac_addr
|
self.mac_address = mac_addr
|
||||||
self.ipv4_address = ipv4_address
|
self.ipv4_address = ipv4_address
|
||||||
|
self.ipv6_address = ipv6_address
|
||||||
self.has_carrier = has_carrier
|
self.has_carrier = has_carrier
|
||||||
self.lldp = lldp
|
self.lldp = lldp
|
||||||
self.vendor = vendor
|
self.vendor = vendor
|
||||||
@@ -582,6 +584,7 @@ class GenericHardwareManager(HardwareManager):
|
|||||||
return NetworkInterface(
|
return NetworkInterface(
|
||||||
interface_name, mac_addr,
|
interface_name, mac_addr,
|
||||||
ipv4_address=self.get_ipv4_addr(interface_name),
|
ipv4_address=self.get_ipv4_addr(interface_name),
|
||||||
|
ipv6_address=self.get_ipv6_addr(interface_name),
|
||||||
has_carrier=netutils.interface_has_carrier(interface_name),
|
has_carrier=netutils.interface_has_carrier(interface_name),
|
||||||
vendor=_get_device_info(interface_name, 'net', 'vendor'),
|
vendor=_get_device_info(interface_name, 'net', 'vendor'),
|
||||||
product=_get_device_info(interface_name, 'net', 'device'),
|
product=_get_device_info(interface_name, 'net', 'device'),
|
||||||
@@ -590,6 +593,14 @@ class GenericHardwareManager(HardwareManager):
|
|||||||
def get_ipv4_addr(self, interface_id):
|
def get_ipv4_addr(self, interface_id):
|
||||||
return netutils.get_ipv4_addr(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):
|
def get_bios_given_nic_name(self, interface_name):
|
||||||
"""Collect the BIOS given NICs name.
|
"""Collect the BIOS given NICs name.
|
||||||
|
|
||||||
|
@@ -203,15 +203,24 @@ def _get_lldp_info(interfaces):
|
|||||||
return lldp_info
|
return lldp_info
|
||||||
|
|
||||||
|
|
||||||
def get_ipv4_addr(interface_id):
|
def get_default_ip_addr(type, interface_id):
|
||||||
|
"""Retrieve default IPv4 or IPv6 address."""
|
||||||
try:
|
try:
|
||||||
addrs = netifaces.ifaddresses(interface_id)
|
addrs = netifaces.ifaddresses(interface_id)
|
||||||
return addrs[netifaces.AF_INET][0]['addr']
|
return addrs[type][0]['addr']
|
||||||
except (ValueError, IndexError, KeyError):
|
except (ValueError, IndexError, KeyError):
|
||||||
# No default IPv4 address found
|
# No default IP address found
|
||||||
return None
|
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):
|
def get_mac_addr(interface_id):
|
||||||
try:
|
try:
|
||||||
addrs = netifaces.ifaddresses(interface_id)
|
addrs = netifaces.ifaddresses(interface_id)
|
||||||
|
@@ -513,7 +513,8 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
|||||||
read_mock = mocked_open.return_value.read
|
read_mock = mocked_open.return_value.read
|
||||||
read_mock.side_effect = ['1']
|
read_mock.side_effect = ['1']
|
||||||
mocked_ifaddresses.return_value = {
|
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', '')
|
mocked_execute.return_value = ('em0\n', '')
|
||||||
mock_get_mac.mock_has_carrier = True
|
mock_get_mac.mock_has_carrier = True
|
||||||
@@ -523,6 +524,7 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
|||||||
self.assertEqual('eth0', interfaces[0].name)
|
self.assertEqual('eth0', interfaces[0].name)
|
||||||
self.assertEqual('00:0c:29:8c:11:b1', interfaces[0].mac_address)
|
self.assertEqual('00:0c:29:8c:11:b1', interfaces[0].mac_address)
|
||||||
self.assertEqual('192.168.1.2', interfaces[0].ipv4_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.assertIsNone(interfaces[0].lldp)
|
||||||
self.assertTrue(interfaces[0].has_carrier)
|
self.assertTrue(interfaces[0].has_carrier)
|
||||||
self.assertEqual('em0', interfaces[0].biosdevname)
|
self.assertEqual('em0', interfaces[0].biosdevname)
|
||||||
@@ -552,7 +554,8 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
|||||||
read_mock = mocked_open.return_value.read
|
read_mock = mocked_open.return_value.read
|
||||||
read_mock.side_effect = ['1']
|
read_mock.side_effect = ['1']
|
||||||
mocked_ifaddresses.return_value = {
|
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', '')
|
mocked_execute.return_value = ('em0\n', '')
|
||||||
mock_get_mac.return_value = '00:0c:29:8c:11:b1'
|
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('eth0', interfaces[0].name)
|
||||||
self.assertEqual('00:0c:29:8c:11:b1', interfaces[0].mac_address)
|
self.assertEqual('00:0c:29:8c:11:b1', interfaces[0].mac_address)
|
||||||
self.assertEqual('192.168.1.2', interfaces[0].ipv4_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.assertIsNone(interfaces[0].lldp)
|
||||||
self.assertTrue(interfaces[0].has_carrier)
|
self.assertTrue(interfaces[0].has_carrier)
|
||||||
self.assertEqual('em0', interfaces[0].biosdevname)
|
self.assertEqual('em0', interfaces[0].biosdevname)
|
||||||
@@ -645,7 +649,8 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
|||||||
read_mock = mocked_open.return_value.read
|
read_mock = mocked_open.return_value.read
|
||||||
read_mock.side_effect = ['1']
|
read_mock.side_effect = ['1']
|
||||||
mocked_ifaddresses.return_value = {
|
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': [
|
mocked_lldp_info.return_value = {'eth0': [
|
||||||
(0, b''),
|
(0, b''),
|
||||||
@@ -661,6 +666,7 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
|||||||
self.assertEqual('eth0', interfaces[0].name)
|
self.assertEqual('eth0', interfaces[0].name)
|
||||||
self.assertEqual('00:0c:29:8c:11:b1', interfaces[0].mac_address)
|
self.assertEqual('00:0c:29:8c:11:b1', interfaces[0].mac_address)
|
||||||
self.assertEqual('192.168.1.2', interfaces[0].ipv4_address)
|
self.assertEqual('192.168.1.2', interfaces[0].ipv4_address)
|
||||||
|
self.assertEqual('fd00::101', interfaces[0].ipv6_address)
|
||||||
expected_lldp_info = [
|
expected_lldp_info = [
|
||||||
(0, ''),
|
(0, ''),
|
||||||
(1, '04885a92ec5459'),
|
(1, '04885a92ec5459'),
|
||||||
@@ -693,7 +699,8 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
|||||||
read_mock = mocked_open.return_value.read
|
read_mock = mocked_open.return_value.read
|
||||||
read_mock.side_effect = ['1']
|
read_mock.side_effect = ['1']
|
||||||
mocked_ifaddresses.return_value = {
|
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_lldp_info.side_effect = Exception('Boom!')
|
||||||
mocked_execute.return_value = ('em0\n', '')
|
mocked_execute.return_value = ('em0\n', '')
|
||||||
@@ -704,6 +711,7 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
|||||||
self.assertEqual('eth0', interfaces[0].name)
|
self.assertEqual('eth0', interfaces[0].name)
|
||||||
self.assertEqual('00:0c:29:8c:11:b1', interfaces[0].mac_address)
|
self.assertEqual('00:0c:29:8c:11:b1', interfaces[0].mac_address)
|
||||||
self.assertEqual('192.168.1.2', interfaces[0].ipv4_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.assertIsNone(interfaces[0].lldp)
|
||||||
self.assertTrue(interfaces[0].has_carrier)
|
self.assertTrue(interfaces[0].has_carrier)
|
||||||
self.assertEqual('em0', interfaces[0].biosdevname)
|
self.assertEqual('em0', interfaces[0].biosdevname)
|
||||||
@@ -734,7 +742,8 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
|||||||
read_mock = mocked_open.return_value.read
|
read_mock = mocked_open.return_value.read
|
||||||
read_mock.side_effect = [OSError('boom')]
|
read_mock.side_effect = [OSError('boom')]
|
||||||
mocked_ifaddresses.return_value = {
|
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', '')
|
mocked_execute.return_value = ('em0\n', '')
|
||||||
mock_has_carrier.return_value = False
|
mock_has_carrier.return_value = False
|
||||||
@@ -744,6 +753,7 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
|||||||
self.assertEqual('eth0', interfaces[0].name)
|
self.assertEqual('eth0', interfaces[0].name)
|
||||||
self.assertEqual('00:0c:29:8c:11:b1', interfaces[0].mac_address)
|
self.assertEqual('00:0c:29:8c:11:b1', interfaces[0].mac_address)
|
||||||
self.assertEqual('192.168.1.2', interfaces[0].ipv4_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.assertFalse(interfaces[0].has_carrier)
|
||||||
self.assertIsNone(interfaces[0].vendor)
|
self.assertIsNone(interfaces[0].vendor)
|
||||||
self.assertEqual('em0', interfaces[0].biosdevname)
|
self.assertEqual('em0', interfaces[0].biosdevname)
|
||||||
@@ -774,7 +784,8 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
|||||||
mac = '00:0c:29:8c:11:b1'
|
mac = '00:0c:29:8c:11:b1'
|
||||||
read_mock.side_effect = ['0x15b3\n', '0x1014\n']
|
read_mock.side_effect = ['0x15b3\n', '0x1014\n']
|
||||||
mocked_ifaddresses.return_value = {
|
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', '')
|
mocked_execute.return_value = ('em0\n', '')
|
||||||
mock_has_carrier.return_value = True
|
mock_has_carrier.return_value = True
|
||||||
@@ -784,6 +795,7 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
|||||||
self.assertEqual('eth0', interfaces[0].name)
|
self.assertEqual('eth0', interfaces[0].name)
|
||||||
self.assertEqual(mac, interfaces[0].mac_address)
|
self.assertEqual(mac, interfaces[0].mac_address)
|
||||||
self.assertEqual('192.168.1.2', interfaces[0].ipv4_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.assertTrue(interfaces[0].has_carrier)
|
||||||
self.assertEqual('0x15b3', interfaces[0].vendor)
|
self.assertEqual('0x15b3', interfaces[0].vendor)
|
||||||
self.assertEqual('0x1014', interfaces[0].product)
|
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.
|
Reference in New Issue
Block a user