netbox-community / ansible_modules

NetBox modules for Ansible using Ansible Collections
GNU General Public License v3.0
320 stars 205 forks source link

[Bug]: netbox.netbox.netbox_device - idempotency issue with custom_fields #1108

Open mkurjanski opened 10 months ago

mkurjanski commented 10 months ago

Ansible NetBox Collection version

v3.13

Ansible version

ansible [core 2.13.11]
  config file = /home/mateusz.kurjanski/repos/pico1.0-device-onboarding/ansible.cfg
  configured module search path = ['/home/mateusz.kurjanski/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/mateusz.kurjanski/repos/niac/lib/python3.8/site-packages/ansible
  ansible collection location = /home/mateusz.kurjanski/repos/pico1.0-device-onboarding/collections
  executable location = /home/mateusz.kurjanski/repos/niac/bin/ansible
  python version = 3.8.10 (default, May 26 2023, 14:05:08) [GCC 9.4.0]
  jinja version = 3.1.2
  libyaml = True

NetBox version

v3.4.4

Python version

3.8

Steps to Reproduce

When you use netbox.netbox.netbox_device with state 'present' and 'custom_fields' input parameters defined, the module will always report the 'changed' state, even when the custom_fields already exist and no actual change was done.

Similarly, on the Netbox side there is a new changelog entry created for the device, even though the pre-change and post-change data is the same.

Expected Behavior

netbox.netbox.netbox_device should not report a change in custom field data if there was not real change done

Observed Behavior

    "output": {
        "changed": true,
        "device": {
        ...
        },
        "diff": {
            "after": {
                "custom_fields": {
                    "device_asn": "275",
                    "device_os_version": "4.28.6.1M"
                }
            },
            "before": {
                "custom_fields": {
                    "device_asn": 275,
                    "device_os_version": "4.28.6.1M"
                }
            }
        },
        "failed": false,
        "msg": "device <redacted> updated"
    }
eliezerlp commented 10 months ago

I did notice that the before is an integer "device_asn": 275 while the after is a string "device_asn": "275".

A couple of relevant questions:

mkurjanski commented 10 months ago

Hi @eliezerlp - thanks for spotting this. device_asn is an object-type custom field, so the integer references the linked object ID, in my case this is an ID of ipam.asn object (which is an integer in netbox)

So I'm guessing netbox.netbox.netbox_device takes 'custom_fields' which is type dict, but it assumes all keys and values in the dict must be strings? I'm feeding it an integer which is accepted and processed, but it breaks idempotency. I'd need to re-test and check the behaviour when the input custom field value is provided as a string.

rodvand commented 10 months ago

Have a look at https://github.com/netbox-community/ansible_modules/issues/985#issuecomment-1526050665