netbox-community / ansible_modules

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

List of VLANs sent as extra-var for tagged_vlans in netbox_device_interface module will only pass last VLAN on the interface #478

Closed baburciu closed 2 years ago

baburciu commented 3 years ago
ISSUE TYPE
SOFTWARE VERSIONS
Ansible:

ansible 2.9.19rc1

Netbox:

v2.10.6

Collection:

3.0.0

SUMMARY

Cannot use module _netbox_deviceinterface to pass multiple VLANs as allowed (tagged) on an interface. Regardless of how many VLANs are sent in list, only the last one will be applied. Similarly, passing first VLAN x as extra-var when running playbook, then passing VLAN y and running playbook again, will result in only VLAN y being showed as tagged under interface. Same is valid for Ansible module collection version 2.0.0, NetBox instance v2.10.3, with ansible 2.10.3.

STEPS TO REPRODUCE

Use the below playbook and run it with ansible-playbook -i ./hosts -v update_interface.yml -e 'dot1q_mode="Tagged" tagged_vlan_id=["204","206","480"] interface_name="10GE1/0/1" interface_device="SWH-OoB-R2" ansible_python_interpreter="/usr/bin/python3" url_var="http://192.168.200.23:8001/" token_var="fe08a748abf3eb828203536f35e411fc8fbf8f9c"' -vv.

boburciu@WX-5CG020BDT2:~/netbox-ansible-automation$ cat hosts

docker_netbox_19216820023 ansible_host=192.168.200.23

boburciu@WX-5CG020BDT2:~/netbox-ansible-automation$ cat update_interface.yml
# ~/netbox-ansible-automation/update_interface.yml

- name: Update interface with LAG and VLAN IDs
  connection: local
  hosts: docker_netbox_19216820023
  gather_facts: False
  collections:
    - netbox.netbox 
  tasks:
    - name: Update interface with tagged VLAN ID and trunk mode
      netbox_device_interface:
        netbox_url: '{{ url_var }}'
        netbox_token: '{{ token_var }}'
        data:
          device: '{{ interface_device }}'
          name: '{{ interface_name }}'
          mode: '{{ dot1q_mode }}'
          tagged_vlans: '{{ tagged_vlan_id }}'
        state: present
      when: tagged_vlan_id is defined 

    - name: Obtain the interface we've changed
      debug:
        msg: >
          "Interace in NetBox: {{ item }}"
      loop: "{{ query('netbox.netbox.nb_lookup', 'interfaces',
                      api_endpoint='http://192.168.200.23:8001/',
                      api_filter='name=10GE1/0/1 device=SWH-OoB-R2',
                      token='fe08a748abf3eb828203536f35e411fc8fbf8f9c') }}"
EXPECTED RESULTS

If I understand correctly the docs, you'd expect to see VLANs "204", "206" & "480" as tagged under interface 10GE1/0/1 of device SWH-OoB-R2.

ACTUAL RESULTS
TASK [Update interface with tagged VLAN ID and trunk mode] **************************************************************
task path: /home/boburciu/netbox-ansible-automation/update_interface.yml:55
:
changed: [docker_netbox_19216820023] => {
    "changed": true,
    "diff": {
        "after": {
            "tagged_vlans": [
                101,
                101,
                101
            ]
        },
        "before": {
            "tagged_vlans": [
                101
            ]
        }
    },
    "interface": {
        "cable": null,
        "cable_peer": null,
        "cable_peer_type": null,
        "connected_endpoint": null,
        "connected_endpoint_reachable": null,
        "connected_endpoint_type": null,
        "count_ipaddresses": 0,
        "description": "",
        "device": 273,
        "enabled": true,
        "id": 967,
        "label": "",
        "lag": 968,
        "mac_address": "48:F8:DB:D4:AB:11",
        "mgmt_only": false,
        "mode": "tagged-all",
        "mtu": 9216,
        "name": "10GE1/0/1",
        "tagged_vlans": [
            101
        ],
        "tags": [],
        "type": "10gbase-t",
        "untagged_vlan": null,
        "url": "http://192.168.200.23:8001/api/dcim/interfaces/967/"
    },
    "invocation": {
        "module_args": {
            "data": {
                "description": null,
                "device": "SWH-OoB-R2",
                "enabled": null,
                "form_factor": null,
                "lag": null,
                "mac_address": null,
                "mgmt_only": null,
                "mode": "Tagged",
                "mtu": null,
                "name": "10GE1/0/1",
                "tagged_vlans": [
                    "204",
                    "206",
                    "480"
                ],
                "tags": null,
                "type": null,
                "untagged_vlan": null
            },
            "netbox_token": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "netbox_url": "http://192.168.200.23:8001/",
            "query_params": null,
            "state": "present",
            "update_vc_child": false,
            "validate_certs": true
        }
    },
    "msg": "interface 10GE1/0/1 updated"
}

