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>
158 lines
6.4 KiB
Markdown
158 lines
6.4 KiB
Markdown
# PON Fleet Upgrader
|
|
|
|
An Electron desktop app for operating a **Ciena MicroClimate Management
|
|
System (MCMS) 6.2** PON Manager. Top tabs split it into:
|
|
|
|
1. **Dashboard** — read-only network telemetry: ONU/OLT/controller counts,
|
|
aggregate up/down traffic, health (abnormal Rx, lasers off), and ONU
|
|
registration-state breakdown (with an opt-in per-ONU Rx/FEC scan).
|
|
Clicking a state jumps to the ONU tab pre-filtered.
|
|
2. **ONU** — two sub-tabs: an **Info / stats** page (per-ONU optical/FEC plus
|
|
the CPE router's DHCPv4/v6 lease status, with a warning when a lease is
|
|
past its renew point) and **Fleet & upgrade** (**bulk ONU firmware
|
|
upgrades**, below).
|
|
3. **OLT** — **bulk OLT NNI-service edits**: PON flooding mode (private↔auto)
|
|
and DHCPv4/v6 filter (pass↔umt) — see "OLT NNI-service edits" below.
|
|
|
|
## ONU firmware upgrades
|
|
|
|
Filters a fleet of ONUs, previews the planned writes, and stages new
|
|
firmware to each device's **inactive bank** so the forced reboot is
|
|
deferred until the next natural restart window.
|
|
|
|
Two execution modes:
|
|
|
|
- **Bulk task (Procedure 8, recommended)** — creates a single
|
|
`AUTO-TASK-CFG` via `PUT /v3/tasks/configs/<id>/`. MCMS owns the rollout
|
|
(retries, pacing, scheduled start).
|
|
- **Per-ONU PUT (Procedure 7)** — iterates the selected ONUs, fetches each
|
|
`ONU-CFG`, mutates `FW Bank {Ptr,Files,Versions}`, and `PUT`s the full
|
|
document back. Slower, but you see errors live per device.
|
|
|
|
## Prerequisites
|
|
|
|
- Node.js 18+ and npm
|
|
- Network reachability to your MCMS host
|
|
- An MCMS user with ONU write + Files write permissions
|
|
- A compatible ONU firmware `.bin` file (already uploaded via this tool
|
|
or the vendor UI into `/files/onu-firmware/`)
|
|
|
|
## Install & run
|
|
|
|
```bash
|
|
cd pon-fleet-upgrader
|
|
npm install
|
|
npm start
|
|
```
|
|
|
|
This launches an Electron window. Use `npm run check` to syntax-check all
|
|
source files without launching the app.
|
|
|
|
## Bank strategy
|
|
|
|
MCMS stores firmware in two slots per ONU (`FW Bank Files[0/1]`,
|
|
`FW Bank Versions[0/1]`) with `FW Bank Ptr` pointing at the active one.
|
|
|
|
| Current `FW Bank Ptr` | Tool writes to slot | Why |
|
|
|-----------------------|---------------------|-----|
|
|
| `0` | `1` | Don't overwrite active image |
|
|
| `1` | `0` | Don't overwrite active image |
|
|
| `65535` (unset) | `1` | Matches Procedure 7 example; slot 0 stays as factory fallback |
|
|
|
|
The tool computes this per ONU and buckets the selection by target slot
|
|
when submitting a bulk task (MCMS's `AUTO-TASK-CFG.Task Details.ONU.FW
|
|
Bank Ptr` accepts a single slot number, so each bucket becomes one task).
|
|
|
|
## Safety notes
|
|
|
|
- **Always validate on one ONU first.** Select a single device, run in
|
|
per-ONU mode, confirm the ONU recovers on slot N before using bulk
|
|
task on the rest of the fleet.
|
|
- **Don't blank the active slot.** The planner preserves both slots'
|
|
existing `Files`/`Versions` and only writes the target slot.
|
|
- **Scheduled start is UTC.** The datetime-local picker converts from
|
|
your local timezone to UTC before submitting the `AUTO-TASK-CFG`.
|
|
- **Leave the session short.** Log out when done — MCMS sessions don't
|
|
auto-expire and a stale cookie on a shared workstation is an
|
|
unnecessary exposure.
|
|
|
|
## Filters
|
|
|
|
The left panel supports:
|
|
|
|
- **Name / address contains** — substring match over
|
|
`ONU.Name`, `ONU.Address`, and `_id`
|
|
- **PON mode** — server-side Mongo filter on `ONU.PON Mode`
|
|
- **Active version matches** — substring match on the version string in
|
|
whichever slot `FW Bank Ptr` points to
|
|
- **Model / version family** — substring match across *both* slots'
|
|
version strings, useful for fleet cuts like `EV051` (all Everest 5.1x)
|
|
|
|
The server-side projection is narrow (serial, name/address, PON mode, bank
|
|
state). The full ONU-CFG is only re-fetched at plan time.
|
|
|
|
## Files
|
|
|
|
```
|
|
pon-fleet-upgrader/
|
|
├── package.json
|
|
├── main.js # Electron main process, IPC handlers
|
|
├── preload.js # contextBridge exposing window.api.*
|
|
├── src/
|
|
│ ├── mcms-api.js # HTTPS client with tough-cookie jar + CSRF
|
|
│ └── bank-strategy.js # inactive-bank selection + plan computation
|
|
└── renderer/
|
|
├── index.html # Login / fleet / campaign views
|
|
├── app.css
|
|
└── app.js # UI logic
|
|
```
|
|
|
|
## OLT NNI-service edits
|
|
|
|
From the fleet view, **Open OLT inspector…** opens a second workflow for
|
|
bulk-checking and editing OLT NNI services. Two independent edits can be
|
|
applied together to every matching service:
|
|
|
|
**Flooding mode** — encoded by the presence of a single key on each
|
|
`OLT-CFG["NNI Networks"]` entry:
|
|
|
|
| Mode | `PON FLOOD ID` key | Change |
|
|
|------|--------------------|--------|
|
|
| **private** | present (any value, incl. `0`) | → auto: delete the key |
|
|
| **auto** | absent | → private: set the key to `0` |
|
|
|
|
**DHCP filter mode** — values nested under each entry's `Filter` object
|
|
(`DHCPv4` / `DHCPv6`), e.g. `pass` ↔ `umt`. Only entries that already have
|
|
the field are touched (the field is never invented); `EAPOL`/`PPPoE`/`NDP`
|
|
are left alone.
|
|
|
|
Workflow: enter a **TAG MATCH** pattern (exact like `s0.c76.c0`, or a `*`
|
|
glob like `s0.c76.*`), **Load OLTs**, pick any of the three actions
|
|
(Flooding / DHCPv4 / DHCPv6), select the OLTs — each matching service shows
|
|
"→ will change (…)" for the edits that apply — then **Execute changes…**
|
|
(two-step confirm). Each OLT is re-fetched, the matching NNI entries are
|
|
edited in one pass, and the full OLT-CFG is PUT back. A result CSV is
|
|
auto-saved to `~/Downloads/pon-olt-nni-*.csv`.
|
|
|
|
All directions are supported (e.g. `umt → pass`), so changes roll back from
|
|
the same screen. Defaults: `s0.c76.c0`, flood `private → auto`, DHCPv4/v6
|
|
`pass → umt`.
|
|
|
|
## Known limitations
|
|
|
|
- The `/v1/onus/<id>/upgrade/status/` path used by the original question
|
|
isn't part of the dev-guide-documented surface; if your MCMS returns
|
|
404 for it, fall back to polling `GET /v1/onus/configs/<id>/` and
|
|
watching `FW Bank Versions` + `FW Bank Ptr` change.
|
|
- Progress of a bulk task is reported back by MCMS in its own task
|
|
status collection — the tool currently submits and then leaves
|
|
monitoring to the PON Manager UI. Follow-up work: poll
|
|
`/v3/tasks/states/<taskId>/`.
|
|
- No offline mode / cached fleet snapshot. Each `Load fleet` hits the
|
|
API.
|
|
- PATCH endpoints aren't used — MCMS requires full-document PUTs for
|
|
`ONU-CFG` updates (the dev guide is explicit about this).
|
|
|
|
## License
|
|
|
|
Internal use only.
|