From 2292b7629cac17391b1fdd25a21d19d95831d149 Mon Sep 17 00:00:00 2001 From: Vladimir Prusakov Date: Mon, 23 Oct 2023 14:41:03 +0300 Subject: [PATCH] 0.9.0 --- .gitignore | 2 +- CHANGELOG.rst | 9 +++- README.rst | 50 ++++++++++++-------- __init__.py | 2 +- examples/intf.py | 2 + netports/__init__.py | 3 +- netports/intf.py | 65 +++++++++++++++----------- netports/intf_map.py | 93 +++++++++++++++++++++---------------- netports/static.py | 8 +++- netports/types_.py | 9 ++-- pyproject.toml | 4 +- tests/helpers__intf_name.py | 3 -- tests/test__intf.py | 80 +++++++++++++++++++++++-------- tests/test__intf_map.py | 42 +++++++++-------- tests/test__package.py | 15 ------ 15 files changed, 232 insertions(+), 155 deletions(-) diff --git a/.gitignore b/.gitignore index 063a60c..fc6cc76 100644 --- a/.gitignore +++ b/.gitignore @@ -133,4 +133,4 @@ dmypy.json # Temp tmp/ temp/ -notes/ +_notes/ diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 13f9e24..c2f6565 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,9 +4,16 @@ CHANGELOG ========= +0.9.0 (2023-10-23) +------------------ +* [new] intf_map.py ALL_SHORT +* [change] platform > device_type +* [change] Intf._init_device_type() ValueError > NetportsValueError +* [new] Intf.name_short(replace=[("Fa", "Eth")]) + 0.8.2 (2023-04-04) ------------------ -Intf(platform="hp_procurve").all_names() -> ["interface Trk1", ...] +* [change] Intf(platform="hp_procurve").all_names() -> ["interface Trk1", ...] 0.8.1 (2023-04-04) ------------------ diff --git a/README.rst b/README.rst index d2e36d8..7cad90a 100644 --- a/README.rst +++ b/README.rst @@ -34,13 +34,13 @@ or install the package from github.com release .. code:: bash - pip install https://github.com/vladimirs-git/netports/archive/refs/tags/0.8.2.tar.gz + pip install https://github.com/vladimirs-git/netports/archive/refs/tags/0.9.0.tar.gz or install the package from github.com repository .. code:: bash - pip install git+https://github.com/vladimirs-git/netports@0.8.2 + pip install git+https://github.com/vladimirs-git/netports@0.9.0 @@ -389,13 +389,13 @@ Return long_to_short() ............... -**long_to_short(platform, key_lower, value_lower)** -Returns Interfaces map long-to-short, platform specific +**long_to_short(device_type, key_lower, value_lower)** +Returns Interfaces map long-to-short, device_type specific =============== =========================== ============================================================================ Parameter Type Description =============== =========================== ============================================================================ -platform *str* Platform, increase priority of platform specific keys. "", "cisco_asr", "cisco_ios", "cisco_nxos", "hp_comware" +device_type *str* Netmiko device type, increase priority of device_type specific keys. "", "cisco_asr", "cisco_ios", "cisco_nxos", "hp_comware" key_lower *bool* True - keys lower-case, False - keys upper-case value_lower *bool* True - values lower-case, False - values upper-case =============== =========================== ============================================================================ @@ -406,13 +406,13 @@ Return long_to_long() .............. -**long_to_long(platform, key_lower, value_lower)** -Returns Interfaces map long-to-long, platform specific +**long_to_long(device_type, key_lower, value_lower)** +Returns Interfaces map long-to-long, device_type specific =============== =========================== ============================================================================ Parameter Type Description =============== =========================== ============================================================================ -platform *str* Platform, increase priority of platform specific keys. "", "cisco_asr", "cisco_ios", "cisco_nxos", "hp_comware" +device_type *str* Netmiko device type, increase priority of device_type specific keys. "", "cisco_asr", "cisco_ios", "cisco_nxos", "hp_comware" key_lower *bool* True - keys lower-case, False - keys upper-case value_lower *bool* True - values lower-case, False - values upper-case =============== =========================== ============================================================================ @@ -423,13 +423,13 @@ Return short_to_long() ............... -**short_to_long(platform, key_lower, value_lower)** -Returns Interfaces map short-to-long, platform specific +**short_to_long(device_type, key_lower, value_lower)** +Returns Interfaces map short-to-long, device_type specific =============== =========================== ============================================================================ Parameter Type Description =============== =========================== ============================================================================ -platform *str* Platform, increase priority of platform specific keys. "", "cisco_asr", "cisco_ios", "cisco_nxos", "hp_comware" +device_type *str* Netmiko device type, increase priority of device_type specific keys. "", "cisco_asr", "cisco_ios", "cisco_nxos", "hp_comware" key_lower *bool* True - keys lower-case, False - keys upper-case value_lower *bool* True - values lower-case, False - values upper-case =============== =========================== ============================================================================ @@ -440,13 +440,13 @@ Return short_to_short() ................ -**short_to_short(platform, key_lower, value_lower)** -Returns Interfaces map short-to-short, platform specific +**short_to_short(device_type, key_lower, value_lower)** +Returns Interfaces map short-to-short, device_type specific =============== =========================== ============================================================================ Parameter Type Description =============== =========================== ============================================================================ -platform *str* Platform, increase priority of platform specific keys. "", "cisco_asr", "cisco_ios", "cisco_nxos", "hp_comware" +device_type *str* Netmiko device type, increase priority of device_type specific keys. "", "cisco_asr", "cisco_ios", "cisco_nxos", "hp_comware" key_lower *bool* True - keys lower-case, False - keys upper-case value_lower *bool* True - values lower-case, False - values upper-case =============== =========================== ============================================================================ @@ -457,7 +457,7 @@ Return Intf() ...... -**Intf(line, platform, splitter)** +**Intf(line, device_type, splitter)** An object of interface name, that can contain up to 4 indexes. Sorts the interfaces by indexes (not by alphabetic). @@ -465,7 +465,7 @@ Sorts the interfaces by indexes (not by alphabetic). Parameter Type Description =============== ======= ============================================================================ line *str* Interface name that can contain up to 4 indexes -platform *str* Platform like in Netmiko (default "") +device_type *str* Netmiko device_type (default "") splitter *str* Separator of characters between indexes (default ",./:") =============== ======= ============================================================================ @@ -486,7 +486,7 @@ ids Interface all IDs line *str* Interface line name *str* Interface name with IDs splitter *str* Separator of characters between indexes -platform *str* Platform +device_type *str* Netmiko device_type =============== ============ ======================================================================= @@ -499,7 +499,7 @@ Index of last ID in interface line all_names() ........... **all_names()** -All variants of names: long, short, upper-case, lover-case. Platform specific +All variants of names: long, short, upper-case, lover-case. Device type specific name_full() @@ -516,8 +516,18 @@ Interface long name with IDs and without interface keyword name_short() ............ -**name_short()** -Interface short name with IDs, platform specific +**name_short(replace)** +Interface short name with IDs, Device type specific + +=========== =========================== ============================================================ +Parameter Type Description +=========== =========================== ============================================================ +replace *List[Tuple[str, str]]* Replace the default short name with the first one + that matches in the list of the 'replace' argument. +=========== =========================== ============================================================ + +Return + *str* Interface short name. part_after() diff --git a/__init__.py b/__init__.py index 96f0746..19a1399 100644 --- a/__init__.py +++ b/__init__.py @@ -3,10 +3,10 @@ from netports.exceptions import NetportsValueError from netports.intf import Intf from netports.intf_gm import IntfGM, intfrange +from netports.intf_map import short_to_long, short_to_short, long_to_short, long_to_long from netports.ip import IP_NAMES, IP_NUMBERS, iip, sip, ip_pairs from netports.item import Item from netports.ports import inumbers, parse_range, snumbers from netports.range import Range from netports.tcp import stcp, itcp from netports.vlan import ivlan, svlan -from netports.intf_map import short_to_long, short_to_short, long_to_short, long_to_long diff --git a/examples/intf.py b/examples/intf.py index 11d1252..ac9d5ae 100644 --- a/examples/intf.py +++ b/examples/intf.py @@ -19,6 +19,7 @@ # Methods print("last_idx", intf.last_idx()) print("name_short", intf.name_short()) +print("name_short", intf.name_short(replace=[("Eth", "Fa")])) print("name_long", intf.name_long()) print("name_full", intf.name_full()) print("part before id", intf.part_before(idx=3)) @@ -29,6 +30,7 @@ print() # last_idx 4 # name_short Eth1/2/3.4 +# name_short Fa1/2/3.4 # name_long Ethernet1/2/3.4 # name_full interface Ethernet1/2/3.4 # part before id interface Ethernet1/2/ diff --git a/netports/__init__.py b/netports/__init__.py index 6f80718..6a971bc 100644 --- a/netports/__init__.py +++ b/netports/__init__.py @@ -3,13 +3,14 @@ from netports.exceptions import NetportsValueError from netports.intf import Intf from netports.intf_gm import IntfGM, intfrange +from netports.intf_map import short_to_long, short_to_short, long_to_short, long_to_long from netports.ip import IP_NAMES, IP_NUMBERS, iip, sip, ip_pairs from netports.item import Item from netports.ports import inumbers, parse_range, snumbers from netports.range import Range from netports.tcp import stcp, itcp from netports.vlan import ivlan, svlan -from netports.intf_map import short_to_long, short_to_short, long_to_short, long_to_long + __all__ = [ "IP_NAMES", "IP_NUMBERS", diff --git a/netports/intf.py b/netports/intf.py index 9bab653..5137fb7 100644 --- a/netports/intf.py +++ b/netports/intf.py @@ -6,8 +6,9 @@ from typing import List, Optional, Set, Tuple, Union from netports import intf_map, helpers as h -from netports.static import PLATFORMS -from netports.types_ import T3Str, T5Str, LStr, SStr, DStr +from netports.exceptions import NetportsValueError +from netports.static import DEVICE_TYPES +from netports.types_ import T3Str, T5Str, LStr, SStr, DStr, LT2Str SPLITTER = ",./:" @@ -23,12 +24,12 @@ def __init__(self, line: str = "", **kwargs): :: :param line: Interface name that can contain up to 4 indexes :type line: str - :param platform: Platform like in Netmiko (default "") - :type platform: str + :param device_type: Netmiko device type (default "") + :type device_type: str :param splitter: Separator of characters between indexes (default ",./:") :type splitter: str """ - self._platform = self._init_platform(**kwargs) + self._device_type = self._init_device_type(**kwargs) self._splitter = str(kwargs.get("splitter") or SPLITTER) self._line = self._init_line(line) @@ -85,13 +86,17 @@ def _init_line(self, line: str) -> str: return "".join(items) @staticmethod - def _init_platform(**kwargs) -> str: - """Init platform""" - platform = str(kwargs.get("platform") or "") - expected = ["", *PLATFORMS] - if platform not in expected: - raise ValueError(f"{platform=} {expected=}") - return platform + def _init_device_type(**kwargs) -> str: + """Init Netmiko device type + :: + :return: Netmiko device type + :raise: NetportsValueError if the device type is unknown + """ + device_type = str(kwargs.get("device_type") or "") + expected = ["", *DEVICE_TYPES] + if device_type not in expected: + raise NetportsValueError(f"{device_type=} {expected=}") + return device_type # =========================== property =========================== @@ -181,9 +186,9 @@ def name(self) -> str: return re.sub(r"^interface\s+", "", self.line) @property - def platform(self) -> str: - """Platform""" - return self._platform + def device_type(self) -> str: + """Netmiko device type""" + return self._device_type @property def splitter(self) -> str: @@ -216,12 +221,12 @@ def all_names(self) -> LStr: name_ = f"interface {name_}" results.add(name_) - intf_map_upper: DStr = intf_map.short_to_long(self._platform) - intf_map_lower: DStr = intf_map.short_to_long(self._platform, key_lower=True) + intf_map_upper: DStr = intf_map.short_to_long(self._device_type) + intf_map_lower: DStr = intf_map.short_to_long(self._device_type, key_lower=True) names: LStr = [self.name, self.name_short()] names = h.no_dupl(names) for name in names: - intf_o = Intf(line=name, platform=self.platform) + intf_o = Intf(line=name, device_type=self.device_type) for id0_short, intf_map_d in [ (intf_o.id0, intf_map_upper), (intf_o.id0.lower(), intf_map_lower), @@ -236,7 +241,7 @@ def all_names(self) -> LStr: results_: LStr = sorted(results) results_.sort(key=len, reverse=True) - if self.platform == "hp_procurve": + if self.device_type == "hp_procurve": if digits := [s for s in results if s.isdigit()]: names = [f"interface 1/{s}" for s in digits] results_.extend(names) @@ -262,7 +267,6 @@ def name_full(self) -> str: name = self.name_long() return f"interface {name}" - # noinspection DuplicatedCode def name_long(self) -> str: """Interface long name with IDs and without interface keyword :: @@ -274,13 +278,13 @@ def name_long(self) -> str: if id0.startswith("interface "): id0 = id0.replace("interface ", "", 1) - intf_map_short: DStr = intf_map.short_to_long(self._platform, key_lower=True) + intf_map_short: DStr = intf_map.short_to_long(self._device_type, key_lower=True) for short_lower, long_upper in intf_map_short.items(): if id0 == short_lower: id0 = long_upper break else: - intf_map_long: DStr = intf_map.long_to_long(self._platform, key_lower=True) + intf_map_long: DStr = intf_map.long_to_long(self._device_type, key_lower=True) for long_lower, long_upper in intf_map_long.items(): if id0 == long_lower: id0 = long_upper @@ -290,30 +294,39 @@ def name_long(self) -> str: name = f"{id0}{id1}" return name - # noinspection DuplicatedCode - def name_short(self) -> str: + def name_short(self, replace: LT2Str = None) -> str: """Interface short name with IDs :: + :param replace: Replace the default short name with the first one + that matches in the list of the 'replace' argument. + :return: Interface short name. :example: intf = Intf("interface FastEthernet1/2") intf.name_short() -> "Fa1/2" + intf.name_short(replace=[("Fa", "Eth")]) -> "Eth1/2" """ id0 = self.id0.lower() if id0.startswith("interface "): id0 = id0.replace("interface ", "", 1) - intf_map_l2s: DStr = intf_map.long_to_short(self._platform, key_lower=True) + intf_map_l2s: DStr = intf_map.long_to_short(self._device_type, key_lower=True) for long_lower, short_upper in intf_map_l2s.items(): if id0 == long_lower: id0 = short_upper break else: - intf_map_s2s: DStr = intf_map.short_to_short(self._platform, key_lower=True) + intf_map_s2s: DStr = intf_map.short_to_short(self._device_type, key_lower=True) for short_lower, short_upper in intf_map_s2s.items(): if id0 == short_lower: id0 = short_upper break + if replace: + for before, after in replace: + if id0 == before: + id0 = after + break + id1 = self.part_after(idx=0) name = f"{id0}{id1}" return name diff --git a/netports/intf_map.py b/netports/intf_map.py index f6bcc92..fec80ff 100644 --- a/netports/intf_map.py +++ b/netports/intf_map.py @@ -1,5 +1,4 @@ """Interface name mapping""" -from netports.static import PLATFORMS from netports.types_ import DStr MAP_OTHER = { # parent of ios @@ -18,6 +17,14 @@ "Vi": "Virtual-Access", "Vt": "Virtual-Template", } +MAP_CISCO_ASR = { + "Te": "TenGigE", # overlapped: ios + "Hu": "HundredGigE", + "BE": "Bundle-Ether", + "Tu": "tunnel-ip", # low-priority, overlapped: ios, nxos + "ti": "tunnel-ip", + "Mg": "MgmtEth", +} MAP_CISCO_IOS = { # parent of nxos, asr "Eth": "Ethernet", "Fa": "FastEthernet", @@ -33,14 +40,6 @@ "Lo": "loopback", # overlapped: cisco, asr "mgmt": "mgmt", } -MAP_CISCO_ASR = { - "Te": "TenGigE", # overlapped: ios - "Hu": "HundredGigE", - "BE": "Bundle-Ether", - "Tu": "tunnel-ip", # low-priority, overlapped: ios, nxos - "ti": "tunnel-ip", - "Mg": "MgmtEth", -} MAP_HP_COMWARE = { # h3c "GE": "GigabitEthernet", "Te": "Ten-GigabitEthernet", # low-priority, overlapped: cisco @@ -51,53 +50,65 @@ MAP_HP_PROCURVE = { # hpc "Trk": "Trk", } - - -def long_to_short(platform: str = "", key_lower: bool = False, value_lower: bool = False) -> DStr: - """Returns Interfaces map long-to-short, platform specific +ALL_SHORT = sorted({ + *MAP_OTHER, + *MAP_CISCO_IOS, + *MAP_CISCO_NXOS, + *MAP_CISCO_ASR, + *MAP_HP_COMWARE, + *MAP_HP_PROCURVE, +}) + + +def long_to_short(device_type: str = "", + key_lower: bool = False, + value_lower: bool = False) -> DStr: + """Returns Interfaces map long-to-short, device_type specific :: - :param platform: Platform, increase priority of platform specific keys + :param device_type: Netmiko device type, increase priority of device_type specific keys :param key_lower: True - keys lower-case, False - keys upper-case :param value_lower: True - values lower-case, False - values upper-case :return: Interfaces map :example: long_to_short() -> {"Vlan": "V", ...} - long_to_short(platform="cisco_ios") -> {"Vlan": "Vlan", ...} - long_to_short(platform="cisco_ios", key_lower=True) -> {"vlan": "Vlan", ...} + long_to_short(device_type="cisco_ios") -> {"Vlan": "Vlan", ...} + long_to_short(device_type="cisco_ios", key_lower=True) -> {"vlan": "Vlan", ...} """ - data: DStr = short_to_long(platform=platform) + data: DStr = short_to_long(device_type=device_type) data = {v: k for k, v in data.items()} data_ = _overlapped(data) data.update(data_) - if platform == "cisco_asr": + if device_type == "cisco_asr": data["Tunnel"] = "ti" - if platform == "hp_comware": + if device_type == "hp_comware": data["TenGigabitEthernet"] = "XGE" data = _lower(data, key_lower, value_lower) return data -def long_to_long(platform: str = "", key_lower: bool = False, value_lower: bool = False) -> DStr: - """Returns Interfaces map long-to-long, platform specific +def long_to_long(device_type: str = "", key_lower: bool = False, value_lower: bool = False) -> DStr: + """Returns Interfaces map long-to-long, device_type specific :: - :param platform: Platform, increase priority of platform specific keys + :param device_type: Netmiko device type, increase priority of device_type specific keys :param key_lower: True - keys lower-case, False - keys upper-case :param value_lower: True - values lower-case, False - values upper-case :return: Interfaces map """ - data: DStr = short_to_long(platform=platform) + data: DStr = short_to_long(device_type=device_type) data = {v: k for k, v in data.items()} data = {k: k for k in data} data = _lower(data, key_lower, value_lower) return data -def short_to_long(platform: str = "", key_lower: bool = False, value_lower: bool = False) -> DStr: - """Returns Interfaces map short-to-long, platform specific +def short_to_long(device_type: str = "", + key_lower: bool = False, + value_lower: bool = False) -> DStr: + """Returns Interfaces map short-to-long, device_type specific :: - :param platform: Platform, increase priority of platform specific keys + :param device_type: Netmiko device type, increase priority of device_type specific keys :param key_lower: True - keys lower-case, False - keys upper-case :param value_lower: True - values lower-case, False - values upper-case :return: Interfaces map @@ -106,27 +117,27 @@ def short_to_long(platform: str = "", key_lower: bool = False, value_lower: bool short_to_long(key_lower=True) -> {"fa": "FastEthernet", ...} short_to_long(value_lower=True) -> {"Fa": "fastethernet", ...} """ - if platform == "cisco_asr": + if device_type == "cisco_asr": data = MAP_OTHER.copy() data.update(MAP_CISCO_IOS) data.update(MAP_CISCO_ASR) - elif platform == "cisco_ios": + elif device_type == "cisco_ios": data = MAP_OTHER.copy() data.update(MAP_CISCO_IOS) - elif platform == "cisco_nxos": + elif device_type == "cisco_nxos": data = MAP_OTHER.copy() data.update(MAP_CISCO_IOS) data.update(MAP_CISCO_NXOS) - elif platform == "hp_comware": # h3c + elif device_type == "hp_comware": # h3c data = MAP_OTHER.copy() data.update(MAP_CISCO_IOS) data.update(MAP_HP_COMWARE) - elif platform == "hp_procurve": # h3c + elif device_type == "hp_procurve": # h3c data = MAP_OTHER.copy() data.update(MAP_CISCO_IOS) data.update(MAP_HP_PROCURVE) else: - data: DStr = MAP_HP_COMWARE.copy() + data = MAP_HP_COMWARE.copy() data.update(MAP_HP_PROCURVE) data.update(MAP_CISCO_ASR) data.update(MAP_CISCO_NXOS) @@ -136,10 +147,12 @@ def short_to_long(platform: str = "", key_lower: bool = False, value_lower: bool return data -def short_to_short(platform: str = "", key_lower: bool = False, value_lower: bool = False) -> DStr: - """Returns Interfaces map short-to-short, platform specific +def short_to_short(device_type: str = "", + key_lower: bool = False, + value_lower: bool = False) -> DStr: + """Returns Interfaces map short-to-short, device_type specific :: - :param platform: Platform, increase priority of platform specific keys + :param device_type: Netmiko device type, increase priority of device_type specific keys :param key_lower: True - keys lower-case, False - keys upper-case :param value_lower: True - values lower-case, False - values upper-case :return: Interfaces map @@ -147,10 +160,10 @@ def short_to_short(platform: str = "", key_lower: bool = False, value_lower: boo short_to_short(key_lower=True) -> {"fa": "Fa", ...} short_to_short(value_lower=True) -> {"Fa": "fa", ...} """ - data: DStr = short_to_long(platform=platform) + data: DStr = short_to_long(device_type=device_type) data = {k: k for k in data} - intf_map_l2s: DStr = long_to_short(platform=platform) - intf_map_s2l: DStr = short_to_long(platform=platform) + intf_map_l2s: DStr = long_to_short(device_type=device_type) + intf_map_s2l: DStr = short_to_long(device_type=device_type) for short_upper, long_upper in intf_map_s2l.items(): if value := intf_map_l2s.get(long_upper): data[short_upper] = value @@ -158,12 +171,10 @@ def short_to_short(platform: str = "", key_lower: bool = False, value_lower: boo return data - - # ============================== helper ============================== def _overlapped(data: DStr) -> DStr: - """Returns Interfaces map long-to-short that overlapped with short key in other platforms + """Returns Interfaces map long-to-short that overlapped with short key in other device_type """ data_ = {v: k for k, v in MAP_OTHER.items()} diff --git a/netports/static.py b/netports/static.py index 93c7a7e..a6d4fab 100644 --- a/netports/static.py +++ b/netports/static.py @@ -1,6 +1,12 @@ """Static settings""" -PLATFORMS = ["cisco_asr", "cisco_ios", "cisco_nxos", "hp_comware", "hp_procurve"] +DEVICE_TYPES = [ + "cisco_asr", + "cisco_ios", + "cisco_nxos", + "hp_comware", + "hp_procurve", +] RANGE_SPLITTER = "-" RANGE_SPLITTER_HPE = " to " RANGE_SPLITTERS = [RANGE_SPLITTER, RANGE_SPLITTER_HPE] diff --git a/netports/types_.py b/netports/types_.py index 8b50022..69f129a 100644 --- a/netports/types_.py +++ b/netports/types_.py @@ -1,6 +1,7 @@ """Typing""" from typing import Any, Dict, Iterable, List, Optional, Set, Tuple, Union +# one-level DAny = Dict[str, Any] DStr = Dict[str, str] DiAny = Dict[int, Any] @@ -13,14 +14,16 @@ SInt = Set[int] SStr = Set[str] StrInt = Union[str, int] +T2Str = Tuple[str, str] +T3Str = Tuple[str, str, str] +T5Str = Tuple[str, str, str, str, str] TIntStr = Tuple[int, str] +# two-level DLStr = Dict[str, LStr] DSStr = Dict[str, SStr] IStrInt = Union[IStr, IInt] +LT2Str = List[T2Str] LTIntStr = List[TIntStr] StrIInt = Union[str, int, IInt] T2SInt = Tuple[SInt, SInt] -T2Str = Tuple[str, str] -T3Str = Tuple[str, str, str] -T5Str = Tuple[str, str, str, str, str] diff --git a/pyproject.toml b/pyproject.toml index 0b554c0..1286e43 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "netports" -version = "0.8.2" +version = "0.9.0" authors = [{ name="Vladimir Prusakov", email="vladimir.prusakovs@gmail.com" }] description = "Python tools for managing ranges of VLANs, TCP/UDP ports, IP protocols, Interfaces" readme = "README.rst" @@ -21,7 +21,7 @@ classifiers = [ "Homepage" = "https://github.com/vladimirs-git/netports" "Repository" = "https://github.com/vladimirs-git/netports" "Bug Tracker" = "https://github.com/vladimirs-git/netports/issues" -"Download URL" = "https://github.com/vladimirs-git/netports/archive/refs/tags/0.8.2.tar.gz" +"Download URL" = "https://github.com/vladimirs-git/netports/archive/refs/tags/0.9.0.tar.gz" [tool.setuptools.packages.find] include = ["netports"] [tool.setuptools.package-data] diff --git a/tests/helpers__intf_name.py b/tests/helpers__intf_name.py index f58b1dc..25107cb 100644 --- a/tests/helpers__intf_name.py +++ b/tests/helpers__intf_name.py @@ -29,7 +29,6 @@ Port-channel1 0 0 0 0 0 0 0 """ - # ============================ CISCO NXOS ============================ # show run | include interface SHOW_RUN__NXOS = """ @@ -68,7 +67,6 @@ pan Eth1/37 120 OR ethernet1/1 """ - # ========================== CISCO ASR 9000 ========================== # show run | include interface @@ -108,7 +106,6 @@ Te0/0/0/1.100 up up 802.1Q 1518 10000000 """ - # ============================ HP COMWARE ============================ # display current-configuration | include interface diff --git a/tests/test__intf.py b/tests/test__intf.py index 323c169..15c1a64 100644 --- a/tests/test__intf.py +++ b/tests/test__intf.py @@ -135,9 +135,13 @@ def test_valid__init__(self): (dict(line=f"{id0}1,2,3,4"), exp_b6), (dict(line=f"{id0}1:2:3:4"), exp_b7), (dict(line=f"{id0}1-2-3-4", splitter="-"), exp_b8), - # platform - (dict(line="interface Ethernet1/1", platform=""), exp_c1), - (dict(line="interface Ethernet1/1", platform="cisco_asr"), exp_c1), + # device_type + (dict(line="interface Ethernet1/1", device_type=""), exp_c1), + (dict(line="interface Ethernet1/1", device_type="cisco_asr"), exp_c1), + (dict(line="interface Ethernet1/1", device_type="cisco_ios"), exp_c1), + (dict(line="interface Ethernet1/1", device_type="cisco_nxos"), exp_c1), + (dict(line="interface Ethernet1/1", device_type="hp_comware"), exp_c1), + (dict(line="interface Ethernet1/1", device_type="hp_procurve"), exp_c1), ]: intf_o = Intf(**kwargs) self._test_attrs(obj=intf_o, exp_d=exp_d, msg=f"{kwargs=}") @@ -145,7 +149,7 @@ def test_valid__init__(self): def test_invalid__init__(self): """Intf.__init__()""" for kwargs, error in [ - (dict(line="Ethernet1/1", platform="typo"), ValueError), + (dict(line="Ethernet1/1", device_type="typo"), ValueError), ]: with self.assertRaises(error, msg=f"{kwargs=}"): Intf(**kwargs) @@ -185,7 +189,7 @@ def test_valid__all_names(self): self.assertEqual(expected, actual, msg=f"{line=}") def test_valid__all_names__cisco_asr(self): - """Intf.all_names() platform="cisco_asr" """ + """Intf.all_names() device_type="cisco_asr" """ for line, expected in [ # upper ("interface Tunnel-ip1", th.ALL_NAMES_TUN_IP_UPPER), @@ -197,17 +201,17 @@ def test_valid__all_names__cisco_asr(self): ("tu1", th.ALL_NAMES_TUN_IP_LOWER), ("ti1", th.ALL_NAMES_TUN_IP), ]: - obj = Intf(line=line, platform="cisco_asr") + obj = Intf(line=line, device_type="cisco_asr") actual = obj.all_names() self.assertEqual(expected, actual, msg=f"{line=}") def test_valid__all_names__hp_procurve(self): - """Intf.all_names() platform="hp_procurve" """ + """Intf.all_names() device_type="hp_procurve" """ for line, expected in [ ("interface 1", th.ALL_NAMES_HPC), ("1", th.ALL_NAMES_HPC), ]: - obj = Intf(line=line, platform="hp_procurve") + obj = Intf(line=line, device_type="hp_procurve") actual = obj.all_names() self.assertEqual(expected, actual, msg=f"{line=}") @@ -273,8 +277,8 @@ def test_valid__name_full(self): self.assertEqual(expected, actual, msg=f"{line=}") def test_valid__name_full__cisco_asr(self): - """Intf.name_full() platform="cisco_asr" """ - platform = "cisco_asr" + """Intf.name_full() device_type="cisco_asr" """ + device_type = "cisco_asr" for line, expected in [ ("interface tunnel-ip1", "interface tunnel-ip1"), ("tunnel-ip1", "interface tunnel-ip1"), @@ -282,9 +286,9 @@ def test_valid__name_full__cisco_asr(self): ("tu1", "interface tunnel-ip1"), ("ti1", "interface tunnel-ip1"), ]: - obj = Intf(line=line, platform=platform) + obj = Intf(line=line, device_type=device_type) actual = obj.name_full() - self.assertEqual(expected, actual, msg=f"{line=} {platform=}") + self.assertEqual(expected, actual, msg=f"{line=} {device_type=}") def test_valid__name_long(self): """Intf.name_long()""" @@ -333,8 +337,8 @@ def test_valid__name_long(self): self.assertEqual(expected, actual, msg=f"{line=}") def test_valid__name_long__cisco_asr(self): - """Intf.name_long() platform="cisco_asr" """ - platform = "cisco_asr" + """Intf.name_long() device_type="cisco_asr" """ + device_type = "cisco_asr" for line, expected in [ ("interface tunnel-ip1", "tunnel-ip1"), ("tunnel-ip1", "tunnel-ip1"), @@ -342,9 +346,9 @@ def test_valid__name_long__cisco_asr(self): ("tu1", "tunnel-ip1"), ("ti1", "tunnel-ip1"), ]: - obj = Intf(line=line, platform=platform) + obj = Intf(line=line, device_type=device_type) actual = obj.name_long() - self.assertEqual(expected, actual, msg=f"{line=} {platform=}") + self.assertEqual(expected, actual, msg=f"{line=} {device_type=}") def test_valid__name_short(self): """Intf.name_short()""" @@ -392,9 +396,45 @@ def test_valid__name_short(self): actual = obj.name_short() self.assertEqual(expected, actual, msg=f"{line=}") + def test_valid__name_short__device_type(self): + """Intf.name_short()""" + for line, device_type, expected in [ + ("interface Vlan1", "", "V1"), + ("interface Vlan1", "cisco_asr", "Vlan1"), + ("interface Vlan1", "cisco_ios", "Vlan1"), + ("interface Vlan1", "cisco_nxos", "Vlan1"), + ("interface Vlan1", "hp_comware", "V1"), + ("interface Vlan1", "hp_procurve", "Vlan1"), + + ("interface GigabitEthernet1", "", "Gi1"), + ("interface GigabitEthernet1", "cisco_asr", "Gi1"), + ("interface GigabitEthernet1", "cisco_ios", "Gi1"), + ("interface GigabitEthernet1", "cisco_nxos", "Gi1"), + ("interface GigabitEthernet1", "hp_comware", "GE1"), + ("interface GigabitEthernet1", "hp_procurve", "Gi1"), + ]: + obj = Intf(line=line, device_type=device_type) + actual = obj.name_short() + self.assertEqual(expected, actual, msg=f"{line=}") + + def test_valid__name_short__replace(self): + """Intf.name_short(replace)""" + for line, replace, expected in [ + ("interface Ethernet1", None, "Eth1"), + ("interface Ethernet1", [], "Eth1"), + ("interface Ethernet1", [("Eth", "Fa")], "Fa1"), + ("interface Ethernet1", [("typo", "Fa")], "Eth1"), + ("interface Ethernet1", [("Eth", "Fa"), ("typo", "Fa")], "Fa1"), + ("interface Ethernet1", [("typo", "Fa"), ("Eth", "Fa")], "Fa1"), + ("interface Ethernet1", [("Eth", "FA"), ("Eth", "Fa")], "FA1"), + ]: + obj = Intf(line) + actual = obj.name_short(replace=replace) + self.assertEqual(expected, actual, msg=f"{line=}") + def test_valid__name_short__cisco_asr(self): - """Intf.name_short() platform="cisco_asr" """ - platform = "cisco_asr" + """Intf.name_short() device_type="cisco_asr" """ + device_type = "cisco_asr" for line, expected in [ ("interface tunnel-ip1", "ti1"), ("tunnel-ip1", "ti1"), @@ -402,9 +442,9 @@ def test_valid__name_short__cisco_asr(self): ("tu1", "ti1"), ("ti1", "ti1"), ]: - obj = Intf(line=line, platform=platform) + obj = Intf(line=line, device_type=device_type) actual = obj.name_short() - self.assertEqual(expected, actual, msg=f"{line=} {platform=}") + self.assertEqual(expected, actual, msg=f"{line=} {device_type=}") def test_valid__part_after(self): """Intf.part_after()""" diff --git a/tests/test__intf_map.py b/tests/test__intf_map.py index c462764..3fcbe95 100644 --- a/tests/test__intf_map.py +++ b/tests/test__intf_map.py @@ -1,7 +1,9 @@ """unittest intf_map.py""" import unittest + import dictdiffer # type: ignore + from netports import intf_map from tests import helpers__intf_map as hm @@ -18,11 +20,11 @@ def test_valid__short_to_long(self): (dict(), hm.SHORT_TO_LONG), (dict(value_lower=True), hm.SHORT_TO_LONG_VALUE_LOW), (dict(key_lower=True), hm.SHORT_TO_LONG_KEY_LOW), - (dict(platform="cisco_asr"), hm.SHORT_TO_LONG_ASR), - (dict(platform="cisco_ios"), hm.SHORT_TO_LONG_IOS), - (dict(platform="cisco_nxos"), hm.SHORT_TO_LONG_NXOS), - (dict(platform="hp_comware"), hm.SHORT_TO_LONG_H3C), - (dict(platform="hp_procurve"), hm.SHORT_TO_LONG_HPC), + (dict(device_type="cisco_asr"), hm.SHORT_TO_LONG_ASR), + (dict(device_type="cisco_ios"), hm.SHORT_TO_LONG_IOS), + (dict(device_type="cisco_nxos"), hm.SHORT_TO_LONG_NXOS), + (dict(device_type="hp_comware"), hm.SHORT_TO_LONG_H3C), + (dict(device_type="hp_procurve"), hm.SHORT_TO_LONG_HPC), ]: actual = intf_map.short_to_long(**kwargs) diff = list(dictdiffer.diff(actual, expected)) @@ -34,11 +36,11 @@ def test_valid__short_to_short(self): (dict(), hm.SHORT_TO_SHORT), (dict(value_lower=True), hm.SHORT_TO_SHORT_VALUE_LOW), (dict(key_lower=True), hm.SHORT_TO_SHORT_KEY_LOW), - (dict(platform="cisco_asr"), hm.SHORT_TO_SHORT_ASR), - (dict(platform="cisco_ios"), hm.SHORT_TO_SHORT_IOS), - (dict(platform="cisco_nxos"), hm.SHORT_TO_SHORT_NXOS), - (dict(platform="hp_comware"), hm.SHORT_TO_SHORT_H3C), - (dict(platform="hp_procurve"), hm.SHORT_TO_SHORT_HPC), + (dict(device_type="cisco_asr"), hm.SHORT_TO_SHORT_ASR), + (dict(device_type="cisco_ios"), hm.SHORT_TO_SHORT_IOS), + (dict(device_type="cisco_nxos"), hm.SHORT_TO_SHORT_NXOS), + (dict(device_type="hp_comware"), hm.SHORT_TO_SHORT_H3C), + (dict(device_type="hp_procurve"), hm.SHORT_TO_SHORT_HPC), ]: actual = intf_map.short_to_short(**kwargs) diff = list(dictdiffer.diff(actual, expected)) @@ -50,11 +52,11 @@ def test_valid__long_to_short(self): (dict(), hm.LONG_TO_SHORT), (dict(value_lower=True), hm.LONG_TO_SHORT_VALUE_LOW), (dict(key_lower=True), hm.LONG_TO_SHORT_KEY_LOW), - (dict(platform="cisco_asr"), hm.LONG_TO_SHORT_ASR), - (dict(platform="cisco_ios"), hm.LONG_TO_SHORT_IOS), - (dict(platform="cisco_nxos"), hm.LONG_TO_SHORT_NXOS), - (dict(platform="hp_comware"), hm.LONG_TO_SHORT_H3C), - (dict(platform="hp_procurve"), hm.LONG_TO_SHORT_HPC), + (dict(device_type="cisco_asr"), hm.LONG_TO_SHORT_ASR), + (dict(device_type="cisco_ios"), hm.LONG_TO_SHORT_IOS), + (dict(device_type="cisco_nxos"), hm.LONG_TO_SHORT_NXOS), + (dict(device_type="hp_comware"), hm.LONG_TO_SHORT_H3C), + (dict(device_type="hp_procurve"), hm.LONG_TO_SHORT_HPC), ]: actual = intf_map.long_to_short(**kwargs) diff = list(dictdiffer.diff(actual, expected)) @@ -66,11 +68,11 @@ def test_valid__long_to_long(self): (dict(), hm.LONG_TO_LONG), (dict(value_lower=True), hm.LONG_TO_LONG_VALUE_LOW), (dict(key_lower=True), hm.LONG_TO_LONG_KEY_LOW), - (dict(platform="cisco_asr"), hm.LONG_TO_LONG_ASR), - (dict(platform="cisco_ios"), hm.LONG_TO_LONG_IOS), - (dict(platform="cisco_nxos"), hm.LONG_TO_LONG_NXOS), - (dict(platform="hp_comware"), hm.LONG_TO_LONG_H3C), - (dict(platform="hp_procurve"), hm.LONG_TO_LONG_HPC), + (dict(device_type="cisco_asr"), hm.LONG_TO_LONG_ASR), + (dict(device_type="cisco_ios"), hm.LONG_TO_LONG_IOS), + (dict(device_type="cisco_nxos"), hm.LONG_TO_LONG_NXOS), + (dict(device_type="hp_comware"), hm.LONG_TO_LONG_H3C), + (dict(device_type="hp_procurve"), hm.LONG_TO_LONG_HPC), ]: actual = intf_map.long_to_long(**kwargs) diff = list(dictdiffer.diff(actual, expected)) diff --git a/tests/test__package.py b/tests/test__package.py index 66632ad..3beabb0 100644 --- a/tests/test__package.py +++ b/tests/test__package.py @@ -43,21 +43,6 @@ def _last_modified_date(root: Path) -> str: class Test(unittest.TestCase): """package""" - def test_valid__init__(self): - """__init__.py""" - regex = r"(import|from)\s" - - path1 = Path.joinpath(ROOT, "__init__.py") - lines1 = {s.strip() for s in path1.read_text().splitlines()} - imports1 = {s for s in lines1 if re.match(regex, s)} - - path2 = Path.joinpath(ROOT, "netports", "__init__.py") - lines2 = {s.strip() for s in path2.read_text().splitlines()} - imports2 = {s for s in lines2 if re.match(regex, s)} - - diff = imports1.difference(imports2) - self.assertEqual(len(diff), 0, msg=f"imports {diff=} in {path1=} {path2=}") - def test_valid__version(self): """version in README, URL""" package = PYPROJECT["project"]["name"].replace("_", "-")