Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
162 commits
Select commit Hold shift + click to select a range
1520c8d
feat(inventory): modules/inventory sync tab with mapping rules
marcinpsk Mar 31, 2026
c53b0c4
fix tests: update db-fallback tests to match new RQ-only cancellation…
marcinpsk Apr 1, 2026
b2fe27d
fix: updated tests
marcinpsk Apr 1, 2026
a60d601
Apply CR findings: code quality, test, docs, and template fixes
marcinpsk Apr 1, 2026
b04c67a
Apply second batch of CR findings on pr/inventory-core
marcinpsk Apr 1, 2026
ca7af1a
Apply CR findings batch 3: test hardening, PlatformMapping lazy impor…
marcinpsk Apr 1, 2026
cc7cb42
cr: batch 4 — prefetch_related, deterministic export, test improvements
marcinpsk Apr 1, 2026
1a9df23
cr: batch 5 — normalization scoping bug, test fixes
marcinpsk Apr 1, 2026
4a73896
cr: batch 6 — normalization rule caching, test correctness
marcinpsk Apr 1, 2026
a5f3b45
fix: FPC slot int/str comparison, stale docstring, test patch targets
marcinpsk Apr 1, 2026
8776a0d
fix: surface ambiguous platform, preloaded-rules fallback, serial mis…
marcinpsk Apr 1, 2026
5d6d856
fix: canonical librenms_id lookup, None guard, transceiver transparen…
marcinpsk Apr 1, 2026
ab85324
Apply CR batch 10 fixes
marcinpsk Apr 2, 2026
a6aece3
Apply CR batch 11 fixes
marcinpsk Apr 2, 2026
75e1a51
fix: normalize librenms_hardware/os to lowercase, fix convert_speed_t…
marcinpsk Apr 2, 2026
281c835
fix(js): address PR #258 review findings
marcinpsk Apr 2, 2026
881c111
fix: handle unsaved manufacturer in normalization, fix JS modal/fetch…
marcinpsk Apr 2, 2026
aa443be
fix: type annotation, non-positive librenms_id guard, htmx label list…
marcinpsk Apr 2, 2026
0773a2f
fix: use _PLACEHOLDER_VALUES for serial normalization, fix docstring
marcinpsk Apr 2, 2026
ae4c50a
Fix CR batch: device_type ambiguity, platform MOR, cache invalidation…
marcinpsk Apr 2, 2026
1e29fc5
Promote SKIP_TYPES and _NON_HARDWARE_CLASSES to module-level constants
marcinpsk Apr 2, 2026
7e70201
Fix find_matching_platform docstring and non-positive string librenms…
marcinpsk Apr 2, 2026
32562e7
fix: normalize placeholder serials and txr_type in modules_view
marcinpsk Apr 2, 2026
513932b
Fix whitespace-only librenms_id, BUILTIN model placeholder, FPC-scope…
marcinpsk Apr 3, 2026
16ee302
Fix non-integer librenms_id passthrough, stale cache on missing ID, e…
marcinpsk Apr 3, 2026
7dfd436
fix: normalize _GENERIC_CONTAINER_MODELS to lowercase; embed librenms…
marcinpsk Apr 3, 2026
727198d
fix: treat duplicate-serial module conflicts as ambiguous instead of …
marcinpsk Apr 3, 2026
ab8dd7d
fix: clear stale cache on legacy payload; ungate generic-model filter…
marcinpsk Apr 3, 2026
521932e
Remove dead vc_requested assignment left by rebase
marcinpsk Apr 14, 2026
316caa1
fix: VC zero-based detection all-zeros guard; align VC-perm tests wit…
marcinpsk Apr 14, 2026
44836e9
fix: CR batch 12 — serial normalization, conflict disambiguation, mod…
marcinpsk Apr 14, 2026
eceb492
fix: address deferred CR findings from issues #53-#56
marcinpsk Apr 14, 2026
e96b3f3
fix: address 3 remaining CR findings from PR #50
marcinpsk Apr 14, 2026
7464ea5
refactor: drop _extract_inventory_list legacy-list fallback
marcinpsk Apr 15, 2026
ca5f8ef
fix: race conditions, class-aware mappings, stale snapshot in module …
marcinpsk Apr 15, 2026
7a202bd
fix: normalize placeholder serials in UpdateModuleSerialView, fix reg…
marcinpsk Apr 15, 2026
45e8078
fix: lock module row before updating serial in UpdateModuleSerialView
marcinpsk Apr 15, 2026
34981aa
Merge pull request #268 from bonzo81/develop
bonzo81 Apr 15, 2026
565eba1
Merge pull request #269 from bonzo81/develop
bonzo81 Apr 15, 2026
87400d5
fix: use fullmatch+expand in _find_parent_module_id regex matching
marcinpsk Apr 15, 2026
b56da37
Merge branch 'develop' into pr/inventory-core
bonzo81 Apr 15, 2026
b4a331d
fix: address CR review batch - regex, tests, docs
marcinpsk Apr 15, 2026
d87863f
revert: restore original docs/usage_tips/virtual_chassis.md
marcinpsk Apr 15, 2026
2d9c89e
Add 'develop' branch to CodeQL workflow triggers
bonzo81 Apr 15, 2026
7ac2017
fix: revert bulk_import cancellation, VC comment, VM docstring, sync …
marcinpsk Apr 15, 2026
fbb8d80
fix: restore naming resolution and VC logic lost during rebase
marcinpsk Apr 15, 2026
338ef60
revert: restore original README.md and virtual_chassis.md
marcinpsk Apr 15, 2026
793797a
fix: improve ambiguity test assertion and error message wording
marcinpsk Apr 15, 2026
9350e33
Merge pull request #273 from bonzo81/develop
bonzo81 Apr 16, 2026
f7d9bdc
chore(deps): bump actions/checkout in the github-actions group
dependabot[bot] Apr 16, 2026
87772d0
fix: CR review - modal close, test line refs, generic e2e
marcinpsk Apr 17, 2026
83f42d0
Merge pull request #274 from bonzo81/dependabot/github_actions/github…
bonzo81 Apr 17, 2026
be40fd8
Merge branch 'develop' into pr/inventory-core
marcinpsk Apr 17, 2026
5e103c0
Merge pull request #277 from bonzo81/develop
bonzo81 Apr 20, 2026
631777e
Merge branch 'develop' into pr/inventory-core
marcinpsk Apr 21, 2026
49a7b23
append project.urls
sorano Apr 27, 2026
b80074f
Merge pull request #281 from sorano/patch-1
bonzo81 Apr 27, 2026
53e76b2
fix: three bugs in module inventory sync reported in PR #261 review
marcinpsk Apr 27, 2026
a1c0be8
fix: improve module table readability in dark mode
marcinpsk Apr 27, 2026
c23a2da
feat: split Mappings into its own navigation group
marcinpsk Apr 27, 2026
c04e700
refactor: reorder navigation groups to Import, Status Check, Mappings…
marcinpsk Apr 27, 2026
0946700
fix: remove table-light from mismatch modal thead for dark mode
marcinpsk Apr 27, 2026
c82fef8
fix: replace table-danger/warning cell backgrounds with text colors i…
marcinpsk Apr 27, 2026
0105892
fix: remove all row background highlighting from module sync table
marcinpsk Apr 27, 2026
04c9b8d
refactor: reorder Mappings group — all mappings first, then Ignore Ru…
marcinpsk Apr 27, 2026
41a7c85
fix: update tests to reflect row_class removal
marcinpsk Apr 27, 2026
3029cd3
fix: auto-generate slug when creating platform from sync page (#279)
marcinpsk Apr 28, 2026
cc40f2a
Revert "fix: auto-generate slug when creating platform from sync page…
marcinpsk Apr 28, 2026
4d21c55
fix: generate slug when creating Platform via CreateAndAssignPlatform…
marcinpsk Apr 28, 2026
ff76ea1
test: assert Platform constructor receives slug in CreateAndAssignPla…
marcinpsk Apr 28, 2026
7524a16
fix: wrap OOB row in table to survive HTMX HTML parsing
marcinpsk Apr 28, 2026
5edcaed
fix(imports): add HTTP status codes, remove redundant full_clean, fix…
marcinpsk Apr 28, 2026
385d60c
fix(js): extract JSON error message in delete-interfaces handler; gua…
marcinpsk Apr 29, 2026
3fc09bf
refactor(js): extract fetchErrorMessage() helper to unify fetch error…
marcinpsk Apr 29, 2026
d89852d
feat: exact-name-first platform lookup; optional mapping on platform …
marcinpsk Apr 30, 2026
09ca860
fix(pr#50): address CR feedback on AddDeviceTypeMapping form and plat…
marcinpsk Apr 30, 2026
08d78e1
fix(pr#50): isolate PlatformMapping save; ignore stale autocomplete r…
marcinpsk Apr 30, 2026
cb9f923
fix(pr#50): check add_platformmapping permission when create_mapping …
marcinpsk May 1, 2026
ce74bd1
Merge branch 'main' into pr/inventory-core
marcinpsk May 1, 2026
7880f53
fix: address CodeQL security scan findings
marcinpsk May 4, 2026
3c185f7
revert: remove workflow permissions additions (tracked separately)
marcinpsk May 5, 2026
11d4b32
Fix PR review findings: available_roles, CSRF, test quality
marcinpsk May 5, 2026
cdccd3b
Fix PR #58 review findings (batch 2)
marcinpsk May 5, 2026
334ad0d
Fix PR #58 review findings (batch 3)
marcinpsk May 5, 2026
23d4ad6
Fix #59–#62: YAML anchor, DynamicModelChoiceField, ToggleColumn, writ…
marcinpsk May 5, 2026
7162e99
Merge branch 'bonzo81:master' into main
marcinpsk May 5, 2026
4fe7830
Merge branch 'main' into pr/inventory-core
marcinpsk May 5, 2026
0a3f98f
Fix PR #63 review findings: ordering, error handling, modal title, cl…
marcinpsk May 5, 2026
27412d9
Fix replacement template validation and deterministic bay lookup
marcinpsk May 5, 2026
c253af4
Fix wildcard constraint, ambiguity message, and scoped permissions
marcinpsk May 5, 2026
c878e89
devcontainer: restore full debug output in codespaces-configuration.py
marcinpsk May 5, 2026
c869d81
fix(migration): add preflight dedup before wildcard UniqueConstraint
marcinpsk May 5, 2026
917f504
fix: remove dead check_match, close TOCTOU race, fix migration db alias
marcinpsk May 5, 2026
6409609
fix: guard symmetric delete race in AddDeviceTypeMappingView
marcinpsk May 5, 2026
3bfb51c
fix: catch IntegrityError on concurrent create in AddDeviceTypeMappin…
marcinpsk May 6, 2026
52571a1
fix: inject hx-swap-oob on device row in AddDeviceTypeMappingView res…
marcinpsk May 6, 2026
188b0bc
fix: use int:device_id converter on all device-import URL patterns
marcinpsk May 6, 2026
664f5e9
fix: suppress false-positive CodeQL XSS on AddDeviceTypeMappingView r…
marcinpsk May 7, 2026
6ba8308
fix: use format_html + mark_safe to clear CodeQL XSS on AddDeviceType…
marcinpsk May 7, 2026
b39e07e
fix: skip change-permission escalation in concurrent-create no-op path
marcinpsk May 7, 2026
96a89e1
docs: clarify mark_safe is a trust assertion, not a sanitizer
marcinpsk May 7, 2026
53cbf3a
feat: add VC-aware module sync
bonzo81 May 7, 2026
e731415
test: align VC module sync expectations
bonzo81 May 7, 2026
216fb84
fix: use all ancestor names as bay-mapping candidates
marcinpsk May 7, 2026
ac7e5c5
Revert "fix: use all ancestor names as bay-mapping candidates"
marcinpsk May 7, 2026
03caca0
test: add prod-shape WS-X4908 bay-matching coverage
marcinpsk May 7, 2026
ef6d269
fix: bail _match_bay_by_position on non-container scaffolding
marcinpsk May 7, 2026
2c839f3
fix: restrict serial_matches_device rule to chassis-level entries
marcinpsk May 7, 2026
d5e493e
fix: class-aware positional fallback + model gap warnings
marcinpsk May 8, 2026
be5f175
feat: ModuleBayMapping suggestions + Add Mapping button on No Bay rows
marcinpsk May 8, 2026
0adcc81
fix: address valid code-review findings
marcinpsk May 8, 2026
873e66d
feat: remove {module} conflict warning, add Generic manufacturer fall…
marcinpsk May 8, 2026
1587c7b
fix: replace {module} conflict tooltip with Name Conflict status badg…
marcinpsk May 8, 2026
74e37df
feat: show conflict reason as tooltip on Name Conflict badge
marcinpsk May 8, 2026
c96be2e
fix: re-apply Name Conflict status after _apply_installed_status
marcinpsk May 8, 2026
d98354c
feat: fix Name Conflict tooltip style and add 'Add Mapping' for No Ty…
marcinpsk May 8, 2026
6cccf1e
fix: remove has_nested_name_conflict — obsolete since NetBox 4.5.5 si…
marcinpsk May 8, 2026
51202ca
Revert "fix: remove has_nested_name_conflict — obsolete since NetBox …
marcinpsk May 8, 2026
1166c40
feat: carrier auto-install rules + vendor-scoped ModuleBayMapping + m…
marcinpsk May 9, 2026
91d81fe
fix: bay-mapping suggestions for integrated children and descr-encode…
marcinpsk May 9, 2026
4c6030b
fix: address CodeRabbit review findings (small fixes)
marcinpsk May 9, 2026
4f8dc88
contrib: vendor-scope generic mapping examples (#73)
marcinpsk May 9, 2026
5219c2c
test/js: minor housekeeping nitpicks (#74)
marcinpsk May 9, 2026
13fc72a
docs: clarify ModuleTypeMapping ambiguity asymmetry (#72)
marcinpsk May 9, 2026
e24bfea
refactor: convert module mismatch modal forms to HTMX (#70)
marcinpsk May 9, 2026
6a3f577
fix(db): tighten uniqueness on nullable manufacturer FKs (#71)
marcinpsk May 10, 2026
7f02cad
Suggest descr-anchored bay mapping for fan/PSU rows whose name is jus…
marcinpsk May 10, 2026
d2df39c
Scope ModuleTypeMapping by manufacturer + fix PlatformMapping ambiguo…
marcinpsk May 10, 2026
1af01cd
Fail-closed Generic ModuleType fallback + CodeRabbit nitpicks
marcinpsk May 10, 2026
fe76d4b
Merge branch 'develop' into pr/inventory-core
marcinpsk May 10, 2026
947ff74
PR #67 4th-pass review fixes (CodeRabbit + Copilot)
marcinpsk May 10, 2026
d0809b4
Add Bay Template QoL: inline modal for missing ModuleBayTemplate
marcinpsk May 11, 2026
9ddd284
Address PR #67 5th-pass review comments
marcinpsk May 11, 2026
4fd7111
Add ModuleBayMapping checkbox to Add-Bay-Template modal
marcinpsk May 11, 2026
384bf55
Offer regex ModuleBayMapping when bay name skeleton matches
marcinpsk May 11, 2026
4a6b0b7
Allow regex bay mapping when libre/NetBox skeletons differ
marcinpsk May 11, 2026
ea3473c
Render bay-mapping preview via DOM nodes, not innerHTML
marcinpsk May 11, 2026
c8d737d
Address PR #67 review pass 6: perms + safe-string fixes
marcinpsk May 11, 2026
1795a8f
Instantiate ModuleBayTemplate onto existing devices/modules
marcinpsk May 11, 2026
44a7961
Squash inventory-core migrations 0010-0015 into a single 0010
marcinpsk May 12, 2026
4a28014
Fix permission gate ordering in SingleModuleVerifyView.post()
marcinpsk May 12, 2026
150a6f4
fix(migrations): lower 0010 external deps to NetBox 4.2 floor
marcinpsk May 13, 2026
c5a5f13
Unify platform-create modal & fix conflict-action error UX
marcinpsk May 16, 2026
2afd7d2
Don't gate librenms_id migration on unrelated validation errors
marcinpsk May 16, 2026
32d52fa
Extend htmx error toast to remaining modal endpoints; update tests
marcinpsk May 16, 2026
56e610b
fix(pr-review): address CodeRabbit feedback batch
marcinpsk May 16, 2026
26771db
fix(pr-review): address 2 new CodeRabbit findings
marcinpsk May 16, 2026
5769bf9
Fix UpdateDevicePlatformView to resolve platform via PlatformMapping
marcinpsk May 16, 2026
846188a
Fix import modal platform row: show Not set + sync for existing devic…
marcinpsk May 16, 2026
01a2f92
fix(pr-review): address 4 CodeRabbit findings
marcinpsk May 16, 2026
c0d17de
fix: format_html no-args TypeError in InventoryIgnoreRuleTable
marcinpsk May 17, 2026
b7968c9
fix(migration): match seeded InventoryIgnoreRules on full signature
marcinpsk May 17, 2026
7eb7926
fix(sync): abort stale verify-module fetches before issuing a new one
marcinpsk May 19, 2026
3d8469b
fix(contrib): anchor the two Nokia transceiver bay regex patterns
marcinpsk May 19, 2026
d5b5575
Fix four CodeRabbit review findings
marcinpsk May 19, 2026
c1f2598
Fix broken tests and PlatformMapping savepoint race condition
marcinpsk May 19, 2026
0118f84
Introduce _parse_request_json helper; guard all json.loads in devices.py
marcinpsk May 19, 2026
0269cb0
Move _parse_request_json to mixins; guard cables_view; fix weak tests
marcinpsk May 19, 2026
e77592f
Rename _parse_request_json -> parse_request_json (make public)
marcinpsk May 19, 2026
6d92824
test: strengthen htmx error-path assertions and align names
marcinpsk May 19, 2026
c9ea0d9
fix: address five CodeRabbit findings from PR #288
marcinpsk May 19, 2026
11e5805
fix(forms): drop legacy poller-group cache fallback + add response-sh…
marcinpsk May 19, 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
2 changes: 2 additions & 0 deletions .devcontainer/config/codespaces-configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
"127.0.0.1",
"*",
]
# Development environment — logging config values is an accepted tradeoff here.
# CodeQL alert for this is dismissed intentionally.
print(f"🔗 Codespaces detected: {codespace_name}")
print(f"🔒 CSRF Trusted Origins: {CSRF_TRUSTED_ORIGINS}")
print(f"🌐 Allowed Hosts: {ALLOWED_HOSTS}")
Expand Down
23 changes: 23 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,29 @@
- Navigation menu (`navigation.py`) has 3 groups: **Settings** (Plugin Settings, Interface Mappings), **Import** (LibreNMS Import), **Status Check** (Site & Location Sync, Device Status, VM Status). All items use `permissions=[PERM_VIEW_PLUGIN]`.
- **Background job polling requires superuser** — non-superusers fall back to synchronous mode. See `background-jobs.instructions.md` for details.

## CodeQL & Security Patterns

### Clearing CodeQL `py/reflected-xss` false positives
When a view builds an `HttpResponse` from Django-template-rendered HTML (decoded via `.content.decode()`), CodeQL traces `request → template-render → HttpResponse` as reflected XSS even though Django templates auto-escape all user values.

**Correct fix:** use `format_html()` to compose the envelope and `mark_safe()` as a **trust assertion** on the inner HTML — CodeQL's Django taint model recognises this pattern and stops tracking the taint:

```python
from django.utils.html import format_html
from django.utils.safestring import mark_safe

modal_html = some_view.get(request, pk).content.decode("utf-8")
oob = format_html('<div id="target" hx-swap-oob="innerHTML">{}</div>', mark_safe(modal_html))
return HttpResponse(oob, content_type="text/html")
```

> **Important:** `mark_safe()` is a trust assertion, not a sanitizer — it tells Django "I guarantee this string is already safe HTML." Only use it when `modal_html` comes from a server-rendered Django view (whose templates auto-escape all user values). Never pass untrusted user input to `mark_safe()` — that would introduce real XSS.

**Do NOT** use `# lgtm[py/reflected-xss]` — that is LGTM.com legacy syntax and is **not** honoured by GitHub's modern CodeQL Action.

### URL converters
Always use `<int:pk>` (not `<str:pk>`) for numeric IDs in URL patterns. Django's `<int:>` converter auto-validates and returns 404 for non-integer values, eliminating the URL-parameter taint source that CodeQL otherwise flags.

## When in Doubt
- Check docs in `docs/development/` for structure, view inheritance, mixins, and template conventions before introducing new patterns.
- Review the existing sync views (e.g., `views/sync/interfaces.py`) as reference implementations for data flow and caching patterns.
Expand Down
2 changes: 2 additions & 0 deletions .github/instructions/testing.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ description: Testing patterns and conventions for the NetBox LibreNMS plugin
- `librenms_api.py` → `test_librenms_api.py`, `test_librenms_api_helpers.py`
- `import_utils/` package (`filters.py`, `device_operations.py`, `vm_operations.py`, `cache.py`, `permissions.py`, `virtual_chassis.py`), `import_validation_helpers.py`, `utils.py` → `test_import_utils.py`, `test_import_validation_helpers.py`, `test_utils.py`
- `jobs.py`, `views/imports/list.py` → `test_background_jobs.py`
- `import_utils/bulk_import.py` → `test_coverage_bulk_import.py`
- Utility helpers (`utils.py` coverage tests) → `test_coverage_utils.py`
- Permission mixins, API permissions, constants → `test_permissions.py`
- VLAN API, mode detection, comparison, sync → `test_vlan_sync.py`
- `VlanAssignmentMixin`, VLAN enrichment → `test_interface_vlan_sync.py`
Expand Down
103 changes: 103 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL Advanced"

on:
push:
branches: [ "master", "develop" ]
pull_request:
branches: [ "master", "develop" ]
schedule:
- cron: '35 13 * * 0'

jobs:
analyze:
name: Analyze (${{ matrix.language }})
# Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners (GitHub.com only)
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
permissions:
# required for all workflows
security-events: write

# required to fetch internal or private CodeQL packs
packages: read

# only required for workflows in private repositories
actions: read
contents: read

strategy:
fail-fast: false
matrix:
include:
- language: actions
build-mode: none
- language: javascript-typescript
build-mode: none
- language: python
build-mode: none
# CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift'
# Use `c-cpp` to analyze code written in C, C++ or both
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
steps:
- name: Checkout repository
uses: actions/checkout@v6

# Add any setup steps before running the `github/codeql-action/init` action.
# This includes steps like installing compilers or runtimes (`actions/setup-node`
# or others). This is typically only required for manual builds.
# - name: Setup runtime (example)
# uses: actions/setup-example@v1

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.

# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality

# If the analyze step fails for one of the languages you are analyzing with
# "We were unable to automatically build your code", modify the matrix above
# to set the build mode to "manual" for that language. Then modify this step
# to build your code.
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
- name: Run manual build steps
if: matrix.build-mode == 'manual'
shell: bash
run: |
echo 'If you are using a "manual" build mode for one or more of the' \
'languages you are analyzing, replace this with the commands to build' \
'your code, for example:'
echo ' make bootstrap'
echo ' make release'
exit 1

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
with:
category: "/language:${{matrix.language}}"
31 changes: 31 additions & 0 deletions contrib/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Contrib: Example Mapping Files

This directory contains example YAML mapping files for bulk import into the
NetBox LibreNMS Plugin. Each file can be imported via the plugin's bulk import
feature in the NetBox UI.

## How to Import

1. Navigate to the mapping page (e.g., **LibreNMS → Device Type Mappings**)
2. Click the **Import** button (upload icon) in the top right
3. Select **YAML** format
4. Paste the contents of the relevant YAML file
5. Click **Submit**

## Available Mappings

| File | Description |
|------|-------------|
| `interface_type_mappings.yaml` | Maps LibreNMS interface types + speeds to NetBox interface types |
| `device_type_mappings.yaml` | Maps LibreNMS hardware strings to NetBox device types |
| `module_type_mappings.yaml` | Maps LibreNMS inventory model names to NetBox module types (incl. transceivers) |
| `module_bay_mappings.yaml` | Maps LibreNMS inventory container names to NetBox module bay names |
| `normalization_rules.yaml` | Regex-based string normalization applied before module type/bay lookups |
| `inventory_ignore_rules.yaml` | Suppresses phantom ENTITY-MIB entries (e.g. Cisco IOS-XR IDPROM artefacts) |
| `platform_mappings.yaml` | Maps LibreNMS platform strings to NetBox device platforms |

## Customisation

These files are **examples** — adjust values to match the device types, module
types, and interface types defined in your NetBox instance. The `netbox_*`
fields must reference objects that already exist in your NetBox.
31 changes: 31 additions & 0 deletions contrib/carrier_auto_install_rules.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Carrier Auto-Install Rules
#
# Suggest a holder/carrier ModuleType to install when LibreNMS reports orphan
# child modules (e.g. CPM cards, mezzanines, MDAs) that have no matching NetBox
# bay because their parent carrier was never installed in NetBox.
#
# Import via: LibreNMS Plugin → Carrier Auto-Install Rules → Import
#
# Fields:
# manufacturer: Optional manufacturer name (exact). Empty = any vendor.
# device_type_pattern: Optional regex on device_type.model. Empty = any model.
# librenms_child_class: Exact entPhysicalClass of the orphan child (e.g. cpmModule).
# librenms_child_name_pattern: Regex on entPhysicalName of the orphan child.
# netbox_bay_name_pattern: Regex on candidate empty device-level bay name.
# carrier_module_type: NetBox ModuleType model (slug-style model field) to install.
# description: Optional description.
#
# Patterns use Python re.fullmatch() — they must match the entire string.
# When the chassis has at least one empty bay matching netbox_bay_name_pattern,
# an "Install Carrier" button appears on the module sync page (suggest-only,
# never auto-installed). Multiple matching empty bays produce one button each.

# Nokia 7750 SR-s chassis (e.g. SR-7s, SR-14s) report CPM cards in slots A/B
# but the physical CMA carrier that holds them is invisible to LibreNMS.
- manufacturer: Nokia
device_type_pattern: '^7750 SR-.*$'
librenms_child_class: cpmModule
librenms_child_name_pattern: '^Slot [AB]$'
netbox_bay_name_pattern: '^CMA$'
carrier_module_type: CMA2-7s
description: Install CMA2-7s carrier when CPM cards are reported orphaned
73 changes: 73 additions & 0 deletions contrib/device_type_mappings.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Device Type Mappings
#
# Maps LibreNMS hardware strings to NetBox device types.
# Import via: LibreNMS Plugin > Device Type Mappings > Import
#
# Fields:
# librenms_hardware — Hardware string exactly as shown in LibreNMS
# netbox_device_type — NetBox DeviceType (matched by model name or ID)
# description — Optional note
#
# The librenms_hardware value is matched case-insensitively.
# These mappings are checked BEFORE the built-in part_number/model fallback.

# Juniper — LibreNMS reports verbose marketing names
- librenms_hardware: "Juniper MX480 Internet Backbone Router"
netbox_device_type: "MX480"
description: "Juniper MX480 chassis"

- librenms_hardware: "Juniper MX960 Internet Backbone Router"
netbox_device_type: "MX960"
description: "Juniper MX960 chassis"

- librenms_hardware: "Juniper MX304 Edge Router"
netbox_device_type: "MX304"
description: "Juniper MX304 edge router"

- librenms_hardware: "JNP10008 [PTX10008]"
netbox_device_type: "PTX10008"
description: "Juniper PTX10008 core router"

- librenms_hardware: "JNP7100-32C [ACX7100-32C]"
netbox_device_type: "ACX7100-32C"
description: "Juniper ACX7100-32C"

- librenms_hardware: "JNP7024 [ACX7024]"
netbox_device_type: "ACX7024"
description: "Juniper ACX7024"

- librenms_hardware: "Juniper JNP10008 Internet Backbone Router"
netbox_device_type: "PTX10008"
description: "Juniper PTX10008 (alternate hardware string)"

- librenms_hardware: "Juniper VRR Internet Backbone Router"
netbox_device_type: "VRR"
description: "Juniper Virtual Route Reflector"

# Nokia — model string matches directly in most cases
- librenms_hardware: "7750 SR-7s"
netbox_device_type: "7750 SR-7s"
description: "Nokia 7750 SR-7s service router"

# Cisco — often matches by part_number but not always
- librenms_hardware: "WS-C4900M"
netbox_device_type: "WS-C4900M"
description: "Cisco Catalyst 4900M"

# Cisco IOS XR
- librenms_hardware: "8201-SYS"
netbox_device_type: "8201"
description: "Cisco 8201 (hardware string differs from model)"

# UfiSpace — LibreNMS reports SONiC/ONIE platform names
- librenms_hardware: "x86-64-ufispace-s9610-36d-r0"
netbox_device_type: "S9610-36D"
description: "UfiSpace S9610-36D"

- librenms_hardware: "x86-64-ufispace-s9610-46dx-r0"
netbox_device_type: "S9610-46DX"
description: "UfiSpace S9610-46DX"

- librenms_hardware: "x86-64-ufispace-s9700-53dx-r9"
netbox_device_type: "S9700-53DX"
description: "UfiSpace S9700-53DX"
75 changes: 75 additions & 0 deletions contrib/interface_type_mappings.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Interface Type Mappings
#
# Maps LibreNMS interface types (and optional speeds) to NetBox interface types.
# Import via: LibreNMS Plugin > Interface Mappings > Import
#
# Fields:
# librenms_type — IANA ifType string from LibreNMS (e.g. ethernetCsmacd)
# librenms_speed — Speed in Kbps (optional, null matches any speed)
# netbox_type — NetBox InterfaceTypeChoices slug
# description — Optional note
#
# Common NetBox interface type slugs:
# 1000base-t, 10gbase-t, 10gbase-x-sfpp, 25gbase-x-sfp28,
# 40gbase-x-qsfpp, 100gbase-x-qsfp28, 400gbase-x-qsfpdd,
# ieee802.11ax, lag, virtual, other

# WARNING: Speed-only matching cannot distinguish copper from fiber optics.
# For example, 1G ethernetCsmacd could be 1000base-t (copper), 1000base-x-sfp (fiber),
# or other media types. Review and adjust these mappings for your environment before
# importing — incorrect mappings will mislabel ports.

- librenms_type: ethernetCsmacd
librenms_speed: 1000000
netbox_type: 1000base-t
description: "1G Ethernet copper"

- librenms_type: ethernetCsmacd
librenms_speed: 10000000
netbox_type: 10gbase-x-sfpp
description: "10G Ethernet SFP+"

- librenms_type: ethernetCsmacd
librenms_speed: 25000000
netbox_type: 25gbase-x-sfp28
description: "25G Ethernet SFP28"

- librenms_type: ethernetCsmacd
librenms_speed: 40000000
netbox_type: 40gbase-x-qsfpp
description: "40G Ethernet QSFP+"

- librenms_type: ethernetCsmacd
librenms_speed: 100000000
netbox_type: 100gbase-x-qsfp28
description: "100G Ethernet QSFP28"

- librenms_type: ethernetCsmacd
librenms_speed: 400000000
netbox_type: 400gbase-x-qsfpdd
description: "400G Ethernet QSFP-DD"

- librenms_type: ieee8023adLag
librenms_speed:
netbox_type: lag
description: "LACP/LAG aggregation"

- librenms_type: propVirtual
librenms_speed:
netbox_type: virtual
description: "Virtual/loopback interface"

- librenms_type: softwareLoopback
librenms_speed:
netbox_type: virtual
description: "Software loopback"

- librenms_type: tunnel
librenms_speed:
netbox_type: virtual
description: "Tunnel interface"

- librenms_type: l2vlan
librenms_speed:
netbox_type: virtual
description: "VLAN interface"
Loading