Skip to content

Commit

Permalink
Release 1.0.0 (#264)
Browse files Browse the repository at this point in the history
* Try importing ujson and rapidjson before json

ujson and rapidjson are libraries that are
faster to encode and decode JSON objects

* Implement configure_session() to send "configure session", diff() for "show session-config diff", commit() for "commit", and abort() for "abort"

* Bump version

* Fix issue #186, fix typo in client.py

* Amend tests for #186

* Amend remove vlan to vni mapping CLI

* Add config session documentation

* Add config session documentation

* Remove config session doc from wrong dir

* adding streaming option for commands

* Correct typo "mutlicast"

* Adding Power support(ppc64le)with continuous integration/testing to the project for architecture independent

* Inorrect import from 'collections' will stop working in Python 3.9

Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.9 it will stop working
Solving

* Fix python2 dependancy on collections

* Bump Python version to 3.9 for CI

* Fix #189 #190 #195

* Bump version to rc

* fixed issue #198

* #197 - updated vlans.getall() to handle vlan grouppings

* updated vlans.get() to return range/list of vlan ids (instead of input regex), plus updated relevant unit tests

* fixed import warning in abstract module

* updated documentation to avoid using localhost for off-box connections

* Refactor deprecated unittest aliases for Python 3.11 compatibility.

* Update configfile.rst

* fix for the issue #213

* Ignore subinterfaces on switchports.getall()

Signed-off-by: DavidVentura <[email protected]>

* Stop on whitespace

* extended config for unit testing issue #213

* Add a test

* Add new value from #213

* merge tests

* address perf issues on section splitting

* fix bad test

* Add option to not include defaults with node.running_config

Currently, the Node(conn).running_config always includes config defaults, this is not always wanted.
For example if you want to compare the running_config to the startup_config, it is easier to not have defaults included in the running_config.

With this option you can do something like this;
```
In [3]: conn = client.connect(**params)

In [4]: node = client.Node(conn, config_defaults=False)

In [5]: node.running_config.splitlines()[3:] == node.startup_config.splitlines()[4:]
Out[5]: True
```

* updated client descritpion to reflect issue #222

* mitor fix in the description for reST markdown

* another minor update for client.connect description

* Add support for passwords that cannot be used to login

* added sphinx_rtd_theme to dev-requrements.txt

* docs: fixing #231

* fixing collection.Iterables in test_utils.py for py3.10

* fixing collection.Iterables in test_utils.py for py3.10 - minor improvement

* fix for issue #234 - allow passing ssl context to pyeapi

* minor markdown fix in client module description

* fix passwd exposure in traceback issue

* fixed issue where sphinx failed to generate API modules doc, plus made it python3 ready

* readying pyeapi for github actions + minor style fixes

* Migrate from Travis CI to GitHub workflows

* extended python-version list for CI with 2.7 and 3.10

* removed password from showing in debugs

* added pep8 E128 to ignore list - to adopt to Arista coding style

* fixed my update to accomodate to unit tests and possibly invalid jsons

* minor typo fixes in comments

* one more minor typo fix in comments

* Update ci.yml

self approving - trivial change

* Update test_client.py

self-approved - this is non-functional, only syntactic change to keep flake8 happy

* Update eapilib.py

self-approving: non-functional, only syntactic changes to keep flake8 happier.

* Update ci.yml

adding flake8 upgrade, as it crashes in some python versions

* fix for issue #210 - getall() fails in ipinterfaces module

* fix for issue #193 - flood list for vxlan in interfaces returns wrong data

* enhanced `section` to match subsections and removed py2.7 from CI

* minor syntax change to keep flake8 happy

* added a doc string and dressed up the function, no functional change

* few more space adjustments to please flake8

* Store and pass credentials as header tuple

* Support session-based authorization

Create a Session API mixin for Http and Https connection methods that
uses the /login endpoint to store a Cookie for all future connections.
This is useful when using centralized AAA to reduce the load of repeated
command calls.

Note that the cookie does have a lifetime, and that the connection will
stop working once the cookie lifetime expires, unless the authentication
method is manually called again

* provisioning for providing CLI variants to handle deprecated cli transitions

* moved cli varinats functionality to clint.py module so that users could use it too

* fixed issue raising the exception properly for the last failed command

* fixed again raising the exception properly for the last failed command

* updated documentation

* space adjustment in the docstring

* provided comments on enforce_verification param deprecation

* removed python 3.5 and 3.6 from the workflows - unsupported

* fix issue #161 - add parsing of secondary ip from interfaces

* making flake8 happy

* Include error message in CommandError for commands that cause internal exceptions

* _parse_bgp_as regex to match as and asdot

* Checking if asn is asdot or not, and return string if asdot and int if not

* typo

* testing dumb shit

* dumby dumb dumb

* dafuq am i doing

* maybe just maybe

* i hate this shit i just wanna do neworking again :(

* lemme be a network engineer again please i wanna die

* play stupid games win stupid prices

* var typo

* testing

* testing suggested changes

* intendation error

* Update ipinterfaces.py

Replace IP MTU magic numbers with constants and provide references to RFCs

* Update ipinterfaces.py

* fixing doc build issues, errors, and providing docstring interpolation decorator

* fixing indents

* moved decorator's descriptin into the doc string

* removed deprecated spanningtree module

* removed all outdated python version checks

* minor improvement for docstr decorator

* Removed reference to python2 (#262)

* Removed reference to python2

* Removed support for lower versions of python

* Updated EOS version to the minimum supported

* Addressed formatting and error handling comments

* Refactored extra python2 check

* removed couple deprecations

* removed one more deprecation

* Created release-notes-1.0.0.rst

* Updated release-notes.rst

* Update VERSION

* Update __init__.py

* Update release-notes-1.0.0.rst

fixed a capital letter.

---------

Signed-off-by: DavidVentura <[email protected]>
Co-authored-by: Xavier Hardy <[email protected]>
Co-authored-by: Shintaro Kojima <[email protected]>
Co-authored-by: andriirr <[email protected]>
Co-authored-by: Andrii Rykhlivskyi <[email protected]>
Co-authored-by: mharista <[email protected]>
Co-authored-by: Bharath Ravindranath <[email protected]>
Co-authored-by: Will Hargrave <[email protected]>
Co-authored-by: Ubuntu <[email protected]>
Co-authored-by: Petr Klíma <[email protected]>
Co-authored-by: Dmitry Lyssenko <[email protected]>
Co-authored-by: Dmitry Lyssenko <[email protected]>
Co-authored-by: Karthikeyan Singaravelan <[email protected]>
Co-authored-by: DavidVentura <[email protected]>
Co-authored-by: erikl <[email protected]>
Co-authored-by: Jeremiah Millay <[email protected]>
Co-authored-by: steve ulrich <[email protected]>
Co-authored-by: Alarig Le Lay <[email protected]>
Co-authored-by: Stefano Rivera <[email protected]>
Co-authored-by: Brandon Ewing <[email protected]>
Co-authored-by: Dylan Kaplan <[email protected]>
Co-authored-by: bh-rr <[email protected]>
Co-authored-by: Greg Skinner <[email protected]>
Co-authored-by: chieto-arista <[email protected]>
  • Loading branch information
1 parent b541d2f commit 0da702b
Show file tree
Hide file tree
Showing 39 changed files with 1,220 additions and 258 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
name: CI
on: [ pull_request, workflow_dispatch ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10']
fail-fast: false
name: Test on Python ${{ matrix.python-version }}
steps:
- uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install wheel
run: pip install wheel
- name: Install dev requirements
run: pip install -r dev-requirements.txt
- name: Upgrade flake8
run: pip install --upgrade flake8
- name: Clean
run: make clean
- name: pep8
run: make pep8
- name: flake8
run: make flake8
- name: check
run: make check
- name: unittest
run: make unittest
21 changes: 0 additions & 21 deletions .travis.yml

This file was deleted.

6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ VERSION := $(shell cat VERSION)
all: clean check pep8 flake8 tests

pep8:
pycodestyle -r --ignore=E402,E731,E501,E221,W291,W391,E302,E251,E203,W293,E231,E303,E201,E225,E261,E241 pyeapi/ test/
pycodestyle -r --ignore=E402,E731,E501,E221,W291,W391,E302,E251,E203,W293,E231,E303,E201,E202,E225,E261,E241,E128 pyeapi/ test/

pyflakes:
pyflakes pyeapi/ test/

flake8:
flake8 --ignore=E302,E303,E402,E731,W391 --exit-zero pyeapi/
flake8 --ignore=E302,E303,E402,E731,W391,N802 --max-line-length=100 test/
flake8 --ignore=E128,E201,E202,E302,E303,E402,E731,W391 --exit-zero pyeapi/
flake8 --ignore=E128,E201,E202,E302,E303,E402,E731,W391,N802 --max-line-length=100 test/

check:
check-manifest
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.8.3
1.0.0
6 changes: 4 additions & 2 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@ coverage
sphinx
sphinxcontrib-napoleon
flake8
flake8-print
flake8-debugger
#commenting below 2 lines until switchover to python3 is complete
#flake8-print
#flake8-debugger
sphinx_rtd_theme
2 changes: 1 addition & 1 deletion docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ PAPER =
BUILDDIR = _build
APIDIR = api_modules
CLIENTDIR = client_modules
CWD := $(shell pwd)
CWD := '$(shell pwd)'

# User-friendly check for sphinx-build
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
Expand Down
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, '../pyeapi')
sys.path.insert(0, os.path.abspath('..') )

# -- General configuration ------------------------------------------------

Expand All @@ -35,7 +35,7 @@
'sphinx.ext.coverage',
'sphinx.ext.viewcode',
'sphinx.ext.doctest',
'sphinxcontrib.napoleon'
'sphinx.ext.napoleon'
]

# Add any paths that contain templates here, relative to this directory.
Expand Down
15 changes: 15 additions & 0 deletions docs/configfile.rst
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,16 @@ As the table above indicates, a pyeapi configuration file is required in
[connection:localhost]
transport: http_local
Pay attention: once ``eapi.conf`` exists, the respective protocol method must be
configured on the box. E.g., for the above ``eapi.conf`` sample, the following
configuration must also exist:

.. code-block:: console
switch(config)#management http-server
switch(config-mgmt-http-server)#protocol http localhost
Using HTTP or HTTPS
===================

Expand Down Expand Up @@ -172,6 +182,11 @@ As the table above indicates, a pyeapi configuration file is required in
username: admin
password: admin
.. Note:: avoid using ``localhost`` name in the connection description (i.e.: ``[connection:localhost]``).
The name ``localhost`` is reserved solely for ``on-box`` connection method and it won't work when
connecting ``off-box``


Using HTTPS with Certificates
=============================

Expand Down
52 changes: 52 additions & 0 deletions docs/configsessions.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
Using Config Sessions via Python Client for eAPI
=======================================================

Config Sessions can be used via Pyeapi. Config sessions allow a block of config
to be added as one operation instead of as individual lines. Configurations applied
in this manner allow the user to abort all the config being applied if an error occurs.

Using Config Sessions:

.. code-block:: python
import pyeapi
node = pyeapi.connect_to('veos01')
vlans = node.api('vlans')
node.configure_session()
node.diff() # Sends "configure session 9c27d0e8-afef-4afd-95ae-3e3200bb7a3e" and "show session-config diff"
"""
=>
--- system:/running-config
+++ session:/9c27d0e8-afef-4afd-95ae-3e3200bb7a3e-session-config
@@ -32,7 +32,7 @@
!
clock timezone Asia/Tokyo
!
-vlan 1000,3001-3006
+vlan 100,1000,3001-3006
!
interface Port-Channel1
switchport trunk allowed vlan 3001-3003
"""
node.abort() # Sends "configure session 9c27d0e8-afef-4afd-95ae-3e3200bb7a3e" and "abort"
# or
node.commit() # Sends "configure session 9c27d0e8-afef-4afd-95ae-3e3200bb7a3e" and "commit"
Config Session with invalid config line:

.. code-block:: python
node = pyeapi.connect_to('veos01')
interfaces = node.api('interfaces')
node.configure_session()
if not (interfaces.configure(['interface Eth6', 'no switchport', 'ip address 172.16.0.1/30']) and \
interfaces.configure(['interface Eth7', 'no switchport', 'ip address 172.16.0.1/30'])):
node.abort() # This aborts everything!!
For more detailed information about using Configure Sessions in EOS, reference the user
manual for the version of EOS running on your switch.
4 changes: 2 additions & 2 deletions docs/generate_modules.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3

from os import listdir, path, makedirs
from os.path import isfile, join, exists
Expand All @@ -22,7 +22,7 @@ def get_module_names(p):
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('__')]
print len(mods)
print( len(mods) )
return mods

def process_modules(modules):
Expand Down
23 changes: 23 additions & 0 deletions docs/release-notes-0.8.4.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Release 0.8.4
-------------

2020-11-13

New Modules
^^^^^^^^^^^


Enhancements
^^^^^^^^^^^^

* Add streaming capability for eapi interface

* Add Power ppc64le support with CI

Fixed
^^^^^

Known Caveats
^^^^^^^^^^^^^


64 changes: 64 additions & 0 deletions docs/release-notes-1.0.0.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
Release 1.0.0
-------------

2023-06-06

- This is a Python3 (3.7 onwards) release only (Python2 is no longer supported)
- Arista EOS 4.22 or later required

New Modules
^^^^^^^^^^^

Enhancements
^^^^^^^^^^^^

Fixed
^^^^^

* Let ``config`` method to raise ``ConnectionError`` exception (`198 <https://github.com/arista-eosplus/pyeapi/issues/198>`_)
The fix ensures that the behavior is consistent with other methods.
* Fixed parsing of VLAN groupings by ``vlans.getall()`` (`200 <https://github.com/arista-eosplus/pyeapi/pull/200>`_)
The fix allows handling a case when multiple VLANs in the configs may be grouped under a common (group) name.
* Enhanced ``vlans.get()`` to return an actual list of VLANs (`202 <https://github.com/arista-eosplus/pyeapi/pull/202>`_)
The method used to return the argument itself (e.g., an RE: ``200-.*``), now the actual list of matched VLANs is returned
* Fixed a corner crash in ``portsVlans.getall()`` (`213 <https://github.com/arista-eosplus/pyeapi/issues/213>`_)
The crash may occur when the switchport is configured with a VLAN profile
* Improved ``switchports.getall()`` behavior (`216 <https://github.com/arista-eosplus/pyeapi/pull/216>`_)
The method will not consider subinterfaces anymore
* Improved JSON parsing speed (`166 <https://github.com/arista-eosplus/pyeapi/pull/166>`_)
User may improve the speed by using ``ujson`` or ``rapidjson`` modules. The standard ``json`` is used as a fallback.
* Allow user to specify an SSL context (`234 <https://github.com/arista-eosplus/pyeapi/issues/234>`_)
Provided the argument option ``context`` to specify an SSL context in ``connection()`` method.
* Fixed user password vulnerability in tracebacks (`238 <https://github.com/arista-eosplus/pyeapi/pull/238>`_)
A user password is exposed in a traceback, which could occur due to invalid credentials.
* Added support for login password exclusively for ssh-key authentication (`227 <https://github.com/arista-eosplus/pyeapi/pull/227>`_)
Catching up with EOS CLI which already supports such login password.
* Fixed user password vulnerability in debugs (`242 <https://github.com/arista-eosplus/pyeapi/pull/242>`_)
A user password was exposed in user enabled debugs. With this commit the user password is masked out now.
* Added option not to include config defaults (`221 <https://github.com/arista-eosplus/pyeapi/pull/221>`_)
Reading running-config or startup-config with default values is not always a desirable behavior. This commit adds an option to control such behavior.
* Fixed a corner crash in ``ipinterfaces`` module (`210 <https://github.com/arista-eosplus/pyeapi/issues/210>`_)
Fixed a crash when MTU value is not present in the interface configuration (this is rather a corner case condition).
* Fixed a bug where vxlan floodlist might return a bogus data (`193 <https://github.com/arista-eosplus/pyeapi/issues/193>`_)
Fixed the issue with ``interfaces`` module, where ``get()`` method returned vxlan data structure with ``flood_list`` parsed incorrectly.
* Improved performance of config parsing (`220 <https://github.com/arista-eosplus/pyeapi/pull/220>`_)
Drastically improved perfromance of config parsing by cacheing section splitting results. This fix also tightens the prior relaxed section match behavior by allowing matching only section line (as vs entire section's content)
* Enhanced PR (`220 <https://github.com/arista-eosplus/pyeapi/pull/220>`_) allowing to match sub-sections (`245 <https://github.com/arista-eosplus/pyeapi/pull/245>`_)
After PR #220, matching subsections was impossible (only entire section could have been matched). This enhancement brings back such functionality.
* Added support for a session based authentication (`203 <https://github.com/arista-eosplus/pyeapi/pull/203>`_)
Added a couple new transport options (``http_session`` and ``https_session``) to ``connect()`` method to support a session based authentication.
* Added support infrastructure to handle deprecated EOS CLI (`247 <https://github.com/arista-eosplus/pyeapi/pull/247>`_)
The added ``CliVariants`` class helps managing transitions from deprecated EOS CLI (by allowing specifying both, new and deprecated CLI variants).
* Added support for parsing secondary ip addresses (`251 <https://github.com/arista-eosplus/pyeapi/pull/251>`_)
The added fix extends the return result for ``get()`` method of ``ipinterfaces`` module with the parsed secondary ip addresses (if present).
* A minor fix to include internal exception handling (`252 <https://github.com/arista-eosplus/pyeapi/pull/252>`_)
With this fix the ``pyeapi.eapilib.CommandError`` exception will elaborate on the causes of internal errors.
* Enhance parsing of BGP router section with ``asdot`` notation (`256 <https://github.com/arista-eosplus/pyeapi/pull/256>`_)
Allow matching and parsing ``router bgp`` sections if spelled with ``asdot`` notation.
* removed and updated deprecations (`204 <https://github.com/arista-eosplus/pyeapi/pull/204>`_, `212 <https://github.com/arista-eosplus/pyeapi/pull/212>`_, `235 <https://github.com/arista-eosplus/pyeapi/pull/235>`_, `260 <https://github.com/arista-eosplus/pyeapi/pull/260>`_, `262 <https://github.com/arista-eosplus/pyeapi/pull/262>`_, `263 <https://github.com/arista-eosplus/pyeapi/pull/263>`_)
* documentation fixes and updates (`209 <https://github.com/arista-eosplus/pyeapi/pull/209>`_, `225 <https://github.com/arista-eosplus/pyeapi/pull/225>`_, `239 <https://github.com/arista-eosplus/pyeapi/pull/239>`_, `257 <https://github.com/arista-eosplus/pyeapi/pull/257>`_, `259 <https://github.com/arista-eosplus/pyeapi/pull/259>`_)

Known Caveats
^^^^^^^^^^^^^


3 changes: 3 additions & 0 deletions docs/release-notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ Release Notes
:maxdepth: 2
:titlesonly:

release-notes-1.0.0.rst
release-notes-0.8.4.rst
release-notes-0.8.3.rst
release-notes-0.8.2.rst
release-notes-0.8.1.rst
release-notes-0.8.0.rst
Expand Down
4 changes: 2 additions & 2 deletions docs/requirements.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
Requirements
############

* Arista EOS 4.12 or later
* Arista EOS 4.22 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)
* Python 3.7+
* Pyeapi requires the netaddr Python module

.. Note:: netaddr gets installed automatically if you use pip to install pyeapi
2 changes: 1 addition & 1 deletion pyeapi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
__version__ = '0.8.3'
__version__ = '1.0.0'
__author__ = 'Arista EOS+'


Expand Down
6 changes: 3 additions & 3 deletions pyeapi/api/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@
ultimately derive from BaseEntity which provides some common functions to
make building API modules easier.
"""
from collections import Callable, Mapping

from pyeapi.eapilib import CommandError, ConnectionError
from collections.abc import Callable, Mapping
from pyeapi.eapilib import CommandError
from pyeapi.utils import make_iterable


Expand Down Expand Up @@ -123,7 +123,7 @@ def configure(self, commands):
try:
self.node.config(commands)
return True
except (CommandError, ConnectionError):
except (CommandError):
return False

def command_builder(self, string, value=None, default=None, disable=None):
Expand Down
11 changes: 5 additions & 6 deletions pyeapi/api/bgp.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ def get(self):
return response

def _parse_bgp_as(self, config):
match = re.search(r'^router bgp (\d+)', config)
return dict(bgp_as=int(match.group(1)))
as_num = re.search(r'(?<=^router bgp ).*', config).group(0)
return { 'bgp_as': int(as_num) if as_num.isnumeric() else as_num }

def _parse_router_id(self, config):
match = re.search(r'router-id ([^\s]+)', config)
Expand Down Expand Up @@ -214,10 +214,9 @@ def _parse_peer_group(self, config, name):
return dict(peer_group=value)

def _parse_remote_as(self, config, name):
regexp = r'neighbor {} remote-as (\d+)'.format(name)
match = re.search(regexp, config)
value = match.group(1) if match else None
return dict(remote_as=value)
remote_as_re = rf'(?<=neighbor {name} remote-as ).*'
match = re.search(remote_as_re, config)
return { 'remote_as': match.group(0) if match else None}

def _parse_send_community(self, config, name):
exp = 'no neighbor {} send-community'.format(name)
Expand Down
Loading

0 comments on commit 0da702b

Please sign in to comment.