Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TASK Add NDFC Fabric Devices <name> fails for IPv6 Devices #251

Open
marehler opened this issue Dec 13, 2024 · 4 comments
Open

TASK Add NDFC Fabric Devices <name> fails for IPv6 Devices #251

marehler opened this issue Dec 13, 2024 · 4 comments
Labels
bug Something isn't working

Comments

@marehler
Copy link

marehler commented Dec 13, 2024

Ansible Version

ansible [core 2.17.0]

Ansible Collection Versions

Collection                               Version
---------------------------------------- -------
ansible.netcommon                        5.3.0  
ansible.posix                            1.5.4  
ansible.utils                            2.11.0 
cisco.dcnm                               3.5.0  
cisco.nac_dc_vxlan                       0.3.0  
cisco.nxos                               5.3.0  
community.general                        8.5.0

Cisco NDFC Version

12.2.2

Cisco NX-OS Version

10.3(6)

Which role is this issue related to?

cisco.nac_dc_vxlan.dtc.create

Which section of the data model is this issue related to?

vxlan.topology

Expected Behavior

Devices with IPv6 management addresses are discovered.

Actual Behavior

ansible-playbook -i inventory.yaml deploy.yaml

<...>

TASK [cisco.nac_dc_vxlan.create : Add NDFC Fabric Devices VXLAN-FABRIC-2] ***********************************************************************
task path: /Users/marehler/nac-vxlan/ansible-dc-vxlan-example/collections/ansible_collections/cisco/nac_dc_vxlan/roles/dtc/create/tasks/devices_discovery.yml:24
[WARNING]: Managing fabric switches can take a while.  Please be patient...
fatal: [marehler_vnd3]: FAILED! => {"changed": false, "module_stderr": "'int' object is not subscriptable", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error"}

Ansible Playbook

---
# This is the main entry point playbook for calling the various roles in this collection.
- hosts: marehler_vnd3
  any_errors_fatal: true
  gather_facts: no

  roles:
    # -----------------------
    # DataCenter Roles
    #   Role: cisco.netascode_dc_vxlan.dtc manages NDFC workflows
    #
    - role: cisco.nac_dc_vxlan.dtc.create
    - role: cisco.nac_dc_vxlan.dtc.deploy
    - role: cisco.nac_dc_vxlan.dtc.remove

Steps to Reproduce

Use a topology with IPv6 management addresses only. Example topology_switches.yaml:

---
vxlan:
  topology:
    switches:
      - name: N9Kv-SPINE3
        role: spine
        serial_number: 940TOBQT4KY
        management:
          management_ipv6_address: 2001:420:448b:8006:fab2::13
          default_gateway_v6: 2001:420:448b:8006::1
        routing_loopback_id: 0
        interfaces:
          - name: Ethernet1/3
            mode: routed
            enabled: false
          - name: Ethernet1/4
            mode: routed
            enabled: false
          - name: Ethernet1/5
            mode: routed
            enabled: false

      - name: N9Kv-LEAF3
        role: leaf
        serial_number: 9P6ZZVYAHFR
        management:
          management_ipv6_address: 2001:420:448b:8006:fab2::23
          default_gateway_v6: 2001:420:448b:8006::1
        routing_loopback_id: 0
        vtep_loopback_id: 1
        interfaces:
          - name: Ethernet1/2
            mode: routed
            enabled: false
          - name: Ethernet1/3
            mode: routed
            enabled: false
          - name: Ethernet1/4
            mode: routed
            enabled: false
          - name: Ethernet1/5
            mode: routed
            enabled: false

      - name: N9Kv-LEAF4
        role: leaf
        serial_number: 9IT4QPTZ8QB
        management:
          management_ipv6_address: 2001:420:448b:8006:fab2::24
          default_gateway_v6: 2001:420:448b:8006::1
        routing_loopback_id: 0
        vtep_loopback_id: 1
        interfaces:
          - name: Ethernet1/2
            mode: routed
            enabled: false
          - name: Ethernet1/3
            mode: routed
            enabled: false
          - name: Ethernet1/4
            mode: routed
            enabled: false
          - name: Ethernet1/5
            mode: routed
            enabled: false

    fabric_links:
      - source_device: N9Kv-SPINE3
        source_interface: eth1/1
        dest_device: N9Kv-LEAF3
        dest_interface: eth1/1
      - source_device: N9Kv-SPINE3
        source_interface: eth1/2
        dest_device: N9Kv-LEAF4
        dest_interface: eth1/1

This is a bug of the cisco.dcnm.dcnm_inventory module. Discovery using IPv6 management addresses works fine via the NDFC GUI as well as via API.

Relevant Debug Output

No response

@marehler marehler added the bug Something isn't working label Dec 13, 2024
@marehler
Copy link
Author

cisco.dcnm.dcnm_inventory fails in 'def get_diff_merge()' in line 905:

match = re.search(r"\S+\((\S+)\)", want_c["switches"][0]["deviceIndex"])

In case of IPv6 addresses, 'want_c["switches"]' is 0:

[{'seedIP': '2001:420:448b:8006:fab2::13', 'snmpV3AuthProtocol': 0, 'username': 'admin', 'password': 'C1sco123', 'maxHops': 0, 'cdpSecondTimeout': '5', 'role': 'spine', 'preserveConfig': False, 'switches': 0}, {'seedIP': '2001:420:448b:8006:fab2::23', 'snmpV3AuthProtocol': 0, 'username': 'admin', 'password': 'C1sco123', 'maxHops': 0, 'cdpSecondTimeout': '5', 'role': 'leaf', 'preserveConfig': False, 'switches': 0}, {'seedIP': '2001:420:448b:8006:fab2::24', 'snmpV3AuthProtocol': 0, 'username': 'admin', 'password': 'C1sco123', 'maxHops': 0, 'cdpSecondTimeout': '5', 'role': 'leaf', 'preserveConfig': False, 'switches': 0}]

In case of IPv4 addresses, 'want_c["switches"]' contains a list of switches as expected:

[{'seedIP': '22.1.172.13', 'snmpV3AuthProtocol': 0, 'username': 'admin', 'password': 'C1sco123', 'maxHops': 0, 'cdpSecondTimeout': '5', 'role': 'spine', 'preserveConfig': False, 'switches': [{'reachable': False, 'auth': False, 'known': False, 'valid': False, 'selectable': False, 'sysName': '22.1.172.13', 'serialNumber': None, 'vdcMac': None, 'vdcId': 0, 'ipaddr': '22.1.172.13', 'platform': None, 'version': None, 'lastChange': None, 'hopCount': 0, 'deviceIndex': '22.1.172.13', 'statusReason': 'not reachable', 'vendor': None, 'switchRole': None}]}, {'seedIP': '22.1.172.23', 'snmpV3AuthProtocol': 0, 'username': 'admin', 'password': 'C1sco123', 'maxHops': 0, 'cdpSecondTimeout': '5', 'role': 'leaf', 'preserveConfig': False, 'switches': [{'reachable': False, 'auth': False, 'known': False, 'valid': False, 'selectable': False, 'sysName': '22.1.172.23', 'serialNumber': None, 'vdcMac': None, 'vdcId': 0, 'ipaddr': '22.1.172.23', 'platform': None, 'version': None, 'lastChange': None, 'hopCount': 0, 'deviceIndex': '22.1.172.23', 'statusReason': 'not reachable', 'vendor': None, 'switchRole': None}]}, {'seedIP': '22.1.172.24', 'snmpV3AuthProtocol': 0, 'username': 'admin', 'password': 'C1sco123', 'maxHops': 0, 'cdpSecondTimeout': '5', 'role': 'leaf', 'preserveConfig': False, 'switches': [{'reachable': False, 'auth': False, 'known': False, 'valid': False, 'selectable': False, 'sysName': '22.1.172.24', 'serialNumber': None, 'vdcMac': None, 'vdcId': 0, 'ipaddr': '22.1.172.24', 'platform': None, 'version': None, 'lastChange': None, 'hopCount': 0, 'deviceIndex': '22.1.172.24', 'statusReason': 'not reachable', 'vendor': None, 'switchRole': None}]}]

@marehler
Copy link
Author

Root Cause Analysis

  • In dcnm_inventory.py, 'def main()' executes 'dcnm_inv.get_want()'.
  • 'def get_want()' calls 'def update_create_params()' that in turns calls 'def update_discover_params()' that performs REST requests to /test-reachability.
  • 'def update_discover_params()', in line 965, compares the inventory IP seed addresses with the IP seed addresses in the responses before it adds switch details. This fails as the inventory includes IPv6 addresses using double colons "::" while the IPv6 addresses in the response data has zeros ":0:".
  • The returned switch details are not added to the inventory data, and the 'switches' attribute in 'dcnm_inv.want_create' remains empty.
  • Example:
(Epdb) p inv_upd
{'seedIP': '2001:420:448b:8006:fab2::13', 'snmpV3AuthProtocol': 0, 'username': 'admin', 'password': 'C1sco123', 'maxHops': 0, 'cdpSecondTimeout': '5', 'role': 'spine', 'preserveConfig': False, 'switches': 0}

(Epdb) response["DATA"]
[{'reachable': False, 'auth': False, 'known': False, 'valid': False, 'selectable': False, 'sysName': '2001:420:448b:8006:fab2:0:0:13', 'serialNumber': None, 'vdcMac': None, 'vdcId': 0, 'ipaddr': '2001:420:448b:8006:fab2:0:0:13', 'platform': None, 'version': None, 'lastChange': None, 'hopCount': 0, 'deviceIndex': '2001:420:448b:8006:fab2:0:0:13', 'statusReason': 'not reachable'}]

Workaround

As a workaround, simply use IPv6 addresses without double colons in the vxlan.topology.switches configuration data.

@mikewiebe
Copy link
Collaborator

Thanks for the RCA @marehler! We are working to update the module to handle this case

@marehler
Copy link
Author

There is another, closely related issue. The switch role assignment fails for IPv6 devices. In dcnm_inventory.py, also 'def assign_role()' compares the IPv6 addresses in the inventory with the IPv6 addresses received from the switch. This fails too if the inventory includes IPv6 addresses using double colons "::" but the IPv6 addresses in the response data has zeros ":0:" instead.

prabahal added a commit to prabahal/ansible-dcnm that referenced this issue Jan 7, 2025
IPv6 address inventory failure.
NDFC returns ipv6 address with unabbrevated form (e.g) 2001:0:0:12 instead of 2001::12 for below requests.
/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/lanConfig/getLanSwitchCredentials
        "ipAddress": "2001:420:448b:8006:fab2:0:0:13",
/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/hello/inventory/test-reachability

in netascode/ansible-dc-vxlan#251
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants