enable_vlan_interfaces: support identifying interfaces by MAC
The enable_vlan_interfaces config option supports a comma-separated list of <interface>.<vlan> pairs. However, using this relies on knowledge of the interface name. When used via the ipa-enable-vlan-interfaces kernel command-line parameter, an interface name may be hard to predict. As an alternative to identifying interfaces by name, support identifying them by MAC. Change-Id: Ice822a8e7b8d82352b3b39f87d930bef3eb7b461 Signed-off-by: Jonathan Davies <jonathan.davies@nutanix.com>
This commit is contained in:
@@ -318,7 +318,9 @@ cli_opts = [
|
||||
cfg.StrOpt('enable_vlan_interfaces',
|
||||
default=APARAMS.get('ipa-enable-vlan-interfaces', ''),
|
||||
help='Comma-separated list of VLAN interfaces to enable, '
|
||||
'in the format "interface.vlan". If only an '
|
||||
'in the format "interface.vlan". The "interface" can be '
|
||||
'an interface name or a MAC address (EUI-48 format, '
|
||||
'case-insensitive). If only an '
|
||||
'interface is provided, then IPA should attempt to '
|
||||
'bring up all VLANs on that interface detected '
|
||||
'via lldp. If "all" is set then IPA should attempt '
|
||||
|
||||
@@ -420,11 +420,14 @@ def bring_up_vlan_interfaces(interfaces_list):
|
||||
if '.' in vlan_int:
|
||||
# interface and vlan are provided
|
||||
interface, vlan = vlan_int.split('.', 1)
|
||||
if any(x.name == interface for x in interfaces_list):
|
||||
name = _add_vlan_interface(interface, vlan,
|
||||
interfaces_list)
|
||||
if name:
|
||||
interfaces.append(name)
|
||||
for x in interfaces_list:
|
||||
if (x.name == interface
|
||||
or x.mac_address.lower() == interface.lower()):
|
||||
name = _add_vlan_interface(x.name, vlan,
|
||||
interfaces_list)
|
||||
if name:
|
||||
interfaces.append(name)
|
||||
break
|
||||
else:
|
||||
LOG.warning('Provided VLAN interface %s does not exist',
|
||||
interface)
|
||||
|
||||
@@ -6901,6 +6901,58 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
||||
self.assertEqual('00:0c:29:8c:11:b1', interfaces[1].mac_address)
|
||||
self.assertIsNone(interfaces[1].lldp)
|
||||
|
||||
def test_list_network_vlan_interfaces_mac(self,
|
||||
mock_has_carrier,
|
||||
mocked_execute,
|
||||
mocked_open,
|
||||
mocked_exists,
|
||||
mocked_listdir,
|
||||
mocked_net_if_addrs,
|
||||
mockedget_managers,
|
||||
mocked_lshw,
|
||||
mocked_get_mac_addr):
|
||||
CONF.set_override('enable_vlan_interfaces', '00:0c:29:8c:11:b1.100')
|
||||
mocked_listdir.return_value = ['lo', 'eth0']
|
||||
mocked_exists.side_effect = [False, False, True]
|
||||
mocked_open.return_value.__enter__ = lambda s: s
|
||||
mocked_open.return_value.__exit__ = mock.Mock()
|
||||
read_mock = mocked_open.return_value.read
|
||||
read_mock.side_effect = ['1']
|
||||
mocked_net_if_addrs.return_value = {
|
||||
'lo': [
|
||||
FakeAddr(socket.AF_INET, '127.0.0.1'),
|
||||
FakeAddr(socket.AF_INET6, '::1'),
|
||||
FakeAddr(socket.AF_PACKET, '00:00:00:00:00:00')
|
||||
],
|
||||
'eth0': [
|
||||
FakeAddr(socket.AF_INET, '192.168.1.2'),
|
||||
FakeAddr(socket.AF_INET6, 'fd00::101'),
|
||||
FakeAddr(socket.AF_PACKET, '00:0c:29:8c:11:b1')
|
||||
],
|
||||
'eth0.100': [
|
||||
FakeAddr(socket.AF_INET, '192.168.2.2'),
|
||||
FakeAddr(socket.AF_INET6, 'fd00::1000::101'),
|
||||
FakeAddr(socket.AF_PACKET, '00:0c:29:8c:11:b1')
|
||||
]
|
||||
}
|
||||
mocked_get_mac_addr.side_effect = lambda iface: {
|
||||
'lo': '00:00:00:00:00:00',
|
||||
'eth0': '00:0c:29:8c:11:b1',
|
||||
'eth0.100': '00:0c:29:8c:11:b1',
|
||||
}.get(iface)
|
||||
mocked_execute.return_value = ('em0\n', '')
|
||||
mock_has_carrier.return_value = True
|
||||
interfaces = self.hardware.list_network_interfaces()
|
||||
self.assertEqual(2, len(interfaces))
|
||||
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.assertEqual('eth0.100', interfaces[1].name)
|
||||
self.assertEqual('00:0c:29:8c:11:b1', interfaces[1].mac_address)
|
||||
self.assertIsNone(interfaces[1].lldp)
|
||||
|
||||
@mock.patch.object(netutils, 'get_lldp_info', autospec=True)
|
||||
def test_list_network_vlan_interfaces_using_lldp(self,
|
||||
mocked_lldp_info,
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Extend ``ipa-enable-vlan-interfaces`` kernel params field to support
|
||||
identifying an interface by its MAC address as an alternative to its name.
|
||||
Reference in New Issue
Block a user