1
0
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:
Jeremy Stretch
2017-03-01 14:23:52 -05:00
parent 1adae67dd7
commit db60e8868c
4 changed files with 40 additions and 3 deletions

View File

@ -6,7 +6,7 @@ from django.db import models
from .formfields import IPFormField from .formfields import IPFormField
from .lookups import ( from .lookups import (
EndsWith, IEndsWith, IRegex, IStartsWith, NetContained, NetContainedOrEqual, NetContains, NetContainsOrEquals, 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(NetContains)
IPNetworkField.register_lookup(NetContainsOrEquals) IPNetworkField.register_lookup(NetContainsOrEquals)
IPNetworkField.register_lookup(NetHost) IPNetworkField.register_lookup(NetHost)
IPNetworkField.register_lookup(NetMaskLength)
class IPAddressField(BaseIPField): class IPAddressField(BaseIPField):
@ -90,3 +91,4 @@ IPAddressField.register_lookup(NetContainedOrEqual)
IPAddressField.register_lookup(NetContains) IPAddressField.register_lookup(NetContains)
IPAddressField.register_lookup(NetContainsOrEquals) IPAddressField.register_lookup(NetContainsOrEquals)
IPAddressField.register_lookup(NetHost) IPAddressField.register_lookup(NetHost)
IPAddressField.register_lookup(NetMaskLength)

View File

@ -92,6 +92,10 @@ class PrefixFilter(CustomFieldFilterSet, django_filters.FilterSet):
method='search_by_parent', method='search_by_parent',
label='Parent prefix', label='Parent prefix',
) )
mask_length = django_filters.NumberFilter(
method='filter_mask_length',
label='Mask length',
)
vrf_id = NullableModelMultipleChoiceFilter( vrf_id = NullableModelMultipleChoiceFilter(
name='vrf_id', name='vrf_id',
queryset=VRF.objects.all(), queryset=VRF.objects.all(),
@ -171,6 +175,11 @@ class PrefixFilter(CustomFieldFilterSet, django_filters.FilterSet):
except AddrFormatError: except AddrFormatError:
return queryset.none() 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): class IPAddressFilter(CustomFieldFilterSet, django_filters.FilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
@ -181,6 +190,10 @@ class IPAddressFilter(CustomFieldFilterSet, django_filters.FilterSet):
method='search_by_parent', method='search_by_parent',
label='Parent prefix', label='Parent prefix',
) )
mask_length = django_filters.NumberFilter(
method='filter_mask_length',
label='Mask length',
)
vrf_id = NullableModelMultipleChoiceFilter( vrf_id = NullableModelMultipleChoiceFilter(
name='vrf_id', name='vrf_id',
queryset=VRF.objects.all(), queryset=VRF.objects.all(),
@ -245,6 +258,11 @@ class IPAddressFilter(CustomFieldFilterSet, django_filters.FilterSet):
except AddrFormatError: except AddrFormatError:
return queryset.none() 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): class VLANGroupFilter(django_filters.FilterSet):
site_id = NullableModelMultipleChoiceFilter( site_id = NullableModelMultipleChoiceFilter(

View File

@ -21,6 +21,12 @@ IP_FAMILY_CHOICES = [
(6, 'IPv6'), (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 # VRFs
@ -266,6 +272,7 @@ class PrefixFilterForm(BootstrapMixin, CustomFieldFilterForm):
'placeholder': 'Prefix', '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=PREFIX_MASK_LENGTH_CHOICES, label='Mask length')
vrf = FilterChoiceField( vrf = FilterChoiceField(
queryset=VRF.objects.annotate(filter_count=Count('prefixes')), queryset=VRF.objects.annotate(filter_count=Count('prefixes')),
to_field_name='rd', to_field_name='rd',
@ -503,7 +510,8 @@ class IPAddressFilterForm(BootstrapMixin, CustomFieldFilterForm):
parent = forms.CharField(required=False, label='Parent Prefix', widget=forms.TextInput(attrs={ parent = forms.CharField(required=False, label='Parent Prefix', widget=forms.TextInput(attrs={
'placeholder': 'Prefix', '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( vrf = FilterChoiceField(
queryset=VRF.objects.annotate(filter_count=Count('ip_addresses')), queryset=VRF.objects.annotate(filter_count=Count('ip_addresses')),
to_field_name='rd', to_field_name='rd',

View File

@ -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 from django.db.models.lookups import BuiltinLookup
@ -87,3 +87,12 @@ class NetHost(Lookup):
rhs_params[0] = rhs_params[0].split('/')[0] rhs_params[0] = rhs_params[0].split('/')[0]
params = lhs_params + rhs_params params = lhs_params + rhs_params
return 'HOST(%s) = %s' % (lhs, 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()