mirror of
https://github.com/hansjone/netx.git
synced 2026-10-08 23:33:21 +08:00
Merge duplicate if-intf checks into Config Interface Intent.
Hide standalone IF VRF from the catalog and point ARP enrich at config_interface so one CLI maps to one check item. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
c1b1c0f75d
commit
1642a0adec
8 changed files with 37 additions and 21 deletions
|
|
@ -21,7 +21,7 @@ Cross-command (multi aux)
|
|||
1. Implement each aux as a normal status profile (steps 1–4)
|
||||
2. On the primary profile::
|
||||
|
||||
aux_commands=[AuxCommand(key="if_intf", profile_id="zte.if_intf")]
|
||||
aux_commands=[AuxCommand(key="if_intf", profile_id="zte.config_interface")]
|
||||
enrich_joins=[EnrichJoin(from_aux="if_intf", on="interface", take=("vrf",))]
|
||||
|
||||
3. CollectSession caches identical concrete CLI in one batch; enrich runs after
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"""ZTE: show arp [| one-line].
|
||||
|
||||
Pipeline: TextFSM ``zte_zxros_show_arp`` → map → hand fallback.
|
||||
Cross-command VRF comes from profile ``enrich_joins`` (if_intf), not here.
|
||||
Cross-command VRF comes from profile ``enrich_joins`` (config_interface aux), not here.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
|
|
|||
|
|
@ -605,14 +605,14 @@ def _zte_status_profiles() -> list[ParseProfile]:
|
|||
command_template="show arp | one-line",
|
||||
match=r"(?i)^\s*show\s+arp(?:\s*\|\s*one-line)?\s*$",
|
||||
textfsm_command="show arp",
|
||||
description="ARP entries (IP/MAC/interface); VRF from if-intf aux.",
|
||||
description="ARP entries (IP/MAC/interface); VRF from config_interface aux.",
|
||||
fields=list(_ARP_FIELDS),
|
||||
tags=["arp", "l3", "status"],
|
||||
sort_order=320,
|
||||
enabled=True,
|
||||
kind="collect",
|
||||
aux_commands=[
|
||||
AuxCommand(key="if_intf", profile_id="zte.if_intf"),
|
||||
AuxCommand(key="if_intf", profile_id="zte.config_interface"),
|
||||
],
|
||||
enrich_joins=[
|
||||
EnrichJoin(from_aux="if_intf", on="interface", take=("vrf",)),
|
||||
|
|
@ -628,13 +628,13 @@ def _zte_status_profiles() -> list[ParseProfile]:
|
|||
match=r"(?i)^\s*show\s+running-config\s+if-intf\s*$",
|
||||
textfsm_command="show running-config if-intf",
|
||||
description=(
|
||||
"Interface VRF map for ARP enrich (aux). "
|
||||
"Free-form CLI match prefers zte.config_interface (longer regex)."
|
||||
"Compat/aux-only interface→VRF map (disabled in catalog). "
|
||||
"Use Config Interface Intent (zte.config_interface) instead."
|
||||
),
|
||||
fields=list(_IF_INTF_FIELDS),
|
||||
tags=["interface", "vrf", "config", "status", "aux"],
|
||||
sort_order=325,
|
||||
enabled=True,
|
||||
enabled=False,
|
||||
kind="collect",
|
||||
),
|
||||
ParseProfile(
|
||||
|
|
@ -1202,7 +1202,10 @@ def _zte_status_profiles() -> list[ParseProfile]:
|
|||
command_template="show running-config if-intf",
|
||||
match=r"(?i)^\s*show\s+running-config\s+if-intf(?:\s*\|\s*one-line)?\s*$",
|
||||
textfsm_command="show running-config if-intf",
|
||||
description="Interface VRF/IP/admin intent (richer than if_intf aux map).",
|
||||
description=(
|
||||
"Interface VRF/IP/admin intent; also ARP VRF enrich source "
|
||||
"(replaces standalone IF VRF / if_intf check)."
|
||||
),
|
||||
fields=list(_CONFIG_IFACE_FIELDS),
|
||||
tags=["config", "interface", "intent"],
|
||||
sort_order=510,
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ ParseProfile (命令 + schema + aux + enrich)
|
|||
| `netx_api/biz_state/enrich.py` | 声明式等值 join |
|
||||
| `netx_api/biz_state/collect_runner.py` | 任务会话采集落库 |
|
||||
|
||||
样板:`zte/interface_brief`(单命令)、`zte/if_intf`(可复用辅表)、`zte.arp`(主+辅+enrich)。
|
||||
样板:`zte/interface_brief`(单命令)、`zte.config_interface`(可复用辅表)、`zte.arp`(主+辅+enrich)。
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ ParseProfile (命令 + schema + aux + enrich)
|
|||
|
||||
```python
|
||||
aux_commands=[
|
||||
AuxCommand(key="if_intf", profile_id="zte.if_intf"),
|
||||
AuxCommand(key="if_intf", profile_id="zte.config_interface"),
|
||||
# 多辅:再 append;key 唯一
|
||||
],
|
||||
enrich_joins=[
|
||||
|
|
@ -159,5 +159,5 @@ Sheet(`metrics_json[]`)能力:
|
|||
- Enrich:`biz_state/enrich.py`
|
||||
- Session:`biz_state/collect_session.py`
|
||||
- Compare:`biz_state/compare_rules.py`、`compare_engine.py`、`compare_service.py`
|
||||
- ARP+VRF:`profiles.py` → `zte.arp`;`parsers/zte/arp.py`;`parsers/zte/if_intf.py`
|
||||
- ARP+VRF:`profiles.py` → `zte.arp`;`parsers/zte/arp.py`;辅表 `zte.config_interface`(`zte.if_intf` 已禁用仅兼容)
|
||||
- 模板:`cli_templates/zte/zte_zxros_show_arp.textfsm`、`..._if_intf.textfsm`
|
||||
|
|
|
|||
|
|
@ -59,18 +59,20 @@ class AuxResolveTests(unittest.TestCase):
|
|||
reload_profiles()
|
||||
|
||||
def test_resolve_from_profile_id(self) -> None:
|
||||
ra = resolve_aux_command(AuxCommand(key="if_intf", profile_id="zte.if_intf"))
|
||||
ra = resolve_aux_command(AuxCommand(key="if_intf", profile_id="zte.config_interface"))
|
||||
self.assertEqual(ra.command, "show running-config if-intf")
|
||||
self.assertEqual(ra.parser_id, "if_intf")
|
||||
self.assertIn("zte_zxros_show_running_config_if_intf", ra.rule_keys)
|
||||
self.assertEqual(ra.parser_id, "config_interface")
|
||||
|
||||
def test_arp_profile_slim(self) -> None:
|
||||
p = get_profile("zte.arp")
|
||||
assert p is not None
|
||||
self.assertEqual(p.aux_commands[0].key, "if_intf")
|
||||
self.assertEqual(p.aux_commands[0].profile_id, "zte.if_intf")
|
||||
self.assertEqual(p.aux_commands[0].profile_id, "zte.config_interface")
|
||||
self.assertEqual(len(p.enrich_joins), 1)
|
||||
self.assertEqual(p.enrich_joins[0].take, ("vrf",))
|
||||
ii = get_profile("zte.if_intf")
|
||||
assert ii is not None
|
||||
self.assertFalse(ii.enabled)
|
||||
|
||||
|
||||
class CollectSessionCacheTests(unittest.TestCase):
|
||||
|
|
@ -98,13 +100,13 @@ class ArpEnrichPipelineTests(unittest.TestCase):
|
|||
|
||||
def test_run_primary_with_enrich(self) -> None:
|
||||
if_recs, if_fsm, _ = run_parser(
|
||||
"if_intf",
|
||||
"config_interface",
|
||||
raw_text=IF_INTF_SAMPLE,
|
||||
vendor="zte",
|
||||
device_type="zte_zxros",
|
||||
command="show running-config if-intf",
|
||||
)
|
||||
ra = resolve_aux_command(AuxCommand(key="if_intf", profile_id="zte.if_intf"))
|
||||
ra = resolve_aux_command(AuxCommand(key="if_intf", profile_id="zte.config_interface"))
|
||||
bundle = build_parse_bundle(
|
||||
primary_raw=ARP_MATCHING,
|
||||
primary_parser_id="arp",
|
||||
|
|
|
|||
|
|
@ -97,7 +97,10 @@ class ArpMultiCommandTests(unittest.TestCase):
|
|||
assert p is not None
|
||||
self.assertEqual(len(p.aux_commands), 1)
|
||||
self.assertEqual(p.aux_commands[0].key, "if_intf")
|
||||
self.assertEqual(p.aux_commands[0].profile_id, "zte.if_intf")
|
||||
self.assertEqual(p.aux_commands[0].profile_id, "zte.config_interface")
|
||||
ii = get_profile("zte.if_intf")
|
||||
assert ii is not None
|
||||
self.assertFalse(ii.enabled)
|
||||
self.assertEqual(get_parser_meta("if_intf")["rule_keys"], ("zte_zxros_show_running_config_if_intf",))
|
||||
|
||||
def test_arp_enriches_vrf_via_aux_records(self) -> None:
|
||||
|
|
@ -110,13 +113,13 @@ class ArpMultiCommandTests(unittest.TestCase):
|
|||
from netx_api.biz_state.profiles import AuxCommand
|
||||
|
||||
if_recs, if_fsm, _ = run_parser(
|
||||
"if_intf",
|
||||
"config_interface",
|
||||
raw_text=IF_INTF_SAMPLE,
|
||||
vendor="zte",
|
||||
device_type="zte_zxros",
|
||||
command="show running-config if-intf",
|
||||
)
|
||||
ra = resolve_aux_command(AuxCommand(key="if_intf", profile_id="zte.if_intf"))
|
||||
ra = resolve_aux_command(AuxCommand(key="if_intf", profile_id="zte.config_interface"))
|
||||
bundle = build_parse_bundle(
|
||||
primary_raw=ARP_MATCHING,
|
||||
primary_parser_id="arp",
|
||||
|
|
|
|||
|
|
@ -233,6 +233,9 @@ class ZteConfigIntentTests(unittest.TestCase):
|
|||
self.assertIsNotNone(hit)
|
||||
assert hit is not None
|
||||
self.assertEqual(hit.profile.profile_id, "zte.config_interface")
|
||||
ii = get_profile("zte.if_intf")
|
||||
assert ii is not None
|
||||
self.assertFalse(ii.enabled)
|
||||
|
||||
def test_config_vrf(self) -> None:
|
||||
rows = normalize_config_vrf(raw_text=_CFG_VRF, command="show running-config vrf")
|
||||
|
|
|
|||
|
|
@ -54,7 +54,12 @@ class ZteStatusParserTests(unittest.TestCase):
|
|||
for mid in ("isis_adjacency", "interface_brief", "arp", "nd6_cache", "bgp_peer", "if_intf"):
|
||||
self.assertIn(mid, metric_field_map())
|
||||
self.assertIsNotNone(get_profile("zte.isis_adjacency"))
|
||||
self.assertIsNotNone(get_profile("zte.if_intf"))
|
||||
ii = get_profile("zte.if_intf")
|
||||
self.assertIsNotNone(ii)
|
||||
assert ii is not None
|
||||
self.assertFalse(ii.enabled)
|
||||
self.assertNotIn("zte.if_intf", zte)
|
||||
self.assertIn("zte.config_interface", zte)
|
||||
|
||||
def test_isis_adjacency(self) -> None:
|
||||
text = _section(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue