netbox-community / ansible_modules

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

[Bug]: Idempotence Issue in netbox.netbox.netbox_cable Module with connection betwin console port and console server port #1217

Open Cyrilpop opened 4 months ago

Cyrilpop commented 4 months ago

Ansible NetBox Collection version

3.15.0

Ansible version

ansible [core 2.14.2]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.11/site-packages/ansible
  ansible collection location = /usr/share/ansible/ansible_collections
  executable location = /usr/bin/ansible
  python version = 3.11.2 (main, Feb 17 2023, 09:28:16) [GCC 8.5.0 20210514 (Red Hat 8.5.0-18)] (/usr/bin/python3.11)
  jinja version = 3.1.2
  libyaml = True

NetBox version

3.6.5

Python version

3.11

Steps to Reproduce

Create de tasks :

    - name: "[CABLES] Création des interconnexions entre les devices"
      netbox.netbox.netbox_cable:
        data:
          termination_a_type: "{{ item.termination_a_type }}"
          termination_a:
            device: "{{ item.termination_a }}"
            name: "{{ item.termination_a_name }}"
          termination_b_type: "{{ item.termination_b_type }}"
          termination_b:
            device: "{{ item.termination_b }}"
            name: "{{ item.termination_b_name }}"
          tenant: "{{ item.tenant }}"
          type: "{{ item.type }}"
          tags: "{{ item.tags }}"
        state: present
      loop: "{{ cables }}"

with variables :

cables:
  - termination_a: STG-firewall-1
    termination_a_name: console
    termination_a_type: dcim.consoleport
    termination_b: STG-Load-Balancer-1
    termination_b_name: port 1
    termination_b_type: dcim.consoleserverport
    type: mmf
    tenant: stg-tenant
    tags: [ stg-tag ]

The first time everything is OK :

changed: [localhost] => (item=Branchement entre STG-firewall-1 (console) et STG-Load-Balancer-1 (port 1)) => changed=true
  ansible_loop_var: item
  cable:
    a_terminations:
    - 49
    b_terminations:
    - 49
    color: ''
    comments: ''
    created: '2024-04-24T10:58:37.475256+02:00'
    custom_fields: {}
    description: ''
    display: '#103'
    id: 103
    label: ''
    last_updated: '2024-04-24T10:58:37.475273+02:00'
    length: null
    length_unit: null
    status: connected
    tags:
    - 40
    tenant: 12
    type: mmf
    url: http://127.0.0.1:8001/api/dcim/cables/103/
  diff:
    after:
      state: present
    before:
      state: absent
  invocation:
    module_args:
      cert: null
      data:
        color: null
        comments: null
        custom_fields: null
        description: null
        label: null
        length: null
        length_unit: null
        status: null
        tags:
        - stg-tag
        tenant: stg-tenant
        termination_a:
          device: STG-firewall-1
          name: console
        termination_a_type: dcim.consoleport
        termination_b:
          device: STG-Load-Balancer-1
          name: port 1
        termination_b_type: dcim.consoleserverport
        type: mmf
      netbox_token: VALUE_SPECIFIED_IN_NO_LOG_PARAMETER
      netbox_url: http://127.0.0.1:8001
      query_params: null
      state: present
      validate_certs: true
  item:
    tags:
    - stg-tag
    tenant: stg-tenant
    termination_a: STG-firewall-1
    termination_a_name: console
    termination_a_type: dcim.consoleport
    termination_b: STG-Load-Balancer-1
    termination_b_name: port 1
    termination_b_type: dcim.consoleserverport
    type: mmf
  msg: cable dcim.consoleport console <> dcim.consoleserverport port 1 created

And the others every thing is KO

