Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions aquilon/netbox2aquilon.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,16 +173,23 @@ def _netbox_copy_interfaces(self, device):
if tag.slug == 'bootable':
is_boot_interface = True

is_lag_interface = hasattr(interface, 'type') and interface.type.value == 'lag'

cmd = [
'add_interface',
'--machine', f'{device.aq_machine_name}',
'--mac', f'{interface.mac_address}',
'--interface', f'{interface.name}',
]
if interface.mac_address and not is_lag_interface:
cmd.extend(['--mac', f'{interface.mac_address}'])

# Specify --iftype if this is a special type of interface.
# Valid values are: bonding, bridge, loopback, management, oa, physical, public, virtual, vlan
if (hasattr(interface, 'mgmt_only') and interface.mgmt_only and not is_boot_interface):
# mgmt_only is only an attribute for physical devices
# Valid values are: bonding, bridge, loopback, management, oa, physical, public, virtual, vlan
cmd.extend(['--iftype', 'management'])
elif is_lag_interface:
cmd.extend(['--iftype', 'bonding'])

cmds.append(cmd)

Expand All @@ -193,6 +200,17 @@ def _netbox_copy_interfaces(self, device):
'--interface', f'{interface.name}',
'--boot',
])

if (hasattr(interface, 'lag') and interface.lag):
# This property is a bit confusing, it contains a link to a LAG interface when the current interface
# is a member of that LAG, it does not mean that the current interface is a LAG.
cmds.append([
'update_interface',
'--machine', f'{device.aq_machine_name}',
'--interface', f'{interface.name}',
'--master', f'{interface.lag.name}',
])

return cmds

def _netbox_copy_addresses(self, device):
Expand Down
4 changes: 3 additions & 1 deletion aquilon/scd_netbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,13 @@ def get_interfaces_from_device(self, device):
for interface in filter_interfaces:
if interface.mac_address:
interfaces.append(interface)
elif hasattr(interface, 'type') and interface.type.value == 'lag':
interfaces.append(interface)
else:
unusedintf += 1

if unusedintf:
logging.warning("%s interfaces without mac address were not included", unusedintf)
logging.warning("%s non-lag interfaces without mac address were not included", unusedintf)

return interfaces

Expand Down
45 changes: 38 additions & 7 deletions aquilon/test_netbox2aquilon.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ def test__netbox_copy_interfaces(mocker):

add_interface_base_cmd = ['add_interface', '--machine', 'system7592']

add_bmc0 = add_interface_base_cmd + ['--mac', 'A1:B2:C3:D4:E5:3F', '--interface', 'bmc0', '--iftype', 'management']
add_eth0 = add_interface_base_cmd + ['--mac', 'A1:B2:C3:D4:E5:DA', '--interface', 'eth0']
add_eth1 = add_interface_base_cmd + ['--mac', 'A1:B2:C3:D4:E5:DB', '--interface', 'eth1']
add_bmc0 = add_interface_base_cmd + ['--interface', 'bmc0', '--mac', 'A1:B2:C3:D4:E5:3F', '--iftype', 'management']
add_eth0 = add_interface_base_cmd + ['--interface', 'eth0', '--mac', 'A1:B2:C3:D4:E5:DA']
add_eth1 = add_interface_base_cmd + ['--interface', 'eth1', '--mac', 'A1:B2:C3:D4:E5:DB']

update_eth0 = ['update_interface', '--machine', 'system7592', '--interface', 'eth0', '--boot']

