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 2021-10-13 18:06:31
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-junos-eznc (Old)
and /work/SRC/openSUSE:Factory/.python-junos-eznc.new.2443 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-junos-eznc"
Wed Oct 13 18:06:31 2021 rev:11 rq:925095 version:2.6.3
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-junos-eznc/python-junos-eznc.changes
2021-04-27 21:35:27.976063204 +0200
+++
/work/SRC/openSUSE:Factory/.python-junos-eznc.new.2443/python-junos-eznc.changes
2021-10-13 18:11:21.819770904 +0200
@@ -1,0 +2,30 @@
+Wed Oct 13 10:15:04 UTC 2021 - ecsos <[email protected]>
+
+- Update to version 2.6.3
+ * Enhancements done
+ Adding ignore warning for rollback api #1131
+ Add escaped $ Bourne-style shell prompt support #868
+ * Bugs Fixed
+ - Fix for junos versions returning a bool value for config diff
+ if there are no changes #1093
+ - Handle ncclient timeout exception at close. #787
+ - Newer junos versions return a bool for config diff and not
+ etree if there are no changes #1093
+- Changes from 2.6.2
+ * Bugs Fixed
+ - Fix for evo device as Password prompt comes directly during
+ telnet #1112
+- Changes from 2.6.1
+ * Enhancement Added
+ - Flag for json.loads() for special character like newline was
+ made false by default. #1029
+ * Bugs Fixed
+ - Transform function modified only for the rpc and set back to
+ original value. #1108
+ - Skip the values returned in re-list without numbers during
+ multi re software install #1099
+ - getiterator() replaced with iter() as was deprecated in
+ Python 3.2 and removed in Python 3.9 #1110
+- Drop python-junos-eznc-py39xml.patch because now in upstream.
+
+-------------------------------------------------------------------
Old:
----
python-junos-eznc-2.6.0.tar.gz
python-junos-eznc-py39xml.patch
New:
----
python-junos-eznc-2.6.3.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-junos-eznc.spec ++++++
--- /var/tmp/diff_new_pack.Kwkcmc/_old 2021-10-13 18:11:22.239771562 +0200
+++ /var/tmp/diff_new_pack.Kwkcmc/_new 2021-10-13 18:11:22.243771568 +0200
@@ -20,7 +20,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%define skip_python2 1
Name: python-junos-eznc
-Version: 2.6.0
+Version: 2.6.3
Release: 0
Summary: Junos 'EZ' automation for non-programmers
License: Apache-2.0
@@ -32,8 +32,6 @@
# 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/pull/1110
-Patch2: python-junos-eznc-py39xml.patch
BuildRequires: %{python_module Jinja2 >= 2.7.1}
BuildRequires: %{python_module PyYAML >= 5.1}
BuildRequires: %{python_module lxml >= 3.2.4}
++++++ python-junos-eznc-2.6.0.tar.gz -> python-junos-eznc-2.6.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py-junos-eznc-2.6.0/.github/workflows/pylint.yml
new/py-junos-eznc-2.6.3/.github/workflows/pylint.yml
--- old/py-junos-eznc-2.6.0/.github/workflows/pylint.yml 1970-01-01
01:00:00.000000000 +0100
+++ new/py-junos-eznc-2.6.3/.github/workflows/pylint.yml 2021-09-16
12:38:45.000000000 +0200
@@ -0,0 +1,45 @@
+name: Pylint
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+jobs:
+ build:
+
+ runs-on: ${{ matrix.os }}
+
+ strategy:
+ matrix:
+ os: [ubuntu-latest, windows-latest]
+ python-version: [3.7, 3.8]
+ exclude:
+ - os: windows-latest
+ python-version: 3.8
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v2
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install pylint
+ pip install -r requirements.txt
+ pip install -r development.txt
+ pip install ntc_templates==1.4.1
+ pip install textfsm==0.4.1
+ pip install .
+
+ - name: Run black tool
+ run: |
+ pip install -U black;
+ black --check --exclude=docs/* .
+
+ - name: Run unit tests
+ run: |
+ nosetests -v --with-coverage --cover-package=jnpr.junos
--cover-inclusive -a unit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py-junos-eznc-2.6.0/COPYRIGHT
new/py-junos-eznc-2.6.3/COPYRIGHT
--- old/py-junos-eznc-2.6.0/COPYRIGHT 2021-04-22 14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/COPYRIGHT 2021-09-16 12:38:45.000000000 +0200
@@ -1,27 +1,15 @@
- Copyright (c) 1999-2013, Juniper Networks Inc.
+ Copyright (c) 1999-2021, Juniper Networks Inc.
2013, Jeremy Schulman
All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
+ License: Apache 2.0
- * 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 Juniper Networks 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 <copyright holder> ''AS IS'' AND ANY
+ THIS SOFTWARE IS PROVIDED BY Juniper Networks Inc. ''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 <copyright holder> BE LIABLE FOR ANY
+ DISCLAIMED. IN NO EVENT SHALL Juniper Networks Inc. 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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py-junos-eznc-2.6.0/lib/jnpr/junos/_version.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/_version.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/_version.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/_version.py 2021-09-16
12:38:45.000000000 +0200
@@ -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 = " (HEAD -> master, tag: 2.6.0)"
- git_full = "216f611d25349e9c17503f0267b4a5c8d6f91d81"
- git_date = "2021-04-22 18:24:35 +0530"
+ git_refnames = " (tag: 2.6.3)"
+ git_full = "b3bf657784e75e77d6ef0264006537ae8b3f6a1b"
+ git_date = "2021-09-16 16:08:45 +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.0/lib/jnpr/junos/cfg/resource.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/cfg/resource.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/cfg/resource.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/cfg/resource.py 2021-09-16
12:38:45.000000000 +0200
@@ -196,22 +196,22 @@
@property
def D(self):
- """ returns the Device object bound to this resource/manager """
+ """returns the Device object bound to this resource/manager"""
return self._junos
@property
def R(self):
- """ returns the Device RPC meta object """
+ """returns the Device RPC meta object"""
return self._junos.rpc
@property
def M(self):
- """ returns the :Resource: manager associated to this resource """
+ """returns the :Resource: manager associated to this resource"""
return self._manager
@property
def P(self):
- """ returns the parent of the associated Junos object """
+ """returns the parent of the associated Junos object"""
return self._parent
# -----------------------------------------------------------------------
@@ -554,7 +554,7 @@
# ---------------------------------------------------------------------
def __iter__(self):
- """ iterate through each Resource in the Manager list """
+ """iterate through each Resource in the Manager list"""
for name in self.list:
yield self[name]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py-junos-eznc-2.6.0/lib/jnpr/junos/console.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/console.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/console.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/console.py 2021-09-16
12:38:45.000000000 +0200
@@ -319,7 +319,7 @@
self._tty.logout()
def zeroize(self):
- """ perform device ZEROIZE actions """
+ """perform device ZEROIZE actions"""
logger.info("zeroize : ZEROIZE device, rebooting")
self._tty.nc.zeroize()
self._skip_logout = True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py-junos-eznc-2.6.0/lib/jnpr/junos/decorators.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/decorators.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/decorators.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/decorators.py 2021-09-16
12:38:45.000000000 +0200
@@ -176,8 +176,12 @@
restore_value = args[0]._use_filter
args[0]._use_filter = use_filter
try:
+ if args[0].D != None:
+ func = args[0].D.transform
result = function(*args, **kwargs)
args[0]._use_filter = restore_value
+ if args[0].D != None:
+ args[0].D.transform = func
return result
except Exception:
args[0]._use_filter = restore_value
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py-junos-eznc-2.6.0/lib/jnpr/junos/device.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/device.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/device.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/device.py 2021-09-16
12:38:45.000000000 +0200
@@ -247,7 +247,7 @@
@ofacts.setter
def ofacts(self, value):
- """ read-only property """
+ """read-only property"""
raise RuntimeError("facts is read-only!")
# ------------------------------------------------------------------------
@@ -340,7 +340,7 @@
@master.setter
def master(self, value):
- """ read-only property """
+ """read-only property"""
raise RuntimeError("master is read-only!")
# ------------------------------------------------------------------------
@@ -374,7 +374,7 @@
@uptime.setter
def uptime(self, value):
- """ read-only property """
+ """read-only property"""
raise RuntimeError("uptime is read-only!")
# ------------------------------------------------------------------------
@@ -439,7 +439,7 @@
@re_name.setter
def re_name(self, value):
- """ read-only property """
+ """read-only property"""
raise RuntimeError("re_name is read-only!")
def _sshconf_lkup(self):
@@ -875,7 +875,7 @@
or (ver_info.major[0] == 14 and ver_info.major[1] >= 2)
):
try:
- return json.loads(rpc_rsp_e.text)
+ return json.loads(rpc_rsp_e.text, strict=False)
except ValueError as ex:
# when data is {}{.*} types
if str(ex).startswith("Extra data"):
@@ -1427,12 +1427,13 @@
Closes the connection to the device only if connected.
"""
if self.connected is True:
+ self.connected = False
try:
self._conn.close_session()
+ except NcOpErrors.TimeoutExpiredError:
+ raise EzErrors.RpcTimeoutError(self, "close", self.timeout)
except NcErrors.SessionCloseError:
pass
- finally:
- self.connected = False
@ignoreWarnDecorator
def _rpc_reply(self, rpc_cmd_e, filter_xml=None):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py-junos-eznc-2.6.0/lib/jnpr/junos/exception.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/exception.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/exception.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/exception.py 2021-09-16
12:38:45.000000000 +0200
@@ -219,22 +219,22 @@
@property
def user(self):
- """ login user-name """
+ """login user-name"""
return self.dev.user
@property
def host(self):
- """ login host name/ipaddr """
+ """login host name/ipaddr"""
return self.dev.hostname
@property
def port(self):
- """ login SSH port """
+ """login SSH port"""
return self.dev._port
@property
def msg(self):
- """ login SSH port """
+ """login SSH port"""
return self._orig
def __repr__(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/py-junos-eznc-2.6.0/lib/jnpr/junos/factory/cfgtable.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/cfgtable.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/factory/cfgtable.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/cfgtable.py 2021-09-16
12:38:45.000000000 +0200
@@ -70,7 +70,7 @@
@property
def keys_required(self):
- """ True/False - if this Table requires keys """
+ """True/False - if this Table requires keys"""
return self.required_keys is not None
# -----------------------------------------------------------------------
@@ -158,7 +158,7 @@
add_field = self._grindfield(lxpath[-1], field_value)
for _add in add_field:
if len(_add.attrib) > 0:
- for i in dot.getiterator():
+ for i in dot.iter():
if i.tag == _add.tag:
i.attrib.update(_add.attrib)
break
@@ -258,7 +258,7 @@
_validate_min_max_value(field_name, value, opt)
def _grindkey(self, key_xpath, key_value):
- """ returns list of XML elements for key values """
+ """returns list of XML elements for key values"""
simple = lambda: [E(key_xpath.replace("_", "-"), key_value)]
composite = lambda: [
E(xp.replace("_", "-"), xv) for xp, xv in zip(key_xpath, key_value)
@@ -266,7 +266,7 @@
return simple() if isinstance(key_xpath, str) else composite()
def _grindxpath(self, key_xpath, key_value):
- """ returns xpath elements for key values """
+ """returns xpath elements for key values"""
simple = lambda: "[{}='{}']".format(key_xpath.replace("_", "-"),
key_value)
composite = lambda: "[{}]".format(
" and ".join(
@@ -279,7 +279,7 @@
return simple() if isinstance(key_xpath, str) else composite()
def _grindfield(self, xpath, value):
- """ returns list of xml elements for field name-value pairs """
+ """returns list of xml elements for field name-value pairs"""
lst = []
if isinstance(value, (list, tuple, set)):
for v in value:
@@ -359,7 +359,7 @@
return dot
def _keyspec(self):
- """ returns tuple (keyname-xpath, item-xpath) """
+ """returns tuple (keyname-xpath, item-xpath)"""
return (self._data_dict.get("key", "name"),
self._data_dict[self._type])
def _init_field(self):
@@ -371,7 +371,7 @@
self.__dict__[fname] = opt["default"] if "default" in opt else None
def _mandatory_check(self):
- """ Mandatory checks for set table/view """
+ """Mandatory checks for set table/view"""
for key in self.key_field:
value = getattr(self, key)
if value is None:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/py-junos-eznc-2.6.0/lib/jnpr/junos/factory/cmdtable.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/cmdtable.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/factory/cmdtable.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/cmdtable.py 2021-09-16
12:38:45.000000000 +0200
@@ -182,27 +182,27 @@
@property
def D(self):
- """ the Device instance """
+ """the Device instance"""
return self._dev
@property
def CLI(self):
- """ the Device.cli instance """
+ """the Device.cli instance"""
return self.D.cli
@property
def RPC(self):
- """ the Device.rpc instance """
+ """the Device.rpc instance"""
return self.D.rpc
@property
def view(self):
- """ returns the current view assigned to this table """
+ """returns the current view assigned to this table"""
return self._view
@view.setter
def view(self, cls):
- """ assigns a new view to the table """
+ """assigns a new view to the table"""
if cls is None:
self._view = None
return
@@ -218,7 +218,7 @@
@property
def key_list(self):
- """ the list of keys, as property for caching """
+ """the list of keys, as property for caching"""
return self._key_list
# -------------------------------------------------------------------------
@@ -241,7 +241,7 @@
# ------------------------------------------------------------------------
def _keys(self):
- """ return a list of data item keys from the data string """
+ """return a list of data item keys from the data string"""
return self.output.keys()
@@ -259,7 +259,7 @@
# ------------------------------------------------------------------------
def values(self):
- """ returns list of table entry items() """
+ """returns list of table entry items()"""
self._assert_data()
return self.output.values()
@@ -269,7 +269,7 @@
# ------------------------------------------------------------------------
def items(self):
- """ returns list of tuple(name,values) for each table entry """
+ """returns list of tuple(name,values) for each table entry"""
return self.output.items()
def to_json(self):
@@ -299,7 +299,7 @@
return len(self.keys())
def __iter__(self):
- """ iterate over each time in the table """
+ """iterate over each time in the table"""
self._assert_data()
for key, value in self.output.items():
@@ -323,7 +323,7 @@
return self.output[value]
def __contains__(self, key):
- """ membership for use with 'in' """
+ """membership for use with 'in'"""
return bool(key in self.keys())
# ------------------------------------------------------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/py-junos-eznc-2.6.0/lib/jnpr/junos/factory/cmdview.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/cmdview.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/factory/cmdview.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/cmdview.py 2021-09-16
12:38:45.000000000 +0200
@@ -22,17 +22,17 @@
@property
def T(self):
- """ return the Table instance for the View """
+ """return the Table instance for the View"""
return self._table
@property
def D(self):
- """ return the Device instance for this View """
+ """return the Device instance for this View"""
return self.T.D
@property
def xml(self):
- """ returns the XML associated to the item """
+ """returns the XML associated to the item"""
return self._xml
# -------------------------------------------------------------------------
@@ -40,19 +40,19 @@
# -------------------------------------------------------------------------
def keys(self):
- """ list of view keys, i.e. field names """
+ """list of view keys, i.e. field names"""
return self.FIELDS.keys()
def values(self):
- """ list of view values """
+ """list of view values"""
return [getattr(self, field) for field in self.keys()]
def items(self):
- """ list of tuple(key,value) """
+ """list of tuple(key,value)"""
return zip(self.keys(), self.values())
def asview(self, view_cls):
- """ create a new View object for this item """
+ """create a new View object for this item"""
return view_cls(self._table, self._xml)
# -------------------------------------------------------------------------
@@ -60,7 +60,7 @@
# -------------------------------------------------------------------------
def __repr__(self):
- """ returns the name of the View with the associate item name """
+ """returns the name of the View with the associate item name"""
return "%s:%s" % (self.__class__.__name__, self.name)
def __getitem__(self, name):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/py-junos-eznc-2.6.0/lib/jnpr/junos/factory/factory_loader.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/factory_loader.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/factory/factory_loader.py
2021-04-22 14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/factory_loader.py
2021-09-16 12:38:45.000000000 +0200
@@ -86,7 +86,7 @@
def _fieldfunc_Search(self, regex_pattern):
def search_field(field_text):
- """ Returns the first occurrence of regex_pattern within given
field_text."""
+ """Returns the first occurrence of regex_pattern within given
field_text."""
match = re.search(regex_pattern, field_text)
if match:
return match.groups()[0]
@@ -96,7 +96,7 @@
return search_field
def _add_dictfield(self, fields, f_name, f_dict, kvargs):
- """ add a field based on its associated dictionary """
+ """add a field based on its associated dictionary"""
# at present if a field is a <dict> then there is **one
# item** - { the xpath value : the option control }. typically
# the option would be a bultin class type like 'int'
@@ -142,7 +142,7 @@
# ---[ END: _add_dictfield ] ---------------------------------------------
def _add_view_fields(self, view_dict, fields_name, fields):
- """ add a group of fields to the view """
+ """add a group of fields to the view"""
fields_dict = view_dict[fields_name]
try:
# see if this is a 'fields_<group>' collection, and if so
@@ -175,7 +175,7 @@
fields.str(f_name, xpath, **kvargs)
def _add_cmd_view_fields(self, view_dict, fields_name, fields):
- """ add a group of fields to the view """
+ """add a group of fields to the view"""
fields_dict = view_dict[fields_name]
for f_name, f_data in fields_dict.items():
if f_data in self._catalog_dict:
@@ -189,7 +189,7 @@
# -------------------------------------------------------------------------
def _build_view(self, view_name):
- """ build a new View definition """
+ """build a new View definition"""
if view_name in self.catalog:
return self.catalog[view_name]
@@ -225,7 +225,7 @@
# -------------------------------------------------------------------------
def _build_cmdview(self, view_name):
- """ build a new View definition """
+ """build a new View definition"""
if view_name in self.catalog:
return self.catalog[view_name]
@@ -261,7 +261,7 @@
# -----------------------------------------------------------------------
def _build_optable(self, table_name):
- """ build a new Get-Table definition """
+ """build a new Get-Table definition"""
if table_name in self.catalog:
return self.catalog[table_name]
@@ -285,7 +285,7 @@
# -----------------------------------------------------------------------
def _build_cmdtable(self, table_name):
- """ build a new command-Table definition """
+ """build a new command-Table definition"""
if table_name in self.catalog:
return self.catalog[table_name]
@@ -333,7 +333,7 @@
# -----------------------------------------------------------------------
def _build_table(self, table_name):
- """ build a new Table definition """
+ """build a new Table definition"""
if table_name in self.catalog:
return self.catalog[table_name]
@@ -353,7 +353,7 @@
return cls
def _build_cfgtable(self, table_name):
- """ build a new Config-Table definition """
+ """build a new Config-Table definition"""
if table_name in self.catalog:
return self.catalog[table_name]
tbl_dict = deepcopy(self._catalog_dict[table_name])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py-junos-eznc-2.6.0/lib/jnpr/junos/factory/table.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/table.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/factory/table.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/table.py 2021-09-16
12:38:45.000000000 +0200
@@ -43,22 +43,22 @@
@property
def D(self):
- """ the Device instance """
+ """the Device instance"""
return self._dev
@property
def RPC(self):
- """ the Device.rpc instance """
+ """the Device.rpc instance"""
return self.D.rpc
@property
def view(self):
- """ returns the current view assigned to this table """
+ """returns the current view assigned to this table"""
return self._view
@view.setter
def view(self, cls):
- """ assigns a new view to the table """
+ """assigns a new view to the table"""
if cls is None:
self._view = None
return
@@ -82,7 +82,7 @@
@property
def key_list(self):
- """ the list of keys, as property for caching """
+ """the list of keys, as property for caching"""
return self._key_list
# -------------------------------------------------------------------------
@@ -94,7 +94,7 @@
raise RuntimeError("Table is empty, use get()")
def _tkey(self, this, key_list):
- """ keys with missing XPATH nodes are set to None """
+ """keys with missing XPATH nodes are set to None"""
keys = []
for k in key_list:
try:
@@ -107,14 +107,14 @@
return tuple(keys)
def _keys_composite(self, xpath, key_list):
- """ composite keys return a tuple of key-items """
+ """composite keys return a tuple of key-items"""
return [self._tkey(item, key_list) for item in self.xml.xpath(xpath)]
def _keys_simple(self, xpath):
return [x.text.strip() for x in self.xml.xpath(xpath)]
def _keyspec(self):
- """ returns tuple (keyname-xpath, item-xpath) """
+ """returns tuple (keyname-xpath, item-xpath)"""
return (self.ITEM_NAME_XPATH, self.ITEM_XPATH)
def _clearkeys(self):
@@ -129,7 +129,7 @@
# ------------------------------------------------------------------------
def _keys(self):
- """ return a list of data item keys from the Table XML """
+ """return a list of data item keys from the Table XML"""
self._assert_data()
key_value, xpath = self._keyspec()
@@ -171,7 +171,7 @@
# ------------------------------------------------------------------------
def values(self):
- """ returns list of table entry items() """
+ """returns list of table entry items()"""
self._assert_data()
if self.view is None:
@@ -186,7 +186,7 @@
# ------------------------------------------------------------------------
def items(self):
- """ returns list of tuple(name,values) for each table entry """
+ """returns list of tuple(name,values) for each table entry"""
return list(zip(self.keys(), self.values()))
# ------------------------------------------------------------------------
@@ -274,7 +274,7 @@
return len(self.keys())
def __iter__(self):
- """ iterate over each time in the table """
+ """iterate over each time in the table"""
self._assert_data()
as_xml = lambda table, view_xml: view_xml
@@ -342,5 +342,5 @@
return use_view(table=self, view_xml=found[0])
def __contains__(self, key):
- """ membership for use with 'in' """
+ """membership for use with 'in'"""
return bool(key in self.keys())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py-junos-eznc-2.6.0/lib/jnpr/junos/factory/view.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/view.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/factory/view.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/view.py 2021-09-16
12:38:45.000000000 +0200
@@ -68,17 +68,17 @@
@property
def T(self):
- """ return the Table instance for the View """
+ """return the Table instance for the View"""
return self._table
@property
def D(self):
- """ return the Device instance for this View """
+ """return the Device instance for this View"""
return self.T.D
@property
def name(self):
- """ return the name of view item """
+ """return the name of view item"""
if self.ITEM_NAME_XPATH is None:
return []
# return self._table.D.hostname
@@ -137,7 +137,7 @@
@property
def xml(self):
- """ returns the XML associated to the item """
+ """returns the XML associated to the item"""
return self._xml
# -------------------------------------------------------------------------
@@ -145,19 +145,19 @@
# -------------------------------------------------------------------------
def keys(self):
- """ list of view keys, i.e. field names """
+ """list of view keys, i.e. field names"""
return self.FIELDS.keys()
def values(self):
- """ list of view values """
+ """list of view values"""
return [getattr(self, field) for field in self.keys()]
def items(self):
- """ list of tuple(key,value) """
+ """list of tuple(key,value)"""
return zip(self.keys(), self.values())
def _updater_instance(self, more):
- """ called from extend """
+ """called from extend"""
if hasattr(more, "fields"):
self.FIELDS = deepcopy(self.__class__.FIELDS)
self.FIELDS.update(more.fields.end)
@@ -171,7 +171,7 @@
self.EVAL.update(more.eval)
def _updater_class(self, more):
- """ called from extend """
+ """called from extend"""
if hasattr(more, "fields"):
self.FIELDS.update(more.fields.end)
@@ -211,7 +211,7 @@
updater(more)
def asview(self, view_cls):
- """ create a new View object for this item """
+ """create a new View object for this item"""
return view_cls(self._table, self._xml)
def refresh(self):
@@ -245,7 +245,7 @@
# -------------------------------------------------------------------------
def __repr__(self):
- """ returns the name of the View with the associate item name """
+ """returns the name of the View with the associate item name"""
return "%s:%s" % (self.__class__.__name__, self.name)
def __getattr__(self, name):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/py-junos-eznc-2.6.0/lib/jnpr/junos/factory/viewfields.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/viewfields.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/factory/viewfields.py
2021-04-22 14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/factory/viewfields.py
2021-09-16 12:38:45.000000000 +0200
@@ -18,7 +18,7 @@
return self._fields
def str(self, name, xpath=None, **kvargs):
- """ field is a string """
+ """field is a string"""
if xpath is None:
xpath = name
field = {name: {"xpath": xpath}}
@@ -46,7 +46,7 @@
return self
def int(self, name, xpath=None, **kvargs):
- """ field is an integer """
+ """field is an integer"""
return self.astype(name, xpath, int, **kvargs)
def flag(self, name, xpath=None, **kvargs):
@@ -65,6 +65,6 @@
return self.astype(name, xpath, str, **kvargs)
def table(self, name, table):
- """ field is a RunstatTable """
+ """field is a RunstatTable"""
self._fields.update({name: {"table": table}})
return self
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py-junos-eznc-2.6.0/lib/jnpr/junos/jxml.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/jxml.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/jxml.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/jxml.py 2021-09-16
12:38:45.000000000 +0200
@@ -161,7 +161,7 @@
def remove_namespaces(xml):
- for elem in xml.getiterator():
+ for elem in xml.iter():
if elem.tag is etree.Comment:
continue
i = elem.tag.find("}")
@@ -171,7 +171,7 @@
def remove_namespaces_and_spaces(xml):
- for elem in xml.getiterator():
+ for elem in xml.iter():
if elem.tag is etree.Comment:
continue
# Remove namespace from attributes
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py-junos-eznc-2.6.0/lib/jnpr/junos/op/teddb.yml
new/py-junos-eznc-2.6.3/lib/jnpr/junos/op/teddb.yml
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/op/teddb.yml 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/op/teddb.yml 2021-09-16
12:38:45.000000000 +0200
@@ -17,6 +17,9 @@
link-in: { ted-database-link-in : int }
link-out: { ted-database-link-out : int }
protocol: ted-database-protocol
+ srgb-base: {
ted-spring-capability/ted-spring-srgb-block/ted-spring-srgb-block-start : int }
+ srgb-range: {
ted-spring-capability/ted-spring-srgb-block/ted-spring-srgb-block-range : int }
+ srgb-flag:
ted-spring-capability/ted-spring-srgb-block/ted-spring-srgb-block-flags
link: _linkTable
_linkTable:
@@ -33,6 +36,10 @@
localADD: ted-link-local-address
metric: { ted-link-metric : int }
color: admin-groups/color
+ sr-adj-sid-label:
{ted-adj-sids/ted-link-p2p-adj-sid/ted-link-p2p-adj-sid-label : int}
+ sr-adj-sid-weight:
{ted-adj-sids/ted-link-p2p-adj-sid/ted-link-p2p-adj-sid-weight : int}
+ sr-adj-sid-afi: ted-adj-sids/ted-link-p2p-adj-sid/ted-link-p2p-adj-sid-af
+ sr-adj-sid-flags:
ted-adj-sids/ted-link-p2p-adj-sid/ted-link-p2p-adj-sid-flags
TedSummaryTable:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py-junos-eznc-2.6.0/lib/jnpr/junos/transport/tty.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/transport/tty.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/transport/tty.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/transport/tty.py 2021-09-16
12:38:45.000000000 +0200
@@ -217,14 +217,19 @@
# assume we're in a hung state, i.e. we don't see
# a login prompt for whatever reason
self.state = self._ST_TTY_NOLOGIN
- if self.console_has_banner:
- # if console connection has a banner or warning,
- # use this hack
- sleep(5)
- self.write("\n")
- else:
- # @@@ this is still a hack - used by default
- self.write("<close-session/>")
+ # For console based telnet connection a new-line is required.
+ # Code modified to check with a newline for telnet based
connections.
+ # Keeping below code as a comment for future enhancement.
+ # if self.console_has_banner:
+ # # if console connection has a banner or warning,
+ # # use this hack
+ # sleep(5)
+ # self.write("\n")
+ sleep(5)
+ self.write("\n")
+ else:
+ # @@@ this is still a hack - used by default
+ self.write("<close-session/>")
def _ev_shell():
if self.state == self._ST_INIT:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/py-junos-eznc-2.6.0/lib/jnpr/junos/transport/tty_netconf.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/transport/tty_netconf.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/transport/tty_netconf.py
2021-04-22 14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/transport/tty_netconf.py
2021-09-16 12:38:45.000000000 +0200
@@ -53,7 +53,7 @@
# -------------------------------------------------------------------------
def open(self, at_shell):
- """ start the XML API process and receive the 'hello' message """
+ """start the XML API process and receive the 'hello' message"""
nc_cmd = ("junoscript", "xml-mode")[at_shell]
self._tty.write(nc_cmd + " netconf need-trailer")
mark_start = datetime.now()
@@ -72,7 +72,7 @@
self._session_id, _ = HelloHandler.parse(self.hello.decode("utf-8"))
def close(self, force=False):
- """ issue the XML API to close the session """
+ """issue the XML API to close the session"""
# if we do not have an open connection, then return now.
if force is False:
@@ -87,7 +87,7 @@
# -------------------------------------------------------------------------
def zeroize(self):
- """ issue a reboot to the device """
+ """issue a reboot to the device"""
cmd = E.command("request system zeroize")
try:
encode = None if sys.version < "3" else "unicode"
@@ -144,7 +144,7 @@
return self._receive_serial()
def _receive_serial(self):
- """ process the XML response into an XML object """
+ """process the XML response into an XML object"""
rxbuf = PY6.EMPTY_STR
line = PY6.EMPTY_STR
while True:
@@ -172,7 +172,7 @@
# -------------------------------------------------------------------------
def _receive_serial_win(self):
- """ process incoming data from windows port"""
+ """process incoming data from windows port"""
rxbuf = PY6.EMPTY_STR
line = PY6.EMPTY_STR
while True:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/py-junos-eznc-2.6.0/lib/jnpr/junos/transport/tty_serial.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/transport/tty_serial.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/transport/tty_serial.py
2021-04-22 14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/transport/tty_serial.py
2021-09-16 12:38:45.000000000 +0200
@@ -55,7 +55,7 @@
# -------------------------------------------------------------------------
def write(self, content):
- """ write content + <RETURN> """
+ """write content + <RETURN>"""
self._ser.write(six.b(content + "\n"))
self._ser.flush()
@@ -63,7 +63,7 @@
self._ser.write(content)
def read(self):
- """ read a single line """
+ """read a single line"""
return self._ser.readline()
def read_prompt(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/py-junos-eznc-2.6.0/lib/jnpr/junos/transport/tty_ssh.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/transport/tty_ssh.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/transport/tty_ssh.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/transport/tty_ssh.py 2021-09-16
12:38:45.000000000 +0200
@@ -134,12 +134,12 @@
# -------------------------------------------------------------------------
def write(self, content):
- """ write content + <ENTER> """
+ """write content + <ENTER>"""
logger.debug("Write: %s" % content)
self._ssh.sendall(six.b((content + "\n")))
def rawwrite(self, content):
- """ write content as-is """
+ """write content as-is"""
logger.debug("rawwrite: %s" % content)
# If baud set to 0 write full speed
if int(self.baud) == 0:
@@ -157,7 +157,7 @@
sleep(wtime) # do not remove
def read(self):
- """ read a single line """
+ """read a single line"""
rxb = six.b("")
while True:
data = self._ssh.recv(self.RECVSZ)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/py-junos-eznc-2.6.0/lib/jnpr/junos/transport/tty_telnet.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/transport/tty_telnet.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/transport/tty_telnet.py
2021-04-22 14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/transport/tty_telnet.py
2021-09-16 12:38:45.000000000 +0200
@@ -67,7 +67,9 @@
sleep(self.RETRY_BACKOFF)
else:
raise RuntimeError("open_fail: port not ready")
- self.write("\n")
+ # the below line was added for console based telnet connection as it
needs newline to work.
+ # it causes issue in EVO devices. Keeping it as a comment for future
enhancement.
+ # self.write("\n")
def _tty_close(self):
self._tn.close()
@@ -77,12 +79,12 @@
# -------------------------------------------------------------------------
def write(self, content):
- """ write content + <ENTER> """
+ """write content + <ENTER>"""
logger.debug("Write: %s" % content)
self._tn.write(six.b((content + "\n")))
def rawwrite(self, content):
- """ write content as-is """
+ """write content as-is"""
logger.debug("rawwrite: %s" % content)
# If baud set to 0 write full speed
if int(self.baud) == 0:
@@ -100,7 +102,7 @@
sleep(wtime) # do not remove
def read(self):
- """ read a single line """
+ """read a single line"""
return self._tn.read_until(PY6.NEW_LINE, self.EXPECT_TIMEOUT)
def read_prompt(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py-junos-eznc-2.6.0/lib/jnpr/junos/utils/config.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/utils/config.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/utils/config.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/utils/config.py 2021-09-16
12:38:45.000000000 +0200
@@ -260,6 +260,16 @@
else:
raise
+ # The output is expected to be an etree, it may have empty
<configuration-output> tags
+ # Adding a preventive check and displaying warning in case the value
is bool.
+ # This check is added for PR 1564189 (juniper internal) which has
issue for certain junos releases.
+ if isinstance(rsp, bool):
+ warnings.warn(
+ "diff shouldn't return boolean as a rpc-reply",
+ RuntimeWarning,
+ )
+ return None
+
diff_txt = rsp.find("configuration-output").text
return None if diff_txt == "\n" else diff_txt
@@ -436,7 +446,7 @@
# ---------------------------------------------------------------------
def _lformat_byext(path):
- """ determine the format style from the file extension """
+ """determine the format style from the file extension"""
ext = os.path.splitext(path)[1]
if ext == ".xml":
return "xml"
@@ -449,7 +459,7 @@
raise ValueError("Unknown file contents from extension: %s" % ext)
def _lset_format(kvargs, rpc_xattrs):
- """ setup the kvargs/rpc_xattrs """
+ """setup the kvargs/rpc_xattrs"""
# when format is given, setup the xml attrs appropriately
if kvargs["format"] == "set":
if overwrite is True or kvargs.get("update") is True:
@@ -462,14 +472,14 @@
rpc_xattrs["format"] = kvargs["format"]
def _lset_fromfile(path):
- """ setup the kvargs/rpc_xattrs based on path """
+ """setup the kvargs/rpc_xattrs based on path"""
if "format" not in kvargs:
# we use the extension to determine the format
kvargs["format"] = _lformat_byext(path)
_lset_format(kvargs, rpc_xattrs)
def _lset_from_rexp(rpc):
- """ setup the kvargs/rpc_xattrs using string regular expression """
+ """setup the kvargs/rpc_xattrs using string regular expression"""
if re.search(r"^\s*<.*>$", rpc, re.MULTILINE):
kvargs["format"] = "xml"
elif re.search(
@@ -643,13 +653,20 @@
# rollback <number|0*>
# -------------------------------------------------------------------------
- def rollback(self, rb_id=0):
+ def rollback(self, rb_id=0, ignore_warning=False):
"""
Rollback the candidate config to either the last active or
a specific rollback number.
:param int rb_id: The rollback id value [0-49], defaults to ``0``.
+ :param ignore_warning: A boolean, string or list of string.
+ If the value is True, it will ignore all warnings regardless of the
+ warning message. If the value is a string, it will ignore
+ warning(s) if the message of each warning matches the string. If
+ the value is a list of strings, ignore warning(s) if the message of
+ each warning matches at least one of the strings in the list.
+
:returns:
``True`` always when successful
@@ -659,7 +676,9 @@
if rb_id < 0 or rb_id > 49:
raise ValueError("Invalid rollback #" + str(rb_id))
- self.rpc.load_configuration(dict(compare="rollback",
rollback=str(rb_id)))
+ self.rpc.load_configuration(
+ dict(compare="rollback", rollback=str(rb_id)),
ignore_warning=ignore_warning
+ )
return True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py-junos-eznc-2.6.0/lib/jnpr/junos/utils/scp.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/utils/scp.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/utils/scp.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/utils/scp.py 2021-09-16
12:38:45.000000000 +0200
@@ -55,7 +55,7 @@
self._scpargs["progress"] = self._scp_progress
def _progress(self, report):
- """ simple progress report function """
+ """simple progress report function"""
print(self._junos.hostname + ": " + report)
def _scp_progress(self, _path, _total, _xfrd):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/py-junos-eznc-2.6.0/lib/jnpr/junos/utils/start_shell.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/utils/start_shell.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/utils/start_shell.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/utils/start_shell.py 2021-09-16
12:38:45.000000000 +0200
@@ -36,7 +36,7 @@
self._client = None
self._chan = None
- def wait_for(self, this=_SHELL_PROMPT, timeout=0):
+ def wait_for(self, this=_SHELL_PROMPT, timeout=0, sleep=0):
"""
Wait for the result of the command, expecting **this** prompt.
@@ -45,6 +45,11 @@
:param int timeout:
Timeout value in seconds to wait for expected string/pattern.
If not specified defaults to self.timeout.
+ :param seconds sleep:
+ Time to wait after initial call to receive data from buffer. This
+ value can help stabilize the output when multiple calls to run()
+ are looped but will increase the time spent receiving output. This
+ value can be a floating point number for subsecond precision.
:returns: resulting string of data in a list
:rtype: list
@@ -59,6 +64,8 @@
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)
@@ -91,11 +98,11 @@
self.wait_for(_SHELL_PROMPT)
def close(self):
- """ Close the SSH client channel """
+ """Close the SSH client channel"""
self._chan.close()
self._client.close()
- def run(self, command, this=_SHELL_PROMPT, timeout=0):
+ def run(self, command, this=_SHELL_PROMPT, timeout=0, sleep=0):
"""
Run a shell command and wait for the response. The return is a
tuple. The first item is True/False if exit-code is 0. The second
@@ -111,6 +118,11 @@
to individual run call. If ``this`` is provided with None value,
function will wait till timeout value to grab all the content from
command output.
+ :param seconds sleep:
+ Time to wait after initial call to receive data from buffer. This
+ value can help stabilize the output when multiple calls to run()
+ are looped but will increase the time spent receiving output. This
+ value can be a floating point number for subsecond precision.
:returns: (last_ok, result of the executed shell command (str) )
@@ -129,7 +141,7 @@
timeout = timeout or self.timeout
# run the command and capture the output
self.send(command)
- got = "".join(self.wait_for(this, timeout))
+ got = "".join(self.wait_for(this, timeout, sleep=sleep))
self.last_ok = False
if this is None:
self.last_ok = got is not ""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py-junos-eznc-2.6.0/lib/jnpr/junos/utils/sw.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/utils/sw.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/utils/sw.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/utils/sw.py 2021-09-16
12:38:45.000000000 +0200
@@ -166,7 +166,7 @@
@classmethod
def progress(cls, dev, report):
- """ simple progress report function """
+ """simple progress report function"""
print(dev.hostname + ": " + report)
# -------------------------------------------------------------------------
@@ -297,21 +297,29 @@
def _parse_pkgadd_response(self, rsp):
got = rsp.getparent()
- # If <package-result> is not present, then assume success.
- # That is, assume <package-result>0</package-result>
- rc = 0
- package_result = got.findtext("package-result")
- if package_result is None:
- self.log(
- "software pkgadd response is missing package-result "
- "element. Assuming success."
- )
- else:
- for result in got.findall("package-result"):
- rc += int(result.text.strip())
output_msg = "\n".join(
[i.text for i in got.findall("output") if i.text is not None]
)
+ package_result = got.findtext("package-result")
+ if package_result is None:
+ # <package-result> is not present
+ if "ERROR:" in output_msg and (
+ ("is not found" in output_msg) or ("no such file" in
output_msg)
+ ):
+ # MX80 output with non-existent package looks like:
+ # <output>
+ # ERROR: package: /var/tmp/nonexistent.tgz is not found or
empty
+ # </output>
+ package_result = "1"
+ else:
+ # Not a known specific error in the output. Assume success.
+ # That is, assume <package-result>0</package-result>
+ self.log(
+ "software pkgadd response is missing package-result "
+ "element. Assuming success."
+ )
+ package_result = "0"
+ rc = int(package_result.strip())
self.log("software pkgadd package-result: %s\nOutput: %s" % (rc,
output_msg))
return rc == 0, output_msg
@@ -951,9 +959,16 @@
"validating software against current config,"
" please be patient ..."
)
- v_ok = self.validate(
- remote_package, issu, nssu, dev_timeout=timeout
- )
+ try:
+ v_ok = self.validate(
+ remote_package, issu, nssu, dev_timeout=timeout
+ )
+ except RpcError as e:
+ if "syntax error" in getattr(e, "message", ""):
+ v_ok = True
+ else:
+ raise
+
if v_ok is not True:
return v_ok, "Package validation failed"
else:
@@ -981,7 +996,11 @@
if self._multi_VC is True:
ok = True, ""
# extract the VC number out of the _RE_list
- vc_members = [re.search("(\d+)", x).group(1) for x in
self._RE_list]
+ vc_members = [
+ re.search("(\d+)", x).group(1)
+ for x in self._RE_list
+ if re.search("(\d+)", x)
+ ]
for vc_id in vc_members:
_progress(
"installing software on VC member: {} ... please "
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py-junos-eznc-2.6.0/lib/jnpr/junos/utils/util.py
new/py-junos-eznc-2.6.3/lib/jnpr/junos/utils/util.py
--- old/py-junos-eznc-2.6.0/lib/jnpr/junos/utils/util.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/lib/jnpr/junos/utils/util.py 2021-09-16
12:38:45.000000000 +0200
@@ -27,7 +27,7 @@
@dev.setter
def dev(self, value):
- """ read-only property """
+ """read-only property"""
raise RuntimeError("read-only: dev")
# -------------------------------------------------------------------------
@@ -43,5 +43,5 @@
@rpc.setter
def rpc(self, value):
- """ read-only property """
+ """read-only property"""
raise RuntimeError("read-only: rpc")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py-junos-eznc-2.6.0/tests/unit/test_jxml.py
new/py-junos-eznc-2.6.3/tests/unit/test_jxml.py
--- old/py-junos-eznc-2.6.0/tests/unit/test_jxml.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/tests/unit/test_jxml.py 2021-09-16
12:38:45.000000000 +0200
@@ -40,7 +40,7 @@
parser = ET.XMLParser()
root = ET.parse(StringIO(xmldata), parser)
test = remove_namespaces(root)
- for elem in test.getiterator():
+ for elem in test.iter():
i = elem.tag.find("}")
if i > 0:
i = i + 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py-junos-eznc-2.6.0/tests/unit/transport/test_tty.py
new/py-junos-eznc-2.6.3/tests/unit/transport/test_tty.py
--- old/py-junos-eznc-2.6.0/tests/unit/transport/test_tty.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/tests/unit/transport/test_tty.py 2021-09-16
12:38:45.000000000 +0200
@@ -39,6 +39,10 @@
self.terminal.read_prompt.return_value = (None, "testing")
self.terminal.write = MagicMock()
self.assertRaises(RuntimeError, self.terminal._login_state_machine)
+ self.terminal.write.assert_called_with("\n")
+ self.terminal.read_prompt.return_value = (None, "testing")
+ self.terminal.write = MagicMock()
+ self.assertRaises(RuntimeError, self.terminal._login_state_machine)
self.terminal.write.assert_called_with("<close-session/>")
@patch("jnpr.junos.transport.tty.sleep")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/py-junos-eznc-2.6.0/tests/unit/utils/rpc-reply/request-package-add.no_mx80_packages.xml
new/py-junos-eznc-2.6.3/tests/unit/utils/rpc-reply/request-package-add.no_mx80_packages.xml
---
old/py-junos-eznc-2.6.0/tests/unit/utils/rpc-reply/request-package-add.no_mx80_packages.xml
1970-01-01 01:00:00.000000000 +0100
+++
new/py-junos-eznc-2.6.3/tests/unit/utils/rpc-reply/request-package-add.no_mx80_packages.xml
2021-09-16 12:38:45.000000000 +0200
@@ -0,0 +1,10 @@
+<rpc-reply xmlns:junos="http://xml.juniper.net/junos/17.3R1/junos">
+ <cli>
+ <ignore-signals>
+ hup
+ </ignore-signals>
+ </cli>
+ <output>
+ ERROR: package: /var/tmp/nonexistent.tgz is not found or empty
+ </output>
+</rpc-reply>
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py-junos-eznc-2.6.0/tests/unit/utils/test_sw.py
new/py-junos-eznc-2.6.3/tests/unit/utils/test_sw.py
--- old/py-junos-eznc-2.6.0/tests/unit/utils/test_sw.py 2021-04-22
14:54:35.000000000 +0200
+++ new/py-junos-eznc-2.6.3/tests/unit/utils/test_sw.py 2021-09-16
12:38:45.000000000 +0200
@@ -229,6 +229,13 @@
self.assertTrue(self.sw.install("test_no_result.tgz", no_copy=True))
@patch("jnpr.junos.Device.execute")
+ def test_sw_install_nonexistent_mx80_package(self, mock_execute):
+ mock_execute.side_effect = self._mock_manager
+ self.sw._multi_RE = False
+ var_ret = self.sw.install("test_no_mx80_packages.tgz", no_copy=True)
+ self.assertFalse(var_ret[0])
+
+ @patch("jnpr.junos.Device.execute")
def test_sw_install_issu(self, mock_execute):
mock_execute.side_effect = self._mock_manager
package = "test.tgz"
@@ -996,6 +1003,12 @@
== "/var/tmp/test_no_result.tgz"
):
return self._read_file(args[0].tag + ".no_result.xml")
+ elif (
+ args
+ and args[0].findtext("package-name")
+ == "/var/tmp/test_no_mx80_packages.tgz"
+ ):
+ return self._read_file(args[0].tag +
".no_mx80_packages.xml")
else:
return self._read_file(args[0].tag + ".xml")
if "path" in kwargs: