From 4d01069f25ab08a4ab6cdb0b312bbbe1fcb96a2a Mon Sep 17 00:00:00 2001 From: Arthur Hanson Date: Mon, 28 Oct 2024 10:45:13 -0700 Subject: [PATCH] 10711 Add Scope to WirelessLAN --- netbox/wireless/constants.py | 5 ++ ...__location_wirelesslan__region_and_more.py | 77 +++++++++++++++++++ netbox/wireless/models.py | 22 +++++- 3 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 netbox/wireless/migrations/0011_wirelesslan__location_wirelesslan__region_and_more.py diff --git a/netbox/wireless/constants.py b/netbox/wireless/constants.py index 63de2b136..e12f87142 100644 --- a/netbox/wireless/constants.py +++ b/netbox/wireless/constants.py @@ -1,2 +1,7 @@ SSID_MAX_LENGTH = 32 # Per IEEE 802.11-2007 PSK_MAX_LENGTH = 64 + +# models values for ContentTypes which may be WirelessLAN scope types +WIRELESSLAN_SCOPE_TYPES = ( + 'region', 'sitegroup', 'site', 'location', +) diff --git a/netbox/wireless/migrations/0011_wirelesslan__location_wirelesslan__region_and_more.py b/netbox/wireless/migrations/0011_wirelesslan__location_wirelesslan__region_and_more.py new file mode 100644 index 000000000..759f1bb66 --- /dev/null +++ b/netbox/wireless/migrations/0011_wirelesslan__location_wirelesslan__region_and_more.py @@ -0,0 +1,77 @@ +# Generated by Django 5.0.9 on 2024-10-28 17:44 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('dcim', '0194_charfield_null_choices'), + ('wireless', '0010_charfield_null_choices'), + ] + + operations = [ + migrations.AddField( + model_name='wirelesslan', + name='_location', + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name='_%(class)ss', + to='dcim.location', + ), + ), + migrations.AddField( + model_name='wirelesslan', + name='_region', + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name='_%(class)ss', + to='dcim.region', + ), + ), + migrations.AddField( + model_name='wirelesslan', + name='_site', + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name='_%(class)ss', + to='dcim.site', + ), + ), + migrations.AddField( + model_name='wirelesslan', + name='_sitegroup', + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name='_%(class)ss', + to='dcim.sitegroup', + ), + ), + migrations.AddField( + model_name='wirelesslan', + name='scope_id', + field=models.PositiveBigIntegerField(blank=True, null=True), + ), + migrations.AddField( + model_name='wirelesslan', + name='scope_type', + field=models.ForeignKey( + blank=True, + limit_choices_to=models.Q(('model__in', ('region', 'sitegroup', 'site', 'location'))), + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='+', + to='contenttypes.contenttype', + ), + ), + ] diff --git a/netbox/wireless/models.py b/netbox/wireless/models.py index 88c60d494..1c15c13c7 100644 --- a/netbox/wireless/models.py +++ b/netbox/wireless/models.py @@ -1,9 +1,11 @@ +from django.contrib.contenttypes.fields import GenericForeignKey from django.core.exceptions import ValidationError from django.db import models from django.utils.translation import gettext_lazy as _ from dcim.choices import LinkStatusChoices from dcim.constants import WIRELESS_IFACE_TYPES +from dcim.models.mixins import CachedScopeMixin from netbox.models import NestedGroupModel, PrimaryModel from netbox.models.mixins import DistanceMixin from .choices import * @@ -71,7 +73,7 @@ class WirelessLANGroup(NestedGroupModel): verbose_name_plural = _('wireless LAN groups') -class WirelessLAN(WirelessAuthenticationBase, PrimaryModel): +class WirelessLAN(WirelessAuthenticationBase, CachedScopeMixin, PrimaryModel): """ A wireless network formed among an arbitrary number of access point and clients. """ @@ -106,8 +108,24 @@ class WirelessLAN(WirelessAuthenticationBase, PrimaryModel): blank=True, null=True ) + scope_type = models.ForeignKey( + to='contenttypes.ContentType', + on_delete=models.PROTECT, + limit_choices_to=models.Q(model__in=WIRELESSLAN_SCOPE_TYPES), + related_name='+', + blank=True, + null=True + ) + scope_id = models.PositiveBigIntegerField( + blank=True, + null=True + ) + scope = GenericForeignKey( + ct_field='scope_type', + fk_field='scope_id' + ) - clone_fields = ('ssid', 'group', 'tenant', 'description') + clone_fields = ('ssid', 'group', 'scope_type', 'scope_id', 'tenant', 'description') class Meta: ordering = ('ssid', 'pk')