Fixes: #18579 Add contact filters to services (#18818)

* Add Contact filter to Services

* Add ContactModelFilterForm to ProviderAccountFilterForm

* Add Contact filter support for Aggregate

* Add Contact filter support for Prefix

* Add Contact filter to IPRange

* Add Contact filter to IPAddress

* Add Contact filter to L2VPN

* Add Contact filter to TunnelGroup

* Add Contact filter to Tunnel

* Add ContactModelFilterSet to ProviderAccountFilterSet

* Fixes classes inheritance order

Setup NetBoxModelFilterSetForm as the last inherited class

Co-authored-by: Jason Novinger <jnovinger@gmail.com>

---------

Co-authored-by: Jason Novinger <jnovinger@gmail.com>
This commit is contained in:
Renato Almeida de Oliveira 2025-03-06 12:41:41 -03:00 committed by GitHub
parent 2d35cc56ed
commit 3ef7ab4416
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 35 additions and 22 deletions

View File

@ -95,7 +95,7 @@ class ProviderFilterSet(NetBoxModelFilterSet, ContactModelFilterSet):
)
class ProviderAccountFilterSet(NetBoxModelFilterSet):
class ProviderAccountFilterSet(NetBoxModelFilterSet, ContactModelFilterSet):
provider_id = django_filters.ModelMultipleChoiceFilter(
queryset=Provider.objects.all(),
label=_('Provider (ID)'),

View File

@ -66,11 +66,12 @@ class ProviderFilterForm(ContactModelFilterForm, NetBoxModelFilterSetForm):
tag = TagFilterField(model)
class ProviderAccountFilterForm(NetBoxModelFilterSetForm):
class ProviderAccountFilterForm(ContactModelFilterForm, NetBoxModelFilterSetForm):
model = ProviderAccount
fieldsets = (
FieldSet('q', 'filter_id', 'tag'),
FieldSet('provider_id', 'account', name=_('Attributes')),
FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')),
)
provider_id = DynamicModelMultipleChoiceField(
queryset=Provider.objects.all(),

View File

@ -12,7 +12,8 @@ from netaddr.core import AddrFormatError
from circuits.models import Provider
from dcim.models import Device, Interface, Region, Site, SiteGroup
from netbox.filtersets import ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, NetBoxModelFilterSet
from tenancy.filtersets import TenancyFilterSet
from tenancy.filtersets import ContactModelFilterSet, TenancyFilterSet
from utilities.filters import (
ContentTypeFilter, MultiValueCharFilter, MultiValueNumberFilter, NumericArrayFilter, TreeNodeMultipleChoiceFilter,
)
@ -148,7 +149,7 @@ class RIRFilterSet(OrganizationalModelFilterSet):
fields = ('id', 'name', 'slug', 'is_private', 'description')
class AggregateFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
class AggregateFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
family = django_filters.NumberFilter(
field_name='prefix',
lookup_expr='family'
@ -276,7 +277,7 @@ class RoleFilterSet(OrganizationalModelFilterSet):
fields = ('id', 'name', 'slug', 'description', 'weight')
class PrefixFilterSet(NetBoxModelFilterSet, ScopedFilterSet, TenancyFilterSet):
class PrefixFilterSet(NetBoxModelFilterSet, ScopedFilterSet, TenancyFilterSet, ContactModelFilterSet):
family = django_filters.NumberFilter(
field_name='prefix',
lookup_expr='family'
@ -430,7 +431,7 @@ class PrefixFilterSet(NetBoxModelFilterSet, ScopedFilterSet, TenancyFilterSet):
).distinct()
class IPRangeFilterSet(TenancyFilterSet, NetBoxModelFilterSet):
class IPRangeFilterSet(TenancyFilterSet, NetBoxModelFilterSet, ContactModelFilterSet):
family = django_filters.NumberFilter(
field_name='start_address',
lookup_expr='family'
@ -522,7 +523,7 @@ class IPRangeFilterSet(TenancyFilterSet, NetBoxModelFilterSet):
return queryset.filter(q)
class IPAddressFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
class IPAddressFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
family = django_filters.NumberFilter(
field_name='address',
lookup_expr='family'
@ -1136,7 +1137,7 @@ class ServiceTemplateFilterSet(NetBoxModelFilterSet):
return queryset.filter(qs_filter)
class ServiceFilterSet(NetBoxModelFilterSet):
class ServiceFilterSet(ContactModelFilterSet, NetBoxModelFilterSet):
device_id = django_filters.ModelMultipleChoiceFilter(
queryset=Device.objects.all(),
label=_('Device (ID)'),

View File

@ -6,7 +6,7 @@ from ipam.choices import *
from ipam.constants import *
from ipam.models import *
from netbox.forms import NetBoxModelFilterSetForm
from tenancy.forms import TenancyFilterForm
from tenancy.forms import ContactModelFilterForm, TenancyFilterForm
from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES, add_blank_choice
from utilities.forms.fields import DynamicModelChoiceField, DynamicModelMultipleChoiceField, TagFilterField
from utilities.forms.rendering import FieldSet
@ -94,12 +94,13 @@ class RIRFilterForm(NetBoxModelFilterSetForm):
tag = TagFilterField(model)
class AggregateFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
class AggregateFilterForm(ContactModelFilterForm, TenancyFilterForm, NetBoxModelFilterSetForm):
model = Aggregate
fieldsets = (
FieldSet('q', 'filter_id', 'tag'),
FieldSet('family', 'rir_id', name=_('Attributes')),
FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')),
)
family = forms.ChoiceField(
required=False,
@ -162,7 +163,7 @@ class RoleFilterForm(NetBoxModelFilterSetForm):
tag = TagFilterField(model)
class PrefixFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
class PrefixFilterForm(ContactModelFilterForm, TenancyFilterForm, NetBoxModelFilterSetForm, ):
model = Prefix
fieldsets = (
FieldSet('q', 'filter_id', 'tag'),
@ -174,6 +175,7 @@ class PrefixFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
FieldSet('vrf_id', 'present_in_vrf_id', name=_('VRF')),
FieldSet('region_id', 'site_group_id', 'site_id', 'location_id', name=_('Scope')),
FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')),
)
mask_length__lte = forms.IntegerField(
widget=forms.HiddenInput()
@ -262,12 +264,13 @@ class PrefixFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
tag = TagFilterField(model)
class IPRangeFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
class IPRangeFilterForm(ContactModelFilterForm, TenancyFilterForm, NetBoxModelFilterSetForm):
model = IPRange
fieldsets = (
FieldSet('q', 'filter_id', 'tag'),
FieldSet('family', 'vrf_id', 'status', 'role_id', 'mark_utilized', name=_('Attributes')),
FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')),
)
family = forms.ChoiceField(
required=False,
@ -301,7 +304,7 @@ class IPRangeFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
tag = TagFilterField(model)
class IPAddressFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
class IPAddressFilterForm(ContactModelFilterForm, TenancyFilterForm, NetBoxModelFilterSetForm):
model = IPAddress
fieldsets = (
FieldSet('q', 'filter_id', 'tag'),
@ -312,6 +315,7 @@ class IPAddressFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
FieldSet('vrf_id', 'present_in_vrf_id', name=_('VRF')),
FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
FieldSet('device_id', 'virtual_machine_id', name=_('Device/VM')),
FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')),
)
selector_fields = ('filter_id', 'q', 'region_id', 'group_id', 'parent', 'status', 'role')
parent = forms.CharField(
@ -590,12 +594,13 @@ class ServiceTemplateFilterForm(NetBoxModelFilterSetForm):
tag = TagFilterField(model)
class ServiceFilterForm(ServiceTemplateFilterForm):
class ServiceFilterForm(ContactModelFilterForm, ServiceTemplateFilterForm):
model = Service
fieldsets = (
FieldSet('q', 'filter_id', 'tag'),
FieldSet('protocol', 'port', name=_('Attributes')),
FieldSet('device_id', 'virtual_machine_id', name=_('Assignment')),
FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')),
)
device_id = DynamicModelMultipleChoiceField(
queryset=Device.objects.all(),

View File

@ -5,7 +5,7 @@ from django.utils.translation import gettext as _
from dcim.models import Device, Interface
from ipam.models import IPAddress, RouteTarget, VLAN
from netbox.filtersets import NetBoxModelFilterSet, OrganizationalModelFilterSet
from tenancy.filtersets import TenancyFilterSet
from tenancy.filtersets import ContactModelFilterSet, TenancyFilterSet
from utilities.filters import ContentTypeFilter, MultiValueCharFilter, MultiValueNumberFilter
from virtualization.models import VirtualMachine, VMInterface
from .choices import *
@ -25,14 +25,14 @@ __all__ = (
)
class TunnelGroupFilterSet(OrganizationalModelFilterSet):
class TunnelGroupFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet):
class Meta:
model = TunnelGroup
fields = ('id', 'name', 'slug', 'description')
class TunnelFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
class TunnelFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
status = django_filters.MultipleChoiceFilter(
choices=TunnelStatusChoices
)
@ -293,7 +293,7 @@ class IPSecProfileFilterSet(NetBoxModelFilterSet):
)
class L2VPNFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
class L2VPNFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
type = django_filters.MultipleChoiceFilter(
choices=L2VPNTypeChoices,
null_value=None

View File

@ -5,7 +5,7 @@ from django.utils.translation import gettext as _
from dcim.models import Device, Region, Site
from ipam.models import RouteTarget, VLAN
from netbox.forms import NetBoxModelFilterSetForm
from tenancy.forms import TenancyFilterForm
from tenancy.forms import ContactModelFilterForm, TenancyFilterForm
from utilities.forms.fields import (
ContentTypeMultipleChoiceField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, TagFilterField,
)
@ -30,18 +30,23 @@ __all__ = (
)
class TunnelGroupFilterForm(NetBoxModelFilterSetForm):
class TunnelGroupFilterForm(ContactModelFilterForm, NetBoxModelFilterSetForm):
model = TunnelGroup
fieldsets = (
FieldSet('q', 'filter_id', 'tag'),
FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')),
)
tag = TagFilterField(model)
class TunnelFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
class TunnelFilterForm(ContactModelFilterForm, TenancyFilterForm, NetBoxModelFilterSetForm):
model = Tunnel
fieldsets = (
FieldSet('q', 'filter_id', 'tag'),
FieldSet('status', 'encapsulation', 'tunnel_id', name=_('Tunnel')),
FieldSet('ipsec_profile_id', name=_('Security')),
FieldSet('tenant_group_id', 'tenant_id', name=_('Tenancy')),
FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')),
)
status = forms.MultipleChoiceField(
label=_('Status'),
@ -206,12 +211,13 @@ class IPSecProfileFilterForm(NetBoxModelFilterSetForm):
tag = TagFilterField(model)
class L2VPNFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
class L2VPNFilterForm(ContactModelFilterForm, TenancyFilterForm, NetBoxModelFilterSetForm):
model = L2VPN
fieldsets = (
FieldSet('q', 'filter_id', 'tag'),
FieldSet('type', 'import_target_id', 'export_target_id', name=_('Attributes')),
FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')),
)
type = forms.ChoiceField(
label=_('Type'),