From effe9204af4d5bb07dff3d2e9c36ce09470a9c80 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Date: Mon, 28 Oct 2024 09:08:17 -0700 Subject: [PATCH] 7699 review changes --- netbox/dcim/models/devices.py | 7 ++++++ netbox/virtualization/models/clusters.py | 27 ++++++++++++++++-------- netbox/virtualization/tables/clusters.py | 14 ++++++------ 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/netbox/dcim/models/devices.py b/netbox/dcim/models/devices.py index 3efb97ce7..47f4ee6c9 100644 --- a/netbox/dcim/models/devices.py +++ b/netbox/dcim/models/devices.py @@ -965,6 +965,13 @@ class Device( ) }) + if self.cluster and self.cluster._location is not None and self.cluster._location != self.location: + raise ValidationError({ + 'cluster': _("The assigned cluster belongs to a different location ({location})").format( + site=self.cluster._location + ) + }) + # Validate virtual chassis assignment if self.virtual_chassis and self.vc_position is None: raise ValidationError({ diff --git a/netbox/virtualization/models/clusters.py b/netbox/virtualization/models/clusters.py index f1ab2b3da..ad2aaedc7 100644 --- a/netbox/virtualization/models/clusters.py +++ b/netbox/virtualization/models/clusters.py @@ -135,19 +135,28 @@ class Cluster(ContactsMixin, CachedScopeMixin, PrimaryModel): def clean(self): super().clean() - site = None + site = location = None if self.scope_type: scope_type = self.scope_type.model_class() if scope_type == apps.get_model('dcim', 'site'): site = self.scope elif scope_type == apps.get_model('dcim', 'location'): - site = self.scope.site + location = self.scope + site = location.site # If the Cluster is assigned to a Site, verify that all host Devices belong to that Site. - if not self._state.adding and site: - if nonsite_devices := Device.objects.filter(cluster=self).exclude(site=site).count(): - raise ValidationError({ - 'site': _( - "{count} devices are assigned as hosts for this cluster but are not in site {site}" - ).format(count=nonsite_devices, site=site) - }) + if not self._state.adding: + if site: + if nonsite_devices := Device.objects.filter(cluster=self).exclude(site=site).count(): + raise ValidationError({ + 'scope': _( + "{count} devices are assigned as hosts for this cluster but are not in site {site}" + ).format(count=nonsite_devices, site=site) + }) + if location: + if nonlocation_devices := Device.objects.filter(cluster=self).exclude(location=location).count(): + raise ValidationError({ + 'scope': _( + "{count} devices are assigned as hosts for this cluster but are not in location {location}" + ).format(count=nonlocation_devices, location=location) + }) diff --git a/netbox/virtualization/tables/clusters.py b/netbox/virtualization/tables/clusters.py index 28a2b00dc..91807e35b 100644 --- a/netbox/virtualization/tables/clusters.py +++ b/netbox/virtualization/tables/clusters.py @@ -73,10 +73,12 @@ class ClusterTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable): status = columns.ChoiceFieldColumn( verbose_name=_('Status'), ) - site = tables.Column( - verbose_name=_('Site'), - linkify=True, - accessor='_site' + scope_type = columns.ContentTypeColumn( + verbose_name=_('Scope Type'), + ) + scope = tables.Column( + verbose_name=_('Scope'), + linkify=True ) device_count = columns.LinkedCountColumn( viewname='dcim:device_list', @@ -98,7 +100,7 @@ class ClusterTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable): class Meta(NetBoxTable.Meta): model = Cluster fields = ( - 'pk', 'id', 'name', 'type', 'group', 'status', 'tenant', 'tenant_group', 'site', 'description', 'comments', - 'device_count', 'vm_count', 'contacts', 'tags', 'created', 'last_updated', + 'pk', 'id', 'name', 'type', 'group', 'status', 'tenant', 'tenant_group', 'scope', 'scope_type', 'description', + 'comments', 'device_count', 'vm_count', 'contacts', 'tags', 'created', 'last_updated', ) default_columns = ('pk', 'name', 'type', 'group', 'status', 'tenant', 'site', 'device_count', 'vm_count')