Просмотр исходного кода

Merge pull request #4007 from netbox-community/3880-use-constants

Closes #3880: Define constants for arbitrary values
Jeremy Stretch 6 лет назад
Родитель
Сommit
151943bfbc

+ 26 - 2
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  # Max value of a signed 16-bit integer
+
 VIRTUAL_IFACE_TYPES = [
     InterfaceTypeChoices.TYPE_VIRTUAL,
     InterfaceTypeChoices.TYPE_LAG,
@@ -31,6 +44,17 @@ 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
 #

+ 12 - 13
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()
     )

+ 10 - 5
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(

+ 43 - 1
netbox/ipam/constants.py

@@ -4,10 +4,34 @@ from .choices import IPAddressRoleChoices
 BGP_ASN_MIN = 1
 BGP_ASN_MAX = 2**32 - 1
 
+
+#
+# VRFs
+#
+
+# Per RFC 4364 section 4.2, a route distinguisher may be encoded as one of the following:
+#   * Type 0 (16-bit AS number : 32-bit integer)
+#   * Type 1 (32-bit IPv4 address : 16-bit integer)
+#   * Type 2 (32-bit AS number : 16-bit integer)
+# 21 characters are sufficient to convey the longest possible string value (255.255.255.255:65535)
+VRF_RD_MAX_LENGTH = 21
+
+
+#
+# Prefixes
+#
+
+PREFIX_LENGTH_MIN = 1
+PREFIX_LENGTH_MAX = 127  # IPv6
+
+
 #
-# IP addresses
+# 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 +41,21 @@ IPADDRESS_ROLES_NONUNIQUE = (
     IPAddressRoleChoices.ROLE_GLBP,
     IPAddressRoleChoices.ROLE_CARP,
 )
+
+
+#
+# VLANs
+#
+
+# 12-bit VLAN ID (values 0 and 4095 are reserved)
+VLAN_VID_MIN = 1
+VLAN_VID_MAX = 4094
+
+
+#
+# Services
+#
+
+# 16-bit port number
+SERVICE_PORT_MIN = 1
+SERVICE_PORT_MAX = 65535

+ 7 - 6
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

+ 3 - 3
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(

+ 7 - 9
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'])

+ 5 - 0
netbox/secrets/constants.py

@@ -0,0 +1,5 @@
+#
+# Secrets
+#
+
+SECRET_PLAINTEXT_MAX_LENGTH = 65535

+ 3 - 2
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()

+ 0 - 1
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
 
 

+ 7 - 6
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(