Skip to main content

NetBox GeoView

NetBox GeoView is a NetBox plugin for displaying infrastructure in a map-oriented view.

It provides:

  • a Leaflet map with configurable raster tile layers
  • filters for sites, devices, device status, tags, ownership, tenancy, and related objects
  • reusable saved filters and native dashboard map widgets
  • device-role filters with inclusion/exclusion and descendant roles
  • optional device-role colors and per-role marker styles
  • configurable site and device popups, including custom fields
  • direct-distance measurement and optional Valhalla route calculation
  • reusable development test data for sites, locations, device types, devices, and custom fields

Versioning

The plugin uses Semantic Versioning in the format MAJOR.MINOR.PATCH.

  • MAJOR: incompatible plugin changes
  • MINOR: new backward-compatible features
  • PATCH: bug fixes and small corrections

NetBox compatibility is managed separately through min_version and max_version in the plugin.

Project Note

This is a personal project to see how far one can go with a practical NetBox plugin idea.

Most of the code was generated with Codex as a coding co-pilot, but maintenance responsibility stays with the developer (the human still carries the pager).

Compatibility

Plugin Release NetBox
0.10.0 4.5.4 to 4.7.4

Later NetBox versions are not included automatically. See testing details for validation reports and test instructions.

Starting with 0.8.1, GeoView requires an authenticated, active user with dcim.view_site or dcim.view_device. The menu is hidden otherwise, and the same rule protects every GeoView endpoint, including tiles and routing. Anonymous requests redirect to login even when NetBox's LOGIN_REQUIRED is disabled; authenticated users without either permission receive HTTP 403. This also applies on NetBox 4.5.10.

Permissions are evaluated through NetBox, including group/default permissions, superusers and EXEMPT_VIEW_PERMISSIONS. Exemptions do not bypass GeoView's login requirement. No separate GeoView permission or plugin model is needed. Object constraints still limit the sites/devices shown, and users need view access to related filter objects they want to select. Saved filters must be enabled and shared or owned by the current user. Saved filters containing unsupported conditions, such as cf_* custom-field filters, are rejected with a visible error rather than silently broadening the map.

GeoView 0.9.0 adds a dedicated save/update/copy workflow and a native NetBox dashboard widget. See saved filters and widgets for usage, filter semantics and permissions. It also adds device-role filtering and optional role-based marker styles. GeoView 0.10.0 adds device-status filters, native saved-filter slugs, tile revalidation and smoother map reloads. See the NetBox 4.7.4 validation report for compatibility checks and upstream upgrade notes.

Installation

Install netbox-geoview from PyPI inside the NetBox virtual environment:

python -m pip install --upgrade netbox-geoview==0.10.0

Optional: install directly from a tagged GitHub source archive:

pip install https://github.com/phlpr/netbox_geoview/archive/refs/tags/v0.10.0.tar.gz

Screenshots

GeoView 0.9.0 on NetBox 4.7.3, using synthetic network data in Austria. Role colors and letter symbols are enabled in the demo configuration; see marker appearance for the settings. Click an image to view it at full size.

Map with device-role colors

GeoView map showing Austrian routers, switches, access switches and firewalls with role colors and symbols

Saved filters, dashboard widgets and routing

Saved filters and device roles

Load a saved selection and refine it with location, hardware and device-role filters.

GeoView filter tab with the saved Austria Switches filter and a selected device role

Native NetBox dashboard widgets

Show different saved selections side by side, with independent maps and refresh controls.

Two native GeoView dashboard widgets showing the complete Austrian demo network and its switches

Routing in dark mode

Compare a calculated road route with the direct distance between two devices.

GeoView in dark mode with a calculated Linz to Vienna route and direct-distance measurement

Configuration

Example plugin settings for configuration.py:

PLUGINS = ["netbox_geoview"]

