mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Closes #901: Support for filtering prefixes and IP addresses by mask length
This commit is contained in:
@ -6,7 +6,7 @@ from django.db import models
|
||||
from .formfields import IPFormField
|
||||
from .lookups import (
|
||||
EndsWith, IEndsWith, IRegex, IStartsWith, NetContained, NetContainedOrEqual, NetContains, NetContainsOrEquals,
|
||||
NetHost, Regex, StartsWith,
|
||||
NetHost, NetMaskLength, Regex, StartsWith,
|
||||
)
|
||||
|
||||
|
||||
@ -67,6 +67,7 @@ IPNetworkField.register_lookup(NetContainedOrEqual)
|
||||
IPNetworkField.register_lookup(NetContains)
|
||||
IPNetworkField.register_lookup(NetContainsOrEquals)
|
||||
IPNetworkField.register_lookup(NetHost)
|
||||
IPNetworkField.register_lookup(NetMaskLength)
|
||||
|
||||
|
||||
class IPAddressField(BaseIPField):
|
||||
@ -90,3 +91,4 @@ IPAddressField.register_lookup(NetContainedOrEqual)
|
||||
IPAddressField.register_lookup(NetContains)
|
||||
IPAddressField.register_lookup(NetContainsOrEquals)
|
||||
IPAddressField.register_lookup(NetHost)
|
||||
IPAddressField.register_lookup(NetMaskLength)
|
||||
|
@ -92,6 +92,10 @@ class PrefixFilter(CustomFieldFilterSet, django_filters.FilterSet):
|
||||
method='search_by_parent',
|
||||
label='Parent prefix',
|
||||
)
|
||||
mask_length = django_filters.NumberFilter(
|
||||
method='filter_mask_length',
|
||||
label='Mask length',
|
||||
)
|
||||
vrf_id = NullableModelMultipleChoiceFilter(
|
||||
name='vrf_id',
|
||||
queryset=VRF.objects.all(),
|
||||
@ -171,6 +175,11 @@ class PrefixFilter(CustomFieldFilterSet, django_filters.FilterSet):
|
||||
except AddrFormatError:
|
||||
return queryset.none()
|
||||
|
||||
def filter_mask_length(self, queryset, name, value):
|
||||
if not value:
|
||||
return queryset
|
||||
return queryset.filter(prefix__net_mask_length=value)
|
||||
|
||||
|
||||
class IPAddressFilter(CustomFieldFilterSet, django_filters.FilterSet):
|
||||
q = django_filters.CharFilter(
|
||||
@ -181,6 +190,10 @@ class IPAddressFilter(CustomFieldFilterSet, django_filters.FilterSet):
|
||||
method='search_by_parent',
|
||||
label='Parent prefix',
|
||||
)
|
||||
mask_length = django_filters.NumberFilter(
|
||||
method='filter_mask_length',
|
||||
label='Mask length',
|
||||
)
|
||||
vrf_id = NullableModelMultipleChoiceFilter(
|
||||
name='vrf_id',
|
||||
queryset=VRF.objects.all(),
|
||||
@ -245,6 +258,11 @@ class IPAddressFilter(CustomFieldFilterSet, django_filters.FilterSet):
|
||||
except AddrFormatError:
|
||||
return queryset.none()
|
||||
|
||||
def filter_mask_length(self, queryset, name, value):
|
||||
if not value:
|
||||
return queryset
|
||||
return queryset.filter(address__net_mask_length=value)
|
||||
|
||||
|
||||
class VLANGroupFilter(django_filters.FilterSet):
|
||||
site_id = NullableModelMultipleChoiceFilter(
|
||||
|
@ -21,6 +21,12 @@ IP_FAMILY_CHOICES = [
|
||||
(6, 'IPv6'),
|
||||
]
|
||||
|
||||
PREFIX_MASK_LENGTH_CHOICES = [
|
||||
('', '---------'),
|
||||
] + [(i, i) for i in range(1, 128)]
|
||||
|
||||
IPADDRESS_MASK_LENGTH_CHOICES = PREFIX_MASK_LENGTH_CHOICES + [(128, 128)]
|
||||
|
||||
|
||||
#
|
||||
# VRFs
|
||||
@ -266,6 +272,7 @@ class PrefixFilterForm(BootstrapMixin, CustomFieldFilterForm):
|
||||
'placeholder': 'Prefix',
|
||||
}))
|
||||
family = forms.ChoiceField(required=False, choices=IP_FAMILY_CHOICES, label='Address family')
|
||||
mask_length = forms.ChoiceField(required=False, choices=PREFIX_MASK_LENGTH_CHOICES, label='Mask length')
|
||||
vrf = FilterChoiceField(
|
||||
queryset=VRF.objects.annotate(filter_count=Count('prefixes')),
|
||||
to_field_name='rd',
|
||||
@ -503,7 +510,8 @@ class IPAddressFilterForm(BootstrapMixin, CustomFieldFilterForm):
|
||||
parent = forms.CharField(required=False, label='Parent Prefix', widget=forms.TextInput(attrs={
|
||||
'placeholder': 'Prefix',
|
||||
}))
|
||||
family = forms.ChoiceField(required=False, choices=IP_FAMILY_CHOICES, label='Address Family')
|
||||
family = forms.ChoiceField(required=False, choices=IP_FAMILY_CHOICES, label='Address family')
|
||||
mask_length = forms.ChoiceField(required=False, choices=IPADDRESS_MASK_LENGTH_CHOICES, label='Mask length')
|
||||
vrf = FilterChoiceField(
|
||||
queryset=VRF.objects.annotate(filter_count=Count('ip_addresses')),
|
||||
to_field_name='rd',
|
||||
|
@ -1,4 +1,4 @@
|
||||
from django.db.models import Lookup
|
||||
from django.db.models import Lookup, Transform, IntegerField
|
||||
from django.db.models.lookups import BuiltinLookup
|
||||
|
||||
|
||||
@ -87,3 +87,12 @@ class NetHost(Lookup):
|
||||
rhs_params[0] = rhs_params[0].split('/')[0]
|
||||
params = lhs_params + rhs_params
|
||||
return 'HOST(%s) = %s' % (lhs, rhs), params
|
||||
|
||||
|
||||
class NetMaskLength(Transform):
|
||||
lookup_name = 'net_mask_length'
|
||||
function = 'MASKLEN'
|
||||
|
||||
@property
|
||||
def output_field(self):
|
||||
return IntegerField()
|
||||
|
Reference in New Issue
Block a user