mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-17 20:46:30 -06:00
Enable filtering FHRP groups by related IP addresses
This commit is contained in:
parent
bb4f3e1789
commit
f48d7aedce
@ -624,6 +624,10 @@ class FHRPGroupFilterSet(PrimaryModelFilterSet):
|
|||||||
auth_type = django_filters.MultipleChoiceFilter(
|
auth_type = django_filters.MultipleChoiceFilter(
|
||||||
choices=FHRPGroupAuthTypeChoices
|
choices=FHRPGroupAuthTypeChoices
|
||||||
)
|
)
|
||||||
|
related_ip = django_filters.ModelMultipleChoiceFilter(
|
||||||
|
queryset=IPAddress.objects.all(),
|
||||||
|
method='filter_related_ip'
|
||||||
|
)
|
||||||
tag = TagFilter()
|
tag = TagFilter()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -637,6 +641,26 @@ class FHRPGroupFilterSet(PrimaryModelFilterSet):
|
|||||||
Q(description__icontains=value)
|
Q(description__icontains=value)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def filter_related_ip(self, queryset, name, value):
|
||||||
|
"""
|
||||||
|
Filter by VRF & prefix of assigned IP addresses.
|
||||||
|
"""
|
||||||
|
ip_filter = Q()
|
||||||
|
for ipaddress in value:
|
||||||
|
if ipaddress.vrf:
|
||||||
|
q = Q(
|
||||||
|
ip_addresses__address__net_contained_or_equal=ipaddress.address,
|
||||||
|
ip_addresses__vrf=ipaddress.vrf
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
q = Q(
|
||||||
|
ip_addresses__address__net_contained_or_equal=ipaddress.address,
|
||||||
|
ip_addresses__vrf__isnull=True
|
||||||
|
)
|
||||||
|
ip_filter |= q
|
||||||
|
|
||||||
|
return queryset.filter(ip_filter)
|
||||||
|
|
||||||
|
|
||||||
class FHRPGroupAssignmentFilterSet(ChangeLoggedModelFilterSet):
|
class FHRPGroupAssignmentFilterSet(ChangeLoggedModelFilterSet):
|
||||||
content_type = ContentTypeFilter()
|
content_type = ContentTypeFilter()
|
||||||
|
@ -546,6 +546,13 @@ class FHRPGroupAssignmentForm(BootstrapMixin, forms.ModelForm):
|
|||||||
model = FHRPGroupAssignment
|
model = FHRPGroupAssignment
|
||||||
fields = ('group', 'priority')
|
fields = ('group', 'priority')
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
ipaddresses = self.instance.object.ip_addresses.all()
|
||||||
|
for ipaddress in ipaddresses:
|
||||||
|
self.fields['group'].widget.add_query_param('related_ip', ipaddress.pk)
|
||||||
|
|
||||||
|
|
||||||
class VLANGroupForm(BootstrapMixin, CustomFieldModelForm):
|
class VLANGroupForm(BootstrapMixin, CustomFieldModelForm):
|
||||||
scope_type = ContentTypeChoiceField(
|
scope_type = ContentTypeChoiceField(
|
||||||
|
@ -44,7 +44,7 @@ class Migration(migrations.Migration):
|
|||||||
('last_updated', models.DateTimeField(auto_now=True, null=True)),
|
('last_updated', models.DateTimeField(auto_now=True, null=True)),
|
||||||
('id', models.BigAutoField(primary_key=True, serialize=False)),
|
('id', models.BigAutoField(primary_key=True, serialize=False)),
|
||||||
('object_id', models.PositiveIntegerField()),
|
('object_id', models.PositiveIntegerField()),
|
||||||
('priority', models.PositiveSmallIntegerField(blank=True)),
|
('priority', models.PositiveSmallIntegerField(blank=True, null=True)),
|
||||||
('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')),
|
('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')),
|
||||||
('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='ipam.fhrpgroup')),
|
('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='ipam.fhrpgroup')),
|
||||||
],
|
],
|
||||||
|
@ -82,6 +82,7 @@ class FHRPGroupAssignment(ChangeLoggedModel):
|
|||||||
)
|
)
|
||||||
priority = models.PositiveSmallIntegerField(
|
priority = models.PositiveSmallIntegerField(
|
||||||
blank=True,
|
blank=True,
|
||||||
|
null=True
|
||||||
)
|
)
|
||||||
|
|
||||||
objects = RestrictedQuerySet.as_manager()
|
objects = RestrictedQuerySet.as_manager()
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import django_tables2 as tables
|
import django_tables2 as tables
|
||||||
|
|
||||||
from utilities.tables import (
|
from utilities.tables import BaseTable, ButtonsColumn, MarkdownColumn, TagColumn, ToggleColumn
|
||||||
BaseTable, ContentTypeColumn, MarkdownColumn, TagColumn, ToggleColumn,
|
|
||||||
)
|
|
||||||
from ipam.models import *
|
from ipam.models import *
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
@ -47,8 +45,11 @@ class FHRPGroupTable(BaseTable):
|
|||||||
|
|
||||||
class FHRPGroupAssignmentTable(BaseTable):
|
class FHRPGroupAssignmentTable(BaseTable):
|
||||||
pk = ToggleColumn()
|
pk = ToggleColumn()
|
||||||
content_type = ContentTypeColumn(
|
object_parent = tables.Column(
|
||||||
verbose_name='Object Type'
|
accessor=tables.A('object.parent_object'),
|
||||||
|
linkify=True,
|
||||||
|
orderable=False,
|
||||||
|
verbose_name='Parent'
|
||||||
)
|
)
|
||||||
object = tables.Column(
|
object = tables.Column(
|
||||||
linkify=True,
|
linkify=True,
|
||||||
@ -57,8 +58,11 @@ class FHRPGroupAssignmentTable(BaseTable):
|
|||||||
group = tables.Column(
|
group = tables.Column(
|
||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
|
actions = ButtonsColumn(
|
||||||
|
model=FHRPGroupAssignment,
|
||||||
|
buttons=('edit', 'delete', 'foo')
|
||||||
|
)
|
||||||
|
|
||||||
class Meta(BaseTable.Meta):
|
class Meta(BaseTable.Meta):
|
||||||
model = FHRPGroupAssignment
|
model = FHRPGroupAssignment
|
||||||
fields = ('pk', 'content_type', 'object', 'group', 'priority')
|
fields = ('pk', 'group', 'object_parent', 'object', 'priority')
|
||||||
default_columns = ('pk', 'content_type', 'object', 'group', 'priority')
|
|
||||||
|
@ -849,12 +849,12 @@ class FHRPGroupView(generic.ObjectView):
|
|||||||
orderable=False
|
orderable=False
|
||||||
)
|
)
|
||||||
|
|
||||||
group_assignments = FHRPGroupAssignment.objects.restrict(request.user, 'view').filter(
|
# Get assigned interfaces
|
||||||
group=instance
|
members_table = tables.FHRPGroupAssignmentTable(
|
||||||
|
data=FHRPGroupAssignment.objects.restrict(request.user, 'view').filter(group=instance),
|
||||||
|
orderable=False
|
||||||
)
|
)
|
||||||
members_table = tables.FHRPGroupAssignmentTable(group_assignments)
|
|
||||||
members_table.columns.hide('group')
|
members_table.columns.hide('group')
|
||||||
paginate_table(members_table, request)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'ipaddress_table': ipaddress_table,
|
'ipaddress_table': ipaddress_table,
|
||||||
|
@ -440,42 +440,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="card">
|
{% include 'ipam/inc/panels/fhrp_groups.html' %}
|
||||||
<h5 class="card-header">NHRP Groups</h5>
|
|
||||||
<div class="card-body">
|
|
||||||
<table class="table table-hover table-headings">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Group</th>
|
|
||||||
<th>Priority</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for assignment in object.fhrp_group_assignments.all %}
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<a href="{{ assignment.group.get_absolute_url }}">{{ assignment.group }}</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ assignment.priority }}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% empty %}
|
|
||||||
<tr>
|
|
||||||
<td colspan="3" class="text-muted">None</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
{% if perms.ipam.add_fhrpgroupassignment %}
|
|
||||||
<div class="card-footer text-end noprint">
|
|
||||||
<a href="{% url 'ipam:fhrpgroupassignment_add' %}?content_type=dcim.interface&object_id={{ object.pk }}" class="btn btn-sm btn-primary">
|
|
||||||
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> New Assignment
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% plugin_right_page object %}
|
{% plugin_right_page object %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -72,10 +72,12 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<h5 class="card-header">Members</h5>
|
<h5 class="card-header">Members</h5>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
{% include 'inc/table.html' with table=members_table %}
|
{% if ipaddress_table.rows %}
|
||||||
|
{% render_table members_table 'inc/table.html' %}
|
||||||
|
{% else %}
|
||||||
|
<div class="text-muted">None</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{% include 'inc/paginator.html' with paginator=members_table.paginator page=members_table.page %}
|
|
||||||
{% plugin_full_width_page object %}
|
{% plugin_full_width_page object %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
45
netbox/templates/ipam/inc/panels/fhrp_groups.html
Normal file
45
netbox/templates/ipam/inc/panels/fhrp_groups.html
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
{% load helpers %}
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h5 class="card-header">NHRP Groups</h5>
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-hover table-headings">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Group</th>
|
||||||
|
<th>Virtual IPs</th>
|
||||||
|
<th>Priority</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for assignment in object.fhrp_group_assignments.all %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="{{ assignment.group.get_absolute_url }}">{{ assignment.group }}</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% for ipaddress in assignment.group.ip_addresses.all %}
|
||||||
|
<a href="{{ ipaddress.get_absolute_url }}">{{ ipaddress }}</a>
|
||||||
|
{% if not forloop.last %}<br />{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ assignment.priority }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% empty %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="3" class="text-muted">None</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{% if perms.ipam.add_fhrpgroupassignment %}
|
||||||
|
<div class="card-footer text-end noprint">
|
||||||
|
<a href="{% url 'ipam:fhrpgroupassignment_add' %}?content_type={{ object|meta:"app_label" }}.{{ object|meta:"model_name" }}&object_id={{ object.pk }}" class="btn btn-sm btn-primary">
|
||||||
|
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Assign Group
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
@ -76,11 +76,12 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% include 'inc/panels/tags.html' %}
|
||||||
{% plugin_left_page object %}
|
{% plugin_left_page object %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-md-6">
|
<div class="col col-md-6">
|
||||||
{% include 'inc/panels/custom_fields.html' %}
|
{% include 'inc/panels/custom_fields.html' %}
|
||||||
{% include 'inc/panels/tags.html' %}
|
{% include 'ipam/inc/panels/fhrp_groups.html' %}
|
||||||
{% plugin_right_page object %}
|
{% plugin_right_page object %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user