napalm-automation / napalm-ansible Goto Github PK
View Code? Open in Web Editor NEWLicense: Apache License 2.0
License: Apache License 2.0
@ktbyers I was thinking in a more "pythonic" way of installing these modules. We could have a regular develop -> master -> release
lifecycle like we have with regular drivers and have the setup.py
provide a simple cli tool whereis-napalm-ansible
that returns the path to where the modules where installed so users can add that path to the ansible.cfg
file.
This would give us a simple mechanism to deploy the modules with all the pip goodies (pin versions, different venv with different versions of the modules, easy rollback if a newer version breaks something, etc).
Thoughts?
There isn't currently a license defined for this project, which makes things difficult for external contributors. It appears most of the other projects within the Napalm project are using Apache 2.0, so I'd suggest doing the same here.
This should be a pass
.
There are timing issues here on SSH connection closures:
<sw01> EXEC /bin/sh -c '/usr/bin/python /home/austindcc/.ansible/tmp/ansible-tmp-1510176054.16-142312610962492/napalm_get_facts.py; rm -rf "/home/austindcc/.ansible/tmp/ansible-tmp-1510176054.16-142312610962492/" > /dev/null 2>&1 && sleep 0'
The full traceback is:
File "/tmp/ansible_onTZIK/ansible_module_napalm_get_facts.py", line 260, in main
device.close()
File "/usr/local/lib/python2.7/dist-packages/napalm_ios/ios.py", line 154, in close
self.device.disconnect()
File "/usr/local/lib/python2.7/dist-packages/netmiko/base_connection.py", line 1053, in disconnect
self.remote_conn_pre.close()
File "/usr/local/lib/python2.7/dist-packages/paramiko/client.py", line 395, in close
self._transport.close()
File "/usr/local/lib/python2.7/dist-packages/paramiko/transport.py", line 658, in close
self.sock.close()
File "/usr/local/lib/python2.7/dist-packages/paramiko/proxy.py", line 110, in close
os.kill(self.process.pid, signal.SIGTERM)
Hi All,
I've been trying to test napalm with the following setup and keep getting the error as shown below.
update: I also tested connectivity
[rbotham@ernie napalmpb]$ sh conn_napalm.sh
Successfully connected to the device.
[rbotham@ernie napalmpb]$
Any assistance would be a great help
versions below
[rbotham@ernie napalmpb]$ ansible --version
[WARNING]: Optional dependency 'cryptography' raised an exception, falling back to 'Crypto'
ansible 2.1.1.0
config file = /etc/ansible/ansible.cfg
configured module search path = Default w/o overrides
[rbotham@ernie napalmpb]$ python --version
Python 2.7.8
napalm (1.1.0)
napalm-base (0.15.0)
napalm-eos (0.3.0)
napalm-fortios (0.1.1)
napalm-ibm (0.1.1)
napalm-ios (0.2.0)
napalm-iosxr (0.2.2)
napalm-junos (0.3.0)
napalm-nxos (0.3.0)
napalm-panos (0.1.0)
napalm-pluribus (0.3.0)
[rbotham@ernie napalmpb]$ ansible --version
[WARNING]: Optional dependency 'cryptography' raised an exception, falling back to 'Crypto'
ansible 2.1.1.0
config file = /etc/ansible/ansible.cfg
configured module search path = Default w/o overrides
host file contents below
[junos]
junipervm3
test_napalm2.yml file contents below
---
- name: Test NAPALM on JUNOS
hosts: junos
tasks:
- name: Test Napalm on Junos
napalm_install_config:
hostname: junipervm3
username: rich
password: password
config_file: new_config.conf
```Error
[rbotham@ernie napalmpb]$ ansible-playbook test_napalm2.yml -i ../../ansible-hosts
[WARNING]: Optional dependency 'cryptography' raised an exception, falling back to 'Crypto'
ERROR! no action detected in task. This often indicates a misspelled module name, or incorrect module path.
The error appears to have been in '/home/rbotham/playbooks/playbookdb/napalmpb/test_napalm2.yml': line 7, column 7, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
tasks:
- name: Test Napalm on Junos
^ here
The error appears to have been in '/home/rbotham/playbooks/playbookdb/napalmpb/test_napalm2.yml': line 7, column 7, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
tasks:
- name: Test Napalm on Junos
^ here
There is a long outstanding issue with ansible with setup.x files and gather_facts. If gather_facts: is not set for False, it will search for any file with setup.x in it under the ansible.cfg library path. This ends up failing for playbooks as there is a name space issue.
In ntc-modules there has been confusion and issues because of this, and I would recommend to remove the setup.py and setup.cfg file.
See ansible/ansible#20702 and ansible/ansible#20717 for further details.
Got "the python module napalm is required" when calling napalm_install_config, confirmed all the required python modules are installed along with the correct path in ansible.cfg.
$ pip freeze|grep -iE 'napalm|ansible'
ansible==2.6.3
napalm==2.3.2
napalm-ansible==0.10.0
$ grep -iE 'library|action_plugins' ansible.cfg
library = /usr/local/lib/python2.7/site-packages/napalm_ansible/modules
action_plugins = /usr/local/lib/python2.7/site-packages/napalm_ansible/plugins/action
The full traceback is:
File "/var/folders/hp/zbcbp7wd5zqgcph8b5bbr3f42vxdjf/T/ansible_Maungo/ansible_module_napalm_install_config.py", line 171, in <module>
from napalm_base import get_network_driver # noqa
fatal: [mgmtsw2-bos1]: FAILED! => {
"changed": false,
"invocation": {
"module_args": {
"archive_file": null,
"candidate_file": null,
"commit_changes": false,
"config": null,
"config_file": "configs/mgmtsw2-bos1",
"dev_os": "ios",
"diff_file": "configs/mgmtsw2-bos1.diff",
"get_diffs": true,
"hostname": "mgmtsw2-bos1",
"optional_args": null,
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"provider": {
"hostname": "mgmtsw2-bos1",
"password": null,
"timeout": 60,
"username": "ansible"
},
"replace_config": false,
"timeout": 60,
"username": "labuser"
}
},
"msg": "the python module napalm is required"
}
Also need to update test suite to add 2.4.0 to testing and deprecate 2.2.X testing.
Documentation says that when echo request fails there should be a response like this:
results:
# when echo request fails
{"error": "connect: Network is unreachable"}
I've tested this and get response like this:
"results": {
"success": {
"packet_loss": -2,
"probes_sent": 0,
"results": [],
"rtt_avg": 0.0,
"rtt_max": 0.0,
"rtt_min": 0.0,
"rtt_stddev": 0.0
}
My task:
- name: Ping hosts
napalm_ping:
destination: "{{ item }}"
dev_os: ios
count: "{{ ping_count | default(2) }}"
provider: "{{ provider }}"
optional_args: {'port': "{{ port | default(22) }}"}
with_items: "{{ pinghosts }}"
As stated in the title, this appears to be an problem with just napalm_install_config
module due to the fact that the stat
module is able to locate it fine.
Running the install role
:
TASK [install : Ensure assembled configuration file exists] ****************************************** [32/966]
ok: [rtp-vba-a]
TASK [install : debug] *******************************************************************************
ok: [rtp-vba-a] => {
"result.stat": {
"atime": 1499900564.0014858,
"attr_flags": "e",
"attributes": [
"extents"
],
"block_size": 4096,
"blocks": 152,
"charset": "us-ascii",
"checksum": "05a37e3fdb9a92e7efd17e3210bdde77d23bb729",
"ctime": 1499900527.9213126,
"dev": 64512,
"device_type": 0,
"executable": false,
"exists": true,
"gid": 901000001,
"gr_name": "coc-users",
"inode": 147520,
"isblk": false,
"ischr": false,
"isdir": false,
"isfifo": false,
"isgid": false,
"islnk": false,
"isreg": true,
"issock": false,
"isuid": false,
"md5": "345db65692def774e6af2e24f9d60bdb",
"mimetype": "text/plain",
"mode": "0644",
"mtime": 1499900527.9213126,
"nlink": 1,
"path": "/home/bl839s/.compiled/rtp-vba-a/assembled.conf",
"pw_name": "bl839s",
"readable": true,
"rgrp": true,
"roth": true,
"rusr": true,
"size": 77357,
"uid": 901000002,
"version": "18446744072107431939",
"wgrp": false,
"woth": false,
"writeable": true,
"wusr": true,
"xgrp": false,
"xoth": false,
"xusr": false
}
}
TASK [install : Fail is the configuration file cannot be located] ************************************
skipping: [rtp-vba-a]
TASK [install : Push configuration onto the device] **************************************************
fatal: [rtp-vba-a]: FAILED! => {"changed": false, "failed": true, "msg": "cannot load config: [Errno 2] No such file or directory: '~/.compiled/rtp-vba-a/assembled.conf'"}
PLAY RECAP *******************************************************************************************
rtp-vba-a : ok=2 changed=0 unreachable=0 failed=1
Contents of the install
role:
$ cat roles/install/tasks/main.yml
- name: Ensure assembled configuration file exists
stat:
path: "{{ host_dir }}/assembled.conf"
register: result
- debug:
var: result.stat
- name: Fail is the configuration file cannot be located
fail:
msg: "Cannot locate configuration file to push!"
when: result.stat.exists == False
- name: Push configuration onto the device
napalm_install_config:
provider: "{{ napalm }}"
config_file: "{{ host_dir }}/assembled.conf"
commit_changes: "{{ not ansible_check_mode }}"
get_diffs: true
diff_file: "{{ host_dir }}/config.diff"
- src: https://github.com/napalm-automation/napalm-ansible/
version: master
name: napalm
path: roles
In requirements.yml
then:
ansible-galaxy install -r requirements.yml --force
Returns
[WARNING]: - napalm was NOT installed successfully: ERROR! this role does not appear to have a meta/main.yml file.
I'm also having this problem when calling napalm via Ansible. Had to set privilege mode of user to 15 in order to get this module to work.
Also have to delete the secret variable as it breaks the playbook.
Netmiko version is 1.1.0.
Here is my playbook.yml
` - name: Push config to switch group.
hosts: test
connection: local
gather_facts: no
tasks:
name: get facts from device
napalm_get_facts:
hostname={{ inventory_hostname }}
username=theusername
dev_os=ios
password=thepassword
secret=thesecret
filter='interfaces'
register: result
debug: msg= "{{ result.stdout }}"`
Also need to add a set of unit tests to it.
Depending on the frequency of changes we also might to periodically make a release to that people can use a specific version of napalm-ansible without it being changed.
Hello guys,
When we follow examples (http://napalm.readthedocs.io/en/latest/tutorials/ansible-napalm.html or https://github.com/napalm-automation/napalm-ansible#examples), the hostname
is using the {{ inventory_hostname }}
But a classic host file is :
[cisco]
spine1 ansible_host=10.0.100.101
spine2 ansible_host=10.0.100.102
leaf1 ansible_host=10.0.100.103
leaf2 ansible_host=10.0.100.104
leaf3 ansible_host=10.0.100.105
leaf4 ansible_host=10.0.100.106
[cisco:vars]
ansible_python_interpreter= "/usr/bin/env python"
Here's the playbook example :
- name: Test Inventory #The Task Name
hosts: cisco #This will be in your ansible inventory file
connection: local #Required
gather_facts: no #Do not gather facts
tasks: #Begin Tasks
- name: get facts from device #Task Name
napalm_get_facts: #Call the napalm module, in this case napal_get_facts
hostname: "{{ inventory_hostname }}" #This is a parameter and is derived from your ansible inventory file
username: 'admin' #The username to ssh with
dev_os: 'nxos_ssh' #The hardware operating system
password: 'xxxx' #The line level password
filter: 'facts' #The list of items you want to retrieve. The filter keyword is _inclusive_ of what you want
register: result #Ansible function for collecting output
- name: print results #Task Name
debug: msg="{{ result }}" #Display the collected output
The playbook does not work
(flacommare_venv2.7) florian@ubuntuvm:~/ansible$ ansible-playbook playbooks/get_facts.yaml -i inventory/host.ini
PLAY [Test Inventory] ************************************************************************************************************************************************************************************************************************
TASK [get facts from device] *****************************************************************************************************************************************************************************************************************
fatal: [leaf2]: FAILED! => {"changed": false, "msg": "cannot connect to device: Cannot connect to leaf2"}
fatal: [leaf1]: FAILED! => {"changed": false, "msg": "cannot connect to device: Cannot connect to leaf1"}
fatal: [leaf3]: FAILED! => {"changed": false, "msg": "cannot connect to device: Cannot connect to leaf3"}
fatal: [spine2]: FAILED! => {"changed": false, "msg": "cannot connect to device: Cannot connect to spine2"}
fatal: [spine1]: FAILED! => {"changed": false, "msg": "cannot connect to device: Cannot connect to spine1"}
fatal: [leaf4]: FAILED! => {"changed": false, "msg": "cannot connect to device: Cannot connect to leaf4"}
to retry, use: --limit @/home/florian/ansible/playbooks/get_facts.retry
PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
leaf1 : ok=0 changed=0 unreachable=0 failed=1
leaf2 : ok=0 changed=0 unreachable=0 failed=1
leaf3 : ok=0 changed=0 unreachable=0 failed=1
leaf4 : ok=0 changed=0 unreachable=0 failed=1
spine1 : ok=0 changed=0 unreachable=0 failed=1
spine2 : ok=0 changed=0 unreachable=0 failed=1
Indeed, the module code set the local params to override provider. (
)Is there some mistake in my inventory file ? Or maybe the example have a mistake and should use {{ ansible_host }}
instead ?
Hi,
I just trying napalm-ansible, but the playbook give error No such file or directory: 'initial.conf'
What steps I miss
tq
GOAL:
-change cisco router hostname from R1 to R11
# ansible-playbook playbooks/napalm.yml
PLAY [cisco1] ******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [cisco1]
TASK [create a diff] ***********************************************************
fatal: [cisco1]: FAILED! => {"changed": false, "msg": "cannot load config: [Errno 2] No such file or directory: 'initial.conf'"}
PLAY RECAP *********************************************************************
cisco1 : ok=1 changed=0 unreachable=0 failed=1
# pip freeze | grep napalm
napalm==2.3.2
napalm-ansible==0.10.0
napalm-base==1.0.0
napalm-fortios==0.4.1
napalm-ios==0.8.1
napalm-junos==0.12.1
# cat playbooks/napalm.yml
---
- hosts: cisco1
connection: local
tasks:
- name: "create a diff"
napalm_install_config:
hostname: "{{ansible_host}}"
username: "{{ansible_user}}"
password: "{{ansible_ssh_pass}}"
optional_args: {'secret': '{{ansible_become_pass}}'}
dev_os: "{{ansible_network_os}}"
config_file: initial.conf
commit_changes: false
replace_config: false
diff_file: initial.diff
# cat playbooks/initial.conf
hostname R11
# cat group_vars/cisco.yml
---
ansible_connection: network_cli
ansible_network_os: ios
ansible_user: cisco
ansible_ssh_pass: cisco
ansbile_become: yes
ansible_become_method: enable
ansible_become_pass: cisco
Running a playbook with napalm_get_facts times out. Output with -vvvv doesn't add more value.
Adding "from netmiko import ConnectHandler" bellow https://github.com/napalm-automation/napalm-ansible/blob/master/data_gathering/napalm_get_facts#L90 seems to solve the issue.
Please let me know if I can provide more data to help.
When trying to use the enable optional argument, this is what I get. However, if I go to the switch and set my privilege to 15 I do not get this error and my command is playbook is accepted. Does anybody have insight on to what I may be running into?
fatal: [SW-AS-07]: FAILED! => {"changed": false, "failed": true, "invocation": {"module_args": {"commit_changes": true, "config_file": "test/running.conf", "dev_os": "ios", "diff_file": "test/initial.diff", "get_diffs": true, "hostname": "SW-AS-07", "optional_args": {"secret": "thesecret"}, "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", "replace_config": false, "timeout": 60, "username": "theuser"}, "module_name": "napalm_install_config"}, "msg": "cannot load config: Privilege denied.\n"}
---
- name: Change hostname test
hosts: SW-AS
connection: local
tasks:
- assemble:
src: test/
dest: test/running.conf
- napalm_install_config:
hostname: "{{ inventory_hostname }}"
username: theuser
password: thepassword
optional_args: {'secret': 'thesecret'}
dev_os: ios
config_file: test/running.conf
commit_changes: True
replace_config: False
get_diffs: True
diff_file: test/initial.diff
register: result
- name: Debugging
debug: var=result
running.conf
hostname test
Hi!
I use napalm from the pip repository, the current napalm-ansible development branch from github together with the napalm-aos community driver (development version) with Python 3.
When I run a playbook without serial: 1
I almost randomly (i. e. not for every task) encounter errors like
failed: [myswitchname] (item=/xxx/ansible-networking/configs/myswitchname/020-mst-merge.txt) => {"changed": false, "item": "/xxx/ansible-networking/configs/myswitchname/020-mst-merge.txt", "msg": "cannot load config: [Errno 2] No such file or directory: '/var/folders/1b/zt9ydwjj26l57xlrrn0hgjj80000gn/T/candidate.cfg'"}
as soon as I run several "napalm_install_config" tasks. This particular playbook currently runs for two hosts. If I add serial: 1
to the playbook, everything works as expected. I think that the problem is that "candidate.cfg" is not a unique filename for each host and I believe that the "napalm_install_config" tasks that run in parallel probably delete "candidate.cfg" as soon as they finished while another task might expect to be working on its own "candidate.cfg". I was trying to figure out which part of napalm-ansible actually creates the "candidate.cfg" file. I suspect that it is the driver but I'm not entirely sure -- could you help me out? In any case, an easy fix would be to add some randomness to the name for each creation of the file to make it unique. I hope to be able to help with a fix as soon as I understand where the filename is set.
---
- name: NAPALM on IOS
hosts: pynet-rtr1
tasks:
- name: NAPALM facts
napalm_get_facts:
hostname: "{{ ansible_host }}"
dev_os: "ios"
$ ansible-playbook napalm_w_cli.yml -u pyclass -k
SSH password:
PLAY [NAPALM on IOS] *************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************
ok: [pynet-rtr1]
TASK [NAPALM facts] **************************************************************************************************************************************************************************************************
fatal: [pynet-rtr1]: FAILED! => {"changed": false, "failed": true, "msg": "username is required"}
PLAY RECAP ***********************************************************************************************************************************************************************************************************
pynet-rtr1 : ok=1 changed=0 unreachable=0 failed=1
Also should support if using a provider.
Hi All
Need help with this issue. A similar issues #209 was opened in the past. It is closed but i am not sure whether a fix is available.
Problem: candidate.txt file created for config replace operation with ansible napalm module is considered not valid by c6k ios 12.2(33)SXJ4,
Here are the files created on the router after executing the playbook.
CAT6KLAB05#dir
Directory of sup-bootdisk:/
1 -rw- 143315812 Mar 19 2017 13:05:24 +00:00 s72033-advipservicesk9_wan-mz.122-33.SXJ4.bin
--snip----
10 -rw- 21 Apr 29 2017 14:09:18 +00:00 candidate.txt
5 -rw- 0 Apr 29 2017 14:05:58 +00:00 merge_config.txt
--snip----
17 -rw- 6268 Apr 29 2017 14:09:30 +00:00 rollback_config.txt
--snip----
13 -rw- 6250 Apr 29 2017 05:08:20 +00:00 ArchiveCfg-Apr-29-05-08-20.040-8318
CAT6KLAB05# configure replace sup-bootdisk:candidate.txt
This will apply all necessary additions and deletions
to replace the current running configuration with the
contents of the specified configuration file, which is
assumed to be a complete configuration, not a partial
configuration. Enter Y if you are sure you want to proceed. ? [no]: Y
%The input file is not a valid config file.
Here is my playbook.
name: NAPALM Playbook
hosts: all
connection: local
gather_facts: False
tasks:
Here is my initial.conf. I am trying to config replace with just one cli ( yes with only hostname to see the diff)
$ more initial.conf
hostname TESTMYSCRIPT
Here is the diff generated. And it is as expected.
$ more initial.diff
+hostname TESTMYSCRIPT-service timestamps debug datetime msec
-service timestamps log datetime msec
-no service password-encryption
-service counters max age 5
-hostname CAT6KLAB05
-boot-start-marker
-boot-end-marker
--snip----
Thanks for the help.
Steps to reproduce:
Place the following in requirements.yml:
---
- src: https://github.com/napalm-automation/napalm-ansible/
version: master
name: napalm
path: roles
then run ansible-galaxy install -r requirements.yml --force
Actual results:
[WARNING]: - napalm was NOT installed successfully: this role does not appear to have a meta/main.yml file.
This file used to exist in napalm: it was added in 4b06902
And was removed again in dc34cfc 6 days ago.
Virtual devices on IOS might not have a file system which might fail with this vague message:
fatal: [r2]: FAILED! => {"changed": false, "msg": "cannot load config: 'NoneType' object has no attribute 'group'"}
fatal: [r1]: FAILED! => {"changed": false, "msg": "cannot load config: 'NoneType' object has no attribute 'group'"}
I am having some problem using napalm_get_facts
with filter facts
under specific plataform related Cisco.
The issue was found under Cisco XRV IOS version 6.1.2.
When executed this feature I received a message related below:
fatal: [XRV]: FAILED! => {"changed": false, "msg": "[facts] cannot retrieve device data: list index out of range"}
If you executed another filters identified we can get correct output like interfaces
, arp_table
, interfaces_ip
.
Does the modules provided by napalm-ansible support network_cli connection plugin provided by ansible (recommended in 2.5) ?
This would allow pipelining and avoid providing connection parameters such as "dev_os".
Loading and merging the candidate config works using napalm cli:
Enter password:
2017-10-17 11:53:32,031 - napalm - DEBUG - Starting napalm's debugging tool
2017-10-17 11:53:32,032 - napalm - DEBUG - Gathering napalm packages
2017-10-17 11:53:32,037 - napalm - DEBUG - napalm-base==0.25.0
2017-10-17 11:53:32,037 - napalm - DEBUG - napalm-eos==0.6.1
2017-10-17 11:53:32,037 - napalm - DEBUG - napalm-fortios==0.4.0
2017-10-17 11:53:32,037 - napalm - DEBUG - napalm-ios==0.6.2
2017-10-17 11:53:32,037 - napalm - DEBUG - napalm-iosxr==0.5.5
2017-10-17 11:53:32,037 - napalm - DEBUG - napalm-junos==0.12.0
2017-10-17 11:53:32,037 - napalm - DEBUG - napalm-nxos==0.7.0
2017-10-17 11:53:32,037 - napalm - DEBUG - napalm-panos==0.4.0
2017-10-17 11:53:32,037 - napalm - DEBUG - napalm-pluribus==0.5.1
2017-10-17 11:53:32,037 - napalm - DEBUG - napalm-ros==0.2.2
2017-10-17 11:53:32,037 - napalm - DEBUG - napalm-vyos==0.1.3
2017-10-17 11:53:32,037 - napalm - DEBUG - napalm==1.2.0
2017-10-17 11:53:32,037 - napalm - DEBUG - get_network_driver - Calling with args: ('ios',), {}
2017-10-17 11:53:32,115 - napalm - DEBUG - get_network_driver - Successful
2017-10-17 11:53:32,115 - napalm - DEBUG - __init__ - Calling with args: (<class 'napalm_ios.ios.IOSDriver'>, 'test-2960.domain', 'ansible'), {'password': u'*******', 'optional_args': {}, 'timeout': 60}
2017-10-17 11:53:32,115 - napalm - DEBUG - __init__ - Successful
2017-10-17 11:53:32,115 - napalm - DEBUG - pre_connection_tests - Calling with args: (<napalm_ios.ios.IOSDriver object at 0x24f7810>,), {}
2017-10-17 11:53:32,115 - napalm - DEBUG - open - Calling with args: (<napalm_ios.ios.IOSDriver object at 0x24f7810>,), {}
2017-10-17 11:53:39,137 - napalm - DEBUG - open - Successful
2017-10-17 11:53:39,137 - napalm - DEBUG - connection_tests - Calling with args: (<napalm_ios.ios.IOSDriver object at 0x24f7810>,), {}
2017-10-17 11:53:39,137 - napalm - DEBUG - get_facts - Calling with args: (<napalm_ios.ios.IOSDriver object at 0x24f7810>,), {}
2017-10-17 11:53:40,943 - napalm - DEBUG - Gathered facts:
{
"os_version": "C2960 Software (C2960-LANBASEK9-M), Version 15.0(2)SE11, RELEASE SOFTWARE (fc3)",
"uptime": 960,
"interface_list": [
"Vlan1",
"Vlan3",
"FastEthernet0/1",
"FastEthernet0/2",
"FastEthernet0/3",
"FastEthernet0/4",
"FastEthernet0/5",
"FastEthernet0/6",
"FastEthernet0/7",
"FastEthernet0/8",
"FastEthernet0/9",
"FastEthernet0/10",
"FastEthernet0/11",
"FastEthernet0/12",
"FastEthernet0/13",
"FastEthernet0/14",
"FastEthernet0/15",
"FastEthernet0/16",
"FastEthernet0/17",
"FastEthernet0/18",
"FastEthernet0/19",
"FastEthernet0/20",
"FastEthernet0/21",
"FastEthernet0/22",
"FastEthernet0/23",
"FastEthernet0/24",
"FastEthernet0/25",
"FastEthernet0/26",
"FastEthernet0/27",
"FastEthernet0/28",
"FastEthernet0/29",
"FastEthernet0/30",
"FastEthernet0/31",
"FastEthernet0/32",
"FastEthernet0/33",
"FastEthernet0/34",
"FastEthernet0/35",
"FastEthernet0/36",
"FastEthernet0/37",
"FastEthernet0/38",
"FastEthernet0/39",
"FastEthernet0/40",
"FastEthernet0/41",
"FastEthernet0/42",
"FastEthernet0/43",
"FastEthernet0/44",
"FastEthernet0/45",
"FastEthernet0/46",
"FastEthernet0/47",
"FastEthernet0/48",
"GigabitEthernet0/1",
"GigabitEthernet0/2"
],
"vendor": "Cisco",
"serial_number": "FOC1247X10Z",
"model": "WS-C2960-48TT-L",
"hostname": "test-2960",
"fqdn": "test-2960.domain"
}
{
"os_version": "C2960 Software (C2960-LANBASEK9-M), Version 15.0(2)SE11, RELEASE SOFTWARE (fc3)",
"uptime": 960,
"interface_list": [
"Vlan1",
"Vlan3",
"FastEthernet0/1",
"FastEthernet0/2",
"FastEthernet0/3",
"FastEthernet0/4",
"FastEthernet0/5",
"FastEthernet0/6",
"FastEthernet0/7",
"FastEthernet0/8",
"FastEthernet0/9",
"FastEthernet0/10",
"FastEthernet0/11",
"FastEthernet0/12",
"FastEthernet0/13",
"FastEthernet0/14",
"FastEthernet0/15",
"FastEthernet0/16",
"FastEthernet0/17",
"FastEthernet0/18",
"FastEthernet0/19",
"FastEthernet0/20",
"FastEthernet0/21",
"FastEthernet0/22",
"FastEthernet0/23",
"FastEthernet0/24",
"FastEthernet0/25",
"FastEthernet0/26",
"FastEthernet0/27",
"FastEthernet0/28",
"FastEthernet0/29",
"FastEthernet0/30",
"FastEthernet0/31",
"FastEthernet0/32",
"FastEthernet0/33",
"FastEthernet0/34",
"FastEthernet0/35",
"FastEthernet0/36",
"FastEthernet0/37",
"FastEthernet0/38",
"FastEthernet0/39",
"FastEthernet0/40",
"FastEthernet0/41",
"FastEthernet0/42",
"FastEthernet0/43",
"FastEthernet0/44",
"FastEthernet0/45",
"FastEthernet0/46",
"FastEthernet0/47",
"FastEthernet0/48",
"GigabitEthernet0/1",
"GigabitEthernet0/2"
],
"vendor": "Cisco",
"serial_number": "FOC1247X10Z",
"model": "WS-C2960-48TT-L",
"hostname": "test-2960",
"fqdn": "test-2960.domain"
}
2017-10-17 11:53:40,943 - napalm - DEBUG - get_facts - Successful
2017-10-17 11:53:40,943 - napalm - DEBUG - load_merge_candidate - Calling with args: (<napalm_ios.ios.IOSDriver object at 0x24f7810>,), {'filename': '.compiled/test-2960/candidate_config.conf'}
2017-10-17 11:53:50,624 - napalm - DEBUG - load_merge_candidate - Successful
2017-10-17 11:53:50,625 - napalm - DEBUG - compare_config - Calling with args: (<napalm_ios.ios.IOSDriver object at 0x24f7810>,), {}
2017-10-17 11:53:54,230 - napalm - DEBUG - Gathered diff:
+snmp-server location test
+banner motd ^C[3] test^C
2017-10-17 11:53:54,231 - napalm - DEBUG - compare_config - Successful
2017-10-17 11:53:54,231 - napalm - DEBUG - commit_config - Calling with args: (<napalm_ios.ios.IOSDriver object at 0x24f7810>,), {}
2017-10-17 11:54:17,827 - napalm - DEBUG - commit_config - Successful
2017-10-17 11:54:17,827 - napalm - DEBUG - close - Calling with args: (<napalm_ios.ios.IOSDriver object at 0x24f7810>,), {}
2017-10-17 11:54:17,842 - napalm - DEBUG - close - Successful
2017-10-17 11:54:17,842 - napalm - DEBUG - post_connection_tests - Calling with args: (<napalm_ios.ios.IOSDriver object at 0x24f7810>,), {}
This same operation called in a playbook as follows fails:
Playbook:
---
- name: Check switch config using templates and yaml source config.
hosts: all
connection: local
gather_facts: no
roles:
- access_switch
- cisco-ios-passwords
vars:
host_dir: ".compiled/{{ inventory_hostname_short }}"
commit_changes: False
pre_tasks:
- name: Remove diffs from previous runs
file:
path: "{{ host_dir }}"
state: absent
changed_when: False
check_mode: no
- name: Create folder to store configurations and diffs for/from the devices
file:
path: "{{ host_dir }}"
state: directory
changed_when: False
check_mode: no
tasks:
- name: Create configuration from jinja2 templates
template:
src: "templates/{{ os }}/{{ switch_model }}/global.j2"
dest: "{{ host_dir }}/candidate_config.conf"
backup: yes
changed_when: False
check_mode: no
- name: Load configuration into the device and diff
napalm_install_config:
hostname: "{{ inventory_hostname }}"
username: "{{ user }}"
dev_os: "{{ os }}"
password: "{{ password }}"
config_file: "{{ host_dir }}/candidate_config.conf"
commit_changes: "{{ commit_changes }}"
replace_config: True
get_diffs: True
diff_file: "{{ host_dir }}/diff"
tags: [print_action]
Example running:
(venv)[oli@ansible-d0 ansible]$ ansible-playbook -i hosts-testing --vault-password-file .vault_pass.txt check_switch_config.yml -vv --extra-vars "commit_changes=True"
ansible-playbook 2.4.0.0
config file = /home/oli/git/ansible/ansible.cfg
configured module search path = [u'/home/oli/git/ansible/library', u'/home/oli/git/napalm-ansible/library']
ansible python module location = /home/oli/git/venv/lib/python2.7/site-packages/ansible
executable location = /home/oli/git/venv/bin/ansible-playbook
python version = 2.7.5 (default, Aug 4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]
Using /home/oli/git/ansible/ansible.cfg as config file
PLAYBOOK: check_switch_config.yml ******************************************************************************************************
1 plays in check_switch_config.yml
PLAY [Check switch config using templates and yaml source config.] *********************************************************************
TASK [Remove diffs from previous runs] *************************************************************************************************
task path: /home/oli/git/ansible/check_switch_config.yml:14
ok: [test-2960.domain] => {"changed": false, "failed": false, "path": ".compiled/test-2960", "state": "absent"}
TASK [Create folder to store configurations and diffs for/from the devices] ************************************************************
task path: /home/oli/git/ansible/check_switch_config.yml:20
ok: [test-2960.domain] => {"changed": false, "failed": false, "gid": 4640, "group": "isys", "mode": "0755", "owner": "oli", "path": ".compiled/test-2960", "secontext": "unconfined_u:object_r:user_home_t:s0", "size": 4096, "state": "directory", "uid": 20577}
META: ran handlers
TASK [Create configuration from jinja2 templates] **************************************************************************************
task path: /home/oli/git/ansible/check_switch_config.yml:28
ok: [test-2960.domain] => {"changed": false, "checksum": "f5d67562daf3c2732611d6a7048194afc365ca9e", "dest": ".compiled/test-2960/candidate_config.conf", "failed": false, "gid": 4640, "group": "isys", "md5sum": "c5f72646e9c1fe6afb34353e6141aa8e", "mode": "0644", "owner": "oli", "secontext": "unconfined_u:object_r:user_home_t:s0", "size": 18345, "src": "/home/oli/.ansible/tmp/ansible-tmp-1508237886.24-90961176918724/source", "state": "file", "uid": 20577}
TASK [Load configuration into the device and diff] *************************************************************************************
task path: /home/oli/git/ansible/check_switch_config.yml:35
changed: [test-2960.domain] => {"changed": true, "failed": false, "msg": "-vstack"}
TASK [Print options] *******************************************************************************************************************
task path: /home/oli/git/ansible/check_switch_config.yml:47
ok: [test-2960.domain] => {
"msg": "Commit Changes True"
}
META: ran handlers
META: ran handlers
PLAY RECAP *****************************************************************************************************************************
test-2960.domain : ok=5 changed=1 unreachable=0 failed=0
(venv)[oli@ansible-d0 ansible]$ ansible-playbook -i hosts-testing --vault-password-file .vault_pass.txt check_switch_config.yml -vvvv --extra-vars "commit_changes=True"
ansible-playbook 2.4.0.0
config file = /home/oli/git/ansible/ansible.cfg
configured module search path = [u'/home/oli/git/ansible/library', u'/home/oli/git/napalm-ansible/library']
ansible python module location = /home/oli/git/venv/lib/python2.7/site-packages/ansible
executable location = /home/oli/git/venv/bin/ansible-playbook
python version = 2.7.5 (default, Aug 4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]
Using /home/oli/git/ansible/ansible.cfg as config file
setting up inventory plugins
Parsed /home/oli/git/ansible/hosts-testing inventory source with ini plugin
Trying secret FileVaultSecret(filename='/home/oli/git/ansible/.vault_pass.txt') for vault_id=default
Loading callback plugin default of type stdout, v2.0 from /home/oli/git/venv/lib/python2.7/site-packages/ansible/plugins/callback/__init__.pyc
PLAYBOOK: check_switch_config.yml ******************************************************************************************************
1 plays in check_switch_config.yml
PLAY [Check switch config using templates and yaml source config.] *********************************************************************
TASK [Remove diffs from previous runs] *************************************************************************************************
task path: /home/oli/git/ansible/check_switch_config.yml:14
Using module file /home/oli/git/venv/lib/python2.7/site-packages/ansible/modules/files/file.py
<test-2960.domain> ESTABLISH LOCAL CONNECTION FOR USER: oli
<test-2960.domain> EXEC /bin/sh -c 'echo ~ && sleep 0'
<test-2960.domain> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/oli/.ansible/tmp/ansible-tmp-1508237947.07-281025839920352 `" && echo ansible-tmp-1508237947.07-281025839920352="` echo /home/oli/.ansible/tmp/ansible-tmp-1508237947.07-281025839920352 `" ) && sleep 0'
<test-2960.domain> PUT /tmp/tmpyMNq_R TO /home/oli/.ansible/tmp/ansible-tmp-1508237947.07-281025839920352/file.py
<test-2960.domain> EXEC /bin/sh -c 'chmod u+x /home/oli/.ansible/tmp/ansible-tmp-1508237947.07-281025839920352/ /home/oli/.ansible/tmp/ansible-tmp-1508237947.07-281025839920352/file.py && sleep 0'
<test-2960.domain> EXEC /bin/sh -c '../venv/bin/python /home/oli/.ansible/tmp/ansible-tmp-1508237947.07-281025839920352/file.py; rm -rf "/home/oli/.ansible/tmp/ansible-tmp-1508237947.07-281025839920352/" > /dev/null 2>&1 && sleep 0'
ok: [test-2960.domain] => {
"changed": false,
"diff": {
"after": {
"path": ".compiled/test-2960",
"state": "absent"
},
"before": {
"path": ".compiled/test-2960",
"state": "directory"
}
},
"failed": false,
"invocation": {
"module_args": {
"attributes": null,
"backup": null,
"content": null,
"delimiter": null,
"diff_peek": null,
"directory_mode": null,
"follow": false,
"force": false,
"group": null,
"mode": null,
"original_basename": null,
"owner": null,
"path": ".compiled/test-2960",
"recurse": false,
"regexp": null,
"remote_src": null,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": null,
"state": "absent",
"unsafe_writes": null,
"validate": null
}
},
"path": ".compiled/test-2960",
"state": "absent"
}
TASK [Create folder to store configurations and diffs for/from the devices] ************************************************************
task path: /home/oli/git/ansible/check_switch_config.yml:20
Using module file /home/oli/git/venv/lib/python2.7/site-packages/ansible/modules/files/file.py
<test-2960.domain> ESTABLISH LOCAL CONNECTION FOR USER: oli
<test-2960.domain> EXEC /bin/sh -c 'echo ~ && sleep 0'
<test-2960.domain> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/oli/.ansible/tmp/ansible-tmp-1508237947.21-9039621643107 `" && echo ansible-tmp-1508237947.21-9039621643107="` echo /home/oli/.ansible/tmp/ansible-tmp-1508237947.21-9039621643107 `" ) && sleep 0'
<test-2960.domain> PUT /tmp/tmpPP9xkq TO /home/oli/.ansible/tmp/ansible-tmp-1508237947.21-9039621643107/file.py
<test-2960.domain> EXEC /bin/sh -c 'chmod u+x /home/oli/.ansible/tmp/ansible-tmp-1508237947.21-9039621643107/ /home/oli/.ansible/tmp/ansible-tmp-1508237947.21-9039621643107/file.py && sleep 0'
<test-2960.domain> EXEC /bin/sh -c '../venv/bin/python /home/oli/.ansible/tmp/ansible-tmp-1508237947.21-9039621643107/file.py; rm -rf "/home/oli/.ansible/tmp/ansible-tmp-1508237947.21-9039621643107/" > /dev/null 2>&1 && sleep 0'
ok: [test-2960.domain] => {
"changed": false,
"diff": {
"after": {
"path": ".compiled/test-2960",
"state": "directory"
},
"before": {
"path": ".compiled/test-2960",
"state": "absent"
}
},
"failed": false,
"gid": 4640,
"group": "isys",
"invocation": {
"module_args": {
"attributes": null,
"backup": null,
"content": null,
"delimiter": null,
"diff_peek": null,
"directory_mode": null,
"follow": false,
"force": false,
"group": null,
"mode": null,
"original_basename": null,
"owner": null,
"path": ".compiled/test-2960",
"recurse": false,
"regexp": null,
"remote_src": null,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": null,
"state": "directory",
"unsafe_writes": null,
"validate": null
}
},
"mode": "0755",
"owner": "oli",
"path": ".compiled/test-2960",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 4096,
"state": "directory",
"uid": 20577
}
META: ran handlers
TASK [Create configuration from jinja2 templates] **************************************************************************************
task path: /home/oli/git/ansible/check_switch_config.yml:28
<test-2960.domain> ESTABLISH LOCAL CONNECTION FOR USER: oli
<test-2960.domain> EXEC /bin/sh -c 'echo ~ && sleep 0'
<test-2960.domain> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/oli/.ansible/tmp/ansible-tmp-1508237947.4-265171165173405 `" && echo ansible-tmp-1508237947.4-265171165173405="` echo /home/oli/.ansible/tmp/ansible-tmp-1508237947.4-265171165173405 `" ) && sleep 0'
Using module file /home/oli/git/venv/lib/python2.7/site-packages/ansible/modules/files/stat.py
<test-2960.domain> PUT /tmp/tmpRIj53I TO /home/oli/.ansible/tmp/ansible-tmp-1508237947.4-265171165173405/stat.py
<test-2960.domain> EXEC /bin/sh -c 'chmod u+x /home/oli/.ansible/tmp/ansible-tmp-1508237947.4-265171165173405/ /home/oli/.ansible/tmp/ansible-tmp-1508237947.4-265171165173405/stat.py && sleep 0'
<test-2960.domain> EXEC /bin/sh -c '../venv/bin/python /home/oli/.ansible/tmp/ansible-tmp-1508237947.4-265171165173405/stat.py && sleep 0'
<test-2960.domain> PUT /tmp/tmp84AWcf/global.j2 TO /home/oli/.ansible/tmp/ansible-tmp-1508237947.4-265171165173405/source
<test-2960.domain> EXEC /bin/sh -c 'chmod u+x /home/oli/.ansible/tmp/ansible-tmp-1508237947.4-265171165173405/ /home/oli/.ansible/tmp/ansible-tmp-1508237947.4-265171165173405/source && sleep 0'
Using module file /home/oli/git/venv/lib/python2.7/site-packages/ansible/modules/files/copy.py
<test-2960.domain> PUT /tmp/tmp4jxjGR TO /home/oli/.ansible/tmp/ansible-tmp-1508237947.4-265171165173405/copy.py
<test-2960.domain> EXEC /bin/sh -c 'chmod u+x /home/oli/.ansible/tmp/ansible-tmp-1508237947.4-265171165173405/ /home/oli/.ansible/tmp/ansible-tmp-1508237947.4-265171165173405/copy.py && sleep 0'
<test-2960.domain> EXEC /bin/sh -c '../venv/bin/python /home/oli/.ansible/tmp/ansible-tmp-1508237947.4-265171165173405/copy.py; rm -rf "/home/oli/.ansible/tmp/ansible-tmp-1508237947.4-265171165173405/" > /dev/null 2>&1 && sleep 0'
ok: [test-2960.domain] => {
"changed": false,
"checksum": "f5d67562daf3c2732611d6a7048194afc365ca9e",
"dest": ".compiled/test-2960/candidate_config.conf",
"diff": [],
"failed": false,
"gid": 4640,
"group": "isys",
"invocation": {
"module_args": {
"attributes": null,
"backup": true,
"content": null,
"delimiter": null,
"dest": ".compiled/test-2960/candidate_config.conf",
"directory_mode": null,
"follow": false,
"force": true,
"group": null,
"local_follow": null,
"mode": null,
"original_basename": "global.j2",
"owner": null,
"regexp": null,
"remote_src": null,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": "/home/oli/.ansible/tmp/ansible-tmp-1508237947.4-265171165173405/source",
"unsafe_writes": null,
"validate": null
}
},
"md5sum": "c5f72646e9c1fe6afb34353e6141aa8e",
"mode": "0644",
"owner": "oli",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 18345,
"src": "/home/oli/.ansible/tmp/ansible-tmp-1508237947.4-265171165173405/source",
"state": "file",
"uid": 20577
}
TASK [Load configuration into the device and diff] *************************************************************************************
task path: /home/oli/git/ansible/check_switch_config.yml:35
Using module file /home/oli/git/napalm-ansible/napalm_ansible/napalm_install_config.py
<test-2960.domain> ESTABLISH LOCAL CONNECTION FOR USER: oli
<test-2960.domain> EXEC /bin/sh -c 'echo ~ && sleep 0'
<test-2960.domain> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/oli/.ansible/tmp/ansible-tmp-1508237948.03-127512870432814 `" && echo ansible-tmp-1508237948.03-127512870432814="` echo /home/oli/.ansible/tmp/ansible-tmp-1508237948.03-127512870432814 `" ) && sleep 0'
<test-2960.domain> PUT /tmp/tmpSj225O TO /home/oli/.ansible/tmp/ansible-tmp-1508237948.03-127512870432814/napalm_install_config.py
<test-2960.domain> EXEC /bin/sh -c 'chmod u+x /home/oli/.ansible/tmp/ansible-tmp-1508237948.03-127512870432814/ /home/oli/.ansible/tmp/ansible-tmp-1508237948.03-127512870432814/napalm_install_config.py && sleep 0'
<test-2960.domain> EXEC /bin/sh -c '../venv/bin/python /home/oli/.ansible/tmp/ansible-tmp-1508237948.03-127512870432814/napalm_install_config.py; rm -rf "/home/oli/.ansible/tmp/ansible-tmp-1508237948.03-127512870432814/" > /dev/null 2>&1 && sleep 0'
changed: [test-2960.domain] => {
"changed": true,
"failed": false,
"invocation": {
"module_args": {
"archive_file": null,
"commit_changes": true,
"config": null,
"config_file": ".compiled/test-2960/candidate_config.conf",
"dev_os": "ios",
"diff_file": ".compiled/test-2960/diff",
"get_diffs": true,
"hostname": "test-2960.domain",
"optional_args": null,
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"provider": null,
"replace_config": true,
"timeout": 60,
"username": "ansible"
}
},
"msg": "+snmp-server location test\n+banner motd ^C[3] test^C\n-snmp-server location Commsdev\n-vstack\n-banner motd ^C[3] Commsdev^C"
}
TASK [Print options] *******************************************************************************************************************
task path: /home/oli/git/ansible/check_switch_config.yml:47
ok: [test-2960.domain] => {
"msg": "Commit Changes True"
}
META: ran handlers
META: ran handlers
PLAY RECAP *****************************************************************************************************************************
test-2960.domain : ok=5 changed=1 unreachable=0 failed=0
Switch logs during the playbook run:
Oct 17 11:58:31 BST: %SYS-5-CONFIG_I: Configured from console by ansible on vty0 (1.2.3.4)
Oct 17 11:59:25 BST: %SYS-5-CONFIG_I: Configured from console by ansible on vty0 (1.2.3.4)
Oct 17 11:59:32 BST: %SYS-5-CONFIG_I: Configured from console by ansible on vty0 (1.2.3.4)
Files on switch after this run match the files generated by the ansible tasks.
ansible==2.4.0.0
ansible-lint==3.4.15
asn1crypto==0.23.0
backports.ssl-match-hostname==3.5.0.1
bcrypt==3.1.4
bigsuds==1.0.4
certifi==2017.7.27.1
cffi==1.11.2
chainmap==1.0.2
chardet==3.0.4
ciscoconfparse==1.2.47
colorama==0.3.9
cryptography==2.0.3
dnspython==1.15.0
docker-py==1.10.6
docker-pycreds==0.2.1
enum34==1.1.6
future==0.16.0
idna==2.6
ipaddr==2.2.0
ipaddress==1.0.18
Jinja2==2.9.6
jmespath==0.9.2
jtextfsm==0.3.1
junos-eznc==2.1.7
librouteros==1.0.4
lxml==4.1.0
MarkupSafe==1.0
napalm==1.2.0
napalm-base==0.25.0
napalm-eos==0.6.1
napalm-fortios==0.4.0
napalm-ios==0.6.2
napalm-iosxr==0.5.5
napalm-junos==0.12.0
napalm-nxos==0.7.0
napalm-panos==0.4.0
napalm-pluribus==0.5.1
napalm-ros==0.2.2
napalm-vyos==0.1.3
ncclient==0.5.3
netaddr==0.7.19
netmiko==1.4.3
pan-python==0.12.0
paramiko==2.3.1
pathspec==0.5.5
pyasn1==0.3.7
pycparser==2.18
pycrypto==2.6.1
pyeapi==0.8.1
pyfg==0.50
pyIOSXR==0.52
PyNaCl==1.1.2
pynxos==0.0.3
pyPluribus==0.3.1
pyserial==3.4
PyYAML==3.12
requests==2.18.4
requests-toolbelt==0.8.0
scp==0.10.2
six==1.11.0
suds==0.4
urllib3==1.22
VyattaConfParser==0.5.1
websocket-client==0.44.0
xmltodict==0.11.0
yamllint==1.8.1
After upgrading to the new napalm-ansible 0.9.0. Any play I run for ios fails with the below. EOS and NXOS are fine. It was installed via the setup command sudo python ./setup.py install
FAILED! => {"changed": false, "failed": true, "msg": "cannot connect to device: Cannot import "napalm_ios". Is the library installed?"}
sudo pip freeze | grep napalm
napalm==2.3.0
napalm-ansible==0.9.0
napalm-base==0.25.0
napalm-eos==0.5.2
napalm-fortios==0.3.1
napalm-ibm==0.1.6
napalm-ios==0.8.1
napalm-iosxr==0.4.6
napalm-junos==0.6.2
napalm-nxos==0.7.0
napalm-panos==0.3.0
napalm-pluribus==0.5.0
napalm-ros==0.2.0
napalm-vyos==0.1.2
napalm-yang==0.0.7
jvill@mgt1:~/ansible> python -c "from napalm.ios import IOSDriver"
Traceback (most recent call last):
File "", line 1, in
File "/opt/ixea/lib/python2.7/site-packages/napalm/ios/init.py", line 16, in
from napalm.ios.ios import IOSDriver
File "/opt/ixea/lib/python2.7/site-packages/napalm/ios/ios.py", line 28, in
from netmiko import ConnectHandler, FileTransfer, InLineTransfer
File "/opt/ixea/lib/python2.7/site-packages/netmiko/init.py", line 8, in
from netmiko.ssh_dispatcher import ConnectHandler
File "/opt/ixea/lib/python2.7/site-packages/netmiko/ssh_dispatcher.py", line 4, in
from netmiko.a10 import A10SSH
File "/opt/ixea/lib/python2.7/site-packages/netmiko/a10/init.py", line 2, in
from netmiko.a10.a10_ssh import A10SSH
File "/opt/ixea/lib/python2.7/site-packages/netmiko/a10/a10_ssh.py", line 4, in
from netmiko.cisco_base_connection import CiscoSSHConnection
File "/opt/ixea/lib/python2.7/site-packages/netmiko/cisco_base_connection.py", line 3, in
from netmiko.base_connection import BaseConnection
File "/opt/ixea/lib/python2.7/site-packages/netmiko/base_connection.py", line 24, in
from netmiko.utilities import write_bytes, check_serial_port, get_structured_data
File "/opt/ixea/lib/python2.7/site-packages/netmiko/utilities.py", line 8, in
import serial.tools.list_ports
napalm.get_network_driver('ios')
Traceback (most recent call last):
File "", line 1, in
File "/opt/jons/lib/python2.7/site-packages/napalm/base/init.py", line 95, in get_network_driver
install_name=module_install_name
napalm.base.exceptions.ModuleImportError: Cannot import "napalm.ios". Is the library installed?
From #94:
Allow nxos_ssh to be used
Is there a reason not to rely on napalm get_network_driver and getter exceptions to filter which driver can or can't be used ?
It seems cumbersome to track the drivers for any addition in the implementation when their is already something we can accurately rely on to do so.
I quickly checked and didn't see one.
The module napalm_get_facts currently set the result in ansible variables that are have quite generic name (for instance interfaces). I run into an issue where I wished to retrieve the list of interfaces on an equipements and that erased the content of my inventory variable interfaces. I had to rework all my inventory in order to avoid collision of the variables names.
In the network core modules, the facts gethered by the differents *_facts put the results in a variable called ansible_net_*. I'd like to know if this behavour would be accepted in napalm ?
Either by putting all the variables in a dictionnary napalm_facts: {interfaces: []}
or by prepending napalm_ to all the variables names.
In order not to break compatibility with the current names, it could also be implements with a new argument to the module namespace
.
without ansible_python_interpreter
set napalm module cannot be found. all other ansible modules work when a python virtualenv is activate
.
python complains that module napalm cannot be found without the ansible_python_interpreter knob set.
It's good we are catching errors to fail with the fail_json
method but we shouldn't hide the errors as it frustrates uses. We should do something like:
try:
whatever
except Exception as e:
module.fail_json(e.msg)
Example output:
ansible_facts:
interfaces:
GigabitEthernet0/0:
description: '>ACC Ethernet AT&T ********M EDBK6CHS0009< [********000:********000]'
is_enabled: true
is_up: true
last_flapped: -1.0
mac_address: 24:E9:B3:2E:36:E1
speed: 100
changed: false
not_implemented: []
Should read:
description: '>ACC Ethernet AT&T 30M EDBK6CHS0009< [30000:30000]'
Versions in use:
ansible 2.3.1.0
napalm (1.2.0)
napalm-base (0.24.1)
napalm-eos (0.6.0)
napalm-fortios (0.4.0)
napalm-ios (0.7.0)
napalm-iosxr (0.5.1)
napalm-junos (0.10.3)
napalm-nxos (0.5.3)
napalm-panos (0.4.0)
napalm-pluribus (0.5.1)
napalm-ros (0.2.2)
napalm-vyos (0.1.3)
netmiko (1.4.1)
Like secret...
Or possibly might want to support passing secret in the provider.
Hi all,
Im working with Napalm with python and Im executing the following lines. This is a Cisco-xe. (ref link http://networktocode.com/labs/tutorials/how-to-use-napalm-python-library-to-manage-ios-devices/)
from napalm import get_network_driver
driver = get_network_driver('ios')
device = driver('csr1', 'ntc', 'ntc123')
device.open()
device.load_replace_candidate(filename='newconfig.cfg')
device.commit_config()
After I commit I get the following error
device.commit_config()
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python2.7/dist-packages/napalm/ios/ios.py", line 447, in commit_config
raise ReplaceConfigException(msg)
napalm.base.exceptions.ReplaceConfigException: Candidate config could not be applied
Failed to apply command Last configuration change at 13:41:24 UTC Thu Jan 18 2018
Aborting Rollback.
Rollback failed.Reverting back to the original configuration: bootflash:archive-Jan-18-17-54-15.366-0 ...
Total number of passes: 1
Rollback Done
The original configuration has been successfully restored.
Thanks.
when using ios for ansible, encounter below issue -
fatal: [router1]: FAILED! => {"changed": false, "failed": true, "msg": "cannot connect to device: An error occurred in dynamically determining remote file system: dir router1#\nrouter1#\nrouter1#"}
my user is priviledge 15 (tacacs), not sure why this happens
Python 2.7.12+ (default, Sep 17 2016, 12:08:02)
[GCC 6.2.0 20160914] on linux2
Type "help", "copyright", "credits" or "license" for more information.
import napalm_base
import napalm_ios
napalm_ios.version
'0.6.2'
netmiko.version
u'1.4.0'
my playbook
name: Test Inventory #The Task Name
hosts: router1 #This will be in your ansible inventory file
connection: local #Required
gather_facts: no
tasks: #Begin Tasks
name: get facts from device #Task Name
napalm_get_facts: #Call the napalm module, in this case napal_get_facts
hostname: "{{ hostname }}" #This is a parameter and is derived from your ansible inventory file
username: 'user1' #The username to ssh with
dev_os: 'ios' #The hardware operating system
password: 'pass1' #The line level password
optional_args: {'secret': 'pass2'}
filter: 'interfaces, bgp_neighbors' #The list of items you want to retrieve. The filter keyword is inclusive of what you want
register: result #Ansible function for collecting output
name: print results #Task Name
debug: msg= "{{ result }}" #Display the collected output
actually my user is already pri 15 so I don't think secret is needed.
same playbook work for junos.
I am using napalm-ansible to install configuration on various equipment and I am getting an error on a specific Nexus7k host.
Everything works fine on my other three Nexus (and on other types of equipment and on all equipment in my dev environment), so this should not be a problem with the way I use the module.
Here is the part in my playbook where I use the napalm_install_config module:
---
- name: "{{ equipment_family }} - Install the configuration using the napalm-ansible library"
napalm_install_config:
hostname: "{{ ansible_ssh_host }}"
username: "{{ smi_username }}"
password: "{{ smi_password }}"
dev_os: "{{ napalm_install_config_dev_os }}"
config_file: "{{ master_config_file }}"
commit_changes: "{{ not ansible_check_mode }}"
replace_config: False
get_diffs: True
diff_file: "{{ diff_file }}"
timeout: "{{ napalm_install_config_timeout }}"
any_errors_fatal: true
And here is the verbose output I get when this part runs on the problematic host:
The full traceback is:
File "/tmp/ansible_gJc7b8/ansible_module_napalm_install_config.py", line 311, in main
device.commit_config()
File "/usr/lib/python2.7/site-packages/napalm/nxos/nxos.py", line 54, in commit_config
self._save_to_checkpoint(self.backup_file)
File "/usr/lib/python2.7/site-packages/napalm/nxos_ssh/nxos_ssh.py", line 645, in _save_to_checkpoint
self.device.send_command(command)
File "/usr/lib/python2.7/site-packages/netmiko/base_connection.py", line 1112, in send_command
search_pattern))
fatal: [QCDRVLS202]: FAILED! => {
"changed": false,
"invocation": {
"module_args": {
"archive_file": null,
"candidate_file": null,
"commit_changes": true,
"config": null,
"config_file": "/var/lib/awx/projects/_79__customer_provisioning_v72/playbooks/../files/configs/2018-08-24_11:35:30/QCDRVLS202/___master.conf",
"dev_os": "nxos_ssh",
"diff_file": "/var/lib/awx/projects/_79__customer_provisioning_v72/playbooks/../files/diffs/2018-08-24_11:35:30/QCDRVLS202.diff",
"get_diffs": true,
"hostname": "10.199.254.47",
"optional_args": null,
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"provider": {
"hostname": "10.199.254.47",
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"timeout": 60,
"username": "removed"
},
"replace_config": false,
"timeout": 60,
"username": "removed"
}
},
"msg": "cannot install config: Search pattern never detected in send_command_expect: QCDRVLS202\\#"
}
As I said, it always happens on the QCDRVLS202 Nexus even though the configuration that I send to this host is the same as the one I send to other hosts.
This error doesn't happen in check_mode. From what I gathered while searching on Google, this might be due to the fact that this specific host might be slower to respond than the three other similar hosts, which makes the prompt "time-out" while waiting for the "QCMTRLS202#" text on the command line, but I can't seem to find a way to make it wait longer.
If you require additional information, I will be glad to provide it as it is very important to me to solve this issue .
Thank you!
See details in the parent issue napalm-automation/napalm-base#65
Hi all, thanks for this awesome piece of code. I'm trying to figure out how to use napalm_parse_yang module within napalm-ansible. napalm_get_facts is working well showing that connectivity is OK with inventory_hosts.
I took your example and change dev_os and profile to "junos" value.
However when running the playbook I have this error:
fatal: [gn4-net-core-1]: FAILED! => {"changed": false, "module_stderr": "No handlers could be found for logger \"napalm-yang\"
Traceback (most recent call last):
File \"/tmp/ansible_OGsNB8/ansible_module_napalm_parse_yang.py\", line 297, in <module>
main()
File \"/tmp/ansible_OGsNB8/ansible_module_napalm_parse_yang.py\", line 291, in main
yang_model = parse_from_device(module, os_choices)
File \"/tmp/ansible_OGsNB8/ansible_module_napalm_parse_yang.py\", line 247, in parse_from_device
root.parse_config(device=device, profile=profiles or device.profile)
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/base.py\", line 225, in parse_config
parser.parse()
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/parser.py\", line 85, in parse
self._parse(self._yang_name, self.model, self.mapping[self._yang_name])
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/parser.py\", line 91, in _parse
self._parse_container(attribute, model, mapping)
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/parser.py\", line 132, in _parse_container
self._parse(k, v, mapping[v._yang_name])
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/parser.py\", line 93, in _parse
self._parse_list(attribute, model, mapping)
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/parser.py\", line 178, in _parse_list
self._parse(key, obj, element_mapping)
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/parser.py\", line 91, in _parse
self._parse_container(attribute, model, mapping)
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/parser.py\", line 132, in _parse_container
self._parse(k, v, mapping[v._yang_name])
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/parser.py\", line 91, in _parse
self._parse_container(attribute, model, mapping)
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/parser.py\", line 132, in _parse_container
self._parse(k, v, mapping[v._yang_name])
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/parser.py\", line 93, in _parse
self._parse_list(attribute, model, mapping)
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/parser.py\", line 178, in _parse_list
self._parse(key, obj, element_mapping)
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/parser.py\", line 91, in _parse
self._parse_container(attribute, model, mapping)
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/parser.py\", line 130, in _parse_container
parser.parse()
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/parser.py\", line 85, in parse
self._parse(self._yang_name, self.model, self.mapping[self._yang_name])
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/parser.py\", line 91, in _parse
self._parse_container(attribute, model, mapping)
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/parser.py\", line 132, in _parse_container
self._parse(k, v, mapping[v._yang_name])
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/parser.py\", line 91, in _parse
self._parse_container(attribute, model, mapping)
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/parser.py\", line 132, in _parse_container
self._parse(k, v, mapping[v._yang_name])
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/parser.py\", line 95, in _parse
self._parse_leaf(attribute, model, mapping)
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/parser.py\", line 199, in _parse_leaf
setter(value)
File \"/usr/local/lib/python2.7/dist-packages/napalm_yang/models/openconfig/interfaces/interface/subinterfaces/subinterface/vlan/config/__init__.py\", line 90, in _set_vlan_id
'generated-type': \"\"\"YANGDynClass(base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={'range': ['0..65535']},int_size=16), restriction_dict={'range': [u'1..4094']}),RestrictedClassType(base_type=unicode, restriction_dict={'pattern': u'(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9])\\\\.((409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9])|\\\\*)'}),], is_leaf=True, yang_name=\"vlan-id\", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://openconfig.net/yang/vlan', defining_module='openconfig-vlan', yang_type='union', is_config=True)\"\"\",
ValueError: {'error-string': 'vlan_id must be of a type compatible with union', 'generated-type': 'YANGDynClass(base=[RestrictedClassType(base_type=RestrictedClassType(base_type=int, restriction_dict={\\'range\\': [\\'0..65535\\']},int_size=16), restriction_dict={\\'range\\': [u\\'1..4094\\']}),RestrictedClassType(base_type=unicode, restriction_dict={\\'pattern\\': u\\'(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9])\\\\.((409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9])|\\\\*)\\'}),], is_leaf=True, yang_name=\"vlan-id\", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace=\\'http://openconfig.net/yang/vlan\\', defining_module=\\'openconfig-vlan\\', yang_type=\\'union\\', is_config=True)', 'defined-type': 'openconfig-vlan:union'}
", "module_stdout": "", "msg": "MODULE FAILURE", "rc": 0}
My playbook:
- name: Test napalm-parse-yang
hosts: gn4-net-core
connection: local
gather_facts: no
tasks:
- name: get facts from device
napalm_get_facts:
hostname: "{{ inventory_hostname }}"
username: "{{ user }}"
dev_os: "{{ os }}"
password: "{{ passwd }}"
filter: ['facts']
register: result
- name: print results
debug: msg="{{ result }}"
- name: Parse from device
napalm_parse_yang:
hostname: "{{ inventory_hostname }}"
username: "{{ user }}"
dev_os: "{{ os }}"
password: "{{ passwd }}"
mode: "config"
profiles: ['junos']
models:
- models.openconfig_interfaces
register: running
- name: print running
debug: msg="{{ running }}" #Display the collected output
Anything I migh miss or misunderstood ?
The router is a vMX with basic PE config. (ISIS, BGP, MPLS activated) I can provide it if needed with interface and subinterface.
Any hints/Tips & tricks would be appreciated... :-)
Thanks for your help !
task:
- name: Push configuration with napalm
napalm_install_config:
hostname: "{{ inventory_hostname }}"
dev_os: ios
username: "{{ cisco_admins.0.username }}"
password: "{{ cisco_admins.0.password }}"
config_file: cisco-configs/{{ inventory_hostname }}/running-config
commit_changes: False
replace_config: False
diff_file: cisco-config/{{ inventory_hostname }}/diff
ouput:
TASK: [cisco-ios | Push configuration with napalm] ****************************
failed: [gw01ram1rls.ram1.rls.io] => {"failed": true, "parsed": false}
SSH connection established to gw01ram1rls.ram1.rls.io:22
Interactive SSH session established
+ service timestamps debug datetime msec
...
+ end
Traceback (most recent call last):
File "/home/t/.ansible/tmp/ansible-tmp-1454334065.32-270842437256163/napalm_install_config", line 1792, in <module>
main()
File "/home/t/.ansible/tmp/ansible-tmp-1454334065.32-270842437256163/napalm_install_config", line 163, in main
diff = device.compare_config().encode('utf-8')
AttributeError: 'NoneType' object has no attribute 'encode'
FATAL: all hosts have already failed -- aborting
Add to unit tests.
This was testing Ansible 2.4.0 'devel' branch as of August29.
The full traceback is:
Traceback (most recent call last):
File "/home/kbyers/VENV/ansible_test3/lib/python3.5/site-packages/ansible-2.4.0-py3.5.egg/ansible/executor/task_executor.py", line 125, in run
res = self._execute()
File "/home/kbyers/VENV/ansible_test3/lib/python3.5/site-packages/ansible-2.4.0-py3.5.egg/ansible/executor/task_executor.py", line 526, in _execute
result = self._handler.run(task_vars=variables)
File "/home/kbyers/VENV/ansible_test3/lib/python3.5/site-packages/ansible-2.4.0-py3.5.egg/ansible/plugins/action/normal.py", line 45, in run
results = merge_hash(results, self._execute_module(tmp=tmp, task_vars=task_vars, wrap_async=wrap_async))
File "/home/kbyers/VENV/ansible_test3/lib/python3.5/site-packages/ansible-2.4.0-py3.5.egg/ansible/plugins/action/__init__.py", line 630, 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/kbyers/VENV/ansible_test3/lib/python3.5/site-packages/ansible-2.4.0-py3.5.egg/ansible/plugins/action/__init__.py", line 165, in _configure_module
environment=final_environment)
File "/home/kbyers/VENV/ansible_test3/lib/python3.5/site-packages/ansible-2.4.0-py3.5.egg/ansible/executor/module_common.py", line 869, in modify_module
environment=environment)
File "/home/kbyers/VENV/ansible_test3/lib/python3.5/site-packages/ansible-2.4.0-py3.5.egg/ansible/executor/module_common.py", line 695, in _find_module_utils
recursive_finder(module_name, b_module_data, py_module_names, py_module_cache, zf)
File "/home/kbyers/VENV/ansible_test3/lib/python3.5/site-packages/ansible-2.4.0-py3.5.egg/ansible/executor/module_common.py", line 466, in recursive_finder
tree = ast.parse(data)
File "/usr/lib64/python3.5/ast.py", line 35, in parse
return compile(source, filename, mode, PyCF_ONLY_AST)
File "<unknown>", line 259
except Exception, e:
The plugin system of ansible is terrible, that's why ansible itself doesn't use it and their modules are basically intertwined in the codebase. The reason I am saying this is because it encourages duplicating a lot of code. For this reason, I was wondering if we should move as much code as possible to napalm
itself so we don't have to repeat the same code over and over.
@ktbyers thoughts?
David already knows what the bug is, this is just a reminder he asked for ;)
Workaround: pass args: {}
The full traceback is:
Traceback (most recent call last):
File "/tmp/ansible_bEwtxf/ansible_module_napalm_get_facts.py", line 263, in <module>
main()
File "/tmp/ansible_bEwtxf/ansible_module_napalm_get_facts.py", line 234, in main
result = get_func(**args.get(getter, {}))
AttributeError: 'NoneType' object has no attribute 'get'
fatal: [E1]: FAILED! => {
"changed": false,
"failed": true,
"module_stderr": "Traceback (most recent call last):\n File \"/tmp/ansible_bEwtxf/ansible_module_napalm_get_facts.py\", line 263, in <module>\n main()\n File \"/tmp/ansible_bEwtxf/ansible_module_napalm_get_facts.py\", line 234, in main\n result = get_func(**args.get(getter, {}))\nAttributeError: 'NoneType' object has no attribute 'get'\n",
"module_stdout": "",
"msg": "MODULE FAILURE",
"rc": 0
}
Hi team,
OSX=10.12.5
python=2.7.13
ansible=2.3.1.0
napalm=1.2.0.0
napalm-eos=0.5.6
I'm trying to run a basic playbook :
- hosts: pod1
connection: local
gather_facts: no
tasks:
- name: BUILD
template:
src=templates/bgp.j2
dest=configs/{{ inventory_hostname }}.conf
tags: build
- name: PUSH
napalm_install_config:
hostname={{ inventory_hostname }}
username=ccompain
password=arista
dev_os=eos
config_file=configs/{{ inventory_hostname }}.conf
commit_changes=true
replace_config=false
get_diffs=false
tags: push
The directory where I'm executing the code is :
~/vEOS/ansible/test4$ ls -aF
./ configure_eos.retry host_vars/ misc/
../ configure_eos.yaml hosts templates/
configs/ group_vars/ library/
I've put the ansible-napalm (get from github) library in library/
directory.
But it doesn't work when I run the playbook - The '-vvvv' extract is :
...
TASK [PUSH] **********************************************************************************************************
task path: /Users/ccompain/vEOS/ansible/test4/configure_eos.yaml:12
Using module file /Users/ccompain/vEOS/ansible/test4/library/napalm_install_config.py
<vEOS-1> ESTABLISH LOCAL CONNECTION FOR USER: ccompain
<vEOS-1> EXEC /bin/sh -c 'echo ~ && sleep 0'
Using module file /Users/ccompain/vEOS/ansible/test4/library/napalm_install_config.py
<vEOS-2> ESTABLISH LOCAL CONNECTION FOR USER: ccompain
<vEOS-2> EXEC /bin/sh -c 'echo ~ && sleep 0'
<vEOS-1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /Users/ccompain/.ansible/tmp/ansible-tmp-1498484651.53-187657461983830 `" && echo ansible-tmp-1498484651.53-187657461983830="` echo /Users/ccompain/.ansible/tmp/ansible-tmp-1498484651.53-187657461983830 `" ) && sleep 0'
<vEOS-2> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /Users/ccompain/.ansible/tmp/ansible-tmp-1498484651.53-154559222962668 `" && echo ansible-tmp-1498484651.53-154559222962668="` echo /Users/ccompain/.ansible/tmp/ansible-tmp-1498484651.53-154559222962668 `" ) && sleep 0'
<vEOS-1> PUT /var/folders/kl/wxylqm7s0ybf9c8w9z51bdkm0000gn/T/tmpMMUrzr TO /Users/ccompain/.ansible/tmp/ansible-tmp-1498484651.53-187657461983830/napalm_install_config.py
<vEOS-1> EXEC /bin/sh -c 'chmod u+x /Users/ccompain/.ansible/tmp/ansible-tmp-1498484651.53-187657461983830/ /Users/ccompain/.ansible/tmp/ansible-tmp-1498484651.53-187657461983830/napalm_install_config.py && sleep 0'
<vEOS-2> PUT /var/folders/kl/wxylqm7s0ybf9c8w9z51bdkm0000gn/T/tmp0fjhAT TO /Users/ccompain/.ansible/tmp/ansible-tmp-1498484651.53-154559222962668/napalm_install_config.py
<vEOS-2> EXEC /bin/sh -c 'chmod u+x /Users/ccompain/.ansible/tmp/ansible-tmp-1498484651.53-154559222962668/ /Users/ccompain/.ansible/tmp/ansible-tmp-1498484651.53-154559222962668/napalm_install_config.py && sleep 0'
<vEOS-1> EXEC /bin/sh -c '/usr/bin/python /Users/ccompain/.ansible/tmp/ansible-tmp-1498484651.53-187657461983830/napalm_install_config.py; rm -rf "/Users/ccompain/.ansible/tmp/ansible-tmp-1498484651.53-187657461983830/" > /dev/null 2>&1 && sleep 0'
<vEOS-2> EXEC /bin/sh -c '/usr/bin/python /Users/ccompain/.ansible/tmp/ansible-tmp-1498484651.53-154559222962668/napalm_install_config.py; rm -rf "/Users/ccompain/.ansible/tmp/ansible-tmp-1498484651.53-154559222962668/" > /dev/null 2>&1 && sleep 0'
fatal: [vEOS-1]: FAILED! => {
"changed": false,
"failed": true,
"invocation": {
"module_args": {
"archive_file": null,
"commit_changes": true,
"config": null,
"config_file": "configs/vEOS-1.conf",
"dev_os": "eos",
"diff_file": null,
"get_diffs": false,
"hostname": "vEOS-1",
"optional_args": null,
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"provider": null,
"replace_config": false,
"timeout": 60,
"username": "ccompain"
}
},
"msg": "the python module napalm is required"
}
fatal: [vEOS-2]: FAILED! => {
"changed": false,
"failed": true,
"invocation": {
"module_args": {
"archive_file": null,
"commit_changes": true,
"config": null,
"config_file": "configs/vEOS-2.conf",
"dev_os": "eos",
"diff_file": null,
"get_diffs": false,
"hostname": "vEOS-2",
"optional_args": null,
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"provider": null,
"replace_config": false,
"timeout": 60,
"username": "ccompain"
}
},
"msg": "the python module napalm is required"
}
...
Any idea for solving this ?
Thanks in advance,
Christophe
PS :
sudo apt-get install python-pip python-dev libffi-dev libssl-dev libxml2-dev libxslt1-dev libjpeg8-dev zlib1g-dev
sudo -H pip install napalm
When attempting to push a config to Arista using napalm_install_config the subsystem fails to recognize the optional_args being passed.
According to the readthedocs entry here, https://media.readthedocs.org/pdf/napalmsdf/latest/napalmsdf.pdf, there is a list of optional args expected and on page 36 it says we can add to them but it isn't clear where the model exists to add the optional args needed for our use case.
In either case I lack the confidence that the subsystem will operate as needed if the model is updated accordingly. Please advise.
Below is sample yaml
- name: Load configuration into the device and diff
napalm_install_config:
hostname: "{{ ansible_host }}"
username: test_user
dev_os: "{{ ansible_os_family }}"
optional_args:
commit_session: "{{ ansible_host }}"
commit: True
commit_timer: 00:02:00
commit_comments: "word"
password: test_password
config_file: "{{ config_file_name }}"
commit_changeas: True
replace_config: False
get_diffs: False
diff_file: "{{ ansible_os_family }}.{{ state }}.conf.diff"
when: has_pending_config == false
tags: [print_action]`
Below is output error s you can see optional_args is null
fatal: [arista7508e.cvr]: FAILED! => {"changed": false, "failed": true, "invocation": {"module_args": {"archive_file": null, "candidate_file": null, "commit_changes": false, "config": null, "config_file": "/arista7508e.cvr.eos.present.conf", "dev_os": "eos", "diff_file": "/arista7508e.cvr.eos.present.conf.diff", "get_diffs": true, "hostname": "arista7508e.cvr.d0cdn.net", "optional_args": null, "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", "provider": null, "replace_config": false, "timeout": 60, "username": "fjone"}, "module_name": "napalm_install_config"}, "msg": "cannot load config: Error [1002]: CLI command 3 of 4510 'commit timer ' failed: invalid command [incomplete command (at token 2: None)]"}
I can manually edit the eos.py class however we want dynamic variable input rather than static.
pip.req is no longer provided by pip package as such https://github.com/napalm-automation/napalm-ansible/blob/develop/setup.py breaks at install.
see pypa/pip#5156
x
Despite the documentation claiming that is a list
the filter
argument is in fact a string. It turns out you can pass a comma separated list of filters but it's not clear in the documentation and it's very fragile as facts,bgp_neighbors
will work but facts, bgp_neighbors
will not. Why not make it a real list instead?
So if people are using this in inventory, then it will work with napalm-ansible.
This is an Ansible 2.5 change.
https://www.ansible.com/blog/porting-ansible-network-playbooks-with-new-connection-plugins
I have attached the playbook and the config file that is trying to be updated.
fortigate.config-update.yml.txt
This is the output that I am getting from the playbook:
ansible-tst:~/fortigate# ansible-playbook fortigate.config-update.yml
PLAY [firewall] ***************************************************************
GATHERING FACTS ***************************************************************
ok: [homefw]
TASK: [update config] *********************************************************
failed: [homefw] => {"failed": true}
msg: cannot install config:
FATAL: all hosts have already failed -- aborting
PLAY RECAP ********************************************************************
to retry, use: --limit @/root/fortigate.config-update.retry
homefw : ok=1 changed=0 unreachable=0 failed=1
Many Thanks!
Dear napalm developers,
It is not clear to me how to reference a custom method deployed for a network driver into the napalm-ansible module.
Reading the documentation : http://napalm.readthedocs.io/en/latest/tutorials/extend_driver.html it is stated
βThe positive side effect is that tools such as Salt, Ansible, and Netbox implicitly have access to these methods.β
So far what I was able to obtain is to leverage my method (get_service_policies) from a standard python script. I have created in the script working directory the custom_napalm folder with the ios.py file and I have expanded the IOSDriver class.
To my understanding I have to write an ansible task as this:
I believe I have to move this folder somewhere else in order to be visible from the ansible module. Can you clarify ?
I'm trying to use the 'route_to' filter on get_facts and I'm failing:
tasks:
- name: get facts from device
napalm_get_facts:
provider: "{{ junos_provider }}"
filter: 'route_to'
register: result
$ ansible-playbook -i ./inventory/ ./getdata.yaml
PLAY [fetch info] ****************************************************************************************************************************************************************************
TASK [get facts from device] *****************************************************************************************************************************************************************
fatal: [10.69.0.208]: FAILED! => {"changed": false, "failed": true, "msg": "[route_to] cannot retrieve device data: Unknown protocol: destination"}
to retry, use: --limit @/home/ubuntu/2d-automation/ansible/getdata.retry
PLAY RECAP ***********************************************************************************************************************************************************************************
10.69.0.208 : ok=0 changed=0 unreachable=0 failed=1
Looking at the code in napalm-junos the function expects two parameters, but I don't think there is a way to pass them.
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.