ansible-collections/cisco.nxos

nxos_acls - Parsing error when gathering and syntax error when configuring ACLs with ACEs which use a source port range

mattspera opened this issue · 3 comments

SUMMARY

When gathering ACL facts using the nxos_acls module, if an ACL contains an ACE which contains a source host with a source port range to a destination, it is parsed incorrectly. Similarly, when attempting to configure an ACL with an ACE of that format, the module errors out.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

nxos_acls

ANSIBLE VERSION
ansible 2.10.14
  config file = /Users/admin/.ansible.cfg
  configured module search path = ['/Users/admin/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/admin/.venvs/two-ten/lib/python3.6/site-packages/ansible
  executable location = /Users/admin/.venvs/two-ten/bin/ansible
  python version = 3.6.15 (default, Apr 21 2023, 11:04:18) [GCC Apple LLVM 14.0.3 (clang-1403.0.22.14.1)]
COLLECTION VERSION
# /Users/admin/.ansible/collections/ansible_collections
Collection Version
---------- -------
cisco.nxos 4.4.0
CONFIGURATION
HOST_KEY_CHECKING(/Users/admin/Development/netbox/ansible.cfg) = False
PERSISTENT_COMMAND_TIMEOUT(/Users/admin/Development/netbox/ansible.cfg) = 300
OS / ENVIRONMENT

cisco Nexus9000 C93108TC-EX chassis
NXOS: version 7.0(3)I7(3)

STEPS TO REPRODUCE

GATHERING BUG

Using the nxos_acls module, gather ACL facts from an NX-OS device which contains an ACL which contains an ACE of the following format:

...
10 permit tcp 1.1.1.1/32 range 7111 9111 192.168.0.0/24 established
...
---

- name: DISCOVER CISCO NX-OS ACL CONFIG
  hosts: all
  gather_facts: false

  tasks:

    - name: GATHER NXOS ACL FACTS
      cisco.nxos.nxos_acls:
        state: gathered
      register: acls

CONFIGURING BUG

Using the nxos_acls module, attempt to deploy an ACL to an NX-OS device which contains an ACE of the following format:

---

- name: DEPLOY CISCO NX-OS ACL CONFIG
  hosts: all
  gather_facts: false

    - name: DEPLOY ACL - NXOS
      cisco.nxos.nxos_acls:
        state: replaced
        config:
          - afi: ipv4
            acls:
              - name: ACL-PLUGIN-TEST
                aces:
                  - sequence: 10
                    grant: permit
                    protocol: tcp
                    protocol_options:
                      tcp:
                        established: true
                    source:
                      host: 1.1.1.1
                      port_protocol:
                        range:
                          start: 7111
                          end: 9111
                    destination:
                      prefix: 192.168.0.0/24
...
EXPECTED RESULTS

GATHERING BUG

It is expected the ACE is parsed correctly, like so (expected output snippet of ACL ACE in question):

...
                        {
                            "destination": {
                                "prefix": "192.168.0.0/24"
                            },
                            "grant": "permit",
                            "protocol": "tcp",
                            "protocol_options": {
                                "tcp": {
                                    "established": true
                                }
                            },
                            "sequence": 10,
                            "source": {
                                "host": "1.1.1.1",
                                "port_protocol": {
                                    "range": {
                                        "end": "9111",
                                        "start": "7111"
                                    }
                                }
                            }
                        },
...

CONFIGURING BUG

It is expected the ACE is deployed correctly, without error, sending the following configuration to the device:.

ip access-list ACL-PLUGIN-TEST
10 permit tcp 1.1.1.1/32 range 7111 9111 192.168.0.0/24 established
ACTUAL RESULTS

GATHERING BUG

Actual output snippet of ACL ACE in question:

...
                        {
                            "destination": {
                                "address": "range",
                                "wildcard_bits": "192.168.0.0/24"
                            },
                            "grant": "permit",
                            "protocol": "tcp",
                            "protocol_options": {
                                "tcp": {
                                    "established": true
                                }
                            },
                            "sequence": 10,
                            "source": {
                                "host": "1.1.1.1",
                                "port_protocol": {
                                    "range": {
                                        "end": "9111",
                                        "start": "7111"
                                    }
                                }
                            }
                        },
...

As can be observed, the destination dict is parsed incorrectly, presenting an address key with a value of range and a wildcard_bits key with a value of the destination prefix (192.168.0.0/24).

CONFIGURING BUG

An error is thrown:

task path: /Users/admin/Development/automation_pipeline/roles/cisco_deploy_acl/tasks/config_deploy.yml:28
File lookup using /Users/admin/Development/automation_pipeline/roles/cisco_deploy_acl/templates/nxos_acl.j2 as file
redirecting (type: terminal) ansible.builtin.nxos to cisco.nxos.nxos
redirecting (type: cliconf) ansible.builtin.nxos to cisco.nxos.nxos
<207.46.199.7> attempting to start connection
<207.46.199.7> using connection plugin ansible.netcommon.network_cli
Found ansible-connection at path /Users/admin/.venvs/two-ten/bin/ansible-connection
<207.46.199.7> local domain socket does not exist, starting it
<207.46.199.7> control socket path is /Users/admin/.ansible/pc/c0fe26ac6b
<207.46.199.7> Loading collection ansible.netcommon from /Users/admin/.ansible/collections/ansible_collections/ansible/netcommon
<207.46.199.7> redirecting (type: terminal) ansible.builtin.nxos to cisco.nxos.nxos
<207.46.199.7> Loading collection cisco.nxos from /Users/admin/.ansible/collections/ansible_collections/cisco/nxos
<207.46.199.7> redirecting (type: cliconf) ansible.builtin.nxos to cisco.nxos.nxos
<207.46.199.7> local domain socket listeners started successfully
<207.46.199.7> loaded cliconf plugin ansible_collections.cisco.nxos.plugins.cliconf.nxos from path /Users/admin/.ansible/collections/ansible_collections/cisco/nxos/plugins/cliconf/nxos.py for network_os nxos
<207.46.199.7> ssh type is set to auto
<207.46.199.7> autodetecting ssh_type
[WARNING]: ansible-pylibssh not installed, falling back to paramiko
<207.46.199.7> ssh type is now set to paramiko
<207.46.199.7>
<207.46.199.7> local domain socket path is /Users/admin/.ansible/pc/c0fe26ac6b
redirecting (type: action) cisco.nxos.nxos_acls to cisco.nxos.nxos
redirecting (type: action) cisco.nxos.nxos_acls to cisco.nxos.nxos
<207.46.199.7> ANSIBLE_NETWORK_IMPORT_MODULES: enabled via connection option
<207.46.199.7> ANSIBLE_NETWORK_IMPORT_MODULES: found cisco.nxos.nxos_acls  at /Users/admin/.ansible/collections/ansible_collections/cisco/nxos/plugins/modules/nxos_acls.py
<207.46.199.7> ANSIBLE_NETWORK_IMPORT_MODULES: running cisco.nxos.nxos_acls
<207.46.199.7> ANSIBLE_NETWORK_IMPORT_MODULES: complete
fatal: [nexus-01]: FAILED! => {
    "changed": false,
    "module_stderr": "no 10 permit tcp host 1.1.1.1 range 7111 9111 range 192.168.0.0/24 established\r\r\n                                  ^\r\n% Invalid command at '^' marker.\r\n\rnexus-01(config-acl)# ",
    "module_stdout": "",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error"
}

As can be observed, the syntax of the command sent to the device is incorrect.

@mattspera Thank you for reporting these issues. The first will be resolved with the changes in #731. However, I'm unsure about how the second issue occurs, i.e., how the ACE negate line that you shared is invalid. It seems to be a valid command when run in a Nexus 9300v (NX-OS 9.3.6).

Will it be possible to share the "before" state of ACLs from that device and the task which triggers this traceback?

Thank you.

@NilashishC No problem.

Regarding the second issue (configuring bug), firstly, the ACE negate line sent to the device by Ansible in the example provided in the issue above is invalid even when running directly on the CLI on a Cisco Nexus9000 C93108TC-EX chassis NXOS: version 7.0(3)I7(3). See output below:

nexus-01(config-acl)# sh ip access-lists ACL-PLUGIN-TEST

IP access list ACL-PLUGIN-TEST
    10 permit tcp 1.1.1.1/32 range 7111 9111 192.168.0.0/24 established
nexus-01(config-acl)# no 10 permit tcp host 1.1.1.1 range 7111 9111 range 192.168.0.0/24 established
                            ^
% Invalid command at '^' marker.

From observing the invalid ACE negate line, we can see that the no 10 permit tcp host 1.1.1.1 range 7111 9111 component of the line is valid, however the range 192.168.0.0/24 is invalid. The range component of this portion of the command should not be there. A valid version of the ACE negate line would look like no 10 permit tcp host 1.1.1.1 range 7111 9111 192.168.0.0/24 established.

Here is an example of the "before" state of an ACL from that device and the task which triggers this traceback:

nexus-01(config)# sh ip access-lists RH-SUPPORT-ACL

IP access list RH-SUPPORT-ACL
    10 permit tcp 1.1.1.1/32 range 7111 9111 192.168.0.0/24 established
nexus-01(config)#

Task to modify this ACL (updating ACE 10 destination prefix to 10.0.0.0/24)

- name: DEPLOY CISCO NX-OS ACL CONFIG
  hosts: all
  gather_facts: false

  tasks:

    - name: DEPLOY ACL - NXOS
      cisco.nxos.nxos_acls:
        state: replaced
        config:
          - afi: ipv4
            acls:
              - name: RH-SUPPORT-ACL
                aces:
                  - sequence: 10
                    grant: permit
                    protocol: tcp
                    protocol_options:
                      tcp:
                        established: true
                    source:
                      host: 1.1.1.1
                      port_protocol:
                        range:
                          start: 7111
                          end: 9111
                    destination:
                      prefix: 10.0.0.0/24

Traceback (-vvv)

fatal: [nexus-01]: FAILED! => {
    "changed": false,
    "module_stderr": "no 10 permit tcp host 1.1.1.1 range 7111 9111 range 192.168.0.0/24 established\r\r\n                                  ^\r\n% Invalid command at '^' marker.\r\n\rnexus-01(config-acl)# ",
    "module_stdout": "",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error"
}

@mattspera Ah, I see. I missed the "range" word in the original traceback you shared. In that case, the patch in #731 fixes both the issues for you.

Thank you!