onu: info/stats sub-tab with CPE lease health + OUI vendor
Adds an ONU info page and splits the ONU tab into two sub-tabs (Info / stats, Fleet & upgrade). The ONU tab now lands on Info; campaign/verify keep the Fleet sub-tab lit. ONU info page (#view-onu-info): master-detail over the already-loaded fleet (search + status filter, no new bulk fetch). Per-ONU detail shows identity, link/optical + FEC (read from the merged ONU-STATE), firmware, and a CPE card. CPE (customer router): - McmsClient.getCpe — GET /api/cpe/onu/<id>/ (unversioned, [status,doc] tuple). - src/cpe.js (pure, shared): summarizeCpe + leaseHealth. Renewal rule — <50% of the lease remaining => "renewal overdue" (amber), past end => expired. v4 expiry = DHCP "Remove Time"; v6 spans Last Success -> Preferred Lifetime (T1 midpoint), with Prefix Delegation surfaced. - api:getOnuCpe (main.js + web/server.js, exposed in both bridges). OUI vendor (src/oui.js, pure, shared): lazy fetch of the IEEE oui.csv, prefix->org map, cached in memory ~30 days + best-effort to disk (PFW_CACHE_DIR / temp; PrivateTmp makes /tmp writable). Resolved server-side in getOnuCpe; every failure degrades to "unknown OUI". CPE itself is not TTL-cached (lease must be live); only the OUI list is. Dashboard abnormal Rx/Tx rows are now clickable -> deep-link to that ONU's info page (showListModal gained per-item onClick). Docs: CLAUDE.md §17 + IPC table + intro; README. Verified: node --check; cpe.js/oui.js unit-tested (15/15: lease ok/warn/ expired/unknown + 50% boundary, v6 prefix parse, OUI quoted-CSV parse + lookup); ONU info page + CPE card rendered offscreen over HTTP. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
5e3d9271a8
commit
55e95ed467
12 changed files with 677 additions and 7 deletions
53
CLAUDE.md
53
CLAUDE.md
|
|
@ -16,8 +16,9 @@ Electron desktop client for operating a **Ciena MCMS 6.2** PON Manager
|
|||
fleet. Top-level **tabs** (Dashboard / ONU / OLT) switch between:
|
||||
|
||||
- **Dashboard** — read-only network telemetry (see §15).
|
||||
- **ONU** — the fleet table + firmware-upgrade campaign + verify flows
|
||||
(the original purpose: bulk ONU firmware upgrades).
|
||||
- **ONU** — two sub-tabs: an **Info / stats** page (per-ONU optical/FEC plus
|
||||
the CPE router's DHCPv4/v6 lease health, §17) and the **Fleet & upgrade**
|
||||
flow (the original purpose: bulk ONU firmware upgrades + verify).
|
||||
- **OLT** — bulk OLT NNI-service edits: PON flooding mode (private↔auto) and
|
||||
DHCPv4/v6 filter (pass↔umt), see §14.
|
||||
|
||||
|
|
@ -118,6 +119,7 @@ stream progress events back to the renderer.
|
|||
| `api:listFleet` | ONU-CFG + ONU-STATE + OLT-STATE merged | — |
|
||||
| `api:fetchStates` | per-ONU state fallback if bulk failed | `states:progress` |
|
||||
| `api:listOnuConfigs` / `api:getOnuConfig` | direct CFG access | — |
|
||||
| `api:getOnuCpe` | CPE (router) DHCP lease health + OUI vendor | — |
|
||||
| `api:listOnuFirmware` / `api:uploadFirmware` | firmware inventory | — |
|
||||
| `api:planUpgrade` | dry-run plan for selected ONUs | — |
|
||||
| `api:executePerOnu` | Procedure 7 — per-ONU PUTs | `upgrade:progress` |
|
||||
|
|
@ -830,4 +832,51 @@ gitignored) which pulls `tough-cookie` and skips the Electron devDep.
|
|||
|
||||
---
|
||||
|
||||
## 17. ONU info / stats page (CPE + OUI)
|
||||
|
||||
The **ONU** top tab has two sub-tabs (`.subtab` buttons in each ONU view's
|
||||
panel-left; `showView` lights the right one — see §15): **Info / stats** and
|
||||
**Fleet & upgrade** (the original fleet/campaign/verify flow). The ONU tab
|
||||
now lands on Info; campaign/verify keep the Fleet sub-tab lit.
|
||||
|
||||
### Info page (`#view-onu-info`)
|
||||
|
||||
Master-detail over the already-loaded `state.fleet` (no new bulk fetch):
|
||||
search (name/address/serial) + status filter on the left; clicking an ONU
|
||||
renders identity, link/optical (read straight from the merged `_state.STATS`
|
||||
via `onuClientStats` — no extra round-trip), firmware, and a **CPE card**.
|
||||
Dashboard abnormal-Rx/Tx drill-downs (§15) deep-link here via `openOnuInfo`.
|
||||
|
||||
### CPE (customer router)
|
||||
|
||||
`api:getOnuCpe` → `McmsClient.getCpe` (`GET /api/cpe/onu/<id>/` — unversioned,
|
||||
returns a `[statusCode, doc]` tuple) → `summarizeCpe` (`src/cpe.js`, pure,
|
||||
shared). The lease-health rule (`leaseHealth`): a DHCP client renews at T1 =
|
||||
50% of the lease, so **< 50% remaining ⇒ renewal overdue** (amber), past end
|
||||
⇒ expired (red). Field mapping confirmed from a real CPE doc:
|
||||
|
||||
- **DHCPv4**: expiry = `DHCP["Remove Time"]` (= `Last Success Time` +
|
||||
`Lease Time`); health spans `Last Success Time` → `Remove Time`.
|
||||
- **DHCPv6**: `DHCPV6` carries `T1/T2/Preferred/Valid Lifetime` + nested
|
||||
`Prefix Delegation[].Prefixes[]`. Health spans `Last Success Time` →
|
||||
`Preferred Lifetime` (T1 is the midpoint), so the same < 50% rule fires
|
||||
once now passes T1.
|
||||
|
||||
### OUI vendor (`src/oui.js`)
|
||||
|
||||
The CPE MAC (`_id` / `Client MAC`) resolves to a vendor via the IEEE registry
|
||||
(`oui.csv`), fetched lazily on first lookup, parsed to a prefix→org map,
|
||||
cached **in memory ~30 days + best-effort to disk** (`PFW_CACHE_DIR` or the
|
||||
temp dir; the web server's `PrivateTmp` makes `/tmp` writable). Every failure
|
||||
path returns `null` → "unknown OUI"; a missing list never breaks the page.
|
||||
The lookup runs server-side in `getOnuCpe` so the renderer gets a vendor
|
||||
string. Needs outbound HTTPS from whoever runs the backend (override the URL
|
||||
with `PFW_OUI_URL`). The ONU `GNXS…` id is a serial, **not** a MAC — OUI only
|
||||
applies to the CPE/OLT MACs.
|
||||
|
||||
CPE is **not** cached by the web server's TTL cache (lease status must be
|
||||
live); only the OUI list is cached.
|
||||
|
||||
---
|
||||
|
||||
*Last updated: 2026-06-23.*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue