Dashboard Modules¶
The sidebar groups the modules by domain: Overview; 5G Network (Core, RAN,
Subscribers, UE Monitor); Network (Topology, Isolation, Health, Capture); Platform
(Kubernetes, Services, Metrics, Operations); then Settings and the Manual. The
header shows where you are and what holds for the whole dashboard. This page describes
what each module does, the data it shows, and the actions it provides. Role gating
follows the two-tier model: read views are open to dashboard-viewer, write and
exec actions require dashboard-admin. See security/iam.md
for the per-route matrix.
See Dashboard Overview for architecture and access details.
Overview¶
Area: Cluster
The landing view. Cluster-wide status at a glance.
- Stat cards: total pods, running, pending, failed, average CPU, average memory
- CPU and memory sparklines (15-minute trend)
- Node cards with status and resource usage
- Network Function status cards; selecting one opens its detail in the 5G Core module
- Exposure stack and Edge apps cards (shown only when those layers are deployed), same idiom; selecting one opens Services or Edge apps
Read-only.
Kubernetes¶
Area: Cluster
Raw Kubernetes resource browser, namespace-scoped.
- Five tabs: Namespaces, Nodes, Storage, Services, Events
- Namespace filter on the Storage, Services, and Events tabs
- Tables: namespace phase and labels; node roles, taints, kubelet version; PVCs; Services with ports and selectors; recent Events
- Manual refresh plus auto-refresh every 15 seconds
Read-only.
5G Core¶
Area: 5G
Per-NF view of the Open5GS core, grouped into Control Plane, User Plane, Data, and Other.
- NF cards with phase, restart count, and node placement; expandable for detail
- AMF CNI alert banner with a "Manage" action to scale the AMF controllers (repair path for the CNI/replicaset issue)
- "Check updates" compares deployed image tags against a version manifest
Admin actions: restart an NF deployment, scale the AMF controller, trigger a streamed NF image update.
Topology¶
Area: Network · /network/topology
Visual map of the running system.
- Two tabs: Logical (NFs, interfaces, NADs, live traffic) and Infrastructure (cluster nodes)
- Interface and NetworkAttachmentDefinition metadata
- Live traffic indicator driven by a WebSocket stream
Read-only.
RAN¶
Area: 5G
Whether the physical gNB reaches the core, where the path breaks, and what fixes it. Admin only.
- Path: five links read by the backend, in order: cable (the worker's RAN
interface and its carrier), bridge (the interface on
br-ran), core (the gNB's NG Setup with the AMF), user plane, UEs. Each link is ok, broken, idle, or blocked by an earlier broken link, and a broken link carries its fix: a piece (for exampleran_link, "Bring the RAN link up"), a CLI command, or a checklist. The page follows a started fix until its read-back. Every action is a piece and leaves a record on the Operations page. - Attach and detach: Detach (
ran_detach) sits at the card's foot while the RAN is attached, and asks fordetachto be typed before it runs. Detached (PHYSICAL_RAN_ENABLED=false), the page reads Detached and the bridge link offers Attach (ran_attach). The worker keeps its RAN adapter either way. - gNB: address, NG Setup, the AMF address and NGAP port (read from the
running AMF), UE and PDU session counts, and the link to the gNB's own web
console, which is where the gNB itself is monitored and configured. Drawers
hold the console address (published at
kelt-gnb.<base>as an external endpoint behind the front-door perimeter plus the appliance login) and the settings to enter on the gNB's RAN interface. - Simulated RAN (UERANSIM): not supported yet from this page.
The page polls every 10 s and has no manual refresh. See Physical RAN Integration.
Subscribers¶
Area: 5G
CRUD for Open5GS subscriber records in MongoDB.
- Expandable list by IMSI, with slice and session detail (SST, SD, APN, QCI, AMBR)
- Subscriber form: IMSI, K, OP/OPc, AMF, aggregate AMBR, default slice
- Import from JSON, and "Initialize from playbook" to reset to the default subscriber set (phase 5 import)
Admin actions: create, edit, delete, import, initialize.
UE Monitor¶
Area: 5G
Live view of registered UEs and RAN activity.
- Summary cards: connected gNBs, RAN UEs, active sessions, registered subscribers
- Registration counters over a selectable window (1m to 6h), with auth-reject context
- gNB table (id, PLMN, SCTP peer, UE count) and active UE table with per-IMSI nickname and icon personalization
- Event feed (registration, session, attach, detach, errors) with expandable cause and debug guidance
- Connectivity tests (ping, iperf3) from a selected UERANSIM pod
Admin actions: run ping or iperf3, edit UE personalization. UE session data comes from a native Open5GS endpoint.
Isolation¶
Area: Network · /network/isolation
What may talk to what, and what was stopped. Read-only, open to viewers; the rules change in the playbooks, which the page names.
- 5G planes: a from/to matrix of the plane bridges on the worker. Allowed crossings (RAN to N2 and N3, N6c to the internet) show their packets over the last 24 h; blocked ones show the packets dropped, counted per ordered pair. Selecting a cell shows its filter rule. Beside it: drops from outside the planes and the latest packets the filter logged, with interfaces, addresses, protocol and rule.
- Pod network: one row per namespace phase 13 isolates, with what it holds, who may enter which app, and whether its outbound traffic is limited; expanding a row lists the destinations and the policy names.
- Check a flow: pick a source namespace (or the management network, or a node) and a destination Service or the internet; the backend evaluates the live policies and answers with the verdict and the policy behind each step. Nothing is sent.
The Overview has an Isolation card and the sidebar shows the blocked count when it
is above zero (one shared poll a minute feeds both). API: GET /api/v1/isolation/planes, /planes/samples, /policies,
/targets, POST /api/v1/isolation/check.
Health¶
Area: Network · /network/health
Per-interface health of the planes (N2, N3, N4, N6c): latency, live PPS and throughput, on-demand in-pod probes, and an animated data-path diagram driven by OVS counter deltas. Viewers may run the checks (they only probe).
Capture¶
Area: Network · /network/capture · admin only
Live packet capture on a chosen interface. It runs a privileged pod, so the page and its router are admin-only.
Metrics¶
Area: Cluster
Resource metrics from Prometheus, with a Nodes tab and an NFs tab.
- Nodes: per-node CPU, memory, disk cards plus CPU and memory history charts
- NFs: per-NF CPU (millicores) and memory (MB) bars plus a CPU trend chart
- Range selector: 15m, 30m, 1h, 6h, 24h
Read-only. "Open in Grafana" in the page's toolbar opens the full Grafana stack, for what these charts do not show: Explore, the Loki logs, long ranges. It is the only link to Grafana in the dashboard.
Operations¶
Area: Platform · admin only
The 50 newest piece runs, from the dashboard and from kelt run-piece: when
it started, what it was, who started it and from where, the piece, the result and
how long it took. Filters: all, running, failed (a failed read-back counts as
failed). A row opens the run's steps (without Ansible's fact gathering) and its
read-back; the tail of the Ansible output is one click away, and open by itself
when the run failed. /operations#<id> opens that run. The header's Operations button links here.
Results: running; done (the read-back passed, or the piece has none); exited 0, not read back yet (the read-back runs when the run is opened); done, not read back (opened more than 10 minutes after the run ended); failed (including a failed read-back); interrupted (the runner stopped before the end). The record is kept as set in Settings → Operations record.
Northbound¶
Area: Positioning / CAMARA
Service-management console for the northbound positioning stack. Read views are
open to dashboard-viewer; all write controls require dashboard-admin.
- Services: inventory of the camara/positioning/mec deployments (image, ready replicas, pod phases). Each service with a contract offers info (what it reads and who provides it) and, for admins, Configure. Every service also offers a plain restart (rolls the pod, config and image unchanged), the same generic action the 5G Core page offers per NF
- Configure (per service): reads the service's own
/contractand shows only the settings the operator owns, grouped as Connection (required or secret), Field mapping / Documents (a file the dashboard can own), Options. Controls follow the contracttype(switch for boolean, number, password for secret). Apply writes<name>-config/<name>-secretsby the contractsensitiveflag and rolls the deployment. Deployment wiring (fromall.yml), KELT's own registration env and storage paths are not offered: they are read in info.ADAPTER_CAPABILITIES(the bound source's traits, contracttype: json) is a guided editor pre-filled from the registry and the schema; accuracy classes come from the gateway's published vocabulary. The transport the adapter uses to reach its source is stated from the contract, not chosen. A service that exposes no contract degrades to a read-only notice. Sensitive current values are never shown, only set/unset. See "Who owns a service's env" in architecture/positioning-adapters.md - Adapter registry: the live registry read from the engine (
GET /adapters), showing each adapter's kind,registeredVia, last-seen, and derived state (live / unreachable / stale). Adapters self-register; admins can force-remove a stale entry. No manual name+URL registration - Deploy adapter from image: pin an
image:tag, port, optionalkind, env vars (secret-marked vars go into a Secret), optionalimagePullSecret; the backend creates the Deployment + ClusterIP Service and injects the self-registration env so the adapter announces itself to the engine. The catalog separates a singleton source (wifi-adapter, deployed at most once) from the genericvendor-adapter, a per-vendor template instantiated once per vendor (name it after the vendor, point it at the vendor API via env). Gated by the backendallow_workload_createsetting on top of admin. - Asset Identity Map: CRUD over the gateway
GET/PUT /assets(Discover devices onboarding). Since engine0.8.19the live broadcast is derived from the adapters'devicescapability, so an onboarded asset goes live as soon as its adapter reports it - no track-list sync needed; see architecture/positioning-adapters.md - Update all: re-runs phase 10 to the images pinned in
all.ymland upgrades the catalog adapters that are behind (no manual image rollout: the pin is the intent) - Adapter contract: the
Measurementschema, a Python adapter skeleton, anenv.contract.yamltemplate, and links to the upstream5g-northbounddocs
See architecture/positioning-adapters.md.
Edge apps¶
Area: Services hub → Edge apps
Console for operator-deployed application pods (phase 12). Reached from the
Services hub. Read views are open to dashboard-viewer; deploy/delete require
dashboard-admin plus the backend allow_workload_create gate.
- Deployed apps: name, image, ready replicas, the public link (
kelt-<name>.<base>) for exposed apps, and an n6m badge for MEC-attached apps. A logs button streams the app pod's logs live (same viewer as the 5G core and Northbound services). Admins can delete an app, or switch it to another pushed tag from a date-ordered version picker; an "update available" hint appears when the registry holds a newer image for the tag - Deploy from image: a registry image (
<host>/name:tag), port, replicas, env vars (secret-marked go into a Secret), optionalimagePullSecret, an expose toggle, and an attach to MEC network (n6m) toggle (optional fixed IP + extra UDP ingest ports) so UEs reach the app over the 5G user plane. The backend creates a worker-pinned Deployment and, when exposed, a port-80 Service the front-door reaches atkelt-<name>.<base> - Starter kit: admins download a zip (README +
.env.example+deploy.sh, prefilled with the registry host) to hand to an app developer
The image must be pushed to the in-cluster local registry first. See architecture/edge-apps.md.
IAM¶
Area: Settings → Identity & Access · admin only
A static reference for the identity model. No write actions; realm changes happen in the Keycloak console.
- Realm info: name, issuer, current user and roles
- Role matrix:
dashboard-admin,dashboard-viewer,camara-location-read, with abilities and restrictions - Seed users (phase 08) and OIDC clients (dashboard, positioning-demo, camara-gateway, dashboard-readonly)
- Links to the Keycloak realm and master admin consoles; M2M
client_credentialscurl snippets are shown to admins only
See security/iam.md for the full role matrix.
Storage¶
Area: Settings → Storage
Disk state for the worker node, and the actions that reclaim space.
The page leads with a breakdown rather than a percentage, because the intuitive culprit is usually the wrong one: nearly all of a node's disk is extracted container image layers, while the in-cluster registry (the thing an operator tends to blame) holds a fraction of that. Each consumer is listed separately, with the registry called out as a subset of the volumes so the relative size is visible, and persistent volumes broken down per claim.
Sizes come from walking the filesystem, so they are measured on request and cached rather than polled. The filesystem totals are always live.
Reclaim actions, in the order they appear (most effective first):
| Action | Frees | Notes |
|---|---|---|
| Prune unused images | GB | Removes image layers no container references |
| Vacuum journals | MB to GB | Trims systemd logs to the cap phase 01 configures |
| Registry garbage collect | MB | Unreferenced blobs; offers a dry run first |
Each action shows what it would free before it is run, and is disabled when the answer is nothing, so no button is a blind click. Those figures are estimates (shared image layers are counted once per image); the amount actually freed is measured from the filesystem after the action and reported back.
Reading is open to dashboard-viewer; every action requires dashboard-admin
and an explicit confirmation. See api-reference.md for the
endpoints and ../security/iam.md for the role matrix.
Operations record¶
Area: Settings → Operations record · admin only
What the record of piece runs holds (runs, size on disk, oldest run) and how long
it is kept: a number of days (1 to 3650, default 30) and a total size in MB (1 to
10240, default 50), whichever is reached first. A running operation is never
deleted. The values are stored in .testbed.env (KELT_OPS_MAX_AGE_DAYS,
KELT_OPS_MAX_MB) and apply at the next run.
Header¶
Area: Infrastructure visibility
A 48 px bar above every page. Left, the breadcrumb: a top-level page shows its sidebar group as plain text (groups have no page), a sub-page shows its parents as links (Services / Northbound / Assets). Right, in order:
- Status: one pill for the whole testbed, from
GET /api/v1/status/summary, polled every 30 s. Green "All systems up", or amber/red with the number of problems; a click lists them, with a button to Health. Sources: the Kubernetes API itself, nodes not Ready, 5G pods Failed, Pending, not ready or stuck (CrashLoopBackOff, image pull errors), the last network check run if younger than 10 minutes, with its age (the pill never starts one; Health does), the AMF CNI alert. Hidden, with the breadcrumb, until there is a session. - Operations (admin): how many pieces are running, with the loader while one is. A click lists at most three running operations and the last result, and links to the Operations page.
- Updates (admin): shown only while a dashboard component has an update available; opens the update section of the Manual.
- Environment: DEV or PROD, the frontend source in its tooltip.
- Cluster clock and the time sync popover (below).
- Account menu: user, what the role allows, tenant scope; the frontend source; the switch that starts the dev frontend (admin, on prod); log out.
Cluster clock and time sync¶
Live clock:
- Displays current time in the user's local timezone (e.g. 01:32:05 CET)
- Synced to the backend server time (corrected for browser-server drift via the /health endpoint, polled every 5 seconds)
- Starts ticking immediately on page load using the browser clock, then silently corrects when the first server response arrives
Time Sync popover (click the clock to open): - Shows per-VM time readings for all testbed VMs (ansible, master, worker, edge) - Times tick forward live in the browser - Offset column shows drift relative to the ansible VM (reference clock) - Color-coded: green (< 500ms), amber (500ms-2s), red (> 2s) - Max drift summary and IN SYNC / DRIFT DETECTED badge - Auto-refreshes every 30 seconds while open
Automatic drift correction:
- When the popover detects drift (> 1 second), it automatically triggers chronyc makestep on all VMs via POST /api/v1/time/force-sync
- Auto-correction fires once per popover open to prevent loops
- A manual "Force Sync" button also appears when drift is detected, for on-demand correction
- The endpoint SSHs to each VM, runs the sync command, and returns updated time readings
What you need¶
- SSH access from ansible VM to all nodes (for time reads and force-sync)
chronyinstalled on all VMs (deployed by Phase 1)sudoaccess forchronycon remote nodes (configured by Phase 1)
Planned / Stubbed¶
The following endpoints are stubbed for future modules:
| Endpoint | Planned purpose |
|---|---|
POST /api/v1/experiments/run |
Run automated test scenarios (E2E, performance) |
POST /api/v1/snapshot/create |
Create a point-in-time snapshot of the testbed state |
Related Documentation¶
- Dashboard Overview: architecture, access, security, deployment
- API Reference: full endpoint listing
- Physical RAN Integration: full physical RAN setup guide