Merge pull request #110 from ryanmerolle/feature

Support for NetBox v3.4 (#99)
This commit is contained in:
Ryan Merolle 2023-01-23 07:23:12 -05:00 committed by GitHub
commit 4418cca03a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 345 additions and 311 deletions

View File

@ -1,8 +1,8 @@
ARG NETBOX_VARIANT=v3.3 ARG NETBOX_VARIANT=v3.4
FROM netboxcommunity/netbox:${NETBOX_VARIANT} FROM netboxcommunity/netbox:${NETBOX_VARIANT}
ARG NETBOX_INITIALIZERS_VARIANT=3.3.* ARG NETBOX_INITIALIZERS_VARIANT=3.4.0
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive

View File

@ -23,14 +23,14 @@ body:
attributes: attributes:
label: NetBox access-list plugin version label: NetBox access-list plugin version
description: What version of the NetBox access-list plugin are you currently running? description: What version of the NetBox access-list plugin are you currently running?
placeholder: v0.1 placeholder: v1.2.0
validations: validations:
required: true required: true
- type: input - type: input
attributes: attributes:
label: NetBox version label: NetBox version
description: What version of NetBox are you currently running? description: What version of NetBox are you currently running?
placeholder: v3.2.7 placeholder: v3.4.3
validations: validations:
required: true required: true
- type: textarea - type: textarea

View File

@ -15,7 +15,7 @@ body:
attributes: attributes:
label: NetBox version label: NetBox version
description: What version of NetBox are you currently running? description: What version of NetBox are you currently running?
placeholder: v3.2.5 placeholder: v3.4.3
validations: validations:
required: true required: true
- type: dropdown - type: dropdown

View File

@ -37,10 +37,13 @@ See the [CONTRIBUTING](CONTRIBUTING.md) for more information.
Each Plugin Version listed below has been tested with its corresponding NetBox Version. Each Plugin Version listed below has been tested with its corresponding NetBox Version.
| NetBox Version | Plugin Version | | NetBox Version | Plugin Version |
|----------------|----------------| |:--------------:|:--------------:|
| 3.2 | 1.0.1 | | 3.2 | 1.0.1 |
| 3.3 | 1.1.1 | | 3.3 | 1.1.0 |
| 3.4 | 1.2.0(coming) | | 3.4 | 1.2.0
## Installing ## Installing

View File

@ -17,9 +17,8 @@ class NetBoxACLsConfig(PluginConfig):
version = __version__ version = __version__
description = "Manage simple ACLs in NetBox" description = "Manage simple ACLs in NetBox"
base_url = "access-lists" base_url = "access-lists"
min_version = "3.3.0" min_version = "3.4.0"
max_version = "3.3.99" max_version = "3.4.99"
# default_settings = {}
config = NetBoxACLsConfig config = NetBoxACLsConfig

View File

@ -28,8 +28,12 @@ class AccessListViewSet(NetBoxModelViewSet):
Defines the view set for the django AccessList model & associates it to a view. Defines the view set for the django AccessList model & associates it to a view.
""" """
queryset = models.AccessList.objects.prefetch_related("tags").annotate( queryset = (
rule_count=Count("aclextendedrules") + Count("aclstandardrules"), models.AccessList.objects.prefetch_related("tags")
.annotate(
rule_count=Count("aclextendedrules") + Count("aclstandardrules"),
)
.prefetch_related("tags")
) )
serializer_class = AccessListSerializer serializer_class = AccessListSerializer
filterset_class = filtersets.AccessListFilterSet filterset_class = filtersets.AccessListFilterSet

View File

@ -2,82 +2,77 @@
Define the plugin menu buttons & the plugin navigation bar enteries. Define the plugin menu buttons & the plugin navigation bar enteries.
""" """
from extras.plugins import PluginMenuButton, PluginMenuItem from extras.plugins import PluginMenu, PluginMenuButton, PluginMenuItem
from utilities.choices import ButtonColorChoices from utilities.choices import ButtonColorChoices
# #
# Define plugin menu buttons # Define plugin menu buttons
# #
accesslist_buttons = [ menu = PluginMenu(
PluginMenuButton( label="Access Lists",
link="plugins:netbox_acls:accesslist_add", groups=(
title="Add", (
icon_class="mdi mdi-plus-thick", "ACLs",
color=ButtonColorChoices.GREEN, (
permissions=["netbox_acls.add_accesslist"], PluginMenuItem(
), link="plugins:netbox_acls:accesslist_list",
] link_text="Access Lists",
permissions=["netbox_acls.view_accesslist"],
aclstandardrule_butons = [ buttons=(
PluginMenuButton( PluginMenuButton(
link="plugins:netbox_acls:aclstandardrule_add", link="plugins:netbox_acls:accesslist_add",
title="Add", title="Add",
icon_class="mdi mdi-plus-thick", icon_class="mdi mdi-plus-thick",
color=ButtonColorChoices.GREEN, color=ButtonColorChoices.GREEN,
permissions=["netbox_acls.add_aclstandardrule"], permissions=["netbox_acls.add_accesslist"],
), ),
] ),
),
aclextendedrule_butons = [ PluginMenuItem(
PluginMenuButton( link="plugins:netbox_acls:aclstandardrule_list",
link="plugins:netbox_acls:aclextendedrule_add", link_text="Standard Rules",
title="Add", permissions=["netbox_acls.view_aclstandardrule"],
icon_class="mdi mdi-plus-thick", buttons=(
color=ButtonColorChoices.GREEN, PluginMenuButton(
permissions=["netbox_acls.add_aclextendedrule"], link="plugins:netbox_acls:aclstandardrule_add",
), title="Add",
] icon_class="mdi mdi-plus-thick",
color=ButtonColorChoices.GREEN,
accesslistassignment_buttons = [ permissions=["netbox_acls.add_aclstandardrule"],
PluginMenuButton( ),
link="plugins:netbox_acls:aclinterfaceassignment_add", ),
title="Add", ),
icon_class="mdi mdi-plus-thick", PluginMenuItem(
color=ButtonColorChoices.GREEN, link="plugins:netbox_acls:aclextendedrule_list",
permissions=["netbox_acls.add_aclinterfaceassignment"], link_text="Extended Rules",
), permissions=["netbox_acls.view_aclextendedrule"],
] buttons=(
PluginMenuButton(
# link="plugins:netbox_acls:aclextendedrule_add",
# Define navigation bar links including the above buttons defined. title="Add",
# icon_class="mdi mdi-plus-thick",
color=ButtonColorChoices.GREEN,
menu_items = ( permissions=["netbox_acls.add_aclextendedrule"],
PluginMenuItem( ),
link="plugins:netbox_acls:accesslist_list", ),
link_text="Access Lists", ),
buttons=accesslist_buttons, PluginMenuItem(
permissions=["netbox_acls.view_accesslist"], link="plugins:netbox_acls:aclinterfaceassignment_list",
), link_text="Interface Assignments",
# Comment out Standard Access List rule to force creation in the ACL view permissions=["netbox_acls.view_aclinterfaceassignment"],
PluginMenuItem( buttons=(
link="plugins:netbox_acls:aclstandardrule_list", PluginMenuButton(
link_text="ACL Standard Rules", link="plugins:netbox_acls:aclinterfaceassignment_add",
buttons=aclstandardrule_butons, title="Add",
permissions=["netbox_acls.view_aclstandardrule"], icon_class="mdi mdi-plus-thick",
), color=ButtonColorChoices.GREEN,
# Comment out Extended Access List rule to force creation in the ACL view permissions=["netbox_acls.add_aclinterfaceassignment"],
PluginMenuItem( ),
link="plugins:netbox_acls:aclextendedrule_list", ),
link_text="ACL Extended Rules", ),
buttons=aclextendedrule_butons, ),
permissions=["netbox_acls.view_aclextendedrule"], ),
),
PluginMenuItem(
link="plugins:netbox_acls:aclinterfaceassignment_list",
link_text="ACL Interface Assignments",
buttons=accesslistassignment_buttons,
permissions=["netbox_acls.view_aclinterfaceassignment"],
), ),
icon_class="mdi mdi-lock",
) )

View File

@ -1,98 +0,0 @@
from django.contrib.contenttypes.models import ContentType
from extras.plugins import PluginTemplateExtension
from .models import AccessList, ACLInterfaceAssignment
__all__ = (
"AccessLists",
"ACLInterfaceAssignments",
"DeviceAccessLists",
"VirtualChassisAccessLists",
"VMAccessLists",
"DeviceACLInterfaceAssignments",
"VMAACLInterfaceAssignments",
)
class ACLInterfaceAssignments(PluginTemplateExtension):
def right_page(self):
obj = self.context["object"]
acl_interface_assignments = None
ctype = ContentType.objects.get_for_model(obj)
if ctype.model in ["interface", "vminterface"]:
acl_interface_assignments = ACLInterfaceAssignment.objects.filter(
assigned_object_id=obj.pk,
assigned_object_type=ctype,
)
if ctype.model == "interface":
parent_type = "device"
parent_id = obj.device.pk
elif ctype.model == "vminterface":
parent_type = "virtual_machine"
parent_id = obj.virtual_machine.pk
else:
parent_type = None
parent_id = None
return self.render(
"inc/assigned_interface/access_lists.html",
extra_context={
"acl_interface_assignments": acl_interface_assignments,
"type": ctype.model,
"parent_type": parent_type,
"parent_id": parent_id,
},
)
class AccessLists(PluginTemplateExtension):
def right_page(self):
obj = self.context["object"]
access_lists = None
ctype = ContentType.objects.get_for_model(obj)
if ctype.model in ["device", "virtualchassis", "virtualmachine"]:
access_lists = AccessList.objects.filter(
assigned_object_id=obj.pk,
assigned_object_type=ctype,
)
return self.render(
"inc/assigned_host/access_lists.html",
extra_context={
"access_lists": access_lists,
"type": ctype.model
if ctype.model == "device"
else ctype.name.replace(" ", "_"),
},
)
class DeviceAccessLists(AccessLists):
model = "dcim.device"
class VirtualChassisAccessLists(AccessLists):
model = "dcim.virtualchassis"
class VMAccessLists(AccessLists):
model = "virtualization.virtualmachine"
class DeviceACLInterfaceAssignments(ACLInterfaceAssignments):
model = "dcim.interface"
class VMAACLInterfaceAssignments(ACLInterfaceAssignments):
model = "virtualization.vminterface"
template_extensions = [
DeviceAccessLists,
VirtualChassisAccessLists,
VMAccessLists,
DeviceACLInterfaceAssignments,
VMAACLInterfaceAssignments,
]

View File

@ -1,13 +0,0 @@
<div class="card">
<h5 class="card-header">
Access Lists
</h5>
<div class="card-body">
{% include 'inc/assigned_host/assigned_access_lists.html' %}
</div>
<div class="card-footer text-end noprint">
<a href="{% url 'plugins:netbox_acls:accesslist_add' %}?{{ type }}={{ object.pk }}&return_url={{ object.get_absolute_url }}" class="btn btn-sm btn-primary">
<i class="mdi mdi-plus-thick"></i> Add Access List
</a>
</div>
</div>

View File

@ -1,27 +0,0 @@
{% if access_lists %}
<table class="table table-hover">
<tr>
<th>Name</th>
<th>Type</th>
<th>Default Action</th>
<th>Rule Count</th>
</tr>
{% for object in access_lists %}
<tr>
<td>{{ object|linkify }}</td>
<td>{{ object.type|title }}</td>
<td>{{ object.default_action|title }}</td>
{% if object.type == 'standard' %}
<td>{{ object.aclstandardrules.count|placeholder }}</td>
{% elif object.type == 'extended' %}
<td>{{ object.aclextendedrules.count|placeholder }}</td>
{% endif %}
</tr>
{% endfor %}
</table>
{% else %}
<div class="text-muted">
None found
</div>
{% endif %}

View File

@ -1,13 +0,0 @@
<div class="card">
<h5 class="card-header">
Access Lists
</h5>
<div class="card-body">
{% include 'inc/assigned_interface/assigned_access_lists.html' %}
</div>
<div class="card-footer text-end noprint">
<a href="{% url 'plugins:netbox_acls:aclinterfaceassignment_add' %}?{{ parent_type }}={{ parent_id }}&{{ type }}={{ object.pk }}&return_url={{ object.get_absolute_url }}" class="btn btn-sm btn-primary">
<i class="mdi mdi-plus-thick"></i> Assign Access List
</a>
</div>
</div>

View File

@ -1,29 +0,0 @@
{% if acl_interface_assignments %}
<table class="table table-hover">
<tr>
<th>Name</th>
<th>Type</th>
<th>Default Action</th>
<th>Rule Count</th>
<th>Direction</th>
</tr>
{% for object in acl_interface_assignments %}
<tr>
<td>{{ object.access_list|linkify }}</td>
<td>{{ object.access_list.type|title }}</td>
<td>{{ object.access_list.default_action|title }}</td>
{% if object.access_list.type == 'standard' %}
<td>{{ object.access_list.aclstandardrules.count|placeholder }}</td>
{% elif object.access_list.type == 'extended' %}
<td>{{ object.access_list.aclextendedrules.count|placeholder }}</td>
{% endif %}
<td>{{ object.direction|title }}</td>
</tr>
{% endfor %}
</table>
{% else %}
<div class="text-muted">
None
</div>
{% endif %}

View File

@ -0,0 +1,31 @@
{% extends 'generic/object.html' %}
{% load buttons %}
{% load helpers %}
{% load plugins %}
{% load render_table from django_tables2 %}
{% block extra_controls %}
{% if perms.netbox_todo.add_accesslist %}
<a href="{% url add_url %}?{{ model_type }}={{ object.pk }}&return_url={{ object.get_absolute_url }}"
class="btn btn-sm btn-primary">
<i class="mdi mdi-plus-thick"></i> Add Access List
</a>
{% endif %}
{% endblock extra_controls %}
{% block content %}
{% include 'inc/table_controls_htmx.html' with table_modal=table_config %}
<form method="post">
{% csrf_token %}
<div class="card">
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
</div>
</form>
{% endblock content %}
{% block modals %}
{{ block.super }}
{% table_config_form table %}
{% endblock modals %}

View File

@ -2,8 +2,8 @@
Map Views to URLs. Map Views to URLs.
""" """
from django.urls import path from django.urls import include, path
from netbox.views.generic import ObjectChangeLogView from utilities.urls import get_model_urls
from . import models, views from . import models, views
@ -33,12 +33,8 @@ urlpatterns = (
name="accesslist_delete", name="accesslist_delete",
), ),
path( path(
"access-lists/<int:pk>/changelog/", "access-lists/<int:pk>/",
ObjectChangeLogView.as_view(), include(get_model_urls("netbox_acls", "accesslist")),
name="accesslist_changelog",
kwargs={
"model": models.AccessList,
},
), ),
# Access List Interface Assignments # Access List Interface Assignments
path( path(
@ -73,12 +69,8 @@ urlpatterns = (
name="aclinterfaceassignment_delete", name="aclinterfaceassignment_delete",
), ),
path( path(
"interface-assignments/<int:pk>/changelog/", "interface-assignments/<int:pk>/",
ObjectChangeLogView.as_view(), include(get_model_urls("netbox_acls", "aclinterfaceassignment")),
name="aclinterfaceassignment_changelog",
kwargs={
"model": models.ACLInterfaceAssignment,
},
), ),
# Standard Access List Rules # Standard Access List Rules
path( path(
@ -112,12 +104,8 @@ urlpatterns = (
name="aclstandardrule_delete", name="aclstandardrule_delete",
), ),
path( path(
"standard-rules/<int:pk>/changelog/", "standard-rules/<int:pk>/",
ObjectChangeLogView.as_view(), include(get_model_urls("netbox_acls", "aclstandardrule")),
name="aclstandardrule_changelog",
kwargs={
"model": models.ACLStandardRule,
},
), ),
# Extended Access List Rules # Extended Access List Rules
path( path(
@ -151,11 +139,7 @@ urlpatterns = (
name="aclextendedrule_delete", name="aclextendedrule_delete",
), ),
path( path(
"extended-rules/<int:pk>/changelog/", "extended-rules/<int:pk>/",
ObjectChangeLogView.as_view(), include(get_model_urls("netbox_acls", "aclextendedrule")),
name="aclextendedrule_changelog",
kwargs={
"model": models.ACLExtendedRule,
},
), ),
) )

View File

@ -3,8 +3,11 @@ Defines the business logic for the plugin.
Specifically, all the various interactions with a client. Specifically, all the various interactions with a client.
""" """
from dcim.models import Device, Interface, VirtualChassis
from django.db.models import Count from django.db.models import Count
from netbox.views import generic from netbox.views import generic
from utilities.views import ViewTab, register_model_view
from virtualization.models import VirtualMachine, VMInterface
from . import choices, filtersets, forms, models, tables from . import choices, filtersets, forms, models, tables
@ -37,12 +40,13 @@ __all__ = (
# #
@register_model_view(models.AccessList)
class AccessListView(generic.ObjectView): class AccessListView(generic.ObjectView):
""" """
Defines the view for the AccessLists django model. Defines the view for the AccessLists django model.
""" """
queryset = models.AccessList.objects.all() queryset = models.AccessList.objects.prefetch_related("tags")
def get_extra_context(self, request, instance): def get_extra_context(self, request, instance):
""" """
@ -73,47 +77,121 @@ class AccessListListView(generic.ObjectListView):
queryset = models.AccessList.objects.annotate( queryset = models.AccessList.objects.annotate(
rule_count=Count("aclextendedrules") + Count("aclstandardrules"), rule_count=Count("aclextendedrules") + Count("aclstandardrules"),
) ).prefetch_related("tags")
table = tables.AccessListTable table = tables.AccessListTable
filterset = filtersets.AccessListFilterSet filterset = filtersets.AccessListFilterSet
filterset_form = forms.AccessListFilterForm filterset_form = forms.AccessListFilterForm
@register_model_view(models.AccessList, "edit")
class AccessListEditView(generic.ObjectEditView): class AccessListEditView(generic.ObjectEditView):
""" """
Defines the edit view for the AccessLists django model. Defines the edit view for the AccessLists django model.
""" """
queryset = models.AccessList.objects.all() queryset = models.AccessList.objects.prefetch_related("tags")
form = forms.AccessListForm form = forms.AccessListForm
template_name = "netbox_acls/accesslist_edit.html" template_name = "netbox_acls/accesslist_edit.html"
@register_model_view(models.AccessList, "delete")
class AccessListDeleteView(generic.ObjectDeleteView): class AccessListDeleteView(generic.ObjectDeleteView):
""" """
Defines delete view for the AccessLists django model. Defines delete view for the AccessLists django model.
""" """
queryset = models.AccessList.objects.all() queryset = models.AccessList.objects.prefetch_related("tags")
class AccessListBulkDeleteView(generic.BulkDeleteView): class AccessListBulkDeleteView(generic.BulkDeleteView):
queryset = models.AccessList.objects.all() queryset = models.AccessList.objects.prefetch_related("tags")
filterset = filtersets.AccessListFilterSet filterset = filtersets.AccessListFilterSet
table = tables.AccessListTable table = tables.AccessListTable
class AccessListChildView(generic.ObjectChildrenView):
"""
Defines the child view for the AccessLists model.
"""
child_model = models.AccessList
table = tables.AccessListTable
filterset = filtersets.AccessListFilterSet
template_name = "inc/view_tab.html"
def get_extra_context(self, request, instance):
return {
"table_config": self.table.__name__,
"model_type": self.queryset.model._meta.verbose_name.replace(" ", "_"),
"add_url": "plugins:netbox_acls:accesslist_add",
}
def prep_table_data(self, request, queryset, parent):
return queryset.annotate(
rule_count=Count("aclextendedrules") + Count("aclstandardrules"),
)
@register_model_view(Device, "access_lists")
class DeviceAccessListView(AccessListChildView):
queryset = Device.objects.prefetch_related("tags")
tab = ViewTab(
label="Access Lists",
badge=lambda obj: models.AccessList.objects.filter(device=obj).count(),
permission="netbox_acls.view_accesslist",
)
def get_children(self, request, parent):
return self.child_model.objects.restrict(request.user, "view").filter(
device=parent,
)
@register_model_view(VirtualChassis, "access_lists")
class VirtualChassisAccessListView(AccessListChildView):
queryset = VirtualChassis.objects.prefetch_related("tags")
tab = ViewTab(
label="Access Lists",
badge=lambda obj: models.AccessList.objects.filter(virtual_chassis=obj).count(),
permission="netbox_acls.view_accesslist",
)
def get_children(self, request, parent):
return self.child_model.objects.restrict(request.user, "view").filter(
virtual_chassis=parent,
)
@register_model_view(VirtualMachine, "access_lists")
class VirtualMachineAccessListView(AccessListChildView):
queryset = VirtualMachine.objects.prefetch_related("tags")
tab = ViewTab(
label="Access Lists",
badge=lambda obj: models.AccessList.objects.filter(virtual_machine=obj).count(),
permission="netbox_acls.view_accesslist",
)
def get_children(self, request, parent):
return self.child_model.objects.restrict(request.user, "view").filter(
virtual_machine=parent,
)
# #
# ACLInterfaceAssignment views # ACLInterfaceAssignment views
# #
@register_model_view(models.ACLInterfaceAssignment)
class ACLInterfaceAssignmentView(generic.ObjectView): class ACLInterfaceAssignmentView(generic.ObjectView):
""" """
Defines the view for the ACLInterfaceAssignments django model. Defines the view for the ACLInterfaceAssignments django model.
""" """
queryset = models.ACLInterfaceAssignment.objects.all() queryset = models.ACLInterfaceAssignment.objects.prefetch_related(
"access_list",
"tags",
)
class ACLInterfaceAssignmentListView(generic.ObjectListView): class ACLInterfaceAssignmentListView(generic.ObjectListView):
@ -121,18 +199,25 @@ class ACLInterfaceAssignmentListView(generic.ObjectListView):
Defines the list view for the ACLInterfaceAssignments django model. Defines the list view for the ACLInterfaceAssignments django model.
""" """
queryset = models.ACLInterfaceAssignment.objects.all() queryset = models.ACLInterfaceAssignment.objects.prefetch_related(
"access_list",
"tags",
)
table = tables.ACLInterfaceAssignmentTable table = tables.ACLInterfaceAssignmentTable
filterset = filtersets.ACLInterfaceAssignmentFilterSet filterset = filtersets.ACLInterfaceAssignmentFilterSet
filterset_form = forms.ACLInterfaceAssignmentFilterForm filterset_form = forms.ACLInterfaceAssignmentFilterForm
@register_model_view(models.ACLInterfaceAssignment, "edit")
class ACLInterfaceAssignmentEditView(generic.ObjectEditView): class ACLInterfaceAssignmentEditView(generic.ObjectEditView):
""" """
Defines the edit view for the ACLInterfaceAssignments django model. Defines the edit view for the ACLInterfaceAssignments django model.
""" """
queryset = models.ACLInterfaceAssignment.objects.all() queryset = models.ACLInterfaceAssignment.objects.prefetch_related(
"access_list",
"tags",
)
form = forms.ACLInterfaceAssignmentForm form = forms.ACLInterfaceAssignmentForm
template_name = "netbox_acls/aclinterfaceassignment_edit.html" template_name = "netbox_acls/aclinterfaceassignment_edit.html"
@ -148,31 +233,97 @@ class ACLInterfaceAssignmentEditView(generic.ObjectEditView):
} }
@register_model_view(models.ACLInterfaceAssignment, "delete")
class ACLInterfaceAssignmentDeleteView(generic.ObjectDeleteView): class ACLInterfaceAssignmentDeleteView(generic.ObjectDeleteView):
""" """
Defines delete view for the ACLInterfaceAssignments django model. Defines delete view for the ACLInterfaceAssignments django model.
""" """
queryset = models.ACLInterfaceAssignment.objects.all() queryset = models.ACLInterfaceAssignment.objects.prefetch_related(
"access_list",
"tags",
)
class ACLInterfaceAssignmentBulkDeleteView(generic.BulkDeleteView): class ACLInterfaceAssignmentBulkDeleteView(generic.BulkDeleteView):
queryset = models.ACLInterfaceAssignment.objects.all() queryset = models.ACLInterfaceAssignment.objects.prefetch_related(
"access_list",
"tags",
)
filterset = filtersets.ACLInterfaceAssignmentFilterSet filterset = filtersets.ACLInterfaceAssignmentFilterSet
table = tables.ACLInterfaceAssignmentTable table = tables.ACLInterfaceAssignmentTable
class ACLInterfaceAssignmentChildView(generic.ObjectChildrenView):
"""
Defines the child view for the ACLInterfaceAssignments model.
"""
child_model = models.ACLInterfaceAssignment
table = tables.ACLInterfaceAssignmentTable
filterset = filtersets.ACLInterfaceAssignmentFilterSet
template_name = "inc/view_tab.html"
def get_extra_context(self, request, instance):
return {
"table_config": self.table.__name__,
"model_type": self.queryset.model._meta.verbose_name.replace(" ", "_"),
"add_url": "plugins:netbox_acls:aclinterfaceassignment_add",
}
@register_model_view(Interface, "acl_interface_assignments")
class InterfaceACLInterfaceAssignmentView(ACLInterfaceAssignmentChildView):
queryset = Interface.objects.prefetch_related("device", "tags")
tab = ViewTab(
label="ACL Interface Assignments",
badge=lambda obj: models.ACLInterfaceAssignment.objects.filter(
interface=obj,
).count(),
permission="netbox_acls.view_aclinterfaceassignment",
)
def get_children(self, request, parent):
return self.child_model.objects.restrict(request.user, "view").filter(
interface=parent,
)
@register_model_view(VMInterface, "acl_interface_assignments")
class VirtualMachineInterfaceACLInterfaceAssignmentView(
ACLInterfaceAssignmentChildView,
):
queryset = VMInterface.objects.prefetch_related("virtual_machine", "tags")
tab = ViewTab(
label="ACL Interface Assignments",
badge=lambda obj: models.ACLInterfaceAssignment.objects.filter(
vminterface=obj,
).count(),
permission="netbox_acls.view_aclinterfaceassignment",
)
def get_children(self, request, parent):
return self.child_model.objects.restrict(request.user, "view").filter(
vminterface=parent,
)
# #
# ACLStandardRule views # ACLStandardRule views
# #
@register_model_view(models.ACLStandardRule)
class ACLStandardRuleView(generic.ObjectView): class ACLStandardRuleView(generic.ObjectView):
""" """
Defines the view for the ACLStandardRule django model. Defines the view for the ACLStandardRule django model.
""" """
queryset = models.ACLStandardRule.objects.all() queryset = models.ACLStandardRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
)
class ACLStandardRuleListView(generic.ObjectListView): class ACLStandardRuleListView(generic.ObjectListView):
@ -180,18 +331,27 @@ class ACLStandardRuleListView(generic.ObjectListView):
Defines the list view for the ACLStandardRule django model. Defines the list view for the ACLStandardRule django model.
""" """
queryset = models.ACLStandardRule.objects.all() queryset = models.ACLStandardRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
)
table = tables.ACLStandardRuleTable table = tables.ACLStandardRuleTable
filterset = filtersets.ACLStandardRuleFilterSet filterset = filtersets.ACLStandardRuleFilterSet
filterset_form = forms.ACLStandardRuleFilterForm filterset_form = forms.ACLStandardRuleFilterForm
@register_model_view(models.ACLStandardRule, "edit")
class ACLStandardRuleEditView(generic.ObjectEditView): class ACLStandardRuleEditView(generic.ObjectEditView):
""" """
Defines the edit view for the ACLStandardRule django model. Defines the edit view for the ACLStandardRule django model.
""" """
queryset = models.ACLStandardRule.objects.all() queryset = models.ACLStandardRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
)
form = forms.ACLStandardRuleForm form = forms.ACLStandardRuleForm
def get_extra_addanother_params(self, request): def get_extra_addanother_params(self, request):
@ -205,16 +365,25 @@ class ACLStandardRuleEditView(generic.ObjectEditView):
} }
@register_model_view(models.ACLStandardRule, "delete")
class ACLStandardRuleDeleteView(generic.ObjectDeleteView): class ACLStandardRuleDeleteView(generic.ObjectDeleteView):
""" """
Defines delete view for the ACLStandardRules django model. Defines delete view for the ACLStandardRules django model.
""" """
queryset = models.ACLStandardRule.objects.all() queryset = models.ACLStandardRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
)
class ACLStandardRuleBulkDeleteView(generic.BulkDeleteView): class ACLStandardRuleBulkDeleteView(generic.BulkDeleteView):
queryset = models.ACLStandardRule.objects.all() queryset = models.ACLStandardRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
)
filterset = filtersets.ACLStandardRuleFilterSet filterset = filtersets.ACLStandardRuleFilterSet
table = tables.ACLStandardRuleTable table = tables.ACLStandardRuleTable
@ -224,12 +393,18 @@ class ACLStandardRuleBulkDeleteView(generic.BulkDeleteView):
# #
@register_model_view(models.ACLExtendedRule)
class ACLExtendedRuleView(generic.ObjectView): class ACLExtendedRuleView(generic.ObjectView):
""" """
Defines the view for the ACLExtendedRule django model. Defines the view for the ACLExtendedRule django model.
""" """
queryset = models.ACLExtendedRule.objects.all() queryset = models.ACLExtendedRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
"destination_prefix",
)
class ACLExtendedRuleListView(generic.ObjectListView): class ACLExtendedRuleListView(generic.ObjectListView):
@ -237,18 +412,29 @@ class ACLExtendedRuleListView(generic.ObjectListView):
Defines the list view for the ACLExtendedRule django model. Defines the list view for the ACLExtendedRule django model.
""" """
queryset = models.ACLExtendedRule.objects.all() queryset = models.ACLExtendedRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
"destination_prefix",
)
table = tables.ACLExtendedRuleTable table = tables.ACLExtendedRuleTable
filterset = filtersets.ACLExtendedRuleFilterSet filterset = filtersets.ACLExtendedRuleFilterSet
filterset_form = forms.ACLExtendedRuleFilterForm filterset_form = forms.ACLExtendedRuleFilterForm
@register_model_view(models.ACLExtendedRule, "edit")
class ACLExtendedRuleEditView(generic.ObjectEditView): class ACLExtendedRuleEditView(generic.ObjectEditView):
""" """
Defines the edit view for the ACLExtendedRule django model. Defines the edit view for the ACLExtendedRule django model.
""" """
queryset = models.ACLExtendedRule.objects.all() queryset = models.ACLExtendedRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
"destination_prefix",
)
form = forms.ACLExtendedRuleForm form = forms.ACLExtendedRuleForm
def get_extra_addanother_params(self, request): def get_extra_addanother_params(self, request):
@ -262,15 +448,26 @@ class ACLExtendedRuleEditView(generic.ObjectEditView):
} }
@register_model_view(models.ACLExtendedRule, "delete")
class ACLExtendedRuleDeleteView(generic.ObjectDeleteView): class ACLExtendedRuleDeleteView(generic.ObjectDeleteView):
""" """
Defines delete view for the ACLExtendedRules django model. Defines delete view for the ACLExtendedRules django model.
""" """
queryset = models.ACLExtendedRule.objects.all() queryset = models.ACLExtendedRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
"destination_prefix",
)
class ACLExtendedRuleBulkDeleteView(generic.BulkDeleteView): class ACLExtendedRuleBulkDeleteView(generic.BulkDeleteView):
queryset = models.ACLExtendedRule.objects.all() queryset = models.ACLExtendedRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
"destination_prefix",
)
filterset = filtersets.ACLExtendedRuleFilterSet filterset = filtersets.ACLExtendedRuleFilterSet
table = tables.ACLExtendedRuleTable table = tables.ACLExtendedRuleTable

View File

@ -23,6 +23,7 @@ def get_version(rel_path):
setup( setup(
name="netbox-acls", name="netbox-acls",
version="1.2.0",
version=get_version("netbox_acls/version.py"), version=get_version("netbox_acls/version.py"),
description="A NetBox plugin for Access List management", description="A NetBox plugin for Access List management",
long_description=long_description, long_description=long_description,