Closes #5892: Introduce SiteGroup model (#5937)

* Initial work on #5892

* Add site group selection to object edit forms

* Add documentation for site groups

* Changelog for #5892

* Finish application of site groups to config context
This commit is contained in:
Jeremy Stretch
2021-03-08 13:28:53 -05:00
committed by GitHub
parent 1c66733b8a
commit 79b19821f6
44 changed files with 1388 additions and 232 deletions
+27 -1
View File
@@ -1,7 +1,7 @@
import django_filters
from django.db.models import Q
from dcim.models import DeviceRole, Platform, Region, Site
from dcim.models import DeviceRole, Platform, Region, Site, SiteGroup
from extras.filters import CustomFieldModelFilterSet, CreatedUpdatedFilterSet, LocalConfigContextFilterSet
from tenancy.filters import TenancyFilterSet
from utilities.filters import (
@@ -52,6 +52,19 @@ class ClusterFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSe
to_field_name='slug',
label='Region (slug)',
)
site_group_id = TreeNodeMultipleChoiceFilter(
queryset=SiteGroup.objects.all(),
field_name='site__group',
lookup_expr='in',
label='Site group (ID)',
)
site_group = TreeNodeMultipleChoiceFilter(
queryset=SiteGroup.objects.all(),
field_name='site__group',
lookup_expr='in',
to_field_name='slug',
label='Site group (slug)',
)
site_id = django_filters.ModelMultipleChoiceFilter(
queryset=Site.objects.all(),
label='Site (ID)',
@@ -151,6 +164,19 @@ class VirtualMachineFilterSet(
to_field_name='slug',
label='Region (slug)',
)
site_group_id = TreeNodeMultipleChoiceFilter(
queryset=SiteGroup.objects.all(),
field_name='cluster__site__group',
lookup_expr='in',
label='Site group (ID)',
)
site_group = TreeNodeMultipleChoiceFilter(
queryset=SiteGroup.objects.all(),
field_name='cluster__site__group',
lookup_expr='in',
to_field_name='slug',
label='Site group (slug)',
)
site_id = django_filters.ModelMultipleChoiceFilter(
field_name='cluster__site',
queryset=Site.objects.all(),
+25 -6
View File
@@ -6,7 +6,7 @@ from django.utils.translation import gettext as _
from dcim.choices import InterfaceModeChoices
from dcim.constants import INTERFACE_MTU_MAX, INTERFACE_MTU_MIN
from dcim.forms import InterfaceCommonForm, INTERFACE_MODE_HELP_TEXT
from dcim.models import Device, DeviceRole, Platform, Rack, Region, Site
from dcim.models import Device, DeviceRole, Platform, Rack, Region, Site, SiteGroup
from extras.forms import (
AddRemoveTagsForm, CustomFieldBulkEditForm, CustomFieldModelCSVForm, CustomFieldModelForm, CustomFieldFilterForm,
)
@@ -87,11 +87,19 @@ class ClusterForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
'sites': '$site'
}
)
site_group = DynamicModelChoiceField(
queryset=SiteGroup.objects.all(),
required=False,
initial_params={
'sites': '$site'
}
)
site = DynamicModelChoiceField(
queryset=Site.objects.all(),
required=False,
query_params={
'region_id': '$region'
'region_id': '$region',
'group_id': '$site_group',
}
)
comments = CommentField()
@@ -103,10 +111,10 @@ class ClusterForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
class Meta:
model = Cluster
fields = (
'name', 'type', 'group', 'tenant', 'region', 'site', 'comments', 'tags',
'name', 'type', 'group', 'tenant', 'region', 'site_group', 'site', 'comments', 'tags',
)
fieldsets = (
('Cluster', ('name', 'type', 'group', 'region', 'site', 'tags')),
('Cluster', ('name', 'type', 'group', 'region', 'site_group', 'site', 'tags')),
('Tenancy', ('tenant_group', 'tenant')),
)
@@ -162,11 +170,16 @@ class ClusterBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEdit
queryset=Region.objects.all(),
required=False,
)
site_group = DynamicModelChoiceField(
queryset=SiteGroup.objects.all(),
required=False,
)
site = DynamicModelChoiceField(
queryset=Site.objects.all(),
required=False,
query_params={
'region_id': '$region'
'region_id': '$region',
'group_id': '$site_group',
}
)
comments = CommentField(
@@ -223,11 +236,17 @@ class ClusterAddDevicesForm(BootstrapMixin, forms.Form):
required=False,
null_option='None'
)
site_group = DynamicModelChoiceField(
queryset=SiteGroup.objects.all(),
required=False,
null_option='None'
)
site = DynamicModelChoiceField(
queryset=Site.objects.all(),
required=False,
query_params={
'region_id': '$region'
'region_id': '$region',
'group_id': '$site_group',
}
)
rack = DynamicModelChoiceField(
+37 -9
View File
@@ -1,6 +1,6 @@
from django.test import TestCase
from dcim.models import DeviceRole, Platform, Region, Site
from dcim.models import DeviceRole, Platform, Region, Site, SiteGroup
from ipam.models import IPAddress
from tenancy.models import Tenant, TenantGroup
from virtualization.choices import *
@@ -96,14 +96,21 @@ class ClusterTestCase(TestCase):
Region(name='Test Region 2', slug='test-region-2'),
Region(name='Test Region 3', slug='test-region-3'),
)
# Can't use bulk_create for models with MPTT fields
for r in regions:
r.save()
site_groups = (
SiteGroup(name='Site Group 1', slug='site-group-1'),
SiteGroup(name='Site Group 2', slug='site-group-2'),
SiteGroup(name='Site Group 3', slug='site-group-3'),
)
for site_group in site_groups:
site_group.save()
sites = (
Site(name='Test Site 1', slug='test-site-1', region=regions[0]),
Site(name='Test Site 2', slug='test-site-2', region=regions[1]),
Site(name='Test Site 3', slug='test-site-3', region=regions[2]),
Site(name='Test Site 1', slug='test-site-1', region=regions[0], group=site_groups[0]),
Site(name='Test Site 2', slug='test-site-2', region=regions[1], group=site_groups[1]),
Site(name='Test Site 3', slug='test-site-3', region=regions[2], group=site_groups[2]),
)
Site.objects.bulk_create(sites)
@@ -144,6 +151,13 @@ class ClusterTestCase(TestCase):
params = {'region': [regions[0].slug, regions[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_site_group(self):
site_groups = SiteGroup.objects.all()[:2]
params = {'site_group_id': [site_groups[0].pk, site_groups[1].pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
params = {'site_group': [site_groups[0].slug, site_groups[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_site(self):
sites = Site.objects.all()[:2]
params = {'site_id': [sites[0].pk, sites[1].pk]}
@@ -206,14 +220,21 @@ class VirtualMachineTestCase(TestCase):
Region(name='Test Region 2', slug='test-region-2'),
Region(name='Test Region 3', slug='test-region-3'),
)
# Can't use bulk_create for models with MPTT fields
for r in regions:
r.save()
site_groups = (
SiteGroup(name='Site Group 1', slug='site-group-1'),
SiteGroup(name='Site Group 2', slug='site-group-2'),
SiteGroup(name='Site Group 3', slug='site-group-3'),
)
for site_group in site_groups:
site_group.save()
sites = (
Site(name='Test Site 1', slug='test-site-1', region=regions[0]),
Site(name='Test Site 2', slug='test-site-2', region=regions[1]),
Site(name='Test Site 3', slug='test-site-3', region=regions[2]),
Site(name='Test Site 1', slug='test-site-1', region=regions[0], group=site_groups[0]),
Site(name='Test Site 2', slug='test-site-2', region=regions[1], group=site_groups[1]),
Site(name='Test Site 3', slug='test-site-3', region=regions[2], group=site_groups[2]),
)
Site.objects.bulk_create(sites)
@@ -329,6 +350,13 @@ class VirtualMachineTestCase(TestCase):
params = {'region': [regions[0].slug, regions[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_site_group(self):
site_groups = SiteGroup.objects.all()[:2]
params = {'site_group_id': [site_groups[0].pk, site_groups[1].pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
params = {'site_group': [site_groups[0].slug, site_groups[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_site(self):
sites = Site.objects.all()[:2]
params = {'site_id': [sites[0].pk, sites[1].pk]}