Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-ciscoconfparse for openSUSE:Factory checked in at 2021-07-13 22:37:32 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-ciscoconfparse (Old) and /work/SRC/openSUSE:Factory/.python-ciscoconfparse.new.2625 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-ciscoconfparse" Tue Jul 13 22:37:32 2021 rev:19 rq:906053 version:1.5.36 Changes: -------- --- /work/SRC/openSUSE:Factory/python-ciscoconfparse/python-ciscoconfparse.changes 2021-02-19 23:44:46.755334801 +0100 +++ /work/SRC/openSUSE:Factory/.python-ciscoconfparse.new.2625/python-ciscoconfparse.changes 2021-07-13 22:37:58.217869980 +0200 @@ -1,0 +2,13 @@ +Tue Jul 13 07:29:52 UTC 2021 - Martin Hauke <mar...@gmx.de> + +- Update to version 1.5.36 + * Fix git tags in Makefile + * Add a helper-function: as_text_list(); improve performance of + .delete() + * Fix __int__() and __index__() on IPv4Obj() and IPv6Obj() + * Enhance ccp_util.CiscoRange() to parse a wider variety of + string inputs + * Remove slow code from ccp_util.CiscoRange() + * Make ccp_util.L4Object().__repr__() more friendly + +------------------------------------------------------------------- Old: ---- ciscoconfparse-1.5.25.tar.gz New: ---- ciscoconfparse-1.5.36.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-ciscoconfparse.spec ++++++ --- /var/tmp/diff_new_pack.DdObc6/_old 2021-07-13 22:37:58.649866501 +0200 +++ /var/tmp/diff_new_pack.DdObc6/_new 2021-07-13 22:37:58.653866470 +0200 @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %bcond_without python2 Name: python-ciscoconfparse -Version: 1.5.25 +Version: 1.5.36 Release: 0 Summary: Library for parsing, querying and modifying Cisco IOS-style configurations License: GPL-3.0-or-later ++++++ ciscoconfparse-1.5.25.tar.gz -> ciscoconfparse-1.5.36.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ciscoconfparse-1.5.25/CHANGES new/ciscoconfparse-1.5.36/CHANGES --- old/ciscoconfparse-1.5.25/CHANGES 2021-01-23 17:54:16.000000000 +0100 +++ new/ciscoconfparse-1.5.36/CHANGES 2021-07-11 16:46:39.000000000 +0200 @@ -1,3 +1,10 @@ +1.5.36 20210711 Rework git remote (i.e. origin) logic +1.5.35 20210711 Fix git tags in Makefile +1.5.30 20210301 Add a helper-function: as_text_list(); improve performance of .delete() +1.5.29 20210128 Fix __int__() and __index__() on IPv4Obj() and IPv6Obj() +1.5.28 20210123 Enhance ccp_util.CiscoRange() to parse a wider variety of string inputs +1.5.27 20210123 Remove slow code from ccp_util.CiscoRange() +1.5.26 20210123 Make ccp_util.L4Object().__repr__() more friendly 1.5.25 20210123 Fix Github Issue #195, merge PR #194, fix multiple unreported bugs in ccp_util.L4Object() 1.5.24 20210106 Fix Github Issue #178 1.5.23 20210105 Prevent find_object_branches() from using None diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ciscoconfparse-1.5.25/PKG-INFO new/ciscoconfparse-1.5.36/PKG-INFO --- old/ciscoconfparse-1.5.25/PKG-INFO 2021-01-23 18:04:18.000000000 +0100 +++ new/ciscoconfparse-1.5.36/PKG-INFO 2021-07-11 16:47:33.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: ciscoconfparse -Version: 1.5.25 +Version: 1.5.36 Summary: Parse, Audit, Query, Build, and Modify Cisco IOS-style configurations Home-page: http://www.pennington.net/py/ciscoconfparse/ Author: David Michael Pennington @@ -98,11 +98,12 @@ As of CiscoConfParse 1.2.4, you can parse `brace-delimited configurations`_ into a Cisco IOS style (see `Github Issue #17`_), which means that - CiscoConfParse understands these configurations: + CiscoConfParse can parse these configurations: - Juniper Networks Junos - Palo Alto Networks Firewall configurations - F5 Networks configurations + - Terraform .tf files CiscoConfParse also handles anything that has a Cisco IOS style of configuration, which includes: @@ -213,7 +214,7 @@ ===================== ciscoconfparse_ is licensed GPLv3_; Copyright `David Michael Pennington`_, - 2007-2020. + 2007-2021. ciscoconfparse_ is not affiliated with Cisco Systems in any way; the word "Cisco" is a registered trademark of Cisco Systems diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ciscoconfparse-1.5.25/README.rst new/ciscoconfparse-1.5.36/README.rst --- old/ciscoconfparse-1.5.25/README.rst 2020-12-06 16:51:58.000000000 +0100 +++ new/ciscoconfparse-1.5.36/README.rst 2021-07-11 15:01:45.000000000 +0200 @@ -90,11 +90,12 @@ As of CiscoConfParse 1.2.4, you can parse `brace-delimited configurations`_ into a Cisco IOS style (see `Github Issue #17`_), which means that -CiscoConfParse understands these configurations: +CiscoConfParse can parse these configurations: - Juniper Networks Junos - Palo Alto Networks Firewall configurations - F5 Networks configurations +- Terraform .tf files CiscoConfParse also handles anything that has a Cisco IOS style of configuration, which includes: @@ -205,7 +206,7 @@ ===================== ciscoconfparse_ is licensed GPLv3_; Copyright `David Michael Pennington`_, -2007-2020. +2007-2021. ciscoconfparse_ is not affiliated with Cisco Systems in any way; the word "Cisco" is a registered trademark of Cisco Systems diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ciscoconfparse-1.5.25/ciscoconfparse/__init__.py new/ciscoconfparse-1.5.36/ciscoconfparse/__init__.py --- old/ciscoconfparse-1.5.25/ciscoconfparse/__init__.py 2020-06-28 00:08:42.000000000 +0200 +++ new/ciscoconfparse-1.5.36/ciscoconfparse/__init__.py 2021-07-11 15:22:52.000000000 +0200 @@ -1,8 +1,9 @@ from __future__ import absolute_import from ciscoconfparse.ciscoconfparse import * +from ciscoconfparse.ccp_util import * """ __init__.py - Parse, Query, Build, and Modify IOS-style configurations - Copyright (C) 2007-2015 David Michael Pennington + Copyright (C) 2007-2021 David Michael Pennington This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ciscoconfparse-1.5.25/ciscoconfparse/ccp_abc.py new/ciscoconfparse-1.5.36/ciscoconfparse/ccp_abc.py --- old/ciscoconfparse-1.5.25/ciscoconfparse/ccp_abc.py 2020-12-27 15:33:38.000000000 +0100 +++ new/ciscoconfparse-1.5.36/ciscoconfparse/ccp_abc.py 2021-03-05 15:38:56.000000000 +0100 @@ -187,7 +187,14 @@ def _list_reassign_linenums(self): # Call this when I want to reparse everything # (which is very slow) - self.confobj._reassign_linenums() + + # NOTE - 1.5.30 removed this method (which was only called + # by confobj.delete()) in favor of a simpler approach + # in confobj.delete() + # + # def _list_reassign_linenums(self): + # self.confobj._reassign_linenums() + raise NotImplementedError() @junos_unsupported def add_parent(self, parentobj): @@ -225,7 +232,10 @@ """Delete this object. By default, if a parent object is deleted, the child objects are also deleted; this happens because ``recurse`` defaults True. """ if recurse: - for child in self.children: + # NOTE - 1.5.30 changed this from iterating over self.children + # to self.all_children + #for child in self.children: + for child in sorted(self.all_children, reverse=True): child.delete() ## Consistency check to refuse deletion of the wrong object... @@ -234,7 +244,17 @@ linenum = self.linenum if self.confobj._list[self.linenum].text == text: del self.confobj._list[self.linenum] - self._list_reassign_linenums() + + # renumber remaining objects after this deletion... + # + # NOTE 1.5.30 removed self._list_reassign_linenums() to speed up + # obj.delete() behavior... instead we just iterate through + # the list of remaining objects and renumber them + # + #self._list_reassign_linenums() + for obj in self.confobj._list[self.linenum:]: + obj.linenum = linenum + linenum += 1 @junos_unsupported def delete_children_matching(self, linespec): @@ -300,14 +320,16 @@ @junos_unsupported def insert_before(self, insertstr): - """insert_before()""" + """Usage: + confobj.insert_before('! insert text before this confobj')""" ## BaseCfgLine.insert_before(), insert a single line before this object retval = self.confobj.insert_before(self, insertstr, atomic=False) return retval @junos_unsupported def insert_after(self, insertstr): - """insert_after()""" + """Usage: + confobj.insert_after('! insert text after this confobj')""" ## BaseCfgLine.insert_after(), insert a single line after this object retval = self.confobj.insert_after(self, insertstr, atomic=False) return retval @@ -358,6 +380,8 @@ >>> >>> for obj in parse.find_objects(r'^interface'): ... obj.append_to_family(' carrier-delay msec 500') + ... + >>> parse.commit() >>> >>> for line in parse.ioscfg: ... print(line) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ciscoconfparse-1.5.25/ciscoconfparse/ccp_util.py new/ciscoconfparse-1.5.36/ciscoconfparse/ccp_util.py --- old/ciscoconfparse-1.5.25/ciscoconfparse/ccp_util.py 2021-01-23 17:57:34.000000000 +0100 +++ new/ciscoconfparse-1.5.36/ciscoconfparse/ccp_util.py 2021-03-12 01:13:28.000000000 +0100 @@ -1,4 +1,5 @@ from __future__ import absolute_import +from operator import attrgetter from colorama import Fore import itertools import warnings @@ -25,7 +26,7 @@ else: from ipaddress import IPv4Network, IPv6Network, IPv4Address, IPv6Address """ ccp_util.py - Parse, Query, Build, and Modify IOS-style configurations - Copyright (C) 2014-2015, 2018-2020 David Michael Pennington + Copyright (C) 2014-2015, 2018-2021 David Michael Pennington This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -47,6 +48,39 @@ class UnsupportedFeatureWarning(SyntaxWarning): pass +def as_text_list(object_list): + """This is a helper-function to convert a list of configuration objects into a list of text config lines. + + Examples + -------- + + >>> from ciscoconfparse.ccp_util import as_text_list + >>> from ciscoconfparse import CiscoConfParse + >>> + >>> config = [ + ... 'interface GigabitEthernet1/13', + ... ' ip address 192.0.2.1/30', + ... ' vrf member ThisRestrictedVrf', + ... ' no ip redirects', + ... ' no ipv6 redirects', + ... ] + >>> parse = CiscoConfParse(config) + >>> interface_object = parse.find_objects("^interface")[0] + >>> interface_config_objects = interface_object.all_children + >>> interface_config_objects + [<IOSCfgLine # 1 ' ip address 192.0.2.1/30' (parent is # 0)>, <IOSCfgLine # 2 ' vrf member ThisRestrictedVrf' (parent is # 0)>, <IOSCfgLine # 3 ' no ip redirects' (parent is # 0)>, <IOSCfgLine # 4 ' no ipv6 redirects' (parent is # 0)>] + >>> + >>> as_text_list(interface_config_objects) + [' ip address 192.0.2.1/30', ' vrf member ThisRestrictedVrf', ' no ip redirects', ' no ipv6 redirects'] + >>> + + """ + assert isinstance(object_list, list) or isinstance(object_list, tuple) + for obj in object_list: + assert isinstance(obj.linenum, int) + assert isinstance(obj.text, str) + return list(map(attrgetter("text"), object_list)) + def junos_unsupported(func): """A function wrapper to warn junos users of unsupported features""" def wrapper(*args, **kwargs): @@ -398,23 +432,17 @@ def __int__(self): """Return this object as an integer""" - for obj in [self, val]: - try: - assert getattr(obj, "as_decimal", None) is not None - except AssertionError: - return False - - return self.as_decimal + if getattr(self, "as_decimal", None) is not None: + return self.as_decimal + else: + return False def __index__(self): """Return this object as an integer (used for hex() and bin() operations)""" - for obj in [self, val]: - try: - assert getattr(obj, "as_decimal", None) is not None - except AssertionError: - return False - - return self.as_decimal + if getattr(self, "as_decimal", None) is not None: + return self.as_decimal + else: + return False def __add__(self, val): """Add an integer to IPv4Obj() and return an IPv4Obj()""" @@ -556,6 +584,11 @@ return self.network_object.hostmask @property + def inverse_netmask(self): + """Returns the host mask as an :class:`ipaddress.IPv4Address` object.""" + return self.network_object.hostmask + + @property def version(self): """Returns the IP version of the object as an integer. i.e. 4""" return 4 @@ -825,11 +858,17 @@ def __int__(self): """Return this object as an integer""" - return self.as_decimal + if getattr(self, "as_decimal", None) is not None: + return self.as_decimal + else: + return False def __index__(self): """Return this object as an integer (used for hex() and bin() operations)""" - return self.as_decimal + if getattr(self, "as_decimal", None) is not None: + return self.as_decimal + else: + return False def __add__(self, val): """Add an integer to IPv6Obj() and return an IPv6Obj()""" @@ -975,6 +1014,11 @@ return self.network_object.hostmask @property + def inverse_netmask(self): + """Returns the host mask as an :class:`ipaddress.IPv4Address` object.""" + return self.network_object.hostmask + + @property def version(self): """Returns the IP version of the object as an integer. i.e. 6""" return 6 @@ -1069,9 +1113,9 @@ >>> from ciscoconfparse.ccp_util import L4Object >>> obj = L4Object(protocol="tcp", port_spec="range ssh smtp", syntax="asa") >>> obj - <L4Object tcp [22, 23, 24, 25]> + <L4Object tcp ports: 22-25> >>> obj.protocol - "tcp" + 'tcp' >>> 25 in obj.port_list True >>> @@ -1118,7 +1162,7 @@ elif "lt " in port_spec.strip(): port_tmp = re.split("\s+", port_spec)[-1] high_port = int(ports.get(port_tmp, port_tmp)) - assert 65535 >= high_port >= 2 + assert 65536 >= high_port >= 2 self.port_list = sorted(range(1, high_port)) elif "gt " in port_spec.strip(): port_tmp = re.split("\s+", port_spec)[-1] @@ -1139,7 +1183,9 @@ return False def __repr__(self): - return "<L4Object {0} {1}>".format(self.protocol, self.port_list) + crobj = CiscoRange() + crobj._list = self.port_list + return "<L4Object {0} ports: {1}>".format(self.protocol, crobj.compressed_str) class DNSResponse(object): @@ -1540,12 +1586,47 @@ self.insert(list_idx, val) return self - def _parse_range_text(self): + def _normalize_and_split_text(self): + """Split self.text on commas, then remove all common string prefixes in the list (except on the first element). Return a 'normalized' list of strings with common_prefix removed except on the first element in the list (i.e. "Eth1/1,Eth1/4,Eth1/7" -> ["Eth1/1", "4", "7"]).""" tmp = self.text.split(",") + + # Handle case of "Eth1/1,Eth1/5-7"... remove the common_prefix... + common_prefix = os.path.commonprefix(tmp) + + # Ensure that we don't capture trailing digits into common_prefix + mm = re.search(r"^(\D.*?)\d*$", common_prefix.strip()) + if mm is not None: + common_prefix = mm.group(1) + # Keep the common_prefix on the first element... + _tmp = [tmp[0]] + + # Remove the common_prefix from all other list elements... + for idx, ii in enumerate(tmp): + if idx > 0: + + # Unicode is the only type with .isnumeric()... + if sys.version_info < (3, 0, 0): + prefix_removed = unicode(ii[len(common_prefix):], "utf-8") + else: + prefix_removed = ii[len(common_prefix):] + + if prefix_removed.isnumeric(): + _tmp.append(prefix_removed) + elif re.search(r"^\d+\s*-\s*\d+$", prefix_removed.strip()): + _tmp.append(prefix_removed) + else: + ERROR = "CiscoRange() couldn't parse '{0}'".format(self.text) + raise ValueError(ERROR) + tmp = _tmp + return tmp + + def _parse_range_text(self): + tmp = self._normalize_and_split_text() + mm = _RGX_CISCO_RANGE.search(tmp[0]) ERROR = "CiscoRange() couldn't parse '{0}'".format(self.text) - assert not (mm is None), ERROR + assert (mm is not None), ERROR mm_result = mm.groupdict() line_prefix = mm_result.get("line_prefix", "") or "" @@ -1612,17 +1693,27 @@ >>> """ retval = list() - prefix_str = self.line_prefix + self.slot_prefix + prefix_str = self.line_prefix.strip() + self.slot_prefix.strip() + prefix_str_len = len(prefix_str) # Build a list of integers (without prefix_str) input_str = list() for ii in self._list: - try: - unicode_ii = str(ii, "utf-8") # Python2.7... - except: + # Removed try / except which is slower than sys.version_info + if sys.version_info < (3, 0, 0): + unicode_ii = unicode(str(ii)) # Python2.7... + else: unicode_ii = str(ii) - ii = re.sub(r"^{0}(\d+)$".format(prefix_str), "\g<1>", unicode_ii) - input_str.append(int(ii)) + + # Removed this in version 1.5.27 because it's so slow... + #trailing_digits = re.sub(r"^{0}(\d+)$".format(prefix_str), "\g<1>", unicode_ii) + + complete_len = len(unicode_ii) + # Assign ii to the trailing number after prefix_str... + # this is much faster than regexp processing... + trailing_digits_len = complete_len - prefix_str_len + trailing_digits = unicode_ii[-1*trailing_digits_len:] + input_str.append(int(trailing_digits)) if len(input_str) == 0: # Special case, handle empty list return "" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ciscoconfparse-1.5.25/ciscoconfparse/ciscoconfparse.py new/ciscoconfparse-1.5.36/ciscoconfparse/ciscoconfparse.py --- old/ciscoconfparse-1.5.25/ciscoconfparse/ciscoconfparse.py 2021-01-06 20:04:46.000000000 +0100 +++ new/ciscoconfparse-1.5.36/ciscoconfparse/ciscoconfparse.py 2021-03-01 21:01:53.000000000 +0100 @@ -60,7 +60,7 @@ r""" ciscoconfparse.py - Parse, Query, Build, and Modify IOS-style configs - Copyright (C) 2007-2020 David Michael Pennington + Copyright (C) 2007-2021 David Michael Pennington This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1983,7 +1983,10 @@ matches linespec, and delete the object""" objs = self.find_objects(linespec, exactmatch, ignore_ws) for obj in reversed(objs): - del self.ConfigObjs[obj.linenum] + # NOTE - 'del self.ConfigObjs...' was replaced in version 1.5.30 + # with a simpler approach + # del self.ConfigObjs[obj.linenum] + obj.delete() def prepend_line(self, linespec): """Unconditionally insert an :class:`~models_cisco.IOSCfgLine` object diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ciscoconfparse-1.5.25/ciscoconfparse/version.json new/ciscoconfparse-1.5.36/ciscoconfparse/version.json --- old/ciscoconfparse-1.5.25/ciscoconfparse/version.json 2021-01-23 17:52:06.000000000 +0100 +++ new/ciscoconfparse-1.5.36/ciscoconfparse/version.json 2021-07-11 16:45:49.000000000 +0200 @@ -1,3 +1,3 @@ { - "version": "1.5.25" + "version": "1.5.36" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ciscoconfparse-1.5.25/ciscoconfparse.egg-info/PKG-INFO new/ciscoconfparse-1.5.36/ciscoconfparse.egg-info/PKG-INFO --- old/ciscoconfparse-1.5.25/ciscoconfparse.egg-info/PKG-INFO 2021-01-23 18:04:14.000000000 +0100 +++ new/ciscoconfparse-1.5.36/ciscoconfparse.egg-info/PKG-INFO 2021-07-11 16:47:29.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: ciscoconfparse -Version: 1.5.25 +Version: 1.5.36 Summary: Parse, Audit, Query, Build, and Modify Cisco IOS-style configurations Home-page: http://www.pennington.net/py/ciscoconfparse/ Author: David Michael Pennington @@ -98,11 +98,12 @@ As of CiscoConfParse 1.2.4, you can parse `brace-delimited configurations`_ into a Cisco IOS style (see `Github Issue #17`_), which means that - CiscoConfParse understands these configurations: + CiscoConfParse can parse these configurations: - Juniper Networks Junos - Palo Alto Networks Firewall configurations - F5 Networks configurations + - Terraform .tf files CiscoConfParse also handles anything that has a Cisco IOS style of configuration, which includes: @@ -213,7 +214,7 @@ ===================== ciscoconfparse_ is licensed GPLv3_; Copyright `David Michael Pennington`_, - 2007-2020. + 2007-2021. ciscoconfparse_ is not affiliated with Cisco Systems in any way; the word "Cisco" is a registered trademark of Cisco Systems diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ciscoconfparse-1.5.25/tests/test_Ccp_Util.py new/ciscoconfparse-1.5.36/tests/test_Ccp_Util.py --- old/ciscoconfparse-1.5.25/tests/test_Ccp_Util.py 2021-01-23 17:46:01.000000000 +0100 +++ new/ciscoconfparse-1.5.36/tests/test_Ccp_Util.py 2021-01-24 01:09:11.000000000 +0100 @@ -557,6 +557,24 @@ result_correct = [1, 2, 3] assert CiscoRange("", result_type=int).append("1-3").as_list == result_correct +def test_CiscoRange_17(): + """Parse a string with a common prefix on all of the CiscoRange() inputs""" + result_correct = [ + "Eth1/1", + "Eth1/10", + "Eth1/12-20", + ] + CiscoRange("Eth1/1,Eth1/12-20,Eth1/16,Eth1/10").as_list == result_correct + +def test_CiscoRange_18(): + """Parse a string with a common prefix on all of the CiscoRange() inputs""" + result_correct = [ + "interface Eth1/1", + "interface Eth1/10", + "interface Eth1/12-20", + ] + CiscoRange("interface Eth1/1,interface Eth1/12-20,interface Eth1/16,interface Eth1/10").as_list == result_correct + def test_CiscoRange_compressed_str_01(): """compressed_str test"""