Repository: netbox-community/netbox
Pull request: 15020 Update assigned VMs site when move cluster
### Fixes: #15020 

Update assigned VMs site when move cluster to new site.

Problem statement:
VM site not updated when changing cluster site
### Deployment Type

NetBox Cloud

### NetBox Version

v3.7.1

### Python Version

3.11

### Steps to Reproduce

1. Create two sites, Site A and Site B.
2. Create a new virtualization cluster (of any type) and assign it to Site A.
3. Create a new virtual machine in the cluster. Do not assign a site when creating the VM.
4. Verify that the new VM is assigned to Site A.
5. Edit the cluster and change its site to Site B.
6. Check the VM's assigned site.

### Expected Behavior

The VM's site should be updated to Site B.

### Observed Behavior

The VM is still assigned to Site A, whereas its cluster is assigned to Site B.

When attempting to save the VM, validation fails, complaining that its site and its cluster's site do not match.

Hints from issue discussion:

Commit message: 15020 call super

Patch to review:
diff --git a/netbox/virtualization/models/clusters.py b/netbox/virtualization/models/clusters.py
index f8acc4c3611..1bfa6b42186 100644
--- a/netbox/virtualization/models/clusters.py
+++ b/netbox/virtualization/models/clusters.py
@@ -141,3 +141,8 @@ def clean(self):
                         "{count} devices are assigned as hosts for this cluster but are not in site {site}"
                     ).format(count=nonsite_devices, site=self.site)
                 })
+
+    def save(self, *args, **kwargs):
+        # Update Site for all assigned virtual machines
+        super().save(*args, **kwargs)
+        self.virtual_machines.all().update(site=self.site)


Code review comments:
diff_hunk: @@ -141,3 +141,8 @@ def clean(self):
                         "{count} devices are assigned as hosts for this cluster but are not in site {site}"
                     ).format(count=nonsite_devices, site=self.site)
                 })
+
+    def save(self, *args, **kwargs):
+        # Update Site for all assigned virtual machines
+        super().save(*args, **kwargs)
+        self.virtual_machines.all().update(site=self.site)
path: netbox/virtualization/models/clusters.py
text: @user1:
In the interest of performance, we should apply this change only when the cluster's assigned site has changed. IIRC we have a pattern where we do this for some other models (though I can't recall which) by recording the field's initial value under `__init__()`, and then comparing the current value to it under `save()`.

 (Also, `.all()` can be omitted from the queryset.)

@user1:
Here we go, found [an example](https://github.com/netbox-community/netbox/blob/1a9149d7d44de01358207f1b8b74145ecc8e33f7/netbox/dcim/models/device_components.py#L84-L88).

@user1:
Actually, a better solution might be to register `VirtualMachine.site` as a [denormalized field](https://github.com/netbox-community/netbox/blob/develop/netbox/netbox/denormalized.py), to ensure that it gets updated automatically.

@author:
changed to denomalized field.