mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-15 19:52:52 -06:00
Add rf_role to Interface
This commit is contained in:
parent
01f791a44e
commit
438b4b4758
@ -632,6 +632,7 @@ class InterfaceSerializer(PrimaryModelSerializer, LinkTerminationSerializer, Con
|
|||||||
parent = NestedInterfaceSerializer(required=False, allow_null=True)
|
parent = NestedInterfaceSerializer(required=False, allow_null=True)
|
||||||
lag = NestedInterfaceSerializer(required=False, allow_null=True)
|
lag = NestedInterfaceSerializer(required=False, allow_null=True)
|
||||||
mode = ChoiceField(choices=InterfaceModeChoices, allow_blank=True, required=False)
|
mode = ChoiceField(choices=InterfaceModeChoices, allow_blank=True, required=False)
|
||||||
|
rf_role = ChoiceField(choices=WirelessRoleChoices, required=False, allow_null=True)
|
||||||
rf_channel = ChoiceField(choices=WirelessChannelChoices, required=False)
|
rf_channel = ChoiceField(choices=WirelessChannelChoices, required=False)
|
||||||
rf_channel_width = ChoiceField(choices=WirelessChannelWidthChoices, required=False, allow_null=True)
|
rf_channel_width = ChoiceField(choices=WirelessChannelWidthChoices, required=False, allow_null=True)
|
||||||
untagged_vlan = NestedVLANSerializer(required=False, allow_null=True)
|
untagged_vlan = NestedVLANSerializer(required=False, allow_null=True)
|
||||||
@ -648,7 +649,7 @@ class InterfaceSerializer(PrimaryModelSerializer, LinkTerminationSerializer, Con
|
|||||||
model = Interface
|
model = Interface
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'url', 'display', 'device', 'name', 'label', 'type', 'enabled', 'parent', 'lag', 'mtu', 'mac_address',
|
'id', 'url', 'display', 'device', 'name', 'label', 'type', 'enabled', 'parent', 'lag', 'mtu', 'mac_address',
|
||||||
'wwn', 'mgmt_only', 'description', 'mode', 'rf_channel', 'rf_channel_width', 'untagged_vlan',
|
'wwn', 'mgmt_only', 'description', 'mode', 'rf_role', 'rf_channel', 'rf_channel_width', 'untagged_vlan',
|
||||||
'tagged_vlans', 'mark_connected', 'cable', 'link_peer', 'link_peer_type', 'connected_endpoint',
|
'tagged_vlans', 'mark_connected', 'cable', 'link_peer', 'link_peer_type', 'connected_endpoint',
|
||||||
'connected_endpoint_type', 'connected_endpoint_reachable', 'tags', 'custom_fields', 'created',
|
'connected_endpoint_type', 'connected_endpoint_reachable', 'tags', 'custom_fields', 'created',
|
||||||
'last_updated', 'count_ipaddresses', '_occupied',
|
'last_updated', 'count_ipaddresses', '_occupied',
|
||||||
|
@ -1139,6 +1139,16 @@ class CableLengthUnitChoices(ChoiceSet):
|
|||||||
# Wireless
|
# Wireless
|
||||||
#
|
#
|
||||||
|
|
||||||
|
class WirelessRoleChoices(ChoiceSet):
|
||||||
|
ROLE_AP = 'ap'
|
||||||
|
ROLE_STATION = 'station'
|
||||||
|
|
||||||
|
CHOICES = (
|
||||||
|
(ROLE_AP, 'Access point'),
|
||||||
|
(ROLE_STATION, 'Station'),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class WirelessChannelChoices(ChoiceSet):
|
class WirelessChannelChoices(ChoiceSet):
|
||||||
CHANNEL_AUTO = 'auto'
|
CHANNEL_AUTO = 'auto'
|
||||||
|
|
||||||
|
@ -991,8 +991,8 @@ class InterfaceFilterSet(PrimaryModelFilterSet, DeviceComponentFilterSet, CableT
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Interface
|
model = Interface
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'name', 'label', 'type', 'enabled', 'mtu', 'mgmt_only', 'mode', 'rf_channel', 'rf_channel_width',
|
'id', 'name', 'label', 'type', 'enabled', 'mtu', 'mgmt_only', 'mode', 'rf_role', 'rf_channel',
|
||||||
'description',
|
'rf_channel_width', 'description',
|
||||||
]
|
]
|
||||||
|
|
||||||
def filter_device(self, queryset, name, value):
|
def filter_device(self, queryset, name, value):
|
||||||
|
@ -926,7 +926,7 @@ class PowerOutletBulkEditForm(
|
|||||||
class InterfaceBulkEditForm(
|
class InterfaceBulkEditForm(
|
||||||
form_from_model(Interface, [
|
form_from_model(Interface, [
|
||||||
'label', 'type', 'parent', 'lag', 'mac_address', 'wwn', 'mtu', 'mgmt_only', 'mark_connected', 'description',
|
'label', 'type', 'parent', 'lag', 'mac_address', 'wwn', 'mtu', 'mgmt_only', 'mark_connected', 'description',
|
||||||
'mode', 'rf_channel', 'rf_channel_width',
|
'mode', 'rf_role', 'rf_channel', 'rf_channel_width',
|
||||||
]),
|
]),
|
||||||
BootstrapMixin,
|
BootstrapMixin,
|
||||||
AddRemoveTagsForm,
|
AddRemoveTagsForm,
|
||||||
|
@ -579,12 +579,17 @@ class InterfaceCSVForm(CustomFieldModelCSVForm):
|
|||||||
required=False,
|
required=False,
|
||||||
help_text='IEEE 802.1Q operational mode (for L2 interfaces)'
|
help_text='IEEE 802.1Q operational mode (for L2 interfaces)'
|
||||||
)
|
)
|
||||||
|
rf_role = CSVChoiceField(
|
||||||
|
choices=WirelessRoleChoices,
|
||||||
|
required=False,
|
||||||
|
help_text='Wireless role (AP/station)'
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Interface
|
model = Interface
|
||||||
fields = (
|
fields = (
|
||||||
'device', 'name', 'label', 'parent', 'lag', 'type', 'enabled', 'mark_connected', 'mac_address', 'wwn',
|
'device', 'name', 'label', 'parent', 'lag', 'type', 'enabled', 'mark_connected', 'mac_address', 'wwn',
|
||||||
'mtu', 'mgmt_only', 'description', 'mode', 'rf_channel', 'rf_channel_width',
|
'mtu', 'mgmt_only', 'description', 'mode', 'rf_role', 'rf_channel', 'rf_channel_width',
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -963,7 +963,7 @@ class InterfaceFilterForm(DeviceComponentFilterForm):
|
|||||||
field_groups = [
|
field_groups = [
|
||||||
['q', 'tag'],
|
['q', 'tag'],
|
||||||
['name', 'label', 'type', 'enabled', 'mgmt_only', 'mac_address', 'wwn'],
|
['name', 'label', 'type', 'enabled', 'mgmt_only', 'mac_address', 'wwn'],
|
||||||
['rf_channel', 'rf_channel_width'],
|
['rf_role', 'rf_channel', 'rf_channel_width'],
|
||||||
['region_id', 'site_group_id', 'site_id', 'location_id', 'device_id'],
|
['region_id', 'site_group_id', 'site_id', 'location_id', 'device_id'],
|
||||||
]
|
]
|
||||||
type = forms.MultipleChoiceField(
|
type = forms.MultipleChoiceField(
|
||||||
@ -991,15 +991,23 @@ class InterfaceFilterForm(DeviceComponentFilterForm):
|
|||||||
required=False,
|
required=False,
|
||||||
label='WWN'
|
label='WWN'
|
||||||
)
|
)
|
||||||
|
rf_role = forms.MultipleChoiceField(
|
||||||
|
choices=WirelessRoleChoices,
|
||||||
|
required=False,
|
||||||
|
widget=StaticSelectMultiple(),
|
||||||
|
label='Wireless role'
|
||||||
|
)
|
||||||
rf_channel = forms.MultipleChoiceField(
|
rf_channel = forms.MultipleChoiceField(
|
||||||
choices=WirelessChannelChoices,
|
choices=WirelessChannelChoices,
|
||||||
required=False,
|
required=False,
|
||||||
widget=StaticSelectMultiple()
|
widget=StaticSelectMultiple(),
|
||||||
|
label='Wireless channel'
|
||||||
)
|
)
|
||||||
rf_channel_width = forms.MultipleChoiceField(
|
rf_channel_width = forms.MultipleChoiceField(
|
||||||
choices=WirelessChannelWidthChoices,
|
choices=WirelessChannelWidthChoices,
|
||||||
required=False,
|
required=False,
|
||||||
widget=StaticSelectMultiple()
|
widget=StaticSelectMultiple(),
|
||||||
|
label='Channel width'
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
|
@ -1104,13 +1104,14 @@ class InterfaceForm(BootstrapMixin, InterfaceCommonForm, CustomFieldModelForm):
|
|||||||
model = Interface
|
model = Interface
|
||||||
fields = [
|
fields = [
|
||||||
'device', 'name', 'label', 'type', 'enabled', 'parent', 'lag', 'mac_address', 'wwn', 'mtu', 'mgmt_only',
|
'device', 'name', 'label', 'type', 'enabled', 'parent', 'lag', 'mac_address', 'wwn', 'mtu', 'mgmt_only',
|
||||||
'mark_connected', 'description', 'mode', 'rf_channel', 'rf_channel_width', 'wireless_lans', 'untagged_vlan',
|
'mark_connected', 'description', 'mode', 'rf_role', 'rf_channel', 'rf_channel_width', 'wireless_lans',
|
||||||
'tagged_vlans', 'tags',
|
'untagged_vlan', 'tagged_vlans', 'tags',
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
'device': forms.HiddenInput(),
|
'device': forms.HiddenInput(),
|
||||||
'type': StaticSelect(),
|
'type': StaticSelect(),
|
||||||
'mode': StaticSelect(),
|
'mode': StaticSelect(),
|
||||||
|
'rf_role': StaticSelect(),
|
||||||
'rf_channel': StaticSelect(),
|
'rf_channel': StaticSelect(),
|
||||||
'rf_channel_width': StaticSelect(),
|
'rf_channel_width': StaticSelect(),
|
||||||
}
|
}
|
||||||
|
@ -467,6 +467,12 @@ class InterfaceCreateForm(ComponentCreateForm, InterfaceCommonForm):
|
|||||||
required=False,
|
required=False,
|
||||||
widget=StaticSelect()
|
widget=StaticSelect()
|
||||||
)
|
)
|
||||||
|
rf_role = forms.ChoiceField(
|
||||||
|
choices=add_blank_choice(WirelessRoleChoices),
|
||||||
|
required=False,
|
||||||
|
widget=StaticSelect(),
|
||||||
|
label='Wireless role'
|
||||||
|
)
|
||||||
rf_channel = forms.ChoiceField(
|
rf_channel = forms.ChoiceField(
|
||||||
choices=add_blank_choice(WirelessChannelChoices),
|
choices=add_blank_choice(WirelessChannelChoices),
|
||||||
required=False,
|
required=False,
|
||||||
@ -489,8 +495,8 @@ class InterfaceCreateForm(ComponentCreateForm, InterfaceCommonForm):
|
|||||||
)
|
)
|
||||||
field_order = (
|
field_order = (
|
||||||
'device', 'name_pattern', 'label_pattern', 'type', 'enabled', 'parent', 'lag', 'mtu', 'mac_address',
|
'device', 'name_pattern', 'label_pattern', 'type', 'enabled', 'parent', 'lag', 'mtu', 'mac_address',
|
||||||
'description', 'mgmt_only', 'mark_connected', 'rf_channel', 'rf_channel_width', 'mode' 'untagged_vlan',
|
'description', 'mgmt_only', 'mark_connected', 'rf_role', 'rf_channel', 'rf_channel_width', 'mode',
|
||||||
'tagged_vlans', 'tags'
|
'untagged_vlan', 'tagged_vlans', 'tags'
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -206,6 +206,9 @@ class InterfaceType(IPAddressesMixin, ComponentObjectType):
|
|||||||
def resolve_mode(self, info):
|
def resolve_mode(self, info):
|
||||||
return self.mode or None
|
return self.mode or None
|
||||||
|
|
||||||
|
def resolve_rf_role(self, info):
|
||||||
|
return self.rf_role or None
|
||||||
|
|
||||||
def resolve_rf_channel(self, info):
|
def resolve_rf_channel(self, info):
|
||||||
return self.rf_channel or None
|
return self.rf_channel or None
|
||||||
|
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
# Generated by Django 3.2.8 on 2021-10-13 13:44
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
@ -10,6 +8,11 @@ class Migration(migrations.Migration):
|
|||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='interface',
|
||||||
|
name='rf_role',
|
||||||
|
field=models.CharField(blank=True, max_length=30),
|
||||||
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='interface',
|
model_name='interface',
|
||||||
name='rf_channel',
|
name='rf_channel',
|
||||||
|
@ -524,6 +524,12 @@ class Interface(ComponentModel, BaseInterface, LinkTermination, PathEndpoint):
|
|||||||
verbose_name='WWN',
|
verbose_name='WWN',
|
||||||
help_text='64-bit World Wide Name'
|
help_text='64-bit World Wide Name'
|
||||||
)
|
)
|
||||||
|
rf_role = models.CharField(
|
||||||
|
max_length=30,
|
||||||
|
choices=WirelessRoleChoices,
|
||||||
|
blank=True,
|
||||||
|
verbose_name='Wireless role'
|
||||||
|
)
|
||||||
rf_channel = models.CharField(
|
rf_channel = models.CharField(
|
||||||
max_length=50,
|
max_length=50,
|
||||||
choices=WirelessChannelChoices,
|
choices=WirelessChannelChoices,
|
||||||
@ -636,9 +642,11 @@ class Interface(ComponentModel, BaseInterface, LinkTermination, PathEndpoint):
|
|||||||
raise ValidationError({'lag': "A LAG interface cannot be its own parent."})
|
raise ValidationError({'lag': "A LAG interface cannot be its own parent."})
|
||||||
|
|
||||||
# RF channel attributes may be set only for wireless interfaces
|
# RF channel attributes may be set only for wireless interfaces
|
||||||
if self.rf_channel and self.type not in WIRELESS_IFACE_TYPES:
|
if self.rf_role and not self.is_wireless:
|
||||||
|
raise ValidationError({'rf_role': "Wireless role may be set only on wireless interfaces."})
|
||||||
|
if self.rf_channel and not self.is_wireless:
|
||||||
raise ValidationError({'rf_channel': "Channel may be set only on wireless interfaces."})
|
raise ValidationError({'rf_channel': "Channel may be set only on wireless interfaces."})
|
||||||
if self.rf_channel_width and self.type not in WIRELESS_IFACE_TYPES:
|
if self.rf_channel_width and not self.is_wireless:
|
||||||
raise ValidationError({'rf_channel_width': "Channel width may be set only on wireless interfaces."})
|
raise ValidationError({'rf_channel_width': "Channel width may be set only on wireless interfaces."})
|
||||||
|
|
||||||
# Validate untagged VLAN
|
# Validate untagged VLAN
|
||||||
|
@ -496,8 +496,8 @@ class InterfaceTable(DeviceComponentTable, BaseInterfaceTable, PathEndpointTable
|
|||||||
model = Interface
|
model = Interface
|
||||||
fields = (
|
fields = (
|
||||||
'pk', 'name', 'device', 'label', 'enabled', 'type', 'mgmt_only', 'mtu', 'mode', 'mac_address', 'wwn',
|
'pk', 'name', 'device', 'label', 'enabled', 'type', 'mgmt_only', 'mtu', 'mode', 'mac_address', 'wwn',
|
||||||
'rf_channel', 'rf_channel_width', 'description', 'mark_connected', 'cable', 'cable_color', 'wireless_link',
|
'rf_role', 'rf_channel', 'rf_channel_width', 'description', 'mark_connected', 'cable', 'cable_color',
|
||||||
'link_peer', 'connection', 'tags', 'ip_addresses', 'untagged_vlan', 'tagged_vlans',
|
'wireless_link', 'link_peer', 'connection', 'tags', 'ip_addresses', 'untagged_vlan', 'tagged_vlans',
|
||||||
)
|
)
|
||||||
default_columns = ('pk', 'name', 'device', 'label', 'enabled', 'type', 'description')
|
default_columns = ('pk', 'name', 'device', 'label', 'enabled', 'type', 'description')
|
||||||
|
|
||||||
@ -528,8 +528,9 @@ class DeviceInterfaceTable(InterfaceTable):
|
|||||||
model = Interface
|
model = Interface
|
||||||
fields = (
|
fields = (
|
||||||
'pk', 'name', 'label', 'enabled', 'type', 'parent', 'lag', 'mgmt_only', 'mtu', 'mode', 'mac_address', 'wwn',
|
'pk', 'name', 'label', 'enabled', 'type', 'parent', 'lag', 'mgmt_only', 'mtu', 'mode', 'mac_address', 'wwn',
|
||||||
'description', 'mark_connected', 'cable', 'cable_color', 'wireless_link', 'link_peer', 'connection', 'tags',
|
'rf_role', 'rf_channel', 'rf_channel_width', 'description', 'mark_connected', 'cable', 'cable_color',
|
||||||
'ip_addresses', 'untagged_vlan', 'tagged_vlans', 'actions',
|
'wireless_link', 'link_peer', 'connection', 'tags', 'ip_addresses', 'untagged_vlan', 'tagged_vlans',
|
||||||
|
'actions',
|
||||||
)
|
)
|
||||||
order_by = ('name',)
|
order_by = ('name',)
|
||||||
default_columns = (
|
default_columns = (
|
||||||
|
@ -39,16 +39,6 @@
|
|||||||
<th scope="row">Type</th>
|
<th scope="row">Type</th>
|
||||||
<td>{{ object.get_type_display }}</td>
|
<td>{{ object.get_type_display }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% if object.is_wireless %}
|
|
||||||
<tr>
|
|
||||||
<th scope="row">Channel</th>
|
|
||||||
<td>{{ object.get_rf_channel_display|placeholder }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">Channel Width</th>
|
|
||||||
<td>{{ object.get_rf_channel_width_display|placeholder }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Enabled</th>
|
<th scope="row">Enabled</th>
|
||||||
<td>
|
<td>
|
||||||
@ -274,6 +264,25 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if object.is_wireless %}
|
{% if object.is_wireless %}
|
||||||
|
<div class="card">
|
||||||
|
<h5 class="card-header">Wireless</h5>
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-hover">
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Role</th>
|
||||||
|
<td>{{ object.get_rf_role_display|placeholder }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Channel</th>
|
||||||
|
<td>{{ object.get_rf_channel_display|placeholder }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Channel Width</th>
|
||||||
|
<td>{{ object.get_rf_channel_width_display|placeholder }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h5 class="card-header">Wireless LANs</h5>
|
<h5 class="card-header">Wireless LANs</h5>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
<div class="row mb-2">
|
<div class="row mb-2">
|
||||||
<h5 class="offset-sm-3">Wireless</h5>
|
<h5 class="offset-sm-3">Wireless</h5>
|
||||||
</div>
|
</div>
|
||||||
|
{% render_field form.rf_role %}
|
||||||
{% render_field form.rf_channel %}
|
{% render_field form.rf_channel %}
|
||||||
{% render_field form.rf_channel_width %}
|
{% render_field form.rf_channel_width %}
|
||||||
{% render_field form.wireless_lans %}
|
{% render_field form.wireless_lans %}
|
||||||
|
Loading…
Reference in New Issue
Block a user