Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5a48621
chore: updated python deps
marcinpsk Dec 15, 2025
d54e492
chore: updated python deps
marcinpsk Dec 15, 2025
c6c422d
chore: updated python deps
marcinpsk Dec 15, 2025
887585c
chore: added .envrc
marcinpsk Dec 28, 2025
813b5cf
Merge main into develop to sync upstream changes
marcinpsk Dec 28, 2025
89994b1
feat: add change detection and --update flag for device types
marcinpsk Dec 28, 2025
04a1592
fix: handle pynetbox Record objects in change detection
marcinpsk Dec 28, 2025
498529b
fix: normalize trailing whitespace in change detection
marcinpsk Dec 28, 2025
07962a6
fix: updated new device creation
marcinpsk Jan 1, 2026
69fc19a
fix: added --remove-components to remove components from models when …
marcinpsk Jan 2, 2026
45fd416
chore: added dependabot.yml, updated tests.yml and removed stale.yml
marcinpsk Feb 6, 2026
3883d97
fix: changed black to ruff format
marcinpsk Feb 6, 2026
aa21e48
refactor: consolidate change detection, DRY up netbox_api, add markdo…
marcinpsk Feb 6, 2026
c981780
fix: correct module counter keys, alias-aware component additions, pe…
marcinpsk Feb 6, 2026
04d1510
fix: respect empty cache in _get_cached_or_fetch, fix NetBox capitali…
marcinpsk Feb 6, 2026
86a2e30
fix: use _get_cached_or_fetch in update/remove_components, fix endpoi…
marcinpsk Feb 6, 2026
28c3eae
fix: use item.name instead of str(item) for component cache keys
marcinpsk Feb 8, 2026
50b7ba3
fix: invalidate component cache after successful creation in _create_…
marcinpsk Feb 8, 2026
45ddfe6
perf: scope component preload to relevant device types when vendors a…
marcinpsk Feb 8, 2026
8a21f19
fix: invalidate component cache after successful removal in remove_co…
marcinpsk Feb 8, 2026
abb1c87
fix: use _get_cached_or_fetch in _create_generic to fix module compon…
marcinpsk Feb 8, 2026
c6d19d8
perf: scope component preload by vendor, global fetch when no vendors…
marcinpsk Feb 8, 2026
1f229f8
fix: updated progress on compare
marcinpsk Feb 8, 2026
641ff69
fix: detect property removals, guard component removal detection, and…
marcinpsk Feb 8, 2026
17d3561
fix: skip absent YAML properties in change detection, remove unused m…
marcinpsk Feb 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# direnv configuration
# Run `direnv allow` to enable

# Source .env file if it exists (contains secrets, not in git)
if [[ -f .env ]]; then
log_status "Loading .env variables..."
dotenv .env
fi

# Create and activate uv virtual environment
if command -v uv &> /dev/null; then
# Create venv if it doesn't exist
if [[ ! -d .venv ]]; then
log_status "Creating virtual environment with uv..."
uv venv .venv
fi

# Sync dependencies
if [[ -f pyproject.toml ]]; then
log_status "Syncing dependencies with uv..."
uv sync --quiet --native-tls
fi

# Activate the virtual environment
source .venv/bin/activate
else
log_error "uv not found. Please install uv: https://docs.astral.sh/uv/"
fi
4 changes: 4 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ updates:
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "uv"
directory: "/"
schedule:
interval: "weekly"
4 changes: 4 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ on:
release:
types: [published, edited]

concurrency:
group: docker-${{ github.ref }}
cancel-in-progress: true

jobs:
build-and-push-images:
runs-on: ubuntu-latest
Expand Down
24 changes: 0 additions & 24 deletions .github/workflows/stale.yml

This file was deleted.

5 changes: 4 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
name: tests

permissions:
contents: read

on:
push:
branches:
Expand Down Expand Up @@ -36,4 +39,4 @@ jobs:
run: uv run ruff check .

- name: Check formatting
run: uv run black --check .
run: uv run ruff format --check .
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ celerybeat.pid
# Environments
.env*
!.env.example
!.envrc
.venv
env/
venv/
Expand Down
5 changes: 5 additions & 0 deletions .markdownlint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"MD013": {
"line_length": 120
}
}
10 changes: 7 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
repos:
- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.47.0
hooks:
- id: markdownlint
- repo: local
hooks:
- id: ruff
Expand All @@ -7,9 +11,9 @@ repos:
language: system
types: [python]
require_serial: true
- id: black
name: black
entry: uv run black
- id: ruff-format
name: ruff-format
entry: uv run ruff format
language: system
types: [python]
require_serial: true
Expand Down
133 changes: 87 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,112 +1,153 @@
# Netbox Device Type Import
# NetBox Device Type Import

