From 38f6d22d2d7ac412efa9b50ef4f598d17726e0a9 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 12 Oct 2021 13:48:06 -0400 Subject: [PATCH] Enable attachment of wireless interfaces to SSIDs --- netbox/dcim/forms/models.py | 10 ++++++-- netbox/dcim/migrations/0136_wireless.py | 6 +++++ netbox/dcim/models/device_components.py | 6 +++++ netbox/templates/dcim/interface.html | 27 ++++++++++++++++++++++ netbox/templates/dcim/interface_edit.html | 1 + netbox/wireless/migrations/0001_initial.py | 1 - netbox/wireless/models.py | 10 +++++++- netbox/wireless/tables.py | 7 +++--- netbox/wireless/views.py | 6 ++--- 9 files changed, 63 insertions(+), 11 deletions(-) diff --git a/netbox/dcim/forms/models.py b/netbox/dcim/forms/models.py index 435fab309..2a6dc1f6f 100644 --- a/netbox/dcim/forms/models.py +++ b/netbox/dcim/forms/models.py @@ -16,6 +16,7 @@ from utilities.forms import ( SlugField, StaticSelect, ) from virtualization.models import Cluster, ClusterGroup +from wireless.models import SSID from .common import InterfaceCommonForm __all__ = ( @@ -1068,6 +1069,11 @@ class InterfaceForm(BootstrapMixin, InterfaceCommonForm, CustomFieldModelForm): 'type': 'lag', } ) + ssids = DynamicModelMultipleChoiceField( + queryset=SSID.objects.all(), + required=False, + label='SSIDs' + ) vlan_group = DynamicModelChoiceField( queryset=VLANGroup.objects.all(), required=False, @@ -1098,8 +1104,8 @@ class InterfaceForm(BootstrapMixin, InterfaceCommonForm, CustomFieldModelForm): model = Interface fields = [ 'device', 'name', 'label', 'type', 'enabled', 'parent', 'lag', 'mac_address', 'wwn', 'mtu', 'mgmt_only', - 'mark_connected', 'description', 'mode', 'rf_channel', 'rf_channel_width', 'untagged_vlan', 'tagged_vlans', - 'tags', + 'mark_connected', 'description', 'mode', 'rf_channel', 'rf_channel_width', 'ssids', 'untagged_vlan', + 'tagged_vlans', 'tags', ] widgets = { 'device': forms.HiddenInput(), diff --git a/netbox/dcim/migrations/0136_wireless.py b/netbox/dcim/migrations/0136_wireless.py index 429a72694..0a1d15365 100644 --- a/netbox/dcim/migrations/0136_wireless.py +++ b/netbox/dcim/migrations/0136_wireless.py @@ -4,6 +4,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ + ('wireless', '__first__'), ('dcim', '0135_location_tenant'), ] @@ -18,4 +19,9 @@ class Migration(migrations.Migration): name='rf_channel_width', field=models.PositiveSmallIntegerField(blank=True, null=True), ), + migrations.AddField( + model_name='interface', + name='ssids', + field=models.ManyToManyField(blank=True, related_name='interfaces', to='wireless.SSID'), + ), ] diff --git a/netbox/dcim/models/device_components.py b/netbox/dcim/models/device_components.py index 4e0d65f86..5e3e7e6db 100644 --- a/netbox/dcim/models/device_components.py +++ b/netbox/dcim/models/device_components.py @@ -529,6 +529,12 @@ class Interface(ComponentModel, BaseInterface, CableTermination, PathEndpoint): null=True, verbose_name='Channel width' ) + ssids = models.ManyToManyField( + to='wireless.SSID', + related_name='interfaces', + blank=True, + verbose_name='SSIDs' + ) untagged_vlan = models.ForeignKey( to='ipam.VLAN', on_delete=models.SET_NULL, diff --git a/netbox/templates/dcim/interface.html b/netbox/templates/dcim/interface.html index 3283aac4f..bc4fc23e2 100644 --- a/netbox/templates/dcim/interface.html +++ b/netbox/templates/dcim/interface.html @@ -258,6 +258,33 @@ {% endif %} + {% if object.is_wireless %} +
+
SSIDs
+
+ + + + + + + + {% for ssid in object.ssids.all %} + + + + {% empty %} + + + + {% endfor %} + +
Name
+ {{ ssid.name }} +
None
+
+
+ {% endif %} {% if object.is_lag %}
LAG Members
diff --git a/netbox/templates/dcim/interface_edit.html b/netbox/templates/dcim/interface_edit.html index e91c74d31..9fc752432 100644 --- a/netbox/templates/dcim/interface_edit.html +++ b/netbox/templates/dcim/interface_edit.html @@ -36,6 +36,7 @@
{% render_field form.rf_channel %} {% render_field form.rf_channel_width %} + {% render_field form.ssids %} {% endif %} diff --git a/netbox/wireless/migrations/0001_initial.py b/netbox/wireless/migrations/0001_initial.py index b0011dad9..78d1dfc73 100644 --- a/netbox/wireless/migrations/0001_initial.py +++ b/netbox/wireless/migrations/0001_initial.py @@ -9,7 +9,6 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('dcim', '0136_wireless'), ('extras', '0062_clear_secrets_changelog'), ('ipam', '0050_iprange'), ] diff --git a/netbox/wireless/models.py b/netbox/wireless/models.py index 5bb964345..2bdcecd79 100644 --- a/netbox/wireless/models.py +++ b/netbox/wireless/models.py @@ -1,7 +1,8 @@ from django.db import models +from django.urls import reverse from extras.utils import extras_features -from netbox.models import PrimaryModel +from netbox.models import BigIDModel, PrimaryModel from utilities.querysets import RestrictedQuerySet __all__ = ( @@ -9,6 +10,10 @@ __all__ = ( ) +# +# SSIDs +# + @extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks') class SSID(PrimaryModel): """ @@ -38,3 +43,6 @@ class SSID(PrimaryModel): def __str__(self): return self.name + + def get_absolute_url(self): + return reverse('wireless:ssid', args=[self.pk]) diff --git a/netbox/wireless/tables.py b/netbox/wireless/tables.py index 846296bb4..9d3705549 100644 --- a/netbox/wireless/tables.py +++ b/netbox/wireless/tables.py @@ -10,9 +10,8 @@ __all__ = ( class SSIDTable(BaseTable): pk = ToggleColumn() - id = tables.Column( - linkify=True, - verbose_name='ID' + name = tables.Column( + linkify=True ) tags = TagColumn( url_name='dcim:cable_list' @@ -20,5 +19,5 @@ class SSIDTable(BaseTable): class Meta(BaseTable.Meta): model = SSID - fields = ('pk', 'id', 'name', 'description', 'vlan') + fields = ('pk', 'name', 'description', 'vlan') default_columns = ('pk', 'name', 'description', 'vlan') diff --git a/netbox/wireless/views.py b/netbox/wireless/views.py index b0d1f5156..b741330b7 100644 --- a/netbox/wireless/views.py +++ b/netbox/wireless/views.py @@ -15,7 +15,7 @@ class SSIDListView(generic.ObjectListView): class SSIDView(generic.ObjectView): - queryset = SSID.objects.prefetch_related('power_panel', 'rack') + queryset = SSID.objects.all() class SSIDEditView(generic.ObjectEditView): @@ -34,13 +34,13 @@ class SSIDBulkImportView(generic.BulkImportView): class SSIDBulkEditView(generic.BulkEditView): - queryset = SSID.objects.prefetch_related('power_panel', 'rack') + queryset = SSID.objects.all() filterset = filtersets.SSIDFilterSet table = tables.SSIDTable form = forms.SSIDBulkEditForm class SSIDBulkDeleteView(generic.BulkDeleteView): - queryset = SSID.objects.prefetch_related('power_panel', 'rack') + queryset = SSID.objects.all() filterset = filtersets.SSIDFilterSet table = tables.SSIDTable