ansible-collections / cisco.ios Goto Github PK
View Code? Open in Web Editor NEWAnsible Network Collection for Cisco IOS
License: GNU General Public License v3.0
Ansible Network Collection for Cisco IOS
License: GNU General Public License v3.0
From @dykow on Jul 27, 2020 10:22
Error is being thrown during module execution. Tested on Python 3.8.2
and Python 2.7.18rc1
with same result.
cisco.ios.ios_config
, but cisco.ios.ios_facts
produces same error, other cisco.ios
modules presumably too.
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]
HOST_KEY_CHECKING(/etc/ansible/ansible.cfg) = False
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)
/etc/ansible/hosts
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
Successful module execution.
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
$ 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"
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.
"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"
}
]
ios_facts
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)]
DEFAULT_FORKS(/etc/ansible/ansible.cfg) = 15
HOST_KEY_CHECKING(/etc/ansible/ansible.cfg) = False
INTERPRETER_PYTHON(/etc/ansible/ansible.cfg) = /usr/bin/python3
"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",
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
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"
}
],
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"
}
]
Currently, merge removes the ACE and then updates the config ideally, it should do dict merge of want and have.
ios_acls
2.10
mac os
Merge do a dict merge of want and have and replace doesn't do delete on ACL
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
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!
ios_facts
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]
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
Cisco WS-C3560-8PC-S
IOS 15.0(2)SE10a
---
- name: Test Collection
hosts: c3560-8p
collections:
- cisco.ios
tasks:
- name: Gather facts
ios_facts:
gather_subset:
- min
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
}
}
}
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": ""
}
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.
ios_l2_interfaces
L2_InterfacesFacts
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)]
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
Fedora 32
Cisco: Any IOS/IOS-XE Switch
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
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.
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
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 shows a change in check mode. However, when registering that variable, it's showing up as empty.
ios_interfaces
ios_banner
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)]
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
MacOS Mojave 10.14.6
- 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 }}
Registered variable to contain "commands"
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 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.
ios_vlans
2.9.6
- name: collect vlan facts for ios
ios_facts:
gather_network_resources:
- vlans
Module doc should reflect supported ios version and throw a user-readable error message for non-supported ios variants.
Throws error
line 185, in __rpc__\nansible.module_utils.connection.ConnectionError: show vlan\r\n% Ambiguous command: \"show vlan\"\r\nan-ios-02#\n",
If we want to add an host and set the facility, the idempotence is not working
ios_logging
module
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)]
HOST_KEY_CHECKING(/home/user/logm/ansible-test/ansible.cfg) = False
Switch Ports Model SW Version SW Image
------ ----- ----- ---------- ----------
* 1 26 WS-C2960+24TC-L 15.0(2)SE6 C2960-LANBASEK9-M
$ 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
Should not have any change after the first execution. Here is a example where we are running twice the same playbook.
$ 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
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.
ios_interfaces
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]
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
Target device:
Cisco IOS Software, C3560CX Software (C3560CX-UNIVERSALK9-M), Version 15.2(4)E5, RELEASE SOFTWARE (fc2)
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#
Module makes no changes if Loopback interface is configured already.
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
}
}
- 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.
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.
ios_facts
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
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
Centos7
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
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
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
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.
networking/ios_config
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.
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
}`
cisco.ios.ios_vlans
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)]
[root@AWX ~]# ansible-config dump --only-changed
[root@AWX ~]#
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)
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
json output of all vlans
{
"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
From @nniehoff on Jul 18, 2020 15:06
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.
ios_config
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]
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)
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"
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.
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
When using replace: block with ios_config
with multiple layers of parents, the lines are re-applied for every level of parent.
ios_config
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]
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
Controller is Ubuntu 18.04, devices are various Cisco IOS routers and switches.
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
Should only apply the following lines:
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)
From @cunningr on Jun 14, 2020 10:27
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.
network_cli
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]
DEFAULT_LOG_PATH(env: ANSIBLE_LOG_PATH) = /root/ansible.log
HOST_KEY_CHECKING(env: ANSIBLE_HOST_KEY_CHECKING) = False
Cisco catalyst 9K. IOS-XE.
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
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
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
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
}
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]
Debian 10 AWX 13
- name: Configure the LAGs
cisco.ios.ios_lag_interfaces:
config: '{{ lagmap }}'
state: overridden
when: lagmap | length > 0
I don't understand why It's sending multiple lag creations and then deletions in the same stream.. It makes no sense to me.
If a banner contains characters on the first line before the line break, ios_banner
crashes.
ios_banner
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]
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
Ubuntu 18.04 against Cisco IOS
- 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)
Banner should be updated
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.
To have the UNIT tests for ios_vlans with VTP version 2 as fixtures, for fixtures ref: #37
ios_vlans
the playbook is related to cisco ios upgrade
Bug Report
ios_command
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)]
[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
cisco c2960 with ios c2900-universalk9-mz.SPA.152-4.M3.bin
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
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
[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
Attempt to run playbook fails with exception if pruning not defined
ios_l2_interfaces
may be related to ansible/ansible#65032, as it works if port mode defined.
~/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]
Cisco WS-C3750X-48 running 15.2(4)E1
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
Successful port configuration
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'
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:
I opened this issue in a different repository and was asked to resubmit this request here by maintainer danielmellado.
ansible/ansible#67314 (comment)
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.
ios_facts
I had a working patch and can issue an pull request in the next days if this is
acceptable.
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.
ios_user
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)]
empty
EL7
Cisco IOS Software, C2960S Software (C2960S-UNIVERSALK9-M), Version 15.2(2)E9, RELEASE SOFTWARE (fc4)
---
- 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
testuser is left with the ssh keys of the second invocation.
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.
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: 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
[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, which is part of ios_facts gathering, is not correctly identifying all trunk ports as trunks.
ios_facts
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]
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
Cisco Catalyst 3850 switch
WS-C3850-48U
IOS 16.6.7
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
}
},
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.
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 throws a traceback when tried to configure protocol_options other than icmp
, igmp
and tcp
.
ios_acls
devel
mac os
- 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
ACE with igrp should be configured
Fails with a traceback
IOS L3 Interfaces Module not working with loopback interfaces.
Not possible to set IPv4 Address on Loopback Interface.
ios_l3_interfaces
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)]
- 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]
different Cisco IOS versions tested
p.e: Cisco IOS XE Software, Version 17.01.01
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
IP address on loopback1 should be set
IPv4 address is not set ("no ip address" on device)
Add gathered, rendered, parsed support to the Ansible 2.9
Resource Modules:
ios
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.
ios_facts module
using the ansible_net_iostype variable.
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)]
no output from command
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
i expect to gather facts for the four above devices and have each of them to print the result IOS-XE
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
Playbook tasks that use the IOS Resource modules do not print out the proposed changes when executed in check mode.
An example would be ios_l3_interfaces. But it is not just this one module.
[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 ~]$
[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 ~]$
Red Hat Enterprise Linux release 8.2 (Ootpa)
---
- 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
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#
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
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.
Tested with:
ios_interfaces
ios_vlans
eos_interfaces
eos_vlans
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
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
Cisco Nexus9000 7.0(3)I7(8)
Arista EOS 4.18.10M
- nxos_vlans:
config:
- vlan_id: 20
name: RED
state: active
- vlan_id: 30
name: BLUE
state: active
state: replaced
When nothing has changed, so before
and after
are identical, changed result should be false.
"changed": true
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
.
ios_config
2.7.15
2.8.5
2.9.1
RHEL 8.1
IOS 15.1.(3)T2๏ผ15.5(3)M5
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
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
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")
When gathering ios_facts l3_interfaces:
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.
ios_facts
utils.py
normalize_interface
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)]
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
"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"
Begin with:
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
***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"
}
]
}
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"
}
]
}
We have a CI failure because if an idempotent issue on ios_acls. Given this is python35, this is likely a dict sort issue.
ios_acl
If we want to enable logging (on
), the idempotence is not working
ios_logging
module
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)]
HOST_KEY_CHECKING(/home/user/logm/ansible-test/ansible.cfg) = False
Switch Ports Model SW Version SW Image
$ 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
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
$ 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
From @luwei19941010 on Jun 18, 2020 06:34
When trying to utilise the ( ios_l3_interfaces and ios_insterfaces ) module more than once within a playbook, a ConnectionError is thrown.
ansible-connection
connection.py
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 ~]#
CentOS-7-x86_64-DVD-1804
ROM: 3700 Software (C3725-ADVIPSERVICESK9-M), Version 12.4(3), RELEASE SOFTWARE (fc2)
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
interface f0/1 config ip and port status change up.
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
The gather_network_resources component of ios_facts module fails to parse acls
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)]
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
RHEL 8, CSR
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
Parsed ACL
{
"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
}
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
ios_l2_interfaces
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)]
all default
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
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
...
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
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"
}
}
}
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
ios_vlans
./module_utils/network/ios/facts/vlans/vlans.py
[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)]
[root@xxx-ansible03]# ansible-config dump --only-changed
DEFAULT_LOG_PATH(/etc/ansible/ansible.cfg) = /etc/ansible/ansible.log
<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
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
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.
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.
./plugins/module_utils/network/ios/facts/vlans/vlans.py
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)]
HOST_KEY_CHECKING(/etc/ansible/ansible.cfg) = False
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
tasks:
- name: add test vlan
cisco.ios.ios_vlans:
config:
- name: vlan_test
vlan_id: 330
state: active
shutdown: disabled
state: merged
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
ios_facts improperly parses l2_interfaces_facts for L3 subinterface
ios_facts
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)]
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
#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
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
Facts are successfully gathered
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"
}
Playbook tasks that use the IOS Resource modules do not print out the proposed changes when executed in check mode.
An example would be ios_l3_interfaces
. But it is not just this one module.
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)]
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
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
---
- 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
Expect the ios modules to also display the changed config to be displayed.
[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
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.
ios_l3_interfaces module
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]
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']
Cisco IOS Software, 7200 Software (C7200-ADVENTERPRISEK9-M), Version 15.1(4)M4, RELEASE SOFTWARE (fc1)
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.
Loopback interface is created and address 1.1.1.1/32 is assigned
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
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:
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!).
Your collection versioning must follow all semver rules. This means:
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:
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.
Run ansible-test sanity --docker -v
in the collection with the latest ansible-base or stable-2.10
ansible/ansible checkout.
Be sure you're subscribed to:
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)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.