This library is intended to be your friend and help you import all the device-types defined within the the [NetBox Device Type Library Repository](https://github.com/netbox-community/devicetype-library).
This library is intended to be your friend and help you import all the device-types defined within
the [NetBox Device Type Library Repository](https://github.com/netbox-community/devicetype-library).

> Tested working with 2.9.4, 2.10.4

## 🪄 Description
## Description

This script will clone a copy of the `netbox-community/devicetype-library` repository to your machine to allow it to import the device types you would like without copy and pasting them into the Netbox UI.
This script will clone a copy of the `netbox-community/devicetype-library` repository to your
machine to allow it to import the device types you would like without copy and pasting them
into the NetBox UI.

## 🚀 Getting Started
## Getting Started

3. This script uses `uv` for dependency management.
1. This script uses `uv` for dependency management.

```
uv sync
```
```shell
uv sync
```

4. There are two variables that are required when using this script to import device types into your NetBox installation. (1) Your Netbox instance URL and (2) a token with **write rights**.
1. There are two variables that are required when using this script to import device types
into your NetBox installation. (1) Your NetBox instance URL and (2) a token with
**write rights**.

Copy the existing `.env.example` to your own `.env` file, and fill in the variables.

```
```shell
cp .env.example .env
vim .env
```

Finally, we are able to execute the script and import some device templates!

## 🔌 Usage
## Usage

To use the script, simply execute the script as follows. `uv` will handle the virtual environment.
To use the script, simply execute the script as follows. `uv` will handle the virtual
environment.

```
```shell
uv run nb-dt-import.py
```

Copy the existing `.env.example` to your own `.env` file, and fill in the variables.
This will clone the latest master branch from the `netbox-community/devicetype-library`
from GitHub and install it into the `repo` subdirectory. If this directory already exists,
it will perform a `git pull` to update the repository instead.

```
cp .env.example .env
vim .env
```
Next, it will loop over every manufacturer and every device of every manufacturer and begin
checking if your NetBox install already has them, and if not, creates them. It will skip
preexisting manufacturers, devices, interfaces, etc. so as to not end up with duplicate
entries in your NetBox instance.

Finally, we are able to execute the script and import some device templates!
### Arguments

## 🔌 Usage
This script currently accepts a list of vendors as an argument, so that you can selectively
import devices.

To use the script, simply execute the script as follows. Make sure you're still in the activated virtual environment we created before.
To import only device by APC, for example:

```shell
./nb-dt-import.py --vendors apc
```
./nb-dt-import.py

`--vendors` can also accept a comma-separated list of vendors if you want to import multiple.

```shell
./nb-dt-import.py --vendors apc,juniper
```

This will clone the latest master branch from the `netbox-community/devicetype-library` from Github and install it into the `repo` subdirectory. If this directory already exists, it will perform a `git pull` to update the repository instead.
#### Update Mode

Next, it will loop over every manufacturer and every device of every manufacturer and begin checking if your Netbox install already has them, and if not, creates them. It will skip preexisting manufacturers, devices, interfaces, etc. so as to not end up with duplicate entries in your Netbox instance.
By default, the script only creates new device types and skips existing ones. To update
existing device types:

### 🧰 Arguments
```shell
./nb-dt-import.py --update
```

This script currently accepts a list of vendors as an argument, so that you can selectively import devices.
This will:

To import only device by APC, for example:
- Add new components (interfaces, power ports, etc.) that are in YAML but missing from NetBox
- Update properties of existing components if they've changed
- Update device type properties (u_height, part_number, etc.) if they've changed
- **Report** components that exist in NetBox but are missing from YAML (won't delete by default)

```
./nb-dt-import.py --vendors apc
```
#### Component Removal (Use with Caution)

`--vendors` can also accept a comma separated list of vendors if you want to import multiple.
> **WARNING**: Removing components can affect existing device instances in NetBox.

If you've changed a device type definition (for example, converting interfaces to module-bays
to support SFP modules), you can remove obsolete components with:

```shell
./nb-dt-import.py --update --remove-components
```
./nb-dt-import.py --vendors apc,juniper
```

This will delete any components (interfaces, ports, bays, etc.) that exist in NetBox but are
no longer present in the YAML definition.

**Use cases**:

- Converting fixed interfaces to module-bays for modular devices
- Removing incorrectly defined components from device templates
- Cleaning up after major device type definition changes

**Important considerations**:

- Components attached to actual device instances may prevent deletion
- Review the change detection report before enabling component removal
- Test on a staging NetBox instance first if possible

## Docker build

It's possible to use this project as a docker container.

To build :
To build:

```
```shell
docker build -t netbox-devicetype-import-library .
```

Alternatively you can pull a pre-built image from Github Container Registry (ghcr.io):
Alternatively you can pull a pre-built image from GitHub Container Registry (ghcr.io):

```
```shell
docker pull ghcr.io/minitriga/netbox-device-type-library-import
```

The container supports the following env var as configuration :
The container supports the following env var as configuration:

- `REPO_URL`, the repo to look for device types (defaults to _https://github.com/netbox-community/devicetype-library.git_)
- `REPO_URL`, the repo to look for device types
(defaults to `https://github.com/netbox-community/devicetype-library.git`)
- `REPO_BRANCH`, the branch to check out if appropriate, defaults to master.
- `NETBOX_URL`, used to access netbox
- `NETBOX_TOKEN`, token for accessing netbox
- `VENDORS`, a comma-separated list of vendors to import (defaults to None)
- `REQUESTS_CA_BUNDLE`, path to a CA_BUNDLE for validation if you are using self-signed certificates(file must be included in the container)
- `REQUESTS_CA_BUNDLE`, path to a CA_BUNDLE for validation if you are using
self-signed certificates (file must be included in the container)

To run :
To run:

```
docker run -e "NETBOX_URL=http://netbox:8080/" -e "NETBOX_TOKEN=98765434567890" ghcr.io/minitriga/netbox-device-type-library-import
```shell
docker run -e "NETBOX_URL=http://netbox:8080/" \
-e "NETBOX_TOKEN=98765434567890" \
ghcr.io/minitriga/netbox-device-type-library-import
```

## 🧑‍💻 Contributing
## Contributing

We're happy about any pull requests!

## 📜 License
## License

MIT
Loading