Hello community, here is the log from the commit of package python-pyeapi for openSUSE:Factory checked in at 2020-11-17 21:26:22 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pyeapi (Old) and /work/SRC/openSUSE:Factory/.python-pyeapi.new.24930 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pyeapi" Tue Nov 17 21:26:22 2020 rev:3 rq:848969 version:0.8.4 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pyeapi/python-pyeapi.changes 2020-01-27 20:16:53.572502571 +0100 +++ /work/SRC/openSUSE:Factory/.python-pyeapi.new.24930/python-pyeapi.changes 2020-11-17 21:26:24.465444606 +0100 @@ -1,0 +2,7 @@ +Sat Nov 14 13:15:51 UTC 2020 - Martin Hauke <mar...@gmx.de> + +- Update to version 0.8.4 + * Fix deprecated 'collections' dependancy + * Power support(ppc64le) with continuous integration + +------------------------------------------------------------------- Old: ---- pyeapi-0.8.3.tar.gz New: ---- pyeapi-0.8.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pyeapi.spec ++++++ --- /var/tmp/diff_new_pack.foF9eo/_old 2020-11-17 21:26:25.093445228 +0100 +++ /var/tmp/diff_new_pack.foF9eo/_new 2020-11-17 21:26:25.093445228 +0100 @@ -1,8 +1,8 @@ # # spec file for package python-pyeapi # -# Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany. -# Copyright (c) 2017-2019, Martin Hauke <mar...@gmx.de> +# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2017-2020, Martin Hauke <mar...@gmx.de> # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-pyeapi -Version: 0.8.3 +Version: 0.8.4 Release: 0 Summary: Python Client for eAPI License: BSD-3-Clause ++++++ pyeapi-0.8.3.tar.gz -> pyeapi-0.8.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyeapi-0.8.3/.travis.yml new/pyeapi-0.8.4/.travis.yml --- old/pyeapi-0.8.3/.travis.yml 2020-01-26 13:17:29.000000000 +0100 +++ new/pyeapi-0.8.4/.travis.yml 2020-11-13 13:47:17.000000000 +0100 @@ -1,8 +1,10 @@ language: python - +arch: + - amd64 + - ppc64le python: - '2.7' - - '3.8' + - '3.9' install: pip install -r dev-requirements.txt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyeapi-0.8.3/VERSION new/pyeapi-0.8.4/VERSION --- old/pyeapi-0.8.3/VERSION 2020-01-26 13:17:29.000000000 +0100 +++ new/pyeapi-0.8.4/VERSION 2020-11-13 13:47:17.000000000 +0100 @@ -1 +1 @@ -0.8.3 +0.8.3-rc0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyeapi-0.8.3/docs/configsessions.rst new/pyeapi-0.8.4/docs/configsessions.rst --- old/pyeapi-0.8.3/docs/configsessions.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/pyeapi-0.8.4/docs/configsessions.rst 2020-11-13 13:47:17.000000000 +0100 @@ -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. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyeapi-0.8.3/pyeapi/api/interfaces.py new/pyeapi-0.8.4/pyeapi/api/interfaces.py --- old/pyeapi-0.8.3/pyeapi/api/interfaces.py 2020-01-26 13:17:29.000000000 +0100 +++ new/pyeapi-0.8.4/pyeapi/api/interfaces.py 2020-11-13 13:47:17.000000000 +0100 @@ -831,7 +831,7 @@ * udp_port (int): The vxlan udp-port value * vlans (dict): The vlan to vni mappings * flood_list (list): The list of global VTEP flood list - * multicast_decap (bool): If the mutlicast decap + * multicast_decap (bool): If the multicast decap feature is configured Args: @@ -884,7 +884,7 @@ return dict(multicast_group=value) def _parse_multicast_decap(self, config): - value = 'vxlan mutlicast-group decap' in config + value = 'vxlan multicast-group decap' in config return dict(multicast_decap=bool(value)) def _parse_udp_port(self, config): @@ -1064,7 +1064,7 @@ True if the command completes successfully """ - cmd = 'vxlan vlan %s vni %s' % (vid, vni) + cmd = 'vxlan vlan add %s vni %s' % (vid, vni) return self.configure_interface(name, cmd) def remove_vlan(self, name, vid): @@ -1080,7 +1080,7 @@ True if the command completes successfully """ - return self.configure_interface(name, 'no vxlan vlan %s vni' % vid) + return self.configure_interface(name, 'vxlan vlan remove %s vni' % vid) INTERFACE_CLASS_MAP = { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyeapi-0.8.3/pyeapi/client.py new/pyeapi-0.8.4/pyeapi/client.py --- old/pyeapi-0.8.3/pyeapi/client.py 2020-01-26 13:17:29.000000000 +0100 +++ new/pyeapi-0.8.4/pyeapi/client.py 2020-11-13 13:47:17.000000000 +0100 @@ -48,7 +48,7 @@ >>> import pyeapi >>> conn = pyeapi.connect(host='10.1.1.1', transport='http') - >>> conn.execute(['show verson']) + >>> conn.execute(['show version']) {u'jsonrpc': u'2.0', u'result': [{u'memTotal': 2028008, u'version': u'4.14.5F', u'internalVersion': u'4.14.5F-2209869.4145F', u'serialNumber': u'', u'systemMacAddress': u'00:0c:29:f5:d2:7d', u'bootupTimestamp': @@ -90,6 +90,7 @@ contains the settings for nodes used by the connect_to function. """ +from uuid import uuid4 import os import re @@ -471,6 +472,7 @@ self._version = None self._version_number = None self._model = None + self._session_name = None self._enablepwd = kwargs.get('enablepwd') self.autorefresh = kwargs.get('autorefresh', True) @@ -578,6 +580,14 @@ output from each command. The function will strip the response from any commands it prepends. """ + if self._session_name: # If in a config session + return self._configure_session(commands, **kwargs) + + return self._configure_terminal(commands, **kwargs) + + def _configure_terminal(self, commands, **kwargs): + """Configures the node with the specified commands with leading "configure terminal" + """ commands = make_iterable(commands) commands = list(commands) @@ -593,6 +603,24 @@ return response + def _configure_session(self, commands, **kwargs): + """Configures the node with the specified commands with leading "configure session <session name>" + """ + if not self._session_name: + raise CommandError('Not currently in a session') + + commands = make_iterable(commands) + commands = list(commands) + + # push the configure command onto the command stack + commands.insert(0, 'configure session %s' % self._session_name) + response = self.run_commands(commands, **kwargs) + + # pop the configure command output off the stack + response.pop(0) + + return response + def section(self, regex, config='running_config'): """Returns a section of the config @@ -824,6 +852,41 @@ self._running_config = None self._startup_config = None + def configure_session(self): + """Enter a config session + """ + self._session_name = self._session_name or uuid4() + + def diff(self): + """Returns session-config diffs in text encoding + + Note: "show session-config diffs" doesn't support json encoding + """ + response = self._configure_session(['show session-config diffs'], encoding='text') + + return response[0]['output'] + + def commit(self): + """Commits the current config session + """ + return self._configure_and_exit_session(['commit']) + + def abort(self): + """Aborts the current config session + """ + return self._configure_session(['abort']) + + def _configure_and_exit_session(self, commands, **kwargs): + response = self._configure_session(commands, **kwargs) + + if self.autorefresh: + self.refresh() + + # Exit the current config session + self._session_name = None + + return response + def connect_to(name): """Creates a node instance based on an entry from the config diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyeapi-0.8.3/pyeapi/eapilib.py new/pyeapi-0.8.4/pyeapi/eapilib.py --- old/pyeapi-0.8.3/pyeapi/eapilib.py 2020-01-26 13:17:29.000000000 +0100 +++ new/pyeapi-0.8.4/pyeapi/eapilib.py 2020-11-13 13:47:17.000000000 +0100 @@ -348,12 +348,16 @@ commands = make_iterable(commands) reqid = id(self) if reqid is None else reqid params = {'version': 1, 'cmds': commands, 'format': encoding} + streaming = False if 'autoComplete' in kwargs: params['autoComplete'] = kwargs['autoComplete'] if 'expandAliases' in kwargs: params['expandAliases'] = kwargs['expandAliases'] + if 'streaming' in kwargs: + streaming = kwargs['streaming'] return json.dumps({'jsonrpc': '2.0', 'method': 'runCmds', - 'params': params, 'id': str(reqid)}) + 'params': params, 'id': str(reqid), + 'streaming': streaming}) def send(self, data): """Sends the eAPI request to the destination node diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyeapi-0.8.3/pyeapi/utils.py new/pyeapi-0.8.4/pyeapi/utils.py --- old/pyeapi-0.8.3/pyeapi/utils.py 2020-01-26 13:17:29.000000000 +0100 +++ new/pyeapi-0.8.4/pyeapi/utils.py 2020-11-13 13:47:17.000000000 +0100 @@ -170,8 +170,12 @@ if isinstance(value, str) or isinstance(value, dict): value = [value] - if not isinstance(value, collections.Iterable): - raise TypeError('value must be an iterable object') + if sys.version_info <= (3, 3): + if not isinstance(value, collections.Iterable): + raise TypeError('value must be an iterable object') + else: + if not isinstance(value, collections.abc.Iterable): + raise TypeError('value must be an iterable object') return value diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyeapi-0.8.3/setup.py new/pyeapi-0.8.4/setup.py --- old/pyeapi-0.8.3/setup.py 2020-01-26 13:17:29.000000000 +0100 +++ new/pyeapi-0.8.4/setup.py 2020-11-13 13:47:17.000000000 +0100 @@ -49,7 +49,7 @@ 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.8', ], keywords='networking arista eos eapi', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyeapi-0.8.3/test/system/test_api_interfaces.py new/pyeapi-0.8.4/test/system/test_api_interfaces.py --- old/pyeapi-0.8.3/test/system/test_api_interfaces.py 2020-01-26 13:17:29.000000000 +0100 +++ new/pyeapi-0.8.4/test/system/test_api_interfaces.py 2020-11-13 13:47:17.000000000 +0100 @@ -635,7 +635,7 @@ api = dut.api('interfaces') instance = api.update_vlan('Vxlan1', '10', '10') self.assertTrue(instance) - self.contains('vxlan vlan 10 vni 10', dut) + self.contains('vxlan vlan add 10 vni 10', dut) def test_remove_vlan(self): for dut in self.duts: @@ -643,7 +643,7 @@ api = dut.api('interfaces') instance = api.remove_vlan('Vxlan1', '10') self.assertTrue(instance) - self.notcontains('vxlan vlan 10 vni 10', dut) + self.notcontains('vxlan vlan remove 10 vni 10', dut) if __name__ == '__main__': diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyeapi-0.8.3/test/unit/test_api_interfaces.py new/pyeapi-0.8.4/test/unit/test_api_interfaces.py --- old/pyeapi-0.8.3/test/unit/test_api_interfaces.py 2020-01-26 13:17:29.000000000 +0100 +++ new/pyeapi-0.8.4/test/unit/test_api_interfaces.py 2020-11-13 13:47:17.000000000 +0100 @@ -501,12 +501,12 @@ self.eapi_positive_config_test(func, cmds) def test_update_vlan(self): - cmds = ['interface Vxlan1', 'vxlan vlan 10 vni 10'] + cmds = ['interface Vxlan1', 'vxlan vlan add 10 vni 10'] func = function('update_vlan', 'Vxlan1', 10, 10) self.eapi_positive_config_test(func, cmds) def test_remove_vlan(self): - cmds = ['interface Vxlan1', 'no vxlan vlan 10 vni'] + cmds = ['interface Vxlan1', 'vxlan vlan remove 10 vni'] func = function('remove_vlan', 'Vxlan1', 10) self.eapi_positive_config_test(func, cmds) _______________________________________________ openSUSE Commits mailing list -- commit@lists.opensuse.org To unsubscribe, email commit-le...@lists.opensuse.org List Netiquette: https://en.opensuse.org/openSUSE:Mailing_list_netiquette List Archives: https://lists.opensuse.org/archives/list/commit@lists.opensuse.org