From db3f461485c51987c51c0395c57b5e361314faf9 Mon Sep 17 00:00:00 2001 From: David Barroso Date: Sun, 7 Feb 2016 22:27:56 +0100 Subject: [PATCH 1/9] Fixed warning when building documentation --- napalm/base.py | 53 ++++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/napalm/base.py b/napalm/base.py index 50e8a16df..92af9542d 100644 --- a/napalm/base.py +++ b/napalm/base.py @@ -261,41 +261,43 @@ def get_bgp_neighbors(self): """ Returns a dictionary of dictionaries. The keys for the first dictionary will be the vrf (global if no vrf). The inner dictionary will contain the following data for each vrf: - * router_id - * peers - another dictionary of dictionaries. Outer keys are the IPs of the neighbors. The inner keys are: - * local_as (int) - * remote_as (int) - * remote_id - peer router id - * is_up (True/False) - * is_enabled (True/False) - * description (string) - * uptime (int in seconds) - * address_family (dictionary) - A dictionary of address families available for the neighbor. So far it can - be 'ipv4' or 'ipv6' - * received_prefixes (int) - * accepted_prefixes (int) - * sent_prefixes (int) + + * router_id + * peers - another dictionary of dictionaries. Outer keys are the IPs of the neighbors. The inner keys are: + * local_as (int) + * remote_as (int) + * remote_id - peer router id + * is_up (True/False) + * is_enabled (True/False) + * description (string) + * uptime (int in seconds) + * address_family (dictionary) - A dictionary of address families available for the neighbor. So far it can\ + be 'ipv4' or 'ipv6' + * received_prefixes (int) + * accepted_prefixes (int) + * sent_prefixes (int) """ raise NotImplementedError def get_environment(self): """ Returns a dictionary where: + * fans is a dictionary of dictionaries where the key is the location and the values: - * status (boolean) - True if it's ok, false if it's broken + * status (boolean) - True if it's ok, false if it's broken * temperature is a dictionary of dictionaries where the key is the location and the values: - * temperature (float) - Temperature in celsius the sensor is reporting. - * is_alert (boolean) - True if the temperature is above the alert threshold - * is_critical (boolean) - True if the temperature is above the critical threshold + * temperature (float) - Temperature in celsius the sensor is reporting. + * is_alert (boolean) - True if the temperature is above the alert threshold + * is_critical (boolean) - True if the temperature is above the critical threshold * power is a dictionary of dictionaries where the key is the PSU id and the values: - * status (boolean) - True if it's ok, false if it's broken - * capacity (float) - Capacity in W that the power supply can support - * output (float) - Watts drawn by the system + * status (boolean) - True if it's ok, false if it's broken + * capacity (float) - Capacity in W that the power supply can support + * output (float) - Watts drawn by the system * cpu is a dictionary of dictionaries where the key is the ID and the values - * %usage + * %usage * memory is a dictionary with: - * available_ram (int) - Total amount of RAM installed in the device - * used_ram (int) - RAM in use in the device + * available_ram (int) - Total amount of RAM installed in the device + * used_ram (int) - RAM in use in the device """ raise NotImplementedError @@ -303,6 +305,7 @@ def get_interfaces_counters(self): """ Returns a dictionary of dictionaries where the first key is an interface name and the inner dictionary contains the following keys: + * tx_errors (int) * rx_errors (int) * tx_discards (int) @@ -316,7 +319,7 @@ def get_interfaces_counters(self): * tx_broadcast_packets (int) * rx_broadcast_packets (int) - Example: + Example:: { u'Ethernet2': { From f570164b3fd178fe42ad7115a2147c2afd8279c6 Mon Sep 17 00:00:00 2001 From: David Barroso Date: Sun, 7 Feb 2016 22:32:32 +0100 Subject: [PATCH 2/9] Updated documentation to reflect new supported methods for the IOS Driver --- docs/support/index.rst | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/support/index.rst b/docs/support/index.rst index 9b234db1a..baf9aff02 100644 --- a/docs/support/index.rst +++ b/docs/support/index.rst @@ -9,8 +9,8 @@ General support matrix _ EOS JunOS IOS-XR FortiOS IBM NXOS IOS ===================== ========== ============= =========== ============== ============= ============ ============ **Driver Name** eos junos iosxr fortios ibm nxos ios -**Structured data** Yes Yes No No Yes Yes No -**Minimum version** 4.15.0F 12.1 5.1.0 5.2.0 ??? 6.1 ??? +**Structured data** Yes Yes No No Yes Yes No +**Minimum version** 4.15.0F 12.1 5.1.0 5.2.0 ??? 6.1 ??? **Backend library** `pyeapi`_ `junos-eznc`_ `pyIOSXR`_ `pyFG`_ `bnclient`_ `pycsco`_ `netmiko`_ **Caveats** :doc:`eos` :doc:`fortios` :doc:`ibm` :doc:`nxos` :doc:`ios` ===================== ========== ============= =========== ============== ============= ============ ============ @@ -33,10 +33,10 @@ Configuration support matrix ===================== ========== ===== ========== ============== ============= ============== ============== _ EOS JunOS IOS-XR FortiOS IBM NXOS IOS ===================== ========== ===== ========== ============== ============= ============== ============== -**Config. replace** Yes Yes Yes Yes Yes [#c3]_ Yes No +**Config. replace** Yes Yes Yes Yes Yes [#c3]_ Yes Yes **Config. merge** Yes Yes Yes Yes Yes Yes Yes **Compare config** Yes Yes Yes [#c1]_ Yes [#c1]_ Yes [#c1]_ Yes [#c4]_ Yes -**Atomic Changes** Yes Yes Yes No [#c2]_ No [#c2]_ Yes/No [#c5]_ No [#c2]_ +**Atomic Changes** Yes Yes Yes No [#c2]_ No [#c2]_ Yes/No [#c5]_ Yes **Rollback** Yes [#c2]_ Yes Yes Yes Yes [#c2]_ Yes/No [#c5]_ Yes ===================== ========== ===== ========== ============== ============= ============== ============== @@ -56,16 +56,16 @@ Getters support matrix .. |yes| unicode:: U+02705 .. Yes .. |no| unicode:: U+0274C .. No -========================== ===== ===== ====== ======= ====== ====== ====== -_ EOS JunOS IOS-XR FortiOS IBM NXOS IOS -========================== ===== ===== ====== ======= ====== ====== ====== -**get_facts** |yes| |yes| |yes| |yes| |no| |yes| |yes| -**get_interfaces** |yes| |yes| |yes| |yes| |no| |yes| |yes| -**get_lldp_neighbors** |yes| |yes| |yes| |yes| |no| |no| |yes| -**get_bgp_neighbors** |yes| |yes| |yes| |yes| |no| |no| |yes| -**get_environment** |yes| |yes| |yes| |yes| |no| |no| |no| -**get_interface_counters** |yes| |yes| |yes| |yes| |no| |no| |no| -========================== ===== ===== ====== ======= ====== ====== ====== +=========================== ===== ===== ====== ======= ====== ====== ===== +_ EOS JunOS IOS-XR FortiOS IBM NXOS IOS +=========================== ===== ===== ====== ======= ====== ====== ===== +**get_facts** |yes| |yes| |yes| |yes| |no| |yes| |yes| +**get_interfaces** |yes| |yes| |yes| |yes| |no| |yes| |yes| +**get_lldp_neighbors** |yes| |yes| |yes| |yes| |no| |no| |yes| +**get_bgp_neighbors** |yes| |yes| |yes| |yes| |no| |no| |yes| +**get_environment** |yes| |yes| |yes| |yes| |no| |no| |yes| +**get_interfaces_counters** |yes| |yes| |yes| |yes| |no| |no| |yes| +=========================== ===== ===== ====== ======= ====== ====== ===== Caveats ------- From 37448cf1af6a5b0107122920ff5cf2fbb284acca Mon Sep 17 00:00:00 2001 From: David Barroso Date: Sun, 7 Feb 2016 23:00:17 +0100 Subject: [PATCH 3/9] Added documentation for the CLI tool cl_napalm_configure --- docs/cli.rst | 114 +++++++++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 1 + 2 files changed, 115 insertions(+) create mode 100644 docs/cli.rst diff --git a/docs/cli.rst b/docs/cli.rst new file mode 100644 index 000000000..1ff5d4067 --- /dev/null +++ b/docs/cli.rst @@ -0,0 +1,114 @@ +Command Line Tool +================= + +NAPALM ships with a simple CLI tool to help you deploying configuration to your devices directly from the shell. +It might be convenient for simple bash scripts or provisioning tools that rely on a shell. + +The usage is very simple. For example, let's do a dry run (changes will not be applied) and check the changes between +my current configuration and a new candidate configuration: + +.. code-block:: diff + + # cl_napalm_configure --user vagrant --vendor eos --strategy replace --optional_args 'port=12443' --dry-run new_good.conf localhost + Enter password: + @@ -2,30 +2,38 @@ + ! + ! boot system flash:/vEOS-lab.swi + ! + -event-handler dhclient + - trigger on-boot + - action bash sudo /mnt/flash/initialize_ma1.sh + +transceiver qsfp default-mode 4x10G + ! + -transceiver qsfp default-mode 4x10G + +hostname pyeos-unittest-changed + ! + spanning-tree mode mstp + ! + aaa authorization exec default local + ! + -aaa root secret 5 $1$b4KXboe4$yeTwqHOKscsF07WGoOnZ0. + +no aaa root + ! + -username admin privilege 15 role network-admin secret 5 $1$nT3t1LkI$1f.SG5YaRo6h4LlhIKgTK. + -username vagrant privilege 15 role network-admin secret 5 $1$589CDTZ0$9S4LGAiCpxHCOC17jECxt1 + +username admin privilege 15 role network-admin secret 5 $1$RT/92Zg9$J8wD1qPAdQBcOhv4fefyt. + +username vagrant privilege 15 role network-admin secret 5 $1$Lw2STh4k$bPEDVVTY2e7lf.vNlnNEO0 + ! + interface Ethernet1 + ! + interface Ethernet2 + + description ble + ! + interface Management1 + ip address 10.0.2.15/24 + ! + no ip routing + ! + +router bgp 65000 + + vrf test + + neighbor 1.1.1.2 remote-as 1 + + neighbor 1.1.1.2 maximum-routes 12000 + + ! + + vrf test2 + + neighbor 2.2.2.3 remote-as 2 + + neighbor 2.2.2.3 maximum-routes 12000 + +! + management api http-commands + no shutdown + ! + # + +We got the diff back. Now let's try a partial configuration instead. However, this time we will directly apply the +configuration and we will also be passing the password directly as an argument: + +.. code-block:: diff + + # cl_napalm_configure --user vagrant --password vagrant --vendor eos --strategy merge --optional_args 'port=12443' merge_good.conf localhost + @@ -7,6 +7,8 @@ + action bash sudo /mnt/flash/initialize_ma1.sh + ! + transceiver qsfp default-mode 4x10G + +! + +hostname NEWHOSTNAME + ! + spanning-tree mode mstp + ! + @@ -20,6 +22,7 @@ + interface Ethernet1 + ! + interface Ethernet2 + + description BLALALAL + ! + interface Management1 + ip address 10.0.2.15/24 + # + +We got the diff back in the stdout. If we try to run the command we should get an empty string: + +.. code-block:: diff + + # cl_napalm_configure --user vagrant --password vagrant --vendor eos --strategy merge --optional_args 'port=12443' merge_good.conf localhost + # + +Errors are detected as well:: + + # cl_napalm_configure --user vagrant --password vagrant --vendor eos --strategy merge --optional_args 'port=12443' merge_typo.conf localhost + Traceback (most recent call last): + File "/Users/dbarroso/.virtualenvs/test/bin/cl_napalm_configure", line 9, in + load_entry_point('napalm==0.50.3', 'console_scripts', 'cl_napalm_configure')() + File "/Users/dbarroso/.virtualenvs/test/lib/python2.7/site-packages/napalm-0.50.3-py2.7.egg/napalm/clitools/cl_napalm_configure.py", line 139, in main + args.optional_args, args.config_file, args.dry_run)) + File "/Users/dbarroso/.virtualenvs/test/lib/python2.7/site-packages/napalm-0.50.3-py2.7.egg/napalm/clitools/cl_napalm_configure.py", line 131, in run + return diff + File "/Users/dbarroso/.virtualenvs/test/lib/python2.7/site-packages/napalm-0.50.3-py2.7.egg/napalm/base.py", line 46, in __exit__ + self.__raise_clean_exception(exc_type, exc_value, exc_traceback) + File "/Users/dbarroso/.virtualenvs/test/lib/python2.7/site-packages/napalm-0.50.3-py2.7.egg/napalm/clitools/cl_napalm_configure.py", line 119, in run + strategy_method(filename=config_file) + File "/Users/dbarroso/.virtualenvs/test/lib/python2.7/site-packages/napalm-0.50.3-py2.7.egg/napalm/eos.py", line 95, in load_merge_candidate + self._load_config(filename, config, False) + File "/Users/dbarroso/.virtualenvs/test/lib/python2.7/site-packages/napalm-0.50.3-py2.7.egg/napalm/eos.py", line 89, in _load_config + raise MergeConfigException(e.message) + napalm.exceptions.MergeConfigException: Error [1002]: CLI command 5 of 5 'descriptin BLALALAL' failed: invalid command + +For more information, run ```cl_napalm_configure --help```. diff --git a/docs/index.rst b/docs/index.rst index f0c04624c..92dba9f60 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -40,4 +40,5 @@ Documentation tutorials/index support/index + cli base From 8d68e7592ffbe914d28a07dfc0ea245f887b466f Mon Sep 17 00:00:00 2001 From: David Barroso Date: Sun, 7 Feb 2016 23:02:40 +0100 Subject: [PATCH 4/9] Updated documentation, IOS supports optional_args[port] --- docs/support/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/support/index.rst b/docs/support/index.rst index baf9aff02..5c37531f2 100644 --- a/docs/support/index.rst +++ b/docs/support/index.rst @@ -95,7 +95,7 @@ List of supported optional arguments ____________________________________ * :code:`fortios_vdom` (fortios) - VDOM to connect to. - * :code:`port` (eos, iosxr, junos) - Allows you to specify a port other than the default. + * :code:`port` (eos, iosxr, junos, ios) - Allows you to specify a port other than the default. Adding optional arguments to NAPALM drivers ___________________________________________ From 9de1d0730800c8c71b48853f52782d4daf5e619d Mon Sep 17 00:00:00 2001 From: David Barroso Date: Sun, 7 Feb 2016 23:05:48 +0100 Subject: [PATCH 5/9] Fixed warnings when building documentation --- docs/support/ibm.rst | 2 +- docs/support/nxos.rst | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/support/ibm.rst b/docs/support/ibm.rst index 6225844c7..cb43d9983 100644 --- a/docs/support/ibm.rst +++ b/docs/support/ibm.rst @@ -1,5 +1,5 @@ IBM Networking Operating System -------- +------------------------------- Rollback ~~~~~~~~ diff --git a/docs/support/nxos.rst b/docs/support/nxos.rst index 1e5f7e85e..0674a276e 100644 --- a/docs/support/nxos.rst +++ b/docs/support/nxos.rst @@ -17,6 +17,7 @@ _____________ Your device must be running NXOS 6.1. The features ``nxapi`` server ``scp-server`` must be enabled. On the device and any checkpoint file you push, you must have the lines:: + feature scp-server feature nxapi @@ -31,7 +32,7 @@ function in the ``napalm.nxos`` driver. Known gotchas _____________ -- Leaving out a ``shutdown`` or ``no shutdown`` line will cause the switch to toggle the up/down state of an interface, depending on it's current state. +- Leaving out a ``shutdown`` or ``no shutdown`` line will cause the switch to toggle the up/down state of an interface, depending on it's current state. - ``!#switchport trunk allowed vlan 1-4094`` is required even if the switchport is in ``switchport mode access``. However if ``!#switchport trunk allowed vlan 1-4094`` is included with ``no switchport``, the configuration replacement will fail. From 766c0844bc5986823b646f78189f8e239015ba3a Mon Sep 17 00:00:00 2001 From: David Barroso Date: Sun, 7 Feb 2016 23:13:14 +0100 Subject: [PATCH 6/9] Fixed warnings when building documentation --- docs/cli.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cli.rst b/docs/cli.rst index 1ff5d4067..df75d96df 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -111,4 +111,4 @@ Errors are detected as well:: raise MergeConfigException(e.message) napalm.exceptions.MergeConfigException: Error [1002]: CLI command 5 of 5 'descriptin BLALALAL' failed: invalid command -For more information, run ```cl_napalm_configure --help```. +For more information, run ``cl_napalm_configure --help``. From f8ac4fc9212f0410376967a0144a0283f08c513e Mon Sep 17 00:00:00 2001 From: David Barroso Date: Sun, 7 Feb 2016 23:15:54 +0100 Subject: [PATCH 7/9] Updated copyright year --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index f4b23e777..d8336ea4a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -48,7 +48,7 @@ # General information about the project. project = u'NAPALM' -copyright = u'2015, David Barroso' +copyright = u'2016, David Barroso' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the From 5aa0b0f549a1450546c9a3914f463a4a883b75a7 Mon Sep 17 00:00:00 2001 From: David Barroso Date: Mon, 8 Feb 2016 09:20:37 +0100 Subject: [PATCH 8/9] Added Context Manager documentation --- docs/tutorials/context_manager.rst | 18 ++++++++++++++++++ docs/tutorials/first_steps_config.rst | 8 +++++++- docs/tutorials/index.rst | 1 + 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 docs/tutorials/context_manager.rst diff --git a/docs/tutorials/context_manager.rst b/docs/tutorials/context_manager.rst new file mode 100644 index 000000000..015f7eabf --- /dev/null +++ b/docs/tutorials/context_manager.rst @@ -0,0 +1,18 @@ +Context Manager +=============== + +In the previous tutorial we used the methods ``open()`` to connect to the device and ``close()`` to disconnect. +Using those methods are useful if you want to do complex or asynchronous code. However, for most situations you should +try to stick with the context manager. It handles opening and closing the session automatically and it's the +pythonic way: + +.. code-block:: python + +>>> from napalm import get_network_driver +>>> driver = get_network_driver('eos') +>>> with driver('localhost', 'vagrant', 'vagrant', optional_args={'port': 12443}) as device: +... print device.get_facts() +... print device.get_interfaces_counters() +... +{'os_version': u'4.15.2.1F-2759627.41521F', 'uptime': 2010, 'interface_list': [u'Ethernet1', u'Ethernet2', u'Management1'], 'vendor': u'Arista', 'serial_number': u'', 'model': u'vEOS', 'hostname': u'NEWHOSTNAME', 'fqdn': u'NEWHOSTNAME'} +{u'Ethernet2': {'tx_multicast_packets': 1028, 'tx_discards': 0, 'tx_octets': 130744, 'tx_errors': 0, 'rx_octets': 0, 'tx_unicast_packets': 0, 'rx_errors': 0, 'tx_broadcast_packets': 0, 'rx_multicast_packets': 0, 'rx_broadcast_packets': 0, 'rx_discards': 0, 'rx_unicast_packets': 0}, u'Management1': {'tx_multicast_packets': 0, 'tx_discards': 0, 'tx_octets': 99664, 'tx_errors': 0, 'rx_octets': 105000, 'tx_unicast_packets': 773, 'rx_errors': 0, 'tx_broadcast_packets': 0, 'rx_multicast_packets': 0, 'rx_broadcast_packets': 0, 'rx_discards': 0, 'rx_unicast_packets': 0}, u'Ethernet1': {'tx_multicast_packets': 1027, 'tx_discards': 0, 'tx_octets': 130077, 'tx_errors': 0, 'rx_octets': 0, 'tx_unicast_packets': 0, 'rx_errors': 0, 'tx_broadcast_packets': 0, 'rx_multicast_packets': 0, 'rx_broadcast_packets': 0, 'rx_discards': 0, 'rx_unicast_packets': 0}} diff --git a/docs/tutorials/first_steps_config.rst b/docs/tutorials/first_steps_config.rst index 71b422f47..47263b8c8 100644 --- a/docs/tutorials/first_steps_config.rst +++ b/docs/tutorials/first_steps_config.rst @@ -13,7 +13,7 @@ Use the appropriate network driver to connect to the device:: >>> device = driver('192.168.76.10', 'dbarroso', 'this_is_not_a_secure_password') >>> device.open() -Configurations can be replaced entirely or merged into the existing device config. +Configurations can be replaced entirely or merged into the existing device config. You can load configuration either from a string or from a file. Replacing the Configuration @@ -79,3 +79,9 @@ If for some reason you committed the changes and you want to rollback:: >>> device.rollback() +Disconnecting +------------- + +To close the session with the device just do:: + + >>> device.close() diff --git a/docs/tutorials/index.rst b/docs/tutorials/index.rst index ee121cf07..c9cd5a18d 100644 --- a/docs/tutorials/index.rst +++ b/docs/tutorials/index.rst @@ -5,3 +5,4 @@ Tutorials :maxdepth: 1 first_steps_config + context_manager From 8ccae3d8fa921f0447d2dc5782e8dbc3b4afff5b Mon Sep 17 00:00:00 2001 From: David Barroso Date: Mon, 8 Feb 2016 09:21:13 +0100 Subject: [PATCH 9/9] Version 0.51 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 64d99c723..39f75e348 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ setup( name="napalm", - version="0.50.3", + version="0.51.0", packages=find_packages(), author="David Barroso", author_email="dbarrosop@dravetech.com",