TASK [Obtain the interface we've changed] *******************************************************************************
task path: /home/boburciu/netbox-ansible-automation/update_interface.yml:67
ok: [docker_netbox_19216820023] => (item={'key': 967, 'value': {'id': 967, 'url': 'http://192.168.200.23:8001/api/dcim/interfaces/967/', 'device': {'id': 273, 'url': 'http://192.168.200.23:8001/api/dcim/devices/273/', 'name': 'SWH-OoB-R2', 'display_name': 'SWH-OoB-R2'}, 'name': '10GE1/0/1', 'label': '', 'type': {'value': '10gbase-t', 'label': '10GBASE-T (10GE)'}, 'enabled': True, 'lag': {'id': 968, 'url': 'http://192.168.200.23:8001/api/dcim/interfaces/968/', 'device': {'id': 273, 'url': 'http://192.168.200.23:8001/api/dcim/devices/273/', 'name': 'SWH-OoB-R2', 'display_name': 'SWH-OoB-R2'}, 'name': 'Eth-Trunk3', 'cable': None}, 'mtu': 9216, 'mac_address': '48:F8:DB:D4:AB:11', 'mgmt_only': False, 'description': '', 'mode': {'value': 'tagged-all', 'label': 'Tagged'}, 'untagged_vlan': None, **'tagged_vlans': [{'id': 101, 'url': 'http://192.168.200.23:8001/api/ipam/vlans/101/', 'vid': 480, 'name': '480', 'display_name': '480 (480)'}]**, 'cable': None, 'cable_peer': None, 'cable_peer_type': None, 'connected_endpoint': None, 'connected_endpoint_type': None, 'connected_endpoint_reachable': None, 'tags': [], 'count_ipaddresses': 0}}) => {
    "msg": "\"Interace in NetBox: {'key': 967, 'value': {'id': 967, 'url': 'http://192.168.200.23:8001/api/dcim/interfaces/967/', 'device': {'id': 273, 'url': 'http://192.168.200.23:8001/api/dcim/devices/273/', 'name': 'SWH-OoB-R2', 'display_name': 'SWH-OoB-R2'}, 'name': '10GE1/0/1', 'label': '', 'type': {'value': '10gbase-t', 'label': '10GBASE-T (10GE)'}, 'enabled': True, 'lag': {'id': 968, 'url': 'http://192.168.200.23:8001/api/dcim/interfaces/968/', 'device': {'id': 273, 'url': 'http://192.168.200.23:8001/api/dcim/devices/273/', 'name': 'SWH-OoB-R2', 'display_name': 'SWH-OoB-R2'}, 'name': 'Eth-Trunk3', 'cable': None}, 'mtu': 9216, 'mac_address': '48:F8:DB:D4:AB:11', 'mgmt_only': False, 'description': '', 'mode': {'value': 'tagged-all', 'label': 'Tagged'}, 'untagged_vlan': None, **'tagged_vlans': [{'id': 101, 'url': 'http://192.168.200.23:8001/api/ipam/vlans/101/', 'vid': 480, 'name': '480', 'display_name': '480 (480)'}]**, 'cable': None, 'cable_peer': None, 'cable_peer_type': None, 'connected_endpoint': None, 'connected_endpoint_type': None, 'connected_endpoint_reachable': None, 'tags': [], 'count_ipaddresses': 0}}\"\n"
}

__

rhyser9 commented 3 years ago

Encountered this today (Netbox v2.11.6, netbox.netbox v3.1.1, Ansible 2.10.9) and after some brief testing this seems to occur when passing a list of strings like VIDs or VLAN names (i.e. tagged_vlans: [ '150', '200' ] or tagged_vlans: [ 'DC1_PXE', 'DC1_Storage' ]). If, however, the integer primary keys of the VLAN objects -- not the VIDs -- are directly passed (i.e. tagged_vlans: [ 7, 21 ]), then all of the VLANs are correctly assigned to the interface.

rodvand commented 2 years ago

As far as my understanding is here, this seems like it's working as expected. Let me know if I'm misunderstanding it.