diff --git a/netbox/dcim/constants.py b/netbox/dcim/constants.py index 3a6f8e5e9..0301da7d8 100644 --- a/netbox/dcim/constants.py +++ b/netbox/dcim/constants.py @@ -4,17 +4,30 @@ from .choices import InterfaceTypeChoices # -# Rack elevation rendering +# Racks # +RACK_U_HEIGHT_DEFAULT = 42 + RACK_ELEVATION_UNIT_WIDTH_DEFAULT = 230 RACK_ELEVATION_UNIT_HEIGHT_DEFAULT = 20 # -# Interface type groups +# RearPorts # +REARPORT_POSITIONS_MIN = 1 +REARPORT_POSITIONS_MAX = 64 + + +# +# Interfaces +# + +INTERFACE_MTU_MIN = 1 +INTERFACE_MTU_MAX = 32767 + VIRTUAL_IFACE_TYPES = [ InterfaceTypeChoices.TYPE_VIRTUAL, InterfaceTypeChoices.TYPE_LAG, @@ -31,6 +44,15 @@ WIRELESS_IFACE_TYPES = [ NONCONNECTABLE_IFACE_TYPES = VIRTUAL_IFACE_TYPES + WIRELESS_IFACE_TYPES +# +# PowerFeeds +# + +POWERFEED_VOLTAGE_DEFAULT = 120 +POWERFEED_AMPERAGE_DEFAULT = 20 +POWERFEED_MAX_UTILIZATION_DEFAULT = 80 # Percentage + + # # Cabling and connections # diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 79fe13a9a..f0667c143 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -5,7 +5,6 @@ from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType from django.contrib.postgres.forms.array import SimpleArrayField from django.core.exceptions import ObjectDoesNotExist -from django.db.models import Q from mptt.forms import TreeNodeChoiceField from netaddr import EUI from netaddr.core import AddrFormatError @@ -1301,8 +1300,8 @@ class RearPortTemplateCreateForm(ComponentForm): widget=StaticSelect2(), ) positions = forms.IntegerField( - min_value=1, - max_value=64, + min_value=REARPORT_POSITIONS_MIN, + max_value=REARPORT_POSITIONS_MAX, initial=1, help_text='The number of front ports which may be mapped to each rear port' ) @@ -2133,8 +2132,8 @@ class DeviceBulkAddInterfaceForm(DeviceBulkAddComponentForm): ) mtu = forms.IntegerField( required=False, - min_value=1, - max_value=32767, + min_value=INTERFACE_MTU_MIN, + max_value=INTERFACE_MTU_MAX, label='MTU' ) mgmt_only = forms.BooleanField( @@ -2620,8 +2619,8 @@ class InterfaceCreateForm(InterfaceCommonForm, ComponentForm, forms.Form): ) mtu = forms.IntegerField( required=False, - min_value=1, - max_value=32767, + min_value=INTERFACE_MTU_MIN, + max_value=INTERFACE_MTU_MAX, label='MTU' ) mac_address = forms.CharField( @@ -2775,8 +2774,8 @@ class InterfaceBulkEditForm(InterfaceCommonForm, BootstrapMixin, AddRemoveTagsFo ) mtu = forms.IntegerField( required=False, - min_value=1, - max_value=32767, + min_value=INTERFACE_MTU_MIN, + max_value=INTERFACE_MTU_MAX, label='MTU' ) mgmt_only = forms.NullBooleanField( @@ -3055,8 +3054,8 @@ class RearPortCreateForm(ComponentForm): widget=StaticSelect2(), ) positions = forms.IntegerField( - min_value=1, - max_value=64, + min_value=REARPORT_POSITIONS_MIN, + max_value=REARPORT_POSITIONS_MAX, initial=1, help_text='The number of front ports which may be mapped to each rear port' ) @@ -3533,7 +3532,7 @@ class CableBulkEditForm(BootstrapMixin, BulkEditForm): required=False ) color = forms.CharField( - max_length=6, + max_length=6, # RGB color code required=False, widget=ColorSelect() ) @@ -3612,7 +3611,7 @@ class CableFilterForm(BootstrapMixin, forms.Form): widget=StaticSelect2() ) color = forms.CharField( - max_length=6, + max_length=6, # RGB color code required=False, widget=ColorSelect() ) diff --git a/netbox/dcim/models/__init__.py b/netbox/dcim/models/__init__.py index 92cec5729..37ee0a266 100644 --- a/netbox/dcim/models/__init__.py +++ b/netbox/dcim/models/__init__.py @@ -488,7 +488,12 @@ class RackElevationHelperMixin: return elevation - def get_elevation_svg(self, face=DeviceFaceChoices.FACE_FRONT, unit_width=230, unit_height=20): + def get_elevation_svg( + self, + face=DeviceFaceChoices.FACE_FRONT, + unit_width=RACK_ELEVATION_UNIT_WIDTH_DEFAULT, + unit_height=RACK_ELEVATION_UNIT_HEIGHT_DEFAULT + ): """ Return an SVG of the rack elevation @@ -574,7 +579,7 @@ class Rack(ChangeLoggedModel, CustomFieldModel, RackElevationHelperMixin): help_text='Rail-to-rail width' ) u_height = models.PositiveSmallIntegerField( - default=42, + default=RACK_U_HEIGHT_DEFAULT, verbose_name='Height (U)', validators=[MinValueValidator(1), MaxValueValidator(100)] ) @@ -1864,15 +1869,15 @@ class PowerFeed(ChangeLoggedModel, CableTermination, CustomFieldModel): ) voltage = models.PositiveSmallIntegerField( validators=[MinValueValidator(1)], - default=120 + default=POWERFEED_VOLTAGE_DEFAULT ) amperage = models.PositiveSmallIntegerField( validators=[MinValueValidator(1)], - default=20 + default=POWERFEED_AMPERAGE_DEFAULT ) max_utilization = models.PositiveSmallIntegerField( validators=[MinValueValidator(1), MaxValueValidator(100)], - default=80, + default=POWERFEED_MAX_UTILIZATION_DEFAULT, help_text="Maximum permissible draw (percentage)" ) available_power = models.PositiveIntegerField( diff --git a/netbox/ipam/constants.py b/netbox/ipam/constants.py index cf6eb2a2a..22a977371 100644 --- a/netbox/ipam/constants.py +++ b/netbox/ipam/constants.py @@ -4,10 +4,29 @@ from .choices import IPAddressRoleChoices BGP_ASN_MIN = 1 BGP_ASN_MAX = 2**32 - 1 + # -# IP addresses +# VRFs # +VRF_RD_MAX_LENGTH = 21 + + +# +# Prefixes +# + +PREFIX_LENGTH_MIN = 1 +PREFIX_LENGTH_MAX = 127 # IPv6 + + +# +# IPAddresses +# + +IPADDRESS_MASK_LENGTH_MIN = 1 +IPADDRESS_MASK_LENGTH_MAX = 128 # IPv6 + IPADDRESS_ROLES_NONUNIQUE = ( # IPAddress roles which are exempt from unique address enforcement IPAddressRoleChoices.ROLE_ANYCAST, @@ -17,3 +36,19 @@ IPADDRESS_ROLES_NONUNIQUE = ( IPAddressRoleChoices.ROLE_GLBP, IPAddressRoleChoices.ROLE_CARP, ) + + +# +# VLANs +# + +VLAN_VID_MIN = 1 +VLAN_VID_MAX = 4094 + + +# +# Services +# + +SERVICE_PORT_MIN = 1 +SERVICE_PORT_MAX = 65535 diff --git a/netbox/ipam/forms.py b/netbox/ipam/forms.py index 265ddcb7b..d175fee4a 100644 --- a/netbox/ipam/forms.py +++ b/netbox/ipam/forms.py @@ -13,6 +13,7 @@ from utilities.forms import ( SlugField, StaticSelect2, StaticSelect2Multiple, BOOLEAN_WITH_BLANK_CHOICES ) from virtualization.models import VirtualMachine +from .constants import * from .choices import * from .models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF @@ -450,8 +451,8 @@ class PrefixBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditF ) ) prefix_length = forms.IntegerField( - min_value=1, - max_value=127, + min_value=PREFIX_LENGTH_MIN, + max_value=PREFIX_LENGTH_MAX, required=False ) tenant = forms.ModelChoiceField( @@ -896,8 +897,8 @@ class IPAddressBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEd ) ) mask_length = forms.IntegerField( - min_value=1, - max_value=128, + min_value=IPADDRESS_MASK_LENGTH_MIN, + max_value=IPADDRESS_MASK_LENGTH_MAX, required=False ) tenant = forms.ModelChoiceField( @@ -1300,8 +1301,8 @@ class VLANFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): class ServiceForm(BootstrapMixin, CustomFieldForm): port = forms.IntegerField( - min_value=1, - max_value=65535 + min_value=SERVICE_PORT_MIN, + max_value=SERVICE_PORT_MAX ) tags = TagField( required=False diff --git a/netbox/ipam/models.py b/netbox/ipam/models.py index 885d5d617..b4ba92fb5 100644 --- a/netbox/ipam/models.py +++ b/netbox/ipam/models.py @@ -14,7 +14,7 @@ from utilities.models import ChangeLoggedModel from utilities.utils import serialize_object from virtualization.models import VirtualMachine from .choices import * -from .constants import IPADDRESS_ROLES_NONUNIQUE +from .constants import * from .fields import IPNetworkField, IPAddressField from .managers import IPAddressManager from .querysets import PrefixQuerySet @@ -44,7 +44,7 @@ class VRF(ChangeLoggedModel, CustomFieldModel): max_length=50 ) rd = models.CharField( - max_length=21, + max_length=VRF_RD_MAX_LENGTH, unique=True, blank=True, null=True, @@ -1006,7 +1006,7 @@ class Service(ChangeLoggedModel, CustomFieldModel): choices=ServiceProtocolChoices ) port = models.PositiveIntegerField( - validators=[MinValueValidator(1), MaxValueValidator(65535)], + validators=[MinValueValidator(SERVICE_PORT_MIN), MaxValueValidator(SERVICE_PORT_MAX)], verbose_name='Port number' ) ipaddresses = models.ManyToManyField( diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index 5cbd55bf4..c8c7d40ca 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -15,6 +15,7 @@ from utilities.views import ( from virtualization.models import VirtualMachine from . import filters, forms, tables from .choices import * +from .constants import * from .models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF @@ -86,23 +87,20 @@ def add_available_vlans(vlan_group, vlans): """ Create fake records for all gaps between used VLANs """ - MIN_VLAN = 1 - MAX_VLAN = 4094 - if not vlans: - return [{'vid': MIN_VLAN, 'available': MAX_VLAN - MIN_VLAN + 1}] + return [{'vid': VLAN_VID_MIN, 'available': VLAN_VID_MAX - VLAN_VID_MIN + 1}] - prev_vid = MAX_VLAN + prev_vid = VLAN_VID_MAX new_vlans = [] for vlan in vlans: if vlan.vid - prev_vid > 1: new_vlans.append({'vid': prev_vid + 1, 'available': vlan.vid - prev_vid - 1}) prev_vid = vlan.vid - if vlans[0].vid > MIN_VLAN: - new_vlans.append({'vid': MIN_VLAN, 'available': vlans[0].vid - MIN_VLAN}) - if prev_vid < MAX_VLAN: - new_vlans.append({'vid': prev_vid + 1, 'available': MAX_VLAN - prev_vid}) + if vlans[0].vid > VLAN_VID_MIN: + new_vlans.append({'vid': VLAN_VID_MIN, 'available': vlans[0].vid - VLAN_VID_MIN}) + if prev_vid < VLAN_VID_MAX: + new_vlans.append({'vid': prev_vid + 1, 'available': VLAN_VID_MAX - prev_vid}) vlans = list(vlans) + new_vlans vlans.sort(key=lambda v: v.vid if type(v) == VLAN else v['vid']) diff --git a/netbox/secrets/constants.py b/netbox/secrets/constants.py new file mode 100644 index 000000000..a1c3cb3da --- /dev/null +++ b/netbox/secrets/constants.py @@ -0,0 +1,5 @@ +# +# Secrets +# + +SECRET_PLAINTEXT_MAX_LENGTH = 65535 diff --git a/netbox/secrets/forms.py b/netbox/secrets/forms.py index c937e6c92..3b81f9586 100644 --- a/netbox/secrets/forms.py +++ b/netbox/secrets/forms.py @@ -9,6 +9,7 @@ from utilities.forms import ( APISelect, APISelectMultiple, BootstrapMixin, FilterChoiceField, FlexibleModelChoiceField, SlugField, StaticSelect2Multiple ) +from .constants import * from .models import Secret, SecretRole, UserKey @@ -69,7 +70,7 @@ class SecretRoleCSVForm(forms.ModelForm): class SecretForm(BootstrapMixin, CustomFieldForm): plaintext = forms.CharField( - max_length=65535, + max_length=SECRET_PLAINTEXT_MAX_LENGTH, required=False, label='Plaintext', widget=forms.PasswordInput( @@ -79,7 +80,7 @@ class SecretForm(BootstrapMixin, CustomFieldForm): ) ) plaintext2 = forms.CharField( - max_length=65535, + max_length=SECRET_PLAINTEXT_MAX_LENGTH, required=False, label='Plaintext (verify)', widget=forms.PasswordInput() diff --git a/netbox/utilities/api.py b/netbox/utilities/api.py index 7c37a5b20..5ef4156aa 100644 --- a/netbox/utilities/api.py +++ b/netbox/utilities/api.py @@ -13,7 +13,6 @@ from rest_framework.response import Response from rest_framework.serializers import Field, ModelSerializer, ValidationError from rest_framework.viewsets import ModelViewSet as _ModelViewSet, ViewSet -from utilities.choices import ChoiceSet from .utils import dict_to_filter_params, dynamic_import diff --git a/netbox/virtualization/forms.py b/netbox/virtualization/forms.py index 910e9a39f..ae516fcb3 100644 --- a/netbox/virtualization/forms.py +++ b/netbox/virtualization/forms.py @@ -3,6 +3,7 @@ from django.core.exceptions import ValidationError from taggit.forms import TagField from dcim.choices import InterfaceModeChoices +from dcim.constants import INTERFACE_MTU_MAX, INTERFACE_MTU_MIN from dcim.forms import INTERFACE_MODE_HELP_TEXT from dcim.models import Device, DeviceRole, Interface, Platform, Rack, Region, Site from extras.forms import AddRemoveTagsForm, CustomFieldBulkEditForm, CustomFieldForm, CustomFieldFilterForm @@ -745,8 +746,8 @@ class InterfaceCreateForm(ComponentForm): ) mtu = forms.IntegerField( required=False, - min_value=1, - max_value=32767, + min_value=INTERFACE_MTU_MIN, + max_value=INTERFACE_MTU_MAX, label='MTU' ) mac_address = forms.CharField( @@ -834,8 +835,8 @@ class InterfaceBulkEditForm(BootstrapMixin, BulkEditForm): ) mtu = forms.IntegerField( required=False, - min_value=1, - max_value=32767, + min_value=INTERFACE_MTU_MIN, + max_value=INTERFACE_MTU_MAX, label='MTU' ) description = forms.CharField( @@ -931,8 +932,8 @@ class VirtualMachineBulkAddInterfaceForm(VirtualMachineBulkAddComponentForm): ) mtu = forms.IntegerField( required=False, - min_value=1, - max_value=32767, + min_value=INTERFACE_MTU_MIN, + max_value=INTERFACE_MTU_MAX, label='MTU' ) description = forms.CharField(