feat: real Nautobot 3.x dev/test environment with CI integration - #11
Conversation
- development/docker-compose.yml: PostgreSQL + Redis + Nautobot 2.x stack - development/entrypoint.sh: Nautobot initialization (migrations, superuser, API token) - development/seed_nautobot.py: Seed script with test data matching mock - development/README.md: Setup documentation - tests/test_nautobot_live.py: Integration tests against real Nautobot (skipped by default) - .github/workflows/ci.yml: New integration-nautobot CI job Co-authored-by: Jackass4life <94110786+Jackass4life@users.noreply.github.com> Agent-Logs-Url: https://github.com/Jackass4life/Nautobot-maps/sessions/1ead7c82-0f4e-4031-9ec3-e5184f3efe1a
…seed script, document env vars Co-authored-by: Jackass4life <94110786+Jackass4life@users.noreply.github.com> Agent-Logs-Url: https://github.com/Jackass4life/Nautobot-maps/sessions/1ead7c82-0f4e-4031-9ec3-e5184f3efe1a
- Docker image: ghcr.io/nautobot/nautobot:2-py3.11 → 3-py3.12 - CI integration job: Python 3.11 → 3.12 - All docs/comments updated to reference Nautobot 3.x Co-authored-by: Jackass4life <94110786+Jackass4life@users.noreply.github.com> Agent-Logs-Url: https://github.com/Jackass4life/Nautobot-maps/sessions/6c444010-1302-4480-ba9b-c96c3aa44fd1
|
@copilot |
…3.0.9 The tag 3-py3.12 does not exist. Use the pinned 3.0.9 tag as specified. Co-authored-by: Jackass4life <94110786+Jackass4life@users.noreply.github.com> Agent-Logs-Url: https://github.com/Jackass4life/Nautobot-maps/sessions/4c9eee7e-70c9-4ccc-8fe0-3c1aa2255f21
Fixed in a3976d2 — changed the image from |
|
Check faildes: 2026-03-23T09:16:57.9706978Z Current runner version: '2.332.0' |
Nautobot 3.0.9 post_upgrade command does not accept --no-input. The container was exiting with code 2 due to unrecognized argument. Co-authored-by: Jackass4life <94110786+Jackass4life@users.noreply.github.com> Agent-Logs-Url: https://github.com/Jackass4life/Nautobot-maps/sessions/19540338-796d-478b-8286-7f736e39681c
The failure was |
|
New error at failing checks ↳ created dcim/platforms/ {'name': 'NX-OS'} |
In Nautobot 3.x, location types must declare which content types they allow. Without "dcim.device" in content_types, assigning a device to a location of that type fails with 400. Also add response body logging to _post() so future errors are easier to diagnose. Co-authored-by: Jackass4life <94110786+Jackass4life@users.noreply.github.com> Agent-Logs-Url: https://github.com/Jackass4life/Nautobot-maps/sessions/3eb971f6-8300-4f86-93dc-943adfe0643c
Fixed in 5090e44. The 3 failures were all caused by the same root cause: Nautobot 3.x returns nested related objects with a
Added a |
|
New issue. nautobot-1 | 11:34:59.635 INFO django.server : |
Nautobot 3.0.9 may return brief nested objects (tenant, status, manufacturer) that only contain id+url without a human-readable name/display field. _nested_str() handles the common cases but cannot extract a name when the object has no text key at all. Add _build_id_name_map() to pre-fetch all tenants/statuses/manufacturers and build UUID→name maps. get_locations() and get_location_detail() now fall back to these maps when _nested_str() returns empty. Also make _nested_str() handle plain-string inputs gracefully. All 61 existing tests still pass; mock tests get empty fallback maps (correct since mock data already has name/label keys). Co-authored-by: Jackass4life <94110786+Jackass4life@users.noreply.github.com> Agent-Logs-Url: https://github.com/Jackass4life/Nautobot-maps/sessions/4795cfa8-315f-4cbc-9e95-b251b190f08a
... Fixed in 753080f. The seeding is working (confirmed from the Nautobot logs you shared). The 3 test failures ( The fix adds |
|
One more issue but think we are closed now. =================================== FAILURES =================================== self = <tests.test_nautobot_live.TestLiveLocationDetail object at 0x7fc02b601430>
E AssertionError: assert '' == 'Cisco' tests/test_nautobot_live.py:183: AssertionError
|
…anufacturer lookup
In Nautobot 3.x, the brief nested device_type object inside device list
responses does not include a manufacturer sub-object. This caused
mfr_name to always be empty because dt.get("manufacturer") returned None.
Add _build_device_type_manufacturer_map() which pre-fetches all device
types once and returns a {device_type_id: manufacturer_name} map.
get_location_detail() now uses this map as a third-tier fallback:
1. _nested_str(mfr_obj, ...) - direct extraction if mfr is in device_type
2. mfr_map.get(mfr_id) - lookup by manufacturer UUID
3. dt_mfr_map.get(dt_id) - lookup via device type UUID (new, Nautobot 3.x)
All 61 existing tests still pass.
Co-authored-by: Jackass4life <94110786+Jackass4life@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Jackass4life/Nautobot-maps/sessions/8e4cb0a6-fe51-4b98-b12d-dc0ebc01a7c1
Fixed in 792c432. Root cause: in Nautobot 3.x, the brief nested Added
|
|
=================================== FAILURES =================================== self = <tests.test_nautobot_live.TestLiveLocationDetail object at 0x7efc219994c0>
E AssertionError: assert '' == 'Cisco' tests/test_nautobot_live.py:183: AssertionError
|
|
Following error: =================================== FAILURES =================================== self = <tests.test_nautobot_live.TestLiveLocationDetail object at 0x7efc219994c0>
E AssertionError: assert '' == 'Cisco' tests/test_nautobot_live.py:183: AssertionError
|
…builder
In Nautobot 3.0.9, the manufacturer sub-object returned inside
/api/dcim/device-types/ list responses is itself a brief nested object
containing only id+url (no name, no display). This caused
_build_device_type_manufacturer_map() to store empty strings and the
manufacturer field to remain '' even after the device-type lookup fix.
Updated _build_device_type_manufacturer_map() to also call
_build_id_name_map("dcim/manufacturers/") and use it as a fallback
when _nested_str() can't find a name directly in the manufacturer
sub-object. Now the resolution chain is:
1. _nested_str(mfr_obj, "name", "display") — inline in device_type
2. mfr_map.get(mfr_id) — UUID lookup via manufacturer endpoint
3. dt_mfr_map.get(dt_id) — device_type UUID → manufacturer name
All 61 existing tests still pass.
Co-authored-by: Jackass4life <94110786+Jackass4life@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Jackass4life/Nautobot-maps/sessions/315bcc3d-b421-43f0-8ad1-f3cfa141e983
Fixed in b79ffae. The previous fix resolved the device-type → manufacturer mapping but missed a secondary issue: Nautobot 3.0.9 also returns the Updated the function to also build a
|
|
New error: =================================== FAILURES =================================== self = <tests.test_nautobot_live.TestLiveLocationDetail object at 0x7f233d2dd850>
E AssertionError: assert '' == 'ASR1001-X' tests/test_nautobot_live.py:184: AssertionError
|
Nautobot 3.0.9 returns brief nested device_type objects (id+url only) inside device list responses, so _nested_str(device_type, "model", "display") always returned "". Renamed _build_device_type_manufacturer_map() to _build_device_type_maps() which now returns a tuple (dt_mfr_map, dt_model_map) by reading the "model" field from each device-type entry in /api/dcim/device-types/. The device_type field in get_location_detail() now falls back to dt_model_map.get(dt_id) after _nested_str(), completing the resolution: 1. _nested_str(dt, "model", "display") — inline in device response 2. dt_model_map.get(dt_id) — UUID lookup via device-types All 61 existing tests still pass. Co-authored-by: Jackass4life <94110786+Jackass4life@users.noreply.github.com> Agent-Logs-Url: https://github.com/Jackass4life/Nautobot-maps/sessions/4476f3b2-6bc6-4afe-849d-c8eeb2c1bcee
Fixed in 647f6d4. Same root cause as manufacturer: Nautobot 3.0.9 returns brief Renamed |
|
@copilot |
… in devices Co-authored-by: Jackass4life <94110786+Jackass4life@users.noreply.github.com> Agent-Logs-Url: https://github.com/Jackass4life/Nautobot-maps/sessions/4dd7254d-f6bf-4899-9ed8-15af35e75927
Fixed in ffbf5ea. Same pattern as manufacturer/device_type: Nautobot 3.0.9 returns the |
The mock Nautobot server doesn't surface real API behavior differences, leading to bugs only caught against a live instance. Sets up a real Nautobot 3.x stack for local dev and CI validation.
development/— Nautobot 3.x stackdocker-compose.yml— PostgreSQL 15 + Redis 7 +ghcr.io/nautobot/nautobot:3.0.9on port 8080. Optionalnautobot-mapsservice via--profile full.entrypoint.sh— Waits for PG, runs migrations, creates admin superuser + deterministic API token (aaaa-bbbb-cccc-dddd-eeee), starts Django dev server.seed_nautobot.py— Idempotent REST API seeder: 4 tenants, 4 location types, 8 locations with GPS, 14 devices, 9 ASNs. Mirrorsdemo/mock_nautobot.pydata exactly.tests/test_nautobot_live.py— live integration tests21 tests covering locations, device detail, proximity search, and e2e flow. Skipped by default unless env var is set:
.github/workflows/ci.yml— newintegration-nautobotjobRuns in parallel with the existing mock-based matrix. Starts the real Nautobot 3.x stack via
docker compose up -d --wait, seeds data, runs live tests. Dumps Nautobot logs on failure.Doc/comment updates
README.md— Nautobot version recommendation updated to v3.xapp.py— Removed stale "Nautobot 2.x" comment on ipam/asns endpointOriginal prompt
📱 Kick off Copilot coding agent tasks wherever you are with GitHub Mobile, available on iOS and Android.