mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-23 04:22:01 -06:00
Adds rf_role to interface template (#13199)
* adds rf_role to interface template #13170 * fixed migration file conflict * Misc cleanup --------- Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
This commit is contained in:
parent
1bcfcad9db
commit
0f9fe96192
@ -514,12 +514,18 @@ class InterfaceTemplateSerializer(ValidatedModelSerializer):
|
|||||||
allow_blank=True,
|
allow_blank=True,
|
||||||
allow_null=True
|
allow_null=True
|
||||||
)
|
)
|
||||||
|
rf_role = ChoiceField(
|
||||||
|
choices=WirelessRoleChoices,
|
||||||
|
required=False,
|
||||||
|
allow_blank=True,
|
||||||
|
allow_null=True
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = InterfaceTemplate
|
model = InterfaceTemplate
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'url', 'display', 'device_type', 'module_type', 'name', 'label', 'type', 'enabled', 'mgmt_only',
|
'id', 'url', 'display', 'device_type', 'module_type', 'name', 'label', 'type', 'enabled', 'mgmt_only',
|
||||||
'description', 'bridge', 'poe_mode', 'poe_type', 'created', 'last_updated',
|
'description', 'bridge', 'poe_mode', 'poe_type', 'rf_role', 'created', 'last_updated',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -696,6 +696,9 @@ class InterfaceTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeCo
|
|||||||
poe_type = django_filters.MultipleChoiceFilter(
|
poe_type = django_filters.MultipleChoiceFilter(
|
||||||
choices=InterfacePoETypeChoices
|
choices=InterfacePoETypeChoices
|
||||||
)
|
)
|
||||||
|
rf_role = django_filters.MultipleChoiceFilter(
|
||||||
|
choices=WirelessRoleChoices
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = InterfaceTemplate
|
model = InterfaceTemplate
|
||||||
|
@ -76,14 +76,14 @@ class PowerOutletBulkCreateForm(
|
|||||||
|
|
||||||
class InterfaceBulkCreateForm(
|
class InterfaceBulkCreateForm(
|
||||||
form_from_model(Interface, [
|
form_from_model(Interface, [
|
||||||
'type', 'enabled', 'speed', 'duplex', 'mtu', 'mgmt_only', 'mark_connected', 'poe_mode', 'poe_type',
|
'type', 'enabled', 'speed', 'duplex', 'mtu', 'mgmt_only', 'mark_connected', 'poe_mode', 'poe_type', 'rf_role'
|
||||||
]),
|
]),
|
||||||
DeviceBulkAddComponentForm
|
DeviceBulkAddComponentForm
|
||||||
):
|
):
|
||||||
model = Interface
|
model = Interface
|
||||||
field_order = (
|
field_order = (
|
||||||
'name', 'label', 'type', 'enabled', 'speed', 'duplex', 'mtu', 'mgmt_only', 'poe_mode',
|
'name', 'label', 'type', 'enabled', 'speed', 'duplex', 'mtu', 'mgmt_only', 'poe_mode',
|
||||||
'poe_type', 'mark_connected', 'description', 'tags',
|
'poe_type', 'mark_connected', 'rf_role', 'description', 'tags',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ from utilities.forms import BulkEditForm, add_blank_choice, form_from_model
|
|||||||
from utilities.forms.fields import ColorField, CommentField, DynamicModelChoiceField, DynamicModelMultipleChoiceField
|
from utilities.forms.fields import ColorField, CommentField, DynamicModelChoiceField, DynamicModelMultipleChoiceField
|
||||||
from utilities.forms.widgets import BulkEditNullBooleanSelect, NumberWithOptions
|
from utilities.forms.widgets import BulkEditNullBooleanSelect, NumberWithOptions
|
||||||
from wireless.models import WirelessLAN, WirelessLANGroup
|
from wireless.models import WirelessLAN, WirelessLANGroup
|
||||||
|
from wireless.choices import WirelessRoleChoices
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'CableBulkEditForm',
|
'CableBulkEditForm',
|
||||||
@ -922,8 +923,14 @@ class InterfaceTemplateBulkEditForm(BulkEditForm):
|
|||||||
initial='',
|
initial='',
|
||||||
label=_('PoE type')
|
label=_('PoE type')
|
||||||
)
|
)
|
||||||
|
rf_role = forms.ChoiceField(
|
||||||
|
choices=add_blank_choice(WirelessRoleChoices),
|
||||||
|
required=False,
|
||||||
|
initial='',
|
||||||
|
label=_('Wireless role')
|
||||||
|
)
|
||||||
|
|
||||||
nullable_fields = ('label', 'description', 'poe_mode', 'poe_type')
|
nullable_fields = ('label', 'description', 'poe_mode', 'poe_type', 'rf_role')
|
||||||
|
|
||||||
|
|
||||||
class FrontPortTemplateBulkEditForm(BulkEditForm):
|
class FrontPortTemplateBulkEditForm(BulkEditForm):
|
||||||
|
@ -826,13 +826,14 @@ class InterfaceTemplateForm(ModularComponentTemplateForm):
|
|||||||
|
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
(None, ('device_type', 'module_type', 'name', 'label', 'type', 'enabled', 'mgmt_only', 'description', 'bridge')),
|
(None, ('device_type', 'module_type', 'name', 'label', 'type', 'enabled', 'mgmt_only', 'description', 'bridge')),
|
||||||
('PoE', ('poe_mode', 'poe_type'))
|
('PoE', ('poe_mode', 'poe_type')),
|
||||||
|
('Wireless', ('rf_role',))
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = InterfaceTemplate
|
model = InterfaceTemplate
|
||||||
fields = [
|
fields = [
|
||||||
'device_type', 'module_type', 'name', 'label', 'type', 'mgmt_only', 'enabled', 'description', 'poe_mode', 'poe_type', 'bridge',
|
'device_type', 'module_type', 'name', 'label', 'type', 'mgmt_only', 'enabled', 'description', 'poe_mode', 'poe_type', 'bridge', 'rf_role',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ from django.utils.translation import gettext as _
|
|||||||
from dcim.choices import InterfacePoEModeChoices, InterfacePoETypeChoices, InterfaceTypeChoices, PortTypeChoices
|
from dcim.choices import InterfacePoEModeChoices, InterfacePoETypeChoices, InterfaceTypeChoices, PortTypeChoices
|
||||||
from dcim.models import *
|
from dcim.models import *
|
||||||
from utilities.forms import BootstrapMixin
|
from utilities.forms import BootstrapMixin
|
||||||
|
from wireless.choices import WirelessRoleChoices
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'ConsolePortTemplateImportForm',
|
'ConsolePortTemplateImportForm',
|
||||||
@ -96,11 +97,17 @@ class InterfaceTemplateImportForm(ComponentTemplateImportForm):
|
|||||||
required=False,
|
required=False,
|
||||||
label=_('PoE type')
|
label=_('PoE type')
|
||||||
)
|
)
|
||||||
|
rf_role = forms.ChoiceField(
|
||||||
|
choices=WirelessRoleChoices,
|
||||||
|
required=False,
|
||||||
|
label=_('Wireless role')
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = InterfaceTemplate
|
model = InterfaceTemplate
|
||||||
fields = [
|
fields = [
|
||||||
'device_type', 'module_type', 'name', 'label', 'type', 'enabled', 'mgmt_only', 'description', 'poe_mode', 'poe_type',
|
'device_type', 'module_type', 'name', 'label', 'type', 'enabled', 'mgmt_only', 'description', 'poe_mode',
|
||||||
|
'poe_type', 'rf_role'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -277,6 +277,9 @@ class InterfaceTemplateType(ComponentTemplateObjectType):
|
|||||||
def resolve_poe_type(self, info):
|
def resolve_poe_type(self, info):
|
||||||
return self.poe_type or None
|
return self.poe_type or None
|
||||||
|
|
||||||
|
def resolve_rf_role(self, info):
|
||||||
|
return self.rf_role or None
|
||||||
|
|
||||||
|
|
||||||
class InventoryItemType(ComponentObjectType):
|
class InventoryItemType(ComponentObjectType):
|
||||||
component = graphene.Field('dcim.graphql.gfk_mixins.InventoryItemComponentType')
|
component = graphene.Field('dcim.graphql.gfk_mixins.InventoryItemComponentType')
|
||||||
|
18
netbox/dcim/migrations/0179_interfacetemplate_rf_role.py
Normal file
18
netbox/dcim/migrations/0179_interfacetemplate_rf_role.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-18 07:55
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('dcim', '0178_virtual_chassis_member_counter'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='interfacetemplate',
|
||||||
|
name='rf_role',
|
||||||
|
field=models.CharField(blank=True, max_length=30),
|
||||||
|
),
|
||||||
|
]
|
@ -13,6 +13,7 @@ from utilities.fields import ColorField, NaturalOrderingField
|
|||||||
from utilities.mptt import TreeManager
|
from utilities.mptt import TreeManager
|
||||||
from utilities.ordering import naturalize_interface
|
from utilities.ordering import naturalize_interface
|
||||||
from utilities.tracking import TrackingModelMixin
|
from utilities.tracking import TrackingModelMixin
|
||||||
|
from wireless.choices import WirelessRoleChoices
|
||||||
from .device_components import (
|
from .device_components import (
|
||||||
ConsolePort, ConsoleServerPort, DeviceBay, FrontPort, Interface, InventoryItem, ModuleBay, PowerOutlet, PowerPort,
|
ConsolePort, ConsoleServerPort, DeviceBay, FrontPort, Interface, InventoryItem, ModuleBay, PowerOutlet, PowerPort,
|
||||||
RearPort,
|
RearPort,
|
||||||
@ -388,6 +389,12 @@ class InterfaceTemplate(ModularComponentTemplateModel):
|
|||||||
blank=True,
|
blank=True,
|
||||||
verbose_name='PoE type'
|
verbose_name='PoE type'
|
||||||
)
|
)
|
||||||
|
rf_role = models.CharField(
|
||||||
|
max_length=30,
|
||||||
|
choices=WirelessRoleChoices,
|
||||||
|
blank=True,
|
||||||
|
verbose_name='Wireless role'
|
||||||
|
)
|
||||||
|
|
||||||
component_model = Interface
|
component_model = Interface
|
||||||
|
|
||||||
@ -406,6 +413,11 @@ class InterfaceTemplate(ModularComponentTemplateModel):
|
|||||||
'bridge': f"Bridge interface ({self.bridge}) must belong to the same module type"
|
'bridge': f"Bridge interface ({self.bridge}) must belong to the same module type"
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if self.rf_role and self.type not in WIRELESS_IFACE_TYPES:
|
||||||
|
raise ValidationError({
|
||||||
|
'rf_role': "Wireless role may be set only on wireless interfaces."
|
||||||
|
})
|
||||||
|
|
||||||
def instantiate(self, **kwargs):
|
def instantiate(self, **kwargs):
|
||||||
return self.component_model(
|
return self.component_model(
|
||||||
name=self.resolve_name(kwargs.get('module')),
|
name=self.resolve_name(kwargs.get('module')),
|
||||||
@ -415,6 +427,7 @@ class InterfaceTemplate(ModularComponentTemplateModel):
|
|||||||
mgmt_only=self.mgmt_only,
|
mgmt_only=self.mgmt_only,
|
||||||
poe_mode=self.poe_mode,
|
poe_mode=self.poe_mode,
|
||||||
poe_type=self.poe_type,
|
poe_type=self.poe_type,
|
||||||
|
rf_role=self.rf_role,
|
||||||
**kwargs
|
**kwargs
|
||||||
)
|
)
|
||||||
instantiate.do_not_call_in_templates = True
|
instantiate.do_not_call_in_templates = True
|
||||||
@ -430,6 +443,7 @@ class InterfaceTemplate(ModularComponentTemplateModel):
|
|||||||
'bridge': self.bridge.name if self.bridge else None,
|
'bridge': self.bridge.name if self.bridge else None,
|
||||||
'poe_mode': self.poe_mode,
|
'poe_mode': self.poe_mode,
|
||||||
'poe_type': self.poe_type,
|
'poe_type': self.poe_type,
|
||||||
|
'rf_role': self.rf_role,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -219,7 +219,10 @@ class InterfaceTemplateTable(ComponentTemplateTable):
|
|||||||
|
|
||||||
class Meta(ComponentTemplateTable.Meta):
|
class Meta(ComponentTemplateTable.Meta):
|
||||||
model = models.InterfaceTemplate
|
model = models.InterfaceTemplate
|
||||||
fields = ('pk', 'name', 'label', 'enabled', 'mgmt_only', 'type', 'description', 'bridge', 'poe_mode', 'poe_type', 'actions')
|
fields = (
|
||||||
|
'pk', 'name', 'label', 'enabled', 'mgmt_only', 'type', 'description', 'bridge', 'poe_mode', 'poe_type',
|
||||||
|
'rf_role', 'actions',
|
||||||
|
)
|
||||||
empty_text = "None"
|
empty_text = "None"
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user