forked from ansible/ansible
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add initial napalm connection plugin (ansible#45224)
* Add initial napalm connection plugin * Fix review comments
- Loading branch information
Showing
2 changed files
with
200 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
# (c) 2018 Ansible Project | ||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) | ||
|
||
from __future__ import (absolute_import, division, print_function) | ||
__metaclass__ = type | ||
|
||
|
||
DOCUMENTATION = """ | ||
--- | ||
author: Ansible Networking Team | ||
connection: napalm | ||
short_description: Provides persistent connection using NAPALM | ||
description: | ||
- This connection plugin provides connectivity to network devices using | ||
the NAPALM network device abstraction library. This library requires | ||
certain features to be enabled on network devices depending on the | ||
destination device operating system. The connection plugin requires | ||
C(napalm) to be installed locally on the Ansible controller. | ||
version_added: "2.8" | ||
requirements: | ||
- napalm | ||
options: | ||
host: | ||
description: | ||
- Specifies the remote device FQDN or IP address to establish the SSH | ||
connection to. | ||
default: inventory_hostname | ||
vars: | ||
- name: ansible_host | ||
port: | ||
type: int | ||
description: | ||
- Specifies the port on the remote device that listens for connections | ||
when establishing the SSH connection. | ||
default: 22 | ||
ini: | ||
- section: defaults | ||
key: remote_port | ||
env: | ||
- name: ANSIBLE_REMOTE_PORT | ||
vars: | ||
- name: ansible_port | ||
network_os: | ||
description: | ||
- Configures the device platform network operating system. This value is | ||
used to load a napalm device abstraction. | ||
vars: | ||
- name: ansible_network_os | ||
remote_user: | ||
description: | ||
- The username used to authenticate to the remote device when the SSH | ||
connection is first established. If the remote_user is not specified, | ||
the connection will use the username of the logged in user. | ||
- Can be configured from the CLI via the C(--user) or C(-u) options. | ||
ini: | ||
- section: defaults | ||
key: remote_user | ||
env: | ||
- name: ANSIBLE_REMOTE_USER | ||
vars: | ||
- name: ansible_user | ||
password: | ||
description: | ||
- Configures the user password used to authenticate to the remote device | ||
when first establishing the SSH connection. | ||
vars: | ||
- name: ansible_password | ||
- name: ansible_ssh_pass | ||
private_key_file: | ||
description: | ||
- The private SSH key or certificate file used to authenticate to the | ||
remote device when first establishing the SSH connection. | ||
ini: | ||
- section: defaults | ||
key: private_key_file | ||
env: | ||
- name: ANSIBLE_PRIVATE_KEY_FILE | ||
vars: | ||
- name: ansible_private_key_file | ||
timeout: | ||
type: int | ||
description: | ||
- Sets the connection time, in seconds, for communicating with the | ||
remote device. This timeout is used as the default timeout value for | ||
commands when issuing a command to the network CLI. If the command | ||
does not return in timeout seconds, an error is generated. | ||
default: 120 | ||
host_key_auto_add: | ||
type: boolean | ||
description: | ||
- By default, Ansible will prompt the user before adding SSH keys to the | ||
known hosts file. By enabling this option, unknown host keys will | ||
automatically be added to the known hosts file. | ||
- Be sure to fully understand the security implications of enabling this | ||
option on production systems as it could create a security vulnerability. | ||
default: False | ||
ini: | ||
- section: paramiko_connection | ||
key: host_key_auto_add | ||
env: | ||
- name: ANSIBLE_HOST_KEY_AUTO_ADD | ||
persistent_connect_timeout: | ||
type: int | ||
description: | ||
- Configures, in seconds, the amount of time to wait when trying to | ||
initially establish a persistent connection. If this value expires | ||
before the connection to the remote device is completed, the connection | ||
will fail. | ||
default: 30 | ||
ini: | ||
- section: persistent_connection | ||
key: connect_timeout | ||
env: | ||
- name: ANSIBLE_PERSISTENT_CONNECT_TIMEOUT | ||
persistent_command_timeout: | ||
type: int | ||
description: | ||
- Configures, in seconds, the amount of time to wait for a command to | ||
return from the remote device. If this timer is exceeded before the | ||
command returns, the connection plugin will raise an exception and | ||
close. | ||
default: 10 | ||
ini: | ||
- section: persistent_connection | ||
key: command_timeout | ||
env: | ||
- name: ANSIBLE_PERSISTENT_COMMAND_TIMEOUT | ||
vars: | ||
- name: ansible_command_timeout | ||
""" | ||
|
||
from ansible.errors import AnsibleConnectionFailure, AnsibleError | ||
from ansible.plugins.connection import NetworkConnectionBase | ||
|
||
try: | ||
from napalm import get_network_driver | ||
from napalm.base import ModuleImportError | ||
HAS_NAPALM = True | ||
except ImportError: | ||
raise AnsibleError( | ||
'Napalm is required to use the napalm connection type.\n' | ||
'Please run pip install napalm' | ||
) | ||
|
||
try: | ||
from __main__ import display | ||
except ImportError: | ||
from ansible.utils.display import Display | ||
display = Display() | ||
|
||
|
||
class Connection(NetworkConnectionBase): | ||
"""Napalm connections""" | ||
|
||
transport = 'napalm' | ||
has_pipelining = False | ||
|
||
def __init__(self, play_context, new_stdin, *args, **kwargs): | ||
super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs) | ||
|
||
self.napalm = None | ||
|
||
def _connect(self): | ||
super(Connection, self)._connect() | ||
|
||
if not self.connected: | ||
if not self._network_os: | ||
raise AnsibleConnectionFailure( | ||
'Unable to automatically determine host network os. Please ' | ||
'manually configure ansible_network_os value for this host' | ||
) | ||
display.display('network_os is set to %s' % self._network_os, log_only=True) | ||
|
||
try: | ||
driver = get_network_driver(self._network_os) | ||
except ModuleImportError: | ||
raise AnsibleConnectionFailure('Failed to import napalm driver for {0}'.format(self._network_os)) | ||
|
||
host = self.get_option('host') | ||
self.napalm = driver( | ||
hostname=host, | ||
username=self.get_option('remote_user'), | ||
password=self.get_option('password'), | ||
timeout=self.get_option('persistent_command_timeout'), | ||
) | ||
|
||
self.napalm.open() | ||
|
||
self._implementation_plugins.append(self.napalm) | ||
display.vvvv('created napalm device for network_os %s' % self._network_os, host=host) | ||
self._connected = True | ||
|
||
def close(self): | ||
if self.napalm: | ||
self.napalm.close() | ||
self.napalm = None | ||
|
||
super(Connection, self).close() |