Expand All @@ -77,8 +77,8 @@ def test__netbox_copy_interfaces(mocker):
aq_machine_name='system6690',
)
test_obj.get_interfaces_from_device = mocker.MagicMock(return_value=deepcopy(FAKE.INTERFACES_VIRTUAL))
add_eth0 = ['add_interface', '--machine', 'system6690', '--mac', 'A1:B2:C3:D4:E5:1B', '--interface', 'eth0']
add_eth1 = ['add_interface', '--machine', 'system6690', '--mac', 'A1:B2:C3:D4:E5:99', '--interface', 'eth1']
add_eth0 = ['add_interface', '--machine', 'system6690', '--interface', 'eth0', '--mac', 'A1:B2:C3:D4:E5:1B']
add_eth1 = ['add_interface', '--machine', 'system6690', '--interface', 'eth1', '--mac', 'A1:B2:C3:D4:E5:99']
update_eth0 = ['update_interface', '--machine', 'system6690', '--interface', 'eth0', '--boot']

cmds = test_obj._netbox_copy_interfaces(fake_device)
Expand All @@ -90,6 +90,37 @@ def test__netbox_copy_interfaces(mocker):
# eth0 must be added before being updated
assert cmds.index(add_eth0) < cmds.index(update_eth0)


# Physical device with two bonded LAG interfaces
fake_device = SimpleNamespace(
aq_machine_name='system8211',
)
test_obj.get_interfaces_from_device = mocker.MagicMock(return_value=deepcopy(FAKE.INTERFACES_PHYSICAL_LAGS))

add_interface_base_cmd = ['add_interface', '--machine', 'system8211']
update_interface_base_cmd = ['update_interface', '--machine', 'system8211']

cmds = test_obj._netbox_copy_interfaces(fake_device)

assert len(cmds) == 12

assert add_interface_base_cmd + ['--interface', 'bond0', '--iftype', 'bonding'] in cmds
assert add_interface_base_cmd + ['--interface', 'bond1', '--iftype', 'bonding'] in cmds
assert add_interface_base_cmd + ['--interface', 'eth0', '--mac', 'A1:B2:C3:69:2A:A1'] in cmds
assert add_interface_base_cmd + ['--interface', 'eth1', '--mac', 'A1:B2:C3:69:2A:A2'] in cmds
assert add_interface_base_cmd + ['--interface', 'eth2', '--mac', 'D4:E5:3F:52:37:8D'] in cmds
assert add_interface_base_cmd + ['--interface', 'eth3', '--mac', 'D4:E5:3F:52:37:8E'] in cmds

assert update_interface_base_cmd + ['--interface', 'bond0', '--boot'] in cmds
assert update_interface_base_cmd + ['--interface', 'eth0', '--master', 'bond1'] in cmds
assert update_interface_base_cmd + ['--interface', 'eth1', '--master', 'bond1'] in cmds
assert update_interface_base_cmd + ['--interface', 'eth2', '--master', 'bond0'] in cmds
assert update_interface_base_cmd + ['--interface', 'eth3', '--master', 'bond0'] in cmds

# eth0 must be added before being updated
#assert cmds.index(add_eth0) < cmds.index(update_eth0)


def test__netbox_copy_addresses(mocker):
test_obj = Netbox2Aquilon()

Expand Down Expand Up @@ -202,14 +233,14 @@ def test__undo_cmds():
[
'add_interface',
'--machine', 'system6690',
'--mac', 'A1:B2:C3:D4:E5:1B',
'--interface', 'eth0',
'--mac', 'A1:B2:C3:D4:E5:1B',
],
[
'add_interface',
'--machine', 'system6690',
'--mac', 'A1:B2:C3:D4:E5:99',
'--interface', 'eth1',
'--mac', 'A1:B2:C3:D4:E5:99',
],
[
'update_interface',
Expand Down
1 change: 1 addition & 0 deletions aquilon/testdata/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def load_data():
'device_physical': pynetbox.models.dcim.Devices,
'device_virtual': pynetbox.models.virtualization.VirtualMachines,
'interfaces_physical': pynetbox.models.dcim.Interfaces,
'interfaces_physical_lags': pynetbox.models.dcim.Interfaces,
'interfaces_virtual': pynetbox.core.response.Record,
'addresses_ipv4': pynetbox.models.ipam.IpAddresses,
'addresses_ipv6': pynetbox.models.ipam.IpAddresses,
Expand Down
Loading