Skip to content

Commit

Permalink
Merge pull request #116 from napalm-automation/command_line_args
Browse files Browse the repository at this point in the history
Action plugin for support of command-line args
  • Loading branch information
ktbyers committed Feb 1, 2018
2 parents 6b07860 + bfb0131 commit d92e06e
Show file tree
Hide file tree
Showing 31 changed files with 174 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ develop
=====
- Fix old napalm_base references
- Various documentation fixes
- Add action plugin to better support command-line arguments

0.8.0
=====
Expand Down
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ The following modules are currently available:
- ``napalm_translate_yang``
- ``napalm_validate``

Actions
=======

Actions will only work with Ansible version 2.3 or greater.
They provides default parameters for the hostname, username, password and timeout paramters.
* hostname is set to the first of provider {{ hostname }}, provider {{ host }}, play-context remote_addr.
* username is set to the first of provider {{ username }}, play-context connection_user.
* password is set to the first of provider {{ password }}, play-context password (-k argument).
* timeout is set to the provider {{ timeout }}, or else defaults to 60 seconds (can't be passed via command-line).

Install
=======

Expand All @@ -37,11 +47,18 @@ file, i.e. `./ansible.cfg`:
[defaults]
library = /Users/dbarroso/workspace/napalm/napalm-ansible/napalm_ansible
action_plugins = /Users/dbarroso/workspace/napalm/napalm-ansible/action_plugins
For more details on ansible's configuration file visit:
https://docs.ansible.com/ansible/latest/intro_configuration.html
```

Dependencies
=======
* [napalm](https://github.com/napalm-automation/napalm) 2.3.0 or later
* [ansible](https://github.com/ansible/ansible) 2.2.0.0 or later


Examples
=======

Expand Down Expand Up @@ -87,3 +104,11 @@ Example to get compliance report
dev_os: "{{ dev_os }}"
validation_file: validate.yml
```

Example to use default connection paramters:
```
- name: get facts from device
napalm_get_facts:
dev_os: "{{ os }}"
filter: facts,interfaces,bgp_neighbors
```
2 changes: 1 addition & 1 deletion library
18 changes: 13 additions & 5 deletions napalm_ansible/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import os
import ansible
from distutils.version import LooseVersion

message = """
To make sure ansible can make use of the napalm modules you will have
to add the following configurtion to your ansible configureation
file, i.e. `./ansible.cfg`:
To ensure Ansible can use the NAPALM modules you will have
to add the following configurtion to your Ansible configuration
file (ansible.cfg):
[defaults]
library = {path}
library = {path}/modules
{action_plugins}
For more details on ansible's configuration file visit:
https://docs.ansible.com/ansible/latest/intro_configuration.html
Expand All @@ -15,4 +18,9 @@

def main():
path = os.path.dirname(__file__)
print(message.format(path=path).strip())
if LooseVersion(ansible.__version__) < LooseVersion('2.3.0.0'):
action_plugins = ""
else:
action_plugins = "action_plugins = {path}/plugins/action".format(path=path)

print(message.format(path=path, action_plugins=action_plugins).strip())
Empty file.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Empty file.
Empty file.
24 changes: 24 additions & 0 deletions napalm_ansible/plugins/action/napalm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

from ansible.plugins.action.normal import ActionModule as _ActionModule


class ActionModule(_ActionModule):
def run(self, tmp=None, task_vars=None):
pc = self._play_context

if hasattr(pc, "connection_user"): # new in ansible 2.3
# populate provider values with context values if not set
provider = self._task.args.get('provider', {})

provider['hostname'] = provider.get('hostname', provider.get('host', pc.remote_addr))
provider['username'] = provider.get('username', pc.connection_user)
provider['password'] = provider.get('password', pc.password)
# Timeout can't be passed via command-line as Ansible defaults to a 10 second timeout
provider['timeout'] = provider.get('timeout', 60)

self._task.args['provider'] = provider

result = super(ActionModule, self).run(tmp, task_vars)
return result
1 change: 1 addition & 0 deletions napalm_ansible/plugins/action/napalm_get_facts.py
1 change: 1 addition & 0 deletions napalm_ansible/plugins/action/napalm_install_config.py
1 change: 1 addition & 0 deletions napalm_ansible/plugins/action/napalm_parse_yang.py
1 change: 1 addition & 0 deletions napalm_ansible/plugins/action/napalm_ping.py
1 change: 1 addition & 0 deletions napalm_ansible/plugins/action/napalm_validate.py
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""setup.py file."""
import uuid

from setuptools import setup
from setuptools import setup, find_packages
from pip.req import parse_requirements


Expand All @@ -12,7 +12,7 @@
setup(
name="napalm-ansible",
version='0.8.0',
packages=["napalm_ansible"],
packages=find_packages(exclude=("test*", "library")),
author="David Barroso, Kirk Byers, Mircea Ulinic",
author_email="dbarrosop@dravetech.com, ktbyers@twb-tech.com",
description="Network Automation and Programmability Abstraction Layer with Multivendor support",
Expand Down
3 changes: 2 additions & 1 deletion tests/ansible.cfg
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[defaults]
library = ../library/
library = ../napalm_ansible/modules
action_plugins = ../napalm_ansible/plugins/action

retry_files_enabled = False
19 changes: 19 additions & 0 deletions tests/napalm_connection/connection_info_in_args.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
- 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
dev_os: "{{ os }}"
optional_args:
path: "{{ playbook_dir }}/mocked"
profile: "{{ profile }}"
filter: ['facts']
register: napalm_facts # store information here
rescue:
# This is expected to fail in ansible < 2.3
- assert:
that: "{{ ansible_version.full | version_compare('2.3', 'lt') }}"
19 changes: 19 additions & 0 deletions tests/napalm_connection/connection_info_in_env.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
- 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
dev_os: "{{ os }}"
optional_args:
path: "{{ playbook_dir }}/mocked"
profile: "{{ profile }}"
filter: ['facts']
register: napalm_facts # store information here
rescue:
# This is expected to fail in ansible < 2.3
- assert:
that: "{{ ansible_version.full | version_compare('2.3', 'lt') }}"
17 changes: 17 additions & 0 deletions tests/napalm_connection/connection_info_in_vars.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
- 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
hostname: "{{ ansible_host }}"
username: "vagrant"
password: "vagrant"
dev_os: "{{ os }}"
optional_args:
path: "{{ playbook_dir }}/mocked"
profile: "{{ profile }}"
filter: ['facts']
18 changes: 18 additions & 0 deletions tests/napalm_connection/connection_info_missing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
- 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
dev_os: "{{ os }}"
optional_args:
path: "{{ playbook_dir }}/mocked"
profile: "{{ profile }}"
filter: ['facts']
register: napalm_facts # store information here
rescue:
- assert:
that: "napalm_facts.failed == True"
5 changes: 5 additions & 0 deletions tests/napalm_connection/hosts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[all]
dummy os=mock profile=[eos] password=vagrant

[all:vars]
ansible_python_interpreter="/usr/bin/env python"
16 changes: 16 additions & 0 deletions tests/napalm_connection/mocked/get_facts.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"fqdn": "localhost",
"hostname": "localhost",
"interface_list": [
"Ethernet1",
"Ethernet2",
"Ethernet3",
"Ethernet4",
"Management1"
],
"model": "vEOS",
"os_version": "4.15.5M-3054042.4155M",
"serial_number": "",
"uptime": "...",
"vendor": "Arista"
}
5 changes: 5 additions & 0 deletions tests/run_tests.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#!/bin/sh
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_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
ansible-playbook -i napalm_install_config/hosts -l "*.commit.*" napalm_install_config/config.yaml
ansible-playbook -i napalm_install_config/hosts -l "*.error*" napalm_install_config/config_error.yaml
Expand Down
4 changes: 2 additions & 2 deletions tests/test_documentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from glob import glob
from importlib import import_module

module_files = glob('napalm_ansible/napalm_*.py')
module_files = glob('napalm_ansible/modules/napalm_*.py')
modules = [module.split('.')[0].replace('/', '.') for module in module_files]


Expand Down Expand Up @@ -62,7 +62,7 @@ def test_build_docs(ansible_module):
content['examples'] = module.EXAMPLES
content['example_lines'] = module.EXAMPLES.split('\n')
content['return_values'] = yaml.load(module.RETURN)
module_name = ansible_module.replace('napalm_ansible.', '')
module_name = ansible_module.replace('napalm_ansible.', '').split('.')[-1]

with open('module_docs/{0}.json'.format(module_name), 'w') as f:
json.dump(content, f, indent=4, sort_keys=False)

0 comments on commit d92e06e

Please sign in to comment.