From cd02af3310002434859e039bfa895c009d0063b0 Mon Sep 17 00:00:00 2001 From: Thomas Foks Date: Wed, 7 Oct 2026 14:55:50 +0200 Subject: [PATCH] feat(check_redfish): add option to skip OS reported IP addresses Some BMCs (i.e. HPE iLO with AMS) report the IP addresses of the operating system on the physical NICs. If the same server is also synced by another source (i.e. as an ESXi host by the VMware source), both sources move these IPs back and forth between the VMkernel interface and the physical NIC on every run, and the primary IP of the device gets unset each time. The new option 'skip_os_reported_ips' (default: False) syncs only the IP addresses of the BMC ports. Co-Authored-By: Claude Opus 5.5 --- module/sources/check_redfish/config.py | 9 ++++ .../sources/check_redfish/import_inventory.py | 3 ++ settings-example.ini | 7 +++ tests/test_check_redfish_interface_ips.py | 50 +++++++++++++++++++ 4 files changed, 69 insertions(+) diff --git a/module/sources/check_redfish/config.py b/module/sources/check_redfish/config.py index 34119bc..00db850 100644 --- a/module/sources/check_redfish/config.py +++ b/module/sources/check_redfish/config.py @@ -92,6 +92,15 @@ def __init__(self): syncing.""", default_value=False), + ConfigOption("skip_os_reported_ips", + bool, + description="""define if IP addresses which the BMC reports for the ports of the server + itself are skipped. Some BMCs (i.e. HPE iLO with AMS) report the IP addresses of the + operating system on the physical NICs. If the operating system is synced by another + source (i.e. VMware ESXi hosts) these IPs would be moved back and forth between + interfaces. If True only the IP addresses of the BMC ports are synced.""", + default_value=False), + ConfigOption(**config_option_ip_tenant_inheritance_order_definition), ] diff --git a/module/sources/check_redfish/import_inventory.py b/module/sources/check_redfish/import_inventory.py index b79ccf2..91add4e 100644 --- a/module/sources/check_redfish/import_inventory.py +++ b/module/sources/check_redfish/import_inventory.py @@ -981,6 +981,9 @@ def update_network_interface(self): # collect ip addresses nic_ips[port_name] = list() + if self.settings.skip_os_reported_ips is True and mgmt_only is False: + continue + for ipv4_address in grab(nic_port, "ipv4_addresses", fallback=list()): if self.settings.permitted_subnets.permitted(ipv4_address, interface_name=port_name) is False: continue diff --git a/settings-example.ini b/settings-example.ini index b1c71fa..4e345d4 100644 --- a/settings-example.ini +++ b/settings-example.ini @@ -584,6 +584,13 @@ inventory_file_path = /full/path/to/inventory/files ; incorrect syncing. ;skip_fhrp_group_ips = False +; define if IP addresses which the BMC reports for the ports of the server itself are +; skipped. Some BMCs (i.e. HPE iLO with AMS) report the IP addresses of the operating +; system on the physical NICs. If the operating system is synced by another source (i.e. +; VMware ESXi hosts) these IPs would be moved back and forth between interfaces. If True +; only the IP addresses of the BMC ports are synced. +;skip_os_reported_ips = False + ; define in which order the IP address tenant will be assigned if tenant is undefined. ; possible values: ; * device : host or VM tenant will be assigned to the IP address diff --git a/tests/test_check_redfish_interface_ips.py b/tests/test_check_redfish_interface_ips.py index 182d5de..577721c 100644 --- a/tests/test_check_redfish_interface_ips.py +++ b/tests/test_check_redfish_interface_ips.py @@ -13,7 +13,9 @@ NBIPAddress objects. """ +from module.common.misc import grab from module.netbox.object_classes import NBInterface, NBIPAddress +from module.sources.common.permitted_subnets import PermittedSubnets def seed_interface_with_ip(context, name="pnet0", address="172.10.10.12/24"): @@ -71,3 +73,51 @@ def test_ip_is_still_removed_when_the_discovered_ips_are_unusable(check_redfish_ keep_undiscovered_ips=True) assert "assigned_object_id" in ip.unset_items + + +def run_network_interface_sync(check_redfish_source, **settings): + """Sync a server NIC port and a BMC port which both report IP addresses, like an HPE iLO + with AMS which reports the IPs of the operating system on the physical NICs.""" + + context = check_redfish_source(**settings) + source = context.source + context.inventory.netbox_api_version = "4.2.0" + source.interface_adapter_type_dict = {} + source.manager_name = "iLO 5" + source.settings.permitted_subnets = PermittedSubnets("10.0.0.0/8") + source.settings.ip_tenant_inheritance_order = [] + + source.inventory_file_content = { + "inventory": { + "network_port": [ + {"id": "2.2", "addresses": ["8C:DC:D4:0F:D7:84"], + "operation_status": "Enabled", "link_status": "Up", "manager_ids": [], + "ipv4_addresses": ["10.40.232.163/22"], "ipv6_addresses": []}, + {"id": "1:1", "name": "Manager Dedicated Network Interface", + "addresses": ["08:F1:EA:93:F3:D6"], "operation_status": "Enabled", + "link_status": "Up", "manager_ids": ["1"], + "ipv4_addresses": ["10.44.102.102/22"], "ipv6_addresses": []}, + ], + } + } + + source.update_network_interface() + + return {grab(ip, "data.assigned_object_id.data.name"): str(grab(ip, "data.address")) + for ip in context.inventory.get_all_items(NBIPAddress)} + + +def test_os_reported_ips_are_synced_by_default(check_redfish_source): + """Without skip_os_reported_ips the IPs of all ports are synced, as before.""" + + assigned_ips = run_network_interface_sync(check_redfish_source) + + assert assigned_ips == {"2.2": "10.40.232.163/22", "iLO 5 (1:1)": "10.44.102.102/22"} + + +def test_os_reported_ips_are_skipped(check_redfish_source): + """With skip_os_reported_ips only the IPs of the BMC ports are synced.""" + + assigned_ips = run_network_interface_sync(check_redfish_source, skip_os_reported_ips=True) + + assert assigned_ips == {"iLO 5 (1:1)": "10.44.102.102/22"}