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 .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)
|
||||||
|
@ -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(
|
||||||
|
@ -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',
|
||||||
|
@ -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()
|
||||||
|
Reference in New Issue
Block a user