diff --git a/netboxlabs/diode/sdk/ingester.py b/netboxlabs/diode/sdk/ingester.py index c37d7c0..b742707 100644 --- a/netboxlabs/diode/sdk/ingester.py +++ b/netboxlabs/diode/sdk/ingester.py @@ -7007,7 +7007,10 @@ def __new__( if site is not None: if device is not None and not device.HasField("site"): device.site.CopyFrom(site) - if cluster is not None and not cluster.HasField("scope_site"): + # scope_site shares a oneof with scope_location/region/site_group, so + # HasField("scope_site") is False while a sibling holds the scope and + # CopyFrom would silently clear it. + if cluster is not None and not cluster.WhichOneof("scope"): cluster.scope_site.CopyFrom(site) if role is not None: if device is not None and not device.HasField("role"): diff --git a/tests/test_ingester.py b/tests/test_ingester.py index 1c9b5b8..853a62a 100644 --- a/tests/test_ingester.py +++ b/tests/test_ingester.py @@ -43,6 +43,7 @@ Prefix, Role, Site, + SiteGroup, Tag, VirtualDisk, VMInterface, @@ -608,6 +609,22 @@ def test_virtual_machine_instantiation_with_cluster_without_site(): assert virtual_machine.cluster.scope_site.name == "Site1" +def test_virtual_machine_instantiation_keeps_cluster_scope_site_group(): + """Check VirtualMachine leaves a cluster that is already scoped to a SiteGroup untouched.""" + cluster = Cluster(name="gc-us-east1", scope_site_group=SiteGroup(name="SiteGroup1")) + + virtual_machine = VirtualMachine( + name="vm1", + cluster=cluster, + site=Site(name="Site1"), + ) + + assert cluster.WhichOneof("scope") == "scope_site_group" + assert cluster.scope_site_group.name == "SiteGroup1" + assert virtual_machine.cluster.WhichOneof("scope") == "scope_site_group" + assert virtual_machine.cluster.scope_site_group.name == "SiteGroup1" + + def test_virtual_disk_instantiation_with_all_fields(): """Check VirtualDisk instantiation with all fields.""" virtual_disk = VirtualDisk(