Skip to content

robwdwd/lg-api

Repository files navigation

Looking Glass

A flexible, multi-vendor network looking glass API written in Python with FastAPI.

User Interface

This project does not include a built-in UI or frontend.
If you need a web-based interface, an optional UI is available here: robwdwd/lg-ui.

For development, you can use the built-in FastAPI automatic documentation at <your_url>/docs or <your_url>/redoc, or build your own frontend against the API.

Installation

Download

Download the source or release file and place it anywhere on your filesystem.

git clone git@github.com:robwdwd/lg-api.git
cd lg-api

Install Dependencies

Poetry is recommended, but any venv tool will work.

poetry install --nodev

Configuration

The configuration file lists locations, devices, and CLI commands for each device type as well as the Looking glass API settings

Copy examples/config.yml.example to config.yml in the project root and edit as needed.

cp examples/config.yml.example config.yml
cp examples/env.example .env

Configuration Options Reference

The config.yml file controls the main application settings. Below are the primary options you can configure:

Option Type Description Default
authentication.groups mapping Authentication groups with username/password for device access See below
title string API title (displayed in docs and UI) Looking Glass API
resolve_traceroute_hops string How to resolve traceroute hops: off, all, or missing off
log_level string Logging level: critical, error, warning, info, debug, trace info
root_path string Root path for the API (useful if served under a subpath) /
environment string Environment: prod or devel prod
server_id string Server identifier api1
limits.max_sources.bgp integer Max source locations for BGP queries 3
limits.max_sources.ping integer Max source locations for ping queries 3
limits.max_destinations.bgp integer Max destination addresses for BGP queries 5
limits.max_destinations.ping integer Max destination addresses for ping queries 5
cache.enabled boolean Enable caching (Using redis backed) false
cache.commands.enabled boolean Enable command caching false
cache.commands.ttl int Time to live for command cache 180
cache.redis.dsn string Redis DSN connection string redis://localhost:6379/0
cache.redis.namespace string Namespace for Redis keys lgapi
cache.redis.timeout integer Redis connection timeout (seconds) 5
locations mapping List of locations/devices (see below for structure)
commands mapping CLI command templates for each device type (see below for structure)

Device Authentication

Device authentication is managed via the authentication.groups section in your config.yml.
You can define multiple authentication groups, each with its own username and password.
Each device (location) can specify which group to use via the authentication key.
If a device does not specify a group, or specifies a non-existent group, the fallback group will be used.

authentication:
  groups:
    core:
      username: myuser
      password: mypass
    access:
      username: otheruser
      password: otherpass
    fallback:
      username: fallbackuser
      password: fallbackpass
  • The fallback group must exist.
  • Assign a group to a device using the authentication key under each location.
  • If omitted, the fallback group credentials are used.

Locations

Example:

locations:
  AMS:                              # Location Code
    name: Amsterdam                 # Location name
    region: Western Europe          # Region
    country: Netherlands            # Country Name
    country_iso: NL                 # Country ISO Code (2 Letters)
    device: router.ams.example.net  # Device hostname
    authentication: core            # Use core authentication group, optional - will use fallback otherwise
    type: cisco_iosxr               # Any scrapli supported device type
    source:
      ipv4: loopback999             # Source interface or IP address for ping and traceroute commands with IPv4 Destination
      ipv6: loopback999             # Source interface or IP address for ping and traceroute commands with IPv6 Destination
  LON:                              # Juniper devices with no authentication line, fallback auth group will be used                  
    name: London                    
    region: Western Europe         
    country: United Kingdom
    country_iso: GB
    device: router.lon.example.net  
    type: juniper_junos
    source:
      ipv4: 10.1.2.11
      ipv6: 62bd:9ded:9ddd:6bed:9f79:0aee:11f2:8e2e

Commands

