ansible / ansible

Ansible is a radically simple IT automation platform that makes your applications and systems easier to deploy and maintain. Automate everything from code deployment to network configuration to cloud management, in a language that approaches plain English, using SSH, with no agents to install on remote systems. https://docs.ansible.com.
https://www.ansible.com/
GNU General Public License v3.0
62.98k stars 23.91k forks source link

nxos_interface breaks idempotency when adding additional port-channel interfaces #62210

Closed jkrabbe closed 4 years ago

jkrabbe commented 5 years ago
SUMMARY

When adding port-channel interfaces through nxos_interface aggregate it breaks idempotency when additional port-channels are configured.

ISSUE TYPE
COMPONENT NAME

nxos_interface

ANSIBLE VERSION
ansible 2.8.3
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/dist-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.15+ (default, Jul  9 2019, 16:51:35) [GCC 7.4.0]
CONFIGURATION
CACHE_PLUGIN(/etc/ansible/ansible.cfg) = jsonfile
CACHE_PLUGIN_CONNECTION(/etc/ansible/ansible.cfg) = /**/config/ansible/facts
DEFAULT_HASH_BEHAVIOUR(/etc/ansible/ansible.cfg) = replace
DISPLAY_SKIPPED_HOSTS(/etc/ansible/ansible.cfg) = True
HOST_KEY_CHECKING(/etc/ansible/ansible.cfg) = False
RETRY_FILES_ENABLED(/etc/ansible/ansible.cfg) = False
OS / ENVIRONMENT

Ansible host:

NAME="Ubuntu"
VERSION="18.04.2 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.2 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic

NX-OS target system:

Software
  BIOS: version 05.33
 NXOS: version 9.2(3)
  BIOS compile time:  09/08/2018
  NXOS image file is: bootflash:///nxos.9.2.3.bin
  NXOS compile time:  2/17/2019 5:00:00 [02/17/2019 15:07:27]

Hardware
  cisco Nexus9000 C93180YC-FX Chassis 
  Intel(R) Xeon(R) CPU D-1528 @ 1.90GHz with 65808588 kB of memory.
STEPS TO REPRODUCE
- hosts:
    switch
  check_mode: no
  gather_facts: no
  tasks:
  - nxos_interface:
      aggregate:
      - { name: PortChannel500, mtu: 1500, description: First-PortChannel }
      state: present
    tags: first
  - nxos_interface:
      aggregate:
      - { name: PortChannel500, mtu: 1500, description: First-PortChannel }
      - { name: PortChannel501, mtu: 1500, description: Second-PortChannel }
      state: present
    tags: second
  - nxos_interface:
      aggregate:
      - { name: PortChannel500, mtu: 1500, description: First-PortChannel }
      - { name: PortChannel501, mtu: 1500, description: Second-PortChannel }
      - { name: PortChannel502, mtu: 1500, description: Third-PortChannel }
      state: present
    tags: third

Then run following three commands:

# ansible-playbook -vvv -i hosts.yml pb.yml -t first
# ansible-playbook -vvv -i hosts.yml pb.yml -t second
# ansible-playbook -vvv -i hosts.yml pb.yml -t third
EXPECTED RESULTS

On first run only PortChannel500 gets created. On second run only PortChannel501 gets created. On third run only PortChannel502 gets created.

ACTUAL RESULTS

The first run:

changed: [switch] => {
    "changed": true, 
    "commands": [
        "interface port-channel500", 
        "no shutdown", 
        "description First-PortChannel", 
        "mtu 1500"
    ], 
    "invocation": {
        "module_args": {
            "admin_state": "up", 
            "aggregate": [
                {
                    "admin_state": "up", 
                    "delay": 10, 
                    "description": "First-PortChannel", 
                    "duplex": null, 
                    "fabric_forwarding_anycast_gateway": null, 
                    "interface_type": null, 
                    "ip_forward": null, 
                    "mode": null, 
                    "mtu": "1500", 
                    "name": "PortChannel500", 
                    "neighbors": null, 
                    "rx_rate": null, 
                    "speed": null, 
                    "state": "present", 
                    "tx_rate": null
                }
            ], 
            "auth_pass": null, 
            "authorize": null, 
            "delay": 10, 
            "description": null, 
            "duplex": null, 
            "fabric_forwarding_anycast_gateway": null, 
            "host": null, 
            "interface_type": null, 
            "ip_forward": null, 
            "mode": null, 
            "mtu": null, 
            "name": null, 
            "neighbors": null, 
            "password": null, 
            "port": null, 
            "provider": null, 
            "rx_rate": null, 
            "speed": null, 
            "ssh_keyfile": null, 
            "state": "present", 
            "timeout": null, 
            "transport": null, 
            "tx_rate": null, 
            "use_ssl": null, 
            "username": null, 
            "validate_certs": null
        }
    }
}

