diff --git a/.travis.yml b/.travis.yml
index 3af0261..a3bc78a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,14 +6,14 @@ python:
- 3.6
env:
- - ANSIBLE_VERSION=2.3
- - ANSIBLE_VERSION=2.4
- ANSIBLE_VERSION=2.5
- ANSIBLE_VERSION=2.6
+ - ANSIBLE_VERSION=2.7
+ - ANSIBLE_VERSION=2.8
install:
- pip install pylama
- - pip install napalm
+ - pip install -r requirements.txt
- pip install "ansible>=$ANSIBLE_VERSION.0,<$ANSIBLE_VERSION.99"
- pip install -r requirements-dev.txt
- pip install -e .
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index ed2a6b6..49103a9 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,6 +1,14 @@
-develop
+1.0.0
=====
+ - Add support for ansible_network_os
+ - Fix minor documentation errors
+ - Expand filenames for `*_file` parameters
+ - Fix Ansible 2.8 backwards incompatible changes
+ - Removing support of legacy napalm_base
+ - Changing napalm_cli to cli_results; napalm_ping to ping_results
+ - Use yaml safe_load for tests
+
0.10.0
=====
diff --git a/README.md b/README.md
index 8a1d43d..ab5a211 100644
--- a/README.md
+++ b/README.md
@@ -105,7 +105,7 @@ Example to get compliance report
validation_file: validate.yml
```
-Example to use default connection paramters:
+Example to use default connection parameters:
```
- name: get facts from device
napalm_get_facts:
diff --git a/napalm_ansible/modules/napalm_cli.py b/napalm_ansible/modules/napalm_cli.py
index 7827c81..6097bd7 100644
--- a/napalm_ansible/modules/napalm_cli.py
+++ b/napalm_ansible/modules/napalm_cli.py
@@ -1,5 +1,14 @@
from __future__ import unicode_literals, print_function
-from ansible.module_utils.basic import AnsibleModule, return_values
+from ansible.module_utils.basic import AnsibleModule
+
+
+# FIX for Ansible 2.8 moving this function and making it private
+# greatly simplified for napalm-ansible's use
+def return_values(obj):
+ """ Return native stringified values from datastructures.
+
+ For use with removing sensitive values pre-jsonification."""
+ yield str(obj)
DOCUMENTATION = '''
@@ -87,15 +96,6 @@
except ImportError:
pass
-# Legacy for pre-reunification napalm (remove in future)
-if not napalm_found:
- try:
- from napalm_base import get_network_driver # noqa
- from napalm_base import ModuleImportError # noqa
- napalm_found = True
- except ImportError:
- pass
-
def main():
module = AnsibleModule(
@@ -175,7 +175,7 @@ def main():
except Exception as e:
module.fail_json(msg="cannot close device connection: " + str(e))
- module.exit_json(changed=False, results=cli_response)
+ module.exit_json(changed=False, cli_results=cli_response)
if __name__ == '__main__':
diff --git a/napalm_ansible/modules/napalm_get_facts.py b/napalm_ansible/modules/napalm_get_facts.py
index 3fae938..d58ddc2 100644
--- a/napalm_ansible/modules/napalm_get_facts.py
+++ b/napalm_ansible/modules/napalm_get_facts.py
@@ -3,8 +3,8 @@
This file is part of Ansible
-Ansible is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
+Ansible is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -17,7 +17,16 @@
along with Ansible. If not, see .
"""
from __future__ import unicode_literals, print_function
-from ansible.module_utils.basic import AnsibleModule, return_values
+from ansible.module_utils.basic import AnsibleModule
+
+
+# FIX for Ansible 2.8 moving this function and making it private
+# greatly simplified for napalm-ansible's use
+def return_values(obj):
+ """ Return native stringified values from datastructures.
+
+ For use with removing sensitive values pre-jsonification."""
+ yield str(obj)
DOCUMENTATION = '''
@@ -145,15 +154,6 @@
except ImportError:
pass
-# Legacy for pre-reunification napalm (remove in future)
-if not napalm_found:
- try:
- from napalm_base import get_network_driver # noqa
- from napalm_base import ModuleImportError # noqa
- napalm_found = True
- except ImportError:
- pass
-
def main():
module = AnsibleModule(
diff --git a/napalm_ansible/modules/napalm_install_config.py b/napalm_ansible/modules/napalm_install_config.py
index 38c4b37..bfa9cef 100644
--- a/napalm_ansible/modules/napalm_install_config.py
+++ b/napalm_ansible/modules/napalm_install_config.py
@@ -18,7 +18,17 @@
along with Ansible. If not, see .
"""
from __future__ import unicode_literals, print_function
-from ansible.module_utils.basic import AnsibleModule, return_values
+import os.path
+from ansible.module_utils.basic import AnsibleModule
+
+
+# FIX for Ansible 2.8 moving this function and making it private
+# greatly simplified for napalm-ansible's use
+def return_values(obj):
+ """ Return native stringified values from datastructures.
+
+ For use with removing sensitive values pre-jsonification."""
+ yield str(obj)
DOCUMENTATION = '''
@@ -165,15 +175,6 @@
except ImportError:
pass
-# Legacy for pre-reunification napalm (remove in future)
-if not napalm_found:
- try:
- from napalm_base import get_network_driver # noqa
- from napalm_base import ModuleImportError # noqa
- napalm_found = True
- except ImportError:
- pass
-
def save_to_file(content, filename):
with open(filename, 'w') as f:
@@ -236,6 +237,14 @@ def main():
get_diffs = module.params['get_diffs']
archive_file = module.params['archive_file']
candidate_file = module.params['candidate_file']
+ if config_file:
+ config_file = os.path.expanduser(os.path.expandvars(config_file))
+ if diff_file:
+ diff_file = os.path.expanduser(os.path.expandvars(diff_file))
+ if archive_file:
+ archive_file = os.path.expanduser(os.path.expandvars(archive_file))
+ if candidate_file:
+ candidate_file = os.path.expanduser(os.path.expandvars(candidate_file))
argument_check = {'hostname': hostname, 'username': username, 'dev_os': dev_os}
for key, val in argument_check.items():
diff --git a/napalm_ansible/modules/napalm_parse_yang.py b/napalm_ansible/modules/napalm_parse_yang.py
index 6a2b7fc..9ba84c9 100644
--- a/napalm_ansible/modules/napalm_parse_yang.py
+++ b/napalm_ansible/modules/napalm_parse_yang.py
@@ -17,7 +17,7 @@
along with Ansible. If not, see .
"""
from __future__ import unicode_literals, print_function
-from ansible.module_utils.basic import AnsibleModule, return_values
+from ansible.module_utils.basic import AnsibleModule
import json
napalm_found = False
@@ -28,21 +28,21 @@
except ImportError:
pass
-# Legacy for pre-reunification napalm (remove in future)
-if not napalm_found:
- try:
- from napalm_base import get_network_driver # noqa
- from napalm_base import ModuleImportError # noqa
- napalm_found = True
- except ImportError:
- pass
-
try:
import napalm_yang
except ImportError:
napalm_yang = None
+# FIX for Ansible 2.8 moving this function and making it private
+# greatly simplified for napalm-ansible's use
+def return_values(obj):
+ """ Return native stringified values from datastructures.
+
+ For use with removing sensitive values pre-jsonification."""
+ yield str(obj)
+
+
DOCUMENTATION = '''
---
module: napalm_parse_yang
diff --git a/napalm_ansible/modules/napalm_ping.py b/napalm_ansible/modules/napalm_ping.py
index d3eeb32..182a32f 100644
--- a/napalm_ansible/modules/napalm_ping.py
+++ b/napalm_ansible/modules/napalm_ping.py
@@ -14,7 +14,16 @@
along with Ansible. If not, see .
"""
from __future__ import unicode_literals, print_function
-from ansible.module_utils.basic import AnsibleModule, return_values
+from ansible.module_utils.basic import AnsibleModule
+
+
+# FIX for Ansible 2.8 moving this function and making it private
+# greatly simplified for napalm-ansible's use
+def return_values(obj):
+ """ Return native stringified values from datastructures.
+
+ For use with removing sensitive values pre-jsonification."""
+ yield str(obj)
DOCUMENTATION = '''
@@ -136,15 +145,6 @@
except ImportError:
pass
-# Legacy for pre-reunification napalm (remove in future)
-if not napalm_found:
- try:
- from napalm_base import get_network_driver # noqa
- from napalm_base import ModuleImportError # noqa
- napalm_found = True
- except ImportError:
- pass
-
def main():
module = AnsibleModule(
@@ -236,7 +236,7 @@ def main():
except Exception as e:
module.fail_json(msg="cannot close device connection: " + str(e))
- module.exit_json(changed=False, results=ping_response)
+ module.exit_json(changed=False, ping_results=ping_response)
if __name__ == '__main__':
diff --git a/napalm_ansible/modules/napalm_validate.py b/napalm_ansible/modules/napalm_validate.py
index 7d48c39..ae138e5 100644
--- a/napalm_ansible/modules/napalm_validate.py
+++ b/napalm_ansible/modules/napalm_validate.py
@@ -1,5 +1,5 @@
from __future__ import unicode_literals, print_function
-from ansible.module_utils.basic import AnsibleModule, return_values
+from ansible.module_utils.basic import AnsibleModule
napalm_found = False
try:
@@ -9,21 +9,21 @@
except ImportError:
pass
-# Legacy for pre-reunification napalm (remove in future)
-if not napalm_found:
- try:
- from napalm_base import get_network_driver # noqa
- from napalm_base import ModuleImportError # noqa
- napalm_found = True
- except ImportError:
- pass
-
try:
import napalm_yang
except ImportError:
napalm_yang = None
+# FIX for Ansible 2.8 moving this function and making it private
+# greatly simplified for napalm-ansible's use
+def return_values(obj):
+ """ Return native stringified values from datastructures.
+
+ For use with removing sensitive values pre-jsonification."""
+ yield str(obj)
+
+
DOCUMENTATION = '''
---
module: napalm_validate
diff --git a/napalm_ansible/plugins/action/napalm.py b/napalm_ansible/plugins/action/napalm.py
index acd8466..ac37522 100644
--- a/napalm_ansible/plugins/action/napalm.py
+++ b/napalm_ansible/plugins/action/napalm.py
@@ -18,6 +18,9 @@ def run(self, tmp=None, task_vars=None):
# Timeout can't be passed via command-line as Ansible defaults to a 10 second timeout
provider['timeout'] = provider.get('timeout', 60)
+ if hasattr(pc, 'network_os'):
+ provider['dev_os'] = provider.get('dev_os', pc.network_os)
+
self._task.args['provider'] = provider
result = super(ActionModule, self).run(tmp, task_vars)
diff --git a/requirements.txt b/requirements.txt
index a98b396..d59b294 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1 +1,2 @@
napalm
+six
diff --git a/setup.py b/setup.py
index 100afde..8c3abce 100644
--- a/setup.py
+++ b/setup.py
@@ -6,7 +6,7 @@
setup(
name="napalm-ansible",
- version='0.10.0',
+ version='1.0.0',
packages=find_packages(exclude=("test*", "library")),
author="David Barroso, Kirk Byers, Mircea Ulinic",
author_email="dbarrosop@dravetech.com, ktbyers@twb-tech.com",
diff --git a/tests/napalm_cli/multiple_commands.yaml b/tests/napalm_cli/multiple_commands.yaml
index 97ad04e..16e68ee 100644
--- a/tests/napalm_cli/multiple_commands.yaml
+++ b/tests/napalm_cli/multiple_commands.yaml
@@ -19,5 +19,5 @@
register: result
- assert:
that:
- - "{{ result.results['show version']|length > 10 }}"
- - "{{ result.results['show interfaces']|length > 10 }}"
+ - "{{ result.cli_results['show version']|length > 10 }}"
+ - "{{ result.cli_results['show interfaces']|length > 10 }}"
diff --git a/tests/napalm_connection/connection_ansible_network_os.yaml b/tests/napalm_connection/connection_ansible_network_os.yaml
new file mode 100644
index 0000000..2c59824
--- /dev/null
+++ b/tests/napalm_connection/connection_ansible_network_os.yaml
@@ -0,0 +1,13 @@
+---
+- name: Get facts
+ hosts: all
+ connection: local # code is run locally
+ gather_facts: no # don't gather facts
+ tasks:
+ - block:
+ - name: get facts from device
+ napalm_get_facts: # NAPALM plugin
+ optional_args:
+ path: "{{ playbook_dir }}/mocked"
+ profile: "{{ profile }}"
+ filter: ['facts']
diff --git a/tests/napalm_connection/hosts b/tests/napalm_connection/hosts
index 44150c8..763864f 100644
--- a/tests/napalm_connection/hosts
+++ b/tests/napalm_connection/hosts
@@ -1,5 +1,5 @@
[all]
-dummy os=mock profile=[eos] password=vagrant
+dummy os=mock profile=[eos] password=vagrant ansible_network_os=mock
[all:vars]
ansible_python_interpreter="/usr/bin/env python"
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index d070a33..61e7e7e 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -4,6 +4,7 @@ set -e
ansible-playbook -i napalm_connection/hosts napalm_connection/connection_info_missing.yaml
ansible-playbook -i napalm_connection/hosts napalm_connection/connection_info_in_vars.yaml
ansible-playbook -i napalm_connection/hosts napalm_connection/connection_info_in_args.yaml -u vagrant
+ansible-playbook -i napalm_connection/hosts napalm_connection/connection_ansible_network_os.yaml -u vagrant
ANSIBLE_REMOTE_USER=vagrant ansible-playbook -i napalm_connection/hosts napalm_connection/connection_info_in_env.yaml
ansible-playbook -i napalm_install_config/hosts -l "*.dry_run.*" napalm_install_config/config.yaml -C
diff --git a/tests/test_documentation.py b/tests/test_documentation.py
index 6f838ec..30418cd 100644
--- a/tests/test_documentation.py
+++ b/tests/test_documentation.py
@@ -24,7 +24,7 @@ def test_module_documentation_exists(ansible_module):
def test_module_documentation_format(ansible_module):
module = import_module(ansible_module)
- docs = yaml.load(module.DOCUMENTATION)
+ docs = yaml.safe_load(module.DOCUMENTATION)
assert 'author' in docs.keys()
assert 'description' in docs.keys()
assert 'short_description' in docs.keys()
@@ -37,8 +37,8 @@ def test_module_documentation_format(ansible_module):
def test_module_examples_format(ansible_module):
module = import_module(ansible_module)
module_name = ansible_module.replace('napalm_ansible.', '')
- examples = yaml.load(module.EXAMPLES)
- params = yaml.load(module.DOCUMENTATION)['options'].keys()
+ examples = yaml.safe_load(module.EXAMPLES)
+ params = yaml.safe_load(module.DOCUMENTATION)['options'].keys()
for example in examples:
if module_name in example.keys():
for param in example[module_name]:
@@ -47,7 +47,7 @@ def test_module_examples_format(ansible_module):
def test_module_return_format(ansible_module):
module = import_module(ansible_module)
- yaml.load(module.RETURN)
+ yaml.safe_load(module.RETURN)
def test_build_docs(ansible_module):
@@ -58,10 +58,10 @@ def test_build_docs(ansible_module):
module = import_module(ansible_module)
content = {}
- content['doc'] = yaml.load(module.DOCUMENTATION)
+ content['doc'] = yaml.safe_load(module.DOCUMENTATION)
content['examples'] = module.EXAMPLES
content['example_lines'] = module.EXAMPLES.split('\n')
- content['return_values'] = yaml.load(module.RETURN)
+ content['return_values'] = yaml.safe_load(module.RETURN)
module_name = ansible_module.replace('napalm_ansible.', '').split('.')[-1]
with open('module_docs/{0}.json'.format(module_name), 'w') as f: