Giter Club home page Giter Club logo

cisco.ios's People

Contributors

akira6592 avatar andersson007 avatar ansible-zuul[bot] avatar ashwini-mhatre avatar benjdudas avatar bentole avatar capttrews avatar dalrrard avatar earendilfr avatar eleksis avatar ganeshrn avatar gellis713 avatar gomathiselvis avatar justjais avatar kb-perbyte avatar komaldesai13 avatar lduck avatar nilashishc avatar ollylawrence avatar pabelanger avatar padminisivaraj avatar poroping avatar pre-commit-ci[bot] avatar qalthos avatar rohitthakur2590 avatar roverflow avatar ruchip16 avatar samccann avatar samjo-nyang avatar tweippert avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cisco.ios's Issues

cisco.ios.ios_config produces "Unexpected failure during module execution"

From @dykow on Jul 27, 2020 10:22

SUMMARY

Error is being thrown during module execution. Tested on Python 3.8.2 and Python 2.7.18rc1 with same result.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

cisco.ios.ios_config, but cisco.ios.ios_facts produces same error, other cisco.ios modules presumably too.

ANSIBLE VERSION
ansible 2.9.6
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/dykow/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.8.2 (default, Jul 16 2020, 14:00:26) [GCC 9.3.0]
CONFIGURATION
HOST_KEY_CHECKING(/etc/ansible/ansible.cfg) = False
OS / ENVIRONMENT

Host OS

Distributor ID:	Ubuntu
Description:	Ubuntu 20.04 LTS
Release:	20.04
Codename:	focal

Target OS

Cisco IOS Software, C2960X Software (C2960X-UNIVERSALK9-M), Version 15.0(2a)EX5, RELEASE SOFTWARE (fc3)
STEPS TO REPRODUCE
  1. Setup cisco device in /etc/ansible/hosts
  2. Run playbook, ex. ansible-playbook setup_cisco_snmp.yml -vvvv --ask-pass
---

- name: Setup SNMP
  connection: local
  gather_facts: no
  hosts: cisco
  collections:
    - cisco.ios

    
  tasks:
    - name: Global config
      ios_config:
        lines:
          - snmp-server community public RO
EXPECTED RESULTS

Successful module execution.

ACTUAL RESULTS
ansible-playbook 2.9.6
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/dykow/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  executable location = /usr/bin/ansible-playbook
  python version = 3.8.2 (default, Jul 16 2020, 14:00:26) [GCC 9.3.0]
Using /etc/ansible/ansible.cfg as config file
SSH password: 
setting up inventory plugins
host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Parsed /etc/ansible/hosts inventory source with ini plugin
Loading callback plugin default of type stdout, v2.0 from /usr/lib/python3/dist-packages/ansible/plugins/callback/default.py

PLAYBOOK: setup_cisco_snmp.yml **************************************************************************************************************************************************************
Positional arguments: ansible/playbooks/setup_cisco_snmp.yml
verbosity: 4
ask_pass: True
connection: smart
timeout: 10
become_method: sudo
tags: ('all',)
inventory: ('/etc/ansible/hosts',)
forks: 5
1 plays in ansible/playbooks/setup_cisco_snmp.yml

PLAY [Setup SNMP] ***************************************************************************************************************************************************************************
META: ran handlers

