Skip to content

[Bug]: query_filters in netbox inventory source can not be fully set by --extra-vars with multiple filters #1515

@lalgarvi-te

Description

@lalgarvi-te

Ansible NetBox Collection version

v3.21.0

Ansible version

ansible [core 2.16.15]
  config file = ansible/ansible.cfg
  configured module search path = ['/home/lalgarvi/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = ansible/.venv/lib/python3.11/site-packages/ansible
  ansible collection location = ansible/.ansible/collections:ansible/collections
  executable location = ansible/.venv/bin/ansible
  python version = 3.11.14 (main, Oct 14 2025, 21:26:53) [Clang 20.1.4 ] (ansible/.venv/bin/python)
  jinja version = 3.1.6
  libyaml = True

NetBox version

v3.7.8

Python version

3.11

Steps to Reproduce

Hello,

I've run into a situation where i can't seem to fully unlock the power of query_filters in netbox inventory source, by not being able to fully set them via --extra-args in the CLI and override any and all of them as needed per ansible playbook run. It will work with just one filter, but if you add more than one, it simply aborts the code with a validation error, and if you remove the validation, it crashes the code or treats the vars wrong.

Previously i was not experiencing any issues with a less flexible approach where you just set multiple --extra-vars variables and add them as a list to the query_filters: [] variable in the netbox inventory source, ie

query_filters:
  - region: "{{ cli_filter_region | default('earth', true) }}"
  - status: "{{ cli_filter_status | default('active', true) }}"

But this is not as flexible as replacing the whole query_filters: [], ie:

query_filters: "{{ cli_filters }}"

Followed docs as described here:

Could you please look and investigate?
Thanks!

Expected Behavior

The query_filters: [] should be treated the same way if set in full via --extra-args with an auxiliary variable as it is if it is set in the netbox inventory source, hardcoded, or using multiple variables.

Observed Behavior

For the testing samples i did the bellow:

  • changed def validate_query_parameter (around like 1681) in nb_inventory.py:
#        if not (isinstance(parameter, dict) and len(parameter) == 1):
#            self.display.warning(
#                "Warning query parameters %s not a dict with a single key." % parameter
#            )
#            return None
        print(parameter)
        k = tuple(parameter.keys())[0]
        v = tuple(parameter.values())[0]
        print(k)
        print(v)
  • changed def refresh_url (around like 1713) in nb_inventory.py:
    def refresh_url(self):
        device_query_parameters = [("limit", 0)]
        vm_query_parameters = [("limit", 0)]
        device_url = self.api_endpoint + "/api/dcim/devices/?"
        vm_url = self.api_endpoint + "/api/virtualization/virtual-machines/?"

        print(self.query_filters)
        print(self.filter_query_parameters)
  • examples described one by one with different methods.

Test cases start here:

  • query_filters directly set in inventory source file with JSON: it works
query_filters: [{"region": "england"},{"region": "france"},{"status": "active"}]
ansible-inventory \
  -i inventories/staging \
  --list -vvvv

[{'region': 'england'}, {'region': 'france'}, {'status': 'active'}]
<bound method InventoryModule.filter_query_parameters of <ansible_collections.netbox.netbox.plugins.inventory.nb_inventory.InventoryModule object at 0x7a0bdffec790>>
{'region': 'england'}
region
england
{'region': 'france'}
region
france
{'status': 'active'}
status
active
{'region': 'england'}
region
england
{'region': 'france'}
region
france
{'status': 'active'}
status
active
Fetching: https://xxx/api/dcim/devices/?limit=0&region=england&region=france&status=active&exclude=config_context
Fetching: https://xxx/api/virtualization/virtual-machines/?limit=0&region=england&region=france&status=active&exclude=config_context
  • the same query_filters sent via extra args as JSON: it does not work
query_filters: "{{ cli_filters }}"
ansible-inventory \
  -i inventories/staging \
  --extra-vars '{"cli_filters": [{"region": "england"},{"region": "france"},{"status": "active"}] }' \
  --list -vvvv

[[{'region': 'england'}, {'region': 'france'}, {'status': 'active'}]]
<bound method InventoryModule.filter_query_parameters of <ansible_collections.netbox.netbox.plugins.inventory.nb_inventory.InventoryModule object at 0x7fc31dab1cd0>>
[{'region': 'england'}, {'region': 'france'}, {'status': 'active'}]
toml declined parsing ansible/inventories/staging/_netbox.yml as it did not pass its verify_file() method
host_list declined parsing ansible/inventories/staging/_netbox.yml as it did not pass its verify_file() method
[WARNING]:  * Failed to parse ansible/inventories/staging/_netbox.yml with auto plugin: 'list' object has no attribute 'keys'
  File "ansible/.venv/lib/python3.11/site-packages/ansible/inventory/manager.py", line 293, in parse_source
    plugin.parse(self._inventory, self._loader, source, cache=cache)
  File "ansible/.venv/lib/python3.11/site-packages/ansible/plugins/inventory/auto.py", line 59, in parse
    plugin.parse(inventory, loader, path, cache=cache)
  File "ansible/.ansible/collections/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 2223, in parse
    self.main()
  File "ansible/.ansible/collections/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 2058, in main
    self.fetch_hosts()
  File "ansible/.ansible/collections/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 1781, in fetch_hosts
    device_url, vm_url = self.refresh_url()
                         ^^^^^^^^^^^^^^^^^^
  File "ansible/.ansible/collections/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 1727, in refresh_url
    device_query_parameters.extend(
  File "ansible/.ansible/collections/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 1688, in validate_query_parameter
    k = tuple(parameter.keys())[0]
              ^^^^^^^^^^^^^^
[WARNING]:  * Failed to parse ansible/inventories/staging/_netbox.yml with yaml plugin: Plugin configuration YAML file, not YAML inventory
  File "ansible/.venv/lib/python3.11/site-packages/ansible/inventory/manager.py", line 293, in parse_source
    plugin.parse(self._inventory, self._loader, source, cache=cache)
  File "ansible/.venv/lib/python3.11/site-packages/ansible/plugins/inventory/yaml.py", line 114, in parse
    raise AnsibleParserError('Plugin configuration YAML file, not YAML inventory')
  • the same query_filters sent via extra args as JSON file: it does not work
query_filters: "{{ cli_filters }}"
{
    "cli_filters": [
        {
            "region": "england"
        },
        {
            "region": "france"
        },
        {
            "status": "active"
        }
    ]
}
ansible-inventory \
  -i inventories/staging \
  --extra-vars "@test.json" \
  --list -vvvv

[[{'region': 'england'}, {'region': 'france'}, {'status': 'active'}]]
<bound method InventoryModule.filter_query_parameters of <ansible_collections.netbox.netbox.plugins.inventory.nb_inventory.InventoryModule object at 0x75c84e0c6390>>
[{'region': 'england'}, {'region': 'france'}, {'status': 'active'}]
toml declined parsing ansible/inventories/staging/_netbox.yml as it did not pass its verify_file() method
host_list declined parsing ansible/inventories/staging/_netbox.yml as it did not pass its verify_file() method
[WARNING]:  * Failed to parse ansible/inventories/staging/_netbox.yml with auto plugin: 'list' object has no attribute 'keys'
  File "ansible/.venv/lib/python3.11/site-packages/ansible/inventory/manager.py", line 293, in parse_source
    plugin.parse(self._inventory, self._loader, source, cache=cache)
  File "ansible/.venv/lib/python3.11/site-packages/ansible/plugins/inventory/auto.py", line 59, in parse
    plugin.parse(inventory, loader, path, cache=cache)
  File "ansible/.ansible/collections/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 2223, in parse
    self.main()
  File "ansible/.ansible/collections/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 2058, in main
    self.fetch_hosts()
  File "ansible/.ansible/collections/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 1781, in fetch_hosts
    device_url, vm_url = self.refresh_url()
                         ^^^^^^^^^^^^^^^^^^
  File "ansible/.ansible/collections/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 1727, in refresh_url
    device_query_parameters.extend(
  File "ansible/.ansible/collections/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 1688, in validate_query_parameter
    k = tuple(parameter.keys())[0]
              ^^^^^^^^^^^^^^
[WARNING]:  * Failed to parse ansible/inventories/staging/_netbox.yml with yaml plugin: Plugin configuration YAML file, not YAML inventory
  File "ansible/.venv/lib/python3.11/site-packages/ansible/inventory/manager.py", line 293, in parse_source
    plugin.parse(self._inventory, self._loader, source, cache=cache)
  File "ansible/.venv/lib/python3.11/site-packages/ansible/plugins/inventory/yaml.py", line 114, in parse
    raise AnsibleParserError('Plugin configuration YAML file, not YAML inventory')
  • the same query_filters sent via extra args as YAML file, variation 1: it does not work
query_filters: "{{ cli_filters }}"
---
cli_filters:
  - region: "england"
  - region: "france"
  - status: "active"
ansible-inventory \
  -i inventories/staging \
  --extra-vars "@test.yaml" \
  --list -vvvv

[[{'region': 'england'}, {'region': 'france'}, {'status': 'active'}]]
<bound method InventoryModule.filter_query_parameters of <ansible_collections.netbox.netbox.plugins.inventory.nb_inventory.InventoryModule object at 0x76e519beaf90>>
[{'region': 'england'}, {'region': 'france'}, {'status': 'active'}]
toml declined parsing ansible/inventories/staging/_netbox.yml as it did not pass its verify_file() method
host_list declined parsing ansible/inventories/staging/_netbox.yml as it did not pass its verify_file() method
[WARNING]:  * Failed to parse ansible/inventories/staging/_netbox.yml with auto plugin: 'list' object has no attribute 'keys'
  File "ansible/.venv/lib/python3.11/site-packages/ansible/inventory/manager.py", line 293, in parse_source
    plugin.parse(self._inventory, self._loader, source, cache=cache)
  File "ansible/.venv/lib/python3.11/site-packages/ansible/plugins/inventory/auto.py", line 59, in parse
    plugin.parse(inventory, loader, path, cache=cache)
  File "ansible/.ansible/collections/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 2223, in parse
    self.main()
  File "ansible/.ansible/collections/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 2058, in main
    self.fetch_hosts()
  File "ansible/.ansible/collections/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 1781, in fetch_hosts
    device_url, vm_url = self.refresh_url()
                         ^^^^^^^^^^^^^^^^^^
  File "ansible/.ansible/collections/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 1727, in refresh_url
    device_query_parameters.extend(
  File "ansible/.ansible/collections/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 1688, in validate_query_parameter
    k = tuple(parameter.keys())[0]
              ^^^^^^^^^^^^^^
[WARNING]:  * Failed to parse ansible/inventories/staging/_netbox.yml with yaml plugin: Plugin configuration YAML file, not YAML inventory
  File "ansible/.venv/lib/python3.11/site-packages/ansible/inventory/manager.py", line 293, in parse_source
    plugin.parse(self._inventory, self._loader, source, cache=cache)
  File "ansible/.venv/lib/python3.11/site-packages/ansible/plugins/inventory/yaml.py", line 114, in parse
    raise AnsibleParserError('Plugin configuration YAML file, not YAML inventory')
  • the same query_filters sent via extra args as YAML file, variation 2: it does not work
query_filters: "{{ cli_filters }}"
---
cli_filters:
  - key: region
    value: "england"
  - key: region
    value: "france"
  - key: status
    value: "active"
ansible-inventory \
  -i inventories/staging \
  --extra-vars "@test.yaml" \
  --list -vvvv


[[{'key': 'region', 'value': 'england'}, {'key': 'region', 'value': 'france'}, {'key': 'status', 'value': 'active'}]]
<bound method InventoryModule.filter_query_parameters of <ansible_collections.netbox.netbox.plugins.inventory.nb_inventory.InventoryModule object at 0x755e78ce6050>>
[{'key': 'region', 'value': 'england'}, {'key': 'region', 'value': 'france'}, {'key': 'status', 'value': 'active'}]
toml declined parsing ansible/inventories/staging/_netbox.yml as it did not pass its verify_file() method
host_list declined parsing ansible/inventories/staging/_netbox.yml as it did not pass its verify_file() method
[WARNING]:  * Failed to parse ansible/inventories/staging/_netbox.yml with auto plugin: 'list' object has no attribute 'keys'
  File "ansible/.venv/lib/python3.11/site-packages/ansible/inventory/manager.py", line 293, in parse_source
    plugin.parse(self._inventory, self._loader, source, cache=cache)
  File "ansible/.venv/lib/python3.11/site-packages/ansible/plugins/inventory/auto.py", line 59, in parse
    plugin.parse(inventory, loader, path, cache=cache)
  File "ansible/.ansible/collections/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 2223, in parse
    self.main()
  File "ansible/.ansible/collections/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 2058, in main
    self.fetch_hosts()
  File "ansible/.ansible/collections/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 1781, in fetch_hosts
    device_url, vm_url = self.refresh_url()
                         ^^^^^^^^^^^^^^^^^^
  File "ansible/.ansible/collections/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 1727, in refresh_url
    device_query_parameters.extend(
  File "ansible/.ansible/collections/ansible_collections/netbox/netbox/plugins/inventory/nb_inventory.py", line 1688, in validate_query_parameter
    k = tuple(parameter.keys())[0]
              ^^^^^^^^^^^^^^
[WARNING]:  * Failed to parse ansible/inventories/staging/_netbox.yml with yaml plugin: Plugin configuration YAML file, not YAML inventory
  File "ansible/.venv/lib/python3.11/site-packages/ansible/inventory/manager.py", line 293, in parse_source
    plugin.parse(self._inventory, self._loader, source, cache=cache)
  File "ansible/.venv/lib/python3.11/site-packages/ansible/plugins/inventory/yaml.py", line 114, in parse
    raise AnsibleParserError('Plugin configuration YAML file, not YAML inventory')
  • the same query_filters sent via extra args as YAML file, variation 3: it does not work fully (only 1 filter accepted)
query_filters: "{{ cli_filters }}"
---
cli_filters:
  region: "england"
  region: "france"
  status: "active"
ansible-inventory \
  -i inventories/staging \
  --extra-vars "@test.yaml" \
  --list -vvvv

[WARNING]: While constructing a mapping from ansible/test.yaml, line 3, column 3, found a duplicate dict key (region). Using last defined value only.
Fetching: https://xxx/api/status/
[{'region': 'france', 'status': 'active'}]
<bound method InventoryModule.filter_query_parameters of <ansible_collections.netbox.netbox.plugins.inventory.nb_inventory.InventoryModule object at 0x7454b1bb15d0>>
{'region': 'france', 'status': 'active'}
region
france
{'region': 'france', 'status': 'active'}
region
france
Fetching: https://xxx/api/dcim/devices/?limit=0&region=france&exclude=config_context
Fetching: https://xxx/api/virtualization/virtual-machines/?limit=0&region=france&exclude=config_context

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