Skip to content

[Bug]: nb_inventory func extract_dns_name() doesn't handle unassigned interface ip address #1444

@jbroillet

Description

@jbroillet

Ansible NetBox Collection version

v3.21.0

Ansible version

ansible --version
ansible [core 2.18.6]
  config file = /home/user/netdevops/semaphore/network-automation/ansible.cfg
  configured module search path = ['/home/user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/user/netdevops/semaphore/network-automation/.venv/lib64/python3.11/site-packages/ansible
  ansible collection location = /home/user/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/user/netdevops/semaphore/network-automation/.venv/bin/ansible
  python version = 3.11.11 (main, Feb 10 2025, 00:00:00) [GCC 11.5.0 20240719 (Red Hat 11.5.0-5)] (/home/user/netdevops/semaphore/network-automation/.venv/bin/python3.11)
  jinja version = 3.1.6
  libyaml = True

NetBox version

v4.3.2

Python version

3.11

Steps to Reproduce

  1. In NetBox, create a device with the following setup:

    • A private IP address (e.g., 192.168.1.1) assigned to an interface (e.g., GigabitEthernet0/0).
    • A public/NAT IP address (e.g., 203.0.113.1), set NAT INSIDE field to the created assigned interface (e.g., 192.168.1.1) and set the NAT IP address (e.g., 203.0.113.1) as the primary IP of the device, but not assigned to any interface.
  2. Observe the behavior:

    • The function fails to resolve the DNS name correctly and produces an error when the primary IP is not associated with an interface.
    • Inventory plugin completely fail and return any hosts

Expected Behavior

The extract_dns_name() function should be able to extract a valid DNS name even if the device's primary IP address is not assigned to any interface.

In this scenario, since the primary IP (e.g., the NAT outside address) is intentionally not associated with an interface, the function should still return a usable DNS name based on the primary IP rather than failing.

Observed Behavior

I have observed that the extract_dns_name() function does not handle the case where the primary IP is not assigned to an interface. The relevant portion of the function is:

def extract_dns_name(self, host):
    # No primary IP assigned
    if not host.get("primary_ip"):
        return None

    before_netbox_v29 = bool(self.ipaddresses_lookup)
    if before_netbox_v29:
        ip_address = self.ipaddresses_lookup.get(host["primary_ip"]["id"])
    else:
        if host["is_virtual"]:
            ip_address = self.vm_ipaddresses_lookup.get(host["primary_ip"]["id"])
        else:
            ip_address = self.device_ipaddresses_lookup.get(
                host["primary_ip"]["id"]
            )

    if ip_address.get("dns_name") == "":
        return None

    return ip_address.get("dns_name")

Issues observed

  • There is no handling if ip_address is None, which causes a runtime error on ip_address.get("dns_name").
  • Adding the following check resolves part of the problem:
if not ip_address:
    return None
  • However, this only partially resolves the issue, since I’m not using the dns_name field in the IP address object at all in my setup.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions