Split L2VPN service instance into type (VPLS/VPWS) and name fields.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-09-20 19:26:31 +08:00
parent 3414137daa
commit ed11f5a60c
3 changed files with 23 additions and 2 deletions

View file

@ -12,6 +12,7 @@ from ..common.pipeline import prefer_fsm
RULE_KEYS = ("zte_zxros_show_l2vpn_forwardinfo_detail",)
_SERVICE_RE = re.compile(r"^Service type and instance name:\[([^\]]+)\]\s*$", re.I)
_SERVICE_SPLIT_RE = re.compile(r"^(VPLS|VPWS)\s+(.+)$", re.I)
# Two-column "Label : value Label : value" or single "Label : value"
_KV_PAIR_RE = re.compile(
r"([A-Za-z][A-Za-z0-9 /|_.-]*)\s*:\s*"
@ -78,12 +79,25 @@ def _empty() -> dict[str, str]:
}
def _split_service(raw: str) -> tuple[str, str]:
"""Split ``VPLS foo`` / ``VPWS bar`` into (type, instance name)."""
text = str(raw or "").strip()
if not text:
return "", ""
m = _SERVICE_SPLIT_RE.match(text)
if m:
return m.group(1).upper(), m.group(2).strip()
return "", text
def _row_out(cur: dict[str, str]) -> dict[str, Any] | None:
pw = str(cur.get("pw_name") or "").strip()
if not pw:
return None
svc_type, svc_name = _split_service(str(cur.get("service_instance") or ""))
return {
"service_instance": str(cur.get("service_instance") or "")[:256],
"service_instance_type": svc_type[:32],
"service_instance": svc_name[:256],
"pw_name": pw[:128],
"peer": str(cur.get("peer") or "")[:64],
"vcid": str(cur.get("vcid") or "")[:64],

View file

@ -382,6 +382,7 @@ _L2VPN_PW_DETAIL_FIELDS: list[FieldDef] = [
FieldDef("vc_status", length=32, role="state", display_name="VC Status"),
FieldDef("remote_status", length=32, role="state", display_name="Remote"),
FieldDef("activation_status", length=32, role="state", display_name="Activation"),
FieldDef("service_instance_type", length=32, role="meta", display_name="Service Type"),
FieldDef("service_instance", length=256, role="meta", display_name="Service"),
FieldDef("conn_mode", length=32, role="meta", display_name="Mode"),
FieldDef("signaling", length=32, role="meta", display_name="Signaling"),

View file

@ -341,7 +341,10 @@ class ZteExtendedParserTests(unittest.TestCase):
self.assertEqual(by["pw19001"]["remote_status"], "ALLOK")
self.assertEqual(by["pw19001"]["vcid"], "19001")
self.assertEqual(by["pw19001"]["peer"], "10.0.0.6")
self.assertIn("demo-vpls-1", by["pw19001"]["service_instance"])
self.assertEqual(by["pw19001"]["service_instance_type"], "VPLS")
self.assertEqual(by["pw19001"]["service_instance"], "qualified demo-vpls-1")
self.assertEqual(by["pw19011"]["service_instance_type"], "VPLS")
self.assertEqual(by["pw19011"]["service_instance"], "demo-vpls-2")
self.assertEqual(by["pw19011"]["vc_status"].upper(), "DOWN")
self.assertEqual(by["pw19011"]["vccv_cv"], "LSP|BFD_BASIC_HEAD")
@ -377,7 +380,10 @@ class ZteExtendedParserTests(unittest.TestCase):
)
self.assertEqual(len(rows), 6)
self.assertTrue(all(r["vc_status"].upper() == "UP" for r in rows))
self.assertTrue(all(r["service_instance_type"] == "VPLS" for r in rows))
self.assertEqual(rows[0]["pw_name"], "pw19001")
self.assertEqual(rows[0]["service_instance"], "qualified mxy-martini-vpls-1")
self.assertEqual(rows[2]["service_instance"], "VPLS_4202")
self.assertEqual(rows[-1]["pw_name"], "pw1230002")
def test_profiles_and_expand(self) -> None: