mirror of https://github.com/ansible/ansible.git
Add initial napalm connection plugin (#45224)
* Add initial napalm connection plugin * Fix review commentspull/45743/head
parent
917fcb9c55
commit
21ff9c6a4a
@ -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()
|
Loading…
Reference in New Issue