PLUGINS_CONFIG = {
    "netbox_geoview": {
        "start_latitude": 47.59397,
        "start_longitude": 14.12456,
        "start_zoom": 7,
        "min_zoom": 2,
        "max_zoom": 19,
        "valhalla_url": "https://valhalla1.openstreetmap.de/route",
        "valhalla_timeout": 10,
        "valhalla_costing_options": ["auto", "bicycle", "pedestrian"],
        "valhalla_default_costing": "auto",
        "valhalla_request_defaults": {
            "alternates": 1,
            "directions_options": {
                "units": "kilometers",
            },
        },
        "valhalla_headers": {
            "X-Client-Id": "your-company-netbox-geoview",
        },
        "valhalla_query": {},
        "default_tile_layer": "OpenStreetMap",
        "scroll_wheel_zoom": True,
        "site_marker": {
            "color": "#f1c40f",
            "symbol": "",
            "icon_url": "",
            "icon_size": [28, 40],
            "icon_anchor": [14, 40],
            "popup_anchor": [0, -34],
        },
        "site_group_markers": {
            "burgenland": {"color": "#f1c40f"},
            "karnten": {"color": "#e74c3c"},
            "niederosterreich": {"color": "#3498db"},
            "oberosterreich": {"color": "#2ecc71"},
            "salzburg": {"color": "#ff69b4"},
            "steiermark": {"color": "#16a085"},
            "tirol": {"color": "#9b59b6"},
            "vorarlberg": {"color": "#34495e"},
            "wien": {"color": "#f39c12"},
        },
        "use_role_colors": False,
        "device_role_markers": {
            "core-router": {"symbol": "R"},
            "access-switch": {"symbol": "S"},
            "firewall": {"color": "#e74c3c", "symbol": "F"},
        },
        "tile_layers": [
            {
                "name": "OpenStreetMap",
                "url": "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
                "attribution": "© OpenStreetMap contributors",
            },
            {
                "name": "OpenStreetMap DE",
                "url": "https://tile.openstreetmap.de/{z}/{x}/{y}.png",
                "attribution": "© OpenStreetMap contributors",
            },
            {
                "name": "OpenStreetMap HOT",
                "url": "https://a.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png",
                "attribution": "© OpenStreetMap contributors, Humanitarian OpenStreetMap Team",
            },
            {
                "name": "MapTiler Satellite",
                "url": "https://api.maptiler.com/maps/satellite/{z}/{x}/{y}.jpg",
                "attribution": "© MapTiler",
                "query": {
                    "key": "YOUR_MAPTILER_API_KEY",
                },
            },
            {
                "name": "MapTiler Hybrid",
                "url": "https://api.maptiler.com/maps/hybrid/{z}/{x}/{y}.png",
                "attribution": "© MapTiler",
                "query": {
                    "key": "YOUR_MAPTILER_API_KEY",
                },
            },
        ],
        "tile_provider_url": "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
    }
}

The same example is included in configuration.example.py.

Available settings:

  • start_latitude: initial map latitude
  • start_longitude: initial map longitude
  • start_zoom: initial map zoom level
  • min_zoom: minimum allowed zoom level
  • max_zoom: maximum allowed zoom level
  • valhalla_url: base URL of the Valhalla route endpoint
  • valhalla_timeout: timeout in seconds for route requests
  • valhalla_costing_options: route profile options shown in UI
  • valhalla_default_costing: default route profile
  • valhalla_request_defaults: additional request payload defaults
  • valhalla_headers: optional HTTP headers for Valhalla requests
  • valhalla_query: optional query string parameters for Valhalla requests
  • default_tile_layer: default base layer name or ID
  • scroll_wheel_zoom: enables zooming with the mouse wheel
  • site_marker: base marker appearance for sites and devices
  • site_group_markers: marker overrides by site group name or slug
  • use_role_colors: Boolean switch to use NetBox device-role colors; default False
  • device_role_markers: per-role color, symbol or image overrides by role ID, slug or name
  • tile_layers: list of available base layers
  • query: optional query string parameters per layer, useful for API keys
  • headers: optional HTTP headers per layer
  • tile_provider_url: upstream tile URL template with {z}, {x}, and {y}

Device-role marker appearance

Set use_role_colors=True to color device pins with their assigned NetBox DeviceRole's color. Only the Boolean True enables this; do not use strings such as "true" or "false". Site markers keep their existing appearance.

Styles are applied in this order, with later values overriding earlier ones:

  1. The existing site_marker and matching site_group_markers style.
  2. The NetBox role color, when use_role_colors is True.
  3. A matching device_role_markers entry, independently of the switch.

With the switch off and no role override, device markers look as before. Role overrides support the same fields as site_marker: color, symbol, icon_url, icon_size, icon_anchor and popup_anchor. Specify only the fields you want to change. An explicit role-marker color wins over the NetBox color. Use icon_url="" to clear an inherited image and return to a colored pin.

For a custom image, provide its URL and optional sizing, for example:

"device_role_markers": {
    "core-router": {
        "icon_url": "https://assets.example.net/netbox/router.svg",
        "icon_size": [32, 40],
        "icon_anchor": [16, 40],
        "popup_anchor": [0, -34],
    },
}

Replace the example URL with an image you host; local /static/... URLs also work. Custom images retain their own colors; the role color applies to the built-in pin. The symbol option adds plain text to that pin.

Matching is case-insensitive. If multiple entries match, the role's numeric ID (an integer or string key) wins over its slug, which wins over its name. IDs can distinguish duplicate names/slugs in a role hierarchy. Overrides apply to the assigned role itself; child roles use their own color and configuration. The full map and dashboard widgets share this styling. Restart NetBox after changing plugin configuration.

