trishul-snmp-suite

Architecture Overview

Trishul SNMP Suite 2.0.2 is a bundle-first SNMP lab and operations platform. The runtime is centered on:

High-Level Shape

The shipped runtime provides:

There is no Nginx layer and no external WebSocket bridge or broker in the current release path. FastAPI serves both the built UI and the live /api/ws socket directly.

Request Flow

Typical browser flow:

  1. the browser requests /
  2. FastAPI serves files from frontend/dist
  3. the shell authenticates with /api/settings/login
  4. the shell sends X-Auth-Token on authenticated requests
  5. the shell opens /api/ws for live status, stats, trap, and simulator-log updates
  6. operator endpoints under /api/... call flat backend services directly

If frontend/dist does not exist, the backend serves a placeholder page that asks the operator to build the frontend artifact.

Runtime Components

FastAPI Application

Defined in backend/app/main.py.

Responsibilities at startup:

Release UI Shell

Source lives under frontend/ and builds to frontend/dist/.

The shipped UI is organized around seven pages:

The shell uses hash navigation, page partial loading, and the API surface exposed by the backend, plus /api/ws for live updates on the main operational pages.

API Routes

All routes live under backend/app/api/routes/ and call flat service modules directly. There is no bridge or adapter layer between the routes and the services.

Route modules:

Service Layer

backend/app/services/ contains flat service modules. Routes call them directly — no intermediate shell or bridge classes.

Key services:

Module Responsibility
runtime.py In-process SNMP responder, manager (GET/GETNEXT/GETBULK/walk), notification listener, trap/inform send, event decode
bundles.py MIB bundle compile, activate, rollback via trishul-smi
mib_sources.py Upload directory scanning, source group precedence, shadowing detection, remote source caching
mib_mutations.py MIB upload, partial compile, dependency fetch, delete with rollback
mibs_service.py Orchestrates mib_sources + mib_mutations + bundles for route handlers and source-group-aware status or export views
browser_service.py OID resolve, module tree, OID tree, search via MibBundle
traps_service.py Trap listener lifecycle, send, event formatting, history reads
simulator_service.py Simulator lifecycle, custom data, logs
walker_service.py Walk execution and result formatting
stats_service.py Stats aggregation from runtime, history, and state store
history.py Durable notification event storage and retrieval
session.py Auth credential storage and session management
state_store.py Persistent key-value settings backed by SQLite
app_settings.py Operator app settings read and write
realtime.py WebSocket connection manager and broadcast functions
bundle_state.py In-memory MibBundle singleton

Bundle Pipeline

backend/app/services/bundles.py drives MIB compilation through trishul-smi.

Compile output is stored as versioned bundle directories containing:

SQLite records bundle metadata, compile runs, and the active-bundle pointer.

The active bundle is loaded into memory at startup as a MibBundle instance. All catalog, browser, and trap resolution queries use this in-memory bundle — there are no SQLite catalog index tables.

Runtime Service

backend/app/services/runtime.py owns all live SNMP surfaces in-process as async tasks. There are no worker subprocesses.

The runtime supports simulation rules (counter, random, timestamp, uptime) and uses the active compiled bundle for symbolic translation and notification enrichment.

Persistence Layout

The default data root is backend/data/ locally or /app/backend/data/ in the container.

Important runtime paths:

Container deployments emit logs to stdout/stderr and rely on Docker log rotation. backend/data/logs/backend.log is only used when file logging is explicitly enabled.

Database Schema

The current SQLite schema covers:

There are no catalog index tables. The active bundle is queried in memory via the loaded MibBundle instance.

Deployment Shape

The container path uses a multi-stage Docker build:

  1. build the operator frontend with Node
  2. install backend requirements including trishul-smi and trishul-snmp
  3. run uvicorn app.main:app from /app/backend

The canonical operator entrypoint is ./install-trishul-snmp-suite.sh.