Skip to content

fix: scope a cluster with the site object so NetBox accepts it - #566

Merged
semx merged 1 commit into
developmentfrom
fix/cluster-scope-id
Sep 10, 2026
Merged

semx merged 1 commit into
developmentfrom
fix/cluster-scope-id

Conversation

@semx

@semx semx commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

Found this by running development against a real NetBox 4.4.5 rather than the test inventory, and it is bad: with cluster_site_relation set, no cluster can be created at all on NetBox 4.2 or newer.

add_cluster() puts {"name": <site>} into scope_id. Everything else in the payload gets turned into an id by get_nb_reference(), but a plain dict is passed through, so NetBox answers:

POST /api/virtualization/clusters/ 400
{'scope_id': ['A valid integer is required.']}
data: {..., 'scope_type': 'dcim.site', 'scope_id': {'name': 'e2e-site'}}

The cluster is never created, and every host and VM that referenced it then fails with "updated item cluster ... could not be fully resolved". On the vc001 capture that was 43 errors and 0 clusters, while 34 VMs and 3 hosts were still written, pointing at nothing.

Two changes. add_cluster() now puts the site object itself into scope_id. And NBCluster gets the scope_id/scope_type handling NBVLANGroup already has: the data model lists the allowed scope classes, and resolve_relations() calls resolve_scoped_relations(). Without that second part NetBox hands the scope back as an id, the id never matches the object, and every run logs scope_id changed from '2' to 'e2e-site' and patches the cluster again.

Measured on NetBox 4.4.5 with the vc001 capture: before, 0 clusters and 43 errors; after, the cluster exists scoped to the site, hosts and VMs attach to it, 0 errors, and two further runs change nothing. cluster_site_relation = .* = <NONE> is also clean, cluster unscoped, idempotent.

tests/test_cluster_scope.py covers both halves and both fail on development: scope_id ends up a dict after a sync, and a scope read back as an id is not resolved. Suite 141.

If it is useful I can turn the throwaway stand I used for this - NetBox in docker plus vcsim, wired to netbox-sync.py - into something reusable. There is no end-to-end coverage against a real NetBox today and this is the kind of thing it catches.

@semx
semx requested a review from bb-Ricardo as a code owner September 10, 2026 08:09
@semx
semx merged commit 7c00552 into development Sep 10, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant