Skip to content

Commit

Permalink
Merge branch 'develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
donckers authored Jul 31, 2019
2 parents 5269d89 + 55dffe0 commit 116715f
Show file tree
Hide file tree
Showing 13 changed files with 210 additions and 103 deletions.
25 changes: 24 additions & 1 deletion docs/contributing/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,27 @@ If you found a bug and know how to fix just contribute the bugfix. It might be i
Documentation
-------------

Just do it! :)
The documentation is built using `Sphinx`_ and hosted on Read the Docs. The docs
are kept in the ``docs/`` directory at the top of the source tree.

To make changes, it is preferable to set up a `python virtual environment`_
called ``env`` and activate it.

Next, install the documentation dependencies using ``pip``:

.. code:: console
pip install -r docs/requirements.txt
Make your changes and then check them for correctness by building them locally:

.. code:: console
# in the docs directory
make html
.. tip:: If it is a simple change to a single page, you can use the "Edit on
GitHub" button in the upper right hand corner of the page in question.

Proposing a new driver
----------------------
Expand All @@ -58,3 +78,6 @@ Please check :ref:`contributing-drivers` to understand the process.

core
drivers

.. _python virtual environment: https://packaging.python.org/guides/installing-using-pip-and-virtualenv/
.. _Sphinx: http://www.sphinx-doc.org/en/master/
19 changes: 19 additions & 0 deletions docs/installation/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,25 @@ You can install napalm with pip:
That will install all the drivers currently available.


OS Package Managers
-------------------

Some execution environments offer napalm through a system-level package manager. Installing with pip outside of a user profile or virtualenv/venv is inadvisable in these cases.

FreeBSD
~~~~~~~

.. code-block:: bash
pkg install net-mgmt/py-napalm
This will install napalm and all drivers and dependencies for the default version(s) of python. To install for a specific version, python X.Y, if supported:

.. code-block:: bash
pkg install pyXY-napalm
Dependencies
------------

Expand Down
8 changes: 0 additions & 8 deletions docs/installation/ios.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,3 @@ RedHat and CentOS
.. code-block:: bash
sudo yum install -y python-pip gcc openssl openssl-devel libffi-devel python-devel
FreeBSD
-------

.. code-block:: bash
sudo pkg_add -r py27-pip
8 changes: 0 additions & 8 deletions docs/installation/iosxr.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,3 @@ RedHat and CentOS
.. code-block:: bash
sudo yum install -y python-pip gcc openssl openssl-devel libffi-devel python-devel
FreeBSD
-------

.. code-block:: bash
sudo pkg_add -r py27-pip
7 changes: 0 additions & 7 deletions docs/installation/junos.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,3 @@ RedHat and CentOS
.. code-block:: bash
sudo yum install -y python-pip python-devel libxml2-devel libxslt-devel gcc openssl openssl-devel libffi-devel
FreeBSD
-------

.. code-block:: bash
sudo pkg_add -r py27-pip libxml2 libxslt
2 changes: 1 addition & 1 deletion docs/validate/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ CLI & Ansible
If you prefer, you can also make use of the validate functionality via the CLI with the command ``cl_napalm_validate`` or with ansible plugin. You can find more information about them here:

* CLI - https://github.com/napalm-automation/napalm/pull/168
* Ansible - https://github.com/napalm-automation/napalm-ansible/blob/master/library/napalm_validate.py
* Ansible - https://github.com/napalm-automation/napalm-ansible/blob/master/napalm_ansible/modules/napalm_validate.py


Why this and what's next
Expand Down
24 changes: 17 additions & 7 deletions napalm/base/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@
from __future__ import print_function
from __future__ import unicode_literals

import sys

from netmiko import ConnectHandler, NetMikoTimeoutException

# local modules
import napalm.base.exceptions
from napalm.base.exceptions import ConnectionException
import napalm.base.helpers
from napalm.base import constants as c
from napalm.base import validate

from netmiko import ConnectHandler, NetMikoTimeoutException
from napalm.base.exceptions import ConnectionException


class NetworkDriver(object):
Expand All @@ -44,8 +46,15 @@ def __init__(self, hostname, username, password, timeout=60, optional_args=None)
raise NotImplementedError

def __enter__(self):
self.open()
return self
try:
self.open()
return self
except: # noqa: E722
# Swallow exception if __exit__ returns a True value
if self.__exit__(*sys.exc_info()):
pass
else:
raise

def __exit__(self, exc_type, exc_value, exc_traceback):
self.close()
Expand Down Expand Up @@ -95,8 +104,9 @@ def _netmiko_open(self, device_type, netmiko_optional_args=None):

def _netmiko_close(self):
"""Standardized method of closing a Netmiko connection."""
self.device.disconnect()
self._netmiko_device = None
if getattr(self, "_netmiko_device", None):
self._netmiko_device.disconnect()
self._netmiko_device = None
self.device = None

