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

Closes #3880: Define constants for arbitrary values
This commit is contained in:
Jeremy Stretch 2020-01-24 15:29:38 -05:00 committed by GitHub
commit 151943bfbc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 123 additions and 48 deletions

View File

@ -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_WIDTH_DEFAULT = 230
RACK_ELEVATION_UNIT_HEIGHT_DEFAULT = 20 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 = [ VIRTUAL_IFACE_TYPES = [
InterfaceTypeChoices.TYPE_VIRTUAL, InterfaceTypeChoices.TYPE_VIRTUAL,
InterfaceTypeChoices.TYPE_LAG, InterfaceTypeChoices.TYPE_LAG,
@ -31,6 +44,17 @@ WIRELESS_IFACE_TYPES = [
NONCONNECTABLE_IFACE_TYPES = VIRTUAL_IFACE_TYPES + 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 # Cabling and connections
# #

View File

@ -5,7 +5,6 @@ from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.forms.array import SimpleArrayField from django.contrib.postgres.forms.array import SimpleArrayField
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Q
from mptt.forms import TreeNodeChoiceField from mptt.forms import TreeNodeChoiceField
from netaddr import EUI from netaddr import EUI
from netaddr.core import AddrFormatError from netaddr.core import AddrFormatError
@ -1301,8 +1300,8 @@ class RearPortTemplateCreateForm(ComponentForm):
widget=StaticSelect2(), widget=StaticSelect2(),
) )
positions = forms.IntegerField( positions = forms.IntegerField(
min_value=1, min_value=REARPORT_POSITIONS_MIN,
max_value=64, max_value=REARPORT_POSITIONS_MAX,
initial=1, initial=1,
help_text='The number of front ports which may be mapped to each rear port' 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( mtu = forms.IntegerField(
required=False, required=False,
min_value=1, min_value=INTERFACE_MTU_MIN,
max_value=32767, max_value=INTERFACE_MTU_MAX,
label='MTU' label='MTU'
) )
mgmt_only = forms.BooleanField( mgmt_only = forms.BooleanField(
@ -2620,8 +2619,8 @@ class InterfaceCreateForm(InterfaceCommonForm, ComponentForm, forms.Form):
) )
mtu = forms.IntegerField( mtu = forms.IntegerField(
required=False, required=False,
min_value=1, min_value=INTERFACE_MTU_MIN,
max_value=32767, max_value=INTERFACE_MTU_MAX,
label='MTU' label='MTU'
) )
mac_address = forms.CharField( mac_address = forms.CharField(
@ -2775,8 +2774,8 @@ class InterfaceBulkEditForm(InterfaceCommonForm, BootstrapMixin, AddRemoveTagsFo
) )
mtu = forms.IntegerField( mtu = forms.IntegerField(
required=False, required=False,
min_value=1, min_value=INTERFACE_MTU_MIN,
max_value=32767, max_value=INTERFACE_MTU_MAX,
label='MTU' label='MTU'
) )
mgmt_only = forms.NullBooleanField( mgmt_only = forms.NullBooleanField(
@ -3055,8 +3054,8 @@ class RearPortCreateForm(ComponentForm):
widget=StaticSelect2(), widget=StaticSelect2(),
) )
positions = forms.IntegerField( positions = forms.IntegerField(
min_value=1, min_value=REARPORT_POSITIONS_MIN,
max_value=64, max_value=REARPORT_POSITIONS_MAX,
initial=1, initial=1,
help_text='The number of front ports which may be mapped to each rear port' 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 required=False
) )
color = forms.CharField( color = forms.CharField(
max_length=6, max_length=6, # RGB color code
required=False, required=False,
widget=ColorSelect() widget=ColorSelect()
) )
@ -3612,7 +3611,7 @@ class CableFilterForm(BootstrapMixin, forms.Form):
widget=StaticSelect2() widget=StaticSelect2()
) )
color = forms.CharField( color = forms.CharField(
max_length=6, max_length=6, # RGB color code
required=False, required=False,
widget=ColorSelect() widget=ColorSelect()
) )

View File

@ -488,7 +488,12 @@ class RackElevationHelperMixin:
return elevation 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 Return an SVG of the rack elevation
@ -574,7 +579,7 @@ class Rack(ChangeLoggedModel, CustomFieldModel, RackElevationHelperMixin):
help_text='Rail-to-rail width' help_text='Rail-to-rail width'
) )
u_height = models.PositiveSmallIntegerField( u_height = models.PositiveSmallIntegerField(
default=42, default=RACK_U_HEIGHT_DEFAULT,
verbose_name='Height (U)', verbose_name='Height (U)',
validators=[MinValueValidator(1), MaxValueValidator(100)] validators=[MinValueValidator(1), MaxValueValidator(100)]
) )
@ -1864,15 +1869,15 @@ class PowerFeed(ChangeLoggedModel, CableTermination, CustomFieldModel):
) )
voltage = models.PositiveSmallIntegerField( voltage = models.PositiveSmallIntegerField(
validators=[MinValueValidator(1)], validators=[MinValueValidator(1)],
default=120 default=POWERFEED_VOLTAGE_DEFAULT
) )
amperage = models.PositiveSmallIntegerField( amperage = models.PositiveSmallIntegerField(
validators=[MinValueValidator(1)], validators=[MinValueValidator(1)],
default=20 default=POWERFEED_AMPERAGE_DEFAULT
) )
max_utilization = models.PositiveSmallIntegerField( max_utilization = models.PositiveSmallIntegerField(
validators=[MinValueValidator(1), MaxValueValidator(100)], validators=[MinValueValidator(1), MaxValueValidator(100)],
default=80, default=POWERFEED_MAX_UTILIZATION_DEFAULT,
help_text="Maximum permissible draw (percentage)" help_text="Maximum permissible draw (percentage)"
) )
available_power = models.PositiveIntegerField( available_power = models.PositiveIntegerField(

View File

@ -4,10 +4,34 @@ from .choices import IPAddressRoleChoices
BGP_ASN_MIN = 1 BGP_ASN_MIN = 1
BGP_ASN_MAX = 2**32 - 1 BGP_ASN_MAX = 2**32 - 1
# #
# IP addresses # 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
#
# IPAddresses
#
IPADDRESS_MASK_LENGTH_MIN = 1
IPADDRESS_MASK_LENGTH_MAX = 128 # IPv6
IPADDRESS_ROLES_NONUNIQUE = ( IPADDRESS_ROLES_NONUNIQUE = (
# IPAddress roles which are exempt from unique address enforcement # IPAddress roles which are exempt from unique address enforcement
IPAddressRoleChoices.ROLE_ANYCAST, IPAddressRoleChoices.ROLE_ANYCAST,
@ -17,3 +41,21 @@ IPADDRESS_ROLES_NONUNIQUE = (
IPAddressRoleChoices.ROLE_GLBP, IPAddressRoleChoices.ROLE_GLBP,
IPAddressRoleChoices.ROLE_CARP, 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

View File

@ -13,6 +13,7 @@ from utilities.forms import (
SlugField, StaticSelect2, StaticSelect2Multiple, BOOLEAN_WITH_BLANK_CHOICES SlugField, StaticSelect2, StaticSelect2Multiple, BOOLEAN_WITH_BLANK_CHOICES
) )
from virtualization.models import VirtualMachine from virtualization.models import VirtualMachine
from .constants import *
from .choices import * from .choices import *
from .models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF 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( prefix_length = forms.IntegerField(
min_value=1, min_value=PREFIX_LENGTH_MIN,
max_value=127, max_value=PREFIX_LENGTH_MAX,
required=False required=False
) )
tenant = forms.ModelChoiceField( tenant = forms.ModelChoiceField(
@ -896,8 +897,8 @@ class IPAddressBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEd
) )
) )
mask_length = forms.IntegerField( mask_length = forms.IntegerField(
min_value=1, min_value=IPADDRESS_MASK_LENGTH_MIN,
max_value=128, max_value=IPADDRESS_MASK_LENGTH_MAX,
required=False required=False
) )
tenant = forms.ModelChoiceField( tenant = forms.ModelChoiceField(
@ -1300,8 +1301,8 @@ class VLANFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
class ServiceForm(BootstrapMixin, CustomFieldForm): class ServiceForm(BootstrapMixin, CustomFieldForm):
port = forms.IntegerField( port = forms.IntegerField(
min_value=1, min_value=SERVICE_PORT_MIN,
max_value=65535 max_value=SERVICE_PORT_MAX
) )
tags = TagField( tags = TagField(
required=False required=False

View File

@ -14,7 +14,7 @@ from utilities.models import ChangeLoggedModel
from utilities.utils import serialize_object from utilities.utils import serialize_object
from virtualization.models import VirtualMachine from virtualization.models import VirtualMachine
from .choices import * from .choices import *
from .constants import IPADDRESS_ROLES_NONUNIQUE from .constants import *
from .fields import IPNetworkField, IPAddressField from .fields import IPNetworkField, IPAddressField
from .managers import IPAddressManager from .managers import IPAddressManager
from .querysets import PrefixQuerySet from .querysets import PrefixQuerySet
@ -44,7 +44,7 @@ class VRF(ChangeLoggedModel, CustomFieldModel):
max_length=50 max_length=50
) )
rd = models.CharField( rd = models.CharField(
max_length=21, max_length=VRF_RD_MAX_LENGTH,
unique=True, unique=True,
blank=True, blank=True,
null=True, null=True,
@ -1006,7 +1006,7 @@ class Service(ChangeLoggedModel, CustomFieldModel):
choices=ServiceProtocolChoices choices=ServiceProtocolChoices
) )
port = models.PositiveIntegerField( port = models.PositiveIntegerField(
validators=[MinValueValidator(1), MaxValueValidator(65535)], validators=[MinValueValidator(SERVICE_PORT_MIN), MaxValueValidator(SERVICE_PORT_MAX)],
verbose_name='Port number' verbose_name='Port number'
) )
ipaddresses = models.ManyToManyField( ipaddresses = models.ManyToManyField(

View File

@ -15,6 +15,7 @@ from utilities.views import (
from virtualization.models import VirtualMachine from virtualization.models import VirtualMachine
from . import filters, forms, tables from . import filters, forms, tables
from .choices import * from .choices import *
from .constants import *
from .models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF 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 Create fake records for all gaps between used VLANs
""" """
MIN_VLAN = 1
MAX_VLAN = 4094
if not vlans: 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 = [] new_vlans = []
for vlan in vlans: for vlan in vlans:
if vlan.vid - prev_vid > 1: if vlan.vid - prev_vid > 1:
new_vlans.append({'vid': prev_vid + 1, 'available': vlan.vid - prev_vid - 1}) new_vlans.append({'vid': prev_vid + 1, 'available': vlan.vid - prev_vid - 1})
prev_vid = vlan.vid prev_vid = vlan.vid
if vlans[0].vid > MIN_VLAN: if vlans[0].vid > VLAN_VID_MIN:
new_vlans.append({'vid': MIN_VLAN, 'available': vlans[0].vid - MIN_VLAN}) new_vlans.append({'vid': VLAN_VID_MIN, 'available': vlans[0].vid - VLAN_VID_MIN})
if prev_vid < MAX_VLAN: if prev_vid < VLAN_VID_MAX:
new_vlans.append({'vid': prev_vid + 1, 'available': MAX_VLAN - prev_vid}) new_vlans.append({'vid': prev_vid + 1, 'available': VLAN_VID_MAX - prev_vid})
vlans = list(vlans) + new_vlans vlans = list(vlans) + new_vlans
vlans.sort(key=lambda v: v.vid if type(v) == VLAN else v['vid']) vlans.sort(key=lambda v: v.vid if type(v) == VLAN else v['vid'])

View File

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

View File

@ -9,6 +9,7 @@ from utilities.forms import (
APISelect, APISelectMultiple, BootstrapMixin, FilterChoiceField, FlexibleModelChoiceField, SlugField, APISelect, APISelectMultiple, BootstrapMixin, FilterChoiceField, FlexibleModelChoiceField, SlugField,
StaticSelect2Multiple StaticSelect2Multiple
) )
from .constants import *
from .models import Secret, SecretRole, UserKey from .models import Secret, SecretRole, UserKey
@ -69,7 +70,7 @@ class SecretRoleCSVForm(forms.ModelForm):
class SecretForm(BootstrapMixin, CustomFieldForm): class SecretForm(BootstrapMixin, CustomFieldForm):
plaintext = forms.CharField( plaintext = forms.CharField(
max_length=65535, max_length=SECRET_PLAINTEXT_MAX_LENGTH,
required=False, required=False,
label='Plaintext', label='Plaintext',
widget=forms.PasswordInput( widget=forms.PasswordInput(
@ -79,7 +80,7 @@ class SecretForm(BootstrapMixin, CustomFieldForm):
) )
) )
plaintext2 = forms.CharField( plaintext2 = forms.CharField(
max_length=65535, max_length=SECRET_PLAINTEXT_MAX_LENGTH,
required=False, required=False,
label='Plaintext (verify)', label='Plaintext (verify)',
widget=forms.PasswordInput() widget=forms.PasswordInput()

View File

@ -13,7 +13,6 @@ from rest_framework.response import Response
from rest_framework.serializers import Field, ModelSerializer, ValidationError from rest_framework.serializers import Field, ModelSerializer, ValidationError
from rest_framework.viewsets import ModelViewSet as _ModelViewSet, ViewSet from rest_framework.viewsets import ModelViewSet as _ModelViewSet, ViewSet
from utilities.choices import ChoiceSet
from .utils import dict_to_filter_params, dynamic_import from .utils import dict_to_filter_params, dynamic_import

View File

@ -3,6 +3,7 @@ from django.core.exceptions import ValidationError
from taggit.forms import TagField from taggit.forms import TagField
from dcim.choices import InterfaceModeChoices 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.forms import INTERFACE_MODE_HELP_TEXT
from dcim.models import Device, DeviceRole, Interface, Platform, Rack, Region, Site from dcim.models import Device, DeviceRole, Interface, Platform, Rack, Region, Site
from extras.forms import AddRemoveTagsForm, CustomFieldBulkEditForm, CustomFieldForm, CustomFieldFilterForm from extras.forms import AddRemoveTagsForm, CustomFieldBulkEditForm, CustomFieldForm, CustomFieldFilterForm
@ -745,8 +746,8 @@ class InterfaceCreateForm(ComponentForm):
) )
mtu = forms.IntegerField( mtu = forms.IntegerField(
required=False, required=False,
min_value=1, min_value=INTERFACE_MTU_MIN,
max_value=32767, max_value=INTERFACE_MTU_MAX,
label='MTU' label='MTU'
) )
mac_address = forms.CharField( mac_address = forms.CharField(
@ -834,8 +835,8 @@ class InterfaceBulkEditForm(BootstrapMixin, BulkEditForm):
) )
mtu = forms.IntegerField( mtu = forms.IntegerField(
required=False, required=False,
min_value=1, min_value=INTERFACE_MTU_MIN,
max_value=32767, max_value=INTERFACE_MTU_MAX,
label='MTU' label='MTU'
) )
description = forms.CharField( description = forms.CharField(
@ -931,8 +932,8 @@ class VirtualMachineBulkAddInterfaceForm(VirtualMachineBulkAddComponentForm):
) )
mtu = forms.IntegerField( mtu = forms.IntegerField(
required=False, required=False,
min_value=1, min_value=INTERFACE_MTU_MIN,
max_value=32767, max_value=INTERFACE_MTU_MAX,
label='MTU' label='MTU'
) )
description = forms.CharField( description = forms.CharField(