diff --git a/.gitignore b/.gitignore index e850f36..6e1c6fb 100644 --- a/.gitignore +++ b/.gitignore @@ -49,6 +49,7 @@ coverage.xml # Sphinx documentation docs/_build/ +docs/*_modules/ # PyBuilder target/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f73b61..84fcc30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,66 +1,7 @@ Python Client for eAPI ====================== -## v0.3.2, 7/16/2015 +Full [release notes] [rns] hosted at readthedocs -- fixes a problem with parsing the hostname value in the system module -## v0.3.1, 6/14/2015 - -- make pyeapi compatible under Python 3.4 with all unit tests passing ok -- added socket_error property to connection to capture socket errors -- adds function to create per vlan vtep flood lists - -## v0.3.0, 5/4/2015 - -- fixes an issue with configuring stp portfast edge correctly -- fixes #13 -- fixes #11 -- added initial support for system api module -- added initial support for acl api module (standard) -- added initial api support for mlag configuration -- added tag feature to eapi.conf - -## v0.2.4, 4/30/2015 - -- adds required docs/description.rst for setup.py - -## v0.2.3, 4/29/2015 - -- fixes issue with importing syslog module on Windows - -## v0.2.2, 04/15/2015 - -- fixes an issue with eAPI error messages that do not return a data key - -## v0.2.1, 03/28/2015 - -- restores default certificate validation behavior for py2.7.9 - -## v0.2.0, 3/19/2015 - -- adds udp_port, vlans and flood_list attributes to vxlan interfaces -- renames spanningtree api module to stp for consistency -- depreciated spanningtree api module in favor of stp -- interfaces module now properly responds to hasattr calls -- fixes an issue with collecting the vxlan global flood list from the config -- fixes an issue with properly parsing portchannel configurations -- adds portfast_type attribute to stp interfaces resource - -## v0.1.1, 2/17/2015 - -- adds introspection properties to CommandError for more details (#4) -- changed the default transport from HTTP to HTTPS to align with EOS -- updates the message returned if the connection profile name is not found -- fixes connection name not copied to host parameter if host not configured -- fixes an issue where an ipinterface wasnt properly recognized -- fixes an issue where a switchport interface was propertly recognized - -## v0.1.0, 1/23/2015 - -- initial public release of pyeapi -- initial support for vlans -- initial support for interfaces -- initial support for spanningtree -- initial support for switchports -- initial support for ipinterfaces +[rns]: http://pyeapi.readthedocs.org/en/master/release-notes.html diff --git a/README.md b/README.md index c7de1d2..7d1e831 100644 --- a/README.md +++ b/README.md @@ -1,220 +1,43 @@ # Arista eAPI Python Library -[![Build Status](https://travis-ci.org/arista-eosplus/pyeapi.svg?branch=develop)](https://travis-ci.org/arista-eosplus/pyeapi) [![Coverage Status](https://coveralls.io/repos/arista-eosplus/pyeapi/badge.svg?branch=develop)](https://coveralls.io/r/arista-eosplus/pyeapi?branch=develop) +[![Build Status](https://travis-ci.org/arista-eosplus/pyeapi.svg?branch=develop)](https://travis-ci.org/arista-eosplus/pyeapi) [![Coverage Status](https://coveralls.io/repos/arista-eosplus/pyeapi/badge.svg?branch=develop)](https://coveralls.io/r/arista-eosplus/pyeapi?branch=develop) [![Documentation Status](https://readthedocs.org/projects/pyeapi/badge/?version=latest)](http://readthedocs.org/docs/pyeapi/en/latest/?badge=latest) The Python library for Arista's eAPI command API implementation provides a client API work using eAPI and communicating with EOS nodes. The Python library can be used to communicate with EOS either locally (on-box) or remotely (off-box). It uses a standard INI-style configuration file to specify one or -more nodes and connection properites. +more nodes and connection properties. The pyeapi library also provides an API layer for building native Python -objects to interact with the destination nodes. The API layer is a convienent +objects to interact with the destination nodes. The API layer is a convenient implementation for working with the EOS configuration and is extensible for -developing custom implemenations. +developing custom implementations. This library is freely provided to the open source community for building robust applications using Arista EOS. Support is provided as best effort through Github issues. -## Requirements - -* Arista EOS 4.12 or later -* Arista eAPI enabled for at least one transport (see Official EOS Config Guide - at arista.com for details) -* Python 2.7 / 3.4+ (Python 3 support is work in progress) - -# Getting Started -In order to use pyeapi, the EOS command API must be enabled using ``management -api http-commands`` configuration mode. This library supports eAPI calls over -both HTTP and UNIX Domain Sockets. Once the command API is enabled on the -destination node, create a configuration file with the node properities. - -**Note:** The default search path for the conf file is ``~/.eapi.conf`` -followed by ``/mnt/flash/eapi.conf``. This can be overridden by setting -``EAPI_CONF=`` in your environment. - -## Example eapi.conf File -Below is an example of an eAPI conf file. The conf file can contain more than -one node. Each node section must be prefaced by **connection:\** where -\ is the name of the connection. - -The following configuration options are available for defining node entries: - -* **host** - The IP address or FQDN of the remote device. If the host - parameter is omitted then the connection name is used -* **username** - The eAPI username to use for authentication (only required for - http or https connections) -* **password** - The eAPI password to use for authentication (only required for - http or https connections) -* **enablepwd** - The enable mode password if required by the destination node -* **transport** - Configures the type of transport connection to use. The - default value is _https_. Valid values are: - * socket (available in EOS 4.14.5 or later) - * http_local (available in EOS 4.14.5 or later) - * http - * https -* **port** - Configures the port to use for the eAPI connection. A default - port is used if this parameter is absent, based on the transport setting -using the following values: - * transport: http, default port: 80 - * transport: https, deafult port: 443 - * transport: https_local, default port: 8080 - * transport: socket, default port: n/a - - -_Note:_ See the EOS User Manual found at arista.com for more details on -configuring eAPI values. - -All configuration values are optional. - -``` -[connection:veos01] -username: eapi -password: password -transport: http - -[connection:veos02] -transport: http - -[connection:veos03] -transport: socket - -[connection:veos04] -host: 172.16.10.1 -username: eapi -password: password -enablepwd: itsasecret -port: 1234 -transport: https - -[connection:localhost] -transport: http_local -``` - -The above example shows different ways to define EOS node connections. All -configuration options will attempt to use default values if not explicitly -defined. If the host parameter is not set for a given entry, then the -connection name will be used as the host address. - -### Configuring \[connection:localhost] - -The pyeapi library automatically installs a single default configuration entry -for connecting to localhost host using a transport of sockets. If using the -pyeapi library locally on an EOS node, simply enable the command API to use -sockets and no further configuration is needed for pyeapi to function. If you -specify an entry in a conf file with the name ``[connection:localhost]``, the -values in the conf file will overwrite the default. - -## Using pyeapi -The Python client for eAPI was designed to be easy to use and implement for -writing tools and applications that interface with the Arista EOS management -plane. - -### Creating a connection and sending commands -Once EOS is configured properly and the config file created, getting started -with a connection to EOS is simple. Below demonstrates a basic connection -using pyeapi. For more examples, please see the examples folder. - -``` -# start by importing the library -import pyeapi - -# create a node object by specifying the node to work with -node = pyeapi.connect_to('veos01') - -# send one or more commands to the node -node.enable('show hostname') -[{'command': 'show hostname', 'result': {u'hostname': u'veos01', u'fqdn': -u'veos01.arista.com'}, 'encoding': 'json'}] - -# use the config method to send configuration commands -node.config('hostname veos01') -[{}] - -# multiple commands can be sent by using a list (works for both enable or -config) -node.config(['interface Ethernet1', 'description foo']) -[{}, {}] - -# return the running or startup configuration from the node (output omitted for -brevity) -node.running_config - -node.startup_config -``` - -### Using the API - -The pyeapi library provides both a client for send and receiving commands over -eAPI as well as an API for working directly with EOS resources. The API is -designed to be easy and straightforward to use yet also extensible. Below is -an example of working with the ``vlans`` API - -``` -# create a connection to the node -import pyeapi -node = pyeapi.connect_to('veos01') - -# get the instance of the API (in this case vlans) -vlans = node.api('vlans') +## Documentation -# return all vlans from the node -vlans.getall() -{'1': {'state': 'active', 'name': 'default', 'vlan_id': 1, 'trunk_groups': []}, -'10': {'state': 'active', 'name': 'VLAN0010', 'vlan_id': 10, 'trunk_groups': -[]}} - -# return a specific vlan from the node -vlans.get(1) -{'state': 'active', 'name': 'default', 'vlan_id': 1, 'trunk_groups': []} - -# add a new vlan to the node -vlans.create(100) -True - -# set the new vlan name -vlans.set_name(100, 'foo') -True -``` - -All API implementations developed by Arista EOS+ CS are found in the pyeapi/api -folder. See the examples folder for additional examples. - -# Installation - -The source code for pyeapi is provided on Github at -http://github.com/arista-eosplus/pyeapi. All current development is done in -the develop branch. Stable released versions are tagged in the master branch -and uploaded to PyPi. +* [Quickstart] [quickstart] +* [Installation] [install] +* [Modules] [modules] +* [Release Notes] [rns] +* [Contribute] [contribute] -* To install the latest stable version of pyeapi, simply run ``pip install - pyeapi`` (or ``pip install --upgrade pyeapi``) -* To install the latest development version from Github, simply clone the - develop branch and run ``python setup.py install`` - -# Testing -The pyeapi library provides both unit tests and system tests. The unit tests -can be run without an EOS node. To run the system tests, you will need to -update the ``dut.conf`` file found in test/fixtures. +### Building Local Documentation -* To run the unit tests, simply run ``make unittest`` from the root of the - pyeapi source folder -* To run the system tests, simply run ``make systest`` from the root of the - pyeapi source fodler -* To run all tests, use ``make tests`` from the root of the pyeapi source - folder +If you cannot access readthedocs.org you have the option of building the +documentation locally. - -# Contributing - -Contributing pull requests are gladly welcomed for this repository. Please -note that all contributions that modify the library behavior require -corresponding test cases otherwise the pull request will be rejected. +1. ``pip install -r dev-requirements.txt`` +2. ``cd docs`` +3. ``make html`` +4. ``open _build/html/index.html`` # License -Copyright (c) 2014, Arista Networks EOS+ +Copyright (c) 2015, Arista Networks EOS+ All rights reserved. Redistribution and use in source and binary forms, with or without @@ -242,3 +65,11 @@ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +[pyeapi]: https://github.com/arista-eosplus/pyeapi +[quickstart]: http://pyeapi.readthedocs.org/en/master/quickstart.html +[install]: http://pyeapi.readthedocs.org/en/master/install.html +[contribute]: http://pyeapi.readthedocs.org/en/master/contribute.html +[modules]: http://pyeapi.readthedocs.org/en/master/modules.html +[support]: http://pyeapi.readthedocs.org/en/master/support.html +[rns]: http://pyeapi.readthedocs.org/en/master/release-notes.html diff --git a/docs/Makefile b/docs/Makefile index d1d0fa5..da55edf 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -6,6 +6,9 @@ SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build +APIDIR = api_modules +CLIENTDIR = client_modules +CWD := $(shell pwd) # User-friendly check for sphinx-build ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) @@ -48,12 +51,19 @@ help: clean: rm -rf $(BUILDDIR)/* + rm -rf $(CLIENTDIR)/* + rm -rf $(APIDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." +modules: + python $(CWD)/generate_modules.py + +docs: clean modules html + dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo diff --git a/docs/conf.py b/docs/conf.py old mode 100644 new mode 100755 index 205c966..c0540be --- a/docs/conf.py +++ b/docs/conf.py @@ -33,6 +33,8 @@ 'sphinx.ext.autodoc', 'sphinx.ext.coverage', 'sphinx.ext.viewcode', + 'sphinx.ext.doctest', + 'sphinxcontrib.napoleon' ] # Add any paths that contain templates here, relative to this directory. diff --git a/docs/configfile.rst b/docs/configfile.rst new file mode 100644 index 0000000..b27ce5e --- /dev/null +++ b/docs/configfile.rst @@ -0,0 +1,193 @@ +.. _configfile: + +######################### +Pyeapi Configuration File +######################### + +The pyeapi configuration file is a convenient place to store node connection +information. By keeping connection information central, your pyeapi scripts +can effortlessly reference nodes without any manual import of credentials +or location information. Therefore, the pyeapi configuration file becomes +a reflection of your switch inventory and the way in which the EOS Command +API is enabled on the node. The following explains how to craft your +pyeapi configuration file to address specific implementation styles. + +.. contents:: + :depth: 2 + +******************** +eapi.conf Parameters +******************** + +The following configuration options are available for defining node entries: + +:host: The IP address or FQDN of the remote device. If the host + parameter is omitted then the connection name is used + +:username: The eAPI username to use for authentication (only required for + http or https connections) + +:password: The eAPI password to use for authentication (only required for + http or https connections) + +:enablepwd: The enable mode password if required by the destination node + +:transport: Configures the type of transport connection to use. Valid + values are: + - socket (default, available in EOS 4.14.5 or later) + - http_local (available in EOS 4.14.5 or later) + - http + - https + +:port: Configures the port to use for the eAPI connection. A default + port is used if this parameter is absent, based on the transport setting + using the following values: + - transport: http, default port: 80 + - transport: https, deafult port: 443 + - transport: http_local, default port: 8080 + - transport: socket, default port: n/a + +********************************* +When is an eapi.conf file needed? +********************************* + +It's important to understand the nuances of the pyeapi configuration file so +you can simplify your implementation. Here's a quick summary of when the +eapi.conf file is needed: + +=========== ================== =============== ======================== +Transport eapi.conf Required Script run from Authentication Required +=========== ================== =============== ======================== +http Yes On/Off-switch Yes +https Yes On/Off-switch Yes +http_local Yes On-switch only No +socket No On-switch only No +=========== ================== =============== ======================== + + +******************************** +Where should the file be placed? +******************************** + +============ ================================================= +Search Order Search Location +============ ================================================= +1 Environment Variable EAPI_CONF=/path/to/eapi.conf +2 $HOME/.eapi.conf +3 /mnt/flash/eapi.conf +============ ================================================= + +.. Note:: There is a slight difference in #2 ``.eapi.conf`` versus + #3 ``eapi.conf`` + +************************************ +eapi.conf for On-box Implementations +************************************ + +This method would be used to run a pyeapi script on-box. In this mode, eAPI +can be configured to require or not require authentication depending upon +how you enabled EOS Command API. + +Notice from the table above, that if EOS Command API Unix Sockets are enabled, +or HTTP Local, you get the benefit of not needing to pass in credentials +since the connection can only be made from localhost and it assumes the user +has already authenticated to get on the switch. + +Using Unix Sockets +================== + +This is the preferred method. The default transport for pyeapi is ``socket`` +and the default host is ``localhost``. Therefore, if running a pyeapi script +on-box and have Unix Sockets enabled, you do not need an eapi.conf, nor do you +need to pass any credentials (quite handy!). + +.. Note:: Unix Sockets are supported on EOS 4.14.5+ + +Using HTTP Local +================ + +As the table above indicates, a pyeapi configuration file is required in +``/mnt/flash/eapi.conf``. It would contain something like: + +.. code-block:: console + + [connection:localhost] + transport: http_local + +Using HTTP or HTTPS +=================== + +As the table above indicates, a pyeapi configuration file is required in +``/mnt/flash/eapi.conf``. It would contain something like: + +.. code-block:: console + + [connection:localhost] + transport: http[s] + username: admin + password: admin + +************************************* +eapi.conf for Off-box Implementations +************************************* + +This method would be used to run a pyeapi script from another server. In this +mode, eAPI will require authentication. The only real option is whether you +connect over HTTP or HTTPS. + +.. Note:: The ``socket`` and ``http_local`` transport options are not + applicable. + +Notice from the table above, that if EOS Command API Unix Sockets are enabled, +or HTTP Local, you get the benefit of not needing to pass in credentials +since the connection can only be made from localhost and it assumes the user +has already authenticated to get on the switch. + +Using HTTP or HTTPS +=================== + +As the table above indicates, a pyeapi configuration file is required in +``$HOME/.eapi.conf``. It would contain something like: + +.. code-block:: console + + [connection:veos01] + transport: http + username: paul + password: nottelling + + [connection:veos03] + transport: https + username: bob + password: mysecret + + [connection:veos04] + host: 192.168.2.10 + transport: https + username: admin + password: admin + +******************* +The DEFAULT Section +******************* + +The [DEFAULT] section can be used to gather globally applicable settings. +Say that all of your nodes use the same transport or username, you can do +something like: + +.. code-block:: console + + [connection:veos01] + + [connection:veos03] + transport: https + username: bob + password: mysecret + + [connection:veos04] + host: 192.168.2.10 + + [DEFAULT] + transport: https + username: admin + password: admin diff --git a/docs/contribute.rst b/docs/contribute.rst new file mode 100644 index 0000000..b94866f --- /dev/null +++ b/docs/contribute.rst @@ -0,0 +1,43 @@ + +########## +Contribute +########## + +The Arista EOS+ team is happy to accept community contributions to the Pyeapi +project. Please note that all contributions that modify the library behavior +require corresponding test cases otherwise the pull request will be rejected. + + +******* +Testing +******* + +The pyeapi library provides both unit tests and system tests. The unit tests +can be run without an EOS node. To run the system tests, you will need to +update the ``dut.conf`` file found in test/fixtures. + + +Unit Test +========= + +To run the unit tests, simply run ``make unittest`` from the root of the +pyeapi source folder + +System Test +=========== + +To run the system tests, simply run ``make systest`` from the root of the +pyeapi source folder. + +.. Tip:: To run all tests, use ``make tests`` from the root of the pyeapi source + folder + +******** +Coverage +******** + +Contributions should maintain 100% code coverage. You can check this locally +before submitting your Pull Request. + +1. Run ``make unittest`` +2. Run ``make coverage_report`` to confirm code coverage. diff --git a/docs/description.rst b/docs/description.rst index 454701c..01d2657 100644 --- a/docs/description.rst +++ b/docs/description.rst @@ -1,5 +1,5 @@ -Python Client for eAPI -====================== +The Python Client for eAPI +========================== The Python Client for eAPI (pyeapi) is a native Python library wrapper around Arista EOS eAPI. It provides a set of Python language bindings for configuring @@ -10,9 +10,9 @@ The Python library can be used to communicate with EOS either locally to specify one or more nodes and connection profiles. The pyeapi library also provides an API layer for building native Python -objects to interact with the destination nodes. The API layer is a convienent +objects to interact with the destination nodes. The API layer is a convenient implementation for working with the EOS configuration and is extensible for -developing custom implemenations. +developing custom implementations. This library is freely provided to the open source community for building robust applications using Arista EOS. Support is provided as best effort diff --git a/docs/generate_modules.py b/docs/generate_modules.py new file mode 100755 index 0000000..a431e34 --- /dev/null +++ b/docs/generate_modules.py @@ -0,0 +1,95 @@ +#!/usr/bin/python + +from os import listdir, path, makedirs +from os.path import isfile, join, exists +import pprint as pp + +HERE = path.abspath(path.dirname(__file__)) + +MODULES_PATH = '%s/../pyeapi/' % HERE +AUTOGEN = '.. This file has been autogenerated by generate_modules.py\n\n' + + +def get_module_names(p): + '''Accepts a path to search for modules. The method will filter on files + that end in .pyc or files that start with __. + + Arguments: + p (string): The path to search + Returns: + list of file names + ''' + mods = list() + mods = [f.split('.')[0] for f in listdir(p) + if isfile(join(p, f)) and not f.endswith('.pyc') and not f.startswith('__')] + return mods + +def process_modules(modules): + '''Accepts dictionary of 'client' and 'api' modules and creates + the corresponding files. + ''' + for mod in modules['client']: + directory = '%s/client_modules' % HERE + if not exists(directory): + makedirs(directory) + write_module_file(mod, directory, 'pyeapi') + + for mod in modules['api']: + directory = '%s/api_modules' % HERE + if not exists(directory): + makedirs(directory) + write_module_file(mod, directory, 'pyeapi.api') + + create_index(modules) + +def create_index(modules): + '''This takes a dict of modules and created the RST index file.''' + for key in modules.keys(): + file_path = join(HERE, '%s_modules/_list_of_modules.rst' % key) + list_file = open(file_path, 'w') + + # Write the generic header + list_file.write('%s\n' % AUTOGEN) + list_file.write('%s\n' % key.title()) + list_file.write('=' * len(key)) + list_file.write('\n\n') + list_file.write('.. toctree::\n') + list_file.write(' :maxdepth: 2\n\n') + + for module in modules[key]: + list_file.write(' %s\n' % module) + + +def write_module_file(name, path, package): + '''Creates an RST file for the module name passed in. It places it in the + path defined + ''' + file_path = join(path, '%s.rst' % name) + mod_file = open(file_path, 'w') + + mod_file.write('%s\n' % AUTOGEN) + mod_file.write('%s\n' % name.title()) + mod_file.write('=' * len(name)) + mod_file.write('\n\n') + mod_file.write('.. toctree::\n') + mod_file.write(' :maxdepth: 1\n\n') + mod_file.write('.. automodule:: %s.%s\n' % (package, name)) + mod_file.write(' :members:\n') + mod_file.write(' :undoc-members:\n') + mod_file.write(' :show-inheritance:\n') + +def main(): + modules = dict(client=None, api=None) + modules['client'] = get_module_names(MODULES_PATH) + modules['api'] = get_module_names('%s/api' % MODULES_PATH) + modules['client'].sort() + modules['api'].sort() + process_modules(modules) + + + + + + +if __name__ == '__main__': + main() diff --git a/docs/index.rst b/docs/index.rst index df6420a..f2aeb5c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,27 +1,44 @@ -.. Python Client for eAPI documentation master file, created by - sphinx-quickstart on Tue Mar 24 21:01:31 2015. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. +.. _intro: -Welcome to Python Client for eAPI's documentation! -================================================== +############ +Introduction +############ + +The Python Client for eAPI (pyeapi) is a native Python library wrapper around +Arista EOS eAPI. It provides a set of Python language bindings for configuring +Arista EOS nodes. + +The Python library can be used to communicate with EOS either locally +(on-box) or remotely (off-box). It uses a standard INI-style configuration file +to specify one or more nodes and connection profiles. + +The pyeapi library also provides an API layer for building native Python +objects to interact with the destination nodes. The API layer is a convenient +implementation for working with the EOS configuration and is extensible for +developing custom solutions. + +This library is freely provided to the open source community for building +robust applications using Arista EOS. Support is provided as best effort +through Github issues. -Contents: .. toctree:: - :maxdepth: 2 + :maxdepth: 1 - pyeapi - pyeapi.api + install + quickstart + configfile modules + requirements + contribute + release-notes + support license - +****************** Indices and tables -================== +****************** * :ref:`genindex` * :ref:`modindex` -* :ref:`search` - diff --git a/docs/install.rst b/docs/install.rst new file mode 100644 index 0000000..f40a867 --- /dev/null +++ b/docs/install.rst @@ -0,0 +1,136 @@ +.. _install: + +############ +Installation +############ + +The installation of pyeapi is straightforward and simple. As mentioned in the +:ref:`intro`, pyeapi can be run on-box or off-box. The instructions below +will provide some tips to help you for either platform. + +.. contents:: + :depth: 3 + +*********************** +Pip with Network Access +*********************** + +If your platform has internet access you can use the Python Package manager +to install pyeapi + +.. code-block:: console + + admin:~ admin$ sudo pip install pyeapi + +.. Note:: You will likely notice Pip install netaddr, a dependency of pyeapi. + + +Pip - Upgrade Pyeapi +==================== + +.. code-block:: console + + admin:~ admin$ sudo pip install --upgrade pyeapi + + +************************** +Pip without Network Access +************************** + +If you want to install pyeapi on a switch with no internet access: + +**Step 1:** Download Pypi Package + +- `Download `_ the latest version of **pyeapi** on your local machine. +- You will also need a dependency package `netaddr `_. + +**Step 2:** SCP both files to the Arista switch and install + +.. code-block:: console + + admin:~ admin$ scp path/to/pyeapi-.tar.gz ansible@veos01:/mnt/flash/ + admin:~ admin$ scp path/to/netaddr-.tar.gz ansible@veos01:/mnt/flash/ + +Then SSH into your node and install it. Be sure to replace ```` with the +actual filename: + +.. code-block:: console + + [admin@veos ~]$ sudo pip install /mnt/flash/netaddr-.tar.gz + [admin@veos ~]$ sudo pip install /mnt/flash/pyeapi-.tar.gz + +These packages must be re-installed on reboot. Therefore, add the install +commands to ``/mnt/flash/rc.eos`` to trigger the install on reboot: + +.. code-block:: console + + [admin@veos ~]$ vi /mnt/flash/rc.eos + +Add the lines (the #! may already exist in your rc.eos) + +.. code-block:: console + + #!/bin/bash + sudo pip install /mnt/flash/netaddr-.tar.gz + sudo pip install /mnt/flash/pyeapi-.tar.gz + + +************************************ +Development - Run pyeapi from Source +************************************ + +.. Tip:: We recommend running pyeapi in a virtual environment. For more + information, `read this. `_ + +These instructions will help you install and run pyeapi from source. This +is useful if you plan on contributing or if you'd always like to see the latest +code in the develop branch. + +.. Important:: These steps require Pip and Git + +**Step 1:** Clone the pyeapi Github repo + +.. code-block:: console + + # Go to a directory where you'd like to keep the source + admin:~ admin$ cd ~/projects + admin:~ admin$ git clone https://github.com/arista-eosplus/pyeapi.git + admin:~ admin$ cd pyeapi + +**Step 2:** Check out the desired version or branch + +.. code-block:: console + + # Go to a directory where you'd like to keep the source + admin:~ admin$ cd ~/projects/pyeapi + + # To see a list of available versions or branches + admin:~ admin$ git tag + admin:~ admin$ git branch + + # Checkout the desired version of code + admin:~ admin$ git checkout v0.3.3 + +**Step 3:** Install pyeapi using Pip with -e switch + +.. code-block:: console + + # Go to a directory where you'd like to keep the source + admin:~ admin$ cd ~/projects/pyeapi + + # Install + admin:~ admin$ sudo pip install -e ~/projects/pyeapi + +.. Tip:: If you start using pyeapi and get import errors, make sure your + PYTHONPATH is set to include the path to pyeapi. + + Development - Upgrade Pyeapi + ============================ + + .. code-block:: console + + admin:~ admin$ cd ~/projects/pyeapi + admin:~ admin$ git pull + +.. Note:: If you followed the directions above and used ``pip install -e``, + pip will automatically use the updated code. diff --git a/docs/modules.rst b/docs/modules.rst index 4e8c689..edac209 100644 --- a/docs/modules.rst +++ b/docs/modules.rst @@ -1,7 +1,8 @@ -pyeapi -====== +Modules +======= .. toctree:: :maxdepth: 4 - pyeapi + client_modules/_list_of_modules + api_modules/_list_of_modules diff --git a/docs/pyeapi.api.rst b/docs/pyeapi.api.rst deleted file mode 100644 index 55566e3..0000000 --- a/docs/pyeapi.api.rst +++ /dev/null @@ -1,70 +0,0 @@ -pyeapi.api package -================== - -Submodules ----------- - -pyeapi.api.abstract module --------------------------- - -.. automodule:: pyeapi.api.abstract - :members: - :undoc-members: - :show-inheritance: - -pyeapi.api.interfaces module ----------------------------- - -.. automodule:: pyeapi.api.interfaces - :members: - :undoc-members: - :show-inheritance: - -pyeapi.api.ipinterfaces module ------------------------------- - -.. automodule:: pyeapi.api.ipinterfaces - :members: - :undoc-members: - :show-inheritance: - -pyeapi.api.spanningtree module ------------------------------- - -.. automodule:: pyeapi.api.spanningtree - :members: - :undoc-members: - :show-inheritance: - -pyeapi.api.stp module ---------------------- - -.. automodule:: pyeapi.api.stp - :members: - :undoc-members: - :show-inheritance: - -pyeapi.api.switchports module ------------------------------ - -.. automodule:: pyeapi.api.switchports - :members: - :undoc-members: - :show-inheritance: - -pyeapi.api.vlans module ------------------------ - -.. automodule:: pyeapi.api.vlans - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: pyeapi.api - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/pyeapi.rst b/docs/pyeapi.rst deleted file mode 100644 index 958d2a2..0000000 --- a/docs/pyeapi.rst +++ /dev/null @@ -1,45 +0,0 @@ -pyeapi package -============== - -Subpackages ------------ - -.. toctree:: - - pyeapi.api - -Submodules ----------- - -pyeapi.client module --------------------- - -.. automodule:: pyeapi.client - :members: - :undoc-members: - :show-inheritance: - -pyeapi.eapilib module ---------------------- - -.. automodule:: pyeapi.eapilib - :members: - :undoc-members: - :show-inheritance: - -pyeapi.utils module -------------------- - -.. automodule:: pyeapi.utils - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: pyeapi - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 79aed30..bcd2d09 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -1,217 +1,114 @@ -Python Client for eAPI -====================== - -The Python library for Arista's eAPI command API implementation provides a -client API work using eAPI and communicating with EOS nodes. The Python -library can be used to communicate with EOS either locally (on-box) or remotely -(off-box). It uses a standard INI-style configuration file to specify one or -more nodes and connection properites. - -The pyeapi library also provides an API layer for building native Python -objects to interact with the destination nodes. The API layer is a convienent -implementation for working with the EOS configuration and is extensible for -developing custom implemenations. - -This library is freely provided to the open source community for building -robust applications using Arista EOS. Support is provided as best effort -through Github issues. - -## Requirements - -* Arista EOS 4.12 or later -* Arista eAPI enabled for at least one transport (see Official EOS Config Guide - at arista.com for details) -* Python 2.7 - -# Getting Started -In order to use pyeapi, the EOS command API must be enabled using ``management -api http-commands`` configuration mode. This library supports eAPI calls over -both HTTP and UNIX Domain Sockets. Once the command API is enabled on the -destination node, create a configuration file with the node properities. - -**Note:** The default search path for the conf file is ``~/.eapi.conf`` -followed by ``/mnt/flash/eapi.conf``. This can be overridden by setting -``EAPI_CONF=`` in your environment. - -## Example eapi.conf File -Below is an example of an eAPI conf file. The conf file can contain more than -one node. Each node section must be prefaced by **connection:\** where -\ is the name of the connection. - -The following configuration options are available for defining node entries: - -* **host** - The IP address or FQDN of the remote device. If the host - parameter is omitted then the connection name is used -* **username** - The eAPI username to use for authentication (only required for - http or https connections) -* **password** - The eAPI password to use for authentication (only required for - http or https connections) -* **enablepwd** - The enable mode password if required by the destination node -* **transport** - Configures the type of transport connection to use. The - default value is _https_. Valid values are: - * socket (available in EOS 4.14.5 or later) - * http_local (available in EOS 4.14.5 or later) - * http - * https -* **port** - Configures the port to use for the eAPI connection. A default - port is used if this parameter is absent, based on the transport setting -using the following values: - * transport: http, default port: 80 - * transport: https, deafult port: 443 - * transport: https_local, default port: 8080 - * transport: socket, default port: n/a - - -_Note:_ See the EOS User Manual found at arista.com for more details on -configuring eAPI values. - -All configuration values are optional. - -``` -[connection:veos01] -username: eapi -password: password -transport: http - -[connection:veos02] -transport: http - -[connection:veos03] -transport: socket - -[connection:veos04] -host: 172.16.10.1 -username: eapi -password: password -enablepwd: itsasecret -port: 1234 -transport: https - -[connection:localhost] -transport: http_local -``` - -The above example shows different ways to define EOS node connections. All -configuration options will attempt to use default values if not explicitly -defined. If the host parameter is not set for a given entry, then the -connection name will be used as the host address. - -### Configuring \[connection:localhost] - -The pyeapi library automatically installs a single default configuration entry -for connecting to localhost host using a transport of sockets. If using the -pyeapi library locally on an EOS node, simply enable the command API to use -sockets and no further configuration is needed for pyeapi to function. If you -specify an entry in a conf file with the name ``[connection:localhost]``, the -values in the conf file will overwrite the default. - -## Using pyeapi +########## +Quickstart +########## + +In order to use pyeapi, the EOS command API must be enabled using configuration +mode. This library supports eAPI calls over both HTTP/S and UNIX Domain +Sockets. Once the command API is enabled on the destination node, create a +configuration file with the node properties. There are some nuances about the +configuration file that are important to understand; take a minute and read +about the :ref:`configfile`. + +********************** +Enable EOS Command API +********************** + +Refer to your official Arista EOS Configuration Guide to learn how to enable +EOS Command API. Depending upon your software version, the options available +include: + - HTTP + - HTTPS + - HTTP Local + - Unix Socket + +************** +Install Pyeapi +************** + +Follow the instructions on the :ref:`install` guide to prepare your node for +pyeapi. + +************************ +Create an eapi.conf file +************************ + +Follow the instructions on the :ref:`configfile` guide to create a pyeapi +configuration file. You can skip this step if you are running the pyeapi +script on-box and Unix Sockets are enabled for EOS Command API. + +***************** +Connect to a Node +***************** + The Python client for eAPI was designed to be easy to use and implement for writing tools and applications that interface with the Arista EOS management -plane. +plane. -### Creating a connection and sending commands Once EOS is configured properly and the config file created, getting started with a connection to EOS is simple. Below demonstrates a basic connection -using pyeapi. For more examples, please see the examples folder. +using pyeapi. For more examples, please see the +`examples `_ +folder on Github. + +This first example shows how to instantiate the Node object. The Node object +provides some helpful methods and attributes to work with the switch. -``` -# start by importing the library -import pyeapi +.. code-block:: python -# create a node object by specifying the node to work with -node = pyeapi.connect_to('veos01') + # start by importing the library + import pyeapi -# send one or more commands to the node -node.enable('show hostname') -[{'command': 'show hostname', 'result': {u'hostname': u'veos01', u'fqdn': -u'veos01.arista.com'}, 'encoding': 'json'}] + # create a node object by specifying the node to work with + node = pyeapi.connect_to('veos01') -# use the config method to send configuration commands -node.config('hostname veos01') -[{}] + # send one or more commands to the node + node.enable('show hostname') + [{'command': 'show hostname', 'result': {u'hostname': u'veos01', u'fqdn': + u'veos01.arista.com'}, 'encoding': 'json'}] -# multiple commands can be sent by using a list (works for both enable or -config) -node.config(['interface Ethernet1', 'description foo']) -[{}, {}] + # use the config method to send configuration commands + node.config('hostname veos01') + [{}] -# return the running or startup configuration from the node (output omitted for -brevity) -node.running_config + # multiple commands can be sent by using a list + # (works for both enable or config) + node.config(['interface Ethernet1', 'description foo']) + [{}, {}] -node.startup_config -``` + # return the running or startup configuration from the + # node (output omitted for brevity) + node.running_config -### Using the API + node.startup_config The pyeapi library provides both a client for send and receiving commands over eAPI as well as an API for working directly with EOS resources. The API is designed to be easy and straightforward to use yet also extensible. Below is an example of working with the ``vlans`` API -``` -# create a connection to the node -import pyeapi -node = pyeapi.connect_to('veos01') - -# get the instance of the API (in this case vlans) -vlans = node.api('vlans') - -# return all vlans from the node -vlans.getall() -{'1': {'state': 'active', 'name': 'default', 'vlan_id': 1, 'trunk_groups': []}, -'10': {'state': 'active', 'name': 'VLAN0010', 'vlan_id': 10, 'trunk_groups': -[]}} - -# return a specific vlan from the node -vlans.get(1) -{'state': 'active', 'name': 'default', 'vlan_id': 1, 'trunk_groups': []} - -# add a new vlan to the node -vlans.create(100) -True - -# set the new vlan name -vlans.set_name(100, 'foo') -True -``` - -All API implementations developed by Arista EOS+ CS are found in the pyeapi/api -folder. See the examples folder for additional examples. - -# Installation - -The source code for pyeapi is provided on Github at -http://github.com/arista-eosplus/pyeapi. All current development is done in -the develop branch. Stable released versions are tagged in the master branch -and uploaded to PyPi. - -* To install the latest stable version of pyeapi, simply run ``pip install - pyeapi`` (or ``pip install --upgrade pyeapi``) -* To install the latest development version from Github, simply clone the - develop branch and run ``python setup.py install`` - -# Testing -The pyeapi library provides both unit tests and system tests. The unit tests -can be run without an EOS node. To run the system tests, you will need to -update the ``dut.conf`` file found in test/fixtures. - -* To run the unit tests, simply run ``make unittest`` from the root of the - pyeapi source folder -* To run the system tests, simply run ``make systest`` from the root of the - pyeapi source fodler -* To run all tests, use ``make tests`` from the root of the pyeapi source - folder +.. code-block:: python + # create a connection to the node + import pyeapi + node = pyeapi.connect_to('veos01') -# Contributing + # get the instance of the API (in this case vlans) + vlans = node.api('vlans') -Contributing pull requests are gladly welcomed for this repository. Please -note that all contributions that modify the library behavior require -corresponding test cases otherwise the pull request will be rejected. + # return all vlans from the node + vlans.getall() + {'1': {'state': 'active', 'name': 'default', 'vlan_id': 1, 'trunk_groups': []}, + '10': {'state': 'active', 'name': 'VLAN0010', 'vlan_id': 10, 'trunk_groups': + []}} -# License + # return a specific vlan from the node + vlans.get(1) + {'state': 'active', 'name': 'default', 'vlan_id': 1, 'trunk_groups': []} -New BSD, See [LICENSE](LICENSE) file + # add a new vlan to the node + vlans.create(100) + True + # set the new vlan name + vlans.set_name(100, 'foo') + True diff --git a/docs/release-notes-0.1.0.rst b/docs/release-notes-0.1.0.rst new file mode 100644 index 0000000..1dfb56f --- /dev/null +++ b/docs/release-notes-0.1.0.rst @@ -0,0 +1,12 @@ +###### +v0.1.0 +###### + +2015-01-23 + +- initial public release of pyeapi +- initial support for vlans +- initial support for interfaces +- initial support for spanningtree +- initial support for switchports +- initial support for ipinterfaces diff --git a/docs/release-notes-0.1.1.rst b/docs/release-notes-0.1.1.rst new file mode 100644 index 0000000..bd50d6c --- /dev/null +++ b/docs/release-notes-0.1.1.rst @@ -0,0 +1,12 @@ +###### +v0.1.1 +###### + +2015-02-17 + +- adds introspection properties to CommandError for more details (#4) +- changed the default transport from HTTP to HTTPS to align with EOS +- updates the message returned if the connection profile name is not found +- fixes connection name not copied to host parameter if host not configured +- fixes an issue where an ipinterface wasnt properly recognized +- fixes an issue where a switchport interface was propertly recognized diff --git a/docs/release-notes-0.2.0.rst b/docs/release-notes-0.2.0.rst new file mode 100644 index 0000000..0ca95fd --- /dev/null +++ b/docs/release-notes-0.2.0.rst @@ -0,0 +1,13 @@ +###### +v0.2.0 +###### + +2015-03-19 + +- adds udp_port, vlans and flood_list attributes to vxlan interfaces +- renames spanningtree api module to stp for consistency +- depreciated spanningtree api module in favor of stp +- interfaces module now properly responds to hasattr calls +- fixes an issue with collecting the vxlan global flood list from the config +- fixes an issue with properly parsing portchannel configurations +- adds portfast_type attribute to stp interfaces resource diff --git a/docs/release-notes-0.2.1.rst b/docs/release-notes-0.2.1.rst new file mode 100644 index 0000000..8f4a340 --- /dev/null +++ b/docs/release-notes-0.2.1.rst @@ -0,0 +1,7 @@ +###### +v0.2.1 +###### + +2015-03-28 + +- restores default certificate validation behavior for py2.7.9 diff --git a/docs/release-notes-0.2.2.rst b/docs/release-notes-0.2.2.rst new file mode 100644 index 0000000..b23a08c --- /dev/null +++ b/docs/release-notes-0.2.2.rst @@ -0,0 +1,7 @@ +###### +v0.2.2 +###### + +2015-04-15 + +- fixes an issue with eAPI error messages that do not return a data key diff --git a/docs/release-notes-0.2.3.rst b/docs/release-notes-0.2.3.rst new file mode 100644 index 0000000..565b5a3 --- /dev/null +++ b/docs/release-notes-0.2.3.rst @@ -0,0 +1,7 @@ +###### +v0.2.3 +###### + +2015-04-29 + +- fixes issue with importing syslog module on Windows diff --git a/docs/release-notes-0.2.4.rst b/docs/release-notes-0.2.4.rst new file mode 100644 index 0000000..efd8ec5 --- /dev/null +++ b/docs/release-notes-0.2.4.rst @@ -0,0 +1,7 @@ +###### +v0.2.4 +###### + +2015-04-30 + +- adds required docs/description.rst for setup.py diff --git a/docs/release-notes-0.3.0.rst b/docs/release-notes-0.3.0.rst new file mode 100644 index 0000000..03d74aa --- /dev/null +++ b/docs/release-notes-0.3.0.rst @@ -0,0 +1,13 @@ +###### +v0.3.0 +###### + +2015-05-04 + +- fixes an issue with configuring stp portfast edge correctly +- fixes #13 +- fixes #11 +- added initial support for system api module +- added initial support for acl api module (standard) +- added initial api support for mlag configuration +- added tag feature to eapi.conf diff --git a/docs/release-notes-0.3.1.rst b/docs/release-notes-0.3.1.rst new file mode 100644 index 0000000..8101cbc --- /dev/null +++ b/docs/release-notes-0.3.1.rst @@ -0,0 +1,9 @@ +###### +v0.3.1 +###### + +2015-06-14 + +- make pyeapi compatible under Python 3.4 with all unit tests passing ok +- added socket_error property to connection to capture socket errors +- adds function to create per vlan vtep flood lists diff --git a/docs/release-notes-0.3.2.rst b/docs/release-notes-0.3.2.rst new file mode 100644 index 0000000..621d255 --- /dev/null +++ b/docs/release-notes-0.3.2.rst @@ -0,0 +1,7 @@ +###### +v0.3.2 +###### + +2015-07-16 + +- fixes a problem with parsing the hostname value in the system module diff --git a/docs/release-notes-0.3.3.rst b/docs/release-notes-0.3.3.rst new file mode 100644 index 0000000..93d034c --- /dev/null +++ b/docs/release-notes-0.3.3.rst @@ -0,0 +1,9 @@ +###### +v0.3.3 +###### + +2015-07-31 + +- added initial support for bgp api module +- add trunk group functionality to switchports +- add ip routing to system api diff --git a/docs/release-notes-0.4.0.rst b/docs/release-notes-0.4.0.rst new file mode 100644 index 0000000..68e357c --- /dev/null +++ b/docs/release-notes-0.4.0.rst @@ -0,0 +1,53 @@ +###### +v0.4.0 +###### + +2015-11-03 + +New APIs +^^^^^^^^ + +* Add support for vrrp api (`57 `_) [`grybak `_] + .. comment +* Add support for staticroute api (`45 `_) [`grybak `_] + The staticroute API enables you to set static IPv4 routes on your EOS device. +* Add support for varp api (`43 `_) [`phil-arista `_] + The Varp API includes the subclass VarpInterfaces. These two combine to provide methods to set virtual IP addresses on interfaces as well as set the global virtual-router mac-address. +* Add support for routemap api (`40 `_) [`phil-arista `_] + .. comment + +Enhancements +^^^^^^^^^^^^ + +* Making configure RADIUS compatible (`53 `_) [`GaryCarneiro `_] + Modifies the syntax of the ``config`` method to use ``configure terminal`` instead of just ``configure``. +* Add lacp mode to set_members() method (`47 `_) [`phil-arista `_] + This enhancement allows you to set the LACP Mode while executing the set_members method. The call would look like ``node.api('interfaces').set_members(1, [Ethernet1,Ethernet2], mode='active')`` +* Added support to specify timeout (`41 `_) [`dbarrosop `_] + This enhancement provides a way to specify a connection timeout. The default is set to 60 seconds. +* Add BGP maximum-paths support (`36 `_) [`phil-arista `_] + This enhancement adds more attributes to ``eos_bgp_config``. This provides the ability to configure ``maximum-paths N ecmp M`` in your ``router bgp R`` configuration. +* Add sshkey support to users API (`34 `_) [`phil-arista `_] + This enhancement augments the ``users`` API to now support SSH Keys. + +Fixed +^^^^^ + +* client.py 'def enable' returned dictionary key inconsistency (`35 `_) + The key that's supposed to be returned is ``result`` but instead the method formerly returned the key ``response``. For now, both ``response`` and ``result`` will be returned with the same data, but ``response`` will be removed in a future release. +* [API Users] Can't run set_role with no value (`33 `_) + The node.api('users').set_role('test') method didn't remove the role or default the role as you would expect. This bug fix resolves that. +* [API Users] Can't run set_privilege with no value (`32 `_) + The set_privilege('user') method did not properly negate the privilege level when no argument was passed into the method. +* [ API interfaces ] get_members regex wrongly includes PeerEthernet when lag is up (`28 `_) + The get_members() method wrongly included a duplicate member when the ``show port-channel N all-ports`` showed the PeerEthernetX. The regular expression has been updated to ignore these entries. +* [API] users - can't create password with non-alpha/int characters (`23 `_) + The characters ``(){}[]`` cannot be part of a username. Documentation has been updated to reflect this. +* Users with sha512 passwords don't get processed correctly using api('users').getall() (`22 `_) + Fixed regex to extract the encrypted passwords accurately. + +Known Caveats +^^^^^^^^^^^^^ + +* failure when eapi.conf is not formatted correctly (`38 `_) + .. comment diff --git a/docs/release-notes.rst b/docs/release-notes.rst new file mode 100644 index 0000000..a4591ec --- /dev/null +++ b/docs/release-notes.rst @@ -0,0 +1,20 @@ +############# +Release Notes +############# + +.. toctree:: + :maxdepth: 2 + :titlesonly: + + release-notes-0.1.0.rst + release-notes-0.1.1.rst + release-notes-0.2.0.rst + release-notes-0.2.1.rst + release-notes-0.2.2.rst + release-notes-0.2.3.rst + release-notes-0.2.4.rst + release-notes-0.3.0.rst + release-notes-0.3.1.rst + release-notes-0.3.2.rst + release-notes-0.3.3.rst + release-notes-0.4.0.rst diff --git a/docs/requirements.rst b/docs/requirements.rst new file mode 100644 index 0000000..fe7cb19 --- /dev/null +++ b/docs/requirements.rst @@ -0,0 +1,11 @@ +############ +Requirements +############ + +* Arista EOS 4.12 or later +* Arista eAPI enabled for at least one transport (see Official EOS Config Guide + at arista.com for details) +* Python 2.7 or 3.4+ (Python 3 support is work in progress) +* Pyeapi requires the netaddr Python module + +.. Note:: netaddr gets installed automatically if you use pip to install pyeapi diff --git a/docs/support.rst b/docs/support.rst new file mode 100644 index 0000000..282f366 --- /dev/null +++ b/docs/support.rst @@ -0,0 +1,33 @@ +####### +Support +####### + +******* +Contact +******* + +Pyeapi is developed by Arista EOS+ CS and supported by the Arista +EOS+ community. Support for the code is provided on a best effort basis by the +Arista EOS+ CS team and the community. You can contact the team that develops +these modules by sending an email to eosplus-dev@arista.com. + +For customers that are looking for a premium level of support, please contact +your local account team or email eosplus@arista.com for help. + +***************** +Submitting Issues +***************** + +The Arista EOS+ CS development team uses Github Issues to track discovered +bugs and enhancement requests. The issues tracker can +be found at https://github.com/arista-eosplus/pyeapi/issues. + +For defect issues, please provide as much relevant data as possible as to what +is causing the issue, if and how it is reproducible, the version of EOS, python, +and any OS details. + +For enhancement requests, please provide a brief description of the +enhancement request and the version of EOS to be supported. + +The issue tracker is monitored by Arista EOS+ CS and issues submitted are +categorized and scheduled for inclusion in upcoming Pyeapi versions. diff --git a/pyeapi/api/interfaces.py b/pyeapi/api/interfaces.py index 4326879..9228e23 100644 --- a/pyeapi/api/interfaces.py +++ b/pyeapi/api/interfaces.py @@ -92,15 +92,15 @@ def get(self, name): def getall(self): """Returns all interfaces in a dict object. - Example: - { - "Ethernet1": {...}, - "Ethernet2": {...} - } - Returns: A Python dictionary object containing all interface - configuration indexed by interface name + configuration indexed by interface name:: + + { + "Ethernet1": {...}, + "Ethernet2": {...} + } + """ interfaces_re = re.compile(r'(?<=^interface\s)(.+)$', re.M) @@ -303,15 +303,6 @@ def __str__(self): def get(self, name): """Returns an interface as a set of key/value pairs - Example: - { - "name": , - "type": "ethernet", - "sflow": [true, false], - "flowcontrol_send": [on, off], - "flowcontrol_receive": [on, off] - } - Args: name (string): the interface identifier to retrieve the from the configuration @@ -319,7 +310,15 @@ def get(self, name): Returns: A Python dictionary object of key/value pairs that represent the current configuration for the specified node. If the - specified interface name does not exist, then None is returned. + specified interface name does not exist, then None is returned:: + + { + "name": , + "type": "ethernet", + "sflow": [true, false], + "flowcontrol_send": [on, off], + "flowcontrol_receive": [on, off] + } """ config = self.get_block('^interface %s' % name) @@ -509,23 +508,23 @@ def __str__(self): def get(self, name): """Returns a Port-Channel interface as a set of key/value pairs - Example: - { - "name": , - "type": "portchannel", - "members": , - "minimum_links: , - "lacp_mode": [on, active, passive] - } - Args: name (str): The interface identifier to retrieve from the running-configuration Returns: A Python dictionary object of key/value pairs that represents - the interface configuration. If the specified interface - does not exist, then None is returned + the interface configuration. If the specified interface + does not exist, then None is returned:: + + { + "name": , + "type": "portchannel", + "members": , + "minimum_links: , + "lacp_mode": [on, active, passive] + } + """ config = self.get_block('^interface %s' % name) if not config: diff --git a/pyeapi/api/ipinterfaces.py b/pyeapi/api/ipinterfaces.py index d53a359..9b8d750 100644 --- a/pyeapi/api/ipinterfaces.py +++ b/pyeapi/api/ipinterfaces.py @@ -120,16 +120,15 @@ def _parse_mtu(self, config): def getall(self): """ Returns all of the IP interfaces found in the running-config - Example: - { - 'Ethernet1': {...}, - 'Ethernet2': {...} - } - Returns: A Python dictionary object of key/value pairs keyed by interface - name that represents all of the IP interfaces on - the current node. + name that represents all of the IP interfaces on + the current node:: + + { + 'Ethernet1': {...}, + 'Ethernet2': {...} + } """ interfaces_re = re.compile(r'^interface\s(.+)', re.M) diff --git a/pyeapi/api/routemaps.py b/pyeapi/api/routemaps.py index 34f504d..b1b10d7 100644 --- a/pyeapi/api/routemaps.py +++ b/pyeapi/api/routemaps.py @@ -36,17 +36,6 @@ * Routemaps - Configures routemaps in EOS -Routemaps Attributes: - name (string): The name given to the routemap clause - action (string): How the clause will filter the route. Typically - permit or deny. - seqno (integer): The sequence number of this clause - description (string): A description for the routemap clause - set (list): The list of set statements present in this clause - match (list): The list of match statements present in this clause. - continue (integer): The next sequence number to evaluate if the criteria - in this clause are met. - Notes: The set and match attributes produce a list of strings with The corresponding configuration. These strings will omit the preceeding @@ -66,6 +55,44 @@ class Routemaps(EntityCollection): """ def get(self, name): + """Provides a method to retrieve all routemap configuration + related to the name attribute. + + Args: + name (string): The name of the routemap. + + Returns: + None if the specified routemap does not exists. If the routermap + exists a dictionary will be provided as follows:: + + { + 'deny': { + 30: { + 'continue': 200, + 'description': None, + 'match': ['as 2000', + 'source-protocol ospf', + 'interface Ethernet2'], + 'set': [] + } + }, + 'permit': { + 10: { + 'continue': 100, + 'description': None, + 'match': ['interface Ethernet1'], + 'set': ['tag 50']}, + 20: { + 'continue': 200, + 'description': None, + 'match': ['as 2000', + 'source-protocol ospf', + 'interface Ethernet2'], + 'set': [] + } + } + } + """ if not self.get_block(r'route-map\s%s\s\w+\s\d+' % name): return None diff --git a/pyeapi/api/spanningtree.py b/pyeapi/api/spanningtree.py index be66be1..8d3eb5b 100644 --- a/pyeapi/api/spanningtree.py +++ b/pyeapi/api/spanningtree.py @@ -31,7 +31,7 @@ # import warnings -warnings.warn("Api module spanningtree is dereciated. Please update api " +warnings.warn("Api module spanningtree is depricated. Please update api " "calls to use stp instead") from pyeapi.api.stp import instance # flake8: noqa diff --git a/pyeapi/api/stp.py b/pyeapi/api/stp.py index 88b2755..03db8fa 100644 --- a/pyeapi/api/stp.py +++ b/pyeapi/api/stp.py @@ -98,20 +98,18 @@ def get(self): interfaces and instances. See the StpInterfaces and StpInstances classes for the key/value pair definitions. - Example - { - "mode": [mstp, none], - "interfaces": {...}, - "instances": {...} - } - Note: See the individual classes for detailed message structures Returns: A Python dictionary object of key/value pairs the represent - the entire supported spanning-tree configuration + the entire supported spanning-tree configuration:: + { + "mode": [mstp, none], + "interfaces": {...}, + "instances": {...} + } """ return dict(interfaces=self.interfaces.getall(), instances=self.instances.getall()) diff --git a/pyeapi/api/varp.py b/pyeapi/api/varp.py index 688367d..b3ef80f 100644 --- a/pyeapi/api/varp.py +++ b/pyeapi/api/varp.py @@ -34,18 +34,7 @@ This module provides an API for configuring VARP resources using EOS and eAPI. -Example: - { - "mac_address": "aa:bb:cc:dd:ee:ff", - "interfaces": { - "Vlan100": { - "addresses": [ "1.1.1.1", "2.2.2.2"] - }, - "Vlan200": [...] - } - } - -Parameters: +Arguments: name (string): The interface name the configuration is in reference to. The interface name is the full interface identifier @@ -85,18 +74,18 @@ def get(self): Return: A Python dictionary object of key/value pairs that represents - the current configuration of the node. If the specified - interface does not exist then None is returned. - Example: - { - "mac_address": "aa:bb:cc:dd:ee:ff", - "interfaces": { - "Vlan100": { - "addresses": [ "1.1.1.1", "2.2.2.2"] - }, - "Vlan200": [...] + the current configuration of the node. If the specified + interface does not exist then None is returned:: + + { + "mac_address": "aa:bb:cc:dd:ee:ff", + "interfaces": { + "Vlan100": { + "addresses": [ "1.1.1.1", "2.2.2.2"] + }, + "Vlan200": [...] + } } - } """ resource = dict() resource.update(self._parse_mac_address()) @@ -122,11 +111,10 @@ def set_mac_address(self, mac_address=None, default=False): Args: mac_address (string): The mac address that will be assigned as - the virtual-router mac address. This should be in the format, - aa:bb:cc:dd:ee:ff. - + the virtual-router mac address. This should be in the format, + aa:bb:cc:dd:ee:ff. default (bool): Sets the virtual-router mac address to the system - default (which is to remove the configuration line). + default (which is to remove the configuration line). Returns: True if the set operation succeeds otherwise False. diff --git a/pyeapi/client.py b/pyeapi/client.py index d470302..16eb1e8 100644 --- a/pyeapi/client.py +++ b/pyeapi/client.py @@ -31,7 +31,7 @@ # """Python Client for eAPI -This module provides the client for eAPI. It provides to primary functions +This module provides the client for eAPI. It provides the primary functions for building applications that work with Arista EOS eAPI-enabled nodes. The first function is to provide a client for sending and receiving eAPI request and response objects on a per node basis. The second function @@ -347,6 +347,7 @@ def hosts_for_tag(tag): Returns: list: A Python list object that includes the list of hosts assoicated with the specified tag. + None: If the specified tag does not exist, then None is returned. """ return config.tags.get(tag) diff --git a/setup.py b/setup.py index 257384b..8c65f1f 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,7 @@ from setuptools import setup, find_packages from codecs import open -from os import path +from os import path, environ +import sys here = path.abspath(path.dirname(__file__)) @@ -71,3 +72,20 @@ 'test': ['coverage', 'mock'], }, ) + +def install(): + if "install" in sys.argv: + return True + else: + return False + +# Use the following to dynamically build pyeapi module documentation +if install() and environ.get('READTHEDOCS'): + print 'This method is only called by READTHEDOCS.' + from subprocess import Popen + proc = Popen(['make', 'modules'], cwd='docs/') + (_, err) = proc.communicate() + return_code = proc.wait() + + if return_code or err: + raise ('Failed to make modules.(%s:%s)' % (return_code, err))