Rerunning first run (=> idempotent):

ok: [switch] => {
    "changed": false, 
    "commands": [], 
    "invocation": {
        "module_args": {
            "admin_state": "up", 
            "aggregate": [
                {
                    "admin_state": "up", 
                    "delay": 10, 
                    "description": "First-PortChannel", 
                    "duplex": null, 
                    "fabric_forwarding_anycast_gateway": null, 
                    "interface_type": null, 
                    "ip_forward": null, 
                    "mode": null, 
                    "mtu": "1500", 
                    "name": "PortChannel500", 
                    "neighbors": null, 
                    "rx_rate": null, 
                    "speed": null, 
                    "state": "present", 
                    "tx_rate": null
                }
            ], 
            "auth_pass": null, 
            "authorize": null, 
            "delay": 10, 
            "description": null, 
            "duplex": null, 
            "fabric_forwarding_anycast_gateway": null, 
            "host": null, 
            "interface_type": null, 
            "ip_forward": null, 
            "mode": null, 
            "mtu": null, 
            "name": null, 
            "neighbors": null, 
            "password": null, 
            "port": null, 
            "provider": null, 
            "rx_rate": null, 
            "speed": null, 
            "ssh_keyfile": null, 
            "state": "present", 
            "timeout": null, 
            "transport": null, 
            "tx_rate": null, 
            "use_ssl": null, 
            "username": null, 
            "validate_certs": null
        }
    }
}

The second run. :bangbang: As you can see this also changes/creates the port-channel500 again. :bangbang:

changed: [switch] => {
    "changed": true, 
    "commands": [
        "interface port-channel500", 
        "no shutdown", 
        "description First-PortChannel", 
        "mtu 1500", 
        "interface port-channel501", 
        "no shutdown", 
        "description Second-PortChannel", 
        "mtu 1500"
    ], 
    "invocation": {
        "module_args": {
            "admin_state": "up", 
            "aggregate": [
                {
                    "admin_state": "up", 
                    "delay": 10, 
                    "description": "First-PortChannel", 
                    "duplex": null, 
                    "fabric_forwarding_anycast_gateway": null, 
                    "interface_type": null, 
                    "ip_forward": null, 
                    "mode": null, 
                    "mtu": "1500", 
                    "name": "PortChannel500", 
                    "neighbors": null, 
                    "rx_rate": null, 
                    "speed": null, 
                    "state": "present", 
                    "tx_rate": null
                }, 
                {
                    "admin_state": "up", 
                    "delay": 10, 
                    "description": "Second-PortChannel", 
                    "duplex": null, 
                    "fabric_forwarding_anycast_gateway": null, 
                    "interface_type": null, 
                    "ip_forward": null, 
                    "mode": null, 
                    "mtu": "1500", 
                    "name": "PortChannel501", 
                    "neighbors": null, 
                    "rx_rate": null, 
                    "speed": null, 
                    "state": "present", 
                    "tx_rate": null
                }
            ], 
            "auth_pass": null, 
            "authorize": null, 
            "delay": 10, 
            "description": null, 
            "duplex": null, 
            "fabric_forwarding_anycast_gateway": null, 
            "host": null, 
            "interface_type": null, 
            "ip_forward": null, 
            "mode": null, 
            "mtu": null, 
            "name": null, 
            "neighbors": null, 
            "password": null, 
            "port": null, 
            "provider": null, 
            "rx_rate": null, 
            "speed": null, 
            "ssh_keyfile": null, 
            "state": "present", 
            "timeout": null, 
            "transport": null, 
            "tx_rate": null, 
            "use_ssl": null, 
            "username": null, 
            "validate_certs": null
        }
    }
}

Rerunning second run (=> idempotent):