TASK [Global config] ************************************************************************************************************************************************************************
task path: /home/dykow/Projects/monitoring_services/ansible/playbooks/setup_cisco_snmp.yml:12
<10.10.10.10> using connection plugin ansible.netcommon.network_cli (was local)
<10.10.10.10> starting connection from persistent connection plugin
The full traceback is:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/ansible/executor/task_executor.py", line 146, in run
    res = self._execute()
  File "/usr/lib/python3/dist-packages/ansible/executor/task_executor.py", line 645, in _execute
    result = self._handler.run(task_vars=variables)
  File "/home/dykow/.ansible/collections/ansible_collections/cisco/ios/plugins/action/ios.py", line 104, in run
    socket_path = connection.run()
  File "/home/dykow/.ansible/collections/ansible_collections/ansible/netcommon/plugins/connection/persistent.py", line 91, in run
    socket_path = start_connection(
TypeError: start_connection() takes 2 positional arguments but 3 were given
fatal: [10.10.10.10]: FAILED! => {
    "msg": "Unexpected failure during module execution.",
    "stdout": ""
}

PLAY RECAP **********************************************************************************************************************************************************************************
10.10.10.10                   : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

Copied from original issue: ansible/ansible#70914

ios_command: doc broken

SUMMARY
$ ansible-doc cisco.ios.ios_command
ERROR! module cisco.ios.ios_command missing documentation (or could not parse documentation): while scanning a quoted scalar
  in "<unicode string>", line 25, column 1:
    " (carriage return, must be double
    ^
found unexpected end of stream
  in "<unicode string>", line 57, column 1:
    
    ^

Looks like it's missing an escape sequence.

'y' or "\r" > 'y' or "\\r"

ISSUE TYPE
  • Documentation Report
COMPONENT NAME
ANSIBLE VERSION
cisco.ios 0.0.3-dev78

gather_network_resources: l3_interfaces returns all interfaces on device instead of only interfaces that have an IP address defined

SUMMARY

gather_network_resources: l3_interfaces returns all interfaces on device instead of only interfaces that have an IP address defined.
"l3_interfaces": [
{
"name": "Port-channel1"
},
{
"ipv4": [
{
"address": "172.25.1.1 255.255.255.0"
}
],
"name": "GigabitEthernet0/0"
},
{
"name": "GigabitEthernet1/0/1"
},
{
"name": "GigabitEthernet1/0/2"
},
{
"name": "GigabitEthernet1/0/3"
},
{
"name": "GigabitEthernet1/0/4"
},
{
"name": "GigabitEthernet1/0/5"
},
{
"name": "GigabitEthernet1/0/6"
},
{
"name": "GigabitEthernet1/0/7"
},
{
"name": "GigabitEthernet1/0/8"
},
{
"name": "GigabitEthernet1/0/9"
},
{
"name": "GigabitEthernet1/0/10"
},
{
"name": "GigabitEthernet1/0/11"
},
{
"name": "GigabitEthernet1/0/12"
},
{
"name": "GigabitEthernet1/0/13"
},
{
"name": "GigabitEthernet1/0/14"
},
{
"name": "GigabitEthernet1/0/15"
},
{
"name": "GigabitEthernet1/0/16"
},
{
"name": "GigabitEthernet1/0/17"
},
{
"name": "GigabitEthernet1/0/18"
},
{
"name": "GigabitEthernet1/0/19"
},
{
"name": "GigabitEthernet1/0/20"
},
{
"name": "GigabitEthernet1/0/21"
},
{
"name": "GigabitEthernet1/0/22"
},
{
"name": "GigabitEthernet1/0/23"
},
{
"name": "GigabitEthernet1/0/24"
},
{
"name": "GigabitEthernet1/1/1"
},
{
"name": "GigabitEthernet1/1/2"
},
{
"name": "TenGigabitEthernet1/1/3"
},
{
"name": "TenGigabitEthernet1/1/4"
},
{
"name": "Vlan1"
}
]

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_facts

ANSIBLE VERSION
ansible 2.9.10
  config file = /home/razvan/Documents/WiFiroedu/ansible_network/ansible.cfg
  configured module search path = ['/home/razvan/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.8/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.8.3 (default, May 29 2020, 00:00:00) [GCC 10.1.1 20200507 (Red Hat 10.1.1-1)]
CONFIGURATION
DEFAULT_FORKS(/etc/ansible/ansible.cfg) = 15
HOST_KEY_CHECKING(/etc/ansible/ansible.cfg) = False
INTERPRETER_PYTHON(/etc/ansible/ansible.cfg) = /usr/bin/python3
OS / ENVIRONMENT

"ansible_net_model": "WS-C3650-24TD"
"ansible_net_system": "ios",
"ansible_net_version": "16.09.04",

and this happens on ASR1000 as well:
"ansible_net_model": "ASR1001-X",
"ansible_net_system": "ios",
"ansible_net_version": "16.06.04",

STEPS TO REPRODUCE

Get facts from ios device with gather_network_resources: l3_interfaces

- name: 'Get facts'
  hosts: catalyst
  module_defaults:
    ios_facts:
      gather_network_resources: 'interfaces,l3_interfaces'
  gather_facts: true
EXPECTED RESULTS

I would expect the module to put only interfaces that have an IP address in the variable, just like nxos_facts does:
"l3_interfaces": [
{
"ipv4": [
{
"address": "172.25.1.1/24"
}
],
"name": "mgmt0"
}
],

ACTUAL RESULTS

The module returns all interfaces even though they do not have ip addresses assigned.

            "l3_interfaces": [
                {
                    "name": "Port-channel1"
                },
                {
                    "ipv4": [
                        {
                            "address": "172.25.1.1 255.255.255.0"
                        }
                    ],
                    "name": "GigabitEthernet0/0"
                },
                {
                    "name": "GigabitEthernet1/0/1"
                },
                {
                    "name": "GigabitEthernet1/0/2"
                },
                {
                    "name": "GigabitEthernet1/0/3"
                },
                {
                    "name": "GigabitEthernet1/0/4"
                },
                {
                    "name": "GigabitEthernet1/0/5"
                },
                {
                    "name": "GigabitEthernet1/0/6"
                },
                {
                    "name": "GigabitEthernet1/0/7"
                },
                {
                    "name": "GigabitEthernet1/0/8"
                },
                {
                    "name": "GigabitEthernet1/0/9"
                },
                {
                    "name": "GigabitEthernet1/0/10"
                },
                {
                    "name": "GigabitEthernet1/0/11"
                },
                {
                    "name": "GigabitEthernet1/0/12"
                },
                {
                    "name": "GigabitEthernet1/0/13"
                },
                {
                    "name": "GigabitEthernet1/0/14"
                },
                {
                    "name": "GigabitEthernet1/0/15"
                },
                {
                    "name": "GigabitEthernet1/0/16"
                },
                {
                    "name": "GigabitEthernet1/0/17"
                },
                {
                    "name": "GigabitEthernet1/0/18"
                },
                {
                    "name": "GigabitEthernet1/0/19"
                },
                {
                    "name": "GigabitEthernet1/0/20"
                },
                {
                    "name": "GigabitEthernet1/0/21"
                },
                {
                    "name": "GigabitEthernet1/0/22"
                },
                {
                    "name": "GigabitEthernet1/0/23"
                },
                {
                    "name": "GigabitEthernet1/0/24"
                },
                {
                    "name": "GigabitEthernet1/1/1"
                },
                {
                    "name": "GigabitEthernet1/1/2"
                },
                {
                    "name": "TenGigabitEthernet1/1/3"
                },
                {
                    "name": "TenGigabitEthernet1/1/4"
                },
                {
                    "name": "Vlan1"
                }
            ]

Update IOS ACLs Merge operations from current behaviour

SUMMARY

Currently, merge removes the ACE and then updates the config ideally, it should do dict merge of want and have.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_acls

ANSIBLE VERSION
2.10
CONFIGURATION

OS / ENVIRONMENT

mac os

STEPS TO REPRODUCE

EXPECTED RESULTS

Merge do a dict merge of want and have and replace doesn't do delete on ACL

ACTUAL RESULTS

Currently, Merge deletes the ACE and update the config only with the want config and for replace operation config does deletes ACL and then apply the ACL and underlying ACE want config


Collection throws error on OSPFv2 facts Module

SUMMARY

With the 1.0.0 Version of the Collection i get an error on my test system:

The full traceback is:
Traceback (most recent call last):
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/executor/task_executor.py", line 146, in run
    res = self._execute()
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/executor/task_executor.py", line 654, in _execute
    result = self._handler.run(task_vars=variables)
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/plugins/action/gather_facts.py", line 79, in run
    res = self._execute_module(module_name=fact_module, module_args=mod_args, task_vars=task_vars, wrap_async=False)
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/plugins/action/__init__.py", line 831, in _execute_module
    (module_style, shebang, module_data, module_path) = self._configure_module(module_name=module_name, module_args=module_args, task_vars=task_vars)
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/plugins/action/__init__.py", line 210, in _configure_module
    (module_data, module_style, module_shebang) = modify_module(module_name, module_path, module_args, self._templar,
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/executor/module_common.py", line 1249, in modify_module
    (b_module_data, module_style, shebang) = _find_module_utils(module_name, b_module_data, module_path, module_args, task_vars, templar, module_compression,
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/executor/module_common.py", line 1088, in _find_module_utils
    recursive_finder(module_name, remote_module_fqn, b_module_data, py_module_names,
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/executor/module_common.py", line 879, in recursive_finder
    recursive_finder(py_module_file[-1], next_fqn, py_module_cache[py_module_file][0],
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/executor/module_common.py", line 724, in recursive_finder
    module_info = CollectionModuleInfo(py_module_name[-idx],
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/executor/module_common.py", line 644, in __init__
    self.get_source()
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/executor/module_common.py", line 660, in get_source
    data = pkgutil.get_data(to_native(self._package_name), to_native(self._mod_name + '.py'))
  File "/usr/lib/python3.8/pkgutil.py", line 619, in get_data
    spec = importlib.util.find_spec(package)
  File "/usr/lib/python3.8/importlib/util.py", line 114, in find_spec
    raise ValueError('{}.__spec__ is None'.format(name))
ValueError: ansible_collections.cisco.ios.plugins.module_utils.network.ios.facts.ospfv2.ospfv2.__spec__ is None
fatal: [c3560-8p]: FAILED! => {
    "msg": "Unexpected failure during module execution.",
    "stdout": ""
}

The last working collection version on this system was 0.0.2!

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_facts

ANSIBLE VERSION
ansible 2.9.10
  config file = /home/weiti/.ansible.cfg
  configured module search path = ['/home/weiti/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible
  executable location = /home/weiti/Develop/ansible-2.9.10/bin/ansible
  python version = 3.8.3 (default, May 17 2020, 18:15:42) [GCC 10.1.0]
CONFIGURATION
DEFAULT_LOG_PATH(/home/weiti/.ansible.cfg) = /home/weiti/ansible.log
HOST_KEY_CHECKING(/home/weiti/.ansible.cfg) = False
INTERPRETER_PYTHON(/home/weiti/.ansible.cfg) = auto_silent
PERSISTENT_COMMAND_TIMEOUT(/home/weiti/.ansible.cfg) = 60
PERSISTENT_CONNECT_RETRY_TIMEOUT(/home/weiti/.ansible.cfg) = 30
OS / ENVIRONMENT

Cisco WS-C3560-8PC-S
IOS 15.0(2)SE10a

STEPS TO REPRODUCE
---
- name: Test Collection
  hosts: c3560-8p

  collections:
    - cisco.ios

  tasks:

  - name: Gather facts
    ios_facts:
      gather_subset:
        - min
EXPECTED RESULTS
TASK [Gather facts] ******************************************************************************************************************************************
task path: /home/weiti/Develop/test_collection.yml:10
<172.18.11.20> ESTABLISH LOCAL CONNECTION FOR USER: weiti
<172.18.11.20> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/weiti/.ansible/tmp/ansible-local-137462898bwaa3l `"&& mkdir /home/weiti/.ansible/tmp/ansible-local-137462898bwaa3l/ansible-tmp-1594400719.6448686-1374667-237934044405698 && echo ansible-tmp-1594400719.6448686-1374667-237934044405698="` echo /home/weiti/.ansible/tmp/ansible-local-137462898bwaa3l/ansible-tmp-1594400719.6448686-1374667-237934044405698 `" ) && sleep 0'
Using module file /home/weiti/.ansible/collections/ansible_collections/cisco/ios/plugins/modules/ios_facts.py
<172.18.11.20> PUT /home/weiti/.ansible/tmp/ansible-local-137462898bwaa3l/tmpq26advlu TO /home/weiti/.ansible/tmp/ansible-local-137462898bwaa3l/ansible-tmp-1594400719.6448686-1374667-237934044405698/AnsiballZ_ios_facts.py
<172.18.11.20> EXEC /bin/sh -c 'chmod u+x /home/weiti/.ansible/tmp/ansible-local-137462898bwaa3l/ansible-tmp-1594400719.6448686-1374667-237934044405698/ /home/weiti/.ansible/tmp/ansible-local-137462898bwaa3l/ansible-tmp-1594400719.6448686-1374667-237934044405698/AnsiballZ_ios_facts.py && sleep 0'
<172.18.11.20> EXEC /bin/sh -c '/usr/bin/python /home/weiti/.ansible/tmp/ansible-local-137462898bwaa3l/ansible-tmp-1594400719.6448686-1374667-237934044405698/AnsiballZ_ios_facts.py && sleep 0'
<172.18.11.20> EXEC /bin/sh -c 'rm -f -r /home/weiti/.ansible/tmp/ansible-local-137462898bwaa3l/ansible-tmp-1594400719.6448686-1374667-237934044405698/ > /dev/null 2>&1 && sleep 0'
ok: [c3560-8p] => {
    "ansible_facts": {
        "ansible_net_api": "cliconf",
        "ansible_net_gather_network_resources": [],
        "ansible_net_gather_subset": [
            "default"
        ],
        "ansible_net_hostname": "c3560-8p",
        "ansible_net_image": "flash:c3560-ipservicesk9-mz.150-2.SE10a.bin",
        "ansible_net_iostype": "IOS",
        "ansible_net_model": "WS-C3560-8PC",
        "ansible_net_python_version": "3.8.3",
        "ansible_net_serialnum": "FOC1524V1WC",
        "ansible_net_stacked_models": [
            "WS-C3560-8PC-S"
        ],
        "ansible_net_stacked_serialnums": [
            "FOC1524V1WC"
        ],
        "ansible_net_system": "ios",
        "ansible_net_version": "15.0(2)SE10a",
        "ansible_network_resources": {}
    },
    "changed": false,
    "invocation": {
        "module_args": {
            "gather_network_resources": null,
            "gather_subset": [
                "min"
            ],
            "provider": null
        }
    }
}
ACTUAL RESULTS
TASK [Gathering Facts] ***************************************************************************************************************************************
task path: /home/weiti/Develop/test_collection.yml:2
[WARNING]: Ignoring timeout(10) for ios_facts
<172.18.11.20> ESTABLISH LOCAL CONNECTION FOR USER: weiti
<172.18.11.20> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/weiti/.ansible/tmp/ansible-local-1374746jf6_e7of `"&& mkdir /home/weiti/.ansible/tmp/ansible-local-1374746jf6_e7of/ansible-tmp-1594400763.946271-1374750-244032104406873 && echo ansible-tmp-1594400763.946271-1374750-244032104406873="` echo /home/weiti/.ansible/tmp/ansible-local-1374746jf6_e7of/ansible-tmp-1594400763.946271-1374750-244032104406873 `" ) && sleep 0'
<172.18.11.20> EXEC /bin/sh -c 'rm -f -r /home/weiti/.ansible/tmp/ansible-local-1374746jf6_e7of/ansible-tmp-1594400763.946271-1374750-244032104406873/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/executor/task_executor.py", line 146, in run
    res = self._execute()
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/executor/task_executor.py", line 654, in _execute
    result = self._handler.run(task_vars=variables)
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/plugins/action/gather_facts.py", line 79, in run
    res = self._execute_module(module_name=fact_module, module_args=mod_args, task_vars=task_vars, wrap_async=False)
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/plugins/action/__init__.py", line 831, in _execute_module
    (module_style, shebang, module_data, module_path) = self._configure_module(module_name=module_name, module_args=module_args, task_vars=task_vars)
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/plugins/action/__init__.py", line 210, in _configure_module
    (module_data, module_style, module_shebang) = modify_module(module_name, module_path, module_args, self._templar,
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/executor/module_common.py", line 1249, in modify_module
    (b_module_data, module_style, shebang) = _find_module_utils(module_name, b_module_data, module_path, module_args, task_vars, templar, module_compression,
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/executor/module_common.py", line 1088, in _find_module_utils
    recursive_finder(module_name, remote_module_fqn, b_module_data, py_module_names,
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/executor/module_common.py", line 879, in recursive_finder
    recursive_finder(py_module_file[-1], next_fqn, py_module_cache[py_module_file][0],
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/executor/module_common.py", line 724, in recursive_finder
    module_info = CollectionModuleInfo(py_module_name[-idx],
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/executor/module_common.py", line 644, in __init__
    self.get_source()
  File "/home/weiti/Develop/ansible-2.9.10/lib/python3.8/site-packages/ansible/executor/module_common.py", line 660, in get_source
    data = pkgutil.get_data(to_native(self._package_name), to_native(self._mod_name + '.py'))
  File "/usr/lib/python3.8/pkgutil.py", line 619, in get_data
    spec = importlib.util.find_spec(package)
  File "/usr/lib/python3.8/importlib/util.py", line 114, in find_spec
    raise ValueError('{}.__spec__ is None'.format(name))
ValueError: ansible_collections.cisco.ios.plugins.module_utils.network.ios.facts.ospfv2.ospfv2.__spec__ is None
fatal: [c3560-8p]: FAILED! => {
    "msg": "Unexpected failure during module execution.",
    "stdout": ""
}

L2_InterfacesFacts not gathering all allowed VLANs from trunk

SUMMARY

The Facts module for L2 properties does not include allowed VLANs on trunk interfaces when there are multiple allowed ranges. The module only recognizes VLAN ranges in switchport trunk allowed vlan X, but not in switchport trunk allowed vlan add Y. This result in change every time.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_l2_interfaces
L2_InterfacesFacts

ANSIBLE VERSION
ansible 2.10.0.dev0
  config file = /home/username/Develop/ansible.cfg
  configured module search path = ['/home/username/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/username/ansible/lib/ansible
  executable location = /home/username/ansible/bin/ansible
  python version = 3.8.3 (default, May 15 2020, 00:00:00) [GCC 10.1.1 20200507 (Red Hat 10.1.1-1)]

CONFIGURATION
DEFAULT_CALLBACK_WHITELIST(/home/username/Develop/ansible.cfg) = ['timer', 'profile_tasks']
DEFAULT_FORKS(/home/username/Develop/ansible.cfg) = 10
DEFAULT_GATHERING(/home/username/Develop/ansible.cfg) = explicit
DEFAULT_VAULT_PASSWORD_FILE(/home/username/Develop/ansible.cfg) = XXXXXXXX
HOST_KEY_CHECKING(/home/username/Develop/ansible.cfg) = False
INTERPRETER_PYTHON(/home/username/Develop/ansible.cfg) = auto_silent
OS / ENVIRONMENT

Fedora 32

Cisco: Any IOS/IOS-XE Switch

STEPS TO REPRODUCE

Playbook:

---
- name: Test Interfaces Trunk
  hosts: all
  collections:
    - cisco.ios

  vars:
    vlans: [1,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,1500,1502,1504]  
  
  tasks:
    - name: Configure Trunk Interfaces
      ios_l2_interfaces:
        config:
          - name: Ethernet0/2
            trunk:
              allowed_vlans: "{{ vlans | join(',') }}"
      tags: test
      register: output

Device config before running the playbook:

SW-1#show running-config interface Ethernet 0/2
Building configuration...

Current configuration : 156 bytes
!
interface Ethernet0/2
 switchport trunk allowed vlan 1,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32
 switchport trunk allowed vlan add 1500,1502,1504
end
EXPECTED RESULTS

Module parses the current device config correctly, including the line switchport trunk allowed vlan add 1500,1502,1504. The module then compares the currently allowed VLANs with the VLANs specified in task and pushes only the difference, preferably using switchport trunk allowed vlan add <diff>. In this exact case, the VLANs configured on the device are identical to the ones specified in task, therefore the task should return ok instead of changed.

ACTUAL RESULTS

The module only recognizes the switchport trunk allowed vlan 1,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32 and tries to update the allowed VLANs to contain 1500,1502,1504. However, it does it in a strange way, putting together already present VLANs with ALL specified VLANs, producing command switchport trunk allowed vlan 1,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,1500,1502,1504,1,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32 . A proper way would be to get want.difference(have) and send switchport trunk allowed vlan add 1500,1502,1504. The difference should be done per individual VLANs, not per ranges.

PLAYBOOK: interfaces_trunk.yml ***************************************************************************************************************************************************************************************************************
1 plays in interfaces_trunk.yml

PLAY [Test Interfaces Trunk] *****************************************************************************************************************************************************************************************************************
META: ran handlers

TASK [Configure Trunk Interfaces] ************************************************************************************************************************************************************************************************************
changed: [SW-01] => {
    "after": [
        {
            "mode": "trunk",
            "name": "Ethernet0/0",
            "trunk": {
                "allowed_vlans": [
                    "10",
                    "20"
                ],
                "encapsulation": "dot1q"
            }
        },
        {
            "name": "Ethernet0/1"
        },
        {
            "name": "Ethernet0/2",
            "trunk": {
                "allowed_vlans": [
                    "1",
                    "2",
                    "4",
                    "6",
                    "8",
                    "10",
                    "12",
                    "14",
                    "16",
                    "18",
                    "20",
                    "22",
                    "24",
                    "26",
                    "28",
                    "30",
                    "32"
                ],
                "native_vlan": 11
            }
        },
        {
            "name": "Ethernet0/3"
        }
    ],
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "before": [
        {
            "mode": "trunk",
            "name": "Ethernet0/0",
            "trunk": {
                "allowed_vlans": [
                    "10",
                    "20"
                ],
                "encapsulation": "dot1q"
            }
        },
        {
            "name": "Ethernet0/1"
        },
        {
            "name": "Ethernet0/2",
            "trunk": {
                "allowed_vlans": [
                    "1",
                    "2",
                    "4",
                    "6",
                    "8",
                    "10",
                    "12",
                    "14",
                    "16",
                    "18",
                    "20",
                    "22",
                    "24",
                    "26",
                    "28",
                    "30",
                    "32"
                ],
                "native_vlan": 11
            }
        },
        {
            "name": "Ethernet0/3"
        }
    ],
    "changed": true,
    "commands": [
        "interface Ethernet0/2",
        "switchport trunk allowed vlan 1,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,1500,1502,1504,1,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32"
    ],
    "invocation": {
        "module_args": {
            "config": [
                {
                    "access": null,
                    "mode": null,
                    "name": "Ethernet0/2",
                    "trunk": {
                        "allowed_vlans": [
                            "1",
                            "2",
                            "4",
                            "6",
                            "8",
                            "10",
                            "12",
                            "14",
                            "16",
                            "18",
                            "20",
                            "22",
                            "24",
                            "26",
                            "28",
                            "30",
                            "32",
                            "1500",
                            "1502",
                            "1504"
                        ],
                        "encapsulation": null,
                        "native_vlan": null,
                        "pruning_vlans": null
                    },
                    "voice": null
                }
            ],
            "running_config": null,
            "state": "merged"
        }
    }
}

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
SW-01                      : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Suggestions

I suggest creating new function in utils for parsing allowed VLANs, maybe something like:

def get_trunk_allowed_vlans(conf):
    allowed_vlans = None
    for line in filter(lambda x: "switchport trunk allowed vlan" in x, conf.split("\n")):
        if allowed_vlans is None:
            allowed_vlans = []
        if "vlan all" in line: 
            return ["1-4094"]
        if "vlan none" in line:
            return []
        allowed_vlans.extend(parse_conf_arg(line, "allowed vlan(?: add)?").split(","))
    return allowed_vlans

It should be noted that the config switchport trunk allowed vlan all will never be present in show running-config only in "show running-config all". Maybe the facts module should return ["1-4094"] for all trunk interfaces with default configuration. Another possibility is switchport trunk allowed vlan none, which could make the module return an empty list. In my opinion, the allowed_vlan = None should be returned only for non-trunking interfaces.

Then another function for expanding the VLAN ranges to the list (or set) of integers:

def expand_vlan_range(vlans):
    expanded = set()
    for vlan_range in vlans:
        if isinstance(vlan_range, int):
            expanded.add(vlan_range)
        elif isinstance(vlan_range, str):
            vlan_range = vlan_range.split("-")
            if len(vlan_range) > 1:
                # Maybe add validation that stop > start
                start = int(vlan_range[0].strip())
                stop = int(vlan_range[1].strip())
                expanded.update(range(start, stop+1))
            else:
                expanded.add(int(vlan_range))
    return list(expanded)

ios_interfaces and ios_banner - register: in check mode does not work

SUMMARY

ios_interfaces and ios_banner shows a change in check mode. However, when registering that variable, it's showing up as empty.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_interfaces
ios_banner

ANSIBLE VERSION
ansible 2.9.9
  config file = /Users/gdykeman/Documents/Ansible/ansible_locker/ansible.cfg
  configured module search path = ['/Users/gdykeman/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/gdykeman/Documents/Ansible/environments/network/lib/python3.7/site-packages/ansible
  executable location = /Users/gdykeman/Documents/Ansible/environments/network/bin/ansible
  python version = 3.7.5 (default, Nov  1 2019, 02:16:32) [Clang 11.0.0 (clang-1100.0.33.8)]
CONFIGURATION
DEFAULT_CALLBACK_WHITELIST(/Users/gdykeman/Documents/Ansible/ansible_locker/ansible.cfg) = ['time']
DEFAULT_FORKS(/Users/gdykeman/Documents/Ansible/ansible_locker/ansible.cfg) = 50
DEFAULT_HOST_LIST(/Users/gdykeman/Documents/Ansible/ansible_locker/ansible.cfg) = ['/Users/gdykeman/Documents/Ansible/ansible_locker/inventory/dev/dev_hosts.yaml']
DEFAULT_NO_TARGET_SYSLOG(/Users/gdykeman/Documents/Ansible/ansible_locker/ansible.cfg) = False
DEFAULT_PRIVATE_KEY_FILE(/Users/gdykeman/Documents/Ansible/ansible_locker/ansible.cfg) = /Users/gdykeman/.ssh/gdykeman-dev-network.pem
DEFAULT_SCP_IF_SSH(/Users/gdykeman/Documents/Ansible/ansible_locker/ansible.cfg) = True
DEFAULT_STDOUT_CALLBACK(/Users/gdykeman/Documents/Ansible/ansible_locker/ansible.cfg) = yaml
DEFAULT_VAULT_PASSWORD_FILE(/Users/gdykeman/Documents/Ansible/ansible_locker/ansible.cfg) = /Users/gdykeman/Documents/Ansible/z_misc/vault.txt
HOST_KEY_CHECKING(/Users/gdykeman/Documents/Ansible/ansible_locker/ansible.cfg) = False
INTERPRETER_PYTHON(/Users/gdykeman/Documents/Ansible/ansible_locker/ansible.cfg) = auto_silent
PERSISTENT_COMMAND_TIMEOUT(/Users/gdykeman/Documents/Ansible/ansible_locker/ansible.cfg) = 200
PERSISTENT_CONNECT_TIMEOUT(/Users/gdykeman/Documents/Ansible/ansible_locker/ansible.cfg) = 200
RETRY_FILES_ENABLED(/Users/gdykeman/Documents/Ansible/ansible_locker/ansible.cfg) = False
OS / ENVIRONMENT

MacOS Mojave 10.14.6

STEPS TO REPRODUCE
  - name: Configure interfaces with provided data model
    ios_interfaces:
      config: "{{ interfaces }}"
      state: replaced
    register: net_interfaces
    check_mode: yes
    ios_banner:
      banner: motd
      text: "{{ lookup('template', 'motd.j2') }}"
      state: present
    register: net_motd
    check_mode: yes
interfaces:
-   enabled: true
    name: loopback0
-   enabled: true
    name: GigabitEthernet1
-   enabled: true
    name: loopback5
Hostname: {{ inventory_hostname }}
Model: {{ ansible_net_model }}
Serial Number: {{ ansible_net_serialnum }}
Version: {{ ansible_net_version }}
EXPECTED RESULTS

Registered variable to contain "commands"

ACTUAL RESULTS
TASK [network_banner : Configure the MOTD] ***********************************************************************************
changed: [cisco1] => changed=true
  commands:
  - |-
    banner motd @
    Hostname: cisco1
    Model: CSR1000V
    Serial Number: 9N74GJXNW2N
    Version: 16.09.02
    @
TASK [debug] *****************************************************************************************************************
ok: [cisco1] =>
  net_motd:
    changed: false
    skip_reason: Conditional result was False
    skipped: true
TASK [network_interfaces : Configure interfaces with provided data model] ****************************************************
changed: [cisco1] => changed=true
  after:
  - enabled: true
    name: loopback0
  - enabled: true
    name: GigabitEthernet1
  before:
  - enabled: true
    name: loopback0
  - enabled: true
    name: GigabitEthernet1
  commands:
  - interface loopback5
  - no shutdown
TASK [debug] *****************************************************************************************************************
ok: [cisco1] =>
  net_interfaces:
    changed: false
    skip_reason: Conditional result was False
    skipped: true

ios_vlans module fails on ios.

SUMMARY

ios_vlans module on classic ios fails with error

line 185, in __rpc__\nansible.module_utils.connection.ConnectionError: show vlan\r\n% Ambiguous command:  \"show vlan\"\r\nan-ios-02#\n",

as it is supported only on ios-l2.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_vlans

ANSIBLE VERSION
2.9.6
CONFIGURATION

OS / ENVIRONMENT
STEPS TO REPRODUCE
  - name: collect vlan facts for ios
    ios_facts:
      gather_network_resources:
      - vlans
EXPECTED RESULTS

Module doc should reflect supported ios version and throw a user-readable error message for non-supported ios variants.

ACTUAL RESULTS

Throws error

line 185, in __rpc__\nansible.module_utils.connection.ConnectionError: show vlan\r\n% Ambiguous command:  \"show vlan\"\r\nan-ios-02#\n",

Idempotence issue in ios_logging with host and facility

SUMMARY

If we want to add an host and set the facility, the idempotence is not working

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_logging module

ANSIBLE VERSION
ansible 2.9.10
  config file = /home/florian/logm/ansible-test/ansible.cfg
  configured module search path = ['/home/florian/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/florian/.pyenv/versions/3.8.3/envs/ansible/lib/python3.8/site-packages/ansible
  executable location = /home/florian/.pyenv/versions/ansible/bin/ansible
  python version = 3.8.3 (default, Jun  5 2020, 11:41:04) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
CONFIGURATION
HOST_KEY_CHECKING(/home/user/logm/ansible-test/ansible.cfg) = False
OS / ENVIRONMENT
Switch Ports Model              SW Version            SW Image                 
------ ----- -----              ----------            ----------               
*    1 26    WS-C2960+24TC-L    15.0(2)SE6            C2960-LANBASEK9-M        
STEPS TO REPRODUCE
$ cat configure_logging.yaml
---
- name: Get logging facts
  hosts: switch
  gather_facts: no
  tasks:

  - name: Configure logging
    ios_logging:
      dest: host
      name: 10.55.240.143
      facility: local6
      state: present
    register: output

  - name: Configure trap logging
    ios_logging:
      dest: trap
      level: notifications
      state: present
    register: output2

  - name: Show output
    debug: var=output

  - name: Show output
    debug: var=output2
EXPECTED RESULTS

Should not have any change after the first execution. Here is a example where we are running twice the same playbook.

ACTUAL RESULTS
$ ansible-playbook -i hosts configure_logging.yaml -k 
SSH password: 

PLAY [Get logging facts] ****************************************************************************************************************************************************************************************************************

TASK [Configure logging] ****************************************************************************************************************************************************************************************************************
changed: [TB_BHD]

TASK [Configure trap logging] ***********************************************************************************************************************************************************************************************************
ok: [TB_BHD]

TASK [Show output] **********************************************************************************************************************************************************************************************************************
ok: [TB_BHD] => {
    "output": {
        "ansible_facts": {
            "discovered_interpreter_python": "/usr/bin/python"
        },
        "changed": true,
        "commands": [
            "logging facility local6",
            "logging host 10.55.240.143"
        ],
        "failed": false
    }
}

TASK [Show output] **********************************************************************************************************************************************************************************************************************
ok: [TB_BHD] => {
    "output2": {
        "changed": false,
        "commands": [],
        "failed": false
    }
}

PLAY RECAP ******************************************************************************************************************************************************************************************************************************
TB_BHD                     : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  





# second execution
$ ansible-playbook -i hosts configure_logging.yaml -k -C
SSH password: 

PLAY [Get logging facts] ****************************************************************************************************************************************************************************************************************

TASK [Configure logging] ****************************************************************************************************************************************************************************************************************
changed: [TB_BHD]

TASK [Configure trap logging] ***********************************************************************************************************************************************************************************************************
ok: [TB_BHD]

TASK [Show output] **********************************************************************************************************************************************************************************************************************
ok: [TB_BHD] => {
    "output": {
        "ansible_facts": {
            "discovered_interpreter_python": "/usr/bin/python"
        },
        "changed": true,
        "commands": [
            "logging host 10.55.240.143"
        ],
        "failed": false
    }
}

TASK [Show output] **********************************************************************************************************************************************************************************************************************
ok: [TB_BHD] => {
    "output2": {
        "changed": false,
        "commands": [],
        "failed": false
    }
}

PLAY RECAP ******************************************************************************************************************************************************************************************************************************
TB_BHD                     : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Module ios_interfaces always 'changing' Loopback interfaces

SUMMARY

Loopback interfaces will a capital 'L' will always show as changed. This is causing issues with idempotentcy as when the interface is referenced in other lines of config by the ios_config module (in my case for radius/logging source) the interface needs to be 'Loopback' as this is how it is displayed in the config.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_interfaces

ANSIBLE VERSION
ansible 2.9.6
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/ansible/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.5/dist-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 3.5.2 (default, Apr 16 2020, 17:47:17) [GCC 5.4.0 20160609]
CONFIGURATION
DEFAULT_HOST_LIST(/etc/ansible/ansible.cfg) = ['/etc/ansible/hosts']
HOST_KEY_CHECKING(/etc/ansible/ansible.cfg) = False
INTERPRETER_PYTHON(/etc/ansible/ansible.cfg) = auto
PARAMIKO_HOST_KEY_AUTO_ADD(/etc/ansible/ansible.cfg) = True
OS / ENVIRONMENT

Target device:

Cisco IOS Software, C3560CX Software (C3560CX-UNIVERSALK9-M), Version 15.2(4)E5, RELEASE SOFTWARE (fc2)
STEPS TO REPRODUCE

Use ios_interfaces module to configure a loopback interface.

- ios_interfaces:
  config:
  - name: Loopback0
    description: 'MGMT loopback'
  state: replaced
  register: debugging
- debug: var=debugging

Device config:

xxx-dist-sw1#show run | sec ^interface Loopback
interface Loopback0
 description MGMT loopback
xxx-dist-sw1#
EXPECTED RESULTS

Module makes no changes if Loopback interface is configured already.

ACTUAL RESULTS

Module attempts to 'change' interface.

TASK [interfaces : configure interfaces] **************************************************************************
changed: [xxx-dist-sw1]

TASK [interfaces : debug] *****************************************************************************************
ok: [xxx-dist-sw1] => {
    "debugging": {
        "after": [
            {
                "description": "MGMT loopback",
                "enabled": true,
                "name": "loopback0"
            }
        ],
        "before": [
            {
                "description": "MGMT loopback",
                "enabled": true,
                "name": "loopback0"
            }
        ],
        "changed": true,
        "commands": [
            "interface Loopback0",
            "description MGMT loopback",
            "no shutdown"
        ],
        "failed": false
    }
}
With lowercase 'L'
- ios_interfaces:
  config:
  - name: loopback0
    description: 'MGMT loopback'
  state: replaced
  register: debugging
- debug: var=debugging
TASK [interfaces : configure interfaces] **************************************************************************
ok: [xxx-dist-sw1]

TASK [interfaces : debug] *****************************************************************************************
ok: [xxx-dist-sw1] => {
    "debugging": {
        "before": [
            {
                "description": "MGMT loopback",
                "enabled": true,
                "name": "loopback0"
            }
        ],
        "changed": false,
        "commands": [],
        "failed": false
    }
}

This issue does not occur with ios_l3_interfaces module. I am not sure why as I would imagine it uses the same/similar function to compare before and after.
As far as I'm aware it's always 'Loopback' with IOS and IOS-XE and 'loopback' on NXOS.

Inconsistent results from ios_facts with l2_interfaces

SUMMARY

when using gather_network_resources: l2_interfaces, results do not appear to be structured correctly when returned and makes accessing the data difficult. Access and trunk ports should have the same format when exported, and key should be the interface name.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_facts

ANSIBLE VERSION
ansible-playbook 2.9.10
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/user/.local/lib/python3.6/site-packages/ansible
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.6.8 (default, Apr  2 2020, 13:34:55) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
Using /etc/ansible/ansible.cfg as config file
CONFIGURATION
DEFAULT_STDOUT_CALLBACK(/etc/ansible/ansible.cfg) = yaml
HOST_KEY_CHECKING(/etc/ansible/ansible.cfg) = False
INTERPRETER_PYTHON(/etc/ansible/ansible.cfg) = /usr/bin/python3
OS / ENVIRONMENT

Centos7

STEPS TO REPRODUCE

Use ios_facts with gather_network_resources: l2_interfaces

- name: Gather switch interface information
  cisco.ios.ios_facts:
    gather_subset:
      - '!all'
      - '!min'
    gather_network_resources:
      - l2_interfaces
  register: ios_interfaces_result
EXPECTED RESULTS

Expect consistently formatted data like example below:

l2_interfaces:
      - name: GigabitEthernet0/1
        mode: access
          vlan: 666
        voice:
          vlan: 10
      - name: GigabitEthernet0/2
        mode: access
          vlan: 666
      - name: GigabitEthernet0/16
        mode: trunk
        trunk:
          allowed_vlans:
          - '10'
          - '49'
          - '105'
          - '4000'
          native_vlan: 4000
ACTUAL RESULTS
  ansible_facts:
    ansible_net_gather_network_resources:
    - l2_interfaces
    ansible_net_gather_subset: []
    ansible_network_resources:
      l2_interfaces:
      - access:
          vlan: 666
        mode: access
        name: GigabitEthernet0/1
        voice:
          vlan: 10
      - access:
          vlan: 666
        mode: access
        name: GigabitEthernet0/2
      - access:
          vlan: 105
        mode: access
        name: GigabitEthernet0/3
      - access:
          vlan: 49
        mode: access
        name: GigabitEthernet0/4
      - access:
          vlan: 666
        mode: access
        name: GigabitEthernet0/5
      - access:
          vlan: 666
        mode: access
        name: GigabitEthernet0/6
      - access:
          vlan: 666
        mode: access
        name: GigabitEthernet0/7
      - access:
          vlan: 666
        mode: access
        name: GigabitEthernet0/8
      - access:
          vlan: 666
        mode: access
        name: GigabitEthernet0/9
      - access:
          vlan: 666
        mode: access
        name: GigabitEthernet0/10
      - access:
          vlan: 666
        mode: access
        name: GigabitEthernet0/11
      - access:
          vlan: 666
        mode: access
        name: GigabitEthernet0/12
      - access:
          vlan: 666
        mode: access
        name: GigabitEthernet0/13
      - access:
          vlan: 100
        mode: access
        name: GigabitEthernet0/14
      - access:
          vlan: 666
        mode: access
        name: GigabitEthernet0/15
      - mode: trunk
        name: GigabitEthernet0/16
        trunk:
          allowed_vlans:
          - '10'
          - '49'
          - '105'
          - '4000'
          native_vlan: 4000

ios_config force remove lines

SUMMARY

Reopening of ansible/ansible#53862 into the appropriate Cisco collections repo.
Some ios config lines require existing config to be removed before successful application. An example of this is the 'service-policy input '. You cannot specify a new policy-map name to apply without removing the old one by name first. In this case, the 'before' option isn't enough.

ISSUE TYPE
  • Feature Idea
COMPONENT NAME

networking/ios_config

ADDITIONAL INFORMATION

The service-policy command is a good example of how this could be useful. Let's say you want a task that will go through and remove any non-standard service-policies bound to interfaces and then add a standard one. There could be a host_vars mapping of service-policy to interface names to loop through in order to achieve this.

Unfortunately, in order to be removed, you need to negate the entire service-policy command, including the name. Since the names are free form, they can vary from interface to interface. At the moment, I think that the only feasible way to accomplish the task described above is by using a nested loop structure wherein you loop through the output of a registered command like "show run {{ item.interface }} | include service-policy" to register the configured service-policies and then compare the output to a loop of your host_vars interface/service-policy mappings. I spent some hours trying to accomplish this but eventually gave up, although it is probably possible.

So anyway, some option for the ios_config module to run the "no" form of whatever it's matching against in the config, regardless of what it looks like, would be nice. The "before" option gets part way there, but it doesn't work when the name of the thing you are removing doesn't necessarily match the name of the thing you're adding.

cisco.ios.ios_vlans state: gathered not working

SUMMARY

running playbook:

  - name: Gather listed vlans with provided configurations
    ios_vlans:
      config:
      state: gathered

produces error message:

`{
    "msg": "value of state must be one of: merged, replaced, overridden, deleted, got: gathered",
    "invocation": {
        "module_args": {
            "config": null,
            "state": "gathered"
        }
    },
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "_ansible_no_log": false,
    "changed": false
}`

ISSUE TYPE
  • Bug Report
COMPONENT NAME

cisco.ios.ios_vlans

ANSIBLE VERSION
ansible 2.9.7
  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.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Nov 21 2019, 19:31:34) [GCC 8.3.1 20190507 (Red Hat 8.3.1-4)]

CONFIGURATION
[root@AWX ~]# ansible-config dump --only-changed
[root@AWX ~]# 

OS / ENVIRONMENT

terrapin-2960-bu#show version
Cisco IOS Software, C2960S Software (C2960S-UNIVERSALK9-M), Version 15.0(2a)SE9, RELEASE SOFTWARE (fc1)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2015 by Cisco Systems, Inc.
Compiled Mon 21-Dec-15 02:41 by prod_rel_team

ROM: Bootstrap program is C2960S board boot loader
BOOTLDR: C2960S Boot Loader (C2960S-HBOOT-M) Version 12.2(55r)SE, RELEASE SOFTWARE (fc1)

STEPS TO REPRODUCE

run playbook against device

---
- name: VLANS

  gather_facts: no
  connection: network_cli
  collections:
    - cisco.ios

  tasks:
  - name: Gather listed vlans with provided configurations
    ios_vlans:
      config:
      state: gathered


EXPECTED RESULTS

json output of all vlans

ACTUAL RESULTS

{
"msg": "value of state must be one of: merged, replaced, overridden, deleted, got: gathered",
"invocation": {
"module_args": {
"config": null,
"state": "gathered"
}
},
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"_ansible_no_log": false,
"changed": false
}

running this from AWX.  Launch with inventory and credential

ios_config running_config not working as expected

From @nniehoff on Jul 18, 2020 15:06

SUMMARY

The running_config parameter for ios_config should allow the operator to pass in the current configuration of a switch for use as a comparison, this will then be used instead of having the module query the switch for the current config. In my testing, every attempt I have made causes the module to determine a change is necessary even when it is not. The documentation and examples I can find aren't the clearest on what the module expects here so it's possible I'm just not passing the expected value to the parameter.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_config

ANSIBLE VERSION
ansible 2.9.6
  config file = /network-config/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.8.2 (default, Apr 27 2020, 15:53:34) [GCC 9.3.0]
CONFIGURATION
OS / ENVIRONMENT

Host OS: Ubuntu 20.04 LTS
Cisco IOS Switch: Cisco IOS Software [Amsterdam], ESS3x00 Switch Software (ESS3x00-UNIVERSALK9-M), Version 17.2.1, RELEASE SOFTWARE (fc4)

STEPS TO REPRODUCE

On cisco switch run:
conf t
vtp mode server

Then run the playbook listed below against that switch

- name: "VTP Off"
  ios_config:
    defaults: yes
    lines: "vtp mode off"

- name: get running configuration
  ios_command:
    commands: show running-config all
  register: postconfig

- name: "VTP Off Post"
  ios_config:
    running_config: postconfig.stdout_lines
    defaults: yes
    lines: "vtp mode off"

- name: "VTP Off"
  ios_config:
    defaults: yes
    lines: "vtp mode off"
EXPECTED RESULTS

I expected the task "VTP Off" to set vtp mode off by changing the config. Then I get the running config and use that running config to the exact same task this time named "VTP Off Post" and passing in the running_config parameter this time the "VTP Off Post" task should read the running_config and determine no change is necessary and proceed with ok.

ACTUAL RESULTS

When passing in the running_config parameter with the config option already set ios_config still determines a change is necessary. I run the same task a third time without the running_config parameter just to confirm when the module reads the config it does in fact determine no change is necessary. It's possible I'm using the running_config parameter incorrectly or maybe I misunderstand the meaning of the parameter. I have tried using stdout and stdout_lines from the ios_command output to get the running config.

PLAY [redsw1] *****************************************************************************************************************************************************************************************************************

TASK [test : VTP Off] *********************************************************************************************************************************************************************************************************
changed: [redsw1]

TASK [test : get running configuration] ***************************************************************************************************************************************************************************************
ok: [redsw1]

TASK [test : VTP Off Post] ****************************************************************************************************************************************************************************************************
changed: [redsw1]

TASK [test : VTP Off] *********************************************************************************************************************************************************************************************************
ok: [redsw1]

PLAY RECAP ********************************************************************************************************************************************************************************************************************
redsw1                     : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Copied from original issue: ansible/ansible#70731

ios_config block with multiple parents

SUMMARY

When using replace: block with ios_config with multiple layers of parents, the lines are re-applied for every level of parent.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_config

ANSIBLE VERSION
ansible 2.9.13
  config file = /home/arantz/ansibletest/ansible.cfg
  configured module search path = ['/home/arantz/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/arantz/ansibletest/venv/lib/python3.7/site-packages/ansible
  executable location = /home/arantz/ansibletest/venv/bin/ansible
  python version = 3.7.6 (default, Jan 19 2020, 22:34:52) [GCC 9.2.1 20200117]
CONFIGURATION
ANSIBLE_PIPELINING(/home/arantz/ansibletest/ansible.cfg) = True
CACHE_PLUGIN(/home/arantz/ansibletest/ansible.cfg) = yaml
CACHE_PLUGIN_CONNECTION(/home/arantz/ansibletest/ansible.cfg) = cache
CACHE_PLUGIN_PREFIX(/home/arantz/ansibletest/ansible.cfg) = cache
DEFAULT_CALLBACK_WHITELIST(/home/arantz/ansibletest/ansible.cfg) = ['timer']
DEFAULT_FORKS(/home/arantz/ansibletest/ansible.cfg) = 25
DEFAULT_HOST_LIST(/home/arantz/ansibletest/ansible.cfg) = ['/home/arantz/ansibletest/inventory']
DEFAULT_LOG_PATH(/home/arantz/ansibletest/ansible.cfg) = /home/arantz/ansibletest/log
HOST_KEY_CHECKING(/home/arantz/ansibletest/ansible.cfg) = False
PERSISTENT_COMMAND_TIMEOUT(/home/arantz/ansibletest/ansible.cfg) = 15
PERSISTENT_CONNECT_TIMEOUT(/home/arantz/ansibletest/ansible.cfg) = 90
OS / ENVIRONMENT

Controller is Ubuntu 18.04, devices are various Cisco IOS routers and switches.

STEPS TO REPRODUCE

ios_config task with multiple parents and replace: block

---
- hosts: all
  gather_facts: no
  tasks:
  - cisco.ios.ios_config:
      replace: block
      lines:
        - conform-action transmit
        - exceed-action drop
      parents:
        - policy-map Foo
        - class COS1
        - police rate percent 4
EXPECTED RESULTS

Should only apply the following lines:

  • policy-map Foo
  • class COS1
  • police rate percent 4
  • conform-action transmit
  • exceed-action drop
ACTUAL RESULTS
changed: [isr4k] => {
    "banners": {},
    "changed": true,
    "commands": [
        "policy-map Foo",
        "class COS1",
        "police rate percent 4",
        "conform-action transmit",
        "exceed-action drop",
        "class COS1",
        "police rate percent 4",
        "conform-action transmit",
        "exceed-action drop",
        "police rate percent 4",
        "conform-action transmit",
        "exceed-action drop"
    ],
    "invocation": {
        "module_args": {
            "after": null,
            "backup": false,
            "backup_options": null,
            "before": null,
            "defaults": false,
            "diff_against": null,
            "diff_ignore_lines": null,
            "intended_config": null,
            "lines": [
                "conform-action transmit",
                "exceed-action drop"
            ],
            "match": "line",
            "multiline_delimiter": "@",
            "parents": [
                "policy-map Foo",
                "class COS1",
                "police rate percent 4"
            ],
            "provider": null,
            "replace": "block",
            "running_config": null,
            "save_when": "never",
            "src": null
        }
    },
    "updates": [
        "policy-map Foo",
        "class COS1",
        "police rate percent 4",
        "conform-action transmit",
        "exceed-action drop",
        "class COS1",
        "police rate percent 4",
        "conform-action transmit",
        "exceed-action drop",
        "police rate percent 4",
        "conform-action transmit",
        "exceed-action drop"
    ]
}

Notice that the two lines from the lines attribute are ultimately applied 3 times. Verified on the router itself that this actually happening.

CMD: 'terminal length 0' 14:35:36 UTC Tue Sep 1 2020
CMD: 'terminal width 512' 14:35:36 UTC Tue Sep 1 2020
CMD: 'terminal width 0' 14:35:36 UTC Tue Sep 1 2020
CMD: 'show version' 14:35:36 UTC Tue Sep 1 2020
CMD: 'show running-config' 14:35:36 UTC Tue Sep 1 2020
CMD: 'configure terminal' 14:35:37 UTC Tue Sep 1 2020
CMD: 'policy-map Foo' 14:35:37 UTC Tue Sep 1 2020
CMD: 'class COS1' 14:35:37 UTC Tue Sep 1 2020
CMD: 'police rate percent 4' 14:35:37 UTC Tue Sep 1 2020
CMD: 'conform-action transmit' 14:35:37 UTC Tue Sep 1 2020
CMD: 'exceed-action drop' 14:35:37 UTC Tue Sep 1 2020
CMD: 'class COS1' 14:35:37 UTC Tue Sep 1 2020
CMD: 'police rate percent 4' 14:35:38 UTC Tue Sep 1 2020
CMD: 'conform-action transmit' 14:35:38 UTC Tue Sep 1 2020
CMD: 'exceed-action drop' 14:35:38 UTC Tue Sep 1 2020
CMD: 'police rate percent 4' 14:35:38 UTC Tue Sep 1 2020
CMD: 'conform-action transmit' 14:35:38 UTC Tue Sep 1 2020
CMD: 'exceed-action drop' 14:35:38 UTC Tue Sep 1 2020
CMD: 'end' 14:35:38 UTC Tue Sep 1 2020
%SYS-5-CONFIG_I: Configured from console by cisco on vty0 (192.168.100.2)

network_cli auth timeout due to slow return of: "Authentication (password) successful!"

From @cunningr on Jun 14, 2020 10:27

SUMMARY

network_cli times out authentication to device after 10 seconds. Unable to find a way to extend the timeout window for paramiko. This is occurring because the device is slow to complete authentication due to backend AAA method timeout.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

network_cli

ANSIBLE VERSION
ansible 2.7.7
  config file = /home/run/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.7.3 (default, Dec 20 2019, 18:57:59) [GCC 8.3.0]
CONFIGURATION
DEFAULT_LOG_PATH(env: ANSIBLE_LOG_PATH) = /root/ansible.log
HOST_KEY_CHECKING(env: ANSIBLE_HOST_KEY_CHECKING) = False
OS / ENVIRONMENT

Cisco catalyst 9K. IOS-XE.

STEPS TO REPRODUCE

Use any ios_command task when the IOS device has slow authentication response due to AAA timeout of device (E.g Cisco device to RADIUS).

  - name: Set HTTP Client Source to mgmt_int
    ios_config:
      lines:
       - ip http client source-interface {{ vars.mgmt_int }}
      provider:
        timeout: 15000
    when: vars.os == "XE"
    vars:
      ansible_persistent_log_messages: True
EXPECTED RESULTS

Successful login and command execution. This the log for a device that completes authentication;

2020-06-14 10:05:58,667 p=3410 u=root | paramiko [3.6.11.25] starting thread (client mode): 0xda77cc50
2020-06-14 10:05:58,667 p=3410 u=root | paramiko [3.6.11.25] Local version/idstring: SSH-2.0-paramiko_2.4.2
2020-06-14 10:05:59,269 p=3410 u=root | paramiko [3.6.11.25] Remote version/idstring: SSH-2.0-Cisco-1.25
2020-06-14 10:05:59,269 p=3410 u=root | paramiko [3.6.11.25] Connected (version 2.0, client Cisco-1.25)
2020-06-14 10:05:59,284 p=3410 u=root | paramiko [3.6.11.25] kex algos:['diffie-hellman-group-exchange-sha1', 'diffie-hellman-group14-sha1'] server key:['ssh-rsa'] client encrypt:['aes128-ctr', 'aes192-ctr', 'aes256-ctr'] server encrypt:['aes128-ctr', 'aes192-ctr', 'aes256-ctr'] client mac:['hmac-sha2-256', 'hmac-sha2-512', 'hmac-sha1', 'hmac-sha1-96'] server mac:['hmac-sha2-256', 'hmac-sha2-512', 'hmac-sha1', 'hmac-sha1-96'] client compress:['none'] server compress:['none'] client lang:[''] server lang:[''] kex follows?False
2020-06-14 10:05:59,285 p=3410 u=root | paramiko [3.6.11.25] Kex agreed: diffie-hellman-group-exchange-sha1
2020-06-14 10:05:59,285 p=3410 u=root | paramiko [3.6.11.25] HostKey agreed: ssh-rsa
2020-06-14 10:05:59,285 p=3410 u=root | paramiko [3.6.11.25] Cipher agreed: aes128-ctr
2020-06-14 10:05:59,285 p=3410 u=root | paramiko [3.6.11.25] MAC agreed: hmac-sha2-256
2020-06-14 10:05:59,285 p=3410 u=root | paramiko [3.6.11.25] Compression agreed: none
2020-06-14 10:05:59,319 p=3410 u=root | paramiko [3.6.11.25] Got server p (2048 bits)
2020-06-14 10:05:59,466 p=3410 u=root | paramiko [3.6.11.25] kex engine KexGex specified hash_algo <built-in function openssl_sha1>
2020-06-14 10:05:59,467 p=3410 u=root | paramiko [3.6.11.25] Switch to new keys ...
2020-06-14 10:05:59,501 p=3410 u=root | paramiko [3.6.11.25] userauth is OK
2020-06-14 10:05:59,535 p=3410 u=root | paramiko [3.6.11.25] Authentication (password) successful!
2020-06-14 10:05:59,535 p=3410 u=root | paramiko [3.6.11.25] [chan 0] Max packet in: 32768 bytes
2020-06-14 10:05:59,567 p=3410 u=root | paramiko [3.6.11.25] [chan 0] Max packet out: 4096 bytes
2020-06-14 10:05:59,568 p=3410 u=root | paramiko [3.6.11.25] Secsh channel 0 opened.
2020-06-14 10:05:59,600 p=3410 u=root | paramiko [3.6.11.25] [chan 0] Sesch channel 0 request ok
2020-06-14 10:05:59,633 p=3410 u=root | paramiko [3.6.11.25] [chan 0] Sesch channel 0 request ok
ACTUAL RESULTS

Randomly some devices will fail to complete login. In the debug logs this fails if the authentication doesn't complete within 10 seconds;

TASK [Set HTTP Client Source to mgmt_int] ***************************************************************************************************************************************************************************************************
changed: [POD1-FR-01]
changed: [POD1-CP-01]
changed: [POD1-FE-02]
changed: [POD1-FE-01]
fatal: [POD1-CP-02]: FAILED! => {"msg": "Invalid/incorrect username/password. Authentication timeout."}
skipping: [POD1-WLC-01]
fatal: [POD1-FE-03]: FAILED! => {"msg": "Invalid/incorrect username/password. Authentication timeout."}
fatal: [POD1-INT-01]: FAILED! => {"msg": "Invalid/incorrect username/password. Authentication timeout."}
fatal: [POD1-FB-01]: FAILED! => {"msg": "Invalid/incorrect username/password. Authentication timeout."}
fatal: [POD1-SS-01]: FAILED! => {"msg": "Invalid/incorrect username/password. Authentication timeout."}
2020-06-14 10:05:58,725 p=3416 u=root | paramiko [3.6.11.26] starting thread (client mode): 0xefacfc88
2020-06-14 10:05:58,726 p=3416 u=root | paramiko [3.6.11.26] Local version/idstring: SSH-2.0-paramiko_2.4.2
2020-06-14 10:05:59,407 p=3416 u=root | paramiko [3.6.11.26] Remote version/idstring: SSH-2.0-Cisco-1.25
2020-06-14 10:05:59,407 p=3416 u=root | paramiko [3.6.11.26] Connected (version 2.0, client Cisco-1.25)
2020-06-14 10:05:59,408 p=3416 u=root | paramiko [3.6.11.26] kex algos:['diffie-hellman-group-exchange-sha1', 'diffie-hellman-group14-sha1'] server key:['ssh-rsa'] client encrypt:['aes128-ctr', 'aes192-ctr', 'aes256-ctr'] server encrypt:['aes128-ctr', 'aes192-ctr', 'aes256-ctr'] client mac:['hmac-sha2-256', 'hmac-sha2-512', 'hmac-sha1', 'hmac-sha1-96'] server mac:['hmac-sha2-256', 'hmac-sha2-512', 'hmac-sha1', 'hmac-sha1-96'] client compress:['none'] server compress:['none'] client lang:[''] server lang:[''] kex follows?False
2020-06-14 10:05:59,408 p=3416 u=root | paramiko [3.6.11.26] Kex agreed: diffie-hellman-group-exchange-sha1
2020-06-14 10:05:59,408 p=3416 u=root | paramiko [3.6.11.26] HostKey agreed: ssh-rsa
2020-06-14 10:05:59,408 p=3416 u=root | paramiko [3.6.11.26] Cipher agreed: aes128-ctr
2020-06-14 10:05:59,408 p=3416 u=root | paramiko [3.6.11.26] MAC agreed: hmac-sha2-256
2020-06-14 10:05:59,408 p=3416 u=root | paramiko [3.6.11.26] Compression agreed: none
2020-06-14 10:05:59,442 p=3416 u=root | paramiko [3.6.11.26] Got server p (2048 bits)
2020-06-14 10:05:59,589 p=3416 u=root | paramiko [3.6.11.26] kex engine KexGex specified hash_algo <built-in function openssl_sha1>
2020-06-14 10:05:59,590 p=3416 u=root | paramiko [3.6.11.26] Switch to new keys ...
2020-06-14 10:05:59,623 p=3416 u=root | paramiko [3.6.11.26] userauth is OK
2020-06-14 10:06:09,682 p=3318 u=root |  fatal: [POD1-CP-02]: FAILED! => {"msg": "Invalid/incorrect username/password. Authentication timeout."}

Copied from original issue: ansible/ansible#70061

cisco.ios.ios_lag_interfaces producing strange output in override

SUMMARY

I'm running override mode, and it's generating the following commands...

{
    "commands": [
        "interface GigabitEthernet0/15",
        "channel-group 1 mode auto",
        "interface GigabitEthernet0/17",
        "channel-group 1 mode auto",
        "interface GigabitEthernet0/16",
        "no channel-group",
        "interface GigabitEthernet0/27",
        "no channel-group",
        "interface GigabitEthernet0/41",
        "no channel-group",
        "no channel-group",
        "channel-group 1 mode auto",
        "channel-group 1 mode auto",
        "no channel-group",
        "channel-group 2 mode auto",
        "interface GigabitEthernet0/18",
        "channel-group 2 mode auto",
        "no channel-group",
        "no channel-group",
        "no channel-group",
        "channel-group 2 mode auto",
        "channel-group 2 mode auto",
        "no channel-group",
        "no channel-group",
        "channel-group 3 mode auto",
        "channel-group 3 mode auto",
        "no channel-group",
        "no channel-group",
        "no channel-group",
        "channel-group 3 mode auto",
        "channel-group 3 mode auto"
    ],

With an input of:

{
    "changed": false,
    "ansible_facts": {
        "lagmap": [
            {
                "name": "Port-channel1",
                "members": [
                    {
                        "member": "GigabitEthernet0/15",
                        "mode": "auto"
                    },
                    {
                        "member": "GigabitEthernet0/17",
                        "mode": "auto"
                    }
                ]
            },
            {
                "name": "Port-channel2",
                "members": [
                    {
                        "member": "GigabitEthernet0/16",
                        "mode": "auto"
                    },
                    {
                        "member": "GigabitEthernet0/18",
                        "mode": "auto"
                    }
                ]
            },
            {
                "name": "Port-channel3",
                "members": [
                    {
                        "member": "GigabitEthernet0/27",
                        "mode": "auto"
                    },
                    {
                        "member": "GigabitEthernet0/41",
                        "mode": "auto"
                    }
                ]
            }
        ]
    },
    "_ansible_no_log": false
}
ISSUE TYPE
  • Bug Report
COMPONENT NAME
ANSIBLE VERSION
ansible 2.9.1
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.7/dist-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 3.7.3 (default, Dec 20 2019, 18:57:59) [GCC 8.3.0]

CONFIGURATION
OS / ENVIRONMENT

Debian 10 AWX 13

STEPS TO REPRODUCE
- name: Configure the LAGs
  cisco.ios.ios_lag_interfaces:
    config: '{{ lagmap }}'
    state: overridden
  when: lagmap | length > 0

EXPECTED RESULTS

I don't understand why It's sending multiple lag creations and then deletions in the same stream.. It makes no sense to me.

ACTUAL RESULTS

ios_banner breaks with first line chars

SUMMARY

If a banner contains characters on the first line before the line break, ios_banner crashes.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_banner

ANSIBLE VERSION
ansible 2.9.4
  config file = /home/arantz/change-scripts/ansible/ansible.cfg
  configured module search path = ['/home/arantz/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/arantz/change-scripts/ansible/venv3/lib/python3.6/site-packages/ansible
  executable location = /home/arantz/change-scripts/ansible/venv3/bin/ansible
  python version = 3.6.8 (default, Oct  7 2019, 12:59:55) [GCC 8.3.0]
CONFIGURATION
ANSIBLE_PIPELINING(/home/arantz/change-scripts/ansible/ansible.cfg) = True
DEFAULT_CALLBACK_WHITELIST(/home/arantz/change-scripts/ansible/ansible.cfg) = ['timer', 'json_result']
DEFAULT_FORKS(/home/arantz/change-scripts/ansible/ansible.cfg) = 45
DEFAULT_HOST_LIST(/home/arantz/change-scripts/ansible/ansible.cfg) = ['/home/arantz/change-scripts/ansible/inventories']
DEFAULT_LOCAL_TMP(/home/arantz/change-scripts/ansible/ansible.cfg) = /home/arantz/.ansible/tmp/ansible-local-16723s58fhpxr
DEFAULT_LOG_PATH(/home/arantz/change-scripts/ansible/ansible.cfg) = /home/arantz/change-scripts/ansible/logs/log
HOST_KEY_CHECKING(/home/arantz/change-scripts/ansible/ansible.cfg) = False
INTERPRETER_PYTHON(/home/arantz/change-scripts/ansible/ansible.cfg) = auto_silent
PERSISTENT_COMMAND_TIMEOUT(/home/arantz/change-scripts/ansible/ansible.cfg) = 120
PERSISTENT_CONNECT_TIMEOUT(/home/arantz/change-scripts/ansible/ansible.cfg) = 90
OS / ENVIRONMENT

Ubuntu 18.04 against Cisco IOS

STEPS TO REPRODUCE
- ios_banner:
    banner: login
    text: "test"
    state: present

Banner looks like:

banner login ^CC
Login banner
^C

Note the extra C (this is very common on restored configurations as people tend to forget to remove it when pasting in an old config)

EXPECTED RESULTS

Banner should be updated

ACTUAL RESULTS
The full traceback is:
Traceback (most recent call last):
  File "<stdin>", line 102, in <module>
  File "<stdin>", line 94, in _ansiballz_main
  File "<stdin>", line 40, in invoke_module
  File "/usr/lib/python3.6/runpy.py", line 205, in run_module
    return _run_module_code(code, init_globals, run_name, mod_spec)
  File "/usr/lib/python3.6/runpy.py", line 96, in _run_module_code
    mod_name, mod_spec, pkg_name, script_name)
  File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/tmp/ansible_ios_banner_payload_gn_g72hu/ansible_ios_banner_payload.zip/ansible/modules/network/ios/ios_banner.py", line 186, in <module>
  File "/tmp/ansible_ios_banner_payload_gn_g72hu/ansible_ios_banner_payload.zip/ansible/modules/network/ios/ios_banner.py", line 171, in main
  File "/tmp/ansible_ios_banner_payload_gn_g72hu/ansible_ios_banner_payload.zip/ansible/modules/network/ios/ios_banner.py", line 127, in map_config_to_obj
IndexError: list index out of range

fatal: [router]: FAILED! => {
  "changed": false,
  "module_stderr": "Traceback (most recent call last):\n  File \"<stdin>\", line 102, in <module>\n  File \"<stdin>\", line 94, in _ansiballz_main\n  File \"<stdin>\", line 40, in invoke_module\n  File \"/usr/lib/python3.6/runpy.py\", line 205, in run_module\n    return _run_module_code(code, init_globals, run_name, mod_spec)\n  File \"/usr/lib/python3.6/runpy.py\", line 96, in _run_module_code\n    mod_name, mod_spec, pkg_name, script_name)\n  File \"/usr/lib/python3.6/runpy.py\", line 85, in _run_code\n    exec(code, run_globals)\n  File \"/tmp/ansible_ios_banner_payload_gn_g72hu/ansible_ios_banner_payload.zip/ansible/modules/network/ios/ios_banner.py\", line 186, in <module>\n  File \"/tmp/ansible_ios_banner_payload_gn_g72hu/ansible_ios_banner_payload.zip/ansible/modules/network/ios/ios_banner.py\", line 171, in main\n  File \"/tmp/ansible_ios_banner_payload_gn_g72hu/ansible_ios_banner_payload.zip/ansible/modules/network/ios/ios_banner.py\", line 127, in map_config_to_obj\nIndexError: list index out of range\n",
  "module_stdout": "",
  "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
  "rc": 1
}

I attempted to backport ios_banner back into 2.9 so that I could use the functionality from ansible/ansible#62573 and got a crash. This is still an issue with the current code.

The issue is on lines https://github.com/ansible-collections/cisco.ios/blob/master/plugins/modules/ios_banner.py#L126-L128

It is not using the same string to match against as it is to split against, so if there any characters between the banner ^C start delimiter and the first new line, you get an IndexError.

In my particular scenario, the extra C is an error, and I corrected it by adding in a .* for extra characters and then using the searches results to split:

    if out:
        regex = 'banner ' + module.params["banner"] + ' \^C.*\n'
        matches = search(regex, out, M)
        if matches:
            output = str((out.split(matches[0]))[1].split("^C\n")[0])
        else:
            output = None

This doesn't allow for someone intentionally not having a newline at the beginning of the banner, but it does at least prevent it from tracing back. As per above, the extra Cs are a very common side effect of restoring a configuration.

unble to copy tfp file to flash: for cisco ios upgrade

SUMMARY

the playbook is related to cisco ios upgrade

ISSUE TYPE

Bug Report

COMPONENT NAME

ios_command

ANSIBLE VERSION
ansible 2.6.20
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.6/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.6.6 (r266:84292, Jun 20 2019, 14:14:55) [GCC 4.4.7 20120313 (Red Hat 4.4.7-23)]
CONFIGURATION
[root@bcre ansible]# ansible-config dump --only-changed
DEFAULT_HOST_LIST(/etc/ansible/ansible.cfg) = [u'/etc/ansible/hosts']
DEFAULT_TIMEOUT(/etc/ansible/ansible.cfg) = 60
HOST_KEY_CHECKING(/etc/ansible/ansible.cfg) = False
PERSISTENT_CONNECT_TIMEOUT(/etc/ansible/ansible.cfg) = 60
OS / ENVIRONMENT

cisco c2960 with ios c2900-universalk9-mz.SPA.152-4.M3.bin

STEPS TO REPRODUCE

copying FTP to flash: file

- name: UPGRADE ROUTER FIRMWARE
  hosts: "UPGRADE"
  gather_facts: false
  connection: network_cli

  vars:
    compliant_ios_version: 15.2

  tasks:
  #   - name: GATHER ROUTER FACTS
  #     ios_facts:

    - name: SET TFTP BLOCKSIZE 8192
      ios_config:
        commands:
          - "ip tftp blocksize 8192"

    - name: UPGRADE IOS IMAGE IF NOT COMPLIANT
      block:
      - name: COPY OVER IOS IMAGE
        ios_command:
          commands:
            # - command: 'copy tftp://10.122.1.79/c2900-universalk9-mz.SPA.157-3.M6.bin flash:'
            - command: 'copy ftp://FTP-TEMP:[email protected]/c2900-universalk9-mz.SPA.157-3.M6.bin flash:'
            # - command: 'copy flash:home.shtml nvram:'
              prompt: "c2900-universalk9-mz.SPA.157-3.M6.bin"
              answer: "\r"
        vars:
          ansible_command_timeout: 1800
EXPECTED RESULTS

actually to copy the .bin image to flash: as showed :

Pruebas#dir flash:
Directory of flash0:/

    1  -rw-    98981944  Jul 25 2013 18:40:00 +00:00  c2900-universalk9-mz.SPA.152-4.M3.bin
    2  -rw-        3064  Jul 25 2013 18:50:10 +00:00  cpconfig-29xx.cfg
    3  -rw-         944  Aug 19 2015 20:02:12 +00:00  vlan.dat
    4  drw-           0  Jul 25 2013 18:50:30 +00:00  ccpexp
  240  -rw-        2464  Jul 25 2013 18:52:12 +00:00  home.shtml
  241  -rw-   110493200   Jun 3 2020 20:49:40 +00:00  c2900-universalk9-mz.SPA.157-3.M6.bin
ACTUAL RESULTS
[root@bcre playbooks]# ansible-playbook upgrade_test_ios.yml -vvv
ansible-playbook 2.6.20
  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.6/site-packages/ansible
  executable location = /usr/bin/ansible-playbook
  python version = 2.6.6 (r266:84292, Jun 20 2019, 14:14:55) [GCC 4.4.7 20120313 (Red Hat 4.4.7-23)]
Using /etc/ansible/ansible.cfg as config file
Parsed /etc/ansible/hosts inventory source with ini plugin

PLAYBOOK: upgrade_test_ios.yml ************************************************************************
1 plays in upgrade_test_ios.yml

PLAY [UPGRADE ROUTER FIRMWARE] ************************************************************************
META: ran handlers

TASK [SET TFTP BLOCKSIZE 8192] ************************************************************************
task path: /etc/ansible/playbooks/upgrade_test_ios.yml:14
<10.120.9.40> ESTABLISH LOCAL CONNECTION FOR USER: collectorlogin
<10.120.9.40> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-local-15530vSjFF7/ansible-tmp-1591217746.72-128062981726310 `" && echo ansible-tmp-1591217746.72-128062981726310="` echo /root/.ansible/tmp/ansible-local-15530vSjFF7/ansible-tmp-1591217746.72-128062981726310 `" ) && sleep 0'
Using module file /usr/lib/python2.6/site-packages/ansible/modules/network/ios/ios_config.py
<10.120.9.40> PUT /root/.ansible/tmp/ansible-local-15530vSjFF7/tmps2A2vH TO /root/.ansible/tmp/ansible-local-15530vSjFF7/ansible-tmp-1591217746.72-128062981726310/ios_config.py
<10.120.9.40> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-local-15530vSjFF7/ansible-tmp-1591217746.72-128062981726310/ /root/.ansible/tmp/ansible-local-15530vSjFF7/ansible-tmp-1591217746.72-128062981726310/ios_config.py && sleep 0'
<10.120.9.40> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-local-15530vSjFF7/ansible-tmp-1591217746.72-128062981726310/ios_config.py && sleep 0'
<10.120.9.40> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-local-15530vSjFF7/ansible-tmp-1591217746.72-128062981726310/ > /dev/null 2>&1 && sleep 0'
ok: [C2900] => {
    "changed": false, 
    "invocation": {
        "module_args": {
            "after": null, 
            "auth_pass": null, 
            "authorize": null, 
            "backup": false, 
            "before": null, 
            "commands": [
                "ip tftp blocksize 8192"
            ], 
            "defaults": false, 
            "diff_against": null, 
            "diff_ignore_lines": null, 
            "force": false, 
            "host": null, 
            "intended_config": null, 
            "lines": [
                "ip tftp blocksize 8192"
            ], 
            "match": "line", 
            "multiline_delimiter": "@", 
            "parents": null, 
            "password": null, 
            "port": null, 
            "provider": null, 
            "replace": "line", 
            "running_config": null, 
            "save": false, 
            "save_when": "never", 
            "src": null, 
            "ssh_keyfile": null, 
            "timeout": null, 
            "username": null
        }
    }
}

TASK [COPY OVER IOS IMAGE] ****************************************************************************
task path: /etc/ansible/playbooks/upgrade_test_ios.yml:21
<10.120.9.40> ESTABLISH LOCAL CONNECTION FOR USER: collectorlogin
<10.120.9.40> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-local-15530vSjFF7/ansible-tmp-1591217748.2-163814151592940 `" && echo ansible-tmp-1591217748.2-163814151592940="` echo /root/.ansible/tmp/ansible-local-15530vSjFF7/ansible-tmp-1591217748.2-163814151592940 `" ) && sleep 0'
Using module file /usr/lib/python2.6/site-packages/ansible/modules/network/ios/ios_command.py
<10.120.9.40> PUT /root/.ansible/tmp/ansible-local-15530vSjFF7/tmps2A2vH TO /root/.ansible/tmp/ansible-local-15530vSjFF7/ansible-tmp-1591217748.2-163814151592940/ios_command.py
<10.120.9.40> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-local-15530vSjFF7/ansible-tmp-1591217748.2-163814151592940/ /root/.ansible/tmp/ansible-local-15530vSjFF7/ansible-tmp-1591217748.2-163814151592940/ios_command.py && sleep 0'
<10.120.9.40> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-local-15530vSjFF7/ansible-tmp-1591217748.2-163814151592940/ios_command.py && sleep 0'
<10.120.9.40> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-local-15530vSjFF7/ansible-tmp-1591217748.2-163814151592940/ > /dev/null 2>&1 && sleep 0'
ok: [C2900] => {
    "changed": false, 
    "invocation": {
        "module_args": {
            "auth_pass": null, 
            "authorize": null, 
            "commands": [
                {
                    "answer": "\r", 
                    "command": "copy ftp://FTP-TEMP:[email protected]/c2900-universalk9-mz.SPA.157-3.M6.bin flash:", 
                    "prompt": "c2900-universalk9-mz.SPA.157-3.M6.bin"
                }
            ], 
            "host": null, 
            "interval": 1, 
            "match": "all", 
            "password": null, 
            "port": null, 
            "provider": null, 
            "retries": 10, 
            "ssh_keyfile": null, 
            "timeout": null, 
            "username": null, 
            "wait_for": null
        }
    }, 
    "stdout": [
        "None"
    ], 
    "stdout_lines": [
        [
            "None"
        ]
    ]
}
META: ran handlers
META: ran handlers

PLAY RECAP ********************************************************************************************
C2900                      : ok=2    changed=0    unreachable=0    failed=0   

[root@bcre playbooks]# ansible-playbook upgrade_test_ios.yml -vvvv
ansible-playbook 2.6.20
  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.6/site-packages/ansible
  executable location = /usr/bin/ansible-playbook
  python version = 2.6.6 (r266:84292, Jun 20 2019, 14:14:55) [GCC 4.4.7 20120313 (Red Hat 4.4.7-23)]
Using /etc/ansible/ansible.cfg as config file
setting up inventory plugins
Parsed /etc/ansible/hosts inventory source with ini plugin
Loading callback plugin default of type stdout, v2.0 from /usr/lib/python2.6/site-packages/ansible/plugins/callback/default.pyc

PLAYBOOK: upgrade_test_ios.yml ************************************************************************
1 plays in upgrade_test_ios.yml

PLAY [UPGRADE ROUTER FIRMWARE] ************************************************************************
META: ran handlers

TASK [SET TFTP BLOCKSIZE 8192] ************************************************************************
task path: /etc/ansible/playbooks/upgrade_test_ios.yml:14
<10.120.9.40> attempting to start connection
<10.120.9.40> using connection plugin network_cli
<10.120.9.40> local domain socket does not exist, starting it
<10.120.9.40> control socket path is /root/.ansible/pc/715faa4189
<10.120.9.40> <10.120.9.40> ESTABLISH CONNECTION FOR USER: admin on PORT 22 TO 10.120.9.40
<10.120.9.40> <10.120.9.40> ssh connection done, setting terminal
<10.120.9.40> <10.120.9.40> loaded terminal plugin for network_os ios
<10.120.9.40> <10.120.9.40> loaded cliconf plugin for network_os ios
<10.120.9.40> <10.120.9.40> firing event: on_open_shell()
<10.120.9.40> <10.120.9.40> ssh connection has completed successfully
<10.120.9.40> connection to remote device started successfully
<10.120.9.40> local domain socket listeners started successfully
<10.120.9.40> 
<10.120.9.40> local domain socket path is /root/.ansible/pc/715faa4189
<10.120.9.40> ESTABLISH LOCAL CONNECTION FOR USER: collectorlogin
<10.120.9.40> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-local-15621vwvHXC/ansible-tmp-1591217798.96-208000181452213 `" && echo ansible-tmp-1591217798.96-208000181452213="` echo /root/.ansible/tmp/ansible-local-15621vwvHXC/ansible-tmp-1591217798.96-208000181452213 `" ) && sleep 0'
Using module file /usr/lib/python2.6/site-packages/ansible/modules/network/ios/ios_config.py
<10.120.9.40> PUT /root/.ansible/tmp/ansible-local-15621vwvHXC/tmpnaukL8 TO /root/.ansible/tmp/ansible-local-15621vwvHXC/ansible-tmp-1591217798.96-208000181452213/ios_config.py
<10.120.9.40> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-local-15621vwvHXC/ansible-tmp-1591217798.96-208000181452213/ /root/.ansible/tmp/ansible-local-15621vwvHXC/ansible-tmp-1591217798.96-208000181452213/ios_config.py && sleep 0'
<10.120.9.40> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-local-15621vwvHXC/ansible-tmp-1591217798.96-208000181452213/ios_config.py && sleep 0'
<10.120.9.40> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-local-15621vwvHXC/ansible-tmp-1591217798.96-208000181452213/ > /dev/null 2>&1 && sleep 0'
ok: [C2900] => {
    "changed": false, 
    "invocation": {
        "module_args": {
            "after": null, 
            "auth_pass": null, 
            "authorize": null, 
            "backup": false, 
            "before": null, 
            "commands": [
                "ip tftp blocksize 8192"
            ], 
            "defaults": false, 
            "diff_against": null, 
            "diff_ignore_lines": null, 
            "force": false, 
            "host": null, 
            "intended_config": null, 
            "lines": [
                "ip tftp blocksize 8192"
            ], 
            "match": "line", 
            "multiline_delimiter": "@", 
            "parents": null, 
            "password": null, 
            "port": null, 
            "provider": null, 
            "replace": "line", 
            "running_config": null, 
            "save": false, 
            "save_when": "never", 
            "src": null, 
            "ssh_keyfile": null, 
            "timeout": null, 
            "username": null
        }
    }
}

TASK [COPY OVER IOS IMAGE] ****************************************************************************
task path: /etc/ansible/playbooks/upgrade_test_ios.yml:21
<10.120.9.40> attempting to start connection
<10.120.9.40> using connection plugin network_cli
<10.120.9.40> found existing local domain socket, using it!
<10.120.9.40> updating play_context for connection
<10.120.9.40> 
<10.120.9.40> local domain socket path is /root/.ansible/pc/715faa4189
<10.120.9.40> ESTABLISH LOCAL CONNECTION FOR USER: collectorlogin
<10.120.9.40> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-local-15621vwvHXC/ansible-tmp-1591217800.42-231527887211661 `" && echo ansible-tmp-1591217800.42-231527887211661="` echo /root/.ansible/tmp/ansible-local-15621vwvHXC/ansible-tmp-1591217800.42-231527887211661 `" ) && sleep 0'
Using module file /usr/lib/python2.6/site-packages/ansible/modules/network/ios/ios_command.py
<10.120.9.40> PUT /root/.ansible/tmp/ansible-local-15621vwvHXC/tmpnaukL8 TO /root/.ansible/tmp/ansible-local-15621vwvHXC/ansible-tmp-1591217800.42-231527887211661/ios_command.py
<10.120.9.40> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-local-15621vwvHXC/ansible-tmp-1591217800.42-231527887211661/ /root/.ansible/tmp/ansible-local-15621vwvHXC/ansible-tmp-1591217800.42-231527887211661/ios_command.py && sleep 0'
<10.120.9.40> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-local-15621vwvHXC/ansible-tmp-1591217800.42-231527887211661/ios_command.py && sleep 0'
<10.120.9.40> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-local-15621vwvHXC/ansible-tmp-1591217800.42-231527887211661/ > /dev/null 2>&1 && sleep 0'
ok: [C2900] => {
    "changed": false, 
    "invocation": {
        "module_args": {
            "auth_pass": null, 
            "authorize": null, 
            "commands": [
                {
                    "answer": "\r", 
                    "command": "copy ftp://FTP-TEMP:[email protected]/c2900-universalk9-mz.SPA.157-3.M6.bin flash:", 
                    "prompt": "c2900-universalk9-mz.SPA.157-3.M6.bin"
                }
            ], 
            "host": null, 
            "interval": 1, 
            "match": "all", 
            "password": null, 
            "port": null, 
            "provider": null, 
            "retries": 10, 
            "ssh_keyfile": null, 
            "timeout": null, 
            "username": null, 
            "wait_for": null
        }
    }, 
    "stdout": [
        "None"
    ], 
    "stdout_lines": [
        [
            "None"
        ]
    ]
}
META: ran handlers
META: ran handlers

PLAY RECAP ********************************************************************************************
C2900                      : ok=2    changed=0    unreachable=0    failed=0 

ios_l2_interfaces in replaced mode fails on fresh ports

SUMMARY

Attempt to run playbook fails with exception if pruning not defined

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_l2_interfaces
may be related to ansible/ansible#65032, as it works if port mode defined.

ANSIBLE VERSION
~/network-ansible$ ansible --version
ansible 2.9.4
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'user path hidden', 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.17 (default, Nov  7 2019, 10:07:09) [GCC 7.4.0]
CONFIGURATION
OS / ENVIRONMENT

Cisco WS-C3750X-48 running 15.2(4)E1

STEPS TO REPRODUCE

Run below playbook against fresh port, that has no configuration yet:
interface GigabitEthernet1/0/13
!

However, if replaced changed to merged, module works as expected.

- name: Replaces device configuration of listed l2 interfaces with provided configuration
  ios_l2_interfaces:
    config:
      - name: GigabitEthernet0/2
        trunk:
        - allowed_vlan: 20-25,40
          native_vlan: 20
          encapsulation: dot1q
    state: replaced
EXPECTED RESULTS

Successful port configuration

ACTUAL RESULTS

Module though an error

The full traceback is:
Traceback (most recent call last):
...
  File "/tmp/ansible_ios_l2_interfaces_payload_DjCV5p/ansible_ios_l2_interfaces_payload.zip/ansible/modules/network/ios/ios_l2_interfaces.py", line 364, in <module>
  File "/tmp/ansible_ios_l2_interfaces_payload_DjCV5p/ansible_ios_l2_interfaces_payload.zip/ansible/modules/network/ios/ios_l2_interfaces.py", line 359, in main
  File "/tmp/ansible_ios_l2_interfaces_payload_DjCV5p/ansible_ios_l2_interfaces_payload.zip/ansible/module_utils/network/ios/config/l2_interfaces/l2_interfaces.py", line 63, in execute_module
  File "/tmp/ansible_ios_l2_interfaces_payload_DjCV5p/ansible_ios_l2_interfaces_payload.zip/ansible/module_utils/network/ios/config/l2_interfaces/l2_interfaces.py", line 88, in set_config
  File "/tmp/ansible_ios_l2_interfaces_payload_DjCV5p/ansible_ios_l2_interfaces_payload.zip/ansible/module_utils/network/ios/config/l2_interfaces/l2_interfaces.py", line 113, in set_state
  File "/tmp/ansible_ios_l2_interfaces_payload_DjCV5p/ansible_ios_l2_interfaces_payload.zip/ansible/module_utils/network/ios/config/l2_interfaces/l2_interfaces.py", line 134, in _state_replaced
  File "/tmp/ansible_ios_l2_interfaces_payload_DjCV5p/ansible_ios_l2_interfaces_payload.zip/ansible/module_utils/network/ios/utils/utils.py", line 75, in filter_dict_having_none_value
AttributeError: 'NoneType' object has no attribute 'get'

Please add support for specifying syslog port number and transport type in the ios_logging module

SUMMARY
The ios_logging module does not support configuring logging on Cisco IOS to non standard syslog ports. Standard port is UDP 514, but some log collectors listen on different ports.

ISSUE TYPE
Feature Idea
Create a transport parameter so that users can specify sending syslog messages to different ports. I would like to see it support the following command:
logging host 1.2.3.4 transport udp port 1234
On Cisco devices, tcp transport is also supported. I'd like to see that as well.
COMPONENT NAME
This should be supported in the ios_logging module.

ADDITIONAL INFORMATION
There are services such as Sumologic that collect logs from an organization and keep them in the cloud. Internally there are collectors that devices point their logs to and in turn are redirected to Sumologic. Different port numbers are sometimes used to distinguish different types of devices. For example, firewalls might log to port 11111, routers to port 22222, etc.

Command would be: logging host 1.2.3.4 transport udp port 1234

it could look like this in the yaml file:

  • name:
    ios_logging:
    • dest: host
    • name: 1.2.3.4
    • transport: udp
    • port: 1234
    • state: present

I opened this issue in a different repository and was asked to resubmit this request here by maintainer danielmellado.
ansible/ansible#67314 (comment)

Detection of Virtual Switch System on IOS based Switches

SUMMARY

With IOS/IOS-XE based switches (on some plattforms C4500X, C650X-E, C6800) it is possible
to form a Virtual Switch System (VSS) from two physical switches. The current fact module for ios is capable to detect "stacked" switches but not "Virtual Switch System"

If a VSS is detected, one or two additional facts will/can be added, e.g.:

        "net_virtual_switch": "VSS",
        "net_virtual_switch_domain": "102",

The fact net_virtual_switch_domain is the needed switch virtual domain configuration. The other fact can be ommited, maybe only the domain is enough. Sometimes it may be nice to had a single fact which differs between "virtual_switch variants". VSS and STACK can be the current ones for IOS/IOS-XE.

ISSUE TYPE
  • Feature Idea
COMPONENT NAME

ios_facts

ADDITIONAL INFORMATION

I had a working patch and can issue an pull request in the next days if this is
acceptable.

ios_user sshkey does not remove/replace existing keys

SUMMARY

We are configuring users with:

- name: "Create user {{ item.user }}"
  ios_user:
    name: "{{ item.user }}"
    sshkey: "{{ item.keylist }}"
    role: network-admin
    privilege: 1
    state: present
  become: yes

however when we change the list of ssh keys, it does not replace the existing ssh keys in the config.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_user

ANSIBLE VERSION
ansible 2.9.9
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/export/home/orion-admin/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /bin/ansible
  python version = 2.7.5 (default, Apr  1 2020, 10:09:19) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
CONFIGURATION
empty
OS / ENVIRONMENT

EL7

Cisco IOS Software, C2960S Software (C2960S-UNIVERSALK9-M), Version 15.2(2)E9, RELEASE SOFTWARE (fc4)

STEPS TO REPRODUCE
---
- hosts: ios
  tasks:
    - name: "Create user testuser"
      ios_user:
        name: testuser
        sshkey:
          - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCxko6+8zhPJn010N99aM1EMogLHjzItU4QWhqRJ5Se6K24q8JaxgdFrysKJkR/W4scw0PPTz/jIl3FRMJi/LIFlDoSgeZRywmDLQRhmHbSCysnr3aUURI4QYdNeKX6wV7ORviWCIG66rUKdRCdVGFWxNYUTcXoTlYcgbOvHi/OWS2ppdRPrJpOGj3lr2UYcuyCJ+43SGhhPKrTWgq/XeKi8D9rK4CuQzxSAk6zmA9m+v68oiGlMMJgsCWp/VE+Cjl3FWmTf+kfwQ+JpMmiN3QD7Unlhwr4ExQLdl9m8504vh7Gk2KcCT/FrMfdf+9UJueXTovXVXagegGxubADS+fh
          - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCns7Q+QLg2MQ04mu+0EPJpRXqdgdw+tUAEgBwqbvKLr4xmf3WVmsIZlN2ZOywuNSdb9k2BQJCXuZKxSHYKBtmN9k1kdYtGEVAQC7i1rOQklKjrD4MmhUIAyuKd9q8cOoabnxmubpitxaz1aFfAMqsjg+PCFho7mjjV0s8+VTzG9waQ4SEQcV6wEi/AkqNRQREPbbHptfDqKkPY3plDspee/dvRfPd6QzAWLcpgSLVYRlLw+h+7MTAu7aotxto8R8kBdsBE//d1Gyo1y+S0Q8qDJ6c4klr6E8jbDeWQN+jqiQWGGTSiV8ntrKG1LB0xOjelQ1A8jAb0QCSSNFptfD5r
        state: present
      become: yes
    - name: "Modify user testuser"
      ios_user:
        name: testuser
        sshkey:
          - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0xBuag8zlMxJ2+SXkkgcO8l5nmCqFzF5BgwfxCq6sj/BVn4aoN5lsECr+YAQEie6ZXrXWI/qIvbg4WRVW/htIMLeOd5AqKO7RPe6oaTF80FrmaFjAR4gxHFVwqnBINhTv1wgHwcazfyd3MA0p/BY0kR+DnllQ4ro7+yBBBXYZet/PuHJaAq9wQKvL1n4+TqbhSIXI3Bi7BrI0y+DgTfQq5LhyxdtYKOcKfdTLAlBVuzGEAsAVOQe5c6oOOZSe5xmrd7OQhqhpXhpUz5NcpqeVUXIgz9erq+PGHCHEmTD885TxlYBQjV2x5OO0wR/fahESL3vCtQMX4ZvG0HjtssCn
          - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0rbm0RJlpt16T8hM4TJauyh+1pQZI6tzlMPMAvljpo52KNXof9zf5z21kn+fmWmESkuHi32Ddzx5u+QoOu7YngDa+Ek/vfMpoLCpc2ioyJTXyOSArj3PLllNzSRewm5LJYxhKYqz7PegfTR9m0+NpNYh6vOIm9rzLFmG5+MZJdkv8zwZoIYbcON+ZAZDczGxinTSU5qK/G8c20CdDJbNyu+YWnd2B0owhgXlq7faddG/aXEpIT3FDJtTcX0EjHLyh1Zr2IIZiMvRlRLdTl2Kq4ujNYJcYSiQGkAfXo5KEyC2iZh5k2m+7qyE7v82m+MXUdVtcFtuw4fTj1edSnOBv
        state: present
      become: yes
EXPECTED RESULTS

testuser is left with the ssh keys of the second invocation.

ACTUAL RESULTS
ansible-playbook 2.9.9
  config file = /export/home/orion-admin/ansible-network/ansible.cfg
  configured module search path = [u'/export/home/orion-admin/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /bin/ansible-playbook
  python version = 2.7.5 (default, Apr  1 2020, 10:09:19) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
Using /export/home/orion-admin/ansible-network/ansible.cfg as config file
BECOME password: 
host_list declined parsing /export/home/orion-admin/ansible-network/hosts as it did not pass its verify_file() method
script declined parsing /export/home/orion-admin/ansible-network/hosts as it did not pass its verify_file() method
auto declined parsing /export/home/orion-admin/ansible-network/hosts as it did not pass its verify_file() method
Parsed /export/home/orion-admin/ansible-network/hosts inventory source with ini plugin

PLAYBOOK: ios_user_sshkey.yml **********************************************************************************************************************************************
1 plays in ios_user_sshkey.yml

PLAY [ios] *****************************************************************************************************************************************************************
META: ran handlers

TASK [Create user testuser] ************************************************************************************************************************************************
task path: /export/home/orion-admin/ansible-network/ios_user_sshkey.yml:4
<switch-2960s> Attempting python interpreter discovery
<switch-2960s> ESTABLISH LOCAL CONNECTION FOR USER: orion-admin
<switch-2960s> EXEC /bin/sh -c 'echo PLATFORM; uname; echo FOUND; command -v '"'"'/usr/bin/python'"'"'; command -v '"'"'python3.7'"'"'; command -v '"'"'python3.6'"'"'; command -v '"'"'python3.5'"'"'; command -v '"'"'python2.7'"'"'; command -v '"'"'python2.6'"'"'; command -v '"'"'/usr/libexec/platform-python'"'"'; command -v '"'"'/usr/bin/python3'"'"'; command -v '"'"'python'"'"'; echo ENDFOUND && sleep 0'                                                                                          
<switch-2960s> EXEC /bin/sh -c '/usr/bin/python && sleep 0'
Using module file /usr/lib/python2.7/site-packages/ansible/modules/network/ios/ios_user.py
Pipelining is enabled.
<switch-2960s> EXEC /bin/sh -c '/usr/bin/python && sleep 0'
[WARNING]: Module did not set no_log for update_password
[WARNING]: Module did not set no_log for password_type
changed: [switch-2960s] => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "commands": [
        "ip ssh pubkey-chain", 
        "username testuser", 
        "key-hash ssh-rsa 2723856A8FDEDC5E54262B1AB5D70357", 
        "key-hash ssh-rsa 18F3175F7C08ADBEBDDB35E892FFCAD0", 
        "exit", 
        "exit"
    ], 
    "invocation": {
        "module_args": {
            "aggregate": null, 
            "auth_pass": null, 
            "authorize": null, 
            "configured_password": null, 
            "hashed_password": null, 
            "host": null, 
            "name": "testuser", 
            "nopassword": null, 
            "password": null, 
            "password_type": "secret", 
            "port": null, 
            "privilege": null, 
            "provider": null, 
            "purge": false, 
            "ssh_keyfile": null, 
            "sshkey": [
                "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCxko6+8zhPJn010N99aM1EMogLHjzItU4QWhqRJ5Se6K24q8JaxgdFrysKJkR/W4scw0PPTz/jIl3FRMJi/LIFlDoSgeZRywmDLQRhmHbSCysnr3aUURI4QYdNeKX6wV7ORviWCIG66rUKdRCdVGFWxNYUTcXoTlYcgbOvHi/OWS2ppdRPrJpOGj3lr2UYcuyCJ+43SGhhPKrTWgq/XeKi8D9rK4CuQzxSAk6zmA9m+v68oiGlMMJgsCWp/VE+Cjl3FWmTf+kfwQ+JpMmiN3QD7Unlhwr4ExQLdl9m8504vh7Gk2KcCT/FrMfdf+9UJueXTovXVXagegGxubADS+fh",                                                                                                                     
                "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCns7Q+QLg2MQ04mu+0EPJpRXqdgdw+tUAEgBwqbvKLr4xmf3WVmsIZlN2ZOywuNSdb9k2BQJCXuZKxSHYKBtmN9k1kdYtGEVAQC7i1rOQklKjrD4MmhUIAyuKd9q8cOoabnxmubpitxaz1aFfAMqsjg+PCFho7mjjV0s8+VTzG9waQ4SEQcV6wEi/AkqNRQREPbbHptfDqKkPY3plDspee/dvRfPd6QzAWLcpgSLVYRlLw+h+7MTAu7aotxto8R8kBdsBE//d1Gyo1y+S0Q8qDJ6c4klr6E8jbDeWQN+jqiQWGGTSiV8ntrKG1LB0xOjelQ1A8jAb0QCSSNFptfD5r"                                                                                                                      
            ], 
            "state": "present", 
            "timeout": null, 
            "update_password": "always", 
            "username": null, 
            "view": null
        }
    }
}

TASK [Modify user testuser] ************************************************************************************************************************************************
task path: /export/home/orion-admin/ansible-network/ios_user_sshkey.yml:12
Using module file /usr/lib/python2.7/site-packages/ansible/modules/network/ios/ios_user.py
Pipelining is enabled.
<switch-2960s> ESTABLISH LOCAL CONNECTION FOR USER: orion-admin
<switch-2960s> EXEC /bin/sh -c '/usr/bin/python && sleep 0'
changed: [switch-2960s] => {
    "changed": true, 
    "commands": [
        "ip ssh pubkey-chain", 
        "username testuser", 
        "key-hash ssh-rsa FFFE5EDD40AA702CAE06DFDAE95F0924", 
        "key-hash ssh-rsa D79DBEA16EFAC377BCB3740E0A793053", 
        "exit", 
        "exit"
    ],
    "invocation": {
        "module_args": {
            "aggregate": null,
            "auth_pass": null,
            "authorize": null,
            "configured_password": null,
            "hashed_password": null,
            "host": null,
            "name": "testuser",
            "nopassword": null,
            "password": null,
            "password_type": "secret",
            "port": null,
            "privilege": null,
            "provider": null,
            "purge": false,
            "ssh_keyfile": null,
            "sshkey": [
                "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0xBuag8zlMxJ2+SXkkgcO8l5nmCqFzF5BgwfxCq6sj/BVn4aoN5lsECr+YAQEie6ZXrXWI/qIvbg4WRVW/htIMLeOd5AqKO7RPe6oaTF80FrmaFjAR4gxHFVwqnBINhTv1wgHwcazfyd3MA0p/BY0kR+DnllQ4ro7+yBBBXYZet/PuHJaAq9wQKvL1n4+TqbhSIXI3Bi7BrI0y+DgTfQq5LhyxdtYKOcKfdTLAlBVuzGEAsAVOQe5c6oOOZSe5xmrd7OQhqhpXhpUz5NcpqeVUXIgz9erq+PGHCHEmTD885TxlYBQjV2x5OO0wR/fahESL3vCtQMX4ZvG0HjtssCn",
                "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0rbm0RJlpt16T8hM4TJauyh+1pQZI6tzlMPMAvljpo52KNXof9zf5z21kn+fmWmESkuHi32Ddzx5u+QoOu7YngDa+Ek/vfMpoLCpc2ioyJTXyOSArj3PLllNzSRewm5LJYxhKYqz7PegfTR9m0+NpNYh6vOIm9rzLFmG5+MZJdkv8zwZoIYbcON+ZAZDczGxinTSU5qK/G8c20CdDJbNyu+YWnd2B0owhgXlq7faddG/aXEpIT3FDJtTcX0EjHLyh1Zr2IIZiMvRlRLdTl2Kq4ujNYJcYSiQGkAfXo5KEyC2iZh5k2m+7qyE7v82m+MXUdVtcFtuw4fTj1edSnOBv"
            ],
            "state": "present",
            "timeout": null,
            "update_password": "always",
            "username": null,
            "view": null
        }
    }
}
META: ran handlers
META: ran handlers

PLAY RECAP *****************************************************************************************************************************************************************
switch-2960s : ok=2    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

show run reports:

  username testuser
   key-hash ssh-rsa 2723856A8FDEDC5E54262B1AB5D70357
   key-hash ssh-rsa 18F3175F7C08ADBEBDDB35E892FFCAD0

which if you compare to the output above is the hashes from the first invocation.

unable to elevate privilege to enable mode, at prompt [Hostname]

From @tamil93-ss on Jun 13, 2020 13:18

SUMMARY

When trying to use ios_facts and any other ios_* queries to gather facts from the device, it fails with a timeout when trying to become using enable. It fails with the same error when trying ios_config.

ANSIBLE VERSION

ansible 2.9.9
python version=2.7.5

ans also in that server we have ansible3,python3.6 as well.

[defaults]
timeout = 60

[persistent_connection]
command_timeout = 1800
persistent_connect_timeout = 1800

OS / ENVIRONMENT

Ubuntu 
Cisco 3750

STEPS TO REPRODUCE


  • name: Get facts from switch
    hosts: switch
    gather_facts: no
    tasks:
    • name: gather facts
      ios_facts:
      register: out

    • debug: var=out

    • name: Test reachability to 10.10.10.10 using default vrf
      ios_ping:
      dest: 172.16.101.1
      register: output

      • debug: var=output

[switch]
c3750 ansible_host=172.16.148.1

[switch:vars]
ansible_become=yes
ansible_become_method=enable
ansible_network_os=ios
ansible_connection=network_cli
ansible_user=cisco
ansible_password=cisco

Run with: ansible-playbook -i switch_inventory getfacts.yml --ask-become-pass

[pts/57][nsrv ] /etc/ansible>ansible-playbook test.yaml --ask-become-pass -vvv
ansible-playbook 2.9.9
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/home/e1085411/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible-playbook
python version = 2.7.5 (default, Aug 7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
Using /etc/ansible/ansible.cfg as config file
BECOME password:
host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Parsed /etc/ansible/hosts inventory source with ini plugin

PLAYBOOK: test.yaml *********************************************************************************************************************
1 plays in test.yaml

PLAY [Show Run file config] *************************************************************************************************************
META: ran handlers

TASK [version] **************************************************************************************************************************
task path: /etc/ansible/test.yaml:9
<172.16.148.1> ESTABLISH LOCAL CONNECTION FOR USER: e1085411
<172.16.148.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "echo /home/e1085411/.ansible/tmp/ansible-local-13695hkZWd1"&& mkdir /home/e1085411/.ansible/tmp/ansible-local-13695hkZWd1/ansible-tmp-1592053415.03-13764-267572791218699 && echo ansible-tmp-1592053415.03-13764-267572791218699="echo /home/e1085411/.ansible/tmp/ansible-local-13695hkZWd1/ansible-tmp-1592053415.03-13764-267572791218699" ) && sleep 0'
<172.16.148.1> Attempting python interpreter discovery
<172.16.148.1> EXEC /bin/sh -c 'echo PLATFORM; uname; echo FOUND; command -v '"'"'/usr/bin/python'"'"'; command -v '"'"'python3.7'"'"'; command -v '"'"'python3.6'"'"'; command -v '"'"'python3.5'"'"'; command -v '"'"'python2.7'"'"'; command -v '"'"'python2.6'"'"'; command -v '"'"'/usr/libexec/platform-python'"'"'; command -v '"'"'/usr/bin/python3'"'"'; command -v '"'"'python'"'"'; echo ENDFOUND && sleep 0'
<172.16.148.1> EXEC /bin/sh -c '/usr/bin/python && sleep 0'
Using module file /usr/lib/python2.7/site-packages/ansible/modules/network/ios/ios_ping.py
<172.16.148.1> PUT /home/e1085411/.ansible/tmp/ansible-local-13695hkZWd1/tmpHtEXR2 TO /home/e1085411/.ansible/tmp/ansible-local-13695hkZWd1/ansible-tmp-1592053415.03-13764-267572791218699/AnsiballZ_ios_ping.py
<172.16.148.1> EXEC /bin/sh -c 'chmod u+x /home/e1085411/.ansible/tmp/ansible-local-13695hkZWd1/ansible-tmp-1592053415.03-13764-267572791218699/ /home/e1085411/.ansible/tmp/ansible-local-13695hkZWd1/ansible-tmp-1592053415.03-13764-267572791218699/AnsiballZ_ios_ping.py && sleep 0'
<172.16.148.1> EXEC /bin/sh -c '/usr/bin/python /home/e1085411/.ansible/tmp/ansible-local-13695hkZWd1/ansible-tmp-1592053415.03-13764-267572791218699/AnsiballZ_ios_ping.py && sleep 0'
<172.16.148.1> EXEC /bin/sh -c 'rm -f -r /home/e1085411/.ansible/tmp/ansible-local-13695hkZWd1/ansible-tmp-1592053415.03-13764-267572791218699/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
WARNING: The below traceback may not be related to the actual failure.
File "/tmp/ansible_ios_ping_payload_xAXqFT/ansible_ios_ping_payload.zip/ansible/module_utils/network/ios/ios.py", line 86, in get_capabilities
capabilities = Connection(module._socket_path).get_capabilities()
File "/tmp/ansible_ios_ping_payload_xAXqFT/ansible_ios_ping_payload.zip/ansible/module_utils/connection.py", line 185, in rpc
raise ConnectionError(to_text(msg, errors='surrogate_then_replace'), code=code)
fatal: [172.16.148.1]: FAILED! => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"invocation": {
"module_args": {
"auth_pass": null,
"authorize": null,
"count": null,
"dest": "172.16.144.1",
"host": null,
"password": null,
"port": null,
"provider": null,
"source": null,
"ssh_keyfile": null,
"state": "present",
"timeout": null,
"username": null,
"vrf": null
}
},
"msg": "unable to elevate privilege to enable mode, at prompt [\nCSW01>] with error: enable\r\nEnter PASSCODE: \r\n% Enter PASSCODE: timeout expired!\r\n% Error in authentication.\r\n\r\nCSW01>"
}

PLAY RECAP ******************************************************************************************************************************
172.16.148.1 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0

[pts/57][nsrv ] /etc/ansible>

Copied from original issue: ansible/ansible#70048

l2_interfaces not correctly identifying all trunks as a trunk

SUMMARY

l2_interfaces, which is part of ios_facts gathering, is not correctly identifying all trunk ports as trunks.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_facts

ANSIBLE VERSION
ansible 2.9.7
  config file = /home/mark6847/git/ansible-is-networks/config-compliance-checks/ansible.cfg
  configured module search path = ['/home/mark6847/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/mark6847/virtual-environments/ansible-python3/lib/python3.7/site-packages/ansible
  executable location = /home/mark6847/virtual-environments/ansible-python3/bin/ansible
  python version = 3.7.3 (default, Dec 20 2019, 18:57:59) [GCC 8.3.0]
CONFIGURATION
HOST_KEY_CHECKING(/home/userxxxx/git/ansible-is-networks/config-compliance-checks/ansible.cfg) = False
INTERPRETER_PYTHON(/home/userxxxx/git/ansible-is-networks/config-compliance-checks/ansible.cfg) = /usr/bin/python
OS / ENVIRONMENT

Cisco Catalyst 3850 switch
WS-C3850-48U
IOS 16.6.7

STEPS TO REPRODUCE

I notice this issue whenever there is a trunk interface that allows ALL vlans and no native vlan is defined on it. When that is the case, then ios_facts does not identify it as a trunk as it should. This is a completely valid configuration to have on a trunk.

Example Cisco config that doesn't get identified as a trunk
interface GigabitEthernet1/0/48
switchport mode trunk
switchport nonegotiate
ip dhcp snooping trust

What Ansible ios_facts l2_interfaces sees
{
"name": "GigabitEthernet1/0/48"
},

For comparison of what does work, if the trunk port has an allowed vlan list, a native vlan, or both defined then it works as expected.

Example Cisco config that works
interface GigabitEthernet1/0/48
switchport trunk native vlan 999
switchport trunk allowed vlan 2726,2727
switchport mode trunk
switchport nonegotiate
ip dhcp snooping trust

What Ansible ios_facts l2_interfaces sees
{
"name": "GigabitEthernet1/0/48",
"trunk": {
"allowed_vlans": [
"2726",
"2727"
],
"native_vlan": 999
}
},


EXPECTED RESULTS

I expect ios_facts l2_interfaces to identify all trunks as trunks regardless of if a native vlan or allowed list is defined on the trunk.

ACTUAL RESULTS

As shown above in the steps to reproduce, the trunk is not identified as being a trunk when the native vlan or allowed list is not defined on it.


IOS ACL resource module traceback error

SUMMARY

IOS ACL resource module throws a traceback when tried to configure protocol_options other than icmp, igmp and tcp.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_acls

ANSIBLE VERSION
devel
CONFIGURATION

OS / ENVIRONMENT

mac os

STEPS TO REPRODUCE
- name: Replace provided configuration
    cisco.ios.ios_acls:
      config:
        - afi: ipv4
          acls:
            - name: 123
              aces:
                - grant: deny
                  protocol: eigrp
                  protocol_options:
                    eigrp: true
                  source:
                    address: 192.0.2.0
                    wildcard_bits: 0.0.0.255
                  destination:
                    address: 192.0.3.0
                    wildcard_bits: 0.0.0.255
                  dscp: ef
                  ttl:
                    eq: 10
      state: replaced
EXPECTED RESULTS

ACE with igrp should be configured

ACTUAL RESULTS

Fails with a traceback


Ios L3 IPv4 address loopback interface

SUMMARY

IOS L3 Interfaces Module not working with loopback interfaces.
Not possible to set IPv4 Address on Loopback Interface.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_l3_interfaces

ANSIBLE VERSION
ansible 2.9.6
  config file = /Users/mrainer/Documents/dev/ansible/labs/ansible.cfg
  configured module search path = ['/Users/mrainer/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/mrainer/venv/network/lib/python3.7/site-packages/ansible
  executable location = /Users/mrainer/venv/network/bin/ansible
  python version = 3.7.6 (default, Dec 30 2019, 19:38:26) [Clang 11.0.0 (clang-1100.0.33.16)]
CONFIGURATION
- name: Interface IPv4 Addresses
  ios_l3_interfaces: 
    config: 
      - name: "{{ item.name }}"
        ipv4: 
        - address: "{{ item.ipv4.address }}"
    state: merged
  loop: "{{ interface_config }}"
  notify: save config
  tags: [always, config]
OS / ENVIRONMENT

different Cisco IOS versions tested
p.e: Cisco IOS XE Software, Version 17.01.01

STEPS TO REPRODUCE

IPv4 address on loopback interface is never set
status is always OK
config "ip address" is always untouched
no matter the subnet is /30 or /32 or /24
also changing the IP address after first deployment, never changes the ansible status or the config on device

interface_config:
    - name: GigabitEthernet2
      ipv4:
        address: 172.16.1.100/25
      description: WAN interface
      enabled: True
    
    - name: GigabitEthernet3
      ipv4:
        address: 172.16.2.100/24
      description: headquarter LAN 
      enabled: True
    
    - name: Loopback1
      ipv4: 
        address: 9.9.9.9/32
      description: loopback 1
      enabled: True
EXPECTED RESULTS

IP address on loopback1 should be set

ACTUAL RESULTS

IPv4 address is not set ("no ip address" on device)


ios modules not correctly diferentiating between IOS and IOS-XE

SUMMARY

in the cisco ios module ios_facts when working with IOS and IOS-XE devices sometimes ios-xe devices are clasified as IOS-XE correctly and other times they are clasified incorrectly as IOS devices.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_facts module

using the ansible_net_iostype variable.

ANSIBLE VERSION
ansible 2.9.9
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/shirtclr/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/shirtclr/ansible_venv/lib64/python3.6/site-packages/ansible
  executable location = /home/shirtclr/ansible_venv/bin/ansible
  python version = 3.6.8 (default, Sep 26 2019, 11:57:09) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
CONFIGURATION
no output from command
OS / ENVIRONMENT

connect to the device
get ios facts
print ansible_net_iostype

---
- name: Cisco Ios type Checks
  hosts: all
  gather_facts: false
  connection: local

  tasks:
    - name: Get IOS facts
      ios_facts:
        gather_subset:
        - min
        - config

    - name: print ios version
      debug:
        var: ansible_net_iostype
EXPECTED RESULTS

i expect to gather facts for the four above devices and have each of them to print the result IOS-XE

ACTUAL RESULTS

gather facts is run for the four devices but the first two devices host 1 and host 2 print the result IOS-XE and the second two devices host 3 and host 4 print the result IOS

PLAY [Cisco Ios type Checks] ***********************************************************************************************************************

TASK [Get IOS facts] *******************************************************************************************************************************
[WARNING]: default value for `gather_subset` will be changed to `min` from `!config` v2.11 onwards
ok: [host2.net.anznb.co.nz]
ok: [host1.net.anznb.co.nz]
ok: [host3.net.anznb.co.nz]
ok: [host4.net.anznb.co.nz]

TASK [print ios version] ***************************************************************************************************************************
ok: [host2.net.anznb.co.nz] => {
    "ansible_net_iostype": "IOS-XE"
}
ok: [host3.net.anznb.co.nz] => {
    "ansible_net_iostype": "IOS"
}
ok: [host4.net.anznb.co.nz] => {
    "ansible_net_iostype": "IOS"
}
ok: [host1.net.anznb.co.nz] => {
    "ansible_net_iostype": "IOS-XE"
}

PLAY RECAP *****************************************************************************************************************************************
host3.net.anznb.co.nz : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host4.net.anznb.co.nz : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host1.net.anznb.co.nz : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host2.net.anznb.co.nz : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Network resource modules behaves inconsistently between IOS/EOS and IOS L3 interfaces doesnโ€™t fn as expected for non-existing interfaces

SUMMARY

Playbook tasks that use the IOS Resource modules do not print out the proposed changes when executed in check mode.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

An example would be ios_l3_interfaces. But it is not just this one module.

ANSIBLE VERSION
[student1@ansible-1 ~]$ ansible --version
ansible 2.9.9
  config file = /home/student1/.ansible.cfg
  configured module search path = ['/home/student1/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Dec  5 2019, 15:45:45) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]
[student1@ansible-1 ~]$ 
CONFIGURATION
[student1@ansible-1 ~]$ ansible-config dump --only-changed
DEFAULT_HOST_LIST(/home/student1/.ansible.cfg) = ['/home/student1/lab_inventory/hosts']
DEFAULT_STDOUT_CALLBACK(/home/student1/.ansible.cfg) = yaml
DEFAULT_TIMEOUT(/home/student1/.ansible.cfg) = 60
DEPRECATION_WARNINGS(/home/student1/.ansible.cfg) = False
HOST_KEY_CHECKING(/home/student1/.ansible.cfg) = False
PERSISTENT_COMMAND_TIMEOUT(/home/student1/.ansible.cfg) = 200
PERSISTENT_CONNECT_TIMEOUT(/home/student1/.ansible.cfg) = 200
RETRY_FILES_ENABLED(/home/student1/.ansible.cfg) = False
[student1@ansible-1 ~]$ 

OS / ENVIRONMENT

Red Hat Enterprise Linux release 8.2 (Ootpa)

STEPS TO REPRODUCE
---
- name: IOS Resource module test
  hosts: rtr1
  gather_facts: no
  tags: ios
  tasks:
    - name: GATHER L3 CONFIG
      ios_facts:
        gather_subset: min
        gather_network_resources: l3_interfaces

    - name: DISPLAY INTERFACE DATA
      debug: var=ansible_network_resources

    - name: ADD LOOPBACK
      ios_l3_interfaces:
        config: 
          - name: Loopback 100
            ipv4:
              - address: 192.168.0.1/24
        state: merged        
          
        
- name: EOS Resource module test
  hosts: rtr2
  gather_facts: no
  tags: eos
  tasks:
    - name: GATHER L3 CONFIG
      eos_facts:
        gather_subset: min
        gather_network_resources: l3_interfaces

    - name: DISPLAY INTERFACE DATA
      debug: var=ansible_network_resources

    - name: ADD LOOPBACK
      eos_l3_interfaces:
        config: 
          - name: Loopback 100
            ipv4:
              - address: 192.168.0.1/24
        state: merged    
EXPECTED RESULTS

I would expect the module to behave identically for IOS vs EOS:
As you can see below, the loopback interface does not exist on the IOS device:

ip-172-16-157-41#sh ip int bri
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       172.16.157.41   YES DHCP   up                    up      
VirtualPortGroup0      192.168.35.101  YES NVRAM  up                    up      
ip-172-16-157-41#
ACTUAL RESULTS

Only the EOS module shows proposed changes while running in check mode.

[student1@ansible-1 ~]$ ansible-playbook resource_test.yaml --check -v
Using /home/student1/.ansible.cfg as config file

PLAY [IOS Resource module test] ******************************************************************************************************************************

TASK [GATHER L3 CONFIG] **************************************************************************************************************************************
[WARNING]: default value for `gather_subset` will be changed to `min` from `!config` v2.11 onwards
ok: [rtr1] => changed=false 
  ansible_facts:
    ansible_net_api: cliconf
    ansible_net_gather_network_resources:
    - l3_interfaces
    ansible_net_gather_subset:
    - default
    ansible_net_hostname: ip-172-16-157-41
    ansible_net_image: bootflash:packages.conf
    ansible_net_iostype: IOS-XE
    ansible_net_model: CSR1000V
    ansible_net_python_version: 3.6.8
    ansible_net_serialnum: 9YD8TTQFUJB
    ansible_net_system: ios
    ansible_net_version: 16.09.02
    ansible_network_resources:
      l3_interfaces:
      - ipv4:
        - address: dhcp
        name: GigabitEthernet1
    discovered_interpreter_python: /usr/libexec/platform-python

TASK [DISPLAY INTERFACE DATA] ********************************************************************************************************************************
ok: [rtr1] => 
  ansible_network_resources:
    l3_interfaces:
    - ipv4:
      - address: dhcp
      name: GigabitEthernet1

TASK [ADD LOOPBACK] ******************************************************************************************************************************************
ok: [rtr1] => changed=false 
  before:
  - ipv4:
    - address: dhcp
    name: GigabitEthernet1
  commands: []

PLAY [EOS Resource module test] ******************************************************************************************************************************

TASK [GATHER L3 CONFIG] **************************************************************************************************************************************
ok: [rtr2] => changed=false 
  ansible_facts:
    ansible_net_api: cliconf
    ansible_net_fqdn: rtr2
    ansible_net_gather_network_resources:
    - l3_interfaces
    ansible_net_gather_subset:
    - default
    ansible_net_hostname: rtr2
    ansible_net_image: flash:vEOS-Router.swi
    ansible_net_model: vEOS
    ansible_net_python_version: 3.6.8
    ansible_net_serialnum: 93951E4FEE89BDE6745A9293888C4D5C
    ansible_net_system: eos
    ansible_net_version: 4.22.1FX-VEOSRouter-cloud
    ansible_network_resources:
      l3_interfaces:
      - ipv4:
        - address: dhcp
        name: Ethernet1
      - ipv4:
        - address: 192.168.2.2/32
        name: Loopback0
      - ipv4:
        - address: 10.101.101.2/24
        name: Tunnel0
      - ipv4:
        - address: 10.200.200.2/24
        name: Tunnel1
    discovered_interpreter_python: /usr/libexec/platform-python

TASK [DISPLAY INTERFACE DATA] ********************************************************************************************************************************
ok: [rtr2] => 
  ansible_network_resources:
    l3_interfaces:
    - ipv4:
      - address: dhcp
      name: Ethernet1
    - ipv4:
      - address: 192.168.2.2/32
      name: Loopback0
    - ipv4:
      - address: 10.101.101.2/24
      name: Tunnel0
    - ipv4:
      - address: 10.200.200.2/24
      name: Tunnel1

TASK [ADD LOOPBACK] ******************************************************************************************************************************************
changed: [rtr2] => changed=true 
  after:
  - ipv4:
    - address: dhcp
    name: Ethernet1
  - ipv4:
    - address: 192.168.2.2/32
    name: Loopback0
  - ipv4:
    - address: 10.101.101.2/24
    name: Tunnel0
  - ipv4:
    - address: 10.200.200.2/24
    name: Tunnel1
  before:
  - ipv4:
    - address: dhcp
    name: Ethernet1
  - ipv4:
    - address: 192.168.2.2/32
    name: Loopback0
  - ipv4:
    - address: 10.101.101.2/24
    name: Tunnel0
  - ipv4:
    - address: 10.200.200.2/24
    name: Tunnel1
  commands:
  - interface Loopback100
  - ip address 192.168.0.1/24

PLAY RECAP ***************************************************************************************************************************************************
rtr1                       : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
rtr2                       : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

New network resource modules always return changed=true

SUMMARY

Whenever I use the new Ansible 2.9 network resource modules they always seem to return changed=true even when the before and after are identical and nothing has changed.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

Tested with:
ios_interfaces
ios_vlans
eos_interfaces
eos_vlans

ANSIBLE VERSION
ansible 2.9.6
  config file = /Users/mchlrv/ansible/ansible.cfg
  configured module search path = [u'/Users/mchlrv/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']

  ansible python module location = /Users/mchlrv/Library/Python/2.7/lib/python/site-packages/ansible
  executable location = /Users/mchlrv/Library/Python/2.7/bin/ansible
  python version = 2.7.16 (default, Dec 13 2019, 18:00:32) [GCC 4.2.1 Compatible Apple LLVM 11.0.0 (clang-1100.0.32.4) (-macos10.15-objc-s
CONFIGURATION
ACTION_WARNINGS(/Users/mchlrv/ansible/ansible.cfg) = False
COMMAND_WARNINGS(/Users/mchlrv/ansible/ansible.cfg) = False
DEFAULT_GATHERING(/Users/mchlrv/ansible/ansible.cfg) = explicit
DEFAULT_GATHER_TIMEOUT(/Users/mchlrv/ansible/ansible.cfg) = 0
DEFAULT_HOST_LIST(/Users/mchlrv/ansible/ansible.cfg) = [u'/Users/mchlrv/ansible/hosts']
DEPRECATION_WARNINGS(/Users/mchlrv/ansible/ansible.cfg) = False
INTERPRETER_PYTHON(/Users/mchlrv/ansible/ansible.cfg) = /usr/bin/python
RETRY_FILES_ENABLED(/Users/mchlrv/ansible/ansible.cfg) = False
SYSTEM_WARNINGS(/Users/mchlrv/ansible/ansible.cfg) = False
OS / ENVIRONMENT

Cisco Nexus9000 7.0(3)I7(8)
Arista EOS 4.18.10M

STEPS TO REPRODUCE
- nxos_vlans:
    config: 
      - vlan_id: 20
        name: RED
        state: active
      - vlan_id: 30
        name: BLUE
        state: active
    state: replaced
EXPECTED RESULTS

When nothing has changed, so before and after are identical, changed result should be false.

ACTUAL RESULTS

"changed": true

ios_config: cannot handle duplicated NAT table entry

SUMMARY

When a static NAT table exists, ios_config cannot handle an error %NAT: similar static entry (10.1.1.5 -> 172.16.1.101) in table_id 0 already exists.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_config

ANSIBLE VERSION

2.7.15
2.8.5
2.9.1

CONFIGURATION
OS / ENVIRONMENT

RHEL 8.1
IOS 15.1.(3)T2๏ผŒ15.5(3)M5

STEPS TO REPRODUCE

This entry is configured in advance.

ip nat inside source static 10.1.1.5 172.16.1.101

Run a playbook.

- name: set CONFIGURATION
  ios_config:
#    provider: "{{ cli }}"
    lines: "{{ lookup('file', 'files/cmd_set.txt') }}"
    replace: line
    match: line
    save_when: changed

files/cmd_set.txt
This is a duplicated entry for 172.16.1.101. I changed from 10.1.1.5 to 10.1.1.55.

ip nat inside source static 10.1.1.55 172.16.1.101
end
EXPECTED RESULTS

IOS returns this error, so it should be treated as failed.

ip-192-168-0-230(config)#ip nat inside source static 10.1.1.55 172.16.1.101
%NAT: similar static entry (10.1.1.5 -> 172.16.1.101) in table_id 0 already exists
ACTUAL RESULTS

changed without error.

$ ansible-playbook -i inventory xxxxxxxx_cisco_set_operation.yml -vvv
ansible-playbook 2.9.1
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/ec2-user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/ec2-user/ansible2.9/lib64/python3.6/site-packages/ansible
  executable location = /home/ec2-user/ansible2.9/bin/ansible-playbook
  python version = 3.6.8 (default, Oct 11 2019, 15:04:54) [GCC 8.3.1 20190507 (Red Hat 8.3.1-4)]
Using /etc/ansible/ansible.cfg as config file
host_list declined parsing /home/ec2-user/xxxxxxxx/inventory as it did not pass its verify_file() method
script declined parsing /home/ec2-user/xxxxxxxx/inventory as it did not pass its verify_file() method
auto declined parsing /home/ec2-user/xxxxxxxx/inventory as it did not pass its verify_file() method
Parsed /home/ec2-user/xxxxxxxx/inventory inventory source with ini plugin

PLAYBOOK: xxxxxxxx_cisco_set_operation.yml ********************************************************************************************************************
1 plays in xxxxxxxx_cisco_set_operation.yml

PLAY [all] **************************************************************************************************************************************************
META: ran handlers

TASK [configure xxxxxxxx and save config file] *******************************************************************************************************************
task path: /home/ec2-user/xxxxxxxx/xxxxxxxx_cisco_set_operation.yml:7

TASK [4_configure_xxxxxxxx : set CONFIGURATION] *************************************************************************************************************
task path: /home/ec2-user/xxxxxxxx/roles/4_configure_xxxxxxxx/tasks/main.yml:1
<192.168.0.230> using connection plugin network_cli (was local)
<192.168.0.230> ESTABLISH LOCAL CONNECTION FOR USER: ec2-user
<192.168.0.230> EXEC /bin/sh -c 'echo ~ec2-user && sleep 0'
<192.168.0.230> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/ec2-user/.ansible/tmp/ansible-tmp-1575275860.2124772-21969709832786 `" && echo ansible-tmp-1575275860.2124772-21969709832786="` echo /home/ec2-user/.ansible/tmp/ansible-tmp-1575275860.2124772-21969709832786 `" ) && sleep 0'
Using module file /home/ec2-user/ansible2.9/lib64/python3.6/site-packages/ansible/modules/network/ios/ios_config.py
<192.168.0.230> PUT /home/ec2-user/.ansible/tmp/ansible-local-140430sdcebof/tmplxtr3aeg TO /home/ec2-user/.ansible/tmp/ansible-tmp-1575275860.2124772-21969709832786/AnsiballZ_ios_config.py
<192.168.0.230> EXEC /bin/sh -c 'chmod u+x /home/ec2-user/.ansible/tmp/ansible-tmp-1575275860.2124772-21969709832786/ /home/ec2-user/.ansible/tmp/ansible-tmp-1575275860.2124772-21969709832786/AnsiballZ_ios_config.py && sleep 0'
<192.168.0.230> EXEC /bin/sh -c '/home/ec2-user/ansible2.9/bin/python /home/ec2-user/.ansible/tmp/ansible-tmp-1575275860.2124772-21969709832786/AnsiballZ_ios_config.py && sleep 0'
<192.168.0.230> EXEC /bin/sh -c 'rm -f -r /home/ec2-user/.ansible/tmp/ansible-tmp-1575275860.2124772-21969709832786/ > /dev/null 2>&1 && sleep 0'
changed: [192.168.0.230] => {
    "banners": {},
    "changed": true,
    "commands": [
        "ip nat inside source static 10.1.1.55 172.16.1.101"
    ],
    "invocation": {
        "module_args": {
            "after": null,
            "auth_pass": null,
            "authorize": null,
            "backup": false,
            "backup_options": null,
            "before": null,
            "defaults": false,
            "diff_against": null,
            "diff_ignore_lines": null,
            "host": null,
            "intended_config": null,
            "lines": [
                "ip nat inside source static 10.1.1.55 172.16.1.101\nend"
            ],
            "match": "line",
            "multiline_delimiter": "@",
            "parents": null,
            "password": null,
            "port": null,
            "provider": {
                "auth_pass": null,
                "authorize": false,
                "host": null,
                "password": null,
                "port": null,
                "ssh_keyfile": null,
                "timeout": null,
                "username": null
            },
            "replace": "line",
            "running_config": null,
            "save_when": "changed",
            "src": null,
            "ssh_keyfile": null,
            "timeout": null,
            "username": null
        }
    },
    "updates": [
        "ip nat inside source static 10.1.1.55 172.16.1.101"
    ]
}
META: ran handlers
META: ran handlers

PLAY RECAP **************************************************************************************************************************************************
192.168.0.230              : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

This issue was moved from ansible/ansible#65411 .

Also, @saito-hideki commented at the past issue;

Hi, I confirmed the following code, and there is no filter for already exists:

https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/terminal/ios.py#L39-L54

So, personally I think we should append something like the following line to terminal_stderr_re:

re.compile(br"already exists")

ios_facts l3_interfaces utils.py normalize_interface returning incorrect or no interface name

SUMMARY

When gathering ios_facts l3_interfaces:

  1. the wrong interface name is returned if the interface 'description' contains the word 'interface' followed by a space then any word that begins with the two letters that indicate an abbreviated interface type.
  2. no ipv4 information is returned if the the interface 'description' contains the word 'interface' followed by a space then any word that does NOT indicate an abbreviated interface type.

My guess is somewhere in l3_interfaces with how the name is being determined with the call to normalize_interface the word 'interface' is being picked-up from within the 'description' directive.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_facts
utils.py
normalize_interface

ANSIBLE VERSION
ansible 2.9.7
  config file = /var/lib/awx/projects/net_compliance/ansible.cfg
  configured module search path = ['/var/lib/awx/projects/net_compliance/library', '/usr/lib/python2.7/site-packages/napalm_ansible/modules', '/usr/lib/python2.7/site-packages/ntc-ansible/library']
  ansible python module location = /root/.local/lib/python3.8/site-packages/ansible
  executable location = /root/.local/bin/ansible
  python version = 3.8.2 (default, May  1 2020, 00:22:45) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
CONFIGURATION
ANSIBLE_PIPELINING(env: ANSIBLE_SSH_PIPELINING) = True
DEFAULT_ACTION_PLUGIN_PATH(/var/lib/awx/projects/net_compliance/ansible.cfg) = ['/usr/lib/python2.7/site-packages/napalm_ansible/plugins/action']
DEFAULT_CALLBACK_WHITELIST(/var/lib/awx/projects/net_compliance/ansible.cfg) = ['profile_roles', 'profile_tasks', 'timer']
DEFAULT_FILTER_PLUGIN_PATH(/var/lib/awx/projects/net_compliance/ansible.cfg) = ['/var/lib/awx/projects/net_compliance/filter_plugins']
DEFAULT_GATHER_TIMEOUT(/var/lib/awx/projects/net_compliance/ansible.cfg) = 30
DEFAULT_HOST_LIST(/var/lib/awx/projects/net_compliance/ansible.cfg) = ['/var/lib/awx/projects/net_compliance/inventory']
DEFAULT_MODULE_PATH(/var/lib/awx/projects/net_compliance/ansible.cfg) = ['/var/lib/awx/projects/net_compliance/library', '/usr/lib/python2.7/site-packages/napalm_ansible/modules', '/usr/lib/python2.7/site-pack
DEFAULT_ROLES_PATH(/var/lib/awx/projects/net_compliance/ansible.cfg) = ['/var/lib/awx/projects/net_compliance/roles']
DEFAULT_STDOUT_CALLBACK(/var/lib/awx/projects/net_compliance/ansible.cfg) = debug
DEFAULT_VAULT_PASSWORD_FILE(env: ANSIBLE_VAULT_PASSWORD_FILE) = /etc/ansible/vault_password
HOST_KEY_CHECKING(/var/lib/awx/projects/net_compliance/ansible.cfg) = False
INVENTORY_ENABLED(/var/lib/awx/projects/net_compliance/ansible.cfg) = ['host_list', 'ini', 'yaml', 'script', 'constructed']
PARAMIKO_HOST_KEY_AUTO_ADD(/var/lib/awx/projects/net_compliance/ansible.cfg) = True
PERSISTENT_COMMAND_TIMEOUT(/var/lib/awx/projects/net_compliance/ansible.cfg) = 300
PERSISTENT_CONNECT_TIMEOUT(/var/lib/awx/projects/net_compliance/ansible.cfg) = 300
OS / ENVIRONMENT
"ansible_facts": {
    "ansible_net_api": "cliconf",
    "ansible_net_gather_network_resources": [
        "l3_interfaces"
    ],
    "ansible_net_gather_subset": [
        "default"
    ],
    "ansible_net_iostype": "IOS",
    "ansible_net_model": "WS-C3850-12X48U",
    "ansible_net_stacked_models": [
        "WS-C3850-12X48U"
    ],
    "ansible_net_system": "ios",
    "ansible_net_version": "16.3.6"
STEPS TO REPRODUCE

Begin with:

  1. Create a vlan interface
  2. Assign a valid ip address and mask

Two Cases:
Case1: set a 'description' that contains the word 'interface' followed by a space then any word that begins with two letters that would normally identify an interface type, e.g. 'fo' == FortyGigabitEthernet:

***Notice here within the description is 'interface fo'

interface Vlan1
 description this interface for testing
 ip address 10.1.1.10 255.255.255.0
end

Case2: set a 'description' that contains the word 'interface' followed by a space then any word that DOES NOT begin with two letters that would normally identify an interface type:

***Notice here within the description is 'interface is'

interface Vlan1
 description this interface is for testing
 ip address 10.1.1.10 255.255.255.0
end
- name: Test l3_interface name error
  hosts: ios
  gather_facts: no

  vars:

  tasks:
  - name: Gather ios_facts
    ios_facts:
      gather_subset:
        - min
      gather_network_resources:
        - l3_interfaces
EXPECTED RESULTS

***Notice "name": "Vlan1" as compared to below Actual Results in comparision.

"ansible_network_resources": {
    "l3_interfaces": [
        .......abbreviated.....
        {
            "ipv4": [
                 {
                      "address": "10.1.1.10 255.255.255.0"
                  }
             ],
                      "name": "Vlan1"
         }
    ]
}
ACTUAL RESULTS

Case1:

"ansible_network_resources": {
    "l3_interfaces": [
        .......abbreviated.....
        {
             "ipv4": [
                  {
                       "address": "10.1.1.10 255.255.255.0"
                  }
             ],
                      "name": "FortyGigabitEthernet"
        }
   ]
}

Case2:

"ansible_network_resources": {
    "l3_interfaces": [
        .......abbreviated.....
       {
            "name": "Vlan1"
       }
    ]
}

ios_acls not idempotent

SUMMARY

We have a CI failure because if an idempotent issue on ios_acls. Given this is python35, this is likely a dict sort issue.

https://object-storage-ca-ymq-1.vexxhost.net/v1/a0b4156a37f9453eb4ec7db5422272df/ansible_8/8/41a1b191da80f1d359d9e708ef63ea3eeec13a6f/check/ansible-test-network-integration-ios-python35/57fa164/controller/ara-report/

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_acl

ANSIBLE VERSION

CONFIGURATION

OS / ENVIRONMENT
STEPS TO REPRODUCE

EXPECTED RESULTS
ACTUAL RESULTS

Idempotence issue in ios_logging when logging is ON

SUMMARY

If we want to enable logging (on), the idempotence is not working

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_logging module

ANSIBLE VERSION
ansible 2.9.10
  config file = /home/florian/logm/ansible-test/ansible.cfg
  configured module search path = ['/home/florian/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/florian/.pyenv/versions/3.8.3/envs/ansible/lib/python3.8/site-packages/ansible
  executable location = /home/florian/.pyenv/versions/ansible/bin/ansible
  python version = 3.8.3 (default, Jun  5 2020, 11:41:04) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
CONFIGURATION
HOST_KEY_CHECKING(/home/user/logm/ansible-test/ansible.cfg) = False
OS / ENVIRONMENT

Switch Ports Model SW Version SW Image


  • 1 26 WS-C2960+24TC-L 15.0(2)SE6 C2960-LANBASEK9-M
STEPS TO REPRODUCE
$ cat enable_logging.yaml 
---
- name: Logging action
  hosts: switch
  gather_facts: no
  tasks:

  - name: Enable logging
    ios_logging:
      dest: on
      state: present
    register: output


  - name: Show output
    debug: var=output

EXPECTED RESULTS

Should not have any change because logging is already activated. Here is a example where we are running twice the same playbook.

I think the parsing config should be done on sh run all because the logging on command is a default command so it won't appear in a sh run command

ACTUAL RESULTS
$ ansible-playbook -i hosts enable_logging.yaml -k
SSH password: 

PLAY [Logging action] *******************************************************************************************************************************************************************************************************************

TASK [Enable logging] *******************************************************************************************************************************************************************************************************************
[WARNING]: The value True (type bool) in a string field was converted to u'True' (type string). If this does not look like what you expect, quote the entire value to ensure it does not change.
changed: [TB_BHD]

TASK [Show output] **********************************************************************************************************************************************************************************************************************
ok: [TB_BHD] => {
    "output": {
        "ansible_facts": {
            "discovered_interpreter_python": "/usr/bin/python"
        },
        "changed": true,
        "commands": [
            "logging on"
        ],
        "failed": false,
        "warnings": [
            "The value True (type bool) in a string field was converted to u'True' (type string). If this does not look like what you expect, quote the entire value to ensure it does not change."
        ]
    }
}

PLAY RECAP ******************************************************************************************************************************************************************************************************************************
TB_BHD                     : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   




$ ansible-playbook -i hosts enable_logging.yaml -k
SSH password: 

PLAY [Logging action] *******************************************************************************************************************************************************************************************************************

TASK [Enable logging] *******************************************************************************************************************************************************************************************************************
[WARNING]: The value True (type bool) in a string field was converted to u'True' (type string). If this does not look like what you expect, quote the entire value to ensure it does not change.
changed: [TB_BHD]

TASK [Show output] **********************************************************************************************************************************************************************************************************************
ok: [TB_BHD] => {
    "output": {
        "ansible_facts": {
            "discovered_interpreter_python": "/usr/bin/python"
        },
        "changed": true,
        "commands": [
            "logging on"
        ],
        "failed": false,
        "warnings": [
            "The value True (type bool) in a string field was converted to u'True' (type string). If this does not look like what you expect, quote the entire value to ensure it does not change."
        ]
    }
}

PLAY RECAP ******************************************************************************************************************************************************************************************************************************
TB_BHD                     : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

When trying to utilise the ( ios_l3_interfaces and ios_interfaces ) module more than once within a playbook, a ConnectionError is thrown.

From @luwei19941010 on Jun 18, 2020 06:34

SUMMARY

When trying to utilise the ( ios_l3_interfaces and ios_insterfaces ) module more than once within a playbook, a ConnectionError is thrown.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ansible-connection
connection.py

ANSIBLE VERSION
ansible 2.9.9
  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/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Apr 11 2018, 07:36:10) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]
[root@luwei ~]# 
CONFIGURATION
OS / ENVIRONMENT

CentOS-7-x86_64-DVD-1804
ROM: 3700 Software (C3725-ADVIPSERVICESK9-M), Version 12.4(3), RELEASE SOFTWARE (fc2)

STEPS TO REPRODUCE
ansible-playbook.yml
---

- name: Network Getting Started First Playbook
  connection: network_cli
  gather_facts: false
  hosts: 192.168.174.200

  tasks:
    - name: Set GigabitEthernet0/3 IPv4 address
      ios_l3_interfaces:
        config:
          - name: FastEthernet0/1    
            ipv4:
            - address: 192.168.0.1/24
        state: merged 
    - name: Merge provided configuration with device configuration
      ios_interfaces:
        config:
          - name: FastEthernet0/1
            description: 'Configured and Merged by Ansible Network'
            enabled: True
        state: merged
EXPECTED RESULTS

interface f0/1 config ip and port status change up.

ACTUAL RESULTS
The full traceback is:
Traceback (most recent call last):
  File "/usr/bin/ansible-connection", line 308, in main
    conn.update_play_context(pc_data)
  File "/usr/local/python3/lib/python3.6/site-packages/ansible/module_utils/connection.py", line 185, in __rpc__
    raise ConnectionError(to_text(msg, errors='surrogate_then_replace'), code=code)

Copied from original issue: ansible/ansible#70135

ios_facts fails to parse acls

SUMMARY

The gather_network_resources component of ios_facts module fails to parse acls

ISSUE TYPE
  • Bug Report
COMPONENT NAME
ANSIBLE VERSION
ansible 2.10.0rc4
  config file = /home/student1/.ansible.cfg
  configured module search path = ['/home/student1/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /opt/my-envs/ansible-2.10/lib64/python3.6/site-packages/ansible
  executable location = /opt/my-envs/ansible-2.10/bin/ansible
  python version = 3.6.8 (default, Dec  5 2019, 15:45:45) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]

CONFIGURATION
DEFAULT_HOST_LIST(/home/student1/.ansible.cfg) = ['/home/student1/lab_inventory/hosts']
DEFAULT_STDOUT_CALLBACK(/home/student1/.ansible.cfg) = yaml
DEFAULT_TIMEOUT(/home/student1/.ansible.cfg) = 60
DEPRECATION_WARNINGS(/home/student1/.ansible.cfg) = False
HOST_KEY_CHECKING(/home/student1/.ansible.cfg) = False
PERSISTENT_COMMAND_TIMEOUT(/home/student1/.ansible.cfg) = 200
PERSISTENT_CONNECT_TIMEOUT(/home/student1/.ansible.cfg) = 200
RETRY_FILES_ENABLED(/home/student1/.ansible.cfg) = False
OS / ENVIRONMENT

RHEL 8, CSR

STEPS TO REPRODUCE

Deploy the following test ACLs:

rtr1#sh access-lists 
Standard IP access list 2
    30 permit 172.16.1.11
    20 permit 172.16.1.10
    10 permit 172.16.1.2
Standard IP access list GS_NAT_ACL
    10 permit 192.168.35.0, wildcard bits 0.0.0.255
Extended IP access list 101
    10 permit tcp 10.1.1.0 0.0.0.255 172.16.1.0 0.0.0.255
    20 permit tcp 10.1.1.0 0.0.0.255 172.16.1.0 0.0.0.255 eq telnet time-range EVERYOTHERDAY (active)
    30 permit tcp host 10.1.1.2 host 172.16.1.1 eq telnet
    40 permit tcp host 10.1.1.2 host 172.16.1.1 eq ftp
    50 permit udp host 10.1.1.2 host 172.16.1.1 eq syslog
    60 permit udp host 10.1.1.2 host 172.16.1.1 eq tftp
    70 permit udp host 10.1.1.2 host 172.16.1.1 eq ntp
Extended IP access list 110
    10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 echo dscp ef ttl eq 10
    20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack
Extended IP access list in_to_out
    10 permit tcp host 10.1.1.2 host 172.16.1.1 eq telnet
Extended IP access list inboundfilters
    10 permit icmp 172.16.1.0 0.0.0.255 10.1.1.0 0.0.0.255
    - name: use the collection facts
      cisco.ios.ios_facts:
        gather_network_resources: all,!vlans
      register: result

    - debug: var=result
EXPECTED RESULTS

Parsed ACL

ACTUAL RESULTS
{
    "msg": "Unsupported parameters for (basic.py) module: set found in config -> acls -> aces -> protocol_options -> tcp. Supported parameters include: ack, established, fin, psh, rst, syn, urg",
    "invocation": {
        "module_args": {
            "config": [
                {
                    "acls": [
                        {
                            "name": "2",
                            "acl_type": "standard",
                            "aces": [
                                {
                                    "sequence": 30,
                                    "grant": "permit",
                                    "source": {
                                        "address": "172.16.1.11",
                                        "wildcard_bits": null,
                                        "any": null,
                                        "host": null,
                                        "port_protocol": null
                                    },
                                    "destination": null,
                                    "protocol": null,
                                    "protocol_options": null,
                                    "dscp": null,
                                    "fragments": null,
                                    "log": null,
                                    "log_input": null,
                                    "option": null,
                                    "precedence": null,
                                    "time_range": null,
                                    "tos": null,
                                    "ttl": null
                                },
                                {
                                    "sequence": 20,
                                    "grant": "permit",
                                    "source": {
                                        "address": "172.16.1.10",
                                        "wildcard_bits": null,
                                        "any": null,
                                        "host": null,
                                        "port_protocol": null
                                    },
                                    "destination": null,
                                    "protocol": null,
                                    "protocol_options": null,
                                    "dscp": null,
                                    "fragments": null,
                                    "log": null,
                                    "log_input": null,
                                    "option": null,
                                    "precedence": null,
                                    "time_range": null,
                                    "tos": null,
                                    "ttl": null
                                },
                                {
                                    "sequence": 10,
                                    "grant": "permit",
                                    "source": {
                                        "address": "172.16.1.2",
                                        "wildcard_bits": null,
                                        "any": null,
                                        "host": null,
                                        "port_protocol": null
                                    },
                                    "destination": null,
                                    "protocol": null,
                                    "protocol_options": null,
                                    "dscp": null,
                                    "fragments": null,
                                    "log": null,
                                    "log_input": null,
                                    "option": null,
                                    "precedence": null,
                                    "time_range": null,
                                    "tos": null,
                                    "ttl": null
                                }
                            ]
                        },
                        {
                            "name": "GS_NAT_ACL",
                            "acl_type": "standard",
                            "aces": [
                                {
                                    "sequence": 10,
                                    "grant": "permit",
                                    "source": {
                                        "address": "192.168.35.0",
                                        "wildcard_bits": "0.0.0.255",
                                        "any": null,
                                        "host": null,
                                        "port_protocol": null
                                    },
                                    "destination": null,
                                    "protocol": null,
                                    "protocol_options": null,
                                    "dscp": null,
                                    "fragments": null,
                                    "log": null,
                                    "log_input": null,
                                    "option": null,
                                    "precedence": null,
                                    "time_range": null,
                                    "tos": null,
                                    "ttl": null
                                }
                            ]
                        },
                        {
                            "name": "101",
                            "acl_type": "extended",
                            "aces": [
                                {
                                    "sequence": 10,
                                    "grant": "permit",
                                    "source": {
                                        "address": "10.1.1.0",
                                        "wildcard_bits": "0.0.0.255",
                                        "any": null,
                                        "host": null,
                                        "port_protocol": null
                                    },
                                    "destination": {
                                        "address": "172.16.1.0",
                                        "wildcard_bits": "0.0.0.255",
                                        "any": null,
                                        "host": null,
                                        "port_protocol": null
                                    },
                                    "protocol": "tcp",
                                    "protocol_options": {
                                        "tcp": {
                                            "set": true
                                        },
                                        "protocol_number": null,
                                        "ahp": null,
                                        "eigrp": null,
                                        "esp": null,
                                        "gre": null,
                                        "hbh": null,
                                        "icmp": null,
                                        "igmp": null,
                                        "ip": null,
                                        "ipv6": null,
                                        "ipinip": null,
                                        "nos": null,
                                        "ospf": null,
                                        "pcp": null,
                                        "pim": null,
                                        "sctp": null,
                                        "udp": null
                                    },
                                    "dscp": null,
                                    "fragments": null,
                                    "log": null,
                                    "log_input": null,
                                    "option": null,
                                    "precedence": null,
                                    "time_range": null,
                                    "tos": null,
                                    "ttl": null
                                },
                                {
                                    "sequence": 20,
                                    "grant": "permit",
                                    "source": {
                                        "address": "10.1.1.0",
                                        "wildcard_bits": "0.0.0.255"
                                    },
                                    "destination": {
                                        "address": "172.16.1.0",
                                        "wildcard_bits": "0.0.0.255",
                                        "port_protocol": {
                                            "eq": "telnet"
                                        }
                                    },
                                    "protocol": "tcp",
                                    "protocol_options": {
                                        "tcp": {
                                            "set": true
                                        }
                                    }
                                },
                                {
                                    "sequence": 30,
                                    "grant": "permit",
                                    "source": {
                                        "host": "10.1.1.2"
                                    },
                                    "destination": {
                                        "host": "172.16.1.1",
                                        "port_protocol": {
                                            "eq": "telnet"
                                        }
                                    },
                                    "protocol": "tcp",
                                    "protocol_options": {
                                        "tcp": {
                                            "set": true
                                        }
                                    }
                                },
                                {
                                    "sequence": 40,
                                    "grant": "permit",
                                    "source": {
                                        "host": "10.1.1.2"
                                    },
                                    "destination": {
                                        "host": "172.16.1.1",
                                        "port_protocol": {
                                            "eq": "ftp"
                                        }
                                    },
                                    "protocol": "tcp",
                                    "protocol_options": {
                                        "tcp": {
                                            "set": true
                                        }
                                    }
                                },
                                {
                                    "sequence": 50,
                                    "grant": "permit",
                                    "source": {
                                        "host": "10.1.1.2"
                                    },
                                    "destination": {
                                        "host": "172.16.1.1",
                                        "port_protocol": {
                                            "eq": "syslog"
                                        }
                                    },
                                    "protocol": "udp",
                                    "protocol_options": {
                                        "udp": true
                                    }
                                },
                                {
                                    "sequence": 60,
                                    "grant": "permit",
                                    "source": {
                                        "host": "10.1.1.2"
                                    },
                                    "destination": {
                                        "host": "172.16.1.1",
                                        "port_protocol": {
                                            "eq": "tftp"
                                        }
                                    },
                                    "protocol": "udp",
                                    "protocol_options": {
                                        "udp": true
                                    }
                                },
                                {
                                    "sequence": 70,
                                    "grant": "permit",
                                    "source": {
                                        "host": "10.1.1.2"
                                    },
                                    "destination": {
                                        "host": "172.16.1.1",
                                        "port_protocol": {
                                            "eq": "ntp"
                                        }
                                    },
                                    "protocol": "udp",
                                    "protocol_options": {
                                        "udp": true
                                    }
                                }
                            ]
                        },
                        {
                            "name": "110",
                            "acl_type": "extended",
                            "aces": [
                                {
                                    "sequence": 10,
                                    "grant": "deny",
                                    "dscp": "ef",
                                    "ttl": {
                                        "eq": "10"
                                    },
                                    "source": {
                                        "address": "192.0.2.0",
                                        "wildcard_bits": "0.0.0.255"
                                    },
                                    "destination": {
                                        "address": "192.0.3.0",
                                        "wildcard_bits": "0.0.0.255"
                                    },
                                    "protocol": "icmp",
                                    "protocol_options": {
                                        "icmp": {
                                            "echo": true
                                        }
                                    }
                                },
                                {
                                    "sequence": 20,
                                    "grant": "deny",
                                    "source": {
                                        "host": "198.51.100.0"
                                    },
                                    "destination": {
                                        "host": "198.51.110.0",
                                        "port_protocol": {
                                            "eq": "telnet"
                                        }
                                    },
                                    "protocol": "tcp",
                                    "protocol_options": {
                                        "tcp": {
                                            "ack": true
                                        }
                                    }
                                }
                            ]
                        },
                        {
                            "name": "in_to_out",
                            "acl_type": "extended",
                            "aces": [
                                {
                                    "sequence": 10,
                                    "grant": "permit",
                                    "source": {
                                        "host": "10.1.1.2"
                                    },
                                    "destination": {
                                        "host": "172.16.1.1",
                                        "port_protocol": {
                                            "eq": "telnet"
                                        }
                                    },
                                    "protocol": "tcp",
                                    "protocol_options": {
                                        "tcp": {
                                            "set": true
                                        }
                                    }
                                }
                            ]
                        },
                        {
                            "name": "inboundfilters",
                            "acl_type": "extended",
                            "aces": [
                                {
                                    "sequence": 10,
                                    "grant": "permit",
                                    "source": {
                                        "address": "172.16.1.0",
                                        "wildcard_bits": "0.0.0.255"
                                    },
                                    "destination": {
                                        "address": "10.1.1.0",
                                        "wildcard_bits": "0.0.0.255"
                                    },
                                    "protocol": "icmp",
                                    "protocol_options": {
                                        "icmp": {
                                            "set": true
                                        }
                                    }
                                }
                            ]
                        }
                    ],
                    "afi": "ipv4"
                }
            ],
            "state": "merged",
            "running_config": null
        }
    },
    "_ansible_no_log": false,
    "changed": false
}

ios_l2_interfaces merge function overwrites instead of merging

SUMMARY

Unexpected behavior of ios_l2_interfaces module when using merged state. Overwrites allowed vlans on trunk links instead of adding to the list of allowed vlans. Same symptoms as here: ansible/ansible#65332

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_l2_interfaces

ANSIBLE VERSION
ansible 2.9.7
  config file = None
  configured module search path = ['/home/centos/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.6/site-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 3.6.8 (default, Nov 21 2019, 19:31:34) [GCC 8.3.1 20190507 (Red Hat 8.3.1-4)]

CONFIGURATION
all default
OS / ENVIRONMENT
Cisco IOS Software, vios_l2 Software (vios_l2-ADVENTERPRISEK9-M), Version 15.2(4.0.55)E, TEST ENGINEERING ESTG_WEEKLY BUILD, synced to  END_OF_FLO_ISP
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2015 by Cisco Systems, Inc.
Compiled Tue 28-Jul-15 18:52 by sasyamal


ROM: Bootstrap program is IOSv

S1 uptime is 25 minutes
System returned to ROM by reload
System image file is "flash0:/vios_l2-adventerprisek9-m"
Last reload reason: Unknown reason



This product contains cryptographic features and is subject to United
States and local country laws governing import, export, transfer and
use. Delivery of Cisco cryptographic products does not imply
third-party authority to import, export, distribute or use encryption.
Importers, exporters, distributors and users are responsible for
compliance with U.S. and local country laws. By using this product you
agree to comply with applicable laws and regulations. If you are unable
to comply with U.S. and local laws, return this product immediately.

A summary of U.S. laws governing Cisco cryptographic products may be found at:
http://www.cisco.com/wwl/export/crypto/tool/stqrg.html

If you require further assistance please contact us by sending email to
[email protected].

Cisco IOSv () processor (revision 1.0) with 836865K/209920K bytes of memory.
Processor board ID 9G9AW7EHZYB
1 Virtual Ethernet interface
16 Gigabit Ethernet interfaces
DRAM configuration is 72 bits wide with parity disabled.
256K bytes of non-volatile configuration memory.
2097152K bytes of ATA System CompactFlash 0 (Read/Write)
0K bytes of ATA CompactFlash 1 (Read/Write)
0K bytes of ATA CompactFlash 2 (Read/Write)
0K bytes of ATA CompactFlash 3 (Read/Write)

Configuration register is 0x0
STEPS TO REPRODUCE

run the playbook

---
- hosts: S1_ios
  gather_facts: false
  vars:
    new_vlans: 200

  tasks:
    - name: add vlans to allowed list
      ios_l2_interfaces:
        config:
          - name: Ethernet2/31
            trunk:
              allowed_vlans: "{{ new_vlans }}"
        state: merged
...

EXPECTED RESULTS

Starting interface config:

S1_ios# show run interface Ethernet 2/31

!Command: show running-config interface Ethernet2/31
!Time: Wed Nov 27 15:57:00 2019

version 7.3(0)D1(1)

interface Ethernet2/31
  shutdown
  switchport
  switchport trunk native vlan 99
  switchport trunk allowed vlan 101,104-106

Post Job interface Config:

S1_ios# show run interface Ethernet 2/31

!Command: show running-config interface Ethernet2/31
!Time: Wed Nov 27 16:04:53 2019

interface Ethernet2/31
  shutdown
  switchport
  switchport trunk native vlan 99
  switchport trunk allowed vlan 200
ACTUAL RESULTS

Allowed trunking vlans on the port are replaced with the single "new vlan", instead of it being added to the list of allowed vlans.

changed: [S1_ios] => {
    "after": [
        {
            "name": "Ethernet2/31",
            "trunk": {
                "allowed_vlans": "200",
                "native_vlan": 99
            }
        }
    ],
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "before": [
        {
            "name": "Ethernet2/31",
            "trunk": {
                "allowed_vlans": "101,104,105,106",
                "native_vlan": 99
            }
        }
    ],
    "changed": true,
    "commands": [
        "interface Ethernet2/31",
        "switchport trunk allowed vlan 200"
    ],
    "invocation": {
        "module_args": {
            "config": [
                {
                    "access": null,
                    "name": "Ethernet2/31",
                    "trunk": {
                        "allowed_vlans": "200",
                        "native_vlan": null
                    }
                }
            ],
            "state": "merged"
        }
    }
}

ios_vlans failing for vlan facts on IOS 16.9.5

SUMMARY

This ios_vlans task is being tested against ios 15.2(2)E7 and 16.9.5. Switches running 15.2(2)E7 are successful but fails with the following traceback for devices running 16.9.5.

Traceback (most recent call last):
  File "/var/lib/awx/.ansible/tmp/ansible-local-3zRW5fX/ansible-tmp-1590277408.56-174-101926446002067/AnsiballZ_ios_vlans.py", line 102, in <module>
    _ansiballz_main()
  File "/var/lib/awx/.ansible/tmp/ansible-local-3zRW5fX/ansible-tmp-1590277408.56-174-101926446002067/AnsiballZ_ios_vlans.py", line 94, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/var/lib/awx/.ansible/tmp/ansible-local-3zRW5fX/ansible-tmp-1590277408.56-174-101926446002067/AnsiballZ_ios_vlans.py", line 40, in invoke_module
    runpy.run_module(mod_name='ansible_collections.cisco.ios.plugins.modules.ios_vlans', init_globals=None, run_name='__main__', alter_sys=True)
  File "/usr/lib64/python2.7/runpy.py", line 176, in run_module
    fname, loader, pkg_name)
  File "/usr/lib64/python2.7/runpy.py", line 82, in _run_module_code
    mod_name, mod_fname, mod_loader, pkg_name)
  File "/usr/lib64/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/tmp/ansible_cisco.ios.ios_vlans_payload_xZACnX/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/modules/ios_vlans.py", line 733, in <module>
  File "/tmp/ansible_cisco.ios.ios_vlans_payload_xZACnX/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/modules/ios_vlans.py", line 728, in main
  File "/tmp/ansible_cisco.ios.ios_vlans_payload_xZACnX/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/vlans/vlans.py", line 70, in execute_module
  File "/tmp/ansible_cisco.ios.ios_vlans_payload_xZACnX/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/vlans/vlans.py", line 52, in get_vlans_facts
  File "/tmp/ansible_cisco.ios.ios_vlans_payload_xZACnX/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/facts.py", line 106, in get_facts
  File "/tmp/ansible_cisco.ios.ios_vlans_payload_xZACnX/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/facts/facts.py", line 131, in get_network_resources_facts
  File "/tmp/ansible_cisco.ios.ios_vlans_payload_xZACnX/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/vlans/vlans.py", line 77, in populate_facts
  File "/tmp/ansible_cisco.ios.ios_vlans_payload_xZACnX/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/vlans/vlans.py", line 127, in render_config
IndexError: list index out of range
ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_vlans
./module_utils/network/ios/facts/vlans/vlans.py

ANSIBLE VERSION
[root@xxx-ansible03]# ansible --version
ansible 2.9.9
  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/site-packages/ansible
  executable location = /bin/ansible
  python version = 2.7.5 (default, Apr  2 2020, 13:16:51) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
CONFIGURATION
[root@xxx-ansible03]# ansible-config dump --only-changed
DEFAULT_LOG_PATH(/etc/ansible/ansible.cfg) = /etc/ansible/ansible.log
OS / ENVIRONMENT
<hostname>#show version
Cisco IOS XE Software, Version 16.09.05
Cisco IOS Software [Fuji], Catalyst L3 Switch Software (CAT3K_CAA-UNIVERSALK9-M), Version 16.9.5, RELEASE SOFTWARE (fc1)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2020 by Cisco Systems, Inc.
Compiled Thu 30-Jan-20 18:17 by mcpre

ROM: IOS-XE ROMMON
BOOTLDR: CAT3K_CAA Boot Loader (CAT3K_CAA-HBOOT-M) Version 4.66, RELEASE SOFTWARE (P)

Technology Package License Information: 

------------------------------------------------------------------------------
Technology-package                                     Technology-package
Current                        Type                       Next reboot  
------------------------------------------------------------------------------
ipbasek9                Smart License                    ipbasek9            
None                    Subscription Smart License       None                          


Smart Licensing Status: UNREGISTERED/EVAL MODE

cisco WS-C3650-48PD (MIPS) processor (revision A0) with 832395K/6147K bytes of memory.
Processor board ID FDO1811Q040
1 Virtual Ethernet interface
50 Gigabit Ethernet interfaces
2 Ten Gigabit Ethernet interfaces
2048K bytes of non-volatile configuration memory.
4194304K bytes of physical memory.
250456K bytes of Crash Files at crashinfo:.
1609272K bytes of Flash at flash:.
0K bytes of WebUI ODM Files at webui:.

Base Ethernet MAC Address          : 64:12:25:15:b7:80
Motherboard Assembly Number        : 73-15125-05
Motherboard Serial Number          : FDO18101N27
Model Revision Number              : A0
Motherboard Revision Number        : A0
Model Number                       : WS-C3650-48PD
System Serial Number               : FDO1811Q040


Switch Ports Model              SW Version        SW Image              Mode   
------ ----- -----              ----------        ----------            ----   
*    1 52    WS-C3650-48PD      16.9.5            CAT3K_CAA-UNIVERSALK9 INSTALL


Configuration register is 0x102    


Configuration register is 0xF

STEPS TO REPRODUCE

task:

- cisco.ios.ios_vlans:
     state: overridden
     config:
       '{{ abc_campus_vlans }}'
  when: ansible_network_os == 'ios'

vars_file:

abc_campus_vlans:
 - name: default
   shutdown: disabled
   state: active
   vlan_id: 1
 - name: ABC
   shutdown: disabled
   state: active
   vlan_id: 4

show vlan:

<hostname>#show vlan

VLAN Name                             Status    Ports
---- -------------------------------- --------- -------------------------------
1    default                          active    
4    ABC                             active    
5    ABCDE-X.X.X.X_23           active    Gi1/0/1, Gi1/0/2, Gi1/0/3, Gi1/0/4, Gi1/0/5, Gi1/0/6, Gi1/0/7, Gi1/0/8, Gi1/0/9, Gi1/0/10, Gi1/0/11, Gi1/0/12, Gi1/0/13, Gi1/0/14, Gi1/0/15, Gi1/0/16, Gi1/0/17, Gi1/0/18, Gi1/0/19, Gi1/0/20, Gi1/0/21
                                                Gi1/0/22, Gi1/0/23, Gi1/0/24, Gi1/0/25, Gi1/0/26, Gi1/0/27, Gi1/0/28, Gi1/0/29, Gi1/0/30, Gi1/0/31, Gi1/0/32, Gi1/0/33, Gi1/0/34, Gi1/0/35, Gi1/0/36, Gi1/0/37, Gi1/0/38, Gi1/0/39, Gi1/0/40, Gi1/0/41, Gi1/0/42
                                                Gi1/0/43, Gi1/0/44, Gi1/0/45, Gi1/0/46, Gi1/0/47, Gi1/0/48
42   AB-CDโ€”VLANNAME_X.X.X.0_24 active    
51   ABC_VLAN_X.X.X.X_24        active    
55   ABCDEF-GUEST-VLAN-X.X.X.0_24  active    
56   ABC-DEF-AAAAAAAAA-X.X.X.0_24 active    
57   ABCDE-WLAN-X.X.X.0_24         active    
58   TEST-ABCDEFGH-NETWORK            active    
60   AB-X.X.X.0_22                  active    
87   VLAN-VLANNAME-X.X.X.0_24   active    
98   ABCDEFG                         active    
99   ABC-HR-X.X.X.0_27              active    
100  ABCDE_X.X.X.X_27              active    
101  PRINTERS_X.X.X.0_25           active    
103  AB-CONSOLES_X.X.X.0_23        active    
105  IT_X.X.X.0_24                 active    
106  ABC_X.X.X.0_23                active    
107  ABC-FINANCE_X.X.X.0_25        active    
109  ADMIN_X.X.X.0_25               active    
110  ABC-DEF-X.X.X.128_25           active    
112  CONFROOMS_X.X.X.0_23         active    
113  ABC_X.X.X.0_24                active    
114  ABCDCOM-X.X.X.0_24            active    
115  ABCDEFGH-CAM_X.X.X.0_24      active    
116  ABC-VLANNAME-X.X.X.0_28     active    
119  ABCDEF-MASKSTATION-X.X.X.0_28
                                      active    
120  ABC-EFG-VLANNAME-X.X.X.0_27  active    
121  ABC-WLAN-THUNDERVLAN-X.X.X.X_24
                                      active    
122  VLAN-WLAN-X.X.34.0_23       active    
123  AB-WLAN-X.X.X.0_23            active    
124  MASKVLAN-WLAN-X.X.X.0_28    active    
125  VLANX-WLAN-X.X.X.0_28       active    
126  ABC-DEFG-X.X.X.0_23           active    
127  CAMPUS-DEFAULT-X.X.X.0_22     active    
130  ABCDEFG-X.X.X.0_28           active    
138  ABC-X.X.X.0_24                active    
139  GUEST-ABC-X.X.X.0_26          active    
141  AB-CDEFGH-NETWORK_X.X.X.0_28   active    
450  AB-CDEFG-NETWORK                 active    
998  ABC-JUMPBOX-X.X.X.0_24       active    
999  ABC-MGMT-X.X.X.0_22          active    
1002 fddi-default                     act/unsup 
1003 trcrf-default                    act/unsup 
1004 fddinet-default                  act/unsup 
1005 trbrf-default                    act/unsup 

VLAN Type  SAID       MTU   Parent RingNo BridgeNo Stp  BrdgMode Trans1 Trans2
---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------
1    enet  100001     1500  -      -      -        -    -        0      0   
4    enet  100004     1500  -      -      -        -    -        0      0   
5    enet  100005     1500  -      -      -        -    -        0      0   
42   enet  100042     1500  -      -      -        -    -        0      0   
51   enet  100051     1500  -      -      -        -    -        0      0   
55   enet  100055     1500  -      -      -        -    -        0      0   
56   enet  100056     1500  -      -      -        -    -        0      0   
57   enet  100057     1500  -      -      -        -    -        0      0   
58   enet  100058     1500  -      -      -        -    -        0      0   
60   enet  100060     1500  -      -      -        -    -        0      0   
87   enet  100087     1500  -      -      -        -    -        0      0   
98   enet  100098     1500  -      -      -        -    -        0      0   
99   enet  100099     1500  -      -      -        -    -        0      0   
100  enet  100100     1500  -      -      -        -    -        0      0   
101  enet  100101     1500  -      -      -        -    -        0      0   
103  enet  100103     1500  -      -      -        -    -        0      0   
105  enet  100105     1500  -      -      -        -    -        0      0   
106  enet  100106     1500  -      -      -        -    -        0      0   
107  enet  100107     1500  -      -      -        -    -        0      0   
109  enet  100109     1500  -      -      -        -    -        0      0   
110  enet  100110     1500  -      -      -        -    -        0      0   
112  enet  100112     1500  -      -      -        -    -        0      0   
113  enet  100113     1500  -      -      -        -    -        0      0   
114  enet  100114     1500  -      -      -        -    -        0      0   
115  enet  100115     1500  -      -      -        -    -        0      0   
116  enet  100116     1500  -      -      -        -    -        0      0   
119  enet  100119     1500  -      -      -        -    -        0      0   
120  enet  100120     1500  -      -      -        -    -        0      0   
121  enet  100121     1500  -      -      -        -    -        0      0   
          
VLAN Type  SAID       MTU   Parent RingNo BridgeNo Stp  BrdgMode Trans1 Trans2
---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------
122  enet  100122     1500  -      -      -        -    -        0      0   
123  enet  100123     1500  -      -      -        -    -        0      0   
124  enet  100124     1500  -      -      -        -    -        0      0   
125  enet  100125     1500  -      -      -        -    -        0      0   
126  enet  100126     1500  -      -      -        -    -        0      0   
127  enet  100127     1500  -      -      -        -    -        0      0   
130  enet  100130     1500  -      -      -        -    -        0      0   
138  enet  100138     1500  -      -      -        -    -        0      0   
139  enet  100139     1500  -      -      -        -    -        0      0   
141  enet  100141     1500  -      -      -        -    -        0      0   
450  enet  100450     1500  -      -      -        -    -        0      0   
998  enet  100998     1500  -      -      -        -    -        0      0   
999  enet  100999     1500  -      -      -        -    -        0      0   
1002 fddi  101002     1500  -      -      -        -    -        0      0   
1003 trcrf 101003     4472  1005   3276   -        -    srb      0      0   
1004 fdnet 101004     1500  -      -      -        ieee -        0      0   
1005 trbrf 101005     4472  -      -      15       ibm  -        0      0   


VLAN AREHops STEHops Backup CRF
---- ------- ------- ----------
1003 7       7       off

Remote SPAN VLANs
------------------------------------------------------------------------------


Primary Secondary Type              Ports
------- --------- ----------------- ------------------------------------------

show vtp status:

<hostname>#show vtp status
VTP Version capable             : 1 to 3
VTP version running             : 3
VTP Domain Name                 : rkv-vtp-domain
VTP Pruning Mode                : Disabled
VTP Traps Generation            : Disabled
Device ID                       : c4c6.039b.cf80

Feature VLAN:
--------------
VTP Operating Mode                : Transparent
Number of existing VLANs          : 46
Number of existing extended VLANs : 0
Maximum VLANs supported locally   : 4096


Feature MST:
--------------
VTP Operating Mode                : Transparent


Feature UNKNOWN:
--------------
VTP Operating Mode                : Transparent

ACTUAL RESULTS

Trying to mask all customer information here so if you would like to see the full job log, playbook, and switch information just reach out internally.

vtp version 2 will break ios_vlans

SUMMARY

With vtp version set to 2 the ios_vlans fails with following traceback:

"Traceback (most recent call last):\n  File \"/root/.ansible/tmp/ansible-local-26914clklL4/ansible-tmp-1589219024.96-26923-82174175600206/AnsiballZ_ios_vlans.py\", line 102, in <module>\n    _ansiballz_main()\n  File \"/root/.ansible/tmp/ansible-local-26914clklL4/ansible-tmp-1589219024.96-26923-82174175600206/AnsiballZ_ios_vlans.py\", line 94, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/root/.ansible/tmp/ansible-local-26914clklL4/ansible-tmp-1589219024.96-26923-82174175600206/AnsiballZ_ios_vlans.py\", line 40, in invoke_module\n    runpy.run_module(mod_name='ansible_collections.cisco.ios.plugins.modules.ios_vlans', init_globals=None, run_name='__main__', alter_sys=True)\n  File \"/usr/lib64/python2.7/runpy.py\", line 176, in run_module\n    fname, loader, pkg_name)\n  File \"/usr/lib64/python2.7/runpy.py\", line 82, in _run_module_code\n    mod_name, mod_fname, mod_loader, pkg_name)\n  File \"/usr/lib64/python2.7/runpy.py\", line 72, in _run_code\n    exec code in run_globals\n  File \"/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/modules/ios_vlans.py\", line 472, in <module>\n  File \"/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/modules/ios_vlans.py\", line 467, in main\n  File \"/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/vlans/vlans.py\", line 69, in execute_module\n  File \"/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/vlans/vlans.py\", line 52, in get_interfaces_facts\n  File \"/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/facts.py\", line 94, in get_facts\n  File \"/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/facts/facts.py\", line 131, in get_network_resources_facts\n  File \"/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/vlans/vlans.py\", line 74, in populate_facts\n  File \"/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/vlans/vlans.py\", line 138, in render_config\nValueError: invalid literal for int() with base 10: 'Backup'\n"

Same thing with occur using gather_network_resources: vlans with ios_facts. Swiching to version 1 will correct the issue.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

./plugins/module_utils/network/ios/facts/vlans/vlans.py

ANSIBLE VERSION
ansible 2.9.7
  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/site-packages/ansible
  executable location = /bin/ansible
  python version = 2.7.5 (default, Apr  2 2020, 13:16:51) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
CONFIGURATION
HOST_KEY_CHECKING(/etc/ansible/ansible.cfg) = False
OS / ENVIRONMENT
an-iosl2-01#show version
Cisco IOS Software, vios_l2 Software (vios_l2-ADVENTERPRISEK9-M), Experimental Version 15.2(20170321:233949) [mmen 101]
Copyright (c) 1986-2017 by Cisco Systems, Inc.
Compiled Wed 22-Mar-17 08:38 by mmen


ROM: Bootstrap program is IOSv

an-iosl2-01 uptime is 20 weeks, 5 days, 12 hours, 39 minutes
System returned to ROM by reload
System image file is "flash0:/vios_l2-adventerprisek9-m"
Last reload reason: Unknown reason



This product contains cryptographic features and is subject to United
States and local country laws governing import, export, transfer and
use. Delivery of Cisco cryptographic products does not imply
third-party authority to import, export, distribute or use encryption.
Importers, exporters, distributors and users are responsible for
compliance with U.S. and local country laws. By using this product you
agree to comply with applicable laws and regulations. If you are unable
to comply with U.S. and local laws, return this product immediately.

A summary of U.S. laws governing Cisco cryptographic products may be found at:
http://www.cisco.com/wwl/export/crypto/tool/stqrg.html

If you require further assistance please contact us by sending email to
[email protected].

Cisco IOSv () processor (revision 1.0) with 734465K/50176K bytes of memory.
Processor board ID 9MUI61D7CNC
5 Gigabit Ethernet interfaces
DRAM configuration is 72 bits wide with parity disabled.
256K bytes of non-volatile configuration memory.
2097152K bytes of ATA System CompactFlash 0 (Read/Write)
0K bytes of ATA CompactFlash 1 (Read/Write)
0K bytes of ATA CompactFlash 2 (Read/Write)
10080K bytes of ATA CompactFlash 3 (Read/Write)

Configuration register is 0x101
an-iosl2-01#show vtp status
VTP Version capable             : 1 to 3
VTP version running             : 2
VTP Domain Name                 :
VTP Pruning Mode                : Disabled
VTP Traps Generation            : Disabled
Device ID                       : 5e00.0000.8000
Configuration last modified by 10.8.38.75 at 4-28-20 03:37:01
Local updater ID is 10.8.38.75 on interface Gi0/0 (first layer3 interface found)

Feature VLAN:
--------------
VTP Operating Mode                : Server
Maximum VLANs supported locally   : 1005
Number of existing VLANs          : 10
Configuration Revision            : 14
MD5 digest                        : 0xB1 0x7B 0x0D 0x99 0x9F 0x19 0xA1 0xF8
                                    0xFC 0xA6 0xD8 0x83 0x80 0x76 0x5A 0x52
STEPS TO REPRODUCE
  tasks:
    - name: add test vlan
      cisco.ios.ios_vlans:
        config:
          - name: vlan_test
            vlan_id: 330
            state: active
            shutdown: disabled
        state: merged
EXPECTED RESULTS
ACTUAL RESULTS
ansible-playbook 2.9.7
  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/site-packages/ansible
  executable location = /bin/ansible-playbook
  python version = 2.7.5 (default, Apr  2 2020, 13:16:51) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
Using /etc/ansible/ansible.cfg as config file
host_list declined parsing /root/ios-facts/hosts as it did not pass its verify_file() method
script declined parsing /root/ios-facts/hosts as it did not pass its verify_file() method
auto declined parsing /root/ios-facts/hosts as it did not pass its verify_file() method
Parsed /root/ios-facts/hosts inventory source with ini plugin

PLAYBOOK: ios-vlans.yml *****************************************************************************
1 plays in ios-vlans.yml

PLAY [ec2_cisco_xe] *********************************************************************************
META: ran handlers

TASK [add test vlan] ********************************************************************************
task path: /root/ios-facts/ios-vlans.yml:6
<10.8.38.75> ESTABLISH LOCAL CONNECTION FOR USER: root
<10.8.38.75> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-local-26914clklL4 `"&& mkdir /root/.ansible/tmp/ansible-local-26914clklL4/ansible-tmp-1589219024.96-26923-82174175600206 && echo ansible-tmp-1589219024.96-26923-82174175600206="` echo /root/.ansible/tmp/ansible-local-26914clklL4/ansible-tmp-1589219024.96-26923-82174175600206 `" ) && sleep 0'
<10.8.38.75> Attempting python interpreter discovery
<10.8.38.75> EXEC /bin/sh -c 'echo PLATFORM; uname; echo FOUND; command -v '"'"'/usr/bin/python'"'"'; command -v '"'"'python3.7'"'"'; command -v '"'"'python3.6'"'"'; command -v '"'"'python3.5'"'"'; command -v '"'"'python2.7'"'"'; command -v '"'"'python2.6'"'"'; command -v '"'"'/usr/libexec/platform-python'"'"'; command -v '"'"'/usr/bin/python3'"'"'; command -v '"'"'python'"'"'; echo ENDFOUND && sleep 0'
<10.8.38.75> EXEC /bin/sh -c '/usr/bin/python && sleep 0'
Using module file /root/.ansible/collections/ansible_collections/cisco/ios/plugins/modules/ios_vlans.py
<10.8.38.75> PUT /root/.ansible/tmp/ansible-local-26914clklL4/tmpsoqotu TO /root/.ansible/tmp/ansible-local-26914clklL4/ansible-tmp-1589219024.96-26923-82174175600206/AnsiballZ_ios_vlans.py
<10.8.38.75> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-local-26914clklL4/ansible-tmp-1589219024.96-26923-82174175600206/ /root/.ansible/tmp/ansible-local-26914clklL4/ansible-tmp-1589219024.96-26923-82174175600206/AnsiballZ_ios_vlans.py && sleep 0'
<10.8.38.75> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-local-26914clklL4/ansible-tmp-1589219024.96-26923-82174175600206/AnsiballZ_ios_vlans.py && sleep 0'
<10.8.38.75> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-local-26914clklL4/ansible-tmp-1589219024.96-26923-82174175600206/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/root/.ansible/tmp/ansible-local-26914clklL4/ansible-tmp-1589219024.96-26923-82174175600206/AnsiballZ_ios_vlans.py", line 102, in <module>
    _ansiballz_main()
  File "/root/.ansible/tmp/ansible-local-26914clklL4/ansible-tmp-1589219024.96-26923-82174175600206/AnsiballZ_ios_vlans.py", line 94, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/root/.ansible/tmp/ansible-local-26914clklL4/ansible-tmp-1589219024.96-26923-82174175600206/AnsiballZ_ios_vlans.py", line 40, in invoke_module
    runpy.run_module(mod_name='ansible_collections.cisco.ios.plugins.modules.ios_vlans', init_globals=None, run_name='__main__', alter_sys=True)
  File "/usr/lib64/python2.7/runpy.py", line 176, in run_module
    fname, loader, pkg_name)
  File "/usr/lib64/python2.7/runpy.py", line 82, in _run_module_code
    mod_name, mod_fname, mod_loader, pkg_name)
  File "/usr/lib64/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/modules/ios_vlans.py", line 472, in <module>
  File "/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/modules/ios_vlans.py", line 467, in main
  File "/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/vlans/vlans.py", line 69, in execute_module
  File "/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/vlans/vlans.py", line 52, in get_interfaces_facts
  File "/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/facts.py", line 94, in get_facts
  File "/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/facts/facts.py", line 131, in get_network_resources_facts
  File "/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/vlans/vlans.py", line 74, in populate_facts
  File "/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/vlans/vlans.py", line 138, in render_config
ValueError: invalid literal for int() with base 10: 'Backup'
fatal: [10.8.38.75]: FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "module_stderr": "Traceback (most recent call last):\n  File \"/root/.ansible/tmp/ansible-local-26914clklL4/ansible-tmp-1589219024.96-26923-82174175600206/AnsiballZ_ios_vlans.py\", line 102, in <module>\n    _ansiballz_main()\n  File \"/root/.ansible/tmp/ansible-local-26914clklL4/ansible-tmp-1589219024.96-26923-82174175600206/AnsiballZ_ios_vlans.py\", line 94, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/root/.ansible/tmp/ansible-local-26914clklL4/ansible-tmp-1589219024.96-26923-82174175600206/AnsiballZ_ios_vlans.py\", line 40, in invoke_module\n    runpy.run_module(mod_name='ansible_collections.cisco.ios.plugins.modules.ios_vlans', init_globals=None, run_name='__main__', alter_sys=True)\n  File \"/usr/lib64/python2.7/runpy.py\", line 176, in run_module\n    fname, loader, pkg_name)\n  File \"/usr/lib64/python2.7/runpy.py\", line 82, in _run_module_code\n    mod_name, mod_fname, mod_loader, pkg_name)\n  File \"/usr/lib64/python2.7/runpy.py\", line 72, in _run_code\n    exec code in run_globals\n  File \"/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/modules/ios_vlans.py\", line 472, in <module>\n  File \"/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/modules/ios_vlans.py\", line 467, in main\n  File \"/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/vlans/vlans.py\", line 69, in execute_module\n  File \"/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/vlans/vlans.py\", line 52, in get_interfaces_facts\n  File \"/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/facts.py\", line 94, in get_facts\n  File \"/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/facts/facts.py\", line 131, in get_network_resources_facts\n  File \"/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/vlans/vlans.py\", line 74, in populate_facts\n  File \"/tmp/ansible_cisco.ios.ios_vlans_payload_ybCUzk/ansible_cisco.ios.ios_vlans_payload.zip/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/vlans/vlans.py\", line 138, in render_config\nValueError: invalid literal for int() with base 10: 'Backup'\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}

PLAY RECAP ******************************************************************************************
10.8.38.75                 : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

L3 Subinterface Improperly Parsed by l2_interfaces_facts

SUMMARY

ios_facts improperly parses l2_interfaces_facts for L3 subinterface

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_facts

ANSIBLE VERSION
ansible 2.9.9
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/user/.venv/sandbox/lib/python3.7/site-packages/ansible
  executable location = /home/user/.venv/sandbox/bin/ansible
  python version = 3.7.7 (default, Mar 13 2020, 21:39:43) [GCC 9.2.1 20190827 (Red Hat 9.2.1-1)]

CONFIGURATION
DEFAULT_ASK_VAULT_PASS(/etc/ansible/ansible.cfg) = True
INTERPRETER_PYTHON(/etc/ansible/ansible.cfg) = auto
PERSISTENT_COMMAND_TIMEOUT(/etc/ansible/ansible.cfg) = 90
PERSISTENT_CONNECT_TIMEOUT(/etc/ansible/ansible.cfg) = 90
RETRY_FILES_ENABLED(/etc/ansible/ansible.cfg) = False
OS / ENVIRONMENT

#show version
Cisco IOS Software, vios_l2 Software (vios_l2-ADVENTERPRISEK9-M), Experimental Version 15.2(20170321:233949) [mmen 101]
Copyright (c) 1986-2017 by Cisco Systems, Inc.
Compiled Wed 22-Mar-17 08:38 by mmen

STEPS TO REPRODUCE

inventory

[ios]
10.10.10.10

[ios:vars]
ansible_connection=network_cli
ansible_network_os=ios
---
- hosts: all
  gather_facts: false
  tasks:
    - name: get config
      ios_facts:
        gather_network_resources: l2_interfaces
      register: result
    - name: debug result
      debug:
        var: result
EXPECTED RESULTS

Facts are successfully gathered

ACTUAL RESULTS
fatal: [10.10.10.10]: FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "invocation": {
        "module_args": {
            "config": [
                {
                    "access": null,
                    "name": "GigabitEthernet0/0",
                    "trunk": null
                },
                {
                    "access": null,
                    "name": "GigabitEthernet0/1",
                    "trunk": null
                },
                {
                    "access": null,
                    "name": "GigabitEthernet0/2",
                    "trunk": {
                        "allowed_vlans": null,
                        "encapsulation": "dot1q",
                        "native_vlan": null,
                        "pruning_vlans": null
                    }
                },
                {
                    "access": null,
                    "name": "GigabitEthernet0/2.1",
                    "trunk": {
                        "encapsulation": "dot1Q 10"
                    }
                }
            ],
            "state": "merged"
        }
    },
    "msg": "value of encapsulation must be one of: dot1q, isl, negotiate, got: dot1Q 10 found in config -> trunk"
}

Network resource modules behaves inconsistently between IOS/EOS

SUMMARY

Playbook tasks that use the IOS Resource modules do not print out the proposed changes when executed in check mode.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

An example would be ios_l3_interfaces. But it is not just this one module.

ANSIBLE VERSION
ansible 2.9.3
  config file = /home/student1/gerald_test/ansible.cfg
  configured module search path = [u'/home/student1/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Jun 11 2019, 14:33:56) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]

CONFIGURATION
COLLECTIONS_PATHS(/home/student1/gerald_test/ansible.cfg) = [u'/home/student1/gerald_test/coll
DEFAULT_HOST_LIST(/home/student1/gerald_test/ansible.cfg) = [u'/home/student1/networking-works
DEFAULT_STDOUT_CALLBACK(/home/student1/gerald_test/ansible.cfg) = yaml
DEPRECATION_WARNINGS(/home/student1/gerald_test/ansible.cfg) = False
HOST_KEY_CHECKING(/home/student1/gerald_test/ansible.cfg) = False
PERSISTENT_COMMAND_TIMEOUT(/home/student1/gerald_test/ansible.cfg) = 600
PERSISTENT_CONNECT_TIMEOUT(/home/student1/gerald_test/ansible.cfg) = 600
RETRY_FILES_ENABLED(/home/student1/gerald_test/ansible.cfg) = False

OS / ENVIRONMENT

Linux ansible 3.10.0-1062.el7.x86_64 #1 SMP Thu Jul 18 20:25:13 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
Cisco CSR

STEPS TO REPRODUCE
---
- name: IOS Resource module test
  hosts: rtr1
  gather_facts: no
  tags: ios
  tasks:
    - name: GATHER L3 CONFIG
      ios_facts:
        gather_subset: min
        gather_network_resources: l3_interfaces

    - name: DISPLAY INTERFACE DATA
      debug: var=ansible_network_resources

    - name: ADD LOOPBACK
      ios_l3_interfaces:
        config: 
          - name: Loopback 100
            ipv4:
              - address: 192.168.0.1/24
        state: merged        
          
        
- name: EOS Resource module test
  hosts: rtr2
  gather_facts: no
  tags: eos
  tasks:
    - name: GATHER L3 CONFIG
      eos_facts:
        gather_subset: min
        gather_network_resources: l3_interfaces

    - name: DISPLAY INTERFACE DATA
      debug: var=ansible_network_resources

    - name: ADD LOOPBACK
      eos_l3_interfaces:
        config: 
          - name: Loopback 100
            ipv4:
              - address: 192.168.0.1/24
        state: merged    

Execute using check mode to see the difference:

ansible-playbook resource_test.yaml --check -v
EXPECTED RESULTS

Expect the ios modules to also display the changed config to be displayed.

ACTUAL RESULTS
[student1@ansible gerald_test]$ ansible-playbook resource_test.yaml --check -v
Using /home/student1/gerald_test/ansible.cfg as config file

PLAY [IOS Resource module test] **************************************************************

TASK [GATHER L3 CONFIG] **********************************************************************
[WARNING]: default value for `gather_subset` will be changed to `min` from `!config` v2.11
onwards

ok: [rtr1] => changed=false 
  ansible_facts:
    ansible_net_api: cliconf
    ansible_net_gather_network_resources:
    - l3_interfaces
    ansible_net_gather_subset:
    - default
    ansible_net_hostname: ip-172-16-149-162
    ansible_net_image: bootflash:packages.conf
    ansible_net_iostype: IOS-XE
    ansible_net_model: CSR1000V
    ansible_net_python_version: 2.7.5
    ansible_net_serialnum: 9NHO4224RYH
    ansible_net_system: ios
    ansible_net_version: 16.09.02
    ansible_network_resources:
      l3_interfaces:
      - ipv4:
        - address: dhcp
        name: GigabitEthernet1
    discovered_interpreter_python: /usr/bin/python

TASK [DISPLAY INTERFACE DATA] ****************************************************************
ok: [rtr1] => 
  ansible_network_resources:
    l3_interfaces:
    - ipv4:
      - address: dhcp
      name: GigabitEthernet1

TASK [ADD LOOPBACK] **************************************************************************
ok: [rtr1] => changed=false 
  before:
  - ipv4:
    - address: dhcp
    name: GigabitEthernet1
  commands: []

PLAY [EOS Resource module test] **************************************************************

TASK [GATHER L3 CONFIG] **********************************************************************
ok: [rtr2] => changed=false 
  ansible_facts:
    ansible_net_api: cliconf
    ansible_net_fqdn: rtr2
    ansible_net_gather_network_resources:
    - l3_interfaces
    ansible_net_gather_subset:
    - default
    ansible_net_hostname: rtr2
    ansible_net_image: flash:vEOS-Router.swi
    ansible_net_model: vEOS
    ansible_net_python_version: 2.7.5
    ansible_net_serialnum: 7D3DD3733E86DADEA9A86FBE905D0F4A
    ansible_net_system: eos
    ansible_net_version: 4.22.1FX-VEOSRouter-cloud
    ansible_network_resources:
      l3_interfaces:
      - ipv4:
        - address: dhcp
        name: Ethernet1
      - ipv4:
        - address: 192.168.2.2/32
        name: Loopback0
      - ipv4:
        - address: 10.101.101.2/24
        name: Tunnel0
      - ipv4:
        - address: 10.200.200.2/24
        name: Tunnel1
    discovered_interpreter_python: /usr/bin/python

TASK [DISPLAY INTERFACE DATA] ****************************************************************
ok: [rtr2] => 
  ansible_network_resources:
    l3_interfaces:
    - ipv4:
      - address: dhcp
      name: Ethernet1
    - ipv4:
      - address: 192.168.2.2/32
      name: Loopback0
    - ipv4:
      - address: 10.101.101.2/24
      name: Tunnel0
    - ipv4:
      - address: 10.200.200.2/24
      name: Tunnel1

TASK [ADD LOOPBACK] **************************************************************************
changed: [rtr2] => changed=true 
  after:
  - ipv4:
    - address: dhcp
    name: Ethernet1
  - ipv4:
    - address: 192.168.2.2/32
    name: Loopback0
  - ipv4:
    - address: 10.101.101.2/24
    name: Tunnel0
  - ipv4:
    - address: 10.200.200.2/24
    name: Tunnel1
  before:
  - ipv4:
    - address: dhcp
    name: Ethernet1
  - ipv4:
    - address: 192.168.2.2/32
    name: Loopback0
  - ipv4:
    - address: 10.101.101.2/24
    name: Tunnel0
  - ipv4:
    - address: 10.200.200.2/24
    name: Tunnel1
  commands:
  - interface Loopback100
  - ip address 192.168.0.1/24

PLAY RECAP ***********************************************************************************
rtr1                       : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
rtr2                       : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   


ios_l3_interfaces doesn't create loopback interfaces when one doesn't exist

SUMMARY

When state is set to merged AND loopback interface doesn't exist, new loopback interface is not created. This is not the case when interface exists.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ios_l3_interfaces module

ANSIBLE VERSION
ansible 2.9.9
  config file = /home/ansible/network_automation/ansible/ansible.cfg
  configured module search path = ['/home/ansible/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.8/site-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 3.8.3 (default, May 26 2020, 14:44:41) [GCC 8.3.0]
CONFIGURATION
ACTION_WARNINGS(default) = True
AGNOSTIC_BECOME_PROMPT(default) = True
ALLOW_WORLD_READABLE_TMPFILES(default) = False
ANSIBLE_CONNECTION_PATH(default) = None
ANSIBLE_COW_PATH(default) = None
ANSIBLE_COW_SELECTION(default) = default
ANSIBLE_COW_WHITELIST(default) = ['bud-frogs', 'bunny', 'cheese', 'daemon', 'default', 'dragon', 'elephant-in-snake', 'elephant', 'eyes', 'hellokitty', 'kitty', 'luke-koala', 'meow', 'milk', 'moofasa', 'moose', 'ren', 'sheep', 'small', 's
ANSIBLE_FORCE_COLOR(default) = False
ANSIBLE_NOCOLOR(default) = False
ANSIBLE_NOCOWS(default) = False
ANSIBLE_PIPELINING(default) = False
ANSIBLE_SSH_ARGS(default) = -C -o ControlMaster=auto -o ControlPersist=60s
ANSIBLE_SSH_CONTROL_PATH(default) = None
ANSIBLE_SSH_CONTROL_PATH_DIR(default) = ~/.ansible/cp
ANSIBLE_SSH_EXECUTABLE(default) = ssh
ANSIBLE_SSH_RETRIES(default) = 0
ANY_ERRORS_FATAL(default) = False
BECOME_ALLOW_SAME_USER(default) = False
BECOME_PLUGIN_PATH(default) = ['/home/ansible/.ansible/plugins/become', '/usr/share/ansible/plugins/become']
CACHE_PLUGIN(default) = memory
CACHE_PLUGIN_CONNECTION(default) = None
CACHE_PLUGIN_PREFIX(default) = ansible_facts
CACHE_PLUGIN_TIMEOUT(default) = 86400
COLLECTIONS_PATHS(default) = ['/home/ansible/.ansible/collections', '/usr/share/ansible/collections']
COLOR_CHANGED(default) = yellow
COLOR_CONSOLE_PROMPT(default) = white
COLOR_DEBUG(default) = dark gray
COLOR_DEPRECATE(default) = purple
COLOR_DIFF_ADD(default) = green
COLOR_DIFF_LINES(default) = cyan
COLOR_DIFF_REMOVE(default) = red
COLOR_ERROR(default) = red
COLOR_HIGHLIGHT(default) = white
COLOR_OK(default) = green
COLOR_SKIP(default) = cyan
COLOR_UNREACHABLE(default) = bright red
COLOR_VERBOSE(default) = blue
COLOR_WARN(default) = bright purple
COMMAND_WARNINGS(default) = True
CONDITIONAL_BARE_VARS(default) = True
CONNECTION_FACTS_MODULES(default) = {'eos': 'eos_facts', 'frr': 'frr_facts', 'ios': 'ios_facts', 'iosxr': 'iosxr_facts', 'junos': 'junos_facts', 'nxos': 'nxos_facts', 'vyos': 'vyos_facts'}
COVERAGE_REMOTE_OUTPUT(default) = None
COVERAGE_REMOTE_WHITELIST(default) = *
DEFAULT_ACTION_PLUGIN_PATH(default) = ['/home/ansible/.ansible/plugins/action', '/usr/share/ansible/plugins/action']
DEFAULT_ALLOW_UNSAFE_LOOKUPS(default) = False
DEFAULT_ASK_PASS(default) = False
DEFAULT_ASK_VAULT_PASS(default) = False
DEFAULT_BECOME(default) = False
DEFAULT_BECOME_ASK_PASS(default) = False
DEFAULT_BECOME_EXE(default) = None
DEFAULT_BECOME_FLAGS(default) =
DEFAULT_BECOME_METHOD(default) = sudo
DEFAULT_BECOME_USER(default) = root
DEFAULT_CACHE_PLUGIN_PATH(default) = ['/home/ansible/.ansible/plugins/cache', '/usr/share/ansible/plugins/cache']
DEFAULT_CALLABLE_WHITELIST(default) = []
DEFAULT_CALLBACK_PLUGIN_PATH(default) = ['/home/ansible/.ansible/plugins/callback', '/usr/share/ansible/plugins/callback']
DEFAULT_CALLBACK_WHITELIST(default) = []
DEFAULT_CLICONF_PLUGIN_PATH(default) = ['/home/ansible/.ansible/plugins/cliconf', '/usr/share/ansible/plugins/cliconf']
DEFAULT_CONNECTION_PLUGIN_PATH(default) = ['/home/ansible/.ansible/plugins/connection', '/usr/share/ansible/plugins/connection']
DEFAULT_DEBUG(default) = False
DEFAULT_EXECUTABLE(default) = /bin/sh
DEFAULT_FACT_PATH(default) = None
DEFAULT_FILTER_PLUGIN_PATH(default) = ['/home/ansible/.ansible/plugins/filter', '/usr/share/ansible/plugins/filter']
DEFAULT_FORCE_HANDLERS(default) = False
DEFAULT_FORKS(default) = 5
DEFAULT_GATHERING(/home/ansible/network_automation/ansible/ansible.cfg) = explicit
DEFAULT_GATHER_SUBSET(default) = ['all']
DEFAULT_GATHER_TIMEOUT(default) = 10
DEFAULT_HANDLER_INCLUDES_STATIC(default) = False
DEFAULT_HASH_BEHAVIOUR(default) = replace
DEFAULT_HOST_LIST(/home/ansible/network_automation/ansible/ansible.cfg) = ['/home/ansible/network_automation/ansible/hosts']
DEFAULT_HTTPAPI_PLUGIN_PATH(default) = ['/home/ansible/.ansible/plugins/httpapi', '/usr/share/ansible/plugins/httpapi']
DEFAULT_INTERNAL_POLL_INTERVAL(default) = 0.001
DEFAULT_INVENTORY_PLUGIN_PATH(default) = ['/home/ansible/.ansible/plugins/inventory', '/usr/share/ansible/plugins/inventory']
DEFAULT_JINJA2_EXTENSIONS(default) = []
DEFAULT_JINJA2_NATIVE(default) = False
DEFAULT_KEEP_REMOTE_FILES(default) = False
DEFAULT_LIBVIRT_LXC_NOSECLABEL(default) = False
DEFAULT_LOAD_CALLBACK_PLUGINS(default) = False
DEFAULT_LOCAL_TMP(default) = /home/ansible/.ansible/tmp/ansible-local-8258d6ghl552
DEFAULT_LOG_FILTER(default) = []
DEFAULT_LOG_PATH(default) = None
DEFAULT_LOOKUP_PLUGIN_PATH(default) = ['/home/ansible/.ansible/plugins/lookup', '/usr/share/ansible/plugins/lookup']
DEFAULT_MANAGED_STR(default) = Ansible managed
DEFAULT_MODULE_ARGS(default) =
DEFAULT_MODULE_COMPRESSION(default) = ZIP_DEFLATED
DEFAULT_MODULE_NAME(default) = command
DEFAULT_MODULE_PATH(default) = ['/home/ansible/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
DEFAULT_MODULE_UTILS_PATH(default) = ['/home/ansible/.ansible/plugins/module_utils', '/usr/share/ansible/plugins/module_utils']
DEFAULT_NETCONF_PLUGIN_PATH(default) = ['/home/ansible/.ansible/plugins/netconf', '/usr/share/ansible/plugins/netconf']
DEFAULT_NO_LOG(default) = False
DEFAULT_NO_TARGET_SYSLOG(default) = False
DEFAULT_NULL_REPRESENTATION(default) = None
DEFAULT_POLL_INTERVAL(default) = 15
DEFAULT_PRIVATE_KEY_FILE(default) = None
DEFAULT_PRIVATE_ROLE_VARS(default) = False
DEFAULT_REMOTE_PORT(default) = None
DEFAULT_REMOTE_USER(default) = None
DEFAULT_ROLES_PATH(default) = ['/home/ansible/.ansible/roles', '/usr/share/ansible/roles', '/etc/ansible/roles']
DEFAULT_SCP_IF_SSH(default) = smart
DEFAULT_SELINUX_SPECIAL_FS(default) = ['fuse', 'nfs', 'vboxsf', 'ramfs', '9p', 'vfat']
DEFAULT_SFTP_BATCH_MODE(default) = True
DEFAULT_SQUASH_ACTIONS(default) = ['apk', 'apt', 'dnf', 'homebrew', 'openbsd_pkg', 'pacman', 'pip', 'pkgng', 'yum', 'zypper']
DEFAULT_SSH_TRANSFER_METHOD(default) = None
DEFAULT_STDOUT_CALLBACK(default) = default
DEFAULT_STRATEGY(default) = linear
DEFAULT_STRATEGY_PLUGIN_PATH(default) = ['/home/ansible/.ansible/plugins/strategy', '/usr/share/ansible/plugins/strategy']
DEFAULT_SU(default) = False
DEFAULT_SYSLOG_FACILITY(default) = LOG_USER
DEFAULT_TASK_INCLUDES_STATIC(default) = False
DEFAULT_TERMINAL_PLUGIN_PATH(default) = ['/home/ansible/.ansible/plugins/terminal', '/usr/share/ansible/plugins/terminal']
DEFAULT_TEST_PLUGIN_PATH(default) = ['/home/ansible/.ansible/plugins/test', '/usr/share/ansible/plugins/test']
DEFAULT_TIMEOUT(default) = 10
DEFAULT_TRANSPORT(default) = smart
DEFAULT_UNDEFINED_VAR_BEHAVIOR(default) = True
DEFAULT_VARS_PLUGIN_PATH(default) = ['/home/ansible/.ansible/plugins/vars', '/usr/share/ansible/plugins/vars']
DEFAULT_VAULT_ENCRYPT_IDENTITY(default) = None
DEFAULT_VAULT_IDENTITY(default) = default
DEFAULT_VAULT_IDENTITY_LIST(default) = []
DEFAULT_VAULT_ID_MATCH(default) = False
DEFAULT_VAULT_PASSWORD_FILE(default) = None
DEFAULT_VERBOSITY(default) = 0
DEPRECATION_WARNINGS(default) = True
DIFF_ALWAYS(default) = False
DIFF_CONTEXT(default) = 3
DISPLAY_ARGS_TO_STDOUT(default) = False
DISPLAY_SKIPPED_HOSTS(default) = True
DOCSITE_ROOT_URL(default) = https://docs.ansible.com/ansible/
DOC_FRAGMENT_PLUGIN_PATH(default) = ['/home/ansible/.ansible/plugins/doc_fragments', '/usr/share/ansible/plugins/doc_fragments']
DUPLICATE_YAML_DICT_KEY(default) = warn
ENABLE_TASK_DEBUGGER(default) = False
ERROR_ON_MISSING_HANDLER(default) = True
FACTS_MODULES(default) = ['smart']
GALAXY_IGNORE_CERTS(default) = False
GALAXY_ROLE_SKELETON(default) = None
GALAXY_ROLE_SKELETON_IGNORE(default) = ['^.git$', '^.*/.git_keep$']
GALAXY_SERVER(default) = https://galaxy.ansible.com
GALAXY_SERVER_LIST(default) = None
GALAXY_TOKEN(default) = None
GALAXY_TOKEN_PATH(default) = /home/ansible/.ansible/galaxy_token
HOST_KEY_CHECKING(/home/ansible/network_automation/ansible/ansible.cfg) = False
HOST_PATTERN_MISMATCH(default) = warning
INJECT_FACTS_AS_VARS(default) = True
INTERPRETER_PYTHON(default) = auto_legacy
INTERPRETER_PYTHON_DISTRO_MAP(default) = {'centos': {'6': '/usr/bin/python', '8': '/usr/libexec/platform-python'}, 'fedora': {'23': '/usr/bin/python3'}, 'redhat': {'6': '/usr/bin/python', '8': '/usr/libexec/platform-python'}, 'rhel': {'6'
INTERPRETER_PYTHON_FALLBACK(default) = ['/usr/bin/python', 'python3.7', 'python3.6', 'python3.5', 'python2.7', 'python2.6', '/usr/libexec/platform-python', '/usr/bin/python3', 'python']
INVALID_TASK_ATTRIBUTE_FAILED(default) = True
INVENTORY_ANY_UNPARSED_IS_FAILED(default) = False
INVENTORY_CACHE_ENABLED(default) = False
INVENTORY_CACHE_PLUGIN(default) = None
INVENTORY_CACHE_PLUGIN_CONNECTION(default) = None
INVENTORY_CACHE_PLUGIN_PREFIX(default) = ansible_facts
INVENTORY_CACHE_TIMEOUT(default) = 3600
INVENTORY_ENABLED(default) = ['host_list', 'script', 'auto', 'yaml', 'ini', 'toml']
INVENTORY_EXPORT(default) = False
INVENTORY_IGNORE_EXTS(default) = {{(BLACKLIST_EXTS + ( '.orig', '.ini', '.cfg', '.retry'))}}
INVENTORY_IGNORE_PATTERNS(default) = []
INVENTORY_UNPARSED_IS_FAILED(default) = False
LOCALHOST_WARNING(default) = True
MAX_FILE_SIZE_FOR_DIFF(default) = 104448
NETCONF_SSH_CONFIG(default) = None
NETWORK_GROUP_MODULES(default) = ['eos', 'nxos', 'ios', 'iosxr', 'junos', 'enos', 'ce', 'vyos', 'sros', 'dellos9', 'dellos10', 'dellos6', 'asa', 'aruba', 'aireos', 'bigip', 'ironware', 'onyx', 'netconf']
OLD_PLUGIN_CACHE_CLEARING(default) = False
PARAMIKO_HOST_KEY_AUTO_ADD(default) = False
PARAMIKO_LOOK_FOR_KEYS(default) = True
PERSISTENT_COMMAND_TIMEOUT(default) = 30
PERSISTENT_CONNECT_RETRY_TIMEOUT(default) = 15
PERSISTENT_CONNECT_TIMEOUT(default) = 30
PERSISTENT_CONTROL_PATH_DIR(default) = /home/ansible/.ansible/pc
PLAYBOOK_DIR(default) = None
PLAYBOOK_VARS_ROOT(default) = top
PLUGIN_FILTERS_CFG(default) = None
PYTHON_MODULE_RLIMIT_NOFILE(default) = 0
RETRY_FILES_ENABLED(/home/ansible/network_automation/ansible/ansible.cfg) = False
RETRY_FILES_SAVE_PATH(default) = None
SHOW_CUSTOM_STATS(default) = False
STRING_CONVERSION_ACTION(default) = warn
STRING_TYPE_FILTERS(default) = ['string', 'to_json', 'to_nice_json', 'to_yaml', 'ppretty', 'json']
SYSTEM_WARNINGS(default) = True
TAGS_RUN(default) = []
TAGS_SKIP(default) = []
TASK_DEBUGGER_IGNORE_ERRORS(default) = True
TRANSFORM_INVALID_GROUP_CHARS(default) = never
USE_PERSISTENT_CONNECTIONS(default) = False
VARIABLE_PRECEDENCE(default) = ['all_inventory', 'groups_inventory', 'all_plugins_inventory', 'all_plugins_play', 'groups_plugins_inventory', 'groups_plugins_play']
VERBOSE_TO_STDERR(default) = False
YAML_FILENAME_EXTENSIONS(default) = ['.yml', '.yaml', '.json']
OS / ENVIRONMENT

Cisco IOS Software, 7200 Software (C7200-ADVENTERPRISEK9-M), Version 15.1(4)M4, RELEASE SOFTWARE (fc1)

STEPS TO REPRODUCE

Just try to configure loopback interface that doesn't exist:

ansible@debian:~/network_automation/ansible$ ansible-playbook 9_ansible_config_interface_using_ios_l3_interfaces.yaml

PLAY [Configuring loopback interfaces] *******************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
[WARNING]: Ignoring timeout(10) for ios_facts
[WARNING]: default value for `gather_subset` will be changed to `min` from `!config` v2.11 onwards
[WARNING]: Platform linux on host R1 is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
ok: [R1]

TASK [Configure router interfaces based on last number of hostname] **************************************************************************************************************************************************************************
ok: [R1]

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
R1                         : ok=2    **changed=0**    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

YAML file:

---
- name: Configuring loopback interfaces
  connection: network_cli
  gather_facts: true
  hosts: R1
  tasks:
    - name: Configure router interfaces based on last number of hostname
      ios_l3_interfaces:
        config:
          - name: loopback0
            ipv4:
            - address: "{{ loopback }}/32"
        state: merged

loopback here is set to 1.1.1.1 in hosts_vars.

EXPECTED RESULTS

Loopback interface is created and address 1.1.1.1/32 is assigned

ACTUAL RESULTS

No config change:

R1#sh ip int brief
Interface                  IP-Address      OK? Method Status                Protocol
Ethernet0/0                unassigned      YES NVRAM  administratively down down
GigabitEthernet0/0         192.168.122.71  YES NVRAM  up                    up
GigabitEthernet1/0         unassigned      YES NVRAM  administratively down down
GigabitEthernet2/0         unassigned      YES NVRAM  administratively down down
GigabitEthernet3/0         unassigned      YES NVRAM  administratively down down

However, if I create a loopback interface first it works:

R1#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
R1(config)#int l 0
R1(config-if)#end
R1#sh
*Jun 20 08:55:45.943: %LINK-3-UPDOWN: Interface Loopback0, changed state to up
*Jun 20 08:55:46.943: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback0, changed state to up
R1#sh ip int brief
Interface                  IP-Address      OK? Method Status                Protocol
Ethernet0/0                unassigned      YES NVRAM  administratively down down
GigabitEthernet0/0         192.168.122.71  YES NVRAM  up                    up
GigabitEthernet1/0         unassigned      YES NVRAM  administratively down down
GigabitEthernet2/0         unassigned      YES NVRAM  administratively down down
GigabitEthernet3/0         unassigned      YES NVRAM  administratively down down
Loopback0                  unassigned      YES manual up                    up
R1#

Now if I run playbook again:

ansible@debian:~/network_automation/ansible$ ansible-playbook 9_ansible_config_interface_using_ios_l3_interfaces.yaml

PLAY [Configuring loopback interfaces] *******************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
[WARNING]: Ignoring timeout(10) for ios_facts
[WARNING]: default value for `gather_subset` will be changed to `min` from `!config` v2.11 onwards
[WARNING]: Platform linux on host R1 is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
ok: [R1]

TASK [Configure router interfaces based on last number of hostname] **************************************************************************************************************************************************************************
changed: [R1]

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
R1                         : ok=2    **changed=1**    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Interface is correctly configured:

R1#sh ip int brief
Interface                  IP-Address      OK? Method Status                Protocol
Ethernet0/0                unassigned      YES NVRAM  administratively down down
GigabitEthernet0/0         192.168.122.71  YES NVRAM  up                    up
GigabitEthernet1/0         unassigned      YES NVRAM  administratively down down
GigabitEthernet2/0         unassigned      YES NVRAM  administratively down down
GigabitEthernet3/0         unassigned      YES NVRAM  administratively down down
Loopback0                  **1.1.1.1**         YES manual up                    up

Inclusion of cisco.ios in Ansible 2.10

This collection will be included in Ansible 2.10 because it contains modules and/or plugins that were included in Ansible 2.9. Please review:

DEADLINE: 2020-08-18

The latest version of the collection available on August 18 will be included in Ansible 2.10.0, except possibly newer versions which differ only in the patch level. (For details, see the roadmap). Please release version 1.0.0 of your collection by this date! If 1.0.0 does not exist, the same 0.x.y version will be used in all of Ansible 2.10 without updates, and your 1.x.y release will not be included until Ansible 2.11 (unless you request an exception at a community working group meeting and go through a demanding manual process to vouch for backwards compatibility . . . you want to avoid this!).

Follow semantic versioning rules

Your collection versioning must follow all semver rules. This means:

  • Patch level releases can only contain bugfixes;
  • Minor releases can contain new features, new modules and plugins, and bugfixes, but must not break backwards compatibility;
  • Major releases can break backwards compatibility.

Changelogs and Porting Guide

Your collection should provide data for the Ansible 2.10 changelog and porting guide. The changelog and porting guide are automatically generated from ansible-base, and from the changelogs of the included collections. All changes from the breaking_changes, major_changes, removed_features and deprecated_features sections will appear in both the changelog and the porting guide. You have two options for providing changelog fragments to include:

  1. If possible, use the antsibull-changelog tool, which uses the same changelog fragment as the ansible/ansible repository (see the documentation).
  2. If you cannot use antsibull-changelog, you can provide the changelog in a machine-readable format as changelogs/changelog.yaml inside your collection (see the documentation of changelogs/changelog.yaml format).

If you cannot contribute to the integrated Ansible changelog using one of these methods, please provide a link to your collection's changelog by creating an issue in https://github.com/ansible-community/ansible-build-data/. If you do not provide changelogs/changelog.yml or a link, users will not be able to find out what changed in your collection from the Ansible changelog and porting guide.

Make sure your collection passes the sanity tests

Run ansible-test sanity --docker -v in the collection with the latest ansible-base or stable-2.10 ansible/ansible checkout.

Keep informed

Be sure you're subscribed to:

Questions and Feedback

If you have questions or want to provide feedback, please see the Feedback section in the collection requirements.

(Internal link to keep track of issues: ansible-collections/overview#102)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.