netbox/netbox/ipam/filters.py

535 lines
16 KiB
Python
Raw Normal View History

2016-03-01 11:23:03 -05:00
import django_filters
2018-11-02 15:20:08 -04:00
import netaddr
from django.core.exceptions import ValidationError
from django.db.models import Q
2016-03-01 11:23:03 -05:00
from netaddr.core import AddrFormatError
from dcim.models import Device, Interface, Region, Site
from extras.filters import CustomFieldFilterSet, CreatedUpdatedFilterSet
2020-01-09 21:05:38 -05:00
from tenancy.filters import TenancyFilterSet
from utilities.filters import (
MultiValueCharFilter, MultiValueNumberFilter, NameSlugSearchFilterSet, NumericInFilter, TagFilter, TreeNodeMultipleChoiceFilter,
)
from virtualization.models import VirtualMachine
2019-11-27 21:46:53 -05:00
from .choices import *
from .models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF
2016-03-01 11:23:03 -05:00
2020-01-08 17:20:31 -05:00
__all__ = (
2020-01-09 20:37:26 -05:00
'AggregateFilterSet',
'IPAddressFilterSet',
'PrefixFilterSet',
'RIRFilterSet',
'RoleFilterSet',
'ServiceFilterSet',
'VLANFilterSet',
'VLANGroupFilterSet',
'VRFFilterSet',
2020-01-08 17:20:31 -05:00
)
2020-01-09 20:37:26 -05:00
class VRFFilterSet(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter(
method='search',
label='Search',
)
tag = TagFilter()
2016-03-01 11:23:03 -05:00
def search(self, queryset, name, value):
if not value.strip():
return queryset
return queryset.filter(
Q(name__icontains=value) |
Q(rd__icontains=value) |
Q(description__icontains=value)
)
class Meta:
model = VRF
fields = ['name', 'rd', 'enforce_unique']
2016-03-01 11:23:03 -05:00
2020-01-09 20:37:26 -05:00
class RIRFilterSet(NameSlugSearchFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
class Meta:
model = RIR
fields = ['name', 'slug', 'is_private']
2020-01-09 20:37:26 -05:00
class AggregateFilterSet(CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter(
method='search',
label='Search',
)
prefix = django_filters.CharFilter(
method='filter_prefix',
label='Prefix',
)
2016-03-01 11:23:03 -05:00
rir_id = django_filters.ModelMultipleChoiceFilter(
queryset=RIR.objects.all(),
label='RIR (ID)',
)
rir = django_filters.ModelMultipleChoiceFilter(
2018-11-02 13:46:28 -04:00
field_name='rir__slug',
2016-03-01 11:23:03 -05:00
queryset=RIR.objects.all(),
to_field_name='slug',
label='RIR (slug)',
)
tag = TagFilter()
2016-03-01 11:23:03 -05:00
class Meta:
model = Aggregate
fields = ('date_added',)
2016-03-01 11:23:03 -05:00
def search(self, queryset, name, value):
if not value.strip():
return queryset
qs_filter = Q(description__icontains=value)
try:
prefix = str(netaddr.IPNetwork(value.strip()).cidr)
qs_filter |= Q(prefix__net_contains_or_equals=prefix)
except (AddrFormatError, ValueError):
pass
return queryset.filter(qs_filter)
def filter_prefix(self, queryset, name, value):
if not value.strip():
return queryset
try:
query = str(netaddr.IPNetwork(value).cidr)
return queryset.filter(prefix=query)
except ValidationError:
return queryset.none()
2016-03-01 11:23:03 -05:00
2020-01-09 20:37:26 -05:00
class RoleFilterSet(NameSlugSearchFilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
)
class Meta:
model = Role
fields = ['id', 'name', 'slug']
2020-01-09 20:37:26 -05:00
class PrefixFilterSet(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter(
method='search',
2016-03-01 11:23:03 -05:00
label='Search',
)
prefix = django_filters.CharFilter(
method='filter_prefix',
label='Prefix',
)
within = django_filters.CharFilter(
method='search_within',
label='Within prefix',
)
within_include = django_filters.CharFilter(
method='search_within_include',
label='Within and including prefix',
2016-03-01 11:23:03 -05:00
)
contains = django_filters.CharFilter(
method='search_contains',
label='Prefixes which contain this prefix or IP',
)
mask_length = django_filters.NumberFilter(
method='filter_mask_length',
label='Mask length',
)
vrf_id = django_filters.ModelMultipleChoiceFilter(
queryset=VRF.objects.all(),
label='VRF',
2016-03-01 11:23:03 -05:00
)
vrf = django_filters.ModelMultipleChoiceFilter(
2018-11-02 13:46:28 -04:00
field_name='vrf__rd',
queryset=VRF.objects.all(),
to_field_name='rd',
label='VRF (RD)',
)
region_id = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='site__region__in',
label='Region (ID)',
)
region = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='site__region__in',
to_field_name='slug',
label='Region (slug)',
)
site_id = django_filters.ModelMultipleChoiceFilter(
2016-03-01 11:23:03 -05:00
queryset=Site.objects.all(),
label='Site (ID)',
)
site = django_filters.ModelMultipleChoiceFilter(
2018-11-02 13:46:28 -04:00
field_name='site__slug',
2016-03-01 11:23:03 -05:00
queryset=Site.objects.all(),
to_field_name='slug',
label='Site (slug)',
)
vlan_id = django_filters.ModelMultipleChoiceFilter(
2016-03-01 11:23:03 -05:00
queryset=VLAN.objects.all(),
label='VLAN (ID)',
)
vlan_vid = django_filters.NumberFilter(
2018-11-02 13:46:28 -04:00
field_name='vlan__vid',
2016-03-01 11:23:03 -05:00
label='VLAN number (1-4095)',
)
role_id = django_filters.ModelMultipleChoiceFilter(
2016-03-01 11:23:03 -05:00
queryset=Role.objects.all(),
label='Role (ID)',
)
role = django_filters.ModelMultipleChoiceFilter(
2018-11-02 13:46:28 -04:00
field_name='role__slug',
2016-03-01 11:23:03 -05:00
queryset=Role.objects.all(),
to_field_name='slug',
label='Role (slug)',
)
status = django_filters.MultipleChoiceFilter(
2019-11-27 21:46:53 -05:00
choices=PrefixStatusChoices,
null_value=None
)
tag = TagFilter()
2016-03-01 11:23:03 -05:00
class Meta:
model = Prefix
fields = ('is_pool',)
2016-03-01 11:23:03 -05:00
def search(self, queryset, name, value):
if not value.strip():
return queryset
qs_filter = Q(description__icontains=value)
try:
prefix = str(netaddr.IPNetwork(value.strip()).cidr)
qs_filter |= Q(prefix__net_contains_or_equals=prefix)
except (AddrFormatError, ValueError):
pass
return queryset.filter(qs_filter)
def filter_prefix(self, queryset, name, value):
if not value.strip():
return queryset
try:
query = str(netaddr.IPNetwork(value).cidr)
return queryset.filter(prefix=query)
except ValidationError:
return queryset.none()
def search_within(self, queryset, name, value):
value = value.strip()
if not value:
return queryset
try:
query = str(netaddr.IPNetwork(value).cidr)
return queryset.filter(prefix__net_contained=query)
except (AddrFormatError, ValueError):
return queryset.none()
def search_within_include(self, queryset, name, value):
2016-03-01 11:23:03 -05:00
value = value.strip()
if not value:
return queryset
try:
query = str(netaddr.IPNetwork(value).cidr)
2016-03-01 11:23:03 -05:00
return queryset.filter(prefix__net_contained_or_equal=query)
except (AddrFormatError, ValueError):
2016-03-01 11:23:03 -05:00
return queryset.none()
def search_contains(self, queryset, name, value):
value = value.strip()
if not value:
return queryset
try:
# Searching by prefix
if '/' in value:
return queryset.filter(prefix__net_contains_or_equals=str(netaddr.IPNetwork(value).cidr))
# Searching by IP address
else:
return queryset.filter(prefix__net_contains=str(netaddr.IPAddress(value)))
except (AddrFormatError, ValueError):
return queryset.none()
def filter_mask_length(self, queryset, name, value):
if not value:
return queryset
return queryset.filter(prefix__net_mask_length=value)
2016-03-01 11:23:03 -05:00
2020-01-09 20:37:26 -05:00
class IPAddressFilterSet(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter(
method='search',
2016-03-01 11:23:03 -05:00
label='Search',
)
parent = django_filters.CharFilter(
method='search_by_parent',
label='Parent prefix',
)
2020-01-10 14:06:21 -05:00
address = MultiValueCharFilter(
method='filter_address',
label='Address',
)
mask_length = django_filters.NumberFilter(
method='filter_mask_length',
label='Mask length',
)
vrf_id = django_filters.ModelMultipleChoiceFilter(
queryset=VRF.objects.all(),
label='VRF',
2016-03-01 11:23:03 -05:00
)
vrf = django_filters.ModelMultipleChoiceFilter(
2018-11-02 13:46:28 -04:00
field_name='vrf__rd',
queryset=VRF.objects.all(),
to_field_name='rd',
label='VRF (RD)',
)
device = MultiValueCharFilter(
method='filter_device',
field_name='name',
label='Device (name)',
)
device_id = MultiValueNumberFilter(
method='filter_device',
field_name='pk',
2016-03-01 11:23:03 -05:00
label='Device (ID)',
)
virtual_machine_id = django_filters.ModelMultipleChoiceFilter(
2018-11-02 13:46:28 -04:00
field_name='interface__virtual_machine',
queryset=VirtualMachine.objects.all(),
label='Virtual machine (ID)',
)
virtual_machine = django_filters.ModelMultipleChoiceFilter(
2018-11-02 13:46:28 -04:00
field_name='interface__virtual_machine__name',
queryset=VirtualMachine.objects.all(),
to_field_name='name',
label='Virtual machine (name)',
)
interface = django_filters.ModelMultipleChoiceFilter(
field_name='interface__name',
queryset=Interface.objects.all(),
to_field_name='name',
label='Interface (ID)',
)
2016-03-01 11:23:03 -05:00
interface_id = django_filters.ModelMultipleChoiceFilter(
queryset=Interface.objects.all(),
label='Interface (ID)',
)
assigned_to_interface = django_filters.BooleanFilter(
method='_assigned_to_interface',
label='Is assigned to an interface',
)
status = django_filters.MultipleChoiceFilter(
2019-11-27 21:54:01 -05:00
choices=IPAddressStatusChoices,
null_value=None
)
role = django_filters.MultipleChoiceFilter(
2019-11-27 22:09:16 -05:00
choices=IPAddressRoleChoices
)
tag = TagFilter()
2016-03-01 11:23:03 -05:00
class Meta:
model = IPAddress
fields = ('dns_name',)
2016-03-01 11:23:03 -05:00
def search(self, queryset, name, value):
if not value.strip():
return queryset
qs_filter = (
2019-04-22 18:10:28 -04:00
Q(dns_name__icontains=value) |
Q(description__icontains=value) |
Q(address__istartswith=value)
)
return queryset.filter(qs_filter)
2016-03-01 11:23:03 -05:00
def search_by_parent(self, queryset, name, value):
value = value.strip()
if not value:
return queryset
try:
query = str(netaddr.IPNetwork(value.strip()).cidr)
return queryset.filter(address__net_host_contained=query)
except (AddrFormatError, ValueError):
return queryset.none()
def filter_address(self, queryset, name, value):
try:
2020-01-12 16:44:15 -05:00
return queryset.filter(address__net_in=value)
except ValidationError:
return queryset.none()
def filter_mask_length(self, queryset, name, value):
if not value:
return queryset
return queryset.filter(address__net_mask_length=value)
def filter_device(self, queryset, name, value):
try:
devices = Device.objects.prefetch_related('device_type').filter(**{'{}__in'.format(name): value})
vc_interface_ids = []
for device in devices:
vc_interface_ids.extend([i['id'] for i in device.vc_interfaces.values('id')])
return queryset.filter(interface_id__in=vc_interface_ids)
except Device.DoesNotExist:
return queryset.none()
def _assigned_to_interface(self, queryset, name, value):
return queryset.exclude(interface__isnull=value)
2016-03-01 11:23:03 -05:00
2020-01-09 20:37:26 -05:00
class VLANGroupFilterSet(NameSlugSearchFilterSet):
region_id = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='site__region__in',
label='Region (ID)',
)
region = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='site__region__in',
to_field_name='slug',
label='Region (slug)',
)
site_id = django_filters.ModelMultipleChoiceFilter(
2016-07-15 13:26:54 -04:00
queryset=Site.objects.all(),
label='Site (ID)',
)
site = django_filters.ModelMultipleChoiceFilter(
2018-11-02 13:46:28 -04:00
field_name='site__slug',
2016-07-15 13:26:54 -04:00
queryset=Site.objects.all(),
to_field_name='slug',
label='Site (slug)',
)
class Meta:
model = VLANGroup
fields = ['id', 'name', 'slug']
2016-07-15 13:26:54 -04:00
2020-01-09 20:37:26 -05:00
class VLANFilterSet(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter(
method='search',
label='Search',
)
region_id = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='site__region__in',
label='Region (ID)',
)
region = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='site__region__in',
to_field_name='slug',
label='Region (slug)',
)
site_id = django_filters.ModelMultipleChoiceFilter(
2016-03-01 11:23:03 -05:00
queryset=Site.objects.all(),
label='Site (ID)',
)
site = django_filters.ModelMultipleChoiceFilter(
2018-11-02 13:46:28 -04:00
field_name='site__slug',
2016-03-01 11:23:03 -05:00
queryset=Site.objects.all(),
to_field_name='slug',
label='Site (slug)',
)
group_id = django_filters.ModelMultipleChoiceFilter(
2016-07-15 13:26:54 -04:00
queryset=VLANGroup.objects.all(),
label='Group (ID)',
)
group = django_filters.ModelMultipleChoiceFilter(
2018-11-02 13:46:28 -04:00
field_name='group__slug',
2016-07-15 13:26:54 -04:00
queryset=VLANGroup.objects.all(),
to_field_name='slug',
label='Group',
)
role_id = django_filters.ModelMultipleChoiceFilter(
2016-03-01 11:23:03 -05:00
queryset=Role.objects.all(),
label='Role (ID)',
)
role = django_filters.ModelMultipleChoiceFilter(
2018-11-02 13:46:28 -04:00
field_name='role__slug',
2016-03-01 11:23:03 -05:00
queryset=Role.objects.all(),
to_field_name='slug',
label='Role (slug)',
)
status = django_filters.MultipleChoiceFilter(
2019-11-27 22:15:59 -05:00
choices=VLANStatusChoices,
null_value=None
)
tag = TagFilter()
2016-03-01 11:23:03 -05:00
class Meta:
model = VLAN
fields = ['vid', 'name']
def search(self, queryset, name, value):
if not value.strip():
return queryset
qs_filter = Q(name__icontains=value) | Q(description__icontains=value)
try:
qs_filter |= Q(vid=int(value.strip()))
except ValueError:
pass
return queryset.filter(qs_filter)
2020-01-09 20:37:26 -05:00
class ServiceFilterSet(CreatedUpdatedFilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
)
2016-12-26 11:58:27 -05:00
device_id = django_filters.ModelMultipleChoiceFilter(
queryset=Device.objects.all(),
label='Device (ID)',
)
device = django_filters.ModelMultipleChoiceFilter(
2018-11-02 13:46:28 -04:00
field_name='device__name',
2016-12-26 11:58:27 -05:00
queryset=Device.objects.all(),
to_field_name='name',
label='Device (name)',
)
virtual_machine_id = django_filters.ModelMultipleChoiceFilter(
queryset=VirtualMachine.objects.all(),
label='Virtual machine (ID)',
)
virtual_machine = django_filters.ModelMultipleChoiceFilter(
2018-11-02 13:46:28 -04:00
field_name='virtual_machine__name',
queryset=VirtualMachine.objects.all(),
to_field_name='name',
label='Virtual machine (name)',
)
tag = TagFilter()
class Meta:
model = Service
fields = ['id', 'name', 'protocol', 'port']
def search(self, queryset, name, value):
if not value.strip():
return queryset
qs_filter = Q(name__icontains=value) | Q(description__icontains=value)
return queryset.filter(qs_filter)