ok: [switch] => {
    "changed": false, 
    "commands": [], 
    "invocation": {
        "module_args": {
            "admin_state": "up", 
            "aggregate": [
                {
                    "admin_state": "up", 
                    "delay": 10, 
                    "description": "First-PortChannel", 
                    "duplex": null, 
                    "fabric_forwarding_anycast_gateway": null, 
                    "interface_type": null, 
                    "ip_forward": null, 
                    "mode": null, 
                    "mtu": "1500", 
                    "name": "PortChannel500", 
                    "neighbors": null, 
                    "rx_rate": null, 
                    "speed": null, 
                    "state": "present", 
                    "tx_rate": null
                }, 
                {
                    "admin_state": "up", 
                    "delay": 10, 
                    "description": "Second-PortChannel", 
                    "duplex": null, 
                    "fabric_forwarding_anycast_gateway": null, 
                    "interface_type": null, 
                    "ip_forward": null, 
                    "mode": null, 
                    "mtu": "1500", 
                    "name": "PortChannel501", 
                    "neighbors": null, 
                    "rx_rate": null, 
                    "speed": null, 
                    "state": "present", 
                    "tx_rate": null
                }
            ], 
            "auth_pass": null, 
            "authorize": null, 
            "delay": 10, 
            "description": null, 
            "duplex": null, 
            "fabric_forwarding_anycast_gateway": null, 
            "host": null, 
            "interface_type": null, 
            "ip_forward": null, 
            "mode": null, 
            "mtu": null, 
            "name": null, 
            "neighbors": null, 
            "password": null, 
            "port": null, 
            "provider": null, 
            "rx_rate": null, 
            "speed": null, 
            "ssh_keyfile": null, 
            "state": "present", 
            "timeout": null, 
            "transport": null, 
            "tx_rate": null, 
            "use_ssl": null, 
            "username": null, 
            "validate_certs": null
        }
    }
}

The third run: :bangbang: As you can see this also changes/creates the port-channel500 and port-channel501 again. :bangbang:

changed: [switch] => {
    "changed": true, 
    "commands": [
        "interface port-channel500", 
        "no shutdown", 
        "description First-PortChannel", 
        "mtu 1500", 
        "interface port-channel501", 
        "no shutdown", 
        "description Second-PortChannel", 
        "mtu 1500", 
        "interface port-channel502", 
        "no shutdown", 
        "description Third-PortChannel", 
        "mtu 1500"
    ], 
    "invocation": {
        "module_args": {
            "admin_state": "up", 
            "aggregate": [
                {
                    "admin_state": "up", 
                    "delay": 10, 
                    "description": "First-PortChannel", 
                    "duplex": null, 
                    "fabric_forwarding_anycast_gateway": null, 
                    "interface_type": null, 
                    "ip_forward": null, 
                    "mode": null, 
                    "mtu": "1500", 
                    "name": "PortChannel500", 
                    "neighbors": null, 
                    "rx_rate": null, 
                    "speed": null, 
                    "state": "present", 
                    "tx_rate": null
                }, 
                {
                    "admin_state": "up", 
                    "delay": 10, 
                    "description": "Second-PortChannel", 
                    "duplex": null, 
                    "fabric_forwarding_anycast_gateway": null, 
                    "interface_type": null, 
                    "ip_forward": null, 
                    "mode": null, 
                    "mtu": "1500", 
                    "name": "PortChannel501", 
                    "neighbors": null, 
                    "rx_rate": null, 
                    "speed": null, 
                    "state": "present", 
                    "tx_rate": null
                }, 
                {
                    "admin_state": "up", 
                    "delay": 10, 
                    "description": "Third-PortChannel", 
                    "duplex": null, 
                    "fabric_forwarding_anycast_gateway": null, 
                    "interface_type": null, 
                    "ip_forward": null, 
                    "mode": null, 
                    "mtu": "1500", 
                    "name": "PortChannel502", 
                    "neighbors": null, 
                    "rx_rate": null, 
                    "speed": null, 
                    "state": "present", 
                    "tx_rate": null
                }
            ], 
            "auth_pass": null, 
            "authorize": null, 
            "delay": 10, 
            "description": null, 
            "duplex": null, 
            "fabric_forwarding_anycast_gateway": null, 
            "host": null, 
            "interface_type": null, 
            "ip_forward": null, 
            "mode": null, 
            "mtu": null, 
            "name": null, 
            "neighbors": null, 
            "password": null, 
            "port": null, 
            "provider": null, 
            "rx_rate": null, 
            "speed": null, 
            "ssh_keyfile": null, 
            "state": "present", 
            "timeout": null, 
            "transport": null, 
            "tx_rate": null, 
            "use_ssl": null, 
            "username": null, 
            "validate_certs": null
        }
    }
}

