ansible_modules
ansible_modules copied to clipboard
[Bug]: netbox_module returns error "More than one result returned for module_bay"
Ansible NetBox Collection version
v3.19.1
Ansible version
ansible [core 2.17.0]
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/foouser/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/foouser/ansible/lib/python3.10/site-packages/ansible
ansible collection location = /home/foouser/.ansible/collections:/usr/share/ansible/collections
executable location = /home/foouser/ansible/bin/ansible
python version = 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] (/home/foouser/ansible/bin/python3)
jinja version = 3.1.2
libyaml = True
NetBox version
v3.7.3
Python version
3.10
Steps to Reproduce
I hope this is not a misunderstanding. In the past I've wanted to use netbox ansible modules to 'insert' a module into a module bay on a device. And while we could create a module_bay and a module_type, there wasn't such functionality. I did it using the URI module, but it of course required some additional logic and was not idempotent without further steps. I perused updates and see the new (to me) netbox_module.
I spin up a playbook to test this as I am doing more of this sort of work this week. I've been modeling my Dell servers with a module bay called network card bay. This allows me to have the same model of server but to account for the fact that one might have been ordered with an installed 4 port Gb integrated NIC, whilst another might have pair of 10Gb SFP+ ports and a pair of gigabit. I poll the host during discovery, add the correct module, which then populates the appropriate network interfaces and such. Example playbook sanitized of details:
- name: Update network card module in host
hosts: localhost
gather_facts: false
tasks:
- name: Set facts
set_fact:
netbox_url: https://netbox.host
netbox_token: redactedTokenStringfoobar
- name: Update network bay module
netbox.netbox.netbox_module:
netbox_url: "{{ netbox_url }}"
netbox_token: "{{ netbox_token }}"
data:
device:
name: foo-device
module_bay:
name: network card bay
module_type:
manufacturer: Dell
model: 4Gb NIC
status: active
state: present
Expected Behavior
I expected to see a Changed outcome to my playbook results and foo-device updated in network to now have a 4-port gigabit integrated network card, along with the new network interfaces.
Observed Behavior
My original problem was that I got state is present but all of the following are missing: status. I found this odd as I needed to have state present in my playbook to indicate whether or not the module should be in the given module bay. Status was not listed as a required field so I left it out originally. In Netbox 3.X there is no status to a module. I put the status as active and re-ran the playbook. Now I get the error More than one result returned for module_bay. This took me a bit to understand as I interpreted it to mean it searched all of the modules bays in foo-device and it found multiple with the name network card bay. That wasn't the case, of course. It wasn't until later that I realized looking through my nginx logs that theres a search for device with name foo-device and then a search for all module_bays with the name network card bay.
::ffff:192.168.1.1 - - [DATESTAMP] "GET /api/dcim/devices/?name=foo-dev&limit=0 HTTP/1.1" 200 2562 "-" "python-requests/2.31.0"
::ffff:192.168.1.1 - - [DATESTAMP] "GET /api/dcim/module-bays/?name=network+card+bay&limit=0 HTTP/1.1" 200 80993 "-" "python-requests/2.31.0"
I find this odd because, at least this is how I do it, I add module bays to device templates. I have one for iDRAC, a network card bay for the integrated NIC ordered for the machine. PCI slots. PSU slots. But they all have the same names in every device of that device type. Its network card bay not hostname's network card bay.
But that appears to be the source of the error, it's returning hundreds of results because I use that same module bay naming on every Dell server, regardless of model. But I've given it the host I am using.
I am unable to test against a Netbox 4.x server because of a different problem I am having. There I get Failed to establish connection to NetBox API when I talk to my 4.x dev server. Not sure why, the same token works from Postman. Added my $.02 to another open issue about this.
To add to my earlier comment, I noticed module status in my 3.x installation, just not as 'up front' as it is in 4.x. The module documentation should be updated to say its a required field. Original, main issue of the module not working remains.
Here to report the same issue. I have all my module bays listed the same for easy automation.
But found out that the module plugin searches all module bays before checking which device.
So messing around with netbox's API I figured a way to get netbox to use a device specific module bay.
Not sure if this will work in the ansible galaxy collection
module_bay:
name: network card bay
device__name: foo-device
I have an identical scenario - adding modules to a Dell server and experience the same error using collection netbox.netbox:3.20.0 The workaround for adding the device__name to the module_bay does not work for me. Netbox v4.1.6
But passing the device rather than the device__name into the module_bay did work:
module_bay:
name: network card bay
device: foo-device
But passing the device rather than the device__name into the module_bay did work:
module_bay: name: network card bay device: foo-device
Well, it worked also in ansible, thank you. The question is, if this is expected behavior. For those using ansible:
Not working:
patch_modules:
- {status: active, device: testpatch, module_bay: Slot, module_type: MOD-MM-24LC-2, description: , comments: , asset_tag: , serial: }
Working yaml.
patch_modules:
- {status: active, device: testpatch, module_bay: {device: testpatch, name: Slot}, module_type: MOD-MM-24LC-2, description: , comments: , asset_tag: , serial: }
Not sure if someone can give me a working example ?
I have this and it returns the error of More than one result returned for module_bay:
- name: Update module bay information
netbox.netbox.netbox_module:
netbox_url: "{{ lookup('env', 'NETBOX_URL') }}"
netbox_token: "{{ lookup('env', 'NETBOX_TOKEN') }}"
data:
device: "{{ item.server_name }}" # device name
module_bay: "{{ item.bay_number }}" # name of module bay
module_type: "{{ item.module_type }}" # # the type eg Add-on Card AOC...
status: "active"
state: present
loop: "{{ module_bays_list }}"
I found a way to make it work for me, I needed the device name as part of the module_bay information.
Like this:
- name: Update module bay information
netbox.netbox.netbox_module:
netbox_url: "{{ lookup('env', 'NETBOX_URL') }}"
netbox_token: "{{ lookup('env', 'NETBOX_TOKEN') }}"
data:
device: "{{ item.server_name }}"
module_bay:
name: "{{ item.bay_number }}"
device: "{{ item.server_name }}"
module_type: "{{ item.module_type }}"
status: "active"
state: present
loop: "{{ module_bays_list }}"