Satellite Providers

Providers with official API-key-based access that fit this plugin well:

  • MapTiler Satellite: simple raster tile API with API key in the request. Official docs: MapTiler Cloud API
  • MapTiler Hybrid: raster hybrid style with satellite imagery plus labels and borders, also usable with an API key. Inference from MapTiler's documented style family plus verified tile endpoint.
  • Mapbox Satellite: raster tiles with access token authentication. Official docs: Mapbox Tilesets Reference
  • Esri World Imagery: enterprise-capable imagery via ArcGIS location services and token-based authentication. Official docs: ArcGIS service endpoints and Esri Leaflet basemap example

Recommendation:

  • MapTiler Satellite is the easiest fit for the current plugin because it follows a straightforward raster tile pattern with an API key.
  • Mapbox Satellite also fits well and can be configured today with query.access_token.
  • Esri World Imagery is a strong enterprise option, but its exact request pattern depends on the ArcGIS endpoint and token model you want to use.

Requirements

  • GeoView 0.10.0: NetBox 4.5.4 through 4.7.4.
  • Python >=3.12
  • No additional Python runtime dependencies are required beyond NetBox's own environment
  • Installation in the NetBox virtual environment (see Installation)
  • Plugin activation in configuration.py:
    • PLUGINS = ["netbox_geoview"]
    • PLUGINS_CONFIG = {"netbox_geoview": {...}}
  • For MapTiler layers: valid API key (query.key)
  • Optional for routing: reachable Valhalla endpoint (valhalla_url)

Development Test Data

Release 0.6.0 includes an idempotent management command that creates a reusable development data set:

python manage.py seed_geoview_testdata

The command is intended only for development and test databases. It creates or updates clearly prefixed sites, locations, device types, devices, roles, and custom fields. See TESTDATA.md for details and for using a custom JSON definition.

Firewall / Network Allowlist

NetBox GeoView fetches external map and route data server-side. So the egress rules must be applied on the NetBox host (or its outbound proxy), not only on client browsers.

Required for default tile setup:

  • HTTPS/443 to tile.openstreetmap.org
  • HTTPS/443 to tile.openstreetmap.de
  • HTTPS/443 to a.tile.openstreetmap.fr

Required when using MapTiler layers:

  • HTTPS/443 to api.maptiler.com

Optional when routing is enabled (Valhalla):

  • HTTPS/443 to your configured Valhalla host from valhalla_url
  • For the shipped example: HTTPS/443 to valhalla1.openstreetmap.de

Valhalla itself is MIT-licensed and can be self-hosted commercially. The example endpoint is a public demonstration service, not an enterprise service: fair-use limits apply and no availability guarantee is provided. Applications using that endpoint should send an identifying X-Client-Id header. For production or high-volume use, self-host Valhalla or use a provider with an appropriate SLA.

The default map and routing data is based on OpenStreetMap. Keep the visible © OpenStreetMap contributors attribution and comply with the ODbL when using or redistributing derived data.

If your environment uses an explicit outbound proxy, make sure NetBox can reach these hosts through that proxy and that TLS inspection does not break certificate validation.

Metadata

Release files for netbox-geoview 0.10.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for netbox-geoview 0.10.0
File Size Uploaded Provenance Actions
netbox_geoview-0.10.0.tar.gz 173.8 kB With provenance Details for netbox_geoview-0.10.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for netbox-geoview 0.10.0
File Interpreter ABI Platform Actions
netbox_geoview-0.10.0-py3-none-any.whl Python 3 none any Details for netbox_geoview-0.10.0-py3-none-any.whl

Total release size: 315.4 kB

Release files / netbox_geoview-0.10.0.tar.gz

Download URL netbox_geoview-0.10.0.tar.gz
Size 173.8 kB
Tags Source
SHA-256 checksum
How to use checksums
b1c7bfda6eea1b052d982cd7ed234ea58949ccbdd049fdab5c8c77ae787ec3fb
BLAKE2b-256 checksum
How to use checksums
f4a67eaed1a7cbb913ce8a70fdb105276a6d0deae2eda08d371b80644c554801
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

Release files / netbox_geoview-0.10.0-py3-none-any.whl

Download URL netbox_geoview-0.10.0-py3-none-any.whl
Size 141.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bd0ccadef4b6bfa06b58a8505b6e8c9618e15d35ee0d284fe123fd199de46ebd
BLAKE2b-256 checksum
How to use checksums
d4bf23fac232177b6cbca5d9fea8025207f0bfdd3225ceb95af3ebc0984e752f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

Security for netbox-geoview 0.10.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for netbox_geoview-0.10.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page