Python client for Arista eAPI

Overview

Arista eAPI Python Library

Build Status Coverage Status Documentation Status

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 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 convenient implementation for working with the EOS configuration and is extensible for 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.

Documentation

Building Local Documentation

If you cannot access readthedocs.org you have the option of building the documentation locally.

  1. pip install -r dev-requirements.txt
  2. cd docs
  3. make html
  4. open _build/html/index.html

License

Copyright (c) 2015, Arista Networks EOS+ All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  • Neither the name of the Arista nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 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.

Comments
  • Certificate validation doesn't work

    Certificate validation doesn't work

    I tried to make certificate validation work, but it seems it's not possible at the moment.

    The validation is disabled by default, and if you want to enable it, you have to pass enforce_verification in kwargs to HttpsEapiConnection constructor.

    This constructor is only ever called from client.py / make_connection(), which in turn is only ever called from this line: https://github.com/arista-eosplus/pyeapi/blob/35557de723152bf00a981082805f173accb99485/pyeapi/client.py#L427

    As you can see, we never pass the enforce_verification to make_connection function.

    We need to either pass down **kwargs, or at the very least the enforce_verification should it ever be set.

    opened by zloo 14
  • add banner support to system api

    add banner support to system api

    TAC had a requirement for an internal tool to change the banner on lab switches programmatically, so I thought this would be a nice add to the pyeapi library

    enhancement 
    opened by dathelen 11
  • New release

    New release

    Hi Is anything blocking a new release? I'm interested in not maintaining my fork anymore -- if there's a pending task or so that you need help with to get a release out, I can help you!

    opened by DavidVentura 8
  • When excepting

    When excepting "pyeapi.eapilib.ConnectionError" I still get the pyeapi script spewing socket exceptions to the screen

    Traceback (most recent call last):
      File "/home/shimamizu/.pyenv/versions/3.9.11/lib/python3.9/site-packages/pyeapi/eapilib.py", line 447, in send
        response_content = response.read()
      File "/home/shimamizu/.pyenv/versions/3.9.11/lib/python3.9/http/client.py", line 470, in read
        return self._readall_chunked()
      File "/home/shimamizu/.pyenv/versions/3.9.11/lib/python3.9/http/client.py", line 577, in _readall_chunked
        chunk_left = self._get_chunk_left()
      File "/home/shimamizu/.pyenv/versions/3.9.11/lib/python3.9/http/client.py", line 560, in _get_chunk_left
        chunk_left = self._read_next_chunk_size()
      File "/home/shimamizu/.pyenv/versions/3.9.11/lib/python3.9/http/client.py", line 520, in _read_next_chunk_size
        line = self.fp.readline(_MAXLINE + 1)
      File "/home/shimamizu/.pyenv/versions/3.9.11/lib/python3.9/socket.py", line 704, in readinto
        return self._sock.recv_into(b)
      File "/home/shimamizu/.pyenv/versions/3.9.11/lib/python3.9/ssl.py", line 1241, in recv_into
        return self.read(nbytes, buffer)
      File "/home/shimamizu/.pyenv/versions/3.9.11/lib/python3.9/ssl.py", line 1099, in read
        return self._sslobj.read(len, buffer)
    socket.timeout: The read operation timed out
    Error connecting to the eAPI for {my_hostname}
    

    The last line is proof that my exception did catch it:

    except pyeapi.eapilib.ConnectionError as conn_error:
                print(f"Error connecting to the eAPI for {self.switch_hostname}")
    

    I have also tried adding an exception for socket.timeout in my pyeapi script wrapper, but that never catches it, since the socket.timeout portion of the error appears to be happening inside the pyeapi library, not handling well, and then just passing the pyeapi.eapilib.ConnectionError back to me which I am able to catch.

    In my logging file I then just see:

    self.logger.warning(
                    f"Connection error on {self.switch_hostname}:\n {str(conn_error.message)}"
                )
    
    2022-06-27 12:03:25,739 WARNING  Connection error on {my_hostname}:
     Socket error during eAPI connection: The read operation timed out
    

    That second line I assume been the error that the pyeapi sent back about socket.timeout

    I would like all the barfing from socket.timeout not to print on screen when I'm catching pyeapi.eapilib.ConnectionError correctly

    question 
    opened by shimamizu 7
  • ssl Handshake failure while connecting to devices when using python 3.10.2

    ssl Handshake failure while connecting to devices when using python 3.10.2

    Here is the failure log: /usr/local/lib/python3.10/site-packages/vane-1.0.0-py3.10.egg/vane/tests_tools.py:817: in return_show_cmd show_output = conn.enable(show_cmd) /usr/local/lib/python3.10/site-packages/pyeapi/client.py:712: in enable resp = self.run_commands(command, encoding, send_enable, /usr/local/lib/python3.10/site-packages/pyeapi/client.py:771: in run_commands response = self._connection.execute(commands, encoding, **kwargs) /usr/local/lib/python3.10/site-packages/pyeapi/eapilib.py:554: in execute response = self.send(request)


    self = EapiConnection(transport=https://10.255.74.38:443//command-api) data = b'{"jsonrpc": "2.0", "method": "runCmds", "params": {"version": 1, "cmds": ["enable", "show agent logs crash"], "format": "json"}, "id": "140108890278976", "streaming": false}' def send(self, data): """Sends the eAPI request to the destination node

        This method is responsible for sending an eAPI request to the
        destination node and returning a response based on the eAPI response
        object.  eAPI responds to request messages with either a success
        message or failure message.
    
        eAPI Response - success
    
        .. code-block:: json
    
            {
                "jsonrpc": "2.0",
                "result": [
                    {},
                    {}
                    {
                        "warnings": [
                            <message>
                        ]
                    },
                ],
                "id": <reqid>
            }
    
        eAPI Response - failure
    
        .. code-block:: json
    
            {
                "jsonrpc": "2.0",
                "error": {
                    "code": <int>,
                    "message": <string>
                    "data": [
                        {},
                        {},
                        {
                            "errors": [
                                <message>
                            ]
                        }
                    ]
                }
                "id": <reqid>
            }
    
        Args:
            data (string): The data to be included in the body of the eAPI
                request object
    
        Returns:
            A decoded response.  The response object is deserialized from
                JSON and returned as a standard Python dictionary object
    
        Raises:
            CommandError if an eAPI failure response object is returned from
                the node.   The CommandError exception includes the error
                code and error message from the eAPI response.
        """
        try:
            _LOGGER.debug('Request content: {}'.format(data))
            # debug('eapi_request: %s' % data)
    
            self.transport.putrequest('POST', '/command-api')
    
            self.transport.putheader('Content-type', 'application/json-rpc')
            self.transport.putheader('Content-length', '%d' % len(data))
    
            if self._auth:
                self.transport.putheader('Authorization',
                                         'Basic %s' % self._auth)
    
            if int(sys.version[0]) > 2:
                # For Python 3.x compatibility
                data = data.encode()
    
            self.transport.endheaders(message_body=data)
    
            try:  # Python 2.7: use buffering of HTTP responses
                response = self.transport.getresponse(buffering=True)
            except TypeError:  # Python 2.6: older, and 3.x on
                response = self.transport.getresponse()
    
            response_content = response.read()
            _LOGGER.debug('Response: status:{status}, reason:{reason}'.format(
                          status=response.status,
                          reason=response.reason))
            _LOGGER.debug('Response content: {}'.format(response_content))
    
            if response.status == 401:
                raise ConnectionError(str(self), '%s. %s' % (response.reason,
                                                             response_content))
    
            # Work around for Python 2.7/3.x compatibility
            if not type(response_content) == str:
                # For Python 3.x - decode bytes into string
                response_content = response_content.decode()
            decoded = json.loads(response_content)
            _LOGGER.debug('eapi_response: %s' % decoded)
    
            if 'error' in decoded:
                (code, msg, err, out) = self._parse_error_message(decoded)
                pattern = "unexpected keyword argument '(.*)'"
                match = re.search(pattern, msg)
                if match:
                    auto_msg = ('%s parameter is not supported in this'
                                ' version of EOS.' % match.group(1))
                    _LOGGER.error(auto_msg)
                    msg = msg + '. ' + auto_msg
                raise CommandError(code, msg, command_error=err, output=out)
    
            return decoded
    
        # socket.error is deprecated in python 3 and replaced with OSError.
        except (socket.error, OSError) as exc:
            _LOGGER.exception(exc)
            self.socket_error = exc
            self.error = exc
            error_msg = 'Socket error during eAPI connection: %s' % str(exc)
    
          raise ConnectionError(str(self), error_msg)
    

    E pyeapi.eapilib.ConnectionError: Socket error during eAPI connection: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:997) /usr/local/lib/python3.10/site-packages/pyeapi/eapilib.py:483: ConnectionError

    Probably it is hitting this problem and we need to change pyeapi code? https://stackoverflow.com/questions/56719290/how-to-solve-the-handshake-failure-using-ssl-in-python

    opened by shachiagarwal 7
  • Switchports API crashing on subinterfaces

    Switchports API crashing on subinterfaces

    Device:

    Arista DCS-7050SX3-48YC8-R
    Hardware version:      11.15
    
    Software image version: 4.23.3M
    Architecture:           i686
    Internal build version: 4.23.3M-16431779.4233M
    

    Port config:

    interface Ethernet48.2044
       description some port description
       no shutdown
       default load-interval
       logging event link-status use-global
       encapsulation dot1q vlan 2044
       snmp trap link-change
       vrf DAT
       no ip proxy-arp
       no ip local-proxy-arp
       no arp gratuitous accept
       ip address 100.76.1.41/31
       no ip verify unicast
       no ip directed-broadcast
       ip attached-routes
       default arp aging timeout
       default ipv6 nd cache expire
       no bfd echo
       no bfd authentication mode
       default ip dhcp relay all-subnets
       no ip helper-address
       no ipv6 dhcp relay destination
       no ipv6 dhcp relay add vendor-option ccap-core
       no ipv6 dhcp relay install routes
       ip dhcp relay information option circuit-id Ethernet48.2044
       no dhcp server ipv4
       no dhcp server ipv6
       no ip attached-host route export
       no ipv6 attached-host route export
       no ip igmp
       ip igmp version 3
       ip igmp last-member-query-count 2
       ip igmp last-member-query-interval 10
       igmp query-max-response-time 100
       ip igmp query-interval 125
       ip igmp startup-query-count 2
       ip igmp startup-query-interval 310
       ip igmp router-alert optional connected
       no ip igmp host-proxy
       no ipv6 enable
       default ipv6 nd dad
       no ipv6 address
       no ipv6 nd ra rx accept default-route
       ipv6 attached-routes
       no ipv6 verify unicast
       no ipv6 nd ra disabled
       ipv6 nd ra interval msec 200000
       ipv6 nd ra lifetime 1800
       no ipv6 nd ra mtu suppress
       no ipv6 nd managed-config-flag
       no ipv6 nd other-config-flag
       ipv6 nd reachable-time 0
       ipv6 nd router-preference medium
       ipv6 nd ra dns-servers lifetime 300
       ipv6 nd ra dns-suffixes lifetime 300
       ipv6 nd ra hop-limit 64
       no tcp mss ceiling
       no multicast ipv4 source route export
       no multicast ipv6 source route export
       no multicast ipv4 static
       no multicast ipv6 static
       mfib ipv4 fastdrop
       no mld
       no mld static-group access-list
       mld query-interval 125
       mld query-response-interval 10
       no mld startup-query-interval
       mld startup-query-count 2
       mld robustness 2
       mld last-listener-query-interval 1
       mld last-listener-query-count 2
       mpls ip
       default ntp serve
       no pim ipv4 sparse-mode
       no pim ipv4 bidirectional
       no pim ipv4 border-router
       pim ipv4 hello interval 30
       pim ipv4 hello count 3.5
       pim ipv4 dr-priority 1
       pim ipv4 join-prune interval 60
       pim ipv4 join-prune count 3.5
       no pim ipv4 neighbor filter 
       default pim ipv4 bfd
       no  pim ipv4 join-prune transport sctp
       no  pim ipv4 local-interface
       no  pim ipv4 non-dr install-oifs
       no pim ipv6 sparse-mode
       no pim ipv6 border-router
       pim ipv6 hello interval 30
       pim ipv6 hello count 3.5
       pim ipv6 dr-priority 1
       pim ipv6 join-prune interval 60
       pim ipv6 join-prune count 3.5
       no pim ipv6 neighbor filter 
       default pim ipv6 bfd
       no pim bsr ipv4 border
       no pim bsr ipv6 border
       no rip v2 multicast disable
       no node-segment ipv4 index
       no node-segment ipv6 index
    !
    
    

    the key part is that this does not include the string "no switchport" - so it is getting parsed as an L2 interface as getall() does not filter out subinterfaces.

    opened by DavidVentura 6
  • No cipher option

    No cipher option

    EOS uses deprecated ciphers by default and we can’t specify the ciphers to use (with ssl.create_default_context().set_ciphers('DHE-RSA-AES256-SHA'), so it’s impossible to connect from a system removing deprecated ciphers by default:

    Traceback (most recent call last):
      File "/usr/lib/python3.9/site-packages/pyeapi/eapilib.py", line 440, in send
        self.transport.endheaders(message_body=data)
      File "/usr/lib/python3.9/http/client.py", line 1252, in endheaders
        self._send_output(message_body, encode_chunked=encode_chunked)
      File "/usr/lib/python3.9/http/client.py", line 1012, in _send_output
        self.send(msg)
      File "/usr/lib/python3.9/http/client.py", line 952, in send
        self.connect()
      File "/usr/lib/python3.9/http/client.py", line 1426, in connect
        self.sock = self._context.wrap_socket(self.sock,
      File "/usr/lib/python3.9/ssl.py", line 500, in wrap_socket
        return self.sslsocket_class._create(
      File "/usr/lib/python3.9/ssl.py", line 1040, in _create
        self.do_handshake()
      File "/usr/lib/python3.9/ssl.py", line 1309, in do_handshake
        self._sslobj.do_handshake()
    ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1145)
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/usr/lib/python3.9/site-packages/napalm/eos/eos.py", line 167, in open
        sh_ver = self.device.run_commands(["show version"])
      File "/usr/lib/python3.9/site-packages/napalm/eos/pyeapi_syntax_wrapper.py", line 42, in run_commands
        return super(Node, self).run_commands(commands, *args, **kwargs)
      File "/usr/lib/python3.9/site-packages/pyeapi/client.py", line 771, in run_commands
        response = self._connection.execute(commands, encoding, **kwargs)
      File "/usr/lib/python3.9/site-packages/pyeapi/eapilib.py", line 554, in execute
        response = self.send(request)
      File "/usr/lib/python3.9/site-packages/pyeapi/eapilib.py", line 483, in send
        raise ConnectionError(str(self), error_msg)
    pyeapi.eapilib.ConnectionError: Socket error during eAPI connection: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1145)
    

    Running a simple urllib.request.Request without the cipher option from ssl returns the same error, by specifying the ciphers it works.

    ~ % python
    Python 3.9.6 (default, Sep 22 2021, 15:28:10) 
    [GCC 10.3.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import ssl
    >>> import urllib.request
    >>> url = urllib.request.Request('https://edge-1/')
    >>> ssl_context = ssl.create_default_context()
    >>> ssl_context.set_ciphers('DHE-RSA-AES256-SHA, AES256-SHA')
    >>> data = urllib.request.urlopen(url).read().decode()
    Traceback (most recent call last):
      File "/usr/lib/python3.9/urllib/request.py", line 1346, in do_open
        h.request(req.get_method(), req.selector, req.data, headers,
      File "/usr/lib/python3.9/http/client.py", line 1257, in request
        self._send_request(method, url, body, headers, encode_chunked)
      File "/usr/lib/python3.9/http/client.py", line 1303, in _send_request
        self.endheaders(body, encode_chunked=encode_chunked)
      File "/usr/lib/python3.9/http/client.py", line 1252, in endheaders
        self._send_output(message_body, encode_chunked=encode_chunked)
      File "/usr/lib/python3.9/http/client.py", line 1012, in _send_output
        self.send(msg)
      File "/usr/lib/python3.9/http/client.py", line 952, in send
        self.connect()
      File "/usr/lib/python3.9/http/client.py", line 1426, in connect
        self.sock = self._context.wrap_socket(self.sock,
      File "/usr/lib/python3.9/ssl.py", line 500, in wrap_socket
        return self.sslsocket_class._create(
      File "/usr/lib/python3.9/ssl.py", line 1040, in _create
        self.do_handshake()
      File "/usr/lib/python3.9/ssl.py", line 1309, in do_handshake
        self._sslobj.do_handshake()
    ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1145)
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/lib/python3.9/urllib/request.py", line 214, in urlopen
        return opener.open(url, data, timeout)
      File "/usr/lib/python3.9/urllib/request.py", line 517, in open
        response = self._open(req, data)
      File "/usr/lib/python3.9/urllib/request.py", line 534, in _open
        result = self._call_chain(self.handle_open, protocol, protocol +
      File "/usr/lib/python3.9/urllib/request.py", line 494, in _call_chain
        result = func(*args)
      File "/usr/lib/python3.9/urllib/request.py", line 1389, in https_open
        return self.do_open(http.client.HTTPSConnection, req,
      File "/usr/lib/python3.9/urllib/request.py", line 1349, in do_open
        raise URLError(err)
    urllib.error.URLError: <urlopen error [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1145)>
    >>> data = urllib.request.urlopen(url, context=ssl_context).read().decode()
    Traceback (most recent call last):
      File "/usr/lib/python3.9/urllib/request.py", line 1346, in do_open
        h.request(req.get_method(), req.selector, req.data, headers,
      File "/usr/lib/python3.9/http/client.py", line 1257, in request
        self._send_request(method, url, body, headers, encode_chunked)
      File "/usr/lib/python3.9/http/client.py", line 1303, in _send_request
        self.endheaders(body, encode_chunked=encode_chunked)
      File "/usr/lib/python3.9/http/client.py", line 1252, in endheaders
        self._send_output(message_body, encode_chunked=encode_chunked)
      File "/usr/lib/python3.9/http/client.py", line 1012, in _send_output
        self.send(msg)
      File "/usr/lib/python3.9/http/client.py", line 952, in send
        self.connect()
      File "/usr/lib/python3.9/http/client.py", line 1426, in connect
        self.sock = self._context.wrap_socket(self.sock,
      File "/usr/lib/python3.9/ssl.py", line 500, in wrap_socket
        return self.sslsocket_class._create(
      File "/usr/lib/python3.9/ssl.py", line 1040, in _create
        self.do_handshake()
      File "/usr/lib/python3.9/ssl.py", line 1309, in do_handshake
        self._sslobj.do_handshake()
    ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate (_ssl.c:1145)
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/lib/python3.9/urllib/request.py", line 214, in urlopen
        return opener.open(url, data, timeout)
      File "/usr/lib/python3.9/urllib/request.py", line 517, in open
        response = self._open(req, data)
      File "/usr/lib/python3.9/urllib/request.py", line 534, in _open
        result = self._call_chain(self.handle_open, protocol, protocol +
      File "/usr/lib/python3.9/urllib/request.py", line 494, in _call_chain
        result = func(*args)
      File "/usr/lib/python3.9/urllib/request.py", line 1389, in https_open
        return self.do_open(http.client.HTTPSConnection, req,
      File "/usr/lib/python3.9/urllib/request.py", line 1349, in do_open
        raise URLError(err)
    urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate (_ssl.c:1145)>
    >>> 
    

    Without a ssl context, urrlib can’t connect to the arista box at all, by specifing it, it’s only a matter of self signed certificate.

    opened by alarig 6
  • ConnectionError: Socket error during eAPI connection: The read operation timed out

    ConnectionError: Socket error during eAPI connection: The read operation timed out

    Please, note that this BUG s related to: https://github.com/napalm-automation/napalm-ansible/issues/165#issuecomment-582143234

    I am using NAPALM to perform config-replace on Arista DCS-7060SX2-48YC6-R version 4.21.8M-13902577.4218M.with pyeapi==0.8.3 The session times out no matter what timeout I configure, either http and https. I can use the library ok for other things like send commands.

    I can see the HTTP session up and the configure session created, however no packets are sent/received and configure session remains in pending

       User              Requests       Bytes in       Bytes out    Last hit
    ----------------- -------------- -------------- --------------- --------------
       prd2204.svc       456            530905         3856176      12 seconds ago
    
       User              Requests       Bytes in       Bytes out    Last hit
    ----------------- -------------- -------------- --------------- ---------------
       prd2204.svc       456            530905         3856176      171 seconds ago
    
    l1a.r5b1.ams7#show configuration sessions
    Maximum number of completed sessions: 1
    Maximum number of pending sessions: 5
    
      Name             State         User                 Terminal
      ------------- ------------- ----------------------- -----------
      napalm_101518    pending        prd2204.svc    command-api
    
    The read operation timed out
    Traceback (most recent call last):
      File "/Users/federicoolivieri/git/NaC/lib/python3.7/site-packages/pyeapi/eapilib.py", line 443, in send
        response_content = response.read()
      File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 454, in read
        return self._readall_chunked()
      File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 561, in _readall_chunked
        chunk_left = self._get_chunk_left()
      File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 544, in _get_chunk_left
        chunk_left = self._read_next_chunk_size()
      File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 504, in _read_next_chunk_size
        line = self.fp.readline(_MAXLINE + 1)
      File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/socket.py", line 589, in readinto
        return self._sock.recv_into(b)
      File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 1049, in recv_into
        return self.read(nbytes, buffer)
      File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 908, in read
        return self._sslobj.read(len, buffer)
    socket.timeout: The read operation timed out
    Traceback (most recent call last):
      File "/Users/federicoolivieri/git/NaC/lib/python3.7/site-packages/pyeapi/eapilib.py", line 443, in send
        response_content = response.read()
      File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 454, in read
        return self._readall_chunked()
      File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 561, in _readall_chunked
        chunk_left = self._get_chunk_left()
      File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 544, in _get_chunk_left
        chunk_left = self._read_next_chunk_size()
      File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 504, in _read_next_chunk_size
        line = self.fp.readline(_MAXLINE + 1)
      File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/socket.py", line 589, in readinto
        return self._sock.recv_into(b)
      File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 1049, in recv_into
        return self.read(nbytes, buffer)
      File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 908, in read
        return self._sslobj.read(len, buffer)
    socket.timeout: The read operation timed out
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/Users/federicoolivieri/git/NaC/lib/python3.7/site-packages/napalm/eos/eos.py", line 297, in load_replace_candidate
        self._load_config(filename, config, True)
      File "/Users/federicoolivieri/git/NaC/lib/python3.7/site-packages/napalm/eos/eos.py", line 286, in _load_config
        self.device.run_commands(commands)
      File "/Users/federicoolivieri/git/NaC/lib/python3.7/site-packages/pyeapi/client.py", line 743, in run_commands
        response = self._connection.execute(commands, encoding, **kwargs)
      File "/Users/federicoolivieri/git/NaC/lib/python3.7/site-packages/pyeapi/eapilib.py", line 550, in execute
        response = self.send(request)
      File "/Users/federicoolivieri/git/NaC/lib/python3.7/site-packages/pyeapi/eapilib.py", line 479, in send
        raise ConnectionError(str(self), error_msg)
    pyeapi.eapilib.ConnectionError: Socket error during eAPI connection: The read operation timed out
    
    opened by lvrfrc87 6
  • VRRP module not getting the VRID information from an interface

    VRRP module not getting the VRID information from an interface

    Hello,

    I am using the vrrp.get(<interface>).get(vrid) method to collect VRRP group information but it seems it is not retrieving any data. Below I am pasting what I am receiving along with the configuration on the switch:

    Swtich configuration

    interface Vlan177
       load-interval 5
       ip address 10.177.0.68/28
       vrrp 70 priority 200
       vrrp 70 ip 10.177.0.70
       vrrp 70 track ETH46 shutdown
       vrrp 71 priority 200
       vrrp 71 ip 10.177.0.71
       vrrp 71 shutdown
       vrrp 72 priority 200
       vrrp 72 ip 10.177.0.72
       vrrp 72 shutdown
    

    Python Example

    vrrp = node.api('vrrp')
    >>> pprint(vrrp.get('Vlan177').get(71))
    {'bfd_ip': '',
     'delay_reload': None,
     'description': '',
     'enable': True,
     'ip_version': None,
     'mac_addr_adv_interval': 30,
     'preempt': True,
     'preempt_delay_min': 0,
     'preempt_delay_reload': 0,
     'primary_ip': None,
     'priority': None,
     'secondary_ip': [],
     'timers_advertise': None,
     'track': []}
    >>> pprint(vrrp.get('Vlan177').get(70))
    {'bfd_ip': '',
     'delay_reload': None,
     'description': '',
     'enable': True,
     'ip_version': None,
     'mac_addr_adv_interval': 30,
     'preempt': True,
     'preempt_delay_min': 0,
     'preempt_delay_reload': 0,
     'primary_ip': None,
     'priority': None,
     'secondary_ip': [],
     'timers_advertise': None,
     'track': []}
    

    You can see from the collected data that the priority = None, when the configuration is stated as 200, and even though the vrrp 71 shutdown it returns it as enabled = True.

    Was this working before? should I use another method?

    Thanks,

    opened by davidban77 6
  • Connection failure due to bad username/password fails to report reason

    Connection failure due to bad username/password fails to report reason

    Upon attempting to connect with bad credentials, a ConnectionError is reported with the following information:

    pyeapi.eapilib.ConnectionError: unable to connect to eAPI
    

    There could be a few reasons for this, I would imaging, for example, the device not being configured / enabled for eAPI.

    But the actual device response_content value in the underlying eapilib.py file, when debugged, provides the root cause:

    (Pdb) pp(response_content)
    'Unable to authenticate user: Bad username/password combination'
    

    It would be very helpful if this information (response_content) could be bubbled up as an additional argument value to the ConnectionError.

    Thank you!

    opened by jeremyschulman 6
  • Execute does not work well with long running commands

    Execute does not work well with long running commands

    When executing a long-running task, a ConnectionError is intermittently raised. From the python console:

    eapi = pyeapi.connect(transport='http', host='172.20.1.6', username='user', password='pass')
    cmds = ['enable', 'routing-context vrf management', 'copy http://172.20.1.4:8080/images/eos/EOS-4.18.1F.swi flash:']
    
    eapi.execute(commands=cmds, encoding='json')
    {u'jsonrpc': u'2.0', u'result': [{}, {}, {u'messages': [u'Copy completed successfully.']}], u'id': u'4542156176'}
    
    eapi.execute(commands=cmds, encoding='json')
    Traceback (most recent call last):
      File "<input>", line 1, in <module>
      File "/Users/bwatson/Projects/aeon-ztps/venv/lib/python2.7/site-packages/pyeapi/eapilib.py", line 490, in execute
        response = self.send(request)
      File "/Users/bwatson/Projects/aeon-ztps/venv/lib/python2.7/site-packages/pyeapi/eapilib.py", line 423, in send
        raise ConnectionError(str(self), 'unable to connect to eAPI')
    ConnectionError: unable to connect to eAPI
    

    The first copy completed without issue. The second raised a connection error.

    opened by bobbywatson3 6
  • Handle big response

    Handle big response

    Hi team, I am running a command "show ip route bgp" and the response is too big for my client, do you have any good idea to chunk the response? Thanks!

    opened by HanfordWu 0
  • New release to support py3.10

    New release to support py3.10

    develop branch has a fix required for py3.10 to work. https://github.com/arista-eosplus/pyeapi/blob/236503162d1aa3ecc953678ec05380f1f605be02/pyeapi/api/abstract.py#L44

    Is there plans for a release soon?

    question 
    opened by jeffkala 8
  • Support for login token to avoid login for each command

    Support for login token to avoid login for each command

    We are observing that for each EAPI request we make in case of offbox, the remote switch is making one login which results in one authentication request to TACACS, in case that is configured. Please confirm this is the expected behavior currently.

    This issue is a request to enhance this, such that EAPI server returns an authentication token that can be reused by clients and thus avoiding doing one login per request..

    enhancement 
    opened by Ragsboss 1
  • Add support for multiple/secondary Ip-addresses in ipinterfaces() function

    Add support for multiple/secondary Ip-addresses in ipinterfaces() function

    Hello, Im trying to get my secondary ip's configured from the api('ipinterfaces').get(interface) function, however it only returns the first it finds as per the def _parse_address function.

    Or is there another way to get all actual ip's configured via api and not parse the configuration with the client enable('show running-config') function?

    Can it perhaps be changed to also return a key with a list of secondary ip-addresses if one exists?

    Actual config:

    interface Loopback0 mtu 1554 ip address 10.128.6.1/32 ip address 10.255.255.1/24 secondary

    the api call:

    arista_device.api('ipinterfaces').get(name='Loopback0') {'name': 'Loopback0', 'address': '10.128.6.1/32', 'mtu': 1554}

    enhancement 
    opened by King-Joakim 0
  • Unable to process parallel requests over the same session

    Unable to process parallel requests over the same session

    When issuing two concomitant requests over the same eAPI session I can get the following errors:

      File "/usr/local/lib/python2.7/dist-packages/pyeapi/client.py", line 730, in run_commands
        response = self._connection.execute(commands, encoding, **kwargs)
      File "/usr/local/lib/python2.7/dist-packages/pyeapi/eapilib.py", line 495, in execute
        response = self.send(request)
      File "/usr/local/lib/python2.7/dist-packages/pyeapi/eapilib.py", line 388, in send
        response = self.transport.getresponse(buffering=True)
      File "/usr/lib/python2.7/httplib.py", line 1099, in getresponse
        raise ResponseNotReady()
    ResponseNotReady
    
      File "/usr/local/lib/python2.7/dist-packages/pyeapi/client.py", line 730, in run_commands
        response = self._connection.execute(commands, encoding, **kwargs)
      File "/usr/local/lib/python2.7/dist-packages/pyeapi/eapilib.py", line 495, in execute
        response = self.send(request)
      File "/usr/local/lib/python2.7/dist-packages/pyeapi/eapilib.py", line 372, in send
        self.transport.putrequest('POST', '/command-api')
      File "/usr/lib/python2.7/httplib.py", line 921, in putrequest
        raise CannotSendRequest()
    CannotSendRequest
    

    or

      File "/usr/local/lib/python2.7/dist-packages/pyeapi/client.py", line 730, in run_commands
        response = self._connection.execute(commands, encoding, **kwargs)
      File "/usr/local/lib/python2.7/dist-packages/pyeapi/eapilib.py", line 495, in execute
        response = self.send(request)
      File "/usr/local/lib/python2.7/dist-packages/pyeapi/eapilib.py", line 392, in send
        response_content = response.read()
      File "/usr/lib/python2.7/httplib.py", line 578, in read
        return self._read_chunked(amt)
      File "/usr/lib/python2.7/httplib.py", line 636, in _read_chunked
        value.append(self._safe_read(chunk_left))
      File "/usr/lib/python2.7/httplib.py", line 693, in _safe_read
        chunk = self.fp.read(min(amt, MAXAMOUNT))
    AttributeError: 'NoneType' object has no attribute 'read'
    

    For the moment I would only like to understand if this is known, desired or should be corrected.

    Thanks!

    opened by mirceaulinic 12
Releases(v0.8.4)
  • v0.8.4(Nov 13, 2020)

  • v0.8.3(Jan 26, 2020)

  • v0.8.2(Feb 9, 2018)

  • v0.8.1(Jul 21, 2017)

    • Fixes bug that breaks unix-socket connection.
    • Allows commands sent as unicode to be used.
    • Updated error messages for commands that timeout.
    Source code(tar.gz)
    Source code(zip)
  • v0.8.0(Mar 14, 2017)

    • Adds VRF API
    • Allows creation of Ethernet subinterfaces
    • Allow usage of expandAliases and autoComplete parameters
    • Adds extended ACL support
    Source code(tar.gz)
    Source code(zip)
  • v0.7.0(Sep 8, 2016)

  • v0.6.1(Mar 4, 2016)

  • v0.6.0(Feb 22, 2016)

    This is a targeted release to enhance the client.run_commands method. This method will now take MULTILINE commands where the command and input need to be split.

    Release Notes: http://pyeapi.readthedocs.org/en/latest/release-notes-0.6.0.html

    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(Feb 17, 2016)

  • v0.4.0(Nov 6, 2015)

Owner
Arista Networks EOS+
Applications developed and supported by Arista EOS+
Arista Networks EOS+
Its The Basic Commands Of Termux

Its The Basic Commands Of Termux

ANKIT KUMAR 1 Dec 27, 2021
a small cli to generate AWS Well Architected Reports on the road

well-architected-review This repo intends to publish some scripts related to Well Architected Reviews. war.py extracts in txt & xlsx files all the WAR

4 Mar 18, 2022
The Research PACS on AWS solution facilitates researchers' access medical images stored in the clinical PACS in a secure and seamless manner

Research PACS on AWS Challenge to solve Solution presentation Deploy the solution Further reading Releases License Challenge to solve The rise of new

AWS Samples 23 Sep 09, 2022
Python Client for Yandex Cloud Logging

Python Client for Yandex Cloud Logging Installation pip3 install python-yandex-cloud-logging Creating a Yandex Cloud Logging Group yc logging group c

MCode 0 Dec 08, 2021
Discord Selfbot, 90+ commands

Setting the bot up. STEP 1: copy the directory yook.club selfbot was downloaded and extracted into, open cmd and type "cd " then paste. STEP 2: python

yook 1 Dec 12, 2021
A Python Library to interface with Flickr REST API, OAuth & JSON Responses

Python-Flickr Python-Flickr is A Python library to interface with Flickr REST API & OAuth Features Photo Uploading Retrieve user information Common Fl

Mike Helmick 40 Sep 25, 2021
Скрипт, позволяющий импортировать плейлисты из Spotify, а также обычные треклисты в VK музыку.

vk-music-import Программа для переноса плейлистов из Spotify и текстовых треклистов в VK Музыку. Преимущества: Позволяет быстро импортировать плейлист

Mew Forest 32 Nov 23, 2022
Python based league of legends orbwalker

League of Legends Orbwalker Usage Install python3 Create a python3 venv Install the requirements pip install -r requirements.txt Get in game and run m

Inusha 43 Dec 12, 2022
A Python library for the Docker Engine API

Docker SDK for Python A Python library for the Docker Engine API. It lets you do anything the docker command does, but from within Python apps – run c

Docker 6.1k Jan 03, 2023
🪣 Bitbucket Server PAT Generator

🪣 Bitbucket Server PAT Generator 🤝 Introduction Bitbucket Server (nee Stash) can hand out Personal Access Tokens (PAT) to be used in-place of user+p

reecetech 2 May 03, 2022
Automatically compile an AWS Service Control Policy that ONLY allows AWS services that are compliant with your preferred compliance frameworks.

aws-allowlister Automatically compile an AWS Service Control Policy that ONLY allows AWS services that are compliant with your preferred compliance fr

Salesforce 189 Dec 08, 2022
Python script to scrape users/id/badges/creation-date from a Discord Server Memberlist

Discord Server Badges Scraper - Credits to bytixo he made this Custom Discord Vanity Creator How To Use Install discum 1.2 Open a terminal and execute

apolo 13 Dec 09, 2022
派蒙Bot / PaimonBot

派蒙Bot / PaimonBot 基于Mrs4s / go-cqhttp 和 nonebot / nonebot2 的原神QQ群聊机器人 特别鸣谢 MingxuanGame 的人物武器名字自动纠正功能 小灰灰 的人物武器信息api 环境 请务必使用Python3.7以上版本!! 尽量在linux下

晓轩 96 Dec 16, 2022
QR login for pyrogram client

Generate Pyrogram session via QRlogin

ポキ 18 Oct 21, 2022
A very simple Salesforce.com REST API client for Python

Simple Salesforce Simple Salesforce is a basic Salesforce.com REST API client built for Python 3.5, 3.6, 3.7 and 3.8. The goal is to provide a very lo

simple salesforce 1.4k Dec 29, 2022
A bot which is a ghost and you can make friends with it

This is a bot which is a ghost and you can make friends with it. It will haunt your friends. Explore and test the bot in replit !

Siwan SR 0 Oct 06, 2022
Fully Automated Omegle Chatbot

omegle-bot tutorial features fast runs in background can run multiple instances at once Requirement Run this command in cmd, terminal or PowerShell (i

6 Aug 07, 2021
OpenVisionAPI client

OpenVisionAPI Client 🚀 Getting Started Prerequisites Installing Install the dependencies $ make setup Usage $ source .venv/bin/activate $ ./ova_clie

Open Vision API 40 Nov 11, 2022
A bot to display per user data from the Twitch Leak

twitch-leak-bot-discord A bot to display per user data from the Twitch Leak by username Where's the data? I can't and don't want to supply the .csv's

SSSEAL-C 0 Nov 08, 2022
troposphere - Python library to create AWS CloudFormation descriptions

troposphere - Python library to create AWS CloudFormation descriptions

4.8k Jan 06, 2023