Fix filterset tests for VMInterface

This commit is contained in:
Brian Tiemann 2024-10-31 14:31:49 -04:00
parent a631b69dc0
commit 5be20924e7
8 changed files with 75 additions and 57 deletions

View File

@ -1099,10 +1099,10 @@ class DeviceFilterSet(
field_name='device_type__is_full_depth', field_name='device_type__is_full_depth',
label=_('Is full depth'), label=_('Is full depth'),
) )
# mac_address = MultiValueMACAddressFilter( mac_address = MultiValueMACAddressFilter(
# field_name='interfaces___mac_address', field_name='interfaces__mac_addresses__mac_address',
# label=_('MAC address'), label=_('MAC address'),
# ) )
serial = MultiValueCharFilter( serial = MultiValueCharFilter(
lookup_expr='iexact' lookup_expr='iexact'
) )
@ -1849,7 +1849,10 @@ class InterfaceFilterSet(
duplex = django_filters.MultipleChoiceFilter( duplex = django_filters.MultipleChoiceFilter(
choices=InterfaceDuplexChoices choices=InterfaceDuplexChoices
) )
# mac_address = MultiValueMACAddressFilter() mac_address = MultiValueMACAddressFilter(
field_name='mac_addresses__mac_address',
label=_('MAC Address')
)
wwn = MultiValueWWNFilter() wwn = MultiValueWWNFilter()
poe_mode = django_filters.MultipleChoiceFilter( poe_mode = django_filters.MultipleChoiceFilter(
choices=InterfacePoEModeChoices choices=InterfacePoEModeChoices

View File

@ -1344,7 +1344,7 @@ class InterfaceFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
fieldsets = ( fieldsets = (
FieldSet('q', 'filter_id', 'tag'), FieldSet('q', 'filter_id', 'tag'),
FieldSet('name', 'label', 'kind', 'type', 'speed', 'duplex', 'enabled', 'mgmt_only', name=_('Attributes')), FieldSet('name', 'label', 'kind', 'type', 'speed', 'duplex', 'enabled', 'mgmt_only', name=_('Attributes')),
FieldSet('vrf_id', 'l2vpn_id', 'wwn', name=_('Addressing')), FieldSet('vrf_id', 'l2vpn_id', 'mac_address', 'wwn', name=_('Addressing')),
FieldSet('poe_mode', 'poe_type', name=_('PoE')), FieldSet('poe_mode', 'poe_type', name=_('PoE')),
FieldSet('rf_role', 'rf_channel', 'rf_channel_width', 'tx_power', name=_('Wireless')), FieldSet('rf_role', 'rf_channel', 'rf_channel_width', 'tx_power', name=_('Wireless')),
FieldSet('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', name=_('Location')), FieldSet('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', name=_('Location')),
@ -1399,10 +1399,10 @@ class InterfaceFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
# mac_address = forms.CharField( mac_address = forms.CharField(
# required=False, required=False,
# label=_('MAC address') label=_('MAC address')
# ) )
wwn = forms.CharField( wwn = forms.CharField(
required=False, required=False,
label=_('WWN') label=_('WWN')

View File

@ -3988,6 +3988,10 @@ class InterfaceTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil
params = {'kind': 'virtual'} params = {'kind': 'virtual'}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 0) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 0)
def test_mac_address(self):
params = {'mac_address': ['00-00-00-00-00-01', '00-00-00-00-00-02']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_type(self): def test_type(self):
params = {'type': [InterfaceTypeChoices.TYPE_1GE_FIXED, InterfaceTypeChoices.TYPE_1GE_GBIC]} params = {'type': [InterfaceTypeChoices.TYPE_1GE_FIXED, InterfaceTypeChoices.TYPE_1GE_GBIC]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)

View File

@ -168,6 +168,8 @@ class BaseFilterSet(django_filters.FilterSet):
# Get properties of the existing filter for later use # Get properties of the existing filter for later use
field_name = existing_filter.field_name field_name = existing_filter.field_name
field = get_model_field(cls._meta.model, field_name) field = get_model_field(cls._meta.model, field_name)
if field is None:
raise ValueError('Invalid field name/lookup on {}: {}'.format(existing_filter_name, field_name))
# Create new filters for each lookup expression in the map # Create new filters for each lookup expression in the map
for lookup_name, lookup_expr in lookup_map.items(): for lookup_name, lookup_expr in lookup_map.items():

View File

@ -5,46 +5,46 @@
{% load i18n %} {% load i18n %}
{% block content %} {% block content %}
<div class="row"> <div class="row">
<div class="col col-md-4"> <div class="col col-md-4">
<div class="card"> <div class="card">
<h2 class="card-header">{% trans "MAC Address" %}</h2> <h2 class="card-header">{% trans "MAC Address" %}</h2>
<table class="table table-hover attr-table"> <table class="table table-hover attr-table">
<tr> <tr>
<th scope="row">{% trans "Description" %}</th> <th scope="row">{% trans "Description" %}</th>
<td>{{ object.description|placeholder }}</td> <td>{{ object.description|placeholder }}</td>
</tr> </tr>
<tr> <tr>
<th scope="row">{% trans "Assignment" %}</th> <th scope="row">{% trans "Assignment" %}</th>
<td> <td>
{% if object.assigned_object %} {% if object.assigned_object %}
{% if object.assigned_object.parent_object %} {% if object.assigned_object.parent_object %}
{{ object.assigned_object.parent_object|linkify }} / {{ object.assigned_object.parent_object|linkify }} /
{% endif %} {% endif %}
{{ object.assigned_object|linkify }} {{ object.assigned_object|linkify }}
{% else %} {% else %}
{{ ''|placeholder }} {{ ''|placeholder }}
{% endif %} {% endif %}
</td> </td>
</tr> </tr>
<tr> <tr>
<th scope="row">{% trans "Primary MAC for Interface" %}</th> <th scope="row">{% trans "Primary MAC for Interface" %}</th>
<td>{% checkmark object.is_primary %}</td> <td>{% checkmark object.is_primary %}</td>
</tr> </tr>
</table> </table>
</div> </div>
{% include 'inc/panels/tags.html' %} {% include 'inc/panels/tags.html' %}
{% include 'inc/panels/custom_fields.html' %} {% include 'inc/panels/custom_fields.html' %}
{% plugin_left_page object %} {% plugin_left_page object %}
</div> </div>
<div class="col col-md-8"> <div class="col col-md-8">
{% include 'inc/panels/comments.html' %} {% include 'inc/panels/comments.html' %}
{% plugin_right_page object %} {% plugin_right_page object %}
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col col-md-12"> <div class="col col-md-12">
{% plugin_full_width_page object %} {% plugin_full_width_page object %}
</div>
</div> </div>
</div>
{% endblock %} {% endblock %}

View File

@ -9,7 +9,7 @@ from extras.models import ConfigTemplate
from ipam.filtersets import PrimaryIPFilterSet from ipam.filtersets import PrimaryIPFilterSet
from netbox.filtersets import OrganizationalModelFilterSet, NetBoxModelFilterSet from netbox.filtersets import OrganizationalModelFilterSet, NetBoxModelFilterSet
from tenancy.filtersets import TenancyFilterSet, ContactModelFilterSet from tenancy.filtersets import TenancyFilterSet, ContactModelFilterSet
from utilities.filters import MultiValueCharFilter, TreeNodeMultipleChoiceFilter from utilities.filters import MultiValueCharFilter, TreeNodeMultipleChoiceFilter, MultiValueMACAddressFilter
from .choices import * from .choices import *
from .models import * from .models import *
@ -297,9 +297,10 @@ class VMInterfaceFilterSet(NetBoxModelFilterSet, CommonInterfaceFilterSet):
queryset=VMInterface.objects.all(), queryset=VMInterface.objects.all(),
label=_('Bridged interface (ID)'), label=_('Bridged interface (ID)'),
) )
# _mac_address = MultiValueMACAddressFilter( mac_address = MultiValueMACAddressFilter(
# label=_('MAC address'), field_name='mac_addresses__mac_address',
# ) label=_('MAC address'),
)
class Meta: class Meta:
model = VMInterface model = VMInterface

View File

@ -195,7 +195,7 @@ class VMInterfaceFilterForm(NetBoxModelFilterSetForm):
fieldsets = ( fieldsets = (
FieldSet('q', 'filter_id', 'tag'), FieldSet('q', 'filter_id', 'tag'),
FieldSet('cluster_id', 'virtual_machine_id', name=_('Virtual Machine')), FieldSet('cluster_id', 'virtual_machine_id', name=_('Virtual Machine')),
FieldSet('enabled', 'vrf_id', 'l2vpn_id', name=_('Attributes')), FieldSet('enabled', 'mac_address', 'vrf_id', 'l2vpn_id', name=_('Attributes')),
) )
selector_fields = ('filter_id', 'q', 'virtual_machine_id') selector_fields = ('filter_id', 'q', 'virtual_machine_id')
cluster_id = DynamicModelMultipleChoiceField( cluster_id = DynamicModelMultipleChoiceField(
@ -218,10 +218,10 @@ class VMInterfaceFilterForm(NetBoxModelFilterSetForm):
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
# mac_address = forms.CharField( mac_address = forms.CharField(
# required=False, required=False,
# label=_('MAC address') label=_('MAC address')
# ) )
vrf_id = DynamicModelMultipleChoiceField( vrf_id = DynamicModelMultipleChoiceField(
queryset=VRF.objects.all(), queryset=VRF.objects.all(),
required=False, required=False,

View File

@ -1,6 +1,6 @@
from django.test import TestCase from django.test import TestCase
from dcim.models import Device, DeviceRole, Platform, Region, Site, SiteGroup from dcim.models import Device, DeviceRole, MACAddress, Platform, Region, Site, SiteGroup
from ipam.models import IPAddress, VLANTranslationPolicy, VRF from ipam.models import IPAddress, VLANTranslationPolicy, VRF
from tenancy.models import Tenant, TenantGroup from tenancy.models import Tenant, TenantGroup
from utilities.testing import ChangeLoggedFilterSetTests, create_test_device from utilities.testing import ChangeLoggedFilterSetTests, create_test_device
@ -568,13 +568,19 @@ class VMInterfaceTestCase(TestCase, ChangeLoggedFilterSetTests):
) )
VLANTranslationPolicy.objects.bulk_create(vlan_translation_policies) VLANTranslationPolicy.objects.bulk_create(vlan_translation_policies)
mac_addresses = (
MACAddress(mac_address='00-00-00-00-00-01'),
MACAddress(mac_address='00-00-00-00-00-02'),
MACAddress(mac_address='00-00-00-00-00-03'),
)
MACAddress.objects.bulk_create(mac_addresses)
interfaces = ( interfaces = (
VMInterface( VMInterface(
virtual_machine=vms[0], virtual_machine=vms[0],
name='Interface 1', name='Interface 1',
enabled=True, enabled=True,
mtu=100, mtu=100,
mac_address='00-00-00-00-00-01',
vrf=vrfs[0], vrf=vrfs[0],
description='foobar1', description='foobar1',
vlan_translation_policy=vlan_translation_policies[0], vlan_translation_policy=vlan_translation_policies[0],
@ -584,7 +590,6 @@ class VMInterfaceTestCase(TestCase, ChangeLoggedFilterSetTests):
name='Interface 2', name='Interface 2',
enabled=True, enabled=True,
mtu=200, mtu=200,
mac_address='00-00-00-00-00-02',
vrf=vrfs[1], vrf=vrfs[1],
description='foobar2', description='foobar2',
vlan_translation_policy=vlan_translation_policies[0], vlan_translation_policy=vlan_translation_policies[0],
@ -594,13 +599,16 @@ class VMInterfaceTestCase(TestCase, ChangeLoggedFilterSetTests):
name='Interface 3', name='Interface 3',
enabled=False, enabled=False,
mtu=300, mtu=300,
mac_address='00-00-00-00-00-03',
vrf=vrfs[2], vrf=vrfs[2],
description='foobar3' description='foobar3'
), ),
) )
VMInterface.objects.bulk_create(interfaces) VMInterface.objects.bulk_create(interfaces)
interfaces[0].mac_addresses.set([mac_addresses[0]])
interfaces[1].mac_addresses.set([mac_addresses[1]])
interfaces[2].mac_addresses.set([mac_addresses[2]])
def test_q(self): def test_q(self):
params = {'q': 'foobar1'} params = {'q': 'foobar1'}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)