Add initial napalm connection plugin (#45224)

* Add initial napalm connection plugin

* Fix review comments
This commit is contained in:
Nathaniel Case 2018-09-17 12:53:57 -04:00 committed by GitHub
parent 917fcb9c55
commit 21ff9c6a4a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 200 additions and 1 deletions

View file

@ -360,7 +360,8 @@ class NetworkConnectionBase(ConnectionBase):
initialize implementation plugin options
'''
for plugin in self._implementation_plugins:
plugin.set_options(task_keys=task_keys, var_options=var_options, direct=direct)
if hasattr(plugin, 'set_options'):
plugin.set_options(task_keys=task_keys, var_options=var_options, direct=direct)
def _update_connection_state(self):
'''

View file

@ -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()