diff --git a/CHANGELOG.md b/CHANGELOG.md index a34a3deec..346e0effe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ v2.6.4 (FUTURE) * [#3027](https://github.com/netbox-community/netbox/issues/3028) - Add `local_context_data` boolean filter for devices * [#3318](https://github.com/netbox-community/netbox/issues/3318) - Increase length of platform name and slug to 100 characters * [#3341](https://github.com/netbox-community/netbox/issues/3341) - Enable inline VLAN assignment while editing an interface +* [#3510](https://github.com/netbox-community/netbox/issues/3510) - Add minimum/maximum prefix length enforcement for `IPNetworkVar` ## Bug Fixes diff --git a/netbox/extras/scripts.py b/netbox/extras/scripts.py index 842133671..4f1133603 100644 --- a/netbox/extras/scripts.py +++ b/netbox/extras/scripts.py @@ -16,6 +16,7 @@ from mptt.models import MPTTModel from ipam.formfields import IPFormField from utilities.exceptions import AbortTransaction +from utilities.validators import MaxPrefixLengthValidator, MinPrefixLengthValidator from .constants import LOG_DEFAULT, LOG_FAILURE, LOG_INFO, LOG_SUCCESS, LOG_WARNING from .forms import ScriptForm from .signals import purge_changelog @@ -162,6 +163,21 @@ class IPNetworkVar(ScriptVariable): """ form_field = IPFormField + def __init__(self, min_prefix_length=None, max_prefix_length=None, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.field_attrs['validators'] = list() + + # Optional minimum/maximum prefix lengths + if min_prefix_length is not None: + self.field_attrs['validators'].append( + MinPrefixLengthValidator(min_prefix_length) + ) + if max_prefix_length is not None: + self.field_attrs['validators'].append( + MaxPrefixLengthValidator(max_prefix_length) + ) + # # Scripts diff --git a/netbox/utilities/validators.py b/netbox/utilities/validators.py index cfa733208..fb7a5bba7 100644 --- a/netbox/utilities/validators.py +++ b/netbox/utilities/validators.py @@ -1,6 +1,6 @@ import re -from django.core.validators import _lazy_re_compile, URLValidator +from django.core.validators import _lazy_re_compile, BaseValidator, URLValidator class EnhancedURLValidator(URLValidator): @@ -26,3 +26,19 @@ class EnhancedURLValidator(URLValidator): r'(?:[/?#][^\s]*)?' # Path r'\Z', re.IGNORECASE) schemes = AnyURLScheme() + + +class MaxPrefixLengthValidator(BaseValidator): + message = 'The prefix length must be less than or equal to %(limit_value)s.' + code = 'max_prefix_length' + + def compare(self, a, b): + return a.prefixlen > b + + +class MinPrefixLengthValidator(BaseValidator): + message = 'The prefix length must be greater than or equal to %(limit_value)s.' + code = 'min_prefix_length' + + def compare(self, a, b): + return a.prefixlen < b