feat: publish OBP keepalive connected status in dashboard_state

Expose a boolean connected field on ENHANCED_OBP openbridge entries so the
monitor can show mesh leg health from the same 60s BCKA rule as routing.
pull/49/head
Rodrigo Pérez 3 months ago
parent 2a530c24fd
commit b27c1663c6

@ -57,6 +57,7 @@
"ip": "44.31.61.68",
"port": 62999,
"enhanced_obp": true,
"connected": false,
"streams": {}
}
}

@ -155,7 +155,11 @@
"network_id": { "$ref": "#/$defs/dmr_id" },
"ip": { "type": "string" },
"port": { "type": "integer", "minimum": 0, "maximum": 65535 },
"enhanced_obp": { "type": "boolean" }
"enhanced_obp": { "type": "boolean" },
"connected": {
"type": "boolean",
"description": "ENHANCED_OBP BCKA keepalive OK (peer answered within 60s). Omitted when ENHANCED_OBP is false."
}
}
},
"dashboard_ctable": {

@ -73,8 +73,28 @@ def _upstream_peer_block(name: str, cfg: dict[str, Any]) -> dict[str, Any]:
return block
def _openbridge_block(name: str, cfg: dict[str, Any], topology_row: dict[str, Any] | None) -> dict[str, Any]:
def _obp_ka_connected(cfg: dict[str, Any], now: float) -> bool | None:
"""BCKA keepalive status for ENHANCED OBP legs; ``None`` when KA gating does not apply."""
if not cfg.get("ENHANCED_OBP"):
return None
bcka = cfg.get("_bcka")
if bcka is None:
return False
try:
return float(bcka) >= now - 60
except (TypeError, ValueError):
return False
def _openbridge_block(
name: str,
cfg: dict[str, Any],
topology_row: dict[str, Any] | None,
*,
now: float,
) -> dict[str, Any]:
"""Enabled OPENBRIDGE legs (``CTABLE.OPENBRIDGES``); STREAMS stay empty here (live chips = monitor/voice)."""
del name
block: dict[str, Any] = {"mode": "OPENBRIDGE", "streams": {}}
network_id = cfg.get("NETWORK_ID")
if network_id is not None:
@ -86,6 +106,9 @@ def _openbridge_block(name: str, cfg: dict[str, Any], topology_row: dict[str, An
block["port"] = int(row["port"])
if row.get("enhanced_obp") or cfg.get("ENHANCED_OBP"):
block["enhanced_obp"] = True
connected = _obp_ka_connected(cfg, now)
if connected is not None:
block["connected"] = connected
return block
@ -137,7 +160,7 @@ def build_dashboard_state(
block["port"] = int(topo["port"])
masters[name] = block
elif mode == "OPENBRIDGE":
openbridges[name] = _openbridge_block(name, cfg, topo)
openbridges[name] = _openbridge_block(name, cfg, topo, now=epoch)
elif mode in ("PEER", "XLXPEER") and _upstream_peer_connected(cfg):
peers[name] = _upstream_peer_block(name, cfg)

@ -103,9 +103,71 @@ def test_dashboard_state_includes_enabled_openbridge():
assert obp["mode"] == "OPENBRIDGE"
assert obp["network_id"] == 73010
assert obp["enhanced_obp"] is True
assert obp["connected"] is False
assert obp["streams"] == {}
def test_openbridge_connected_true_when_bcka_fresh() -> None:
now = 1000.0
systems = {
"OBP-CL": {
"MODE": "OPENBRIDGE",
"ENABLED": True,
"NETWORK_ID": 73010,
"ENHANCED_OBP": True,
"_bcka": now - 10,
"PEERS": {},
},
}
state = build_dashboard_state(systems, ts=now)
assert state["ctable"]["OPENBRIDGES"]["OBP-CL"]["connected"] is True
def test_openbridge_connected_false_when_bcka_stale() -> None:
now = 1000.0
systems = {
"OBP-CL": {
"MODE": "OPENBRIDGE",
"ENABLED": True,
"NETWORK_ID": 73010,
"ENHANCED_OBP": True,
"_bcka": now - 61,
"PEERS": {},
},
}
state = build_dashboard_state(systems, ts=now)
assert state["ctable"]["OPENBRIDGES"]["OBP-CL"]["connected"] is False
def test_openbridge_connected_false_when_bcka_missing() -> None:
now = 1000.0
systems = {
"OBP-CL": {
"MODE": "OPENBRIDGE",
"ENABLED": True,
"NETWORK_ID": 73010,
"ENHANCED_OBP": True,
"PEERS": {},
},
}
state = build_dashboard_state(systems, ts=now)
assert state["ctable"]["OPENBRIDGES"]["OBP-CL"]["connected"] is False
def test_openbridge_connected_omitted_without_enhanced_obp() -> None:
systems = {
"OBP-CL": {
"MODE": "OPENBRIDGE",
"ENABLED": True,
"NETWORK_ID": 73010,
"PEERS": {},
},
}
state = build_dashboard_state(systems)
obp = state["ctable"]["OPENBRIDGES"]["OBP-CL"]
assert "connected" not in obp
def test_dashboard_state_includes_connected_upstream_peer():
systems = {
"XLX-730": {

Loading…
Cancel
Save

Powered by TurnKey Linux.