Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-junos-eznc for openSUSE:Factory checked in at 2023-03-02 23:04:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-junos-eznc (Old) and /work/SRC/openSUSE:Factory/.python-junos-eznc.new.31432 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-junos-eznc" Thu Mar 2 23:04:02 2023 rev:14 rq:1068621 version:2.6.7 Changes: -------- --- /work/SRC/openSUSE:Factory/python-junos-eznc/python-junos-eznc.changes 2022-05-03 21:19:47.849060710 +0200 +++ /work/SRC/openSUSE:Factory/.python-junos-eznc.new.31432/python-junos-eznc.changes 2023-03-02 23:04:27.052137888 +0100 @@ -1,0 +2,29 @@ +Thu Mar 2 07:14:57 UTC 2023 - Daniel Garcia <daniel.gar...@suse.com> + +- Add python-311.patch to support python 3.11, gh#Juniper/py-junos-eznc#1236 +- Remove python-junos-eznc-fix-unittests.patch, not needed anymore +- Update to 2.6.7: + * Supported option to set look_for_keys with bool True/False #1234 + * Fixed build failure against setuptools #1231 +- 2.6.6 + * Fixed reboot failing on other RE #1199 + * Fixed passing 'sleep' arg to StartShell run() #1202 + * Fixed PyEZ get-facts support for ACX model #1209 + * Fixed EthPortTable regex pattern #1215 + * Fixed StartShell UnboundLocalError #1203 #1211 +- 2.6.5 + * Supported multi-gig ports for EthPortTable.yml #1177 + * Fixed on-box support for start shell types #1190 #1186 + * Fixed conn_open_timeout value was getting set None , changed it to + default 30 seconds #1184 +- 2.6.4 + * Supported start_shell options to choose the shell types (sh or csh) #995 + * Supported for python 3.9 + * Fixed Device facts current_re returns the SRX cluster node0 and + node1 details with cluster ID 16 #1135 + * Fixed upgrade ncclient version 0.6.13, updated requirements.txt to + install ncclient==0.6.13 #1153 + * Fixed deprecation warning due to invalid escape sequences #1034 + * Fixed Unit tests test_sw_put_ftp failure #1165 + +------------------------------------------------------------------- Old: ---- python-junos-eznc-2.6.3.tar.gz python-junos-eznc-fix-unittests.patch New: ---- python-311.patch python-junos-eznc-2.6.7.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-junos-eznc.spec ++++++ --- /var/tmp/diff_new_pack.3RQdKp/_old 2023-03-02 23:04:27.836141804 +0100 +++ /var/tmp/diff_new_pack.3RQdKp/_new 2023-03-02 23:04:27.840141824 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-junos-eznc # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2023 SUSE LLC # Copyright (c) 2017-2020, Martin Hauke <mar...@gmx.de> # # All modifications and additions to the file contributed by third parties @@ -17,10 +17,9 @@ # -%{?!python_module:%define python_module() python-%{**} python3-%{**}} %define skip_python2 1 Name: python-junos-eznc -Version: 2.6.3 +Version: 2.6.7 Release: 0 Summary: Junos 'EZ' automation for non-programmers License: Apache-2.0 @@ -32,14 +31,14 @@ # replace deprecated yamlordereddictloader by yamlloader # https://github.com/Juniper/py-junos-eznc/pull/1078 Patch1: python-junos-eznc-remove-yamlordereddictloader.patch -# https://github.com/Juniper/py-junos-eznc/commit/96f25bb8aa006e12e48902a91a1dc6ff595bdd2d -Patch2: python-junos-eznc-fix-unittests.patch # https://github.com/Juniper/py-junos-eznc/issues/1176 Patch3: python-junos-eznc-no-mock.patch +# PATCH-FIX-OPENSUSE python-311.patch gh#Juniper/py-junos-eznc#1236 +Patch4: python-311.patch BuildRequires: %{python_module Jinja2 >= 2.7.1} BuildRequires: %{python_module PyYAML >= 5.1} BuildRequires: %{python_module lxml >= 3.2.4} -BuildRequires: %{python_module ncclient >= 0.6.9} +BuildRequires: %{python_module ncclient >= 0.6.13} BuildRequires: %{python_module netaddr} BuildRequires: %{python_module ntc-templates} BuildRequires: %{python_module paramiko >= 1.15.2} @@ -57,7 +56,7 @@ Requires: python-Jinja2 >= 2.7.1 Requires: python-PyYAML >= 5.1 Requires: python-lxml >= 3.2.4 -Requires: python-ncclient >= 0.6.9 +Requires: python-ncclient >= 0.6.13 Requires: python-netaddr Requires: python-ntc-templates Requires: python-paramiko >= 1.15.2 ++++++ python-junos-eznc-fix-unittests.patch -> python-311.patch ++++++ --- /work/SRC/openSUSE:Factory/python-junos-eznc/python-junos-eznc-fix-unittests.patch 2022-05-03 21:19:47.801060650 +0200 +++ /work/SRC/openSUSE:Factory/.python-junos-eznc.new.31432/python-311.patch 2023-03-02 23:04:26.936137308 +0100 @@ -1,70 +1,32 @@ -diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml -index daaf86ae2..b6f561ba9 100644 ---- a/.github/workflows/pylint.yml -+++ b/.github/workflows/pylint.yml -@@ -14,7 +14,7 @@ jobs: - strategy: - matrix: - os: [ubuntu-latest, windows-latest] -- python-version: [3.7, 3.8] -+ python-version: [3.7, 3.8, 3.9] - exclude: - - os: windows-latest - python-version: 3.8 -@@ -38,7 +38,7 @@ jobs: - - name: Run black tool - run: | - pip install -U black; -- black --check --exclude=docs/* . -+ black --check --diff --exclude="docs|build|tests|samples" . - - - name: Run unit tests - run: | -diff --git a/lib/jnpr/junos/factory/table.py b/lib/jnpr/junos/factory/table.py -index 724c3d988..72eb6d79b 100644 ---- a/lib/jnpr/junos/factory/table.py -+++ b/lib/jnpr/junos/factory/table.py -@@ -245,7 +245,9 @@ def savexml(self, path, hostname=False, timestamp=False, append=None): - fname += "_%s" % append +Index: py-junos-eznc-2.6.7/lib/jnpr/junos/device.py +=================================================================== +--- py-junos-eznc-2.6.7.orig/lib/jnpr/junos/device.py ++++ py-junos-eznc-2.6.7/lib/jnpr/junos/device.py +@@ -43,6 +43,11 @@ from jnpr.junos.exception import JSONLoa + from ncclient.operations.third_party.juniper.rpc import ExecuteRpc + import inspect - path = fname + fext -- return etree.ElementTree(self.xml).write(open(path, "wb")) -+ with open(path, "wb+") as f: -+ pass -+ return etree.ElementTree(self.xml).write(path) ++# Python 3.11 compatibility ++# gh#Juniper/py-junos-eznc#1236 ++if not hasattr(inspect, "getargspec"): ++ inspect.getargspec = inspect.getfullargspec ++ + if sys.version_info.major >= 3: + NCCLIENT_FILTER_XML = len(inspect.signature(ExecuteRpc.request).parameters) == 3 + else: +Index: py-junos-eznc-2.6.7/lib/jnpr/junos/utils/scp.py +=================================================================== +--- py-junos-eznc-2.6.7.orig/lib/jnpr/junos/utils/scp.py ++++ py-junos-eznc-2.6.7/lib/jnpr/junos/utils/scp.py +@@ -1,6 +1,11 @@ + from __future__ import absolute_import + import inspect - def to_json(self): - """ -diff --git a/tests/unit/factory/test_table.py b/tests/unit/factory/test_table.py -index 25e8b1b18..870a723ed 100644 ---- a/tests/unit/factory/test_table.py -+++ b/tests/unit/factory/test_table.py -@@ -139,9 +139,9 @@ def test_table_get_RuntimeError(self): - def test_table_savexml(self, mock_file, mock_execute): - mock_execute.side_effect = self._mock_manager - self.ppt.xml = etree.XML("<root><a>test</a></root>") -- self.ppt.savexml("/vasr/tmssp/foo.xml", hostname=True, append="test") -- mock_file.assert_called_once_with("/vasr/tmssp/foo_1.1.1.1_test.xml", "wb") -- self.ppt.savexml("/vasr/tmssp/foo.xml", hostname=True, timestamp=True) -+ self.ppt.savexml("foo.xml", hostname=True, append="test") -+ mock_file.assert_called_once_with("foo_1.1.1.1_test.xml", "wb+") -+ self.ppt.savexml("foo.xml", hostname=True, timestamp=True) - self.assertEqual(mock_file.call_count, 2) ++# Python 3.11 compatibility ++# gh#Juniper/py-junos-eznc#1236 ++if not hasattr(inspect, "getargspec"): ++ inspect.getargspec = inspect.getfullargspec ++ + from scp import SCPClient + from jnpr.junos.utils.ssh_client import open_ssh_client - def _read_file(self, fname): -diff --git a/tests/unit/utils/test_sw.py b/tests/unit/utils/test_sw.py -index f7c566249..c48d6f1a9 100644 ---- a/tests/unit/utils/test_sw.py -+++ b/tests/unit/utils/test_sw.py -@@ -161,7 +161,9 @@ def test_sw_put_ftp(self, mock_ftp_put): - dev.facts = facts - sw = SW(dev) - sw.put(package="test.tgz") -- self.assertTrue(call("test.tgz", "/var/tmp") in mock_ftp_put.mock_calls) -+ self.assertTrue( -+ any("('test.tgz', '/var/tmp')" in str(s) for s in mock_ftp_put.mock_calls) -+ ) - - @patch("jnpr.junos.utils.scp.SCP.__exit__") - @patch("jnpr.junos.utils.scp.SCP.__init__") - ++++++ python-junos-eznc-2.6.3.tar.gz -> python-junos-eznc-2.6.7.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/.github/workflows/pylint.yml new/py-junos-eznc-2.6.7/.github/workflows/pylint.yml --- old/py-junos-eznc-2.6.3/.github/workflows/pylint.yml 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/.github/workflows/pylint.yml 2023-02-28 16:03:43.000000000 +0100 @@ -14,10 +14,12 @@ strategy: matrix: os: [ubuntu-latest, windows-latest] - python-version: [3.7, 3.8] + python-version: [3.7, 3.8, 3.9] exclude: - os: windows-latest python-version: 3.8 + - os: windows-latest + python-version: 3.9 steps: - uses: actions/checkout@v2 @@ -38,7 +40,7 @@ - name: Run black tool run: | pip install -U black; - black --check --exclude=docs/* . + black --check --diff --exclude="docs|build|tests|samples" . - name: Run unit tests run: | diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/.travis.yml new/py-junos-eznc-2.6.7/.travis.yml --- old/py-junos-eznc-2.6.3/.travis.yml 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/.travis.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,40 +0,0 @@ -language: python -matrix: - include: - - python: 3.7 - dist: xenial - - python: 3.8 - dist: xenial - - os: windows - language: shell - python: 3.7 - before_install: - - choco install python3 --version=3.7.4 - - pip install ntc_templates==1.4.1 - - pip install textfsm==0.4.1 - env: - - PATH=/c/Python37:/c/Python37/Scripts:$PATH - - TRAVIS_PYTHON_VERSION=3.7 - - CRYPTOGRAPHY_DONT_BUILD_RUST=1 -addons: - apt: - packages: - - python-dev - - libxml2-dev - - libxslt1-dev - -install: - - "pip install -r development.txt" - - "pip install -r requirements.txt" - - "pip install ." - - if [[ $TRAVIS_PYTHON_VERSION > 3.5 ]]; then pip install -U black; fi - -script: - - if [[ $TRAVIS_PYTHON_VERSION > 3.5 ]]; then black --check --exclude=docs/* . ; fi - - nosetests -v --with-coverage --cover-package=jnpr.junos --cover-inclusive -a unit - -after_success: - coveralls - -notifications: - email: false diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/INSTALL-RHEL.md new/py-junos-eznc-2.6.7/INSTALL-RHEL.md --- old/py-junos-eznc-2.6.3/INSTALL-RHEL.md 1970-01-01 01:00:00.000000000 +0100 +++ new/py-junos-eznc-2.6.7/INSTALL-RHEL.md 2023-02-28 16:03:43.000000000 +0100 @@ -0,0 +1,40 @@ +### Installation on RHEL + +The following are instructions for setting up a system starting from a stock system images. + +These instructions were tested on a 64-bit systems from https://github.com/opscode/bento, and using the _Junos PyEZ_ library version 2.6.4. + +Operating Systems +--------------- +- Red hat Enterprise Linux 8.1 (Ootpa) + +#### Step 1: Install Python and PIP + +##### For Python 3.x: + dnf install python3-pip python3-wheel + +#### Step 2: Install Junos PyEZ + +##### For Python 3.x: + sudo pip3 install junos-eznc + +#### Step 3: Verify + +Once you've completed the above step, you should be able to create a `Device` instance, connect to a Junos system, and display the "facts", as illustrated in the README.md file. + +Enjoy! + +#### Installing from GitHub + +Development code can be installed directly from GitHub based on any branch, commit, or tag. + +***Step 1 and 3 still required.*** +#### Alternate Step 4: Install Junos PyEZ from GitHub + +#### Step 4a: Install Git from OS packages + pip3 install git + +#### Step 4b: Install Junos PyEZ from GitHub + +##### For Python 3.x: + pip3 install git+https://github.com/Juniper/py-junos-eznc.git diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/RELEASE-NOTES.md new/py-junos-eznc-2.6.7/RELEASE-NOTES.md --- old/py-junos-eznc-2.6.3/RELEASE-NOTES.md 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/RELEASE-NOTES.md 2023-02-28 16:03:43.000000000 +0100 @@ -1,3 +1,35 @@ +## Release 2.6.7.dev0 - 9 DEC 2022 +## Features Added + +## Bugs fixed + +## Release 2.6.6 - 9 DEC 2022 +## Bugs fixed +- Fixed reboot failing on other RE #1199 +- Fixed passing 'sleep' arg to StartShell run() #1202 +- Fixed PyEZ get-facts support for ACX model #1209 +- Fixed EthPortTable regex pattern #1215 +- Fixed StartShell UnboundLocalError #1203 #1211 +- +## Release 2.6.5 - 29 JULY 2022 +## Features Added +- Supported multi-gig ports for EthPortTable.yml #1177 + +## Bugs fixed +- Fixed on-box support for start shell types #1190 #1186 +- Fixed conn_open_timeout value was getting set to None , changed to default 30 seconds #1184 + + +## Release 2.6.4 - 9 JUNE 2022 +### Features Added +- Supported start_shell options to choose the shell types (sh or csh) #995 +- Supported for python 3.9 +### Bugs fixed: +- Fixed Device facts current_re returns the SRX cluster node0 and node1 details with cluster ID 16 #1135 +- Fixed upgrade ncclient version 0.6.13, updated requirements.txt to install ncclient==0.6.13 #1153 +- Fixed deprecation warning due to invalid escape sequences #1034 +- Fixed Unit tests test_sw_put_ftp failure #1165 + ## Release 2.4.2.dev0 - 29 APRIL 2020 ## Features Added diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/_version.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/_version.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/_version.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/_version.py 2023-02-28 16:03:43.000000000 +0100 @@ -22,9 +22,9 @@ # setup.py/versioneer.py will grep for the variable names, so they must # each be defined on a line of their own. _version.py will just call # get_keywords(). - git_refnames = " (tag: 2.6.3)" - git_full = "b3bf657784e75e77d6ef0264006537ae8b3f6a1b" - git_date = "2021-09-16 16:08:45 +0530" + git_refnames = " (HEAD -> master, tag: 2.6.7)" + git_full = "0dcf5de507e2da44807823c5dba73ee045f2597a" + git_date = "2023-02-28 20:33:43 +0530" keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} return keywords diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/cfg/phyport/classic.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/cfg/phyport/classic.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/cfg/phyport/classic.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/cfg/phyport/classic.py 2023-02-28 16:03:43.000000000 +0100 @@ -8,7 +8,6 @@ class PhyPortClassic(PhyPortBase): - # ----------------------------------------------------------------------- # XML readers # ----------------------------------------------------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/cfg/phyport/switch.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/cfg/phyport/switch.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/cfg/phyport/switch.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/cfg/phyport/switch.py 2023-02-28 16:03:43.000000000 +0100 @@ -8,7 +8,6 @@ class PhyPortSwitch(PhyPortBase): - PORT_SPEED = { "auto": "auto-negotiation", "10m": "ethernet-10m", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/cfg/resource.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/cfg/resource.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/cfg/resource.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/cfg/resource.py 2023-02-28 16:03:43.000000000 +0100 @@ -13,7 +13,6 @@ class Resource(object): - PROPERTIES = [P_JUNOS_EXISTS, P_JUNOS_ACTIVE] def __init__(self, junos, namevar=None, **kvargs): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/device.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/device.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/device.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/device.py 2023-02-28 16:03:43.000000000 +0100 @@ -430,7 +430,7 @@ if re_name is None: # Still haven't figured it out. Is this a bsys? for re_state in self.facts["current_re"]: - match = re.search("^re\d+$", re_state) + match = re.search(r"^re\d+$", re_state) if match: re_string = "bsys-" + match.group(0) if re_string in self.facts["hostname_info"].keys(): @@ -879,7 +879,7 @@ except ValueError as ex: # when data is {}{.*} types if str(ex).startswith("Extra data"): - return json.loads(re.sub("\s?{\s?}\s?", "", rpc_rsp_e.text)) + return json.loads(re.sub(r"\s?{\s?}\s?", "", rpc_rsp_e.text)) else: raise JSONLoadError(ex, rpc_rsp_e.text) else: @@ -906,7 +906,7 @@ # protocol: operation-failed # error: device asdf not found # </rpc-reply> - if rpc_rsp_e.text is not None and rpc_rsp_e.text.strip() is not "": + if rpc_rsp_e.text is not None and rpc_rsp_e.text.strip() != "": return rpc_rsp_e # no children, so assume it means we are OK return True @@ -1111,6 +1111,15 @@ ): from jnpr.junos.console import Console + if kwargs.get("conn_open_timeout", None): + # Console already supports timeout while opening connections + # via `timeout` parameter. Refer `Console` documentation + # for more details. + + # Note: The actual timeout may appear higher than set timeout as + # the actual timeout is 3*(timeout+2) + kwargs["timeout"] = kwargs.pop("conn_open_timeout") + instance = object.__new__(Console, *args, **kwargs) # Python only calls __init__() if the object returned from # __new__() is an instance of the class in which the __new__() @@ -1198,9 +1207,18 @@ default is ``False`` to use DOM. Select ``True`` to use SAX (if SAX input is provided). + :param int conn_open_timeout: + *OPTIONAL* To specify the timeout in seconds, which will + be used while opening SSH connection to the device + :param bool huge_tree: *OPTIONAL* parse XML with very deep trees and long text content. default is ``False``. + + :param bool look_for_keys: + *OPTIONAL* To disable public key authentication. + default is ``None``. + """ # ---------------------------------------- @@ -1217,6 +1235,8 @@ self._fact_style = kvargs.get("fact_style", "new") self._use_filter = kvargs.get("use_filter", False) self._huge_tree = kvargs.get("huge_tree", False) + self._conn_open_timeout = kvargs.get("conn_open_timeout", 30) + self._look_for_keys = kvargs.get("look_for_keys", None) if self._fact_style != "new": warnings.warn( "fact-style %s will be removed in a future " @@ -1327,7 +1347,7 @@ """ auto_probe = kvargs.get("auto_probe", self._auto_probe) - if auto_probe is not 0: + if auto_probe != 0: if not self.probe(auto_probe): raise EzErrors.ProbeError(self) @@ -1343,6 +1363,13 @@ (self._auth_password is None) and (self._ssh_private_key_file is None) ) + # option to disable ncclient transport ssh authentication + # using public keys look_for_keys=False + if self._look_for_keys is None: + look_for_keys = True + else: + look_for_keys = self._look_for_keys + # open connection using ncclient transport self._conn = netconf_ssh.connect( host=self._hostname, @@ -1353,7 +1380,9 @@ hostkey_verify=False, key_filename=self._ssh_private_key_file, allow_agent=allow_agent, + look_for_keys=look_for_keys, ssh_config=self._sshconf_lkup(), + timeout=self._conn_open_timeout, device_params={ "name": "junos", "local": self.__class__.ON_JUNOS, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/exception.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/exception.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/exception.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/exception.py 2023-02-28 16:03:43.000000000 +0100 @@ -329,7 +329,7 @@ self.ex_msg = str(exception) self.rpc_content = rpc_content self.offending_line = "" - obj = re.search("line (\d+)", self.ex_msg) + obj = re.search(r"line (\d+)", self.ex_msg) if obj: line_no = int(obj.group(1)) rpc_lines = rpc_content.splitlines() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/cfgtable.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/factory/cfgtable.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/cfgtable.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/factory/cfgtable.py 2023-02-28 16:03:43.000000000 +0100 @@ -9,7 +9,6 @@ class CfgTable(Table): - __isfrozen = False # ----------------------------------------------------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/cmdtable.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/factory/cmdtable.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/cmdtable.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/factory/cmdtable.py 2023-02-28 16:03:43.000000000 +0100 @@ -54,7 +54,7 @@ # ------------------------------------------------------------------------- def get(self, *vargs, **kvargs): - """ + r""" Retrieve the XML (string blob under <output> tag of table data from the Device instance and returns back the Table instance - for call-chaining purposes. @@ -339,6 +339,8 @@ :param raw: string blob output from the cli command execution :return: dict of parsed data. """ + command = command.replace("/", "-") + attrs = dict(Command=command, Platform=platform) template = None diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/factory_loader.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/factory/factory_loader.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/factory_loader.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/factory/factory_loader.py 2023-02-28 16:03:43.000000000 +0100 @@ -389,7 +389,6 @@ self._item_views.append(k) def load(self, catalog_dict, envrion={}): - # load the yaml data and extract the item names. these names will # become the new class definitions diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/optable.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/factory/optable.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/optable.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/factory/optable.py 2023-02-28 16:03:43.000000000 +0100 @@ -14,14 +14,13 @@ class OpTable(Table): - # ------------------------------------------------------------------------- # PUBLIC METHODS # ------------------------------------------------------------------------- @checkSAXParserDecorator def get(self, *vargs, **kvargs): - """ + r""" Retrieve the XML table data from the Device instance and returns back the Table instance - for call-chaining purposes. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/state_machine.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/factory/state_machine.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/state_machine.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/factory/state_machine.py 2023-02-28 16:03:43.000000000 +0100 @@ -297,11 +297,11 @@ self._data[master_key][key] = StateMachine(tbl).parse(lines) else: self._table.TITLE = lines[0] - delimiter = self._table.DELIMITER or "\s\s+" + delimiter = self._table.DELIMITER or r"\s\s+" temp_dict = {} pre_space_delimit = self._get_pre_space_delimiter(lines[1]) for line in lines[1:]: - if re.match(pre_space_delimit + "\s+", line): + if re.match(pre_space_delimit + r"\s+", line): break if line.startswith(pre_space_delimit): try: @@ -311,9 +311,9 @@ temp_dict[key] = value except ValueError: regex = ( - "(\d+)\s(.*)" + r"(\d+)\s(.*)" if item_types[0] == int - else "(" ".*)\s(\d+)" + else "(" r".*)\s(\d+)" ) obj = re.search(regex, line) if obj: @@ -455,14 +455,14 @@ user_defined_columns.pop(x) break key = self._get_key(event.kwargs.get("key", self._table.KEY)) - items = re.split("\s\s+", self._lines[1].strip()) + items = re.split(r"\s\s+", self._lines[1].strip()) post_integer_data_types = event.kwargs.get("check", list(map(data_type, items))) index = event.kwargs.get("index", 1) # col_len = len(col_order) columns_list = list(col_order.values()) for index, line in enumerate(self._lines[index:], start=index): - items = re.split("\s\s+", line.strip()) + items = re.split(r"\s\s+", line.strip()) if len(items) >= len(columns_list): if len(items) > len(columns_list): if ( @@ -587,7 +587,7 @@ index = event.kwargs.get("index") post_integer_data_types = event.kwargs.get("check") line = self._lines[index] - items = re.split("\s\s+", line.strip()) + items = re.split(r"\s\s+", line.strip()) post_integer_data_types, pre_integer_data_types = ( list(map(data_type, items)), post_integer_data_types, @@ -620,7 +620,7 @@ TX Packets 512-1023 Octets 526513 """ pre_space_delimit = "" - obj = re.search("(\s+).*", line) + obj = re.search(r"(\s+).*", line) if obj: pre_space_delimit = obj.group(1) return pre_space_delimit @@ -705,10 +705,10 @@ and not self._view.REGEX ): return - delimiter = self._table.DELIMITER or "\s\s+" + delimiter = self._table.DELIMITER or r"\s\s+" pre_space_delimit = self._get_pre_space_delimiter(self._lines[1]) for line in self._lines[1:]: - if re.match(pre_space_delimit + "\s+", line): + if re.match(pre_space_delimit + r"\s+", line): break if line.startswith(pre_space_delimit): try: @@ -722,7 +722,9 @@ elif key in self._table.KEY_ITEMS: self._data[self._view.FIELDS.get(key, key)] = value except ValueError: - regex = "(\d+)\s(.*)" if item_types[0] == int else "(" ".*)\s(\d+)" + regex = ( + r"(\d+)\s(.*)" if item_types[0] == int else "(" r".*)\s(\d+)" + ) obj = re.search(regex, line) if obj: items = obj.groups() @@ -734,7 +736,7 @@ return self._data def parse_using_regex(self, event): - """ + r""" All the regex should add up to match a line Args: @@ -819,7 +821,7 @@ ) def parse_using_item_and_regex(self, event): - """ + r""" when multiple map is provided for regex, they gets added to search each line. But when item is '*' each regex item is used to search given value regular expression in whole string blob. @@ -922,7 +924,7 @@ 'PTP': 0} """ - delimiter = self._table.DELIMITER or "\s\s+" + delimiter = self._table.DELIMITER or r"\s\s+" pre_space_delimit = "" if self._table.TITLE is None: for line in self._lines[1:]: @@ -930,7 +932,7 @@ self._lines = self._lines[self._lines.index(line) + 1 :] break else: - obj = re.search("^(\s+).*", self._lines[1]) + obj = re.search(r"^(\s+).*", self._lines[1]) if obj: pre_space_delimit = obj.group(1) for index, line in enumerate(self._lines[1:]): @@ -981,7 +983,7 @@ self._data[key] = re.search(search, self._raw, re.I | re.M) is not None def _insert_eval_data(self, tmp_dict): - """ + r""" Args: tmp_dict: dictionary of key value from a iteration of view diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/table.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/factory/table.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/table.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/factory/table.py 2023-02-28 16:03:43.000000000 +0100 @@ -245,7 +245,9 @@ fname += "_%s" % append path = fname + fext - return etree.ElementTree(self.xml).write(open(path, "wb")) + with open(path, "wb+") as f: + pass + return etree.ElementTree(self.xml).write(path) def to_json(self): """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/facts/__example.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/facts/__example.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/facts/__example.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/facts/__example.py 2023-02-28 16:03:43.000000000 +0100 @@ -16,6 +16,7 @@ # An import for each fact file must be present in # lib/jnpr/junos/facts/__init__.py + # The file must include a provide_facts() function # The provide_facts() function must return a dictionary. The keys of the # dictionary are each fact that is handled/returned by this module. The value diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/facts/__init__.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/facts/__init__.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/facts/__init__.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/facts/__init__.py 2023-02-28 16:03:43.000000000 +0100 @@ -66,7 +66,7 @@ """ callbacks = {} doc_strings = {} - for (name, module) in sys.modules.items(): + for name, module in sys.modules.items(): if name.startswith("jnpr.junos.facts.") and module is not None: new_doc_strings = module.provides_facts() for key in new_doc_strings: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/facts/current_re.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/facts/current_re.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/facts/current_re.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/facts/current_re.py 2023-02-28 16:03:43.000000000 +0100 @@ -68,6 +68,10 @@ cluster_id_octet = str( (int(device.facts["srx_cluster_id"]) & 0x000F) << 4 ) + if cluster_id_octet == "0": + cluster_id_octet = str( + device.facts["srx_cluster_id"] + ) # node0 will have an IP of # 129.<cluster_id_octet>.0.1 # node1 will have an IP of diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/facts/personality.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/facts/personality.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/facts/personality.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/facts/personality.py 2023-02-28 16:03:43.000000000 +0100 @@ -65,14 +65,14 @@ virtual = True else: virtual = False - elif re.match("SRX\s?(\d){4}", model): + elif re.match(r"SRX\s?(\d){4}", model): srx_model = int(model[-4:]) if srx_model > 5000: personality = "SRX_HIGHEND" else: personality = "SRX_MIDRANGE" virtual = False - elif re.match("SRX\s?(\d){3}", model): + elif re.match(r"SRX\s?(\d){3}", model): personality = "SRX_BRANCH" virtual = False elif re.search("firefly", model, re.IGNORECASE): @@ -87,6 +87,9 @@ elif "JUNOS_NODE_SLICING" == model: personality = "JDM" virtual = True + elif model.startswith("ACX"): + personality = "ACX" + virtual = False return { "personality": personality, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/facts/swver.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/facts/swver.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/facts/swver.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/facts/swver.py 2023-02-28 16:03:43.000000000 +0100 @@ -13,7 +13,7 @@ if "X" == self.type: # assumes form similar to "45-D10", so extract the bits from this - xm = re.match("(\d+)-(\w)(\d+)", self.minor) + xm = re.match(r"(\d+)-(\w)(\d+)", self.minor) if xm is not None: self.minor = tuple([int(xm.group(1)), xm.group(2), int(xm.group(3))]) if len(after_type) < 2: @@ -95,7 +95,7 @@ def version_yaml_representer(dumper, version): - return dumper.represent_mapping(u"tag:yaml.org,2002:map", version.v_dict) + return dumper.represent_mapping("tag:yaml.org,2002:map", version.v_dict) def provides_facts(): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/ofacts/personality.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/ofacts/personality.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/ofacts/personality.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/ofacts/personality.py 2023-02-28 16:03:43.000000000 +0100 @@ -2,14 +2,13 @@ def facts_personality(junos, facts): - model = facts["model"] if model != "Virtual Chassis": examine = model else: for fact in facts: - if re.match("^RE\d", fact): + if re.match(r"^RE\d", fact): examine = facts[fact]["model"] break @@ -34,9 +33,9 @@ persona = "T" elif examine.startswith("PTX"): persona = "PTX" - elif re.match("SRX\s?(\d){4}", examine): + elif re.match(r"SRX\s?(\d){4}", examine): persona = "SRX_HIGHEND" - elif re.match("SRX\s?(\d){3}", examine): + elif re.match(r"SRX\s?(\d){3}", examine): persona = "SRX_BRANCH" elif re.search("firefly", examine, re.IGNORECASE): facts["virtual"] = True diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/ofacts/routing_engines.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/ofacts/routing_engines.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/ofacts/routing_engines.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/ofacts/routing_engines.py 2023-02-28 16:03:43.000000000 +0100 @@ -17,7 +17,6 @@ def facts_routing_engines(junos, facts): - re_facts = ["mastership-state", "status", "model", "up-time", "last-reboot-reason"] master = [] @@ -65,7 +64,7 @@ re_name = re_name + slot_id else: # multi-instance routing platform - m = RE.search("(\d)", x_re_name[0].text) + m = RE.search(r"(\d)", x_re_name[0].text) if vc_info is not None: # => RE0-RE0 | RE0-RE1 re_name = "RE{}-RE{}".format(m.group(0), re.find("slot").text) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/ofacts/swver.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/ofacts/swver.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/ofacts/swver.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/ofacts/swver.py 2023-02-28 16:03:43.000000000 +0100 @@ -64,7 +64,6 @@ facts["hostname"] = x_swver.findtext(".//software-information/host-name") for re_sw in x_swver.xpath(".//software-information"): - re_name = re_sw.xpath("preceding-sibling::re-name")[0].text # handle the cases where the "RE name" could be things like diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/op/ethport.yml new/py-junos-eznc-2.6.7/lib/jnpr/junos/op/ethport.yml --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/op/ethport.yml 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/op/ethport.yml 2023-02-28 16:03:43.000000000 +0100 @@ -3,7 +3,7 @@ rpc: get-interface-information args: media: True - interface_name: '[afgxe][et]-*' + interface_name: '[afgxe][et]-*' args_key: interface_name item: physical-interface view: EthPortView diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/rpcmeta.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/rpcmeta.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/rpcmeta.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/rpcmeta.py 2023-02-28 16:03:43.000000000 +0100 @@ -6,7 +6,6 @@ class _RpcMetaExec(object): - # ----------------------------------------------------------------------- # CONSTRUCTOR # ----------------------------------------------------------------------- @@ -154,7 +153,7 @@ self._junos.transform = transform # in case of model provided top level should be data # return response - if model and filter_xml is None and options.get("format") is not "json": + if model and filter_xml is None and options.get("format") != "json": response = response.getparent() response.tag = "data" return response diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/transport/tty.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/transport/tty.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/transport/tty.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/transport/tty.py 2023-02-28 16:03:43.000000000 +0100 @@ -44,17 +44,17 @@ _ST_TTY_OPTION = 7 _ST_TTY_HOTKEY = 8 - _re_pat_login = "(?P<login>ogin:\s*$)" + _re_pat_login = r"(?P<login>ogin:\s*$)" _RE_PAT = [ - "(?P<loader>oader>\s*$)", + r"(?P<loader>oader>\s*$)", _re_pat_login, - "(?P<passwd>assword:\s*$)", + r"(?P<passwd>assword:\s*$)", "(?P<badpasswd>ogin incorrect)", - "(?P<netconf_closed><!-- session end at .*-->\s*)", - "(?P<shell>%|#|(~\$)\s*$)", + r"(?P<netconf_closed><!-- session end at .*-->\s*)", + r"(?P<shell>%|#|(~\$)\s*$)", '(?P<cli>[^\\-"]>\s*$)', - "(?P<option>Enter your option:\s*$)", + r"(?P<option>Enter your option:\s*$)", "(?P<hotkey>connection: <CTRL>Z)", ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/utils/config.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/utils/config.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/utils/config.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/utils/config.py 2023-02-28 16:03:43.000000000 +0100 @@ -484,7 +484,7 @@ kvargs["format"] = "xml" elif re.search( r"^\s*(set|delete|rename|insert|activate|deactivate" - "|annotate|copy|protect|unprotect)\s", + r"|annotate|copy|protect|unprotect)\s", rpc, ): kvargs["format"] = "set" @@ -824,7 +824,6 @@ Util.__init__(self, dev=dev) def __enter__(self): - # defining separate functions for each mode so that can be # changed/edited as per the need of corresponding rpc call. def _open_configuration_private(): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/utils/ftp.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/utils/ftp.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/utils/ftp.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/utils/ftp.py 2023-02-28 16:03:43.000000000 +0100 @@ -61,7 +61,7 @@ remote_file = "/tmp/" + mat.group(1) else: if re.search("^.*/(.*)$", remote_path) and re.search( - "\.\w+$", remote_path + r"\.\w+$", remote_path ): remote_file = remote_path # Looks like remote path is given as file location diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/utils/scp.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/utils/scp.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/utils/scp.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/utils/scp.py 2023-02-28 16:03:43.000000000 +0100 @@ -59,7 +59,6 @@ print(self._junos.hostname + ": " + report) def _scp_progress(self, _path, _total, _xfrd): - # calculate current percentage xferd pct = int(float(_xfrd) / float(_total) * 100) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/utils/start_shell.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/utils/start_shell.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/utils/start_shell.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/utils/start_shell.py 2023-02-28 16:03:43.000000000 +0100 @@ -2,9 +2,13 @@ import re import datetime from jnpr.junos.utils.ssh_client import open_ssh_client +import subprocess +import six +from threading import Thread +import time _JUNOS_PROMPT = "> " -_SHELL_PROMPT = "(%|#|\$)\s" +_SHELL_PROMPT = r"(%|#|\$)\s" _SELECT_WAIT = 0.1 _RECVSZ = 1024 @@ -22,7 +26,7 @@ """ - def __init__(self, nc, timeout=30): + def __init__(self, nc, timeout=30, shell_type="csh"): """ Utility Constructor @@ -35,6 +39,12 @@ self.timeout = timeout self._client = None self._chan = None + self.ON_JUNOS = self._nc.__class__.ON_JUNOS + self.shell_type = shell_type + + def write_stdin(self, stdin, data): + stdin.write(data.encode("utf-8")) + stdin.flush() def wait_for(self, this=_SHELL_PROMPT, timeout=0, sleep=0): """ @@ -61,16 +71,21 @@ timeout = timeout or self.timeout timeout = datetime.datetime.now() + datetime.timedelta(seconds=timeout) while timeout > datetime.datetime.now(): - rd, wr, err = select([chan], [], [], _SELECT_WAIT) - if rd: - data = chan.recv(_RECVSZ) - if sleep: - time.sleep(sleep) - if isinstance(data, bytes): - data = data.decode("utf-8", "replace") - got.append(data) - if this is not None and re.search(r"{}\s?$".format(this), data): - break + if self.ON_JUNOS is True: + data = chan.stdout.readline() + else: + rd, wr, err = select([chan], [], [], _SELECT_WAIT) + if rd: + data = chan.recv(_RECVSZ) + else: + continue + if sleep: + time.sleep(sleep) + if isinstance(data, bytes): + data = data.decode("utf-8", "replace") + got.append(data) + if this is not None and re.search(r"{}\s?$".format(this), data): + break return got def send(self, data): @@ -80,8 +95,16 @@ :param str data: the data to write out onto the shell. :returns: result of SSH channel send """ - self._chan.send(data) - self._chan.send("\n") + if self.ON_JUNOS is True: + data += " && echo ']]>]]>' \n" + self._chan.stdin.write(data.encode("utf-8")) + self.t = Thread(target=self.write_stdin, args=(self._chan.stdin, data)) + self.t.daemon = True # thread dies with the program + self.t.start() + return + else: + self._chan.send(data) + self._chan.send("\n") def open(self): """ @@ -89,18 +112,32 @@ drop into the Junos shell (csh). This process opens a :class:`paramiko.SSHClient` instance. """ - self._client = open_ssh_client(dev=self._nc) - self._chan = self._client.invoke_shell() - - got = self.wait_for(r"(%|>|#|\$)") - if got[-1].endswith(_JUNOS_PROMPT): - self.send("start shell") - self.wait_for(_SHELL_PROMPT) + if self.ON_JUNOS is True: + self._chan = subprocess.Popen( + ["cli", "start", "shell", self.shell_type], + shell=False, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + close_fds=1, + bufsize=1, + ) + else: + self._client = open_ssh_client(dev=self._nc) + self._chan = self._client.invoke_shell() + + got = self.wait_for(r"(%|>|#|\$)") + if got[-1].endswith(_JUNOS_PROMPT): + self.send("start shell " + self.shell_type) + self.wait_for(_SHELL_PROMPT) def close(self): """Close the SSH client channel""" - self._chan.close() - self._client.close() + + if self.ON_JUNOS is True: + self._chan.terminate() + else: + self._chan.close() + self._client.close() def run(self, command, this=_SHELL_PROMPT, timeout=0, sleep=0): """ @@ -141,17 +178,23 @@ timeout = timeout or self.timeout # run the command and capture the output self.send(command) - got = "".join(self.wait_for(this, timeout, sleep=sleep)) - self.last_ok = False - if this is None: - self.last_ok = got is not "" - elif this != _SHELL_PROMPT: - self.last_ok = re.search(r"{}\s?$".format(this), got) is not None - elif re.search(r"{}\s?$".format(_SHELL_PROMPT), got) is not None: - # use $? to get the exit code of the command + if self.ON_JUNOS is True: + got = "".join(self.wait_for(this="]]>]]>", timeout=timeout)) self.send("echo $?") - rc = "".join(self.wait_for(_SHELL_PROMPT)) - self.last_ok = rc.find("\r\n0\r\n") > 0 + rc = "".join(self.wait_for(this="]]>]]>")) + self.last_ok = rc.find("0") > 0 + else: + got = "".join(self.wait_for(this, timeout, sleep=sleep)) + self.last_ok = False + if this is None: + self.last_ok = got != "" + elif this != _SHELL_PROMPT: + self.last_ok = re.search(r"{}\s?$".format(this), got) is not None + elif re.search(r"{}\s?$".format(_SHELL_PROMPT), got) is not None: + # use $? to get the exit code of the command + self.send("echo $?") + rc = "".join(self.wait_for(_SHELL_PROMPT)) + self.last_ok = rc.find("\r\n0\r\n") > 0 return (self.last_ok, got) # ------------------------------------------------------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/utils/sw.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/utils/sw.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/utils/sw.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/utils/sw.py 2023-02-28 16:03:43.000000000 +0100 @@ -104,7 +104,7 @@ @classmethod def local_sha256(cls, package): - """ + r""" Computes the SHA-256 value on the package file. :param str package: @@ -117,7 +117,7 @@ @classmethod def local_md5(cls, package): - """ + r""" Computes the MD5 checksum value on the local package file. :param str package: @@ -130,7 +130,7 @@ @classmethod def local_sha1(cls, package): - """ + r""" Computes the SHA1 checksum value on the local package file. :param str package: @@ -143,7 +143,7 @@ @classmethod def local_checksum(cls, package, algorithm="md5"): - """ + r""" Computes the checksum value on the local package file. :param str package: @@ -997,9 +997,9 @@ ok = True, "" # extract the VC number out of the _RE_list vc_members = [ - re.search("(\d+)", x).group(1) + re.search(r"(\d+)", x).group(1) for x in self._RE_list - if re.search("(\d+)", x) + if re.search(r"(\d+)", x) ] for vc_id in vc_members: _progress( @@ -1077,7 +1077,7 @@ """ if other_re is True: if self._dev.facts["2RE"]: - cmd = E("other-routing-engine") + cmd.append(E("other-routing-engine")) elif all_re is True: if self._multi_RE is True and vmhost is True: cmd.append(E("routing-engine", "both")) @@ -1106,7 +1106,7 @@ if i.text is not None ] ) - if output_msg is not "": + if output_msg != "": got = output_msg return got except Exception as err: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/lib/jnpr/junos/version.py new/py-junos-eznc-2.6.7/lib/jnpr/junos/version.py --- old/py-junos-eznc-2.6.3/lib/jnpr/junos/version.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/lib/jnpr/junos/version.py 2023-02-28 16:03:43.000000000 +0100 @@ -1,5 +1,5 @@ -VERSION = "2.5.0" -DATE = "2020-Jun-15" +VERSION = "2.6.7" +DATE = "2023-Feb-28" # Augment with the internal version if present try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/requirements.txt new/py-junos-eznc-2.6.7/requirements.txt --- old/py-junos-eznc-2.6.3/requirements.txt 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/requirements.txt 2023-02-28 16:03:43.000000000 +0100 @@ -1,6 +1,6 @@ lxml>=3.2.4 # ncclient version 0.6.10 has issues with PyEZ(junos-eznc) and needs to be avoided -ncclient==0.6.9 +ncclient==0.6.13 paramiko>=1.15.2 scp>=0.7.0 jinja2>=2.7.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/setup.py new/py-junos-eznc-2.6.7/setup.py --- old/py-junos-eznc-2.6.3/setup.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/setup.py 2023-02-28 16:03:43.000000000 +0100 @@ -24,7 +24,7 @@ "jnpr.junos.cfgro": ["*.yml"], "jnpr.junos.resources": ["*.yml"], }, - python_requires=">=3.*, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*", + python_requires=">=3.5, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*", install_requires=install_reqs, classifiers=[ "Development Status :: 5 - Production/Stable", @@ -39,6 +39,7 @@ "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", "Topic :: Software Development :: Libraries", "Topic :: Software Development :: Libraries :: Application Frameworks", "Topic :: Software Development :: Libraries :: Python Modules", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/tests/functional/test_shell.py new/py-junos-eznc-2.6.7/tests/functional/test_shell.py --- old/py-junos-eznc-2.6.3/tests/functional/test_shell.py 1970-01-01 01:00:00.000000000 +0100 +++ new/py-junos-eznc-2.6.7/tests/functional/test_shell.py 2023-02-28 16:03:43.000000000 +0100 @@ -0,0 +1,49 @@ +__author__ = "jnpr-community-netdev" + +try: + import unittest2 as unittest +except ImportError: + import unittest + +from nose.plugins.attrib import attr +import yaml + + +@attr('functional') +class test(unittest.TestCase): + + @classmethod + def setUpClass(self): + from jnpr.junos import Device + with open("config.yaml", "r") as fyaml: + cfg = yaml.safe_load(fyaml) + self.dev = Device(**cfg) + self.dev.open() + + @classmethod + def tearDownClass(self): + self.dev.close() + + def test_shell_run(self): + from jnpr.junos.utils.start_shell import StartShell + with StartShell(self.dev) as sh: + output = sh.run('pwd') + self.assertTrue(output[0]) + + def test_shell_run_with_sleep(self): + from jnpr.junos.utils.start_shell import StartShell + with StartShell(self.dev) as sh: + output = sh.run('hostname', sleep=2) + self.assertTrue(output[0]) + + def test_shell_run_shell_type_ssh(self): + from jnpr.junos.utils.start_shell import StartShell + with StartShell(self.dev, shell_type="ssh") as sh: + output = sh.run('hostname', sleep=2) + self.assertTrue(output[0]) + + def test_shell_run_shell_type_csh(self): + from jnpr.junos.utils.start_shell import StartShell + with StartShell(self.dev, shell_type="csh") as sh: + output = sh.run('hostname', sleep=2) + self.assertTrue(output[0]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/tests/unit/factory/test_table.py new/py-junos-eznc-2.6.7/tests/unit/factory/test_table.py --- old/py-junos-eznc-2.6.3/tests/unit/factory/test_table.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/tests/unit/factory/test_table.py 2023-02-28 16:03:43.000000000 +0100 @@ -139,9 +139,9 @@ def test_table_savexml(self, mock_file, mock_execute): mock_execute.side_effect = self._mock_manager self.ppt.xml = etree.XML("<root><a>test</a></root>") - self.ppt.savexml("/vasr/tmssp/foo.xml", hostname=True, append="test") - mock_file.assert_called_once_with("/vasr/tmssp/foo_1.1.1.1_test.xml", "wb") - self.ppt.savexml("/vasr/tmssp/foo.xml", hostname=True, timestamp=True) + self.ppt.savexml("foo.xml", hostname=True, append="test") + mock_file.assert_called_once_with("foo_1.1.1.1_test.xml", "wb+") + self.ppt.savexml("foo.xml", hostname=True, timestamp=True) self.assertEqual(mock_file.call_count, 2) def _read_file(self, fname): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/tests/unit/facts/rpc-reply/current_re_srx_primary_get-interface-information.xml new/py-junos-eznc-2.6.7/tests/unit/facts/rpc-reply/current_re_srx_primary_get-interface-information.xml --- old/py-junos-eznc-2.6.3/tests/unit/facts/rpc-reply/current_re_srx_primary_get-interface-information.xml 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/tests/unit/facts/rpc-reply/current_re_srx_primary_get-interface-information.xml 2023-02-28 16:03:43.000000000 +0100 @@ -246,6 +246,9 @@ <ifa-local junos:emit="emit">129.240.0.1/2</ifa-local> </interface-address> <interface-address> + <ifa-local junos:emit="emit">129.16.0.1/2</ifa-local> + </interface-address> + <interface-address> <ifa-local junos:emit="emit">143.240.0.1/2</ifa-local> </interface-address> </address-family> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/tests/unit/facts/test_current_re.py new/py-junos-eznc-2.6.7/tests/unit/facts/test_current_re.py --- old/py-junos-eznc-2.6.3/tests/unit/facts/test_current_re.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/tests/unit/facts/test_current_re.py 2023-02-28 16:03:43.000000000 +0100 @@ -50,6 +50,13 @@ self.assertEqual(self.dev.facts["current_re"], ["node0", "primary"]) @patch("jnpr.junos.Device.execute") + def test_current_re_fact_srx_cluster_primary_id_16(self, mock_execute): + mock_execute.side_effect = self._mock_manager_current_re_srx_primary + self.dev.facts._cache["srx_cluster_id"] = "16" + print(self.dev.facts._cache["srx_cluster_id"]) + self.assertEqual(self.dev.facts["current_re"], ["node0"]) + + @patch("jnpr.junos.Device.execute") def test_current_re_fact_srx_cluster_primary_id_31(self, mock_execute): mock_execute.side_effect = self._mock_manager_current_re_srx_primary self.dev.facts._cache["srx_cluster_id"] = "31" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/tests/unit/facts/test_personality.py new/py-junos-eznc-2.6.7/tests/unit/facts/test_personality.py --- old/py-junos-eznc-2.6.3/tests/unit/facts/test_personality.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/tests/unit/facts/test_personality.py 2023-02-28 16:03:43.000000000 +0100 @@ -121,6 +121,14 @@ self.assertEqual(self.dev.facts["personality"], "MX-GNF") self.assertEqual(self.dev.facts["virtual"], True) + def test_personality_acx(self): + self.dev.facts._cache["model"] = "ACX7908" + self.dev.facts._cache["re_info"] = { + "default": {"default": {"model": "ACX-7900-RE"}} + } + self.assertEqual(self.dev.facts["personality"], "ACX") + self.assertEqual(self.dev.facts["virtual"], False) + @patch("jnpr.junos.Device.execute") def test_personality_vptx(self, mock_execute): mock_execute.side_effect = self._mock_manager_personality_vptx diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/tests/unit/test_device.py new/py-junos-eznc-2.6.7/tests/unit/test_device.py --- old/py-junos-eznc-2.6.3/tests/unit/test_device.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/tests/unit/test_device.py 2023-02-28 16:03:43.000000000 +0100 @@ -466,6 +466,36 @@ @patch("ncclient.manager.connect") @patch("jnpr.junos.Device.execute") + def test_device_open_with_look_for_keys_False(self, mock_connect, mock_execute): + with patch("jnpr.junos.utils.fs.FS.cat") as mock_cat: + mock_cat.return_value = """ + + domain jls.net + + """ + mock_connect.side_effect = self._mock_manager + mock_execute.side_effect = self._mock_manager + self.dev2 = Device(host="2.2.2.2", user="test", password="password123", look_for_keys=False) + self.dev2.open() + self.assertEqual(self.dev2.connected, True) + + @patch("ncclient.manager.connect") + @patch("jnpr.junos.Device.execute") + def test_device_open_with_look_for_keys_True(self, mock_connect, mock_execute): + with patch("jnpr.junos.utils.fs.FS.cat") as mock_cat: + mock_cat.return_value = """ + + domain jls.net + + """ + mock_connect.side_effect = self._mock_manager + mock_execute.side_effect = self._mock_manager + self.dev2 = Device(host="2.2.2.2", user="test", password="password123", look_for_keys=True) + self.dev2.open() + self.assertEqual(self.dev2.connected, True) + + @patch("ncclient.manager.connect") + @patch("jnpr.junos.Device.execute") def test_device_outbound(self, mock_connect, mock_execute): with patch("jnpr.junos.utils.fs.FS.cat") as mock_cat: mock_cat.return_value = """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py-junos-eznc-2.6.3/tests/unit/utils/test_sw.py new/py-junos-eznc-2.6.7/tests/unit/utils/test_sw.py --- old/py-junos-eznc-2.6.3/tests/unit/utils/test_sw.py 2021-09-16 12:38:45.000000000 +0200 +++ new/py-junos-eznc-2.6.7/tests/unit/utils/test_sw.py 2023-02-28 16:03:43.000000000 +0100 @@ -161,7 +161,9 @@ dev.facts = facts sw = SW(dev) sw.put(package="test.tgz") - self.assertTrue(call("test.tgz", "/var/tmp") in mock_ftp_put.mock_calls) + self.assertTrue( + any("('test.tgz', '/var/tmp')" in str(s) for s in mock_ftp_put.mock_calls) + ) @patch("jnpr.junos.utils.scp.SCP.__exit__") @patch("jnpr.junos.utils.scp.SCP.__init__") ++++++ python-junos-eznc-no-mock.patch ++++++ ++++ 657 lines (skipped) ++++ between /work/SRC/openSUSE:Factory/python-junos-eznc/python-junos-eznc-no-mock.patch ++++ and /work/SRC/openSUSE:Factory/.python-junos-eznc.new.31432/python-junos-eznc-no-mock.patch ++++++ python-junos-eznc-remove-nose.patch ++++++ ++++ 818 lines (skipped) ++++ between /work/SRC/openSUSE:Factory/python-junos-eznc/python-junos-eznc-remove-nose.patch ++++ and /work/SRC/openSUSE:Factory/.python-junos-eznc.new.31432/python-junos-eznc-remove-nose.patch