def open(self):
Expand Down
2 changes: 1 addition & 1 deletion napalm/ios/ios.py
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ def rollback(self):
if not self._check_file_exists(cfg_file):
raise ReplaceConfigException("Rollback config file does not exist")
cmd = "configure replace {} force".format(cfg_file)
self.device.send_command_expect(cmd)
self._commit_handler(cmd)

# After a rollback - we no longer know whether this is configured or not.
self.prompt_quiet_configured = None
Expand Down
6 changes: 3 additions & 3 deletions napalm/junos/junos.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def _unlock(self):
self.device.cu.unlock()
self.locked = False
except JnrpUnlockError as jue:
raise UnlockError(jue.messsage)
raise UnlockError(jue)

def _rpc(self, get, child=None, **kwargs):
"""
Expand Down Expand Up @@ -818,7 +818,7 @@ def get_lldp_neighbors_detail(self, interface=""):
interface_args = {interface_variable: interface}
lldp_table.get(**interface_args)
except RpcError as e:
if "syntax error" in e.message:
if "syntax error" in str(e):
# Looks like we need to call a different RPC on this device
# Switch to the alternate style
lldp_table.GET_RPC = alt_rpc
Expand Down Expand Up @@ -1571,7 +1571,7 @@ def get_mac_address_table(self):
except RpcError as e:
# Device hasn't got it's l2 subsystem running
# Don't error but just return an empty result
if "l2-learning subsystem" in e.message:
if "l2-learning subsystem" in str(e):
return []
else:
raise
Expand Down
13 changes: 12 additions & 1 deletion napalm/nxos/nxos.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,12 @@ def commit_config(self, message=""):
else:
self._commit_merge()

try:
# If hostname changes ensure Netmiko state is updated properly
self._netmiko_device.set_base_prompt()
except AttributeError:
pass

self._copy_run_start()
self.loaded = False
else:
Expand Down Expand Up @@ -1109,7 +1115,12 @@ def get_interfaces_ip(self):
interfaces_ip[interface_name]["ipv6"] = {}
if "addr" not in interface.keys():
# Handle nexus 9000 ipv6 interface output
addrs = [addr["addr"] for addr in interface["TABLE_addr"]["ROW_addr"]]
if isinstance(interface["TABLE_addr"]["ROW_addr"], list):
addrs = [
addr["addr"] for addr in interface["TABLE_addr"]["ROW_addr"]
]
elif isinstance(interface["TABLE_addr"]["ROW_addr"], dict):
addrs = interface["TABLE_addr"]["ROW_addr"]["addr"]
interface["addr"] = addrs

if type(interface.get("addr", "")) is list:
Expand Down
21 changes: 16 additions & 5 deletions napalm/nxos_ssh/nxos_ssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,12 +449,15 @@ def _send_command(self, command, raw_text=False):
"""
return self.device.send_command(command)

def _send_command_list(self, commands):
def _send_command_list(self, commands, expect_string=None):
"""Wrapper for Netmiko's send_command method (for list of commands."""
output = ""
for command in commands:
output += self.device.send_command(
command, strip_prompt=False, strip_command=False
command,
strip_prompt=False,
strip_command=False,
expect_string=expect_string,
)
return output

Expand Down Expand Up @@ -523,13 +526,15 @@ def _copy_run_start(self):
raise CommandErrorException(msg)

def _load_cfg_from_checkpoint(self):

commands = [
"terminal dont-ask",
"rollback running-config file {}".format(self.candidate_cfg),
"no terminal dont-ask",
]

try:
rollback_result = self._send_command_list(commands)
rollback_result = self._send_command_list(commands, expect_string=r"[#>]")
finally:
self.changed = True
msg = rollback_result
Expand All @@ -538,10 +543,16 @@ def _load_cfg_from_checkpoint(self):

def rollback(self):
if self.changed:
command = "rollback running-config file {}".format(self.rollback_cfg)
result = self._send_command(command)
commands = [
"terminal dont-ask",
"rollback running-config file {}".format(self.rollback_cfg),
"no terminal dont-ask",
]
result = self._send_command_list(commands, expect_string=r"[#>]")
if "completed" not in result.lower():
raise ReplaceConfigException(result)
# If hostname changes ensure Netmiko state is updated properly
self._netmiko_device.set_base_prompt()
self._copy_run_start()
self.changed = False

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@
"172.16.100.1": {
"prefix_length": 24
}
}
},
"Ethernet1/128": {
},
"ipv6": {
"2001:dead:beef::1": {
"200::2": {
"prefix_length": 128
},
"dead:beef::1": {
"prefix_length": 64
}
}
},
"Ethernet1/2": {
"ipv6": {
"2001:c0ff:ee::1": {
"prefix_length": 128
}
Expand Down
Loading

0 comments on commit 116715f

Please sign in to comment.