mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
1118 lines
31 KiB
Python
1118 lines
31 KiB
Python
from django import forms
|
|
from django.contrib.auth.models import User
|
|
from timezone_field import TimeZoneFormField
|
|
|
|
from dcim.choices import *
|
|
from dcim.constants import *
|
|
from dcim.models import *
|
|
from extras.forms import AddRemoveTagsForm, CustomFieldModelBulkEditForm
|
|
from ipam.constants import BGP_ASN_MAX, BGP_ASN_MIN
|
|
from ipam.models import VLAN
|
|
from tenancy.models import Tenant
|
|
from utilities.forms import (
|
|
add_blank_choice, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect, ColorField, CommentField,
|
|
DynamicModelChoiceField, DynamicModelMultipleChoiceField, form_from_model, SmallTextarea, StaticSelect,
|
|
)
|
|
|
|
__all__ = (
|
|
'CableBulkEditForm',
|
|
'ConsolePortBulkEditForm',
|
|
'ConsolePortTemplateBulkEditForm',
|
|
'ConsoleServerPortBulkEditForm',
|
|
'ConsoleServerPortTemplateBulkEditForm',
|
|
'DeviceBayBulkEditForm',
|
|
'DeviceBayTemplateBulkEditForm',
|
|
'DeviceBulkEditForm',
|
|
'DeviceRoleBulkEditForm',
|
|
'DeviceTypeBulkEditForm',
|
|
'FrontPortBulkEditForm',
|
|
'FrontPortTemplateBulkEditForm',
|
|
'InterfaceBulkEditForm',
|
|
'InterfaceTemplateBulkEditForm',
|
|
'InventoryItemBulkEditForm',
|
|
'LocationBulkEditForm',
|
|
'ManufacturerBulkEditForm',
|
|
'PlatformBulkEditForm',
|
|
'PowerFeedBulkEditForm',
|
|
'PowerOutletBulkEditForm',
|
|
'PowerOutletTemplateBulkEditForm',
|
|
'PowerPanelBulkEditForm',
|
|
'PowerPortBulkEditForm',
|
|
'PowerPortTemplateBulkEditForm',
|
|
'RackBulkEditForm',
|
|
'RackReservationBulkEditForm',
|
|
'RackRoleBulkEditForm',
|
|
'RearPortBulkEditForm',
|
|
'RearPortTemplateBulkEditForm',
|
|
'RegionBulkEditForm',
|
|
'SiteBulkEditForm',
|
|
'SiteGroupBulkEditForm',
|
|
'VirtualChassisBulkEditForm',
|
|
)
|
|
|
|
|
|
class RegionBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=Region.objects.all(),
|
|
widget=forms.MultipleHiddenInput
|
|
)
|
|
parent = DynamicModelChoiceField(
|
|
queryset=Region.objects.all(),
|
|
required=False
|
|
)
|
|
description = forms.CharField(
|
|
max_length=200,
|
|
required=False
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ['parent', 'description']
|
|
|
|
|
|
class SiteGroupBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=SiteGroup.objects.all(),
|
|
widget=forms.MultipleHiddenInput
|
|
)
|
|
parent = DynamicModelChoiceField(
|
|
queryset=SiteGroup.objects.all(),
|
|
required=False
|
|
)
|
|
description = forms.CharField(
|
|
max_length=200,
|
|
required=False
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ['parent', 'description']
|
|
|
|
|
|
class SiteBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=Site.objects.all(),
|
|
widget=forms.MultipleHiddenInput
|
|
)
|
|
status = forms.ChoiceField(
|
|
choices=add_blank_choice(SiteStatusChoices),
|
|
required=False,
|
|
initial='',
|
|
widget=StaticSelect()
|
|
)
|
|
region = DynamicModelChoiceField(
|
|
queryset=Region.objects.all(),
|
|
required=False
|
|
)
|
|
group = DynamicModelChoiceField(
|
|
queryset=SiteGroup.objects.all(),
|
|
required=False
|
|
)
|
|
tenant = DynamicModelChoiceField(
|
|
queryset=Tenant.objects.all(),
|
|
required=False
|
|
)
|
|
asn = forms.IntegerField(
|
|
min_value=BGP_ASN_MIN,
|
|
max_value=BGP_ASN_MAX,
|
|
required=False,
|
|
label='ASN'
|
|
)
|
|
description = forms.CharField(
|
|
max_length=100,
|
|
required=False
|
|
)
|
|
time_zone = TimeZoneFormField(
|
|
choices=add_blank_choice(TimeZoneFormField().choices),
|
|
required=False,
|
|
widget=StaticSelect()
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = [
|
|
'region', 'group', 'tenant', 'asn', 'description', 'time_zone',
|
|
]
|
|
|
|
|
|
class LocationBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=Location.objects.all(),
|
|
widget=forms.MultipleHiddenInput
|
|
)
|
|
site = DynamicModelChoiceField(
|
|
queryset=Site.objects.all(),
|
|
required=False
|
|
)
|
|
parent = DynamicModelChoiceField(
|
|
queryset=Location.objects.all(),
|
|
required=False,
|
|
query_params={
|
|
'site_id': '$site'
|
|
}
|
|
)
|
|
tenant = DynamicModelChoiceField(
|
|
queryset=Tenant.objects.all(),
|
|
required=False
|
|
)
|
|
description = forms.CharField(
|
|
max_length=200,
|
|
required=False
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ['parent', 'tenant', 'description']
|
|
|
|
|
|
class RackRoleBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=RackRole.objects.all(),
|
|
widget=forms.MultipleHiddenInput
|
|
)
|
|
color = ColorField(
|
|
required=False
|
|
)
|
|
description = forms.CharField(
|
|
max_length=200,
|
|
required=False
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ['color', 'description']
|
|
|
|
|
|
class RackBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=Rack.objects.all(),
|
|
widget=forms.MultipleHiddenInput
|
|
)
|
|
region = DynamicModelChoiceField(
|
|
queryset=Region.objects.all(),
|
|
required=False,
|
|
initial_params={
|
|
'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',
|
|
'group_id': '$site_group',
|
|
}
|
|
)
|
|
location = DynamicModelChoiceField(
|
|
queryset=Location.objects.all(),
|
|
required=False,
|
|
query_params={
|
|
'site_id': '$site'
|
|
}
|
|
)
|
|
tenant = DynamicModelChoiceField(
|
|
queryset=Tenant.objects.all(),
|
|
required=False
|
|
)
|
|
status = forms.ChoiceField(
|
|
choices=add_blank_choice(RackStatusChoices),
|
|
required=False,
|
|
initial='',
|
|
widget=StaticSelect()
|
|
)
|
|
role = DynamicModelChoiceField(
|
|
queryset=RackRole.objects.all(),
|
|
required=False
|
|
)
|
|
serial = forms.CharField(
|
|
max_length=50,
|
|
required=False,
|
|
label='Serial Number'
|
|
)
|
|
asset_tag = forms.CharField(
|
|
max_length=50,
|
|
required=False
|
|
)
|
|
type = forms.ChoiceField(
|
|
choices=add_blank_choice(RackTypeChoices),
|
|
required=False,
|
|
widget=StaticSelect()
|
|
)
|
|
width = forms.ChoiceField(
|
|
choices=add_blank_choice(RackWidthChoices),
|
|
required=False,
|
|
widget=StaticSelect()
|
|
)
|
|
u_height = forms.IntegerField(
|
|
required=False,
|
|
label='Height (U)'
|
|
)
|
|
desc_units = forms.NullBooleanField(
|
|
required=False,
|
|
widget=BulkEditNullBooleanSelect,
|
|
label='Descending units'
|
|
)
|
|
outer_width = forms.IntegerField(
|
|
required=False,
|
|
min_value=1
|
|
)
|
|
outer_depth = forms.IntegerField(
|
|
required=False,
|
|
min_value=1
|
|
)
|
|
outer_unit = forms.ChoiceField(
|
|
choices=add_blank_choice(RackDimensionUnitChoices),
|
|
required=False,
|
|
widget=StaticSelect()
|
|
)
|
|
comments = CommentField(
|
|
widget=SmallTextarea,
|
|
label='Comments'
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = [
|
|
'location', 'tenant', 'role', 'serial', 'asset_tag', 'outer_width', 'outer_depth', 'outer_unit', 'comments',
|
|
]
|
|
|
|
|
|
class RackReservationBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=RackReservation.objects.all(),
|
|
widget=forms.MultipleHiddenInput()
|
|
)
|
|
user = forms.ModelChoiceField(
|
|
queryset=User.objects.order_by(
|
|
'username'
|
|
),
|
|
required=False,
|
|
widget=StaticSelect()
|
|
)
|
|
tenant = DynamicModelChoiceField(
|
|
queryset=Tenant.objects.all(),
|
|
required=False
|
|
)
|
|
description = forms.CharField(
|
|
max_length=100,
|
|
required=False
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = []
|
|
|
|
|
|
class ManufacturerBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=Manufacturer.objects.all(),
|
|
widget=forms.MultipleHiddenInput
|
|
)
|
|
description = forms.CharField(
|
|
max_length=200,
|
|
required=False
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ['description']
|
|
|
|
|
|
class DeviceTypeBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=DeviceType.objects.all(),
|
|
widget=forms.MultipleHiddenInput()
|
|
)
|
|
manufacturer = DynamicModelChoiceField(
|
|
queryset=Manufacturer.objects.all(),
|
|
required=False
|
|
)
|
|
u_height = forms.IntegerField(
|
|
min_value=1,
|
|
required=False
|
|
)
|
|
is_full_depth = forms.NullBooleanField(
|
|
required=False,
|
|
widget=BulkEditNullBooleanSelect(),
|
|
label='Is full depth'
|
|
)
|
|
airflow = forms.ChoiceField(
|
|
choices=add_blank_choice(DeviceAirflowChoices),
|
|
required=False,
|
|
widget=StaticSelect()
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ['airflow']
|
|
|
|
|
|
class DeviceRoleBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=DeviceRole.objects.all(),
|
|
widget=forms.MultipleHiddenInput
|
|
)
|
|
color = ColorField(
|
|
required=False
|
|
)
|
|
vm_role = forms.NullBooleanField(
|
|
required=False,
|
|
widget=BulkEditNullBooleanSelect,
|
|
label='VM role'
|
|
)
|
|
description = forms.CharField(
|
|
max_length=200,
|
|
required=False
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ['color', 'description']
|
|
|
|
|
|
class PlatformBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=Platform.objects.all(),
|
|
widget=forms.MultipleHiddenInput
|
|
)
|
|
manufacturer = DynamicModelChoiceField(
|
|
queryset=Manufacturer.objects.all(),
|
|
required=False
|
|
)
|
|
napalm_driver = forms.CharField(
|
|
max_length=50,
|
|
required=False
|
|
)
|
|
# TODO: Bulk edit support for napalm_args
|
|
description = forms.CharField(
|
|
max_length=200,
|
|
required=False
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ['manufacturer', 'napalm_driver', 'description']
|
|
|
|
|
|
class DeviceBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=Device.objects.all(),
|
|
widget=forms.MultipleHiddenInput()
|
|
)
|
|
manufacturer = DynamicModelChoiceField(
|
|
queryset=Manufacturer.objects.all(),
|
|
required=False
|
|
)
|
|
device_type = DynamicModelChoiceField(
|
|
queryset=DeviceType.objects.all(),
|
|
required=False,
|
|
query_params={
|
|
'manufacturer_id': '$manufacturer'
|
|
}
|
|
)
|
|
device_role = DynamicModelChoiceField(
|
|
queryset=DeviceRole.objects.all(),
|
|
required=False
|
|
)
|
|
site = DynamicModelChoiceField(
|
|
queryset=Site.objects.all(),
|
|
required=False
|
|
)
|
|
location = DynamicModelChoiceField(
|
|
queryset=Location.objects.all(),
|
|
required=False,
|
|
query_params={
|
|
'site_id': '$site'
|
|
}
|
|
)
|
|
tenant = DynamicModelChoiceField(
|
|
queryset=Tenant.objects.all(),
|
|
required=False
|
|
)
|
|
platform = DynamicModelChoiceField(
|
|
queryset=Platform.objects.all(),
|
|
required=False
|
|
)
|
|
status = forms.ChoiceField(
|
|
choices=add_blank_choice(DeviceStatusChoices),
|
|
required=False,
|
|
widget=StaticSelect()
|
|
)
|
|
airflow = forms.ChoiceField(
|
|
choices=add_blank_choice(DeviceAirflowChoices),
|
|
required=False,
|
|
widget=StaticSelect()
|
|
)
|
|
serial = forms.CharField(
|
|
max_length=50,
|
|
required=False,
|
|
label='Serial Number'
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = [
|
|
'tenant', 'platform', 'serial', 'airflow',
|
|
]
|
|
|
|
|
|
class CableBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=Cable.objects.all(),
|
|
widget=forms.MultipleHiddenInput
|
|
)
|
|
type = forms.ChoiceField(
|
|
choices=add_blank_choice(CableTypeChoices),
|
|
required=False,
|
|
initial='',
|
|
widget=StaticSelect()
|
|
)
|
|
status = forms.ChoiceField(
|
|
choices=add_blank_choice(LinkStatusChoices),
|
|
required=False,
|
|
widget=StaticSelect(),
|
|
initial=''
|
|
)
|
|
tenant = DynamicModelChoiceField(
|
|
queryset=Tenant.objects.all(),
|
|
required=False
|
|
)
|
|
label = forms.CharField(
|
|
max_length=100,
|
|
required=False
|
|
)
|
|
color = ColorField(
|
|
required=False
|
|
)
|
|
length = forms.DecimalField(
|
|
min_value=0,
|
|
required=False
|
|
)
|
|
length_unit = forms.ChoiceField(
|
|
choices=add_blank_choice(CableLengthUnitChoices),
|
|
required=False,
|
|
initial='',
|
|
widget=StaticSelect()
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = [
|
|
'type', 'status', 'tenant', 'label', 'color', 'length',
|
|
]
|
|
|
|
def clean(self):
|
|
super().clean()
|
|
|
|
# Validate length/unit
|
|
length = self.cleaned_data.get('length')
|
|
length_unit = self.cleaned_data.get('length_unit')
|
|
if length and not length_unit:
|
|
raise forms.ValidationError({
|
|
'length_unit': "Must specify a unit when setting length"
|
|
})
|
|
|
|
|
|
class VirtualChassisBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=VirtualChassis.objects.all(),
|
|
widget=forms.MultipleHiddenInput()
|
|
)
|
|
domain = forms.CharField(
|
|
max_length=30,
|
|
required=False
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ['domain']
|
|
|
|
|
|
class PowerPanelBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=PowerPanel.objects.all(),
|
|
widget=forms.MultipleHiddenInput
|
|
)
|
|
region = DynamicModelChoiceField(
|
|
queryset=Region.objects.all(),
|
|
required=False,
|
|
initial_params={
|
|
'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',
|
|
'group_id': '$site_group',
|
|
}
|
|
)
|
|
location = DynamicModelChoiceField(
|
|
queryset=Location.objects.all(),
|
|
required=False,
|
|
query_params={
|
|
'site_id': '$site'
|
|
}
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ['location']
|
|
|
|
|
|
class PowerFeedBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=PowerFeed.objects.all(),
|
|
widget=forms.MultipleHiddenInput
|
|
)
|
|
power_panel = DynamicModelChoiceField(
|
|
queryset=PowerPanel.objects.all(),
|
|
required=False
|
|
)
|
|
rack = DynamicModelChoiceField(
|
|
queryset=Rack.objects.all(),
|
|
required=False,
|
|
)
|
|
status = forms.ChoiceField(
|
|
choices=add_blank_choice(PowerFeedStatusChoices),
|
|
required=False,
|
|
initial='',
|
|
widget=StaticSelect()
|
|
)
|
|
type = forms.ChoiceField(
|
|
choices=add_blank_choice(PowerFeedTypeChoices),
|
|
required=False,
|
|
initial='',
|
|
widget=StaticSelect()
|
|
)
|
|
supply = forms.ChoiceField(
|
|
choices=add_blank_choice(PowerFeedSupplyChoices),
|
|
required=False,
|
|
initial='',
|
|
widget=StaticSelect()
|
|
)
|
|
phase = forms.ChoiceField(
|
|
choices=add_blank_choice(PowerFeedPhaseChoices),
|
|
required=False,
|
|
initial='',
|
|
widget=StaticSelect()
|
|
)
|
|
voltage = forms.IntegerField(
|
|
required=False
|
|
)
|
|
amperage = forms.IntegerField(
|
|
required=False
|
|
)
|
|
max_utilization = forms.IntegerField(
|
|
required=False
|
|
)
|
|
mark_connected = forms.NullBooleanField(
|
|
required=False,
|
|
widget=BulkEditNullBooleanSelect
|
|
)
|
|
comments = CommentField(
|
|
widget=SmallTextarea,
|
|
label='Comments'
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = [
|
|
'location', 'comments',
|
|
]
|
|
|
|
|
|
#
|
|
# Device component templates
|
|
#
|
|
|
|
class ConsolePortTemplateBulkEditForm(BootstrapMixin, BulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=ConsolePortTemplate.objects.all(),
|
|
widget=forms.MultipleHiddenInput()
|
|
)
|
|
label = forms.CharField(
|
|
max_length=64,
|
|
required=False
|
|
)
|
|
type = forms.ChoiceField(
|
|
choices=add_blank_choice(ConsolePortTypeChoices),
|
|
required=False,
|
|
widget=StaticSelect()
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ('label', 'type', 'description')
|
|
|
|
|
|
class ConsoleServerPortTemplateBulkEditForm(BootstrapMixin, BulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=ConsoleServerPortTemplate.objects.all(),
|
|
widget=forms.MultipleHiddenInput()
|
|
)
|
|
label = forms.CharField(
|
|
max_length=64,
|
|
required=False
|
|
)
|
|
type = forms.ChoiceField(
|
|
choices=add_blank_choice(ConsolePortTypeChoices),
|
|
required=False,
|
|
widget=StaticSelect()
|
|
)
|
|
description = forms.CharField(
|
|
required=False
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ('label', 'type', 'description')
|
|
|
|
|
|
class PowerPortTemplateBulkEditForm(BootstrapMixin, BulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=PowerPortTemplate.objects.all(),
|
|
widget=forms.MultipleHiddenInput()
|
|
)
|
|
label = forms.CharField(
|
|
max_length=64,
|
|
required=False
|
|
)
|
|
type = forms.ChoiceField(
|
|
choices=add_blank_choice(PowerPortTypeChoices),
|
|
required=False,
|
|
widget=StaticSelect()
|
|
)
|
|
maximum_draw = forms.IntegerField(
|
|
min_value=1,
|
|
required=False,
|
|
help_text="Maximum power draw (watts)"
|
|
)
|
|
allocated_draw = forms.IntegerField(
|
|
min_value=1,
|
|
required=False,
|
|
help_text="Allocated power draw (watts)"
|
|
)
|
|
description = forms.CharField(
|
|
required=False
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ('label', 'type', 'maximum_draw', 'allocated_draw', 'description')
|
|
|
|
|
|
class PowerOutletTemplateBulkEditForm(BootstrapMixin, BulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=PowerOutletTemplate.objects.all(),
|
|
widget=forms.MultipleHiddenInput()
|
|
)
|
|
device_type = forms.ModelChoiceField(
|
|
queryset=DeviceType.objects.all(),
|
|
required=False,
|
|
disabled=True,
|
|
widget=forms.HiddenInput()
|
|
)
|
|
label = forms.CharField(
|
|
max_length=64,
|
|
required=False
|
|
)
|
|
type = forms.ChoiceField(
|
|
choices=add_blank_choice(PowerOutletTypeChoices),
|
|
required=False,
|
|
widget=StaticSelect()
|
|
)
|
|
power_port = forms.ModelChoiceField(
|
|
queryset=PowerPortTemplate.objects.all(),
|
|
required=False
|
|
)
|
|
feed_leg = forms.ChoiceField(
|
|
choices=add_blank_choice(PowerOutletFeedLegChoices),
|
|
required=False,
|
|
widget=StaticSelect()
|
|
)
|
|
description = forms.CharField(
|
|
required=False
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ('label', 'type', 'power_port', 'feed_leg', 'description')
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
|
|
# Limit power_port queryset to PowerPortTemplates which belong to the parent DeviceType
|
|
if 'device_type' in self.initial:
|
|
device_type = DeviceType.objects.filter(pk=self.initial['device_type']).first()
|
|
self.fields['power_port'].queryset = PowerPortTemplate.objects.filter(device_type=device_type)
|
|
else:
|
|
self.fields['power_port'].choices = ()
|
|
self.fields['power_port'].widget.attrs['disabled'] = True
|
|
|
|
|
|
class InterfaceTemplateBulkEditForm(BootstrapMixin, BulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=InterfaceTemplate.objects.all(),
|
|
widget=forms.MultipleHiddenInput()
|
|
)
|
|
label = forms.CharField(
|
|
max_length=64,
|
|
required=False
|
|
)
|
|
type = forms.ChoiceField(
|
|
choices=add_blank_choice(InterfaceTypeChoices),
|
|
required=False,
|
|
widget=StaticSelect()
|
|
)
|
|
mgmt_only = forms.NullBooleanField(
|
|
required=False,
|
|
widget=BulkEditNullBooleanSelect,
|
|
label='Management only'
|
|
)
|
|
description = forms.CharField(
|
|
required=False
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ('label', 'description')
|
|
|
|
|
|
class FrontPortTemplateBulkEditForm(BootstrapMixin, BulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=FrontPortTemplate.objects.all(),
|
|
widget=forms.MultipleHiddenInput()
|
|
)
|
|
label = forms.CharField(
|
|
max_length=64,
|
|
required=False
|
|
)
|
|
type = forms.ChoiceField(
|
|
choices=add_blank_choice(PortTypeChoices),
|
|
required=False,
|
|
widget=StaticSelect()
|
|
)
|
|
color = ColorField(
|
|
required=False
|
|
)
|
|
description = forms.CharField(
|
|
required=False
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ('description',)
|
|
|
|
|
|
class RearPortTemplateBulkEditForm(BootstrapMixin, BulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=RearPortTemplate.objects.all(),
|
|
widget=forms.MultipleHiddenInput()
|
|
)
|
|
label = forms.CharField(
|
|
max_length=64,
|
|
required=False
|
|
)
|
|
type = forms.ChoiceField(
|
|
choices=add_blank_choice(PortTypeChoices),
|
|
required=False,
|
|
widget=StaticSelect()
|
|
)
|
|
color = ColorField(
|
|
required=False
|
|
)
|
|
description = forms.CharField(
|
|
required=False
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ('description',)
|
|
|
|
|
|
class DeviceBayTemplateBulkEditForm(BootstrapMixin, BulkEditForm):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=DeviceBayTemplate.objects.all(),
|
|
widget=forms.MultipleHiddenInput()
|
|
)
|
|
label = forms.CharField(
|
|
max_length=64,
|
|
required=False
|
|
)
|
|
description = forms.CharField(
|
|
required=False
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ('label', 'description')
|
|
|
|
|
|
#
|
|
# Device components
|
|
#
|
|
|
|
class ConsolePortBulkEditForm(
|
|
form_from_model(ConsolePort, ['label', 'type', 'speed', 'mark_connected', 'description']),
|
|
BootstrapMixin,
|
|
AddRemoveTagsForm,
|
|
CustomFieldModelBulkEditForm
|
|
):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=ConsolePort.objects.all(),
|
|
widget=forms.MultipleHiddenInput()
|
|
)
|
|
mark_connected = forms.NullBooleanField(
|
|
required=False,
|
|
widget=BulkEditNullBooleanSelect
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ['label', 'description']
|
|
|
|
|
|
class ConsoleServerPortBulkEditForm(
|
|
form_from_model(ConsoleServerPort, ['label', 'type', 'speed', 'mark_connected', 'description']),
|
|
BootstrapMixin,
|
|
AddRemoveTagsForm,
|
|
CustomFieldModelBulkEditForm
|
|
):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=ConsoleServerPort.objects.all(),
|
|
widget=forms.MultipleHiddenInput()
|
|
)
|
|
mark_connected = forms.NullBooleanField(
|
|
required=False,
|
|
widget=BulkEditNullBooleanSelect
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ['label', 'description']
|
|
|
|
|
|
class PowerPortBulkEditForm(
|
|
form_from_model(PowerPort, ['label', 'type', 'maximum_draw', 'allocated_draw', 'mark_connected', 'description']),
|
|
BootstrapMixin,
|
|
AddRemoveTagsForm,
|
|
CustomFieldModelBulkEditForm
|
|
):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=PowerPort.objects.all(),
|
|
widget=forms.MultipleHiddenInput()
|
|
)
|
|
mark_connected = forms.NullBooleanField(
|
|
required=False,
|
|
widget=BulkEditNullBooleanSelect
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ['label', 'description']
|
|
|
|
|
|
class PowerOutletBulkEditForm(
|
|
form_from_model(PowerOutlet, ['label', 'type', 'feed_leg', 'power_port', 'mark_connected', 'description']),
|
|
BootstrapMixin,
|
|
AddRemoveTagsForm,
|
|
CustomFieldModelBulkEditForm
|
|
):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=PowerOutlet.objects.all(),
|
|
widget=forms.MultipleHiddenInput()
|
|
)
|
|
device = forms.ModelChoiceField(
|
|
queryset=Device.objects.all(),
|
|
required=False,
|
|
disabled=True,
|
|
widget=forms.HiddenInput()
|
|
)
|
|
mark_connected = forms.NullBooleanField(
|
|
required=False,
|
|
widget=BulkEditNullBooleanSelect
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ['label', 'type', 'feed_leg', 'power_port', 'description']
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
|
|
# Limit power_port queryset to PowerPorts which belong to the parent Device
|
|
if 'device' in self.initial:
|
|
device = Device.objects.filter(pk=self.initial['device']).first()
|
|
self.fields['power_port'].queryset = PowerPort.objects.filter(device=device)
|
|
else:
|
|
self.fields['power_port'].choices = ()
|
|
self.fields['power_port'].widget.attrs['disabled'] = True
|
|
|
|
|
|
class InterfaceBulkEditForm(
|
|
form_from_model(Interface, [
|
|
'label', 'type', 'parent', 'bridge', 'lag', 'mac_address', 'wwn', 'mtu', 'mgmt_only', 'mark_connected',
|
|
'description', 'mode', 'rf_role', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power',
|
|
]),
|
|
BootstrapMixin,
|
|
AddRemoveTagsForm,
|
|
CustomFieldModelBulkEditForm
|
|
):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=Interface.objects.all(),
|
|
widget=forms.MultipleHiddenInput()
|
|
)
|
|
device = forms.ModelChoiceField(
|
|
queryset=Device.objects.all(),
|
|
required=False,
|
|
disabled=True,
|
|
widget=forms.HiddenInput()
|
|
)
|
|
enabled = forms.NullBooleanField(
|
|
required=False,
|
|
widget=BulkEditNullBooleanSelect
|
|
)
|
|
parent = DynamicModelChoiceField(
|
|
queryset=Interface.objects.all(),
|
|
required=False
|
|
)
|
|
bridge = DynamicModelChoiceField(
|
|
queryset=Interface.objects.all(),
|
|
required=False
|
|
)
|
|
lag = DynamicModelChoiceField(
|
|
queryset=Interface.objects.all(),
|
|
required=False,
|
|
query_params={
|
|
'type': 'lag',
|
|
}
|
|
)
|
|
mgmt_only = forms.NullBooleanField(
|
|
required=False,
|
|
widget=BulkEditNullBooleanSelect,
|
|
label='Management only'
|
|
)
|
|
mark_connected = forms.NullBooleanField(
|
|
required=False,
|
|
widget=BulkEditNullBooleanSelect
|
|
)
|
|
untagged_vlan = DynamicModelChoiceField(
|
|
queryset=VLAN.objects.all(),
|
|
required=False
|
|
)
|
|
tagged_vlans = DynamicModelMultipleChoiceField(
|
|
queryset=VLAN.objects.all(),
|
|
required=False
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = [
|
|
'label', 'parent', 'bridge', 'lag', 'mac_address', 'wwn', 'mtu', 'description', 'mode', 'rf_channel',
|
|
'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'untagged_vlan', 'tagged_vlans',
|
|
]
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
if 'device' in self.initial:
|
|
device = Device.objects.filter(pk=self.initial['device']).first()
|
|
|
|
# Restrict parent/bridge/LAG interface assignment by device
|
|
self.fields['parent'].widget.add_query_param('device_id', device.pk)
|
|
self.fields['bridge'].widget.add_query_param('device_id', device.pk)
|
|
self.fields['lag'].widget.add_query_param('device_id', device.pk)
|
|
|
|
# Limit VLAN choices by device
|
|
self.fields['untagged_vlan'].widget.add_query_param('available_on_device', device.pk)
|
|
self.fields['tagged_vlans'].widget.add_query_param('available_on_device', device.pk)
|
|
|
|
else:
|
|
# See #4523
|
|
if 'pk' in self.initial:
|
|
site = None
|
|
interfaces = Interface.objects.filter(pk__in=self.initial['pk']).prefetch_related('device__site')
|
|
|
|
# Check interface sites. First interface should set site, further interfaces will either continue the
|
|
# loop or reset back to no site and break the loop.
|
|
for interface in interfaces:
|
|
if site is None:
|
|
site = interface.device.site
|
|
elif interface.device.site is not site:
|
|
site = None
|
|
break
|
|
|
|
if site is not None:
|
|
self.fields['untagged_vlan'].widget.add_query_param('site_id', site.pk)
|
|
self.fields['tagged_vlans'].widget.add_query_param('site_id', site.pk)
|
|
|
|
self.fields['parent'].choices = ()
|
|
self.fields['parent'].widget.attrs['disabled'] = True
|
|
self.fields['bridge'].choices = ()
|
|
self.fields['bridge'].widget.attrs['disabled'] = True
|
|
self.fields['lag'].choices = ()
|
|
self.fields['lag'].widget.attrs['disabled'] = True
|
|
|
|
def clean(self):
|
|
super().clean()
|
|
|
|
# Untagged interfaces cannot be assigned tagged VLANs
|
|
if self.cleaned_data['mode'] == InterfaceModeChoices.MODE_ACCESS and self.cleaned_data['tagged_vlans']:
|
|
raise forms.ValidationError({
|
|
'mode': "An access interface cannot have tagged VLANs assigned."
|
|
})
|
|
|
|
# Remove all tagged VLAN assignments from "tagged all" interfaces
|
|
elif self.cleaned_data['mode'] == InterfaceModeChoices.MODE_TAGGED_ALL:
|
|
self.cleaned_data['tagged_vlans'] = []
|
|
|
|
|
|
class FrontPortBulkEditForm(
|
|
form_from_model(FrontPort, ['label', 'type', 'color', 'mark_connected', 'description']),
|
|
BootstrapMixin,
|
|
AddRemoveTagsForm,
|
|
CustomFieldModelBulkEditForm
|
|
):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=FrontPort.objects.all(),
|
|
widget=forms.MultipleHiddenInput()
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ['label', 'description']
|
|
|
|
|
|
class RearPortBulkEditForm(
|
|
form_from_model(RearPort, ['label', 'type', 'color', 'mark_connected', 'description']),
|
|
BootstrapMixin,
|
|
AddRemoveTagsForm,
|
|
CustomFieldModelBulkEditForm
|
|
):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=RearPort.objects.all(),
|
|
widget=forms.MultipleHiddenInput()
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ['label', 'description']
|
|
|
|
|
|
class DeviceBayBulkEditForm(
|
|
form_from_model(DeviceBay, ['label', 'description']),
|
|
BootstrapMixin,
|
|
AddRemoveTagsForm,
|
|
CustomFieldModelBulkEditForm
|
|
):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=DeviceBay.objects.all(),
|
|
widget=forms.MultipleHiddenInput()
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ['label', 'description']
|
|
|
|
|
|
class InventoryItemBulkEditForm(
|
|
form_from_model(InventoryItem, ['label', 'manufacturer', 'part_id', 'description']),
|
|
BootstrapMixin,
|
|
AddRemoveTagsForm,
|
|
CustomFieldModelBulkEditForm
|
|
):
|
|
pk = forms.ModelMultipleChoiceField(
|
|
queryset=InventoryItem.objects.all(),
|
|
widget=forms.MultipleHiddenInput()
|
|
)
|
|
manufacturer = DynamicModelChoiceField(
|
|
queryset=Manufacturer.objects.all(),
|
|
required=False
|
|
)
|
|
|
|
class Meta:
|
|
nullable_fields = ['label', 'manufacturer', 'part_id', 'description']
|