Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IP addresses missing from virtual machine interfaces #334

Merged
merged 3 commits into from Sep 27, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
35 changes: 30 additions & 5 deletions plugins/inventory/nb_inventory.py
Expand Up @@ -599,11 +599,19 @@ def extract_interfaces(self, host):

interfaces = list(interfaces_lookup[host["id"]].values())

before_netbox_v29 = bool(self.ipaddresses_lookup)
# Attach IP Addresses to their interface
for interface in interfaces:
interface["ip_addresses"] = list(
self.ipaddresses_lookup[interface["id"]].values()
)
if before_netbox_v29:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we even need to to determine if it's < 2.9?

Could we just have the two lookups, device and VM ip address lookups? So we handle the difference in versions in the code below by determining which bucket to throw them into?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you look in the changes I did in refresh_ipaddresses then you see that for NetBox v2.9 and later I will know if it is an IP address is connected to a VM or device by looking at the assigned_object_type. But in earlier NetBox versions this information is not available like that to determine which bucket to throw them into. Or what kind of change do you suggest?

It would have been great if I just could have the the two lookups and skip the ipaddresses_lookup completely but as said I do not see that I have the information available in earlier version to put IPs in the two buckets.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I do see what you're saying now. And we can't act off anything else with the way the inventory is setup to differentiate.

I will approve and merge this in.

interface["ip_addresses"] = list(
self.ipaddresses_lookup[interface["id"]].values()
)
else:
interface["ip_addresses"] = list(
self.vm_ipaddresses_lookup[interface["id"]].values()
if host["is_virtual"]
else self.device_ipaddresses_lookup[interface["id"]].values()
)

return interfaces
except Exception:
Expand Down Expand Up @@ -907,20 +915,37 @@ def refresh_ipaddresses(self):
# Construct a dictionary of lists, to allow looking up ip addresses by interface id
# Note that interface ids share the same namespace for both devices and vms so this is a single dictionary
self.ipaddresses_lookup = defaultdict(dict)
# NetBox v2.9 and onwards
self.vm_ipaddresses_lookup = defaultdict(dict)
self.device_ipaddresses_lookup = defaultdict(dict)

for ipaddress in ipaddresses:
# As of NetBox v2.9 "assigned_object_x" replaces "interface"
if ipaddress.get("assigned_object_id"):
interface_id = ipaddress["assigned_object_id"]
ip_id = ipaddress["id"]
# We need to copy the ipaddress entry to preserve the original in case caching is used.
ipaddress_copy = ipaddress.copy()

if ipaddress["assigned_object_type"] == 'virtualization.vminterface':
self.vm_ipaddresses_lookup[interface_id][ip_id] = ipaddress_copy
else:
self.device_ipaddresses_lookup[interface_id][ip_id] = ipaddress_copy # Remove "assigned_object_X" attributes, as that's redundant when ipaddress is added to an interface

del ipaddress_copy["assigned_object_id"]
del ipaddress_copy["assigned_object_type"]
del ipaddress_copy["assigned_object"]
continue

if not ipaddress.get("interface"):
continue

interface_id = ipaddress["interface"]["id"]
ip_id = ipaddress["id"]

# We need to copy the ipaddress entry to preserve the original in case caching is used.
ipaddress_copy = ipaddress.copy()

self.ipaddresses_lookup[interface_id][ip_id] = ipaddress_copy

# Remove "interface" attribute, as that's redundant when ipaddress is added to an interface
del ipaddress_copy["interface"]

Expand Down