Skip to content

Commit

Permalink
Merge branch 'develop' into ios_show_ip_int_brief2
Browse files Browse the repository at this point in the history
  • Loading branch information
mirceaulinic committed Jul 9, 2019
2 parents 1c1cb4f + 17b7ba2 commit 1e35c1e
Show file tree
Hide file tree
Showing 11 changed files with 183 additions and 99 deletions.
19 changes: 19 additions & 0 deletions docs/installation/index.rst
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
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
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
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
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
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
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
13 changes: 12 additions & 1 deletion napalm/nxos/nxos.py
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 @@ -1105,7 +1111,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
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
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

0 comments on commit 1e35c1e

Please sign in to comment.