IPADDRESS is substituted for the destination IP address or prefix, and SOURCE is substituted for the source IP or interface (from the location's source key):

commands:
  ping:
    cisco_iosxr:
      ipv4: ping IPADDRESS source SOURCE
      ipv6: ping IPADDRESS source SOURCE
    juniper_junos:
      ipv4: ping IPADDRESS source SOURCE count 5
      ipv6: ping IPADDRESS source SOURCE count 5
  bgp:
    cisco_iosxr:
      ipv4: show bgp ipv4 unicast IPADDRESS
      ipv6: show bgp ipv6 unicast IPADDRESS
    juniper_junos:
      ipv4: show route IPADDRESS protocol bgp detail table inet.0
      ipv6: show route IPADDRESS protocol bgp detail table inet6.0
  traceroute:
    cisco_iosxr:
      ipv4: traceroute IPADDRESS source SOURCE timeout 2
      ipv6: traceroute IPADDRESS source SOURCE timeout 2
    juniper_junos:
      ipv4: traceroute IPADDRESS source SOURCE
      ipv6: traceroute IPADDRESS source SOURCE

Traceroute Hop Resolution

Set resolve_traceroute_hops in config.yml:

  • off: Use router output only.
  • missing: Resolve only unresolved hops.
  • all: Resolve all hops, ignoring router resolution.

Tip:
Disable reverse DNS lookup on the routers to speed up the traceroutes. Example config:

traceroute:
    cisco_iosxr:
      ipv4: traceroute IPADDRESS numeric source SOURCE timeout 2
      ipv6: traceroute IPADDRESS numeric source SOURCE timeout 2
    juniper_junos:
      ipv4: traceroute IPADDRESS no-resolve source SOURCE
      ipv6: traceroute IPADDRESS no-resolve source SOURCE

Caching

The API provides Redis-based caching to improve performance and reduce load on external services and network devices. Caching is disabled by default.

Cache Types

  • Command Cache: Network device command outputs (ping, traceroute, BGP lookups)
  • External API Cache: Results from Cymru IP-to-ASN, CAIDA AS rank, and reverse DNS lookups

Configuration

Enable caching in your config.yml:

cache:
  enabled: true                    # Turn all caching on or off
  commands:
    enabled: true                  # Enable command result caching
    ttl: 180                       # TTL for command cache in seconds
  redis:
    dsn: redis://localhost:6379/0  # Redis connection string
    namespace: lgapi               # Key namespace prefix
    timeout: 5                     # Connection timeout (seconds)

You can customise the Redis connection variables as needed in config.yml.

Redis DSN Format

The dsn field uses a Redis Data Source Name with this format:

redis://[:password]@host:port/db

Examples:

Scenario DSN
Local Redis, default settings redis://localhost:6379
With password redis://:mypassword@localhost:6379
Remote server, database 2 redis://redis.example.com:6379/2
Custom port with auth redis://:secretpass@redis.example.com:6380/1

Components:

  • redis:// — Protocol
  • :password@ — Optional password (omit if none)
  • host — Redis hostname/IP
  • :port — Port number (default: 6379)
  • /db — Database number (default: 0)

Environment Variables

Environment variables are used by Gunicorn for production use, they are not used by the looking glass API itself.

Copy examples/env.example to .env in the project root (not the package folder).

Variable Description
PORT Port number the application listens on (default: 8012).
LISTEN IP/interface to bind the server (default: 127.0.0.1).
WORKERS Number of worker processes (default: 4).
ROOT_PATH Root path for the app (e.g., / or /lg).
LOG_DIR Directory for log files (default: /var/log/lg/).

Community Maps

Community maps convert BGP community values into human-friendly text descriptions.

The mapsdb/asns folder contains the default community mapping files, with one .txt file per ASN (for example, 8220.txt, 3356.txt, etc.).
These files are part of the code base and should not be modified directly. If you wish to contribute new ASN mappings, please submit a pull request.

To customise or override any mappings for your deployment, add files (ending in .txt and preferably named <asn>.txt) to the mapsdb/override folder.
Mappings in the override folder will take precedence over those in the asns folder for the same community values, allowing you to tailor or supplement the default mappings without changing the code base.

How it works:

  • When the application starts, it loads all mapping files from mapsdb/asns and then applies any overrides from mapsdb/override.
  • If a community value exists in both, the override version is used.

To update mappings:

  1. Add or edit a .txt file in mapsdb/override with your custom mappings.
  2. Restart the server to apply the changes.

Note:
Do not edit files in mapsdb/asns directly, as these may be overwritten during upgrades or by version control.

Permissions

Set permissions for the mapsdb folder and .env file:

chgrp <web_server_user> mapsdb .env
chmod g+s mapsdb
setfacl -dR -m u:<web_server_user>:rwX -m u:<your_user>:rwX mapsdb

Running the Development Server

Use Poetry or another virtual environment:

poetry shell
fastapi dev lgapi/main.py

Systemd Service

  1. Copy the example unit file:

    cp examples/lgapi.service /etc/systemd/system/lgapi.service
  2. Edit WorkingDirectory, User, Group, PATH, and VIRTUAL_ENV as needed.

  3. Create the log directory and set permissions:

    mkdir /var/log/lg/
    chown www-data.www-data /var/log/lg/
  4. Enable and start the service:

    systemctl daemon-reload
    systemctl enable lgapi.service
    systemctl start lgapi.service

Nginx Configuration

A reverse proxy via Nginx is recommended.
If serving under a subpath, set ROOT_PATH in .env (e.g., ROOT_PATH=/lgapi).

See examples/nginx.conf and examples/nginx-subpath.conf for sample configs.

Releases

No releases published

Packages

No packages published

Languages