1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Introduce IPAddressVar and IPAddressWithMaskVar

This commit is contained in:
Jeremy Stretch
2020-01-22 17:14:31 -05:00
parent aa56c020ab
commit f41564b578
4 changed files with 69 additions and 17 deletions

View File

@ -124,7 +124,7 @@ Arbitrary text of any length. Renders as multi-line text input field.
Stored a numeric integer. Options include: Stored a numeric integer. Options include:
* `min_value:` - Minimum value * `min_value` - Minimum value
* `max_value` - Maximum value * `max_value` - Maximum value
### BooleanVar ### BooleanVar
@ -158,9 +158,20 @@ A NetBox object. The list of available objects is defined by the queryset parame
An uploaded file. Note that uploaded files are present in memory only for the duration of the script's execution: They will not be save for future use. An uploaded file. Note that uploaded files are present in memory only for the duration of the script's execution: They will not be save for future use.
### IPAddressVar
An IPv4 or IPv6 address, without a mask. Returns a `netaddr.IPAddress` object.
### IPAddressWithMaskVar
An IPv4 or IPv6 address with a mask. Returns a `netaddr.IPNetwork` object which includes the mask.
### IPNetworkVar ### IPNetworkVar
An IPv4 or IPv6 network with a mask. An IPv4 or IPv6 network with a mask. Returns a `netaddr.IPNetwork` object. Two attributes are available to validate the provided mask:
* `min_prefix_length` - Minimum length of the mask (default: none)
* `max_prefix_length` - Maximum length of the mask (default: none)
### Default Options ### Default Options

View File

@ -14,10 +14,10 @@ from django.db import transaction
from mptt.forms import TreeNodeChoiceField, TreeNodeMultipleChoiceField from mptt.forms import TreeNodeChoiceField, TreeNodeMultipleChoiceField
from mptt.models import MPTTModel from mptt.models import MPTTModel
from ipam.formfields import IPFormField from ipam.formfields import IPAddressFormField, IPNetworkFormField
from utilities.exceptions import AbortTransaction from ipam.validators import MaxPrefixLengthValidator, MinPrefixLengthValidator, prefix_validator
from ipam.validators import MaxPrefixLengthValidator, MinPrefixLengthValidator
from .constants import LOG_DEFAULT, LOG_FAILURE, LOG_INFO, LOG_SUCCESS, LOG_WARNING from .constants import LOG_DEFAULT, LOG_FAILURE, LOG_INFO, LOG_SUCCESS, LOG_WARNING
from utilities.exceptions import AbortTransaction
from .forms import ScriptForm from .forms import ScriptForm
from .signals import purge_changelog from .signals import purge_changelog
@ -27,6 +27,8 @@ __all__ = [
'ChoiceVar', 'ChoiceVar',
'FileVar', 'FileVar',
'IntegerVar', 'IntegerVar',
'IPAddressVar',
'IPAddressWithMaskVar',
'IPNetworkVar', 'IPNetworkVar',
'MultiObjectVar', 'MultiObjectVar',
'ObjectVar', 'ObjectVar',
@ -48,15 +50,19 @@ class ScriptVariable:
def __init__(self, label='', description='', default=None, required=True): def __init__(self, label='', description='', default=None, required=True):
# Default field attributes # Initialize field attributes
self.field_attrs = { if not hasattr(self, 'field_attrs'):
'help_text': description, self.field_attrs = {}
'required': required if description:
} self.field_attrs['help_text'] = description
if label: if label:
self.field_attrs['label'] = label self.field_attrs['label'] = label
if default: if default:
self.field_attrs['initial'] = default self.field_attrs['initial'] = default
if required:
self.field_attrs['required'] = True
if 'validators' not in self.field_attrs:
self.field_attrs['validators'] = []
def as_field(self): def as_field(self):
""" """
@ -196,17 +202,32 @@ class FileVar(ScriptVariable):
form_field = forms.FileField form_field = forms.FileField
class IPAddressVar(ScriptVariable):
"""
An IPv4 or IPv6 address without a mask.
"""
form_field = IPAddressFormField
class IPAddressWithMaskVar(ScriptVariable):
"""
An IPv4 or IPv6 address with a mask.
"""
form_field = IPNetworkFormField
class IPNetworkVar(ScriptVariable): class IPNetworkVar(ScriptVariable):
""" """
An IPv4 or IPv6 prefix. An IPv4 or IPv6 prefix.
""" """
form_field = IPFormField form_field = IPNetworkFormField
field_attrs = {
'validators': [prefix_validator]
}
def __init__(self, min_prefix_length=None, max_prefix_length=None, *args, **kwargs): def __init__(self, min_prefix_length=None, max_prefix_length=None, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.field_attrs['validators'] = list()
# Optional minimum/maximum prefix lengths # Optional minimum/maximum prefix lengths
if min_prefix_length is not None: if min_prefix_length is not None:
self.field_attrs['validators'].append( self.field_attrs['validators'].append(

View File

@ -3,7 +3,7 @@ from django.db import models
from netaddr import AddrFormatError, IPNetwork from netaddr import AddrFormatError, IPNetwork
from . import lookups, validators from . import lookups, validators
from .formfields import IPFormField from .formfields import IPNetworkFormField
class BaseIPField(models.Field): class BaseIPField(models.Field):
@ -33,7 +33,7 @@ class BaseIPField(models.Field):
return str(self.to_python(value)) return str(self.to_python(value))
def form_class(self): def form_class(self):
return IPFormField return IPNetworkFormField
def formfield(self, **kwargs): def formfield(self, **kwargs):
defaults = {'form_class': self.form_class()} defaults = {'form_class': self.form_class()}

View File

@ -1,13 +1,33 @@
from django import forms from django import forms
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from netaddr import IPNetwork, AddrFormatError from netaddr import IPAddress, IPNetwork, AddrFormatError
# #
# Form fields # Form fields
# #
class IPFormField(forms.Field): class IPAddressFormField(forms.Field):
default_error_messages = {
'invalid': "Enter a valid IPv4 or IPv6 address (without a mask).",
}
def to_python(self, value):
if not value:
return None
if isinstance(value, IPAddress):
return value
try:
return IPAddress(value)
except ValueError:
raise ValidationError('This field requires an IP address without a mask.')
except AddrFormatError:
raise ValidationError("Please specify a valid IPv4 or IPv6 address.")
class IPNetworkFormField(forms.Field):
default_error_messages = { default_error_messages = {
'invalid': "Enter a valid IPv4 or IPv6 address (with CIDR mask).", 'invalid': "Enter a valid IPv4 or IPv6 address (with CIDR mask).",
} }