The full traceback is:
Traceback (most recent call last):
  File "/home/netbox/.ansible/tmp/ansible-tmp-1713949829.866893-2860074-121097859752944/AnsiballZ_netbox_cable.py", line 107, in <module>
    _ansiballz_main()
  File "/home/netbox/.ansible/tmp/ansible-tmp-1713949829.866893-2860074-121097859752944/AnsiballZ_netbox_cable.py", line 99, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/home/netbox/.ansible/tmp/ansible-tmp-1713949829.866893-2860074-121097859752944/AnsiballZ_netbox_cable.py", line 47, in invoke_module
    runpy.run_module(mod_name='ansible_collections.netbox.netbox.plugins.modules.netbox_cable', init_globals=dict(_module_fqn='ansible_collections.netbox.netbox.plugins.modules.netbox_cable', _modlib_path=modlib_path),
  File "<frozen runpy>", line 226, in run_module
  File "<frozen runpy>", line 98, in _run_module_code
  File "<frozen runpy>", line 88, in _run_code
  File "/tmp/ansible_netbox.netbox.netbox_cable_payload_x7og9fet/ansible_netbox.netbox.netbox_cable_payload.zip/ansible_collections/netbox/netbox/plugins/modules/netbox_cable.py", line 371, in <module>
  File "/tmp/ansible_netbox.netbox.netbox_cable_payload_x7og9fet/ansible_netbox.netbox.netbox_cable_payload.zip/ansible_collections/netbox/netbox/plugins/modules/netbox_cable.py", line 367, in main
  File "/tmp/ansible_netbox.netbox.netbox_cable_payload_x7og9fet/ansible_netbox.netbox.netbox_cable_payload.zip/ansible_collections/netbox/netbox/plugins/module_utils/netbox_dcim.py", line 225, in run
  File "/tmp/ansible_netbox.netbox.netbox_cable_payload_x7og9fet/ansible_netbox.netbox.netbox_cable_payload.zip/ansible_collections/netbox/netbox/plugins/module_utils/netbox_utils.py", line 1451, in _ensure_object_exists
  File "/tmp/ansible_netbox.netbox.netbox_cable_payload_x7og9fet/ansible_netbox.netbox.netbox_cable_payload.zip/ansible_collections/netbox/netbox/plugins/module_utils/netbox_utils.py", line 1402, in _update_netbox_object
  File "/tmp/ansible_netbox.netbox.netbox_cable_payload_x7og9fet/ansible_netbox.netbox.netbox_cable_payload.zip/ansible_collections/netbox/netbox/plugins/module_utils/netbox_utils.py", line 1395, in _convert_termination
  File "/tmp/ansible_netbox.netbox.netbox_cable_payload_x7og9fet/ansible_netbox.netbox.netbox_cable_payload.zip/ansible_collections/netbox/netbox/plugins/module_utils/netbox_utils.py", line 1127, in _find_app
Exception: console-ports not found in API_APPS_ENDPOINTS
failed: [localhost] (item=Branchement entre STG-firewall-1 (console) et STG-Load-Balancer-1 (port 1)) => changed=false
  ansible_loop_var: item
  item:
    tags:
    - stg-tag
    tenant: stg-tenant
    termination_a: STG-firewall-1
    termination_a_name: console
    termination_a_type: dcim.consoleport
    termination_b: STG-Load-Balancer-1
    termination_b_name: port 1
    termination_b_type: dcim.consoleserverport
    type: mmf
  module_stderr: |-
    Traceback (most recent call last):
      File "/home/netbox/.ansible/tmp/ansible-tmp-1713949829.866893-2860074-121097859752944/AnsiballZ_netbox_cable.py", line 107, in <module>
        _ansiballz_main()
      File "/home/netbox/.ansible/tmp/ansible-tmp-1713949829.866893-2860074-121097859752944/AnsiballZ_netbox_cable.py", line 99, in _ansiballz_main
        invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
      File "/home/netbox/.ansible/tmp/ansible-tmp-1713949829.866893-2860074-121097859752944/AnsiballZ_netbox_cable.py", line 47, in invoke_module
        runpy.run_module(mod_name='ansible_collections.netbox.netbox.plugins.modules.netbox_cable', init_globals=dict(_module_fqn='ansible_collections.netbox.netbox.plugins.modules.netbox_cable', _modlib_path=modlib_path),
      File "<frozen runpy>", line 226, in run_module
      File "<frozen runpy>", line 98, in _run_module_code
      File "<frozen runpy>", line 88, in _run_code
      File "/tmp/ansible_netbox.netbox.netbox_cable_payload_x7og9fet/ansible_netbox.netbox.netbox_cable_payload.zip/ansible_collections/netbox/netbox/plugins/modules/netbox_cable.py", line 371, in <module>
      File "/tmp/ansible_netbox.netbox.netbox_cable_payload_x7og9fet/ansible_netbox.netbox.netbox_cable_payload.zip/ansible_collections/netbox/netbox/plugins/modules/netbox_cable.py", line 367, in main
      File "/tmp/ansible_netbox.netbox.netbox_cable_payload_x7og9fet/ansible_netbox.netbox.netbox_cable_payload.zip/ansible_collections/netbox/netbox/plugins/module_utils/netbox_dcim.py", line 225, in run
      File "/tmp/ansible_netbox.netbox.netbox_cable_payload_x7og9fet/ansible_netbox.netbox.netbox_cable_payload.zip/ansible_collections/netbox/netbox/plugins/module_utils/netbox_utils.py", line 1451, in _ensure_object_exists
      File "/tmp/ansible_netbox.netbox.netbox_cable_payload_x7og9fet/ansible_netbox.netbox.netbox_cable_payload.zip/ansible_collections/netbox/netbox/plugins/module_utils/netbox_utils.py", line 1402, in _update_netbox_object
      File "/tmp/ansible_netbox.netbox.netbox_cable_payload_x7og9fet/ansible_netbox.netbox.netbox_cable_payload.zip/ansible_collections/netbox/netbox/plugins/module_utils/netbox_utils.py", line 1395, in _convert_termination
      File "/tmp/ansible_netbox.netbox.netbox_cable_payload_x7og9fet/ansible_netbox.netbox.netbox_cable_payload.zip/ansible_collections/netbox/netbox/plugins/module_utils/netbox_utils.py", line 1127, in _find_app
    Exception: console-ports not found in API_APPS_ENDPOINTS
  module_stdout: ''
  msg: |-
    MODULE FAILURE
    See stdout/stderr for the exact error
  rc: 1

Expected Behavior

When the module is executed multiple times, if the connection does not exist, it is created. If the module is rerun, the connection should either be updated if it has changed, or skipped if it already exists and is up to date.

Observed Behavior

When the module is first executed, the cable and the connection are successfully created. However, subsequent executions of the module result in a failure. It is unable to maintain idempotence when executed multiple times. Therefore, an error occurs if the connection already exists.

Cyrilpop commented 4 months ago

Temporary workaround solution: Perform deletion before insertion.