diff --git a/netx_api/biz_state/parsers/__init__.py b/netx_api/biz_state/parsers/__init__.py index d68b75b..9011cba 100644 --- a/netx_api/biz_state/parsers/__init__.py +++ b/netx_api/biz_state/parsers/__init__.py @@ -1,22 +1,56 @@ -"""Biz-state CLI parsers: vendor folders + one module per command/metric.""" +"""Biz-state CLI parsers: vendor folders + one module per command/metric. + +Layout:: + + parsers/ + common/ # cross-vendor (lldp, vrf_list, vrf_route_summary) + zte/ # implemented status tables + cisco/ # skeleton — add command modules here + huawei/ + h3c/ + juniper/ + nokia/ + ericsson/ + +Each vendor package exports ``PARSERS: dict[parser_id, normalize_fn]``. +""" from __future__ import annotations from typing import Any, Callable +from .cisco import PARSERS as _CISCO_PARSERS from .common.lldp_neighbors import normalize_lldp_neighbors from .common.vrf_list import normalize_vrf_list from .common.vrf_route_summary import normalize_vrf_route_summary +from .ericsson import PARSERS as _ERICSSON_PARSERS +from .h3c import PARSERS as _H3C_PARSERS +from .huawei import PARSERS as _HUAWEI_PARSERS +from .juniper import PARSERS as _JUNIPER_PARSERS +from .nokia import PARSERS as _NOKIA_PARSERS from .zte import PARSERS as _ZTE_PARSERS NormalizeFn = Callable[..., list[dict[str, Any]]] +# Later vendor packages may override earlier ones for the same parser_id. +# Prefer moving shared logic to common/ when two vendors implement the same metric. +_VENDOR_PARSERS: list[dict[str, NormalizeFn]] = [ + _CISCO_PARSERS, + _HUAWEI_PARSERS, + _H3C_PARSERS, + _JUNIPER_PARSERS, + _NOKIA_PARSERS, + _ERICSSON_PARSERS, + _ZTE_PARSERS, # last so current ZTE status parsers win on overlaps +] + _REGISTRY: dict[str, NormalizeFn] = { "lldp_neighbors": normalize_lldp_neighbors, "vrf_list": normalize_vrf_list, "vrf_route_summary": normalize_vrf_route_summary, - **_ZTE_PARSERS, } +for _pack in _VENDOR_PARSERS: + _REGISTRY.update(_pack) def get_parser(parser_id: str) -> NormalizeFn | None: diff --git a/netx_api/biz_state/parsers/cisco/__init__.py b/netx_api/biz_state/parsers/cisco/__init__.py new file mode 100644 index 0000000..69f0964 --- /dev/null +++ b/netx_api/biz_state/parsers/cisco/__init__.py @@ -0,0 +1,22 @@ +"""Cisco IOS / NX-OS / XR parsers. + +LLDP already works via ``common.lldp_neighbors`` (profile ``parser_id=lldp_neighbors``). + +Stub modules (not registered until implemented):: + + interface_brief.py arp.py isis_adjacency.py nd6_cache.py bgp_peer.py + +When ready, import and add to ``PARSERS``. If ``parser_id`` already exists for +another vendor, prefer a vendor-dispatch in ``common/`` or a prefixed parser_id. +""" + +from __future__ import annotations + +from typing import Any, Callable + +NormalizeFn = Callable[..., list[dict[str, Any]]] + +# Do not register stubs yet — they raise NotImplementedError. +PARSERS: dict[str, NormalizeFn] = {} + +__all__ = ["PARSERS"] diff --git a/netx_api/biz_state/parsers/cisco/arp.py b/netx_api/biz_state/parsers/cisco/arp.py new file mode 100644 index 0000000..f5c3688 --- /dev/null +++ b/netx_api/biz_state/parsers/cisco/arp.py @@ -0,0 +1,17 @@ +"""Cisco: show ip arp / show arp — TODO implement.""" + +from __future__ import annotations + +from typing import Any + + +def normalize_arp( + *, + raw_text: str, + vendor: str = "", + device_type: str = "", + command: str = "", + params: dict[str, str] | None = None, +) -> list[dict[str, Any]]: + _ = (raw_text, vendor, device_type, command, params) + raise NotImplementedError("cisco arp parser not implemented yet") diff --git a/netx_api/biz_state/parsers/cisco/bgp_peer.py b/netx_api/biz_state/parsers/cisco/bgp_peer.py new file mode 100644 index 0000000..8c74d85 --- /dev/null +++ b/netx_api/biz_state/parsers/cisco/bgp_peer.py @@ -0,0 +1,17 @@ +"""Cisco: show bgp * summary / show ip bgp summary — TODO implement.""" + +from __future__ import annotations + +from typing import Any + + +def normalize_bgp_peer( + *, + raw_text: str, + vendor: str = "", + device_type: str = "", + command: str = "", + params: dict[str, str] | None = None, +) -> list[dict[str, Any]]: + _ = (raw_text, vendor, device_type, command, params) + raise NotImplementedError("cisco bgp_peer parser not implemented yet") diff --git a/netx_api/biz_state/parsers/cisco/interface_brief.py b/netx_api/biz_state/parsers/cisco/interface_brief.py new file mode 100644 index 0000000..003f05e --- /dev/null +++ b/netx_api/biz_state/parsers/cisco/interface_brief.py @@ -0,0 +1,17 @@ +"""Cisco: show ip interface brief / show interfaces status — TODO implement.""" + +from __future__ import annotations + +from typing import Any + + +def normalize_interface_brief( + *, + raw_text: str, + vendor: str = "", + device_type: str = "", + command: str = "", + params: dict[str, str] | None = None, +) -> list[dict[str, Any]]: + _ = (raw_text, vendor, device_type, command, params) + raise NotImplementedError("cisco interface_brief parser not implemented yet") diff --git a/netx_api/biz_state/parsers/cisco/isis_adjacency.py b/netx_api/biz_state/parsers/cisco/isis_adjacency.py new file mode 100644 index 0000000..fd6194c --- /dev/null +++ b/netx_api/biz_state/parsers/cisco/isis_adjacency.py @@ -0,0 +1,17 @@ +"""Cisco: show isis neighbors / adjacency — TODO implement.""" + +from __future__ import annotations + +from typing import Any + + +def normalize_isis_adjacency( + *, + raw_text: str, + vendor: str = "", + device_type: str = "", + command: str = "", + params: dict[str, str] | None = None, +) -> list[dict[str, Any]]: + _ = (raw_text, vendor, device_type, command, params) + raise NotImplementedError("cisco isis_adjacency parser not implemented yet") diff --git a/netx_api/biz_state/parsers/cisco/nd6_cache.py b/netx_api/biz_state/parsers/cisco/nd6_cache.py new file mode 100644 index 0000000..c044a1b --- /dev/null +++ b/netx_api/biz_state/parsers/cisco/nd6_cache.py @@ -0,0 +1,17 @@ +"""Cisco: show ipv6 neighbors — TODO implement.""" + +from __future__ import annotations + +from typing import Any + + +def normalize_nd6_cache( + *, + raw_text: str, + vendor: str = "", + device_type: str = "", + command: str = "", + params: dict[str, str] | None = None, +) -> list[dict[str, Any]]: + _ = (raw_text, vendor, device_type, command, params) + raise NotImplementedError("cisco nd6_cache parser not implemented yet") diff --git a/netx_api/biz_state/parsers/common/__init__.py b/netx_api/biz_state/parsers/common/__init__.py index 7da73de..d1f36f6 100644 --- a/netx_api/biz_state/parsers/common/__init__.py +++ b/netx_api/biz_state/parsers/common/__init__.py @@ -1 +1,4 @@ -"""Cross-vendor / shared parsers.""" +"""Cross-vendor shared parsers (LLDP, VRF discover / route summary, …). + +Vendor-specific show/display commands live under ``parsers//``. +""" diff --git a/netx_api/biz_state/parsers/ericsson/__init__.py b/netx_api/biz_state/parsers/ericsson/__init__.py new file mode 100644 index 0000000..5adf7c2 --- /dev/null +++ b/netx_api/biz_state/parsers/ericsson/__init__.py @@ -0,0 +1,16 @@ +"""Ericsson IPOS parsers (skeleton). + +LLDP profile exists; TextFSM may still be stub — see topology_lldp.STUB_PARSER_KEYS. + +Add one module per show command, then register in ``PARSERS``. +""" + +from __future__ import annotations + +from typing import Any, Callable + +NormalizeFn = Callable[..., list[dict[str, Any]]] + +PARSERS: dict[str, NormalizeFn] = {} + +__all__ = ["PARSERS"] diff --git a/netx_api/biz_state/parsers/h3c/__init__.py b/netx_api/biz_state/parsers/h3c/__init__.py new file mode 100644 index 0000000..cd6de8b --- /dev/null +++ b/netx_api/biz_state/parsers/h3c/__init__.py @@ -0,0 +1,17 @@ +"""H3C / HP Comware parsers. + +LLDP already works via ``common.lldp_neighbors`` +(``display lldp neighbor-information list``). + +Add one module per display command, then register in ``PARSERS``. +""" + +from __future__ import annotations + +from typing import Any, Callable + +NormalizeFn = Callable[..., list[dict[str, Any]]] + +PARSERS: dict[str, NormalizeFn] = {} + +__all__ = ["PARSERS"] diff --git a/netx_api/biz_state/parsers/huawei/__init__.py b/netx_api/biz_state/parsers/huawei/__init__.py new file mode 100644 index 0000000..f9028c7 --- /dev/null +++ b/netx_api/biz_state/parsers/huawei/__init__.py @@ -0,0 +1,21 @@ +"""Huawei VRP parsers. + +LLDP already works via ``common.lldp_neighbors`` (``display lldp neighbor``). + +Stub modules (not registered until implemented):: + + interface_brief.py arp.py isis_adjacency.py nd6_cache.py bgp_peer.py + +When ready, import and add to ``PARSERS``. +""" + +from __future__ import annotations + +from typing import Any, Callable + +NormalizeFn = Callable[..., list[dict[str, Any]]] + +# Do not register stubs yet — they raise NotImplementedError. +PARSERS: dict[str, NormalizeFn] = {} + +__all__ = ["PARSERS"] diff --git a/netx_api/biz_state/parsers/huawei/arp.py b/netx_api/biz_state/parsers/huawei/arp.py new file mode 100644 index 0000000..cf28553 --- /dev/null +++ b/netx_api/biz_state/parsers/huawei/arp.py @@ -0,0 +1,17 @@ +"""Huawei: display arp all / display arp — TODO implement.""" + +from __future__ import annotations + +from typing import Any + + +def normalize_arp( + *, + raw_text: str, + vendor: str = "", + device_type: str = "", + command: str = "", + params: dict[str, str] | None = None, +) -> list[dict[str, Any]]: + _ = (raw_text, vendor, device_type, command, params) + raise NotImplementedError("huawei arp parser not implemented yet") diff --git a/netx_api/biz_state/parsers/huawei/bgp_peer.py b/netx_api/biz_state/parsers/huawei/bgp_peer.py new file mode 100644 index 0000000..27082e7 --- /dev/null +++ b/netx_api/biz_state/parsers/huawei/bgp_peer.py @@ -0,0 +1,17 @@ +"""Huawei: display bgp peer / display bgp vpnv4 all peer — TODO implement.""" + +from __future__ import annotations + +from typing import Any + + +def normalize_bgp_peer( + *, + raw_text: str, + vendor: str = "", + device_type: str = "", + command: str = "", + params: dict[str, str] | None = None, +) -> list[dict[str, Any]]: + _ = (raw_text, vendor, device_type, command, params) + raise NotImplementedError("huawei bgp_peer parser not implemented yet") diff --git a/netx_api/biz_state/parsers/huawei/interface_brief.py b/netx_api/biz_state/parsers/huawei/interface_brief.py new file mode 100644 index 0000000..930fcea --- /dev/null +++ b/netx_api/biz_state/parsers/huawei/interface_brief.py @@ -0,0 +1,17 @@ +"""Huawei: display interface brief — TODO implement.""" + +from __future__ import annotations + +from typing import Any + + +def normalize_interface_brief( + *, + raw_text: str, + vendor: str = "", + device_type: str = "", + command: str = "", + params: dict[str, str] | None = None, +) -> list[dict[str, Any]]: + _ = (raw_text, vendor, device_type, command, params) + raise NotImplementedError("huawei interface_brief parser not implemented yet") diff --git a/netx_api/biz_state/parsers/huawei/isis_adjacency.py b/netx_api/biz_state/parsers/huawei/isis_adjacency.py new file mode 100644 index 0000000..4035caa --- /dev/null +++ b/netx_api/biz_state/parsers/huawei/isis_adjacency.py @@ -0,0 +1,17 @@ +"""Huawei: display isis peer / display isis interface — TODO implement.""" + +from __future__ import annotations + +from typing import Any + + +def normalize_isis_adjacency( + *, + raw_text: str, + vendor: str = "", + device_type: str = "", + command: str = "", + params: dict[str, str] | None = None, +) -> list[dict[str, Any]]: + _ = (raw_text, vendor, device_type, command, params) + raise NotImplementedError("huawei isis_adjacency parser not implemented yet") diff --git a/netx_api/biz_state/parsers/huawei/nd6_cache.py b/netx_api/biz_state/parsers/huawei/nd6_cache.py new file mode 100644 index 0000000..9ecc7ec --- /dev/null +++ b/netx_api/biz_state/parsers/huawei/nd6_cache.py @@ -0,0 +1,17 @@ +"""Huawei: display ipv6 neighbors — TODO implement.""" + +from __future__ import annotations + +from typing import Any + + +def normalize_nd6_cache( + *, + raw_text: str, + vendor: str = "", + device_type: str = "", + command: str = "", + params: dict[str, str] | None = None, +) -> list[dict[str, Any]]: + _ = (raw_text, vendor, device_type, command, params) + raise NotImplementedError("huawei nd6_cache parser not implemented yet") diff --git a/netx_api/biz_state/parsers/juniper/__init__.py b/netx_api/biz_state/parsers/juniper/__init__.py new file mode 100644 index 0000000..806c69a --- /dev/null +++ b/netx_api/biz_state/parsers/juniper/__init__.py @@ -0,0 +1,16 @@ +"""Juniper Junos parsers. + +LLDP already works via ``common.lldp_neighbors`` (``show lldp neighbors``). + +Add one module per show command, then register in ``PARSERS``. +""" + +from __future__ import annotations + +from typing import Any, Callable + +NormalizeFn = Callable[..., list[dict[str, Any]]] + +PARSERS: dict[str, NormalizeFn] = {} + +__all__ = ["PARSERS"] diff --git a/netx_api/biz_state/parsers/nokia/__init__.py b/netx_api/biz_state/parsers/nokia/__init__.py new file mode 100644 index 0000000..a0079ab --- /dev/null +++ b/netx_api/biz_state/parsers/nokia/__init__.py @@ -0,0 +1,17 @@ +"""Nokia / Alcatel (SROS / AOS) parsers. + +LLDP already works via ``common.lldp_neighbors`` +(``show system lldp neighbor`` / AOS ``show lldp remote-system``). + +Add one module per show command, then register in ``PARSERS``. +""" + +from __future__ import annotations + +from typing import Any, Callable + +NormalizeFn = Callable[..., list[dict[str, Any]]] + +PARSERS: dict[str, NormalizeFn] = {} + +__all__ = ["PARSERS"] diff --git a/netx_api/biz_state/parsers/zte/__init__.py b/netx_api/biz_state/parsers/zte/__init__.py index 59d75b9..10f00da 100644 --- a/netx_api/biz_state/parsers/zte/__init__.py +++ b/netx_api/biz_state/parsers/zte/__init__.py @@ -1,4 +1,8 @@ -"""ZTE ZXROS status parsers — one module per show command.""" +"""ZTE ZXROS status parsers — one module per show command. + +LLDP uses ``common.lldp_neighbors`` (``show lldp neighbor brief``). +Status tables below are ZTE-specific implementations. +""" from __future__ import annotations