Point at a NETCONF device's IP, get a working gNMI server.
Vendor-agnostic telemetry for optical and network gear that never spoke gRPC.
Dual-licensed. Splice is available under the GNU AGPL v3.0-or-later (free, copyleft β see
LICENSE) or a commercial licence for proprietary / closed-source use (seeCOMMERCIAL-LICENSE.md, contactinfoknex@tcd.ie). Details β
Modern telemetry collectors β gnmic, Telegraf, OpenConfig pipelines β expect gNMI over gRPC. But a huge amount of deployed optical and transport gear only speaks NETCONF: ROADMs, transponders, amplifiers, line systems. Each vendor ships its own YANG models, its own list keys, its own quirks. Bolting a collector onto them usually means writing per-device glue and re-writing it every firmware bump.
This bridge fixes that. Give it an IP and credentials; it discovers the device's YANG models, builds a telemetry catalog, polls NETCONF under the hood, and serves standard gNMI to any client β no per-vendor code, no changes to the device.
Three different vendors β Lumentum ROADM, Adtran Teraflex, Juniper ILA β streaming optical power into one Grafana dashboard through the bridge.
graph LR
D["NETCONF device<br/>:830 (SSH)"] -->|YANG discovery| C[Catalog]
C --> P[Poller]
P -->|NETCONF get| D
P --> M[(TTL cache)]
M --> G["gNMI server<br/>:9339 (gRPC)"]
G -->|gNMI Get / Subscribe| K["gnmic Β· Telegraf<br/>AI agents"]
DB[(PostgreSQL)] -.-> C
Discovery walks the device's YANG library into module-qualified catalog paths, the planner batches them into efficient NETCONF reads, and a resilient poller fills a TTL cache that the gRPC server answers from. Performance-monitoring data is published under synthetic, instance-keyed paths so per-port metrics never collide.
| Feature | Description | |
|---|---|---|
| π§ | Zero-touch onboarding | quickstart --host <ip> discovers YANG, builds the catalog, and serves gNMI in one command |
| π·οΈ | Vendor-agnostic | Works across any NETCONF/YANG device β proven live on Lumentum, Adtran, and Juniper gear |
| π | Instance-keyed telemetry | PM data carries its originating port as gNMI keys, so multi-line metrics stay distinct |
| π | Drift self-healing | Re-resolves list instances at startup and rebuilds filters when a device is re-provisioned |
| π©Ί | Lockout-safe resilience | Reconnect-once, circuit breaker, and auth/session-limit detection protect fragile devices |
| π― | Curated polling | Poll only the metrics you care about with include patterns and per-pattern intervals |
| π | Grafana dashboards out of the box | Setup generates per-device live-telemetry and YANG-inventory dashboards from the discovered catalog |
| π | Hybrid path search | Find paths in huge YANG catalogs by keyword (BM25, no extra deps) blended with semantic embeddings when installed |
| π§ͺ | Hardware-free simulation | --simulate openroadm runs the full pipeline against a simulated device |
| π€ | AI-agent ready | Built-in MCP server exposes the bridge as tools for Claude and other agents |
Resilience is the load-bearing design choice: optical devices frequently limit concurrent NETCONF sessions and lock accounts on repeated auth failures, so every RPC path is built to back off rather than hammer.
python -m venv .venv && source .venv/bin/activate
pip install -e . # core CLI + gNMI server
pip install -e ".[tui]" # optional: interactive console
pip install -e ".[mcp]" # optional: AI-agent interfacesplice --simulate openroadm runIn another terminal, it answers gNMI like any real server:
gnmic -a localhost:9339 --insecure capabilities
# gNMI version: 0.8.0
# supported models:
# - org-openroadm-device, 2023-05-26 ...Or read live values straight from the simulated device via the Python API:
from splice.api.device import Device
with Device("sim://openroadm") as dev:
print(dev.get("/org-openroadm-device/node-id"))
# [{'path': '/org-openroadm-device/node-id', 'value': 'ROADM-SIM-01'}]NETCONF_PASSWORD='...' splice quickstart --host 10.0.0.1 --username adminThis generates a per-device config, runs full discovery, writes Grafana dashboards for the device, and starts the gNMI server. That's the whole promise β an IP in, a gNMI endpoint out.
| Interface | Entry point | Best for |
|---|---|---|
| CLI + PostgreSQL | splice --config <cfg> setup | run |
Production: persistent catalog, multi-device, history |
| Python API | Device("sim://openroadm") |
Scripting and notebooks β no database or config files |
| MCP server | splice mcp |
AI agents β connect, query, and set config as tools |
| Interactive TUI | splice-tui --devices-dir devices |
Operators β browse paths, watch live telemetry, run setup |
The Textual console managing a live Adtran Teraflex β health cards, circuit-breaker state, and catalog counts at a glance.
YAML-based, one file per device. Credentials come from the NETCONF_PASSWORD env var or a password_file β never committed.
device:
host: 10.0.0.1
username: admin
password_file: devices/my_device/password
gnmi:
port: 9339
expansion_mode: direct # use cached list instances (safe default)
poller:
default_interval_sec: 30
task_failure_limit: 5 # drop a path after N consecutive failures
metrics: # optional: poll only what you care about
enabled: true
include:
- { pattern: "opt-rcv-pwr|fec-ber", regex: true, interval_sec: 5 }See docs/configuration.md for the full reference.
| Document | Description |
|---|---|
| Quickstart | Step-by-step first device |
| Configuration | Every config section, with examples |
| Python API | The Device class, no DB required |
| TUI Guide | Interactive console walkthrough |
| Troubleshooting | Common failure modes and fixes |
| CLAUDE.md | Architecture overview for contributors and agents |
git clone https://github.com/Open-Ireland-Testbed/splice.git
cd splice
python -m venv .venv && source .venv/bin/activate
pip install -e ".[tui,mcp,search]"
python -m pytest # ~640 tests, no DB needed
TEST_DATABASE_URL='postgresql+psycopg://postgres:postgres@localhost:5432/splice' \
python -m pytest # include PostgreSQL-backed testsCI runs the migration-safety, no-database, and full PostgreSQL 16 suites on every push.
Splice is dual-licensed:
- GNU AGPL v3.0-or-later (see
LICENSE) β free for open-source and AGPL-compliant use. If you modify Splice or run it as a network service, the AGPL requires you to make your corresponding source available to its users. - Commercial licence β for proprietary, embedded, or closed-source use
without the AGPL's copyleft obligations. See
COMMERCIAL-LICENSE.mdfor a summary.
If you use Splice in a closed-source or commercial product, you must obtain a commercial licence. To request one, contact Trinity College Dublin (Trinity Innovation & Enterprise) at infoknex@tcd.ie.
Copyright (c) 2026 Trinity College Dublin. Splice bundles and depends on third-party open-source components (gRPC, ncclient, SQLAlchemy, pyang, paramiko, the OpenConfig gNMI definitions, and others) under their own permissive or LGPL licences; none of those impose copyleft on Splice or constrain this dual-license choice.
Built for the Open Ireland optical testbed β so any NETCONF device can join a modern telemetry pipeline.