mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-20 12:22:23 -06:00
Fixes #3315: Enable filtering devices/interfaces by multiple MAC addresses
This commit is contained in:
@@ -2,15 +2,14 @@ import django_filters
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db.models import Q
|
||||
from netaddr import EUI
|
||||
from netaddr.core import AddrFormatError
|
||||
|
||||
from extras.filters import CustomFieldFilterSet
|
||||
from tenancy.filtersets import TenancyFilterSet
|
||||
from tenancy.models import Tenant
|
||||
from utilities.constants import COLOR_CHOICES
|
||||
from utilities.filters import (
|
||||
MultiValueNumberFilter, NameSlugSearchFilterSet, NumericInFilter, TagFilter, TreeNodeMultipleChoiceFilter,
|
||||
MultiValueMACAddressFilter, MultiValueNumberFilter, NameSlugSearchFilterSet, NumericInFilter, TagFilter,
|
||||
TreeNodeMultipleChoiceFilter,
|
||||
)
|
||||
from virtualization.models import Cluster
|
||||
from .constants import *
|
||||
@@ -516,8 +515,8 @@ class DeviceFilter(TenancyFilterSet, CustomFieldFilterSet):
|
||||
field_name='device_type__is_full_depth',
|
||||
label='Is full depth',
|
||||
)
|
||||
mac_address = django_filters.CharFilter(
|
||||
method='_mac_address',
|
||||
mac_address = MultiValueMACAddressFilter(
|
||||
field_name='interfaces__mac_address',
|
||||
label='MAC address',
|
||||
)
|
||||
has_primary_ip = django_filters.BooleanFilter(
|
||||
@@ -574,16 +573,6 @@ class DeviceFilter(TenancyFilterSet, CustomFieldFilterSet):
|
||||
Q(comments__icontains=value)
|
||||
).distinct()
|
||||
|
||||
def _mac_address(self, queryset, name, value):
|
||||
value = value.strip()
|
||||
if not value:
|
||||
return queryset
|
||||
try:
|
||||
mac = EUI(value.strip())
|
||||
return queryset.filter(interfaces__mac_address=mac).distinct()
|
||||
except AddrFormatError:
|
||||
return queryset.none()
|
||||
|
||||
def _has_primary_ip(self, queryset, name, value):
|
||||
if value:
|
||||
return queryset.filter(
|
||||
@@ -726,10 +715,7 @@ class InterfaceFilter(django_filters.FilterSet):
|
||||
queryset=Interface.objects.all(),
|
||||
label='LAG interface (ID)',
|
||||
)
|
||||
mac_address = django_filters.CharFilter(
|
||||
method='_mac_address',
|
||||
label='MAC address',
|
||||
)
|
||||
mac_address = MultiValueMACAddressFilter()
|
||||
tag = TagFilter()
|
||||
vlan_id = django_filters.CharFilter(
|
||||
method='filter_vlan_id',
|
||||
@@ -801,16 +787,6 @@ class InterfaceFilter(django_filters.FilterSet):
|
||||
'wireless': queryset.filter(type__in=WIRELESS_IFACE_TYPES),
|
||||
}.get(value, queryset.none())
|
||||
|
||||
def _mac_address(self, queryset, name, value):
|
||||
value = value.strip()
|
||||
if not value:
|
||||
return queryset
|
||||
try:
|
||||
mac = EUI(value.strip())
|
||||
return queryset.filter(mac_address=mac)
|
||||
except AddrFormatError:
|
||||
return queryset.none()
|
||||
|
||||
|
||||
class FrontPortFilter(DeviceComponentFilterSet):
|
||||
cabled = django_filters.BooleanFilter(
|
||||
|
||||
@@ -7,6 +7,8 @@ from django.contrib.postgres.forms.array import SimpleArrayField
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db.models import Q
|
||||
from mptt.forms import TreeNodeChoiceField
|
||||
from netaddr import EUI
|
||||
from netaddr.core import AddrFormatError
|
||||
from taggit.forms import TagField
|
||||
from timezone_field import TimeZoneFormField
|
||||
|
||||
@@ -76,6 +78,28 @@ class BulkRenameForm(forms.Form):
|
||||
})
|
||||
|
||||
|
||||
#
|
||||
# Fields
|
||||
#
|
||||
|
||||
class MACAddressField(forms.Field):
|
||||
widget = forms.CharField
|
||||
default_error_messages = {
|
||||
'invalid': 'MAC address must be in EUI-48 format',
|
||||
}
|
||||
|
||||
def to_python(self, value):
|
||||
value = super().to_python(value)
|
||||
|
||||
# Validate MAC address format
|
||||
try:
|
||||
value = EUI(value.strip())
|
||||
except AddrFormatError:
|
||||
raise forms.ValidationError(self.error_messages['invalid'], code='invalid')
|
||||
|
||||
return value
|
||||
|
||||
|
||||
#
|
||||
# Regions
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user