Show aux commands in biz-state UI; keep only config_vrf under BGP VRF summary.

Add an Aux column for each monitor item. Drop ip_route/ipv6_route as summary enrich aux so FIB stays a standalone collect profile. Export defaults to primary commands only.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-09-22 11:39:44 +08:00
parent 67930bb348
commit 089c88d35e
9 changed files with 116 additions and 29 deletions

View file

@ -807,7 +807,7 @@ def _zte_status_profiles() -> list[ParseProfile]:
textfsm_command="show bgp vpnv4 unicast summary",
description=(
"Per-VRF BGP VPNv4 peer summary. Bind one or more VRFs; "
"aux: IPv4 FIB + config_vrf."
"aux: config_vrf (RD/AF enrich). IPv4 FIB is a separate monitor item."
),
placeholders=[_VRF_PLACEHOLDER_IPV4],
fields=list(_BGP_PEER_FIELDS),
@ -817,7 +817,6 @@ def _zte_status_profiles() -> list[ParseProfile]:
kind="collect",
aux_commands=[
AuxCommand(key="config_vrf", profile_id="zte.config_vrf"),
AuxCommand(key="ip_route", profile_id="zte.ip_route_vrf"),
],
enrich_joins=[
EnrichJoin(
@ -839,7 +838,7 @@ def _zte_status_profiles() -> list[ParseProfile]:
textfsm_command="show bgp vpnv6 unicast summary",
description=(
"Per-VRF BGP VPNv6 peer summary. Bind one or more VRFs; "
"aux: IPv6 FIB + config_vrf."
"aux: config_vrf (RD/AF enrich). IPv6 FIB is a separate monitor item."
),
placeholders=[_VRF_PLACEHOLDER_IPV6],
fields=list(_BGP_PEER_FIELDS),
@ -849,7 +848,6 @@ def _zte_status_profiles() -> list[ParseProfile]:
kind="collect",
aux_commands=[
AuxCommand(key="config_vrf", profile_id="zte.config_vrf"),
AuxCommand(key="ipv6_route", profile_id="zte.ipv6_route_vrf"),
],
enrich_joins=[
EnrichJoin(
@ -1548,6 +1546,17 @@ def metric_field_map() -> dict[str, list[FieldDef]]:
def profile_to_public_dict(p: ParseProfile, *, overrides: dict[str, Any] | None = None) -> dict[str, Any]:
ov = overrides or {}
aux_out: list[dict[str, Any]] = []
for a in p.aux_commands or []:
ap = get_profile(a.profile_id)
aux_out.append(
{
"key": a.key,
"profile_id": a.profile_id,
"title": (ap.title if ap else "") or a.profile_id,
"command_template": (ap.command_template if ap else "") or "",
}
)
return {
"profile_id": p.profile_id,
"vendor_key": p.vendor_key,
@ -1591,13 +1600,7 @@ def profile_to_public_dict(p: ParseProfile, *, overrides: dict[str, Any] | None
"kind": p.kind,
"match": p.match,
"textfsm_command": p.textfsm_command or p.command_template,
"aux_commands": [
{
"key": a.key,
"profile_id": a.profile_id,
}
for a in (p.aux_commands or [])
],
"aux_commands": aux_out,
"enrich_joins": [
{
"from_aux": j.from_aux,

View file

@ -1034,12 +1034,13 @@ def plan_task_collect_commands(
task_id: str,
*,
enabled_only: bool = True,
include_aux: bool = True,
include_aux: bool = False,
) -> dict[str, Any]:
"""Plan concrete collect CLIs for a task (no device login).
expand_all items (unbound optional discover) are listed with a note; aux
commands are resolved from primary params when include_aux is True.
By default only each monitoring item's primary command is listed.
Aux CLIs (parser enrich helpers such as FIB/config under BGP summary)
are omitted unless include_aux=True — they are not separate UI items.
"""
task = db.get(BizStateTask, task_id)
if not task:
@ -1223,7 +1224,7 @@ def export_task_commands_text(
task_id: str,
*,
enabled_only: bool = True,
include_aux: bool = True,
include_aux: bool = False,
) -> str:
"""Plain-text export of planned collect commands (one CLI per line + section headers)."""
plan = plan_task_collect_commands(

View file

@ -177,7 +177,7 @@ def api_get_task(task_id: str, db: Session = Depends(get_db)) -> dict[str, Any]:
def api_plan_task_commands(
task_id: str,
enabled_only: bool = Query(True),
include_aux: bool = Query(True),
include_aux: bool = Query(False),
db: Session = Depends(get_db),
) -> dict[str, Any]:
"""List planned collect CLIs for a task (bindings expanded; no device login)."""
@ -190,7 +190,7 @@ def api_plan_task_commands(
def api_export_task_commands(
task_id: str,
enabled_only: bool = Query(True),
include_aux: bool = Query(True),
include_aux: bool = Query(False),
db: Session = Depends(get_db),
) -> StreamingResponse:
"""Download planned collect commands as a .txt file."""