Rerunning third run (=> idempotent):

ok: [switch] => {
    "changed": false, 
    "commands": [], 
    "invocation": {
        "module_args": {
            "admin_state": "up", 
            "aggregate": [
                {
                    "admin_state": "up", 
                    "delay": 10, 
                    "description": "First-PortChannel", 
                    "duplex": null, 
                    "fabric_forwarding_anycast_gateway": null, 
                    "interface_type": null, 
                    "ip_forward": null, 
                    "mode": null, 
                    "mtu": "1500", 
                    "name": "PortChannel500", 
                    "neighbors": null, 
                    "rx_rate": null, 
                    "speed": null, 
                    "state": "present", 
                    "tx_rate": null
                }, 
                {
                    "admin_state": "up", 
                    "delay": 10, 
                    "description": "Second-PortChannel", 
                    "duplex": null, 
                    "fabric_forwarding_anycast_gateway": null, 
                    "interface_type": null, 
                    "ip_forward": null, 
                    "mode": null, 
                    "mtu": "1500", 
                    "name": "PortChannel501", 
                    "neighbors": null, 
                    "rx_rate": null, 
                    "speed": null, 
                    "state": "present", 
                    "tx_rate": null
                }, 
                {
                    "admin_state": "up", 
                    "delay": 10, 
                    "description": "Third-PortChannel", 
                    "duplex": null, 
                    "fabric_forwarding_anycast_gateway": null, 
                    "interface_type": null, 
                    "ip_forward": null, 
                    "mode": null, 
                    "mtu": "1500", 
                    "name": "PortChannel502", 
                    "neighbors": null, 
                    "rx_rate": null, 
                    "speed": null, 
                    "state": "present", 
                    "tx_rate": null
                }
            ], 
            "auth_pass": null, 
            "authorize": null, 
            "delay": 10, 
            "description": null, 
            "duplex": null, 
            "fabric_forwarding_anycast_gateway": null, 
            "host": null, 
            "interface_type": null, 
            "ip_forward": null, 
            "mode": null, 
            "mtu": null, 
            "name": null, 
            "neighbors": null, 
            "password": null, 
            "port": null, 
            "provider": null, 
            "rx_rate": null, 
            "speed": null, 
            "ssh_keyfile": null, 
            "state": "present", 
            "timeout": null, 
            "transport": null, 
            "tx_rate": null, 
            "use_ssl": null, 
            "username": null, 
            "validate_certs": null
        }
    }
}
ansibot commented 5 years ago

Files identified in the description:

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

ansibot commented 5 years ago

cc @chrisvanheuveln @jedelman8 @mikewiebe @rahushen @trishnaguha click here for bot help

ansibot commented 5 years ago

@jkrabbe, just so you are aware we have a dedicated Working Group for network. You can find other people interested in this in #ansible-network on Freenode IRC For more information about communities, meetings and agendas see https://github.com/ansible/community

click here for bot help

jkrabbe commented 5 years ago

Some additional information:

The problem comes from the fact that nxos_interface tries to do show interface {0} with the interface name. For a non-existent port-channel interface this command fails.

Now there is different problems with the nxos_interface module.

                        "output":       {
                                "code": "400",
                                "msg":  "CLI execution error",
                                "clierror":     "Invalid range\n",
                                "input":        "show run interface port-channel502"
                        }

But the body variable seems to only have the command and msg in it, i.e.: [u'show interface port-channel502: CLI execution error']

GomathiselviS commented 5 years ago

@jkrabbe 'nxos_interface' will get deprecated soon and will be replaced by 'nxos_interfaces'. This will be released in a couple of weeks. Requesting you to use 'nxos_interfaces' and let us know the behavior.

GomathiselviS commented 5 years ago

needs_info

ansibot commented 4 years ago

@jkrabbe This issue is waiting for your response. Please respond or the issue will be closed.

click here for bot help

jkrabbe commented 4 years ago

WTF? QA? The new module is not even working with Ansible 2.9.1 for me. See #64526 Please let me know once a working Ansible version for nxos_interfaces is available.

Qalthos commented 4 years ago

Thank you very much for your interest in Ansible. This plugin is no longer maintained in this repository and has been migrated to https://github.com/ansible-collections/cisco.nxos

Please re-submit this issue in the above repository.

If you have further questions please stop by IRC or the mailing list: