Show source-backed hardware end-of-service-life status on NetBox Devices and Device Types, from EOSL.ai.
Project description
netbox-eosl
Show source-backed hardware end-of-service-life (EOSL) status on your NetBox Devices and Device Types, straight from EOSL.ai — where every date links to the vendor's own end-of-life bulletin.
A panel appears on the right side of each Device and Device Type page: end-of-sale date,
end-of-service-life date, the EOSL Exposure Score, a link to the vendor bulletin, and a link to
the full EOSL.ai model page. A manage.py eosl_check command audits your whole inventory.
Matching is exact part-number only — the plugin never fuzzy-matches, so it can't put a wrong end-of-life date on the wrong device. If a part number isn't in the database, it says so and offers a search link instead of guessing.
Requirements
| NetBox | 4.3 or later (uses the models template-extension API) |
| Python | 3.10+ |
| Network | outbound HTTPS to eosl.ai from the NetBox host |
Install
# In your NetBox virtual environment
source /opt/netbox/venv/bin/activate
pip install netbox-eosl
Add it to NetBox's configuration.py:
PLUGINS = [
"netbox_eosl",
]
(Optional) tune it:
PLUGINS_CONFIG = {
"netbox_eosl": {
"api_url": "https://eosl.ai", # data source origin
"cache_timeout": 86400, # seconds to cache the lookup table (default 24h)
"request_timeout": 5, # network timeout in seconds
},
}
Then restart NetBox and run migrations (none are added, but this reloads plugins):
python /opt/netbox/netbox/manage.py migrate
sudo systemctl restart netbox netbox-rq
Add netbox-eosl to your local_requirements.txt so upgrades keep it installed.
Use
In the UI — open any Device or Device Type that has a part number set. The "Hardware End-of-Life" card appears in the right column.
Inventory audit — from the NetBox host:
python /opt/netbox/netbox/manage.py eosl_check
EOSL.ai audit — 214 device types
Past / action recommended: 57
Ending soon (plan/watch): 18
Tracked, supported: 44
Active — no EOL announced: 9
Not found in EOSL.ai: 79
No part number set: 7
Past end-of-service-life:
Cisco Catalyst 3850-48P (WS-C3850-48P-S) — EOSL 2025-10 — 12 in service — https://eosl.ai/system/cisco-catalyst-3850/
...
Use --past-only to print just the past-EOSL list (handy in a cron/report).
How matching works
The plugin downloads https://eosl.ai/data/lookup.json (the same part-number → status map that
powers the eosl.ai bulk checker) and caches it. For each Device Type it resolves the part_number
field (a Device inherits it from its Device Type) in three deterministic, conservative steps:
- Exact match (case-insensitive).
- Loose match — ignores spaces/dashes/case, so
FortiGate 60EresolvesFortiGate-60E. - Vendor-gated aliases — expands a manufacturer's short SKU form to the catalogued long form,
but only when the NetBox manufacturer matches that vendor. E.g. a Fortinet
FG-60EresolvesFortiGate-60E,FS-148E→FortiSwitch-148E,FAP-221E→FortiAP-221E. The vendor gate means a non-FortinetFG-…can never be mis-resolved onto a Fortinet record.
There is no fuzzy or substring matching. No part number, or no confident match → a neutral "not tracked" panel with a search link. Nothing is inferred.
The matching logic lives in netbox_eosl/matching.py (no Django imports) and is unit-tested in
tests/ — run python tests/test_matching.py (or pytest).
Data & trust
- Dates come from EOSL.ai, sourced from each vendor's official end-of-life bulletin and linked for verification. Where a vendor publishes no per-model EOSL date, EOSL.ai computes it from the vendor's published support-life policy and labels it "computed".
- This plugin reads public data; it sends none of your inventory anywhere. The only outbound request is fetching the public lookup table.
- Confirm any critical date against the linked vendor bulletin before a purchase, renewal, or migration decision.
License
Apache-2.0. See LICENSE.
Contributing / publishing
Issues and PRs welcome — especially additional vendor SKU aliases (see FORTINET_PREFIX in
matching.py for the pattern) and screenshots. Maintainers: see PUBLISHING.md for the
PyPI + NetBox-community release steps.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file netbox_eosl-0.1.0.tar.gz.
File metadata
- Download URL: netbox_eosl-0.1.0.tar.gz
- Upload date:
- Size: 16.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d0c1650957b9a92a601b20d838e3cd5b233d4786c9076cb455382738567c28f3
|
|
| MD5 |
93b6a124bba3518d371940ba16fb3114
|
|
| BLAKE2b-256 |
c415d1b01d33c5825b95170d2c47aadfeb33db4d547b332cc470d7fb417187b5
|
File details
Details for the file netbox_eosl-0.1.0-py3-none-any.whl.
File metadata
- Download URL: netbox_eosl-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a0c5f7917c55c7a9e0fc012e241c21e0d1e9cdffb2f11aa676fa3967bd18207b
|
|
| MD5 |
6dcf8b30a65c34b93ac697ba2b17f314
|
|
| BLAKE2b-256 |
a1df13845762a504a95a941c5214aa947bd8511905cf9e1286d01948b6baf032
|