netbox-community / ansible_modules

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

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

Open mkurjanski opened 1 year ago

mkurjanski commented 1 year 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 1 year 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 1 year 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 1 year ago

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