Skip to content

fix: ip discovery before subnet filter - #618

Open
marcinpsk wants to merge 2 commits into
bb-Ricardo:developmentfrom
marcinpsk:fix/ip-discovery-before-subnet-filter
Open

marcinpsk wants to merge 2 commits into
bb-Ricardo:developmentfrom
marcinpsk:fix/ip-discovery-before-subnet-filter

Conversation

@marcinpsk

Copy link
Copy Markdown
Contributor

Problem

keep_undiscovered_ips exists so an interface Redfish reports no address for keeps the IPs it already has. Redfish does not report host NIC, bond or bridge addresses, and such an interface is matched only by a shared MAC, so pruning from an empty discovery destroyed management IPs.

Whether anything was discovered was read from interface_ips, the list the source hands over. That list is already filtered. update_network_interface() drops any address permitted_subnets rejects before building it:

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
    nic_ips[port_name].append(ipv4_address)

Port where Redfish reported an address the operator excluded looked identical to a port Redfish said nothing, and its existing IPs were kept instead of cleaned up.

Why the two cases are different

  • Redfish reported nothing: the source is blind to this interface and must not be trusted to prune. Keep what NetBox has.
  • Redfish reported an address the operator excluded: the source could see the interface. An address in NetBox that is no longer reported really is gone, and should be removed.

Fix

The source decides - update_network_interface() counts the addresses Redfish reported per port (before permitted_subnets) and passes keep_undiscovered_ips only for a port that reported none

…ltering

keep_undiscovered_ips exists so an interface Redfish reports no address for keeps the
IPs it already has: Redfish does not report host NIC, bond or bridge addresses, and such
an interface is matched only by a shared MAC.

Whether anything was discovered was read from interface_ips, the list the check_redfish
source hands over. That list is already filtered: update_network_interface() drops any
address permitted_subnets rejects before building it. So a port where Redfish reported
an address the operator excluded looked identical to a port Redfish said nothing about,
and its existing IPs were kept instead of being cleaned up.

The two cases are different. In the first the source could see the interface, so an
address in NetBox which is no longer reported is gone and should be removed. Only the
second means the source is blind and must not be trusted to prune.

The source now decides, because it is the only place that sees its own discovery before
filtering: update_network_interface() counts the addresses Redfish reported per port and
passes keep_undiscovered_ips only for a port which reported none. add_update_interface()
is unchanged apart from saying so, since interface_ips is a surviving subset and cannot
answer the question on its own.

The test drives the real update_network_interface() with a real PermittedSubnets which
excludes the reported address, and asserts the stale address is still removed. It also
asserts PermittedSubnets parsed the exclusion, because an unparseable subnet permits
everything and would have made the test pass without exercising anything.

The shared check_redfish test fixture now calls reset_inventory_state(), which sets up
the per inventory file state __init__ would have, so a test can drive the network
interface path at all.

A port skipped by skip_os_reported_ips is not counted. The operator told the source to
ignore the addresses of that port, so it did not see them and must keep what NetBox has.

The test seeds the interface with a primary MAC address object, because on NetBox 4.2
and later an interface is matched by that object and not by the legacy mac_address field.
An inventory entry which is not an IP address (null, "N/A") made a port count as
discovered. keep_undiscovered_ips was then false, and the existing IPs of the
interface were removed although the port reported no usable address.

Count only entries which parse as an IP address. An excluded valid address still
counts, so permitted_subnets filtering does not hide a real discovery.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant