From 41a3f292177e4930ed937a6545297c8835a34b70 Mon Sep 17 00:00:00 2001 From: ryanmerolle Date: Fri, 29 Jul 2022 16:15:27 +0000 Subject: [PATCH] lint fixes --- .devcontainer/configuration/plugins.py | 2 +- .devcontainer/requirements-dev.txt | 1 + .github/workflows/codeql-analysis.yml | 6 +- .pre-commit-config.yaml | 6 +- LICENSE => LICENSE.txt | 0 netbox_access_lists/__init__.py | 11 +- netbox_access_lists/api/nested_serializers.py | 41 +- netbox_access_lists/api/serializers.py | 245 +++++++--- netbox_access_lists/api/urls.py | 10 +- netbox_access_lists/api/views.py | 37 +- netbox_access_lists/choices.py | 54 ++- netbox_access_lists/constants.py | 12 +- netbox_access_lists/filtersets.py | 92 ++-- netbox_access_lists/forms/__init__.py | 14 +- netbox_access_lists/forms/bulk_edit.py | 14 +- netbox_access_lists/forms/filtersets.py | 122 +++-- netbox_access_lists/forms/models.py | 456 ++++++++++++------ netbox_access_lists/graphql.py | 22 +- .../migrations/0001_initial.py | 297 +++++++++--- .../models/access_list_rules.py | 67 +-- netbox_access_lists/models/access_lists.py | 115 +++-- netbox_access_lists/navigation.py | 64 +-- netbox_access_lists/tables.py | 143 ++++-- netbox_access_lists/template_content.py | 75 +-- .../assigned_host/assigned_access_lists.html | 2 +- netbox_access_lists/urls.py | 187 +++++-- netbox_access_lists/views.py | 73 ++- setup.py | 24 +- 28 files changed, 1455 insertions(+), 737 deletions(-) rename LICENSE => LICENSE.txt (100%) diff --git a/.devcontainer/configuration/plugins.py b/.devcontainer/configuration/plugins.py index f9be283..681eb40 100644 --- a/.devcontainer/configuration/plugins.py +++ b/.devcontainer/configuration/plugins.py @@ -6,7 +6,7 @@ PLUGINS = [ "netbox_access_lists", - ] +] PLUGINS_CONFIG = { "netbox_access_lists": {}, diff --git a/.devcontainer/requirements-dev.txt b/.devcontainer/requirements-dev.txt index 093cf52..070e81d 100644 --- a/.devcontainer/requirements-dev.txt +++ b/.devcontainer/requirements-dev.txt @@ -9,4 +9,5 @@ pycodestyle pydocstyle pylint pylint-django +wily yapf diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index f9ca404..b6b4ebb 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -48,11 +48,11 @@ jobs: # If you wish to specify custom queries, you can do so here or in a config file. # By default, queries listed here will override any specified in a config file. # Prefix the list here with "+" to use these queries and those in the config file. - + # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs # queries: security-extended,security-and-quality - + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild @@ -61,7 +61,7 @@ jobs: # â„šī¸ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - # If the Autobuild fails above, remove it and uncomment the following three lines. + # If the Autobuild fails above, remove it and uncomment the following three lines. # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. # - run: | diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4655193..0f71548 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,7 +17,7 @@ repos: args: - '--py36-plus' - repo: 'https://github.com/asottile/pyupgrade' - rev: v2.34.0 + rev: v2.37.3 hooks: - id: pyupgrade args: @@ -42,11 +42,9 @@ repos: hooks: - id: black - repo: 'https://github.com/igorshubovych/markdownlint-cli' - rev: v0.31.1 + rev: v0.32.1 hooks: - id: markdownlint - - repo: local - hooks: - repo: local hooks: - id: wily diff --git a/LICENSE b/LICENSE.txt similarity index 100% rename from LICENSE rename to LICENSE.txt diff --git a/netbox_access_lists/__init__.py b/netbox_access_lists/__init__.py index 3b49054..20f8f12 100644 --- a/netbox_access_lists/__init__.py +++ b/netbox_access_lists/__init__.py @@ -6,10 +6,11 @@ from extras.plugins import PluginConfig class NetBoxAccessListsConfig(PluginConfig): - name = 'netbox_access_lists' - verbose_name = 'Access Lists' - description = 'Manage simple ACLs in NetBox' - version = '0.1' - base_url = 'access-lists' + name = "netbox_access_lists" + verbose_name = "Access Lists" + description = "Manage simple ACLs in NetBox" + version = "0.1" + base_url = "access-lists" + config = NetBoxAccessListsConfig diff --git a/netbox_access_lists/api/nested_serializers.py b/netbox_access_lists/api/nested_serializers.py index a5910da..8d80dde 100644 --- a/netbox_access_lists/api/nested_serializers.py +++ b/netbox_access_lists/api/nested_serializers.py @@ -6,75 +6,88 @@ while Django itself handles the database abstraction. from netbox.api.serializers import WritableNestedSerializer from rest_framework import serializers -from ..models import (AccessList, ACLExtendedRule, ACLInterfaceAssignment, - ACLStandardRule) +from ..models import ( + AccessList, + ACLExtendedRule, + ACLInterfaceAssignment, + ACLStandardRule, +) __all__ = [ - 'NestedAccessListSerializer', - 'NestedACLInterfaceAssignmentSerializer', - 'NestedACLStandardRuleSerializer', - 'NestedACLExtendedRuleSerializer' + "NestedAccessListSerializer", + "NestedACLInterfaceAssignmentSerializer", + "NestedACLStandardRuleSerializer", + "NestedACLExtendedRuleSerializer", ] + class NestedAccessListSerializer(WritableNestedSerializer): """ Defines the nested serializer for the django AccessList model & associates it to a view. """ + url = serializers.HyperlinkedIdentityField( - view_name='plugins-api:netbox_access_lists-api:accesslist-detail' + view_name="plugins-api:netbox_access_lists-api:accesslist-detail", ) class Meta: """ Associates the django model ACLStandardRule & fields to the nested serializer. """ + model = AccessList - fields = ('id', 'url', 'display', 'name') + fields = ("id", "url", "display", "name") class NestedACLInterfaceAssignmentSerializer(WritableNestedSerializer): """ Defines the nested serializer for the django ACLInterfaceAssignment model & associates it to a view. """ + url = serializers.HyperlinkedIdentityField( - view_name='plugins-api:netbox_access_lists-api:aclinterfaceassignment-detail' + view_name="plugins-api:netbox_access_lists-api:aclinterfaceassignment-detail", ) class Meta: """ Associates the django model ACLInterfaceAssignment & fields to the nested serializer. """ + model = ACLInterfaceAssignment - fields = ('id', 'url', 'display', 'access_list') + fields = ("id", "url", "display", "access_list") class NestedACLStandardRuleSerializer(WritableNestedSerializer): """ Defines the nested serializer for the django ACLStandardRule model & associates it to a view. """ + url = serializers.HyperlinkedIdentityField( - view_name='plugins-api:netbox_access_lists-api:aclstandardrule-detail' + view_name="plugins-api:netbox_access_lists-api:aclstandardrule-detail", ) class Meta: """ Associates the django model ACLStandardRule & fields to the nested serializer. """ + model = ACLStandardRule - fields = ('id', 'url', 'display', 'index') + fields = ("id", "url", "display", "index") class NestedACLExtendedRuleSerializer(WritableNestedSerializer): """ Defines the nested serializer for the django ACLExtendedRule model & associates it to a view. """ + url = serializers.HyperlinkedIdentityField( - view_name='plugins-api:netbox_access_lists-api:aclextendedrule-detail' + view_name="plugins-api:netbox_access_lists-api:aclextendedrule-detail", ) class Meta: """ Associates the django model ACLExtendedRule & fields to the nested serializer. """ + model = ACLExtendedRule - fields = ('id', 'url', 'display', 'index') + fields = ("id", "url", "display", "index") diff --git a/netbox_access_lists/api/serializers.py b/netbox_access_lists/api/serializers.py index efb6adb..ef7c926 100644 --- a/netbox_access_lists/api/serializers.py +++ b/netbox_access_lists/api/serializers.py @@ -4,50 +4,60 @@ while Django itself handles the database abstraction. """ from django.contrib.contenttypes.models import ContentType +from django.core.exceptions import ObjectDoesNotExist from drf_yasg.utils import swagger_serializer_method from ipam.api.serializers import NestedPrefixSerializer -from django.core.exceptions import ObjectDoesNotExist from netbox.api import ContentTypeField from netbox.api.serializers import NetBoxModelSerializer from rest_framework import serializers from utilities.api import get_serializer_for_model -from ..constants import (ACL_HOST_ASSIGNMENT_MODELS, - ACL_INTERFACE_ASSIGNMENT_MODELS) -from ..models import (AccessList, ACLExtendedRule, ACLInterfaceAssignment, - ACLStandardRule) -from .nested_serializers import (NestedAccessListSerializer, - NestedACLExtendedRuleSerializer, - NestedACLInterfaceAssignmentSerializer, - NestedACLStandardRuleSerializer) +from ..constants import ACL_HOST_ASSIGNMENT_MODELS, ACL_INTERFACE_ASSIGNMENT_MODELS +from ..models import ( + AccessList, + ACLExtendedRule, + ACLInterfaceAssignment, + ACLStandardRule, +) +from .nested_serializers import ( + NestedAccessListSerializer, + NestedACLExtendedRuleSerializer, + NestedACLInterfaceAssignmentSerializer, + NestedACLStandardRuleSerializer, +) __all__ = [ - 'AccessListSerializer', - 'ACLInterfaceAssignmentSerializer', - 'ACLStandardRuleSerializer', - 'ACLExtendedRuleSerializer' + "AccessListSerializer", + "ACLInterfaceAssignmentSerializer", + "ACLStandardRuleSerializer", + "ACLExtendedRuleSerializer", ] # Sets a standard error message for ACL rules with an action of remark, but no remark set. -error_message_no_remark = 'Action is set to remark, you MUST add a remark.' +error_message_no_remark = "Action is set to remark, you MUST add a remark." # Sets a standard error message for ACL rules with an action of remark, but no source_prefix is set. -error_message_action_remark_source_prefix_set = 'Action is set to remark, Source Prefix CANNOT be set.' +error_message_action_remark_source_prefix_set = ( + "Action is set to remark, Source Prefix CANNOT be set." +) # Sets a standard error message for ACL rules with an action not set to remark, but no remark is set. -error_message_remark_without_action_remark = 'CANNOT set remark unless action is set to remark.' +error_message_remark_without_action_remark = ( + "CANNOT set remark unless action is set to remark." +) # Sets a standard error message for ACL rules no associated to an ACL of the same type. -error_message_acl_type = 'Provided parent Access List is not of right type.' +error_message_acl_type = "Provided parent Access List is not of right type." class AccessListSerializer(NetBoxModelSerializer): """ Defines the serializer for the django AccessList model & associates it to a view. """ + url = serializers.HyperlinkedIdentityField( - view_name='plugins-api:netbox_access_lists-api:accesslist-detail' + view_name="plugins-api:netbox_access_lists-api:accesslist-detail", ) rule_count = serializers.IntegerField(read_only=True) assigned_object_type = ContentTypeField( - queryset=ContentType.objects.filter(ACL_HOST_ASSIGNMENT_MODELS) + queryset=ContentType.objects.filter(ACL_HOST_ASSIGNMENT_MODELS), ) assigned_object = serializers.SerializerMethodField(read_only=True) @@ -55,16 +65,30 @@ class AccessListSerializer(NetBoxModelSerializer): """ Associates the django model AccessList & fields to the serializer. """ + model = AccessList fields = ( - 'id', 'url', 'display', 'name', 'assigned_object_type', 'assigned_object_id', 'assigned_object', 'type', 'default_action', 'comments', 'tags', 'custom_fields', 'created', - 'last_updated', 'rule_count' + "id", + "url", + "display", + "name", + "assigned_object_type", + "assigned_object_id", + "assigned_object", + "type", + "default_action", + "comments", + "tags", + "custom_fields", + "created", + "last_updated", + "rule_count", ) @swagger_serializer_method(serializer_or_field=serializers.DictField) def get_assigned_object(self, obj): - serializer = get_serializer_for_model(obj.assigned_object, prefix='Nested') - context = {'request': self.context['request']} + serializer = get_serializer_for_model(obj.assigned_object, prefix="Nested") + context = {"request": self.context["request"]} return serializer(obj.assigned_object, context=context).data def validate(self, data): @@ -76,18 +100,26 @@ class AccessListSerializer(NetBoxModelSerializer): error_message = {} # Check that the GFK object is valid. - if 'assigned_object_type' in data and 'assigned_object_id' in data: + if "assigned_object_type" in data and "assigned_object_id" in data: try: - assigned_object = data['assigned_object_type'].get_object_for_this_type(id=data['assigned_object_id']) + assigned_object = data["assigned_object_type"].get_object_for_this_type( + id=data["assigned_object_id"] + ) except ObjectDoesNotExist: # Sets a standard error message for invalid GFK error_message_invalid_gfk = f"Invalid assigned_object {data['assigned_object_type']} ID {data['assigned_object_id']}" - error_message['assigned_object_type'] = [error_message_invalid_gfk] - error_message['assigned_object_id'] = [error_message_invalid_gfk] + error_message["assigned_object_type"] = [error_message_invalid_gfk] + error_message["assigned_object_id"] = [error_message_invalid_gfk] # Check if Access List has no existing rules before change the Access List's type. - if self.instance and self.instance.type != data.get('type') and self.instance.rule_count > 0: - error_message['type'] = ['This ACL has ACL rules associated, CANNOT change ACL type.'] + if ( + self.instance + and self.instance.type != data.get("type") + and self.instance.rule_count > 0 + ): + error_message["type"] = [ + "This ACL has ACL rules associated, CANNOT change ACL type." + ] if error_message: raise serializers.ValidationError(error_message) @@ -99,11 +131,12 @@ class ACLInterfaceAssignmentSerializer(NetBoxModelSerializer): """ Defines the serializer for the django ACLInterfaceAssignment model & associates it to a view. """ + url = serializers.HyperlinkedIdentityField( - view_name='plugins-api:netbox_access_lists-api:aclinterfaceassignment-detail' + view_name="plugins-api:netbox_access_lists-api:aclinterfaceassignment-detail", ) assigned_object_type = ContentTypeField( - queryset=ContentType.objects.filter(ACL_INTERFACE_ASSIGNMENT_MODELS) + queryset=ContentType.objects.filter(ACL_INTERFACE_ASSIGNMENT_MODELS), ) assigned_object = serializers.SerializerMethodField(read_only=True) @@ -111,16 +144,27 @@ class ACLInterfaceAssignmentSerializer(NetBoxModelSerializer): """ Associates the django model ACLInterfaceAssignment & fields to the serializer. """ + model = ACLInterfaceAssignment fields = ( - 'id', 'url', 'access_list', 'direction', 'assigned_object_type', 'assigned_object_id', 'assigned_object', 'comments', 'tags', 'custom_fields', 'created', - 'last_updated' + "id", + "url", + "access_list", + "direction", + "assigned_object_type", + "assigned_object_id", + "assigned_object", + "comments", + "tags", + "custom_fields", + "created", + "last_updated", ) @swagger_serializer_method(serializer_or_field=serializers.DictField) def get_assigned_object(self, obj): - serializer = get_serializer_for_model(obj.assigned_object, prefix='Nested') - context = {'request': self.context['request']} + serializer = get_serializer_for_model(obj.assigned_object, prefix="Nested") + context = {"request": self.context["request"]} return serializer(obj.assigned_object, context=context).data def validate(self, data): @@ -130,56 +174,81 @@ class ACLInterfaceAssignmentSerializer(NetBoxModelSerializer): - Check that the associated interface's parent host has the selected ACL defined. """ error_message = {} - acl_host = data['access_list'].assigned_object + acl_host = data["access_list"].assigned_object # Check that the GFK object is vlaid. - if 'assigned_object_type' in data and 'assigned_object_id' in data: + if "assigned_object_type" in data and "assigned_object_id" in data: try: - assigned_object = data['assigned_object_type'].get_object_for_this_type(id=data['assigned_object_id']) + assigned_object = data["assigned_object_type"].get_object_for_this_type( + id=data["assigned_object_id"] + ) except ObjectDoesNotExist: # Sets a standard error message for invalid GFK error_message_invalid_gfk = f"Invalid assigned_object {data['assigned_object_type']} ID {data['assigned_object_id']}" - error_message['assigned_object_type'] = [error_message_invalid_gfk] - error_message['assigned_object_id'] = [error_message_invalid_gfk] + error_message["assigned_object_type"] = [error_message_invalid_gfk] + error_message["assigned_object_id"] = [error_message_invalid_gfk] - - if data['assigned_object_type'].model == 'interface': - interface_host = data['assigned_object_type'].get_object_for_this_type(id=data['assigned_object_id']).device - elif data['assigned_object_type'].model == 'vminterface': - interface_host = data['assigned_object_type'].get_object_for_this_type(id=data['assigned_object_id']).virtual_machine + if data["assigned_object_type"].model == "interface": + interface_host = ( + data["assigned_object_type"] + .get_object_for_this_type(id=data["assigned_object_id"]) + .device + ) + elif data["assigned_object_type"].model == "vminterface": + interface_host = ( + data["assigned_object_type"] + .get_object_for_this_type(id=data["assigned_object_id"]) + .virtual_machine + ) # Check that the associated interface's parent host has the selected ACL defined. if acl_host != interface_host: - error_acl_not_assigned_to_host = "Access List not present on the selected interface's host." - error_message['access_list'] = [error_acl_not_assigned_to_host] - error_message['assigned_object_id'] = [error_acl_not_assigned_to_host] + error_acl_not_assigned_to_host = ( + "Access List not present on the selected interface's host." + ) + error_message["access_list"] = [error_acl_not_assigned_to_host] + error_message["assigned_object_id"] = [error_acl_not_assigned_to_host] if error_message: raise serializers.ValidationError(error_message) return super().validate(data) + class ACLStandardRuleSerializer(NetBoxModelSerializer): """ Defines the serializer for the django ACLStandardRule model & associates it to a view. """ + url = serializers.HyperlinkedIdentityField( - view_name='plugins-api:netbox_access_lists-api:aclstandardrule-detail' + view_name="plugins-api:netbox_access_lists-api:aclstandardrule-detail", ) access_list = NestedAccessListSerializer() source_prefix = NestedPrefixSerializer( required=False, allow_null=True, - default=None + default=None, ) class Meta: """ Associates the django model ACLStandardRule & fields to the serializer. """ + model = ACLStandardRule fields = ( - 'id', 'url', 'display', 'access_list', 'index', 'action', 'tags', 'description', - 'remark', 'created', 'custom_fields', 'last_updated', 'source_prefix' + "id", + "url", + "display", + "access_list", + "index", + "action", + "tags", + "description", + "remark", + "created", + "custom_fields", + "last_updated", + "source_prefix", ) def validate(self, data): @@ -191,11 +260,13 @@ class ACLStandardRuleSerializer(NetBoxModelSerializer): error_message = {} # Check if action set to remark, but no remark set. - if data.get('action') == 'remark' and data.get('remark') is None: - error_message['remark'] = [error_message_no_remark] + if data.get("action") == "remark" and data.get("remark") is None: + error_message["remark"] = [error_message_no_remark] # Check if action set to remark, but source_prefix set. - if data.get('source_prefix'): - error_message['source_prefix'] = [error_message_action_remark_source_prefix_set] + if data.get("source_prefix"): + error_message["source_prefix"] = [ + error_message_action_remark_source_prefix_set + ] if error_message: raise serializers.ValidationError(error_message) @@ -207,30 +278,46 @@ class ACLExtendedRuleSerializer(NetBoxModelSerializer): """ Defines the serializer for the django ACLExtendedRule model & associates it to a view. """ + url = serializers.HyperlinkedIdentityField( - view_name='plugins-api:netbox_access_lists-api:aclextendedrule-detail' + view_name="plugins-api:netbox_access_lists-api:aclextendedrule-detail", ) access_list = NestedAccessListSerializer() source_prefix = NestedPrefixSerializer( required=False, allow_null=True, - default=None + default=None, ) destination_prefix = NestedPrefixSerializer( required=False, allow_null=True, - default=None + default=None, ) class Meta: """ Associates the django model ACLExtendedRule & fields to the serializer. """ + model = ACLExtendedRule fields = ( - 'id', 'url', 'display', 'access_list', 'index', 'action', 'tags', 'description', - 'created', 'custom_fields', 'last_updated', 'source_prefix', 'source_ports', - 'destination_prefix', 'destination_ports', 'protocol', 'remark', + "id", + "url", + "display", + "access_list", + "index", + "action", + "tags", + "description", + "created", + "custom_fields", + "last_updated", + "source_prefix", + "source_ports", + "destination_prefix", + "destination_ports", + "protocol", + "remark", ) def validate(self, data): @@ -247,23 +334,33 @@ class ACLExtendedRuleSerializer(NetBoxModelSerializer): error_message = {} # Check if action set to remark, but no remark set. - if data.get('action') == 'remark' and data.get('remark') is None: - error_message['remark'] = [error_message_no_remark] + if data.get("action") == "remark" and data.get("remark") is None: + error_message["remark"] = [error_message_no_remark] # Check if action set to remark, but source_prefix set. - if data.get('source_prefix'): - error_message['source_prefix'] = [error_message_action_remark_source_prefix_set] + if data.get("source_prefix"): + error_message["source_prefix"] = [ + error_message_action_remark_source_prefix_set + ] # Check if action set to remark, but source_ports set. - if data.get('source_ports'): - error_message['source_ports'] = ['Action is set to remark, Source Ports CANNOT be set.'] + if data.get("source_ports"): + error_message["source_ports"] = [ + "Action is set to remark, Source Ports CANNOT be set." + ] # Check if action set to remark, but destination_prefix set. - if data.get('destination_prefix'): - error_message['destination_prefix'] = ['Action is set to remark, Destination Prefix CANNOT be set.'] + if data.get("destination_prefix"): + error_message["destination_prefix"] = [ + "Action is set to remark, Destination Prefix CANNOT be set." + ] # Check if action set to remark, but destination_ports set. - if data.get('destination_ports'): - error_message['destination_ports'] = ['Action is set to remark, Destination Ports CANNOT be set.'] + if data.get("destination_ports"): + error_message["destination_ports"] = [ + "Action is set to remark, Destination Ports CANNOT be set." + ] # Check if action set to remark, but protocol set. - if data.get('protocol'): - error_message['protocol'] = ['Action is set to remark, Protocol CANNOT be set.'] + if data.get("protocol"): + error_message["protocol"] = [ + "Action is set to remark, Protocol CANNOT be set." + ] if error_message: raise serializers.ValidationError(error_message) diff --git a/netbox_access_lists/api/urls.py b/netbox_access_lists/api/urls.py index f38d1d9..dd6853f 100644 --- a/netbox_access_lists/api/urls.py +++ b/netbox_access_lists/api/urls.py @@ -6,12 +6,12 @@ from netbox.api.routers import NetBoxRouter from . import views -app_name = 'netbox_access_list' +app_name = "netbox_access_list" router = NetBoxRouter() -router.register('access-lists', views.AccessListViewSet) -router.register('interface-assignments', views.ACLInterfaceAssignmentViewSet) -router.register('standard-acl-rules', views.ACLStandardRuleViewSet) -router.register('extended-acl-rules', views.ACLExtendedRuleViewSet) +router.register("access-lists", views.AccessListViewSet) +router.register("interface-assignments", views.ACLInterfaceAssignmentViewSet) +router.register("standard-acl-rules", views.ACLStandardRuleViewSet) +router.register("extended-acl-rules", views.ACLExtendedRuleViewSet) urlpatterns = router.urls diff --git a/netbox_access_lists/api/views.py b/netbox_access_lists/api/views.py index d4bd19b..589285f 100644 --- a/netbox_access_lists/api/views.py +++ b/netbox_access_lists/api/views.py @@ -8,15 +8,17 @@ from django.db.models import Count from netbox.api.viewsets import NetBoxModelViewSet from .. import filtersets, models -from .serializers import (AccessListSerializer, ACLExtendedRuleSerializer, - ACLInterfaceAssignmentSerializer, - ACLStandardRuleSerializer) +from .serializers import ( + AccessListSerializer, + ACLExtendedRuleSerializer, + ACLInterfaceAssignmentSerializer, + ACLStandardRuleSerializer, +) __all__ = [ - 'AccessListViewSet', - 'ACLStandardRuleViewSet', - 'ACLInterfaceAssignmentViewSet' - 'ACLExtendedRuleViewSet', + "AccessListViewSet", + "ACLStandardRuleViewSet", + "ACLInterfaceAssignmentViewSet" "ACLExtendedRuleViewSet", ] @@ -24,8 +26,9 @@ class AccessListViewSet(NetBoxModelViewSet): """ Defines the view set for the django AccessList model & associates it to a view. """ - queryset = models.AccessList.objects.prefetch_related('tags').annotate( - rule_count=Count('aclextendedrules') + Count('aclstandardrules') + + queryset = models.AccessList.objects.prefetch_related("tags").annotate( + rule_count=Count("aclextendedrules") + Count("aclstandardrules"), ) serializer_class = AccessListSerializer filterset_class = filtersets.AccessListFilterSet @@ -35,7 +38,10 @@ class ACLInterfaceAssignmentViewSet(NetBoxModelViewSet): """ Defines the view set for the django ACLInterfaceAssignment model & associates it to a view. """ - queryset = models.ACLInterfaceAssignment.objects.prefetch_related('access_list', 'tags') + + queryset = models.ACLInterfaceAssignment.objects.prefetch_related( + "access_list", "tags" + ) serializer_class = ACLInterfaceAssignmentSerializer filterset_class = filtersets.ACLInterfaceAssignmentFilterSet @@ -44,8 +50,11 @@ class ACLStandardRuleViewSet(NetBoxModelViewSet): """ Defines the view set for the django ACLStandardRule model & associates it to a view. """ + queryset = models.ACLStandardRule.objects.prefetch_related( - 'access_list', 'tags', 'source_prefix' + "access_list", + "tags", + "source_prefix", ) serializer_class = ACLStandardRuleSerializer filterset_class = filtersets.ACLStandardRuleFilterSet @@ -55,8 +64,12 @@ class ACLExtendedRuleViewSet(NetBoxModelViewSet): """ Defines the view set for the django ACLExtendedRule model & associates it to a view. """ + queryset = models.ACLExtendedRule.objects.prefetch_related( - 'access_list', 'tags', 'source_prefix', 'destination_prefix', + "access_list", + "tags", + "source_prefix", + "destination_prefix", ) serializer_class = ACLExtendedRuleSerializer filterset_class = filtersets.ACLExtendedRuleFilterSet diff --git a/netbox_access_lists/choices.py b/netbox_access_lists/choices.py index 6531e9b..8247d45 100644 --- a/netbox_access_lists/choices.py +++ b/netbox_access_lists/choices.py @@ -5,12 +5,12 @@ Defines the various choices to be used by the models, forms, and other plugin sp from utilities.choices import ChoiceSet __all__ = ( - 'ACLActionChoices', - 'ACLAssignmentDirectionChoices', - 'ACLProtocolChoices', - 'ACLRuleActionChoices', - 'ACLTypeChoices', - 'ACLProtocolChoices', + "ACLActionChoices", + "ACLAssignmentDirectionChoices", + "ACLProtocolChoices", + "ACLRuleActionChoices", + "ACLTypeChoices", + "ACLProtocolChoices", ) @@ -18,14 +18,15 @@ class ACLActionChoices(ChoiceSet): """ Defines the choices availble for the Access Lists plugin specific to ACL default_action. """ - ACTION_DENY = 'deny' - ACTION_PERMIT = 'permit' - ACTION_REJECT = 'reject' + + ACTION_DENY = "deny" + ACTION_PERMIT = "permit" + ACTION_REJECT = "reject" CHOICES = [ - (ACTION_DENY, 'Deny', 'red'), - (ACTION_PERMIT, 'Permit', 'green'), - (ACTION_REJECT, 'Reject (Reset)', 'orange'), + (ACTION_DENY, "Deny", "red"), + (ACTION_PERMIT, "Permit", "green"), + (ACTION_REJECT, "Reject (Reset)", "orange"), ] @@ -33,14 +34,15 @@ class ACLRuleActionChoices(ChoiceSet): """ Defines the choices availble for the Access Lists plugin specific to ACL rule actions. """ - ACTION_DENY = 'deny' - ACTION_PERMIT = 'permit' - ACTION_REMARK = 'remark' + + ACTION_DENY = "deny" + ACTION_PERMIT = "permit" + ACTION_REMARK = "remark" CHOICES = [ - (ACTION_DENY, 'Deny', 'red'), - (ACTION_PERMIT, 'Permit', 'green'), - (ACTION_REMARK, 'Remark', 'blue'), + (ACTION_DENY, "Deny", "red"), + (ACTION_PERMIT, "Permit", "green"), + (ACTION_REMARK, "Remark", "blue"), ] @@ -50,8 +52,8 @@ class ACLAssignmentDirectionChoices(ChoiceSet): """ CHOICES = [ - ('ingress', 'Ingress', 'blue'), - ('egress', 'Egress', 'purple'), + ("ingress", "Ingress", "blue"), + ("egress", "Egress", "purple"), ] @@ -59,9 +61,10 @@ class ACLTypeChoices(ChoiceSet): """ Defines the choices availble for the Access Lists plugin specific to ACL type. """ + CHOICES = [ - ('extended', 'Extended', 'purple'), - ('standard', 'Standard', 'blue'), + ("extended", "Extended", "purple"), + ("standard", "Standard", "blue"), ] @@ -69,8 +72,9 @@ class ACLProtocolChoices(ChoiceSet): """ Defines the choices availble for the Access Lists plugin specific to ACL Rule protocol. """ + CHOICES = [ - ('icmp', 'ICMP', 'purple'), - ('tcp', 'TCP', 'blue'), - ('udp', 'UDP', 'orange'), + ("icmp", "ICMP", "purple"), + ("tcp", "TCP", "blue"), + ("udp", "UDP", "orange"), ] diff --git a/netbox_access_lists/constants.py b/netbox_access_lists/constants.py index 74f5b26..8d73006 100644 --- a/netbox_access_lists/constants.py +++ b/netbox_access_lists/constants.py @@ -4,12 +4,12 @@ Constants for filters from django.db.models import Q ACL_HOST_ASSIGNMENT_MODELS = Q( - Q(app_label='dcim', model='device') | - Q(app_label='dcim', model='virtualchassis') | - Q(app_label='virtualization', model='virtualmachine') + Q(app_label="dcim", model="device") + | Q(app_label="dcim", model="virtualchassis") + | Q(app_label="virtualization", model="virtualmachine"), ) ACL_INTERFACE_ASSIGNMENT_MODELS = Q( - Q(app_label='dcim', model='interface') | - Q(app_label='virtualization', model='vminterface') -) \ No newline at end of file + Q(app_label="dcim", model="interface") + | Q(app_label="virtualization", model="vminterface"), +) diff --git a/netbox_access_lists/filtersets.py b/netbox_access_lists/filtersets.py index d03b16e..326850e 100644 --- a/netbox_access_lists/filtersets.py +++ b/netbox_access_lists/filtersets.py @@ -10,10 +10,10 @@ from virtualization.models import VirtualMachine, VMInterface from .models import * __all__ = ( - 'AccessListFilterSet', - 'ACLStandardRuleFilterSet', - 'ACLInterfaceAssignmentFilterSet', - 'ACLExtendedRuleFilterSet', + "AccessListFilterSet", + "ACLStandardRuleFilterSet", + "ACLInterfaceAssignmentFilterSet", + "ACLExtendedRuleFilterSet", ) @@ -21,46 +21,60 @@ class AccessListFilterSet(NetBoxModelFilterSet): """ Define the filter set for the django model AccessList. """ + device = django_filters.ModelMultipleChoiceFilter( - field_name='device__name', + field_name="device__name", queryset=Device.objects.all(), - to_field_name='name', - label='Device (name)', + to_field_name="name", + label="Device (name)", ) device_id = django_filters.ModelMultipleChoiceFilter( - field_name='device', + field_name="device", queryset=Device.objects.all(), - label='Device (ID)', + label="Device (ID)", ) virtual_chassis = django_filters.ModelMultipleChoiceFilter( - field_name='virtual_chassis__name', + field_name="virtual_chassis__name", queryset=VirtualChassis.objects.all(), - to_field_name='name', - label='Virtual Chassis (name)', + to_field_name="name", + label="Virtual Chassis (name)", ) virtual_chassis_id = django_filters.ModelMultipleChoiceFilter( - field_name='virtual_chassis', + field_name="virtual_chassis", queryset=VirtualChassis.objects.all(), - label='Virtual Chassis (ID)', + label="Virtual Chassis (ID)", ) virtual_machine = django_filters.ModelMultipleChoiceFilter( - field_name='virtual_machine__name', + field_name="virtual_machine__name", queryset=VirtualMachine.objects.all(), - to_field_name='name', - label='Virtual Machine (name)', + to_field_name="name", + label="Virtual Machine (name)", ) virtual_machine_id = django_filters.ModelMultipleChoiceFilter( - field_name='virtual_machine', + field_name="virtual_machine", queryset=VirtualMachine.objects.all(), - label='Virtual machine (ID)', + label="Virtual machine (ID)", ) class Meta: """ Associates the django model AccessList & fields to the filter set. """ + model = AccessList - fields = ('id', 'name', 'device', 'device_id', 'virtual_chassis', 'virtual_chassis_id', 'virtual_machine', 'virtual_machine_id', 'type', 'default_action', 'comments') + fields = ( + "id", + "name", + "device", + "device_id", + "virtual_chassis", + "virtual_chassis_id", + "virtual_machine", + "virtual_machine_id", + "type", + "default_action", + "comments", + ) def search(self, queryset, name, value): """ @@ -73,35 +87,45 @@ class ACLInterfaceAssignmentFilterSet(NetBoxModelFilterSet): """ Define the filter set for the django model ACLInterfaceAssignment. """ + interface = django_filters.ModelMultipleChoiceFilter( - field_name='interface__name', + field_name="interface__name", queryset=Interface.objects.all(), - to_field_name='name', - label='Interface (name)', + to_field_name="name", + label="Interface (name)", ) interface_id = django_filters.ModelMultipleChoiceFilter( - field_name='interface', + field_name="interface", queryset=Interface.objects.all(), - label='Interface (ID)', + label="Interface (ID)", ) vminterface = django_filters.ModelMultipleChoiceFilter( - field_name='vminterface__name', + field_name="vminterface__name", queryset=VMInterface.objects.all(), - to_field_name='name', - label='VM Interface (name)', + to_field_name="name", + label="VM Interface (name)", ) vminterface_id = django_filters.ModelMultipleChoiceFilter( - field_name='vminterface', + field_name="vminterface", queryset=VMInterface.objects.all(), - label='VM Interface (ID)', + label="VM Interface (ID)", ) class Meta: """ Associates the django model ACLInterfaceAssignment & fields to the filter set. """ + model = ACLInterfaceAssignment - fields = ('id', 'access_list', 'direction', 'interface', 'interface_id', 'vminterface', 'vminterface_id') + fields = ( + "id", + "access_list", + "direction", + "interface", + "interface_id", + "vminterface", + "vminterface_id", + ) def search(self, queryset, name, value): """ @@ -119,8 +143,9 @@ class ACLStandardRuleFilterSet(NetBoxModelFilterSet): """ Associates the django model ACLStandardRule & fields to the filter set. """ + model = ACLStandardRule - fields = ('id', 'access_list', 'index', 'action') + fields = ("id", "access_list", "index", "action") def search(self, queryset, name, value): """ @@ -138,8 +163,9 @@ class ACLExtendedRuleFilterSet(NetBoxModelFilterSet): """ Associates the django model ACLExtendedRule & fields to the filter set. """ + model = ACLExtendedRule - fields = ('id', 'access_list', 'index', 'action', 'protocol') + fields = ("id", "access_list", "index", "action", "protocol") def search(self, queryset, name, value): """ diff --git a/netbox_access_lists/forms/__init__.py b/netbox_access_lists/forms/__init__.py index 909d541..9e74634 100644 --- a/netbox_access_lists/forms/__init__.py +++ b/netbox_access_lists/forms/__init__.py @@ -2,13 +2,15 @@ Import each of the directory's scripts. """ -#from .bulk_create import * +# from .bulk_create import * from .bulk_edit import * -#from .bulk_import import * -#from .connections import * + +# from .bulk_import import * +# from .connections import * from .filtersets import * -#from .formsets import * + +# from .formsets import * from .models import * -#from .object_create import * -#from .object_import import * +# from .object_create import * +# from .object_import import * diff --git a/netbox_access_lists/forms/bulk_edit.py b/netbox_access_lists/forms/bulk_edit.py index bf9d72d..4a62ca9 100644 --- a/netbox_access_lists/forms/bulk_edit.py +++ b/netbox_access_lists/forms/bulk_edit.py @@ -7,19 +7,23 @@ from django import forms from django.core.exceptions import ValidationError from django.utils.safestring import mark_safe from netbox.forms import NetBoxModelBulkEditForm -from utilities.forms import (ChoiceField, DynamicModelChoiceField, - StaticSelect, add_blank_choice) +from utilities.forms import ( + ChoiceField, + DynamicModelChoiceField, + StaticSelect, + add_blank_choice, +) from virtualization.models import VirtualMachine from ..choices import ACLActionChoices, ACLTypeChoices from ..models import AccessList -#__all__ = ( +# __all__ = ( # 'AccessListBulkEditForm', -#) +# ) -#class AccessListBulkEditForm(NetBoxModelBulkEditForm): +# class AccessListBulkEditForm(NetBoxModelBulkEditForm): # model = AccessList # # region = DynamicModelChoiceField( diff --git a/netbox_access_lists/forms/filtersets.py b/netbox_access_lists/forms/filtersets.py index 96d09b9..5e37852 100644 --- a/netbox_access_lists/forms/filtersets.py +++ b/netbox_access_lists/forms/filtersets.py @@ -2,27 +2,39 @@ Defines each django model's GUI filter/search options. """ -from dcim.models import (Device, Interface, Region, Site, SiteGroup, - VirtualChassis) +from dcim.models import Device, Interface, Region, Site, SiteGroup, VirtualChassis from django import forms from ipam.models import Prefix from netbox.forms import NetBoxModelFilterSetForm -from utilities.forms import (ChoiceField, DynamicModelChoiceField, - StaticSelect, StaticSelectMultiple, - TagFilterField, add_blank_choice) +from utilities.forms import ( + ChoiceField, + DynamicModelChoiceField, + StaticSelect, + StaticSelectMultiple, + TagFilterField, + add_blank_choice, +) from virtualization.models import VirtualMachine, VMInterface -from ..choices import (ACLActionChoices, ACLAssignmentDirectionChoices, - ACLProtocolChoices, ACLRuleActionChoices, - ACLTypeChoices) -from ..models import (AccessList, ACLExtendedRule, ACLInterfaceAssignment, - ACLStandardRule) +from ..choices import ( + ACLActionChoices, + ACLAssignmentDirectionChoices, + ACLProtocolChoices, + ACLRuleActionChoices, + ACLTypeChoices, +) +from ..models import ( + AccessList, + ACLExtendedRule, + ACLInterfaceAssignment, + ACLStandardRule, +) __all__ = ( - 'AccessListFilterForm', - 'ACLInterfaceAssignmentFilterForm', - 'ACLStandardRuleFilterForm', - 'ACLExtendedRuleFilterForm', + "AccessListFilterForm", + "ACLInterfaceAssignmentFilterForm", + "ACLStandardRuleFilterForm", + "ACLExtendedRuleFilterForm", ) @@ -30,6 +42,7 @@ class AccessListFilterForm(NetBoxModelFilterSetForm): """ GUI filter form to search the django AccessList model. """ + model = AccessList region = DynamicModelChoiceField( queryset=Region.objects.all(), @@ -38,40 +51,40 @@ class AccessListFilterForm(NetBoxModelFilterSetForm): site_group = DynamicModelChoiceField( queryset=SiteGroup.objects.all(), required=False, - label='Site Group' + label="Site Group", ) site = DynamicModelChoiceField( queryset=Site.objects.all(), - required=False + required=False, ) device = DynamicModelChoiceField( queryset=Device.objects.all(), query_params={ - 'region': '$region', - 'group_id': '$site_group', - 'site_id': '$site', + "region": "$region", + "group_id": "$site_group", + "site_id": "$site", }, - required=False + required=False, ) type = ChoiceField( choices=add_blank_choice(ACLTypeChoices), required=False, - initial='', + initial="", widget=StaticSelect(), ) default_action = ChoiceField( choices=add_blank_choice(ACLActionChoices), required=False, - initial='', + initial="", widget=StaticSelect(), - label='Default Action', + label="Default Action", ) tag = TagFilterField(model) fieldsets = ( - (None, ('q', 'tag')), - ('Host Details', ('region', 'site_group', 'site', 'device')), - ('ACL Details', ('type', 'default_action')), + (None, ("q", "tag")), + ("Host Details", ("region", "site_group", "site", "device")), + ("ACL Details", ("type", "default_action")), ) @@ -79,6 +92,7 @@ class ACLInterfaceAssignmentFilterForm(NetBoxModelFilterSetForm): """ GUI filter form to search the django AccessList model. """ + model = ACLInterfaceAssignment region = DynamicModelChoiceField( queryset=Region.objects.all(), @@ -87,84 +101,85 @@ class ACLInterfaceAssignmentFilterForm(NetBoxModelFilterSetForm): site_group = DynamicModelChoiceField( queryset=SiteGroup.objects.all(), required=False, - label='Site Group' + label="Site Group", ) site = DynamicModelChoiceField( queryset=Site.objects.all(), - required=False + required=False, ) device = DynamicModelChoiceField( queryset=Device.objects.all(), query_params={ - 'region': '$region', - 'group_id': '$site_group', - 'site_id': '$site', + "region": "$region", + "group_id": "$site_group", + "site_id": "$site", }, - required=False + required=False, ) interface = DynamicModelChoiceField( queryset=Interface.objects.all(), required=False, query_params={ - 'device_id': '$device' - } + "device_id": "$device", + }, ) virtual_machine = DynamicModelChoiceField( queryset=VirtualMachine.objects.all(), required=False, - label='Virtual Machine', + label="Virtual Machine", ) vminterface = DynamicModelChoiceField( queryset=VMInterface.objects.all(), required=False, query_params={ - 'virtual_machine_id': '$virtual_machine' + "virtual_machine_id": "$virtual_machine", }, - label='Interface' + label="Interface", ) access_list = DynamicModelChoiceField( queryset=AccessList.objects.all(), query_params={ - 'assigned_object': '$device', + "assigned_object": "$device", }, - label='Access List', + label="Access List", ) direction = ChoiceField( choices=add_blank_choice(ACLAssignmentDirectionChoices), required=False, - initial='', + initial="", widget=StaticSelect(), ) tag = TagFilterField(model) - #fieldsets = ( + # fieldsets = ( # (None, ('q', 'tag')), # ('Host Details', ('region', 'site_group', 'site', 'device')), # ('ACL Details', ('type', 'default_action')), - #) + # ) class ACLStandardRuleFilterForm(NetBoxModelFilterSetForm): """ GUI filter form to search the django ACLStandardRule model. """ + model = ACLStandardRule tag = TagFilterField(model) source_prefix = forms.ModelMultipleChoiceField( queryset=Prefix.objects.all(), required=False, widget=StaticSelectMultiple(), - label='Source Prefix', + label="Source Prefix", ) action = forms.ChoiceField( choices=add_blank_choice(ACLRuleActionChoices), required=False, - initial='', + initial="", widget=StaticSelect(), ) fieldsets = ( - (None, ('q', 'tag')), - ('Rule Details', ('action', 'source_prefix',)), + (None, ("q", "tag")), + ("Rule Details", ("action", "source_prefix")), ) @@ -172,37 +187,38 @@ class ACLExtendedRuleFilterForm(NetBoxModelFilterSetForm): """ GUI filter form to search the django ACLExtendedRule model. """ + model = ACLExtendedRule index = forms.IntegerField( - required=False + required=False, ) tag = TagFilterField(model) action = forms.ChoiceField( choices=add_blank_choice(ACLRuleActionChoices), required=False, widget=StaticSelect(), - initial='', + initial="", ) source_prefix = forms.ModelMultipleChoiceField( queryset=Prefix.objects.all(), required=False, widget=StaticSelectMultiple(), - label='Source Prefix', + label="Source Prefix", ) desintation_prefix = forms.ModelMultipleChoiceField( queryset=Prefix.objects.all(), required=False, widget=StaticSelectMultiple(), - label='Destination Prefix', + label="Destination Prefix", ) protocol = ChoiceField( choices=add_blank_choice(ACLProtocolChoices), required=False, widget=StaticSelect(), - initial='', + initial="", ) fieldsets = ( - (None, ('q', 'tag')), - ('Rule Details', ('action', 'source_prefix', 'desintation_prefix', 'protocol')), + (None, ("q", "tag")), + ("Rule Details", ("action", "source_prefix", "desintation_prefix", "protocol")), ) diff --git a/netbox_access_lists/forms/models.py b/netbox_access_lists/forms/models.py index 7a479bc..bbf0575 100644 --- a/netbox_access_lists/forms/models.py +++ b/netbox_access_lists/forms/models.py @@ -2,41 +2,55 @@ Defines each django model's GUI form to add or edit objects for each django model. """ -from dcim.models import (Device, Interface, Region, Site, SiteGroup, - VirtualChassis) +from dcim.models import Device, Interface, Region, Site, SiteGroup, VirtualChassis from django import forms from django.contrib.contenttypes.models import ContentType from django.utils.safestring import mark_safe from extras.models import Tag from ipam.models import Prefix from netbox.forms import NetBoxModelForm -from utilities.forms import (CommentField, DynamicModelChoiceField, - DynamicModelMultipleChoiceField) +from utilities.forms import ( + CommentField, + DynamicModelChoiceField, + DynamicModelMultipleChoiceField, +) from virtualization.models import VirtualMachine, VMInterface -from ..models import (AccessList, ACLExtendedRule, ACLInterfaceAssignment, - ACLStandardRule) +from ..models import ( + AccessList, + ACLExtendedRule, + ACLInterfaceAssignment, + ACLStandardRule, +) __all__ = ( - 'AccessListForm', - 'ACLInterfaceAssignmentForm', - 'ACLStandardRuleForm', - 'ACLExtendedRuleForm', + "AccessListForm", + "ACLInterfaceAssignmentForm", + "ACLStandardRuleForm", + "ACLExtendedRuleForm", ) # Sets a standard mark_safe help_text value to be used by the various classes -help_text_acl_rule_logic = mark_safe('*Note: CANNOT be set if action is set to remark.') +help_text_acl_rule_logic = mark_safe( + "*Note: CANNOT be set if action is set to remark." +) # Sets a standard help_text value to be used by the various classes for acl action -help_text_acl_action = 'Action the rule will take (remark, deny, or allow).' +help_text_acl_action = "Action the rule will take (remark, deny, or allow)." # Sets a standard help_text value to be used by the various classes for acl index -help_text_acl_rule_index = 'Determines the order of the rule in the ACL processing. AKA Sequence Number.' +help_text_acl_rule_index = ( + "Determines the order of the rule in the ACL processing. AKA Sequence Number." +) # Sets a standard error message for ACL rules with an action of remark, but no remark set. -error_message_no_remark = 'Action is set to remark, you MUST add a remark.' +error_message_no_remark = "Action is set to remark, you MUST add a remark." # Sets a standard error message for ACL rules with an action of remark, but no source_prefix is set. -error_message_action_remark_source_prefix_set = 'Action is set to remark, Source Prefix CANNOT be set.' +error_message_action_remark_source_prefix_set = ( + "Action is set to remark, Source Prefix CANNOT be set." +) # Sets a standard error message for ACL rules with an action not set to remark, but no remark is set. -error_message_remark_without_action_remark = 'CANNOT set remark unless action is set to remark.' +error_message_remark_without_action_remark = ( + "CANNOT set remark unless action is set to remark." +) class AccessListForm(NetBoxModelForm): @@ -44,6 +58,7 @@ class AccessListForm(NetBoxModelForm): GUI form to add or edit an AccessList. Requires a device, a name, a type, and a default_action. """ + region = DynamicModelChoiceField( queryset=Region.objects.all(), required=False, @@ -51,59 +66,73 @@ class AccessListForm(NetBoxModelForm): site_group = DynamicModelChoiceField( queryset=SiteGroup.objects.all(), required=False, - label='Site Group' + label="Site Group", ) site = DynamicModelChoiceField( queryset=Site.objects.all(), - required=False + required=False, ) device = DynamicModelChoiceField( queryset=Device.objects.all(), required=False, query_params={ - 'region': '$region', - 'group_id': '$site_group', - 'site_id': '$site', + "region": "$region", + "group_id": "$site_group", + "site_id": "$site", }, ) virtual_chassis = DynamicModelChoiceField( queryset=VirtualChassis.objects.all(), required=False, - label='Virtual Chassis', + label="Virtual Chassis", ) virtual_machine = DynamicModelChoiceField( queryset=VirtualMachine.objects.all(), required=False, - label='Virtual Machine', + label="Virtual Machine", ) comments = CommentField() tags = DynamicModelMultipleChoiceField( queryset=Tag.objects.all(), - required=False + required=False, ) class Meta: model = AccessList - fields = ('region', 'site_group', 'site', 'device', 'virtual_machine', 'virtual_chassis', 'name', 'type', 'default_action', 'comments', 'tags') + fields = ( + "region", + "site_group", + "site", + "device", + "virtual_machine", + "virtual_chassis", + "name", + "type", + "default_action", + "comments", + "tags", + ) help_texts = { - 'default_action': 'The default behavior of the ACL.', - 'name': 'The name uniqueness per device is case insensitive.', - 'type': mark_safe('*Note: CANNOT be changed if ACL Rules are assoicated to this Access List.'), + "default_action": "The default behavior of the ACL.", + "name": "The name uniqueness per device is case insensitive.", + "type": mark_safe( + "*Note: CANNOT be changed if ACL Rules are assoicated to this Access List." + ), } def __init__(self, *args, **kwargs): # Initialize helper selectors - instance = kwargs.get('instance') - initial = kwargs.get('initial', {}).copy() + instance = kwargs.get("instance") + initial = kwargs.get("initial", {}).copy() if instance: if type(instance.assigned_object) is Device: - initial['device'] = instance.assigned_object + initial["device"] = instance.assigned_object elif type(instance.assigned_object) is VirtualChassis: - initial['virtual_chassis'] = instance.assigned_object + initial["virtual_chassis"] = instance.assigned_object elif type(instance.assigned_object) is VirtualMachine: - initial['virtual_machine'] = instance.assigned_object - kwargs['initial'] = initial + initial["virtual_machine"] = instance.assigned_object + kwargs["initial"] = initial super().__init__(*args, **kwargs) @@ -117,40 +146,62 @@ class AccessListForm(NetBoxModelForm): """ cleaned_data = super().clean() error_message = {} - if self.errors.get('name'): + if self.errors.get("name"): return cleaned_data - name = cleaned_data.get('name') - acl_type = cleaned_data.get('type') - device = cleaned_data.get('device') - virtual_chassis = cleaned_data.get('virtual_chassis') - virtual_machine = cleaned_data.get('virtual_machine') - + name = cleaned_data.get("name") + acl_type = cleaned_data.get("type") + device = cleaned_data.get("device") + virtual_chassis = cleaned_data.get("virtual_chassis") + virtual_machine = cleaned_data.get("virtual_machine") # Check if more than one host type selected. - if (device and virtual_chassis) or (device and virtual_machine) or (virtual_chassis and virtual_machine): - raise forms.ValidationError('Access Lists must be assigned to one host (either a device, virtual chassis or virtual machine) at a time.') + if ( + (device and virtual_chassis) + or (device and virtual_machine) + or (virtual_chassis and virtual_machine) + ): + raise forms.ValidationError( + "Access Lists must be assigned to one host (either a device, virtual chassis or virtual machine) at a time." + ) # Check if no hosts selected. if not device and not virtual_chassis and not virtual_machine: - raise forms.ValidationError('Access Lists must be assigned to a device, virtual chassis or virtual machine.') + raise forms.ValidationError( + "Access Lists must be assigned to a device, virtual chassis or virtual machine." + ) if device: - host_type = 'device' + host_type = "device" existing_acls = AccessList.objects.filter(name=name, device=device).exists() elif virtual_chassis: - host_type = 'virtual_chassis' - existing_acls = AccessList.objects.filter(name=name, virtual_chassis=virtual_chassis).exists() + host_type = "virtual_chassis" + existing_acls = AccessList.objects.filter( + name=name, virtual_chassis=virtual_chassis + ).exists() elif virtual_machine: - host_type = 'virtual_machine' - existing_acls = AccessList.objects.filter(name=name, virtual_machine=virtual_machine).exists() + host_type = "virtual_machine" + existing_acls = AccessList.objects.filter( + name=name, virtual_machine=virtual_machine + ).exists() host = cleaned_data.get(host_type) # Check if duplicate entry. - if ('name' in self.changed_data or host_type in self.changed_data) and existing_acls: - error_same_acl_name = 'An ACL with this name is already associated to this host.' - error_message |= {host_type: [error_same_acl_name], 'name': [error_same_acl_name]} + if ( + "name" in self.changed_data or host_type in self.changed_data + ) and existing_acls: + error_same_acl_name = ( + "An ACL with this name is already associated to this host." + ) + error_message |= { + host_type: [error_same_acl_name], + "name": [error_same_acl_name], + } # Check if Access List has no existing rules before change the Access List's type. - if (acl_type == 'extended' and self.instance.aclstandardrules.exists()) or (acl_type == 'standard' and self.instance.aclextendedrules.exists()): - error_message['type'] = ['This ACL has ACL rules associated, CANNOT change ACL type.'] + if (acl_type == "extended" and self.instance.aclstandardrules.exists()) or ( + acl_type == "standard" and self.instance.aclextendedrules.exists() + ): + error_message["type"] = [ + "This ACL has ACL rules associated, CANNOT change ACL type." + ] if error_message: raise forms.ValidationError(error_message) @@ -159,7 +210,11 @@ class AccessListForm(NetBoxModelForm): def save(self, *args, **kwargs): # Set assigned object - self.instance.assigned_object = self.cleaned_data.get('device') or self.cleaned_data.get('virtual_chassis') or self.cleaned_data.get('virtual_machine') + self.instance.assigned_object = ( + self.cleaned_data.get("device") + or self.cleaned_data.get("virtual_chassis") + or self.cleaned_data.get("virtual_machine") + ) return super().save(*args, **kwargs) @@ -169,78 +224,88 @@ class ACLInterfaceAssignmentForm(NetBoxModelForm): GUI form to add or edit ACL Host Object assignments Requires an access_list, a name, a type, and a default_action. """ + device = DynamicModelChoiceField( queryset=Device.objects.all(), required=False, query_params={ - # Need to pass ACL device to it + # Need to pass ACL device to it }, ) interface = DynamicModelChoiceField( queryset=Interface.objects.all(), required=False, query_params={ - 'device_id': '$device' - } + "device_id": "$device", + }, ) virtual_machine = DynamicModelChoiceField( queryset=VirtualMachine.objects.all(), required=False, - label='Virtual Machine', + label="Virtual Machine", ) vminterface = DynamicModelChoiceField( queryset=VMInterface.objects.all(), required=False, query_params={ - 'virtual_machine_id': '$virtual_machine' + "virtual_machine_id": "$virtual_machine", }, - label='VM Interface' + label="VM Interface", ) - #virtual_chassis = DynamicModelChoiceField( + # virtual_chassis = DynamicModelChoiceField( # queryset=VirtualChassis.objects.all(), # required=False, # label='Virtual Chassis', - #) + # ) access_list = DynamicModelChoiceField( queryset=AccessList.objects.all(), - #query_params={ + # query_params={ # 'assigned_object': '$device', # 'assigned_object': '$virtual_machine', - #}, - label='Access List', - help_text=mark_safe('*Note: Access List must be present on the device already.') + # }, + label="Access List", + help_text=mark_safe( + "*Note: Access List must be present on the device already." + ), ) comments = CommentField() tags = DynamicModelMultipleChoiceField( queryset=Tag.objects.all(), - required=False + required=False, ) def __init__(self, *args, **kwargs): # Initialize helper selectors - instance = kwargs.get('instance') - initial = kwargs.get('initial', {}).copy() + instance = kwargs.get("instance") + initial = kwargs.get("initial", {}).copy() if instance: if type(instance.assigned_object) is Interface: - initial['interface'] = instance.assigned_object - initial['device'] = 'device' + initial["interface"] = instance.assigned_object + initial["device"] = "device" elif type(instance.assigned_object) is VMInterface: - initial['vminterface'] = instance.assigned_object - initial['virtual_machine'] = 'virtual_machine' - kwargs['initial'] = initial + initial["vminterface"] = instance.assigned_object + initial["virtual_machine"] = "virtual_machine" + kwargs["initial"] = initial super().__init__(*args, **kwargs) - class Meta: model = ACLInterfaceAssignment fields = ( - 'access_list', 'direction', 'device', 'interface', 'virtual_machine', - 'vminterface', 'comments', 'tags', + "access_list", + "direction", + "device", + "interface", + "virtual_machine", + "vminterface", + "comments", + "tags", ) help_texts = { - 'direction': mark_safe('*Note: CANNOT assign 2 ACLs to the same interface & direction.'), + "direction": mark_safe( + "*Note: CANNOT assign 2 ACLs to the same interface & direction." + ), } def clean(self): @@ -255,47 +320,81 @@ class ACLInterfaceAssignmentForm(NetBoxModelForm): """ cleaned_data = super().clean() error_message = {} - access_list = cleaned_data.get('access_list') - direction = cleaned_data.get('direction') - interface = cleaned_data.get('interface') - vminterface = cleaned_data.get('vminterface') - assigned_object = cleaned_data.get('assigned_object') + access_list = cleaned_data.get("access_list") + direction = cleaned_data.get("direction") + interface = cleaned_data.get("interface") + vminterface = cleaned_data.get("vminterface") + assigned_object = cleaned_data.get("assigned_object") if interface: assigned_object = interface - assigned_object_type = 'interface' - host_type = 'device' + assigned_object_type = "interface" + host_type = "device" host = Interface.objects.get(pk=assigned_object.pk).device elif vminterface: assigned_object = vminterface - assigned_object_type = 'vminterface' - host_type = 'virtual_machine' + assigned_object_type = "vminterface" + host_type = "virtual_machine" host = VMInterface.objects.get(pk=assigned_object.pk).virtual_machine if interface or vminterface: assigned_object_id = VMInterface.objects.get(pk=assigned_object.pk).pk - assigned_object_type_id = ContentType.objects.get_for_model(assigned_object).pk + assigned_object_type_id = ContentType.objects.get_for_model( + assigned_object + ).pk access_list_host = AccessList.objects.get(pk=access_list.pk).assigned_object # Check if both interface and vminterface are set. if interface and vminterface: - error_too_many_interfaces = 'Access Lists must be assigned to one type of interface at a time (VM interface or physical interface)' - error_too_many_hosts = 'Access Lists must be assigned to one type of device at a time (VM or physical device).' - error_message |= {'device': [error_too_many_hosts], 'interface': [error_too_many_interfaces], 'virtual_machine': [error_too_many_hosts], 'vminterface': [error_too_many_interfaces]} + error_too_many_interfaces = "Access Lists must be assigned to one type of interface at a time (VM interface or physical interface)" + error_too_many_hosts = "Access Lists must be assigned to one type of device at a time (VM or physical device)." + error_message |= { + "device": [error_too_many_hosts], + "interface": [error_too_many_interfaces], + "virtual_machine": [error_too_many_hosts], + "vminterface": [error_too_many_interfaces], + } # Check if neither interface or vminterface are set. elif not (interface or vminterface): - error_no_interface = 'An Access List assignment but specify an Interface or VM Interface.' - error_message |= {'interface': [error_no_interface], 'vminterface': [error_no_interface]} + error_no_interface = ( + "An Access List assignment but specify an Interface or VM Interface." + ) + error_message |= { + "interface": [error_no_interface], + "vminterface": [error_no_interface], + } # Check that an interface's parent device/virtual_machine is assigned to the Access List. elif access_list_host != host: - error_acl_not_assigned_to_host = 'Access List not present on selected host.' - error_message |= {'access_list': [error_acl_not_assigned_to_host], assigned_object_type: [error_acl_not_assigned_to_host], host_type: [error_acl_not_assigned_to_host]} + error_acl_not_assigned_to_host = "Access List not present on selected host." + error_message |= { + "access_list": [error_acl_not_assigned_to_host], + assigned_object_type: [error_acl_not_assigned_to_host], + host_type: [error_acl_not_assigned_to_host], + } # Check for duplicate entry. - elif ACLInterfaceAssignment.objects.filter(access_list=access_list, assigned_object_id=assigned_object_id, assigned_object_type=assigned_object_type_id, direction=direction).exists(): - error_duplicate_entry = 'An ACL with this name is already associated to this interface & direction.' - error_message |= {'access_list': [error_duplicate_entry], 'direction': [error_duplicate_entry], assigned_object_type: [error_duplicate_entry]} + elif ACLInterfaceAssignment.objects.filter( + access_list=access_list, + assigned_object_id=assigned_object_id, + assigned_object_type=assigned_object_type_id, + direction=direction, + ).exists(): + error_duplicate_entry = "An ACL with this name is already associated to this interface & direction." + error_message |= { + "access_list": [error_duplicate_entry], + "direction": [error_duplicate_entry], + assigned_object_type: [error_duplicate_entry], + } # Check that the interface does not have an existing ACL applied in the direction already. - elif ACLInterfaceAssignment.objects.filter(assigned_object_id=assigned_object_id, assigned_object_type=assigned_object_type_id, direction=direction).exists(): - error_interface_already_assigned = 'Interfaces can only have 1 Access List assigned in each direction.' - error_message |= {'direction': [error_interface_already_assigned], assigned_object_type: [error_interface_already_assigned]} + elif ACLInterfaceAssignment.objects.filter( + assigned_object_id=assigned_object_id, + assigned_object_type=assigned_object_type_id, + direction=direction, + ).exists(): + error_interface_already_assigned = ( + "Interfaces can only have 1 Access List assigned in each direction." + ) + error_message |= { + "direction": [error_interface_already_assigned], + assigned_object_type: [error_interface_already_assigned], + } if error_message: raise forms.ValidationError(error_message) @@ -303,7 +402,9 @@ class ACLInterfaceAssignmentForm(NetBoxModelForm): def save(self, *args, **kwargs): # Set assigned object - self.instance.assigned_object = self.cleaned_data.get('interface') or self.cleaned_data.get('vminterface') + self.instance.assigned_object = self.cleaned_data.get( + "interface" + ) or self.cleaned_data.get("vminterface") return super().save(*args, **kwargs) @@ -314,40 +415,50 @@ class ACLStandardRuleForm(NetBoxModelForm): Requires an access_list, an index, and ACL rule type. See the clean function for logic on other field requirements. """ + access_list = DynamicModelChoiceField( queryset=AccessList.objects.all(), query_params={ - 'type': 'standard' + "type": "standard", }, - help_text=mark_safe('*Note: This field will only display Standard ACLs.'), - label='Access List', + help_text=mark_safe( + "*Note: This field will only display Standard ACLs." + ), + label="Access List", ) source_prefix = DynamicModelChoiceField( queryset=Prefix.objects.all(), required=False, help_text=help_text_acl_rule_logic, - label='Source Prefix', + label="Source Prefix", ) tags = DynamicModelMultipleChoiceField( queryset=Tag.objects.all(), - required=False + required=False, ) fieldsets = ( - ('Access List Details', ('access_list', 'description', 'tags')), - ('Rule Definition', ('index', 'action', 'remark', 'source_prefix')), + ("Access List Details", ("access_list", "description", "tags")), + ("Rule Definition", ("index", "action", "remark", "source_prefix")), ) class Meta: model = ACLStandardRule fields = ( - 'access_list', 'index', 'action', 'remark', 'source_prefix', - 'tags', 'description' + "access_list", + "index", + "action", + "remark", + "source_prefix", + "tags", + "description", ) help_texts = { - 'index': help_text_acl_rule_index, - 'action': help_text_acl_action, - 'remark': mark_safe('*Note: CANNOT be set if source prefix OR action is set.'), + "index": help_text_acl_rule_index, + "action": help_text_acl_action, + "remark": mark_safe( + "*Note: CANNOT be set if source prefix OR action is set." + ), } def clean(self): @@ -362,16 +473,18 @@ class ACLStandardRuleForm(NetBoxModelForm): # No need to check for unique_together since there is no usage of GFK - if cleaned_data.get('action') == 'remark': + if cleaned_data.get("action") == "remark": # Check if action set to remark, but no remark set. - if not cleaned_data.get('remark'): - error_message['remark'] = [error_message_no_remark] + if not cleaned_data.get("remark"): + error_message["remark"] = [error_message_no_remark] # Check if action set to remark, but source_prefix set. - if cleaned_data.get('source_prefix'): - error_message['source_prefix'] = [error_message_action_remark_source_prefix_set] + if cleaned_data.get("source_prefix"): + error_message["source_prefix"] = [ + error_message_action_remark_source_prefix_set + ] # Check remark set, but action not set to remark. - elif cleaned_data.get('remark'): - error_message['remark'] = [error_message_remark_without_action_remark] + elif cleaned_data.get("remark"): + error_message["remark"] = [error_message_remark_without_action_remark] if error_message: raise forms.ValidationError(error_message) @@ -384,49 +497,74 @@ class ACLExtendedRuleForm(NetBoxModelForm): Requires an access_list, an index, and ACL rule type. See the clean function for logic on other field requirements. """ + access_list = DynamicModelChoiceField( queryset=AccessList.objects.all(), query_params={ - 'type': 'extended' + "type": "extended", }, - help_text=mark_safe('*Note: This field will only display Extended ACLs.'), - label='Access List', + help_text=mark_safe( + "*Note: This field will only display Extended ACLs." + ), + label="Access List", ) tags = DynamicModelMultipleChoiceField( queryset=Tag.objects.all(), - required=False + required=False, ) source_prefix = DynamicModelChoiceField( queryset=Prefix.objects.all(), required=False, help_text=help_text_acl_rule_logic, - label='Source Prefix', + label="Source Prefix", ) destination_prefix = DynamicModelChoiceField( queryset=Prefix.objects.all(), required=False, help_text=help_text_acl_rule_logic, - label='Destination Prefix', + label="Destination Prefix", ) fieldsets = ( - ('Access List Details', ('access_list', 'description', 'tags')), - ('Rule Definition', ('index', 'action', 'remark', 'source_prefix', 'source_ports', 'destination_prefix', 'destination_ports', 'protocol',)), + ("Access List Details", ("access_list", "description", "tags")), + ( + "Rule Definition", + ( + "index", + "action", + "remark", + "source_prefix", + "source_ports", + "destination_prefix", + "destination_ports", + "protocol", + ), + ), ) class Meta: model = ACLExtendedRule fields = ( - 'access_list', 'index', 'action', 'remark', 'source_prefix', - 'source_ports', 'destination_prefix', 'destination_ports', 'protocol', - 'tags', 'description' + "access_list", + "index", + "action", + "remark", + "source_prefix", + "source_ports", + "destination_prefix", + "destination_ports", + "protocol", + "tags", + "description", ) help_texts = { - 'action': help_text_acl_action, - 'destination_ports': help_text_acl_rule_logic, - 'index': help_text_acl_rule_index, - 'protocol': help_text_acl_rule_logic, - 'remark': mark_safe('*Note: CANNOT be set if action is not set to remark.'), - 'source_ports': help_text_acl_rule_logic, + "action": help_text_acl_action, + "destination_ports": help_text_acl_rule_logic, + "index": help_text_acl_rule_index, + "protocol": help_text_acl_rule_logic, + "remark": mark_safe( + "*Note: CANNOT be set if action is not set to remark." + ), + "source_ports": help_text_acl_rule_logic, } def clean(self): @@ -446,28 +584,38 @@ class ACLExtendedRuleForm(NetBoxModelForm): # No need to check for unique_together since there is no usage of GFK - if cleaned_data.get('action') == 'remark': + if cleaned_data.get("action") == "remark": # Check if action set to remark, but no remark set. - if not cleaned_data.get('remark'): - error_message['remark'] = [error_message_no_remark] + if not cleaned_data.get("remark"): + error_message["remark"] = [error_message_no_remark] # Check if action set to remark, but source_prefix set. - if cleaned_data.get('source_prefix'): - error_message['source_prefix'] = [error_message_action_remark_source_prefix_set] + if cleaned_data.get("source_prefix"): + error_message["source_prefix"] = [ + error_message_action_remark_source_prefix_set + ] # Check if action set to remark, but source_ports set. - if cleaned_data.get('source_ports'): - error_message['source_ports'] = ['Action is set to remark, Source Ports CANNOT be set.'] + if cleaned_data.get("source_ports"): + error_message["source_ports"] = [ + "Action is set to remark, Source Ports CANNOT be set." + ] # Check if action set to remark, but destination_prefix set. - if cleaned_data.get('destination_prefix'): - error_message['destination_prefix'] = ['Action is set to remark, Destination Prefix CANNOT be set.'] + if cleaned_data.get("destination_prefix"): + error_message["destination_prefix"] = [ + "Action is set to remark, Destination Prefix CANNOT be set." + ] # Check if action set to remark, but destination_ports set. - if cleaned_data.get('destination_ports'): - error_message['destination_ports'] = ['Action is set to remark, Destination Ports CANNOT be set.'] + if cleaned_data.get("destination_ports"): + error_message["destination_ports"] = [ + "Action is set to remark, Destination Ports CANNOT be set." + ] # Check if action set to remark, but protocol set. - if cleaned_data.get('protocol'): - error_message['protocol'] = ['Action is set to remark, Protocol CANNOT be set.'] + if cleaned_data.get("protocol"): + error_message["protocol"] = [ + "Action is set to remark, Protocol CANNOT be set." + ] # Check if action not set to remark, but remark set. - elif cleaned_data.get('remark'): - error_message['remark'] = [error_message_remark_without_action_remark] + elif cleaned_data.get("remark"): + error_message["remark"] = [error_message_remark_without_action_remark] if error_message: raise forms.ValidationError(error_message) diff --git a/netbox_access_lists/graphql.py b/netbox_access_lists/graphql.py index e1eac6d..8de0dd2 100644 --- a/netbox_access_lists/graphql.py +++ b/netbox_access_lists/graphql.py @@ -9,10 +9,10 @@ from netbox.graphql.types import NetBoxObjectType from . import filtersets, models __all__ = ( - 'AccessListType', - 'ACLInterfaceAssignmentType', - 'ACLExtendedRuleType', - 'ACLStandardRuleType', + "AccessListType", + "ACLInterfaceAssignmentType", + "ACLExtendedRuleType", + "ACLStandardRuleType", ) # @@ -29,8 +29,9 @@ class AccessListType(NetBoxObjectType): """ Associates the filterset, fields, and model for the django model AccessList. """ + model = models.AccessList - fields = '__all__' + fields = "__all__" filterset_class = filtersets.AccessListFilterSet @@ -43,8 +44,9 @@ class ACLInterfaceAssignmentType(NetBoxObjectType): """ Associates the filterset, fields, and model for the django model ACLInterfaceAssignment. """ + model = models.ACLInterfaceAssignment - fields = '__all__' + fields = "__all__" filterset_class = filtersets.ACLInterfaceAssignmentFilterSet @@ -57,8 +59,9 @@ class ACLExtendedRuleType(NetBoxObjectType): """ Associates the filterset, fields, and model for the django model ACLExtendedRule. """ + model = models.ACLExtendedRule - fields = '__all__' + fields = "__all__" filterset_class = filtersets.ACLExtendedRuleFilterSet @@ -71,10 +74,12 @@ class ACLStandardRuleType(NetBoxObjectType): """ Associates the filterset, fields, and model for the django model ACLStandardRule. """ + model = models.ACLStandardRule - fields = '__all__' + fields = "__all__" filterset_class = filtersets.ACLStandardRuleFilterSet + # # Queries # @@ -94,4 +99,5 @@ class Query(ObjectType): acl_standard_rule = ObjectField(ACLStandardRuleType) acl_standard_rule_list = ObjectListField(ACLStandardRuleType) + schema = Query diff --git a/netbox_access_lists/migrations/0001_initial.py b/netbox_access_lists/migrations/0001_initial.py index 60e10ac..74d93de 100644 --- a/netbox_access_lists/migrations/0001_initial.py +++ b/netbox_access_lists/migrations/0001_initial.py @@ -8,9 +8,8 @@ import django.db.models.deletion import taggit.managers from django.db import migrations, models -__all__ = ( - 'Migration', -) +__all__ = ("Migration",) + class Migration(migrations.Migration): """ @@ -20,100 +19,258 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('extras', '0072_created_datetimefield'), - ('ipam', '0057_created_datetimefield'), + ("extras", "0072_created_datetimefield"), + ("ipam", "0057_created_datetimefield"), ] operations = [ migrations.CreateModel( - name='AccessList', + name="AccessList", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)), - ('name', models.CharField(max_length=500)), - ('assigned_object_id', models.PositiveIntegerField()), - ('assigned_object_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='contenttypes.contenttype')), - ('type', models.CharField(max_length=100)), - ('default_action', models.CharField(default='deny', max_length=30)), - ('comments', models.TextField(blank=True)), - ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False + ), + ), + ("created", models.DateTimeField(auto_now_add=True, null=True)), + ("last_updated", models.DateTimeField(auto_now=True, null=True)), + ( + "custom_field_data", + models.JSONField( + blank=True, + default=dict, + encoder=django.core.serializers.json.DjangoJSONEncoder, + ), + ), + ("name", models.CharField(max_length=500)), + ("assigned_object_id", models.PositiveIntegerField()), + ( + "assigned_object_type", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="contenttypes.contenttype", + ), + ), + ("type", models.CharField(max_length=100)), + ("default_action", models.CharField(default="deny", max_length=30)), + ("comments", models.TextField(blank=True)), + ( + "tags", + taggit.managers.TaggableManager( + through="extras.TaggedItem", to="extras.Tag" + ), + ), ], options={ - 'ordering': ('name', 'device'), - 'unique_together': {('assigned_object_type', 'assigned_object_id', 'name')}, - 'verbose_name': 'Access List', + "ordering": ("name", "device"), + "unique_together": { + ("assigned_object_type", "assigned_object_id", "name") + }, + "verbose_name": "Access List", }, ), migrations.CreateModel( - name='ACLInterfaceAssignment', + name="ACLInterfaceAssignment", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)), - ('access_list', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='aclinterfaceassignment', to='netbox_access_lists.accesslist')), - ('direction', models.CharField(max_length=100)), - ('assigned_object_id', models.PositiveIntegerField()), - ('assigned_object_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='contenttypes.contenttype')), - ('comments', models.TextField(blank=True)), - ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False + ), + ), + ("created", models.DateTimeField(auto_now_add=True, null=True)), + ("last_updated", models.DateTimeField(auto_now=True, null=True)), + ( + "custom_field_data", + models.JSONField( + blank=True, + default=dict, + encoder=django.core.serializers.json.DjangoJSONEncoder, + ), + ), + ( + "access_list", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="aclinterfaceassignment", + to="netbox_access_lists.accesslist", + ), + ), + ("direction", models.CharField(max_length=100)), + ("assigned_object_id", models.PositiveIntegerField()), + ( + "assigned_object_type", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="contenttypes.contenttype", + ), + ), + ("comments", models.TextField(blank=True)), + ( + "tags", + taggit.managers.TaggableManager( + through="extras.TaggedItem", to="extras.Tag" + ), + ), ], options={ - 'ordering': ('access_list', 'assigned_object_type', 'assigned_object_id', 'direction'), - 'unique_together': {('assigned_object_type', 'assigned_object_id', 'access_list', 'direction')}, - 'verbose_name': 'ACL Interface Assignment', + "ordering": ( + "access_list", + "assigned_object_type", + "assigned_object_id", + "direction", + ), + "unique_together": { + ( + "assigned_object_type", + "assigned_object_id", + "access_list", + "direction", + ) + }, + "verbose_name": "ACL Interface Assignment", }, ), migrations.CreateModel( - name='ACLStandardRule', + name="ACLStandardRule", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)), - ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), - ('access_list', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='aclstandardrules', to='netbox_access_lists.accesslist')), - ('index', models.PositiveIntegerField()), - ('description', models.CharField(blank=True, max_length=500)), - ('action', models.CharField(max_length=30)), - ('remark', models.CharField(blank=True, null=True, max_length=500)), - ('source_prefix', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='ipam.prefix')), + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False + ), + ), + ("created", models.DateTimeField(auto_now_add=True, null=True)), + ("last_updated", models.DateTimeField(auto_now=True, null=True)), + ( + "custom_field_data", + models.JSONField( + blank=True, + default=dict, + encoder=django.core.serializers.json.DjangoJSONEncoder, + ), + ), + ( + "tags", + taggit.managers.TaggableManager( + through="extras.TaggedItem", to="extras.Tag" + ), + ), + ( + "access_list", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="aclstandardrules", + to="netbox_access_lists.accesslist", + ), + ), + ("index", models.PositiveIntegerField()), + ("description", models.CharField(blank=True, max_length=500)), + ("action", models.CharField(max_length=30)), + ("remark", models.CharField(blank=True, null=True, max_length=500)), + ( + "source_prefix", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="+", + to="ipam.prefix", + ), + ), ], options={ - 'ordering': ('access_list', 'index'), - 'unique_together': {('access_list', 'index')}, - 'verbose_name': 'ACL Standard Rule', + "ordering": ("access_list", "index"), + "unique_together": {("access_list", "index")}, + "verbose_name": "ACL Standard Rule", }, ), migrations.CreateModel( - name='ACLExtendedRule', + name="ACLExtendedRule", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True, null=True)), - ('last_updated', models.DateTimeField(auto_now=True, null=True)), - ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)), - ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), - ('access_list', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='aclstandardrules', to='netbox_access_lists.accesslist')), - ('index', models.PositiveIntegerField()), - ('description', models.CharField(blank=True, max_length=500)), - ('action', models.CharField(max_length=30)), - ('remark', models.CharField(blank=True, null=True, max_length=500)), - ('source_prefix', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='ipam.prefix')), - ('source_ports', django.contrib.postgres.fields.ArrayField(base_field=models.PositiveIntegerField(), blank=True, null=True, size=None)), - ('destination_prefix', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='ipam.prefix')), - ('destination_ports', django.contrib.postgres.fields.ArrayField(base_field=models.PositiveIntegerField(), blank=True, null=True, size=None)), - ('protocol', models.CharField(blank=True, max_length=30)), + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False + ), + ), + ("created", models.DateTimeField(auto_now_add=True, null=True)), + ("last_updated", models.DateTimeField(auto_now=True, null=True)), + ( + "custom_field_data", + models.JSONField( + blank=True, + default=dict, + encoder=django.core.serializers.json.DjangoJSONEncoder, + ), + ), + ( + "tags", + taggit.managers.TaggableManager( + through="extras.TaggedItem", to="extras.Tag" + ), + ), + ( + "access_list", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="aclstandardrules", + to="netbox_access_lists.accesslist", + ), + ), + ("index", models.PositiveIntegerField()), + ("description", models.CharField(blank=True, max_length=500)), + ("action", models.CharField(max_length=30)), + ("remark", models.CharField(blank=True, null=True, max_length=500)), + ( + "source_prefix", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="+", + to="ipam.prefix", + ), + ), + ( + "source_ports", + django.contrib.postgres.fields.ArrayField( + base_field=models.PositiveIntegerField(), + blank=True, + null=True, + size=None, + ), + ), + ( + "destination_prefix", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="+", + to="ipam.prefix", + ), + ), + ( + "destination_ports", + django.contrib.postgres.fields.ArrayField( + base_field=models.PositiveIntegerField(), + blank=True, + null=True, + size=None, + ), + ), + ("protocol", models.CharField(blank=True, max_length=30)), ], options={ - 'ordering': ('access_list', 'index'), - 'unique_together': {('access_list', 'index')}, - 'verbose_name': 'ACL Extended Rule', + "ordering": ("access_list", "index"), + "unique_together": {("access_list", "index")}, + "verbose_name": "ACL Extended Rule", }, ), - #migrations.AddConstraint( + # migrations.AddConstraint( # model_name='accesslist', # constraint=models.UniqueConstraint(fields=('assigned_object_type', 'assigned_object_id'), name='accesslist_assigned_object'), - #), + # ), ] diff --git a/netbox_access_lists/models/access_list_rules.py b/netbox_access_lists/models/access_list_rules.py index 7ac017d..cf530d9 100644 --- a/netbox_access_lists/models/access_list_rules.py +++ b/netbox_access_lists/models/access_list_rules.py @@ -11,9 +11,9 @@ from ..choices import * from .access_lists import AccessList __all__ = ( - 'ACLRule', - 'ACLStandardRule', - 'ACLExtendedRule', + "ACLRule", + "ACLStandardRule", + "ACLExtendedRule", ) @@ -22,20 +22,21 @@ class ACLRule(NetBoxModel): Abstract model for ACL Rules. Inherrited by both ACLStandardRule and ACLExtendedRule. """ + access_list = models.ForeignKey( on_delete=models.CASCADE, to=AccessList, - verbose_name='Access List', - related_name='rules', + verbose_name="Access List", + related_name="rules", ) index = models.PositiveIntegerField() remark = models.CharField( max_length=500, - blank=True + blank=True, ) description = models.CharField( max_length=500, - blank=True + blank=True, ) action = models.CharField( choices=ACLRuleActionChoices, @@ -45,13 +46,13 @@ class ACLRule(NetBoxModel): blank=True, null=True, on_delete=models.PROTECT, - related_name='+', - to='ipam.Prefix', - verbose_name='Source Prefix' + related_name="+", + to="ipam.Prefix", + verbose_name="Source Prefix", ) def __str__(self): - return f'{self.access_list}: Rule {self.index}' + return f"{self.access_list}: Rule {self.index}" def get_action_color(self): return ACLRuleActionChoices.colors.get(self.action) @@ -63,21 +64,23 @@ class ACLRule(NetBoxModel): - ordering - unique together """ + abstract = True - ordering = ['access_list', 'index'] - unique_together = ['access_list', 'index'] + ordering = ["access_list", "index"] + unique_together = ["access_list", "index"] class ACLStandardRule(ACLRule): """ Inherits ACLRule. """ + access_list = models.ForeignKey( on_delete=models.CASCADE, to=AccessList, - verbose_name='Standard Access List', - limit_choices_to={'type': 'standard'}, - related_name='aclstandardrules', + verbose_name="Standard Access List", + limit_choices_to={"type": "standard"}, + related_name="aclstandardrules", ) def get_absolute_url(self): @@ -85,7 +88,7 @@ class ACLStandardRule(ACLRule): The method is a Django convention; although not strictly required, it conveniently returns the absolute URL for any particular object. """ - return reverse('plugins:netbox_access_lists:aclstandardrule', args=[self.pk]) + return reverse("plugins:netbox_access_lists:aclstandardrule", args=[self.pk]) class Meta(ACLRule.Meta): """ @@ -94,40 +97,43 @@ class ACLStandardRule(ACLRule): - verbose name (for displaying in the GUI) - verbose name plural (for displaying in the GUI) """ - verbose_name='ACL Standard Rule' - verbose_name_plural='ACL Standard Rules' + + verbose_name = "ACL Standard Rule" + verbose_name_plural = "ACL Standard Rules" + class ACLExtendedRule(ACLRule): """ Inherits ACLRule. Add ACLExtendedRule specific fields: source_ports, desintation_prefix, destination_ports, and protocol """ + access_list = models.ForeignKey( on_delete=models.CASCADE, to=AccessList, - verbose_name='Extended Access List', - limit_choices_to={'type': 'extended'}, - related_name='aclextendedrules', + verbose_name="Extended Access List", + limit_choices_to={"type": "extended"}, + related_name="aclextendedrules", ) source_ports = ArrayField( base_field=models.PositiveIntegerField(), blank=True, null=True, - verbose_name='Soure Ports' + verbose_name="Soure Ports", ) destination_prefix = models.ForeignKey( blank=True, null=True, on_delete=models.PROTECT, - related_name='+', - to='ipam.Prefix', - verbose_name='Destination Prefix' + related_name="+", + to="ipam.Prefix", + verbose_name="Destination Prefix", ) destination_ports = ArrayField( base_field=models.PositiveIntegerField(), blank=True, null=True, - verbose_name='Destination Ports' + verbose_name="Destination Ports", ) protocol = models.CharField( blank=True, @@ -140,7 +146,7 @@ class ACLExtendedRule(ACLRule): The method is a Django convention; although not strictly required, it conveniently returns the absolute URL for any particular object. """ - return reverse('plugins:netbox_access_lists:aclextendedrule', args=[self.pk]) + return reverse("plugins:netbox_access_lists:aclextendedrule", args=[self.pk]) def get_protocol_color(self): return ACLProtocolChoices.colors.get(self.protocol) @@ -152,5 +158,6 @@ class ACLExtendedRule(ACLRule): - verbose name (for displaying in the GUI) - verbose name plural (for displaying in the GUI) """ - verbose_name='ACL Extended Rule' - verbose_name_plural='ACL Extended Rules' + + verbose_name = "ACL Extended Rule" + verbose_name_plural = "ACL Extended Rules" diff --git a/netbox_access_lists/models/access_lists.py b/netbox_access_lists/models/access_lists.py index f0486e3..a20f428 100644 --- a/netbox_access_lists/models/access_lists.py +++ b/netbox_access_lists/models/access_lists.py @@ -3,8 +3,7 @@ Define the django models for this plugin. """ from dcim.models import Device, Interface, VirtualChassis -from django.contrib.contenttypes.fields import (GenericForeignKey, - GenericRelation) +from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation from django.contrib.contenttypes.models import ContentType from django.core.validators import RegexValidator from django.db import models @@ -13,54 +12,58 @@ from netbox.models import NetBoxModel from virtualization.models import VirtualMachine, VMInterface from ..choices import * -from ..constants import (ACL_HOST_ASSIGNMENT_MODELS, - ACL_INTERFACE_ASSIGNMENT_MODELS) +from ..constants import ACL_HOST_ASSIGNMENT_MODELS, ACL_INTERFACE_ASSIGNMENT_MODELS __all__ = ( - 'AccessList', - 'ACLInterfaceAssignment', + "AccessList", + "ACLInterfaceAssignment", ) -alphanumeric_plus = RegexValidator(r'^[0-9a-zA-Z,-,_]*$', 'Only alphanumeric, hyphens, and underscores characters are allowed.') +alphanumeric_plus = RegexValidator( + r"^[0-9a-zA-Z,-,_]*$", + "Only alphanumeric, hyphens, and underscores characters are allowed.", +) + class AccessList(NetBoxModel): """ Model defintion for Access Lists. """ + name = models.CharField( max_length=500, - validators=[alphanumeric_plus] + validators=[alphanumeric_plus], ) assigned_object_type = models.ForeignKey( to=ContentType, limit_choices_to=ACL_HOST_ASSIGNMENT_MODELS, - on_delete=models.PROTECT + on_delete=models.PROTECT, ) assigned_object_id = models.PositiveBigIntegerField() assigned_object = GenericForeignKey( - ct_field='assigned_object_type', - fk_field='assigned_object_id' + ct_field="assigned_object_type", + fk_field="assigned_object_id", ) type = models.CharField( max_length=30, - choices=ACLTypeChoices + choices=ACLTypeChoices, ) default_action = models.CharField( default=ACLActionChoices.ACTION_DENY, max_length=30, choices=ACLActionChoices, - verbose_name='Default Action' + verbose_name="Default Action", ) comments = models.TextField( - blank=True + blank=True, ) class Meta: - unique_together = ['assigned_object_type', 'assigned_object_id', 'name'] - ordering = ['assigned_object_type', 'assigned_object_id', 'name'] - verbose_name = 'Access List' - verbose_name_plural = 'Access Lists' + unique_together = ["assigned_object_type", "assigned_object_id", "name"] + ordering = ["assigned_object_type", "assigned_object_id", "name"] + verbose_name = "Access List" + verbose_name_plural = "Access Lists" def __str__(self): return self.name @@ -70,7 +73,7 @@ class AccessList(NetBoxModel): The method is a Django convention; although not strictly required, it conveniently returns the absolute URL for any particular object. """ - return reverse('plugins:netbox_access_lists:accesslist', args=[self.pk]) + return reverse("plugins:netbox_access_lists:accesslist", args=[self.pk]) def get_default_action_color(self): return ACLActionChoices.colors.get(self.default_action) @@ -90,38 +93,50 @@ class ACLInterfaceAssignment(NetBoxModel): access_list = models.ForeignKey( on_delete=models.CASCADE, to=AccessList, - verbose_name='Access List', + verbose_name="Access List", ) direction = models.CharField( max_length=30, - choices=ACLAssignmentDirectionChoices + choices=ACLAssignmentDirectionChoices, ) assigned_object_type = models.ForeignKey( to=ContentType, limit_choices_to=ACL_INTERFACE_ASSIGNMENT_MODELS, - on_delete=models.PROTECT + on_delete=models.PROTECT, ) assigned_object_id = models.PositiveBigIntegerField() assigned_object = GenericForeignKey( - ct_field='assigned_object_type', - fk_field='assigned_object_id' + ct_field="assigned_object_type", + fk_field="assigned_object_id", ) comments = models.TextField( - blank=True + blank=True, ) class Meta: - unique_together = ['assigned_object_type', 'assigned_object_id', 'access_list', 'direction'] - ordering = ['assigned_object_type', 'assigned_object_id', 'access_list', 'direction'] - verbose_name = 'ACL Interface Assignment' - verbose_name_plural = 'ACL Interface Assignments' + unique_together = [ + "assigned_object_type", + "assigned_object_id", + "access_list", + "direction", + ] + ordering = [ + "assigned_object_type", + "assigned_object_id", + "access_list", + "direction", + ] + verbose_name = "ACL Interface Assignment" + verbose_name_plural = "ACL Interface Assignments" def get_absolute_url(self): """ The method is a Django convention; although not strictly required, it conveniently returns the absolute URL for any particular object. """ - return reverse('plugins:netbox_access_lists:aclinterfaceassignment', args=[self.pk]) + return reverse( + "plugins:netbox_access_lists:aclinterfaceassignment", args=[self.pk] + ) def get_direction_color(self): return ACLAssignmentDirectionChoices.colors.get(self.direction) @@ -129,35 +144,35 @@ class ACLInterfaceAssignment(NetBoxModel): GenericRelation( to=ACLInterfaceAssignment, - content_type_field='assigned_object_type', - object_id_field='assigned_object_id', - related_query_name='interface' -).contribute_to_class(Interface, 'accesslistassignments') + content_type_field="assigned_object_type", + object_id_field="assigned_object_id", + related_query_name="interface", +).contribute_to_class(Interface, "accesslistassignments") GenericRelation( to=ACLInterfaceAssignment, - content_type_field='assigned_object_type', - object_id_field='assigned_object_id', - related_query_name='vminterface' -).contribute_to_class(VMInterface, 'accesslistassignments') + content_type_field="assigned_object_type", + object_id_field="assigned_object_id", + related_query_name="vminterface", +).contribute_to_class(VMInterface, "accesslistassignments") GenericRelation( to=AccessList, - content_type_field='assigned_object_type', - object_id_field='assigned_object_id', - related_query_name='device' -).contribute_to_class(Device, 'accesslists') + content_type_field="assigned_object_type", + object_id_field="assigned_object_id", + related_query_name="device", +).contribute_to_class(Device, "accesslists") GenericRelation( to=AccessList, - content_type_field='assigned_object_type', - object_id_field='assigned_object_id', - related_query_name='virtual_chassis' -).contribute_to_class(VirtualChassis, 'accesslists') + content_type_field="assigned_object_type", + object_id_field="assigned_object_id", + related_query_name="virtual_chassis", +).contribute_to_class(VirtualChassis, "accesslists") GenericRelation( to=AccessList, - content_type_field='assigned_object_type', - object_id_field='assigned_object_id', - related_query_name='virtual_machine' -).contribute_to_class(VirtualMachine, 'accesslists') + content_type_field="assigned_object_type", + object_id_field="assigned_object_id", + related_query_name="virtual_machine", +).contribute_to_class(VirtualMachine, "accesslists") diff --git a/netbox_access_lists/navigation.py b/netbox_access_lists/navigation.py index 2131f4e..7680c17 100644 --- a/netbox_access_lists/navigation.py +++ b/netbox_access_lists/navigation.py @@ -11,38 +11,38 @@ from utilities.choices import ButtonColorChoices accesslist_buttons = [ PluginMenuButton( - link='plugins:netbox_access_lists:accesslist_add', - title='Add', - icon_class='mdi mdi-plus-thick', - color=ButtonColorChoices.GREEN - ) + link="plugins:netbox_access_lists:accesslist_add", + title="Add", + icon_class="mdi mdi-plus-thick", + color=ButtonColorChoices.GREEN, + ), ] aclstandardrule_butons = [ PluginMenuButton( - link='plugins:netbox_access_lists:aclstandardrule_add', - title='Add', - icon_class='mdi mdi-plus-thick', - color=ButtonColorChoices.GREEN - ) + link="plugins:netbox_access_lists:aclstandardrule_add", + title="Add", + icon_class="mdi mdi-plus-thick", + color=ButtonColorChoices.GREEN, + ), ] aclextendedrule_butons = [ PluginMenuButton( - link='plugins:netbox_access_lists:aclextendedrule_add', - title='Add', - icon_class='mdi mdi-plus-thick', - color=ButtonColorChoices.GREEN - ) + link="plugins:netbox_access_lists:aclextendedrule_add", + title="Add", + icon_class="mdi mdi-plus-thick", + color=ButtonColorChoices.GREEN, + ), ] accesslistassignment_buttons = [ PluginMenuButton( - link='plugins:netbox_access_lists:aclinterfaceassignment_add', - title='Add', - icon_class='mdi mdi-plus-thick', - color=ButtonColorChoices.GREEN - ) + link="plugins:netbox_access_lists:aclinterfaceassignment_add", + title="Add", + icon_class="mdi mdi-plus-thick", + color=ButtonColorChoices.GREEN, + ), ] # @@ -51,25 +51,25 @@ accesslistassignment_buttons = [ menu_items = ( PluginMenuItem( - link='plugins:netbox_access_lists:accesslist_list', - link_text='Access Lists', - buttons=accesslist_buttons + link="plugins:netbox_access_lists:accesslist_list", + link_text="Access Lists", + buttons=accesslist_buttons, ), # Comment out Standard Access List rule to force creation in the ACL view PluginMenuItem( - link='plugins:netbox_access_lists:aclstandardrule_list', - link_text='ACL Standard Rules', - buttons=aclstandardrule_butons + link="plugins:netbox_access_lists:aclstandardrule_list", + link_text="ACL Standard Rules", + buttons=aclstandardrule_butons, ), # Comment out Extended Access List rule to force creation in the ACL view PluginMenuItem( - link='plugins:netbox_access_lists:aclextendedrule_list', - link_text='ACL Extended Rules', - buttons=aclextendedrule_butons + link="plugins:netbox_access_lists:aclextendedrule_list", + link_text="ACL Extended Rules", + buttons=aclextendedrule_butons, ), PluginMenuItem( - link='plugins:netbox_access_lists:aclinterfaceassignment_list', - link_text='ACL Interface Assignments', - buttons=accesslistassignment_buttons + link="plugins:netbox_access_lists:aclinterfaceassignment_list", + link_text="ACL Interface Assignments", + buttons=accesslistassignment_buttons, ), ) diff --git a/netbox_access_lists/tables.py b/netbox_access_lists/tables.py index b23f4dc..74ecb26 100644 --- a/netbox_access_lists/tables.py +++ b/netbox_access_lists/tables.py @@ -3,17 +3,15 @@ Define the object lists / table view for each of the plugin models. """ import django_tables2 as tables -from netbox.tables import (ChoiceFieldColumn, NetBoxTable, TemplateColumn, - columns) +from netbox.tables import ChoiceFieldColumn, NetBoxTable, TemplateColumn, columns -from .models import (AccessList, ACLExtendedRule, ACLInterfaceAssignment, - ACLStandardRule) +from .models import AccessList, ACLExtendedRule, ACLInterfaceAssignment, ACLStandardRule __all__ = ( - 'AccessListTable', - 'ACLInterfaceAssignmentTable', - 'ACLStandardRuleTable', - 'ACLExtendedRuleTable', + "AccessListTable", + "ACLInterfaceAssignmentTable", + "ACLStandardRuleTable", + "ACLExtendedRuleTable", ) @@ -25,93 +23,144 @@ COL_HOST_ASSIGNMENT = """ {% endif %} """ + class AccessListTable(NetBoxTable): """ Defines the table view for the AccessList model. """ + pk = columns.ToggleColumn() id = tables.Column( - linkify=True + linkify=True, ) assigned_object = tables.Column( linkify=True, orderable=False, - verbose_name='Assigned Host' + verbose_name="Assigned Host", ) name = tables.Column( - linkify=True + linkify=True, ) device = tables.Column( - linkify=True + linkify=True, ) type = ChoiceFieldColumn() default_action = ChoiceFieldColumn() rule_count = tables.Column( - verbose_name='Rule Count' + verbose_name="Rule Count", ) tags = columns.TagColumn( - url_name='plugins:netbox_access_lists:accesslist_list' + url_name="plugins:netbox_access_lists:accesslist_list", ) class Meta(NetBoxTable.Meta): model = AccessList - fields = ('pk', 'id', 'name', 'assigned_object', 'type', 'rule_count', 'default_action', 'comments', 'actions', 'tags') - default_columns = ('name', 'assigned_object', 'type', 'rule_count', 'default_action', 'tags') + fields = ( + "pk", + "id", + "name", + "assigned_object", + "type", + "rule_count", + "default_action", + "comments", + "actions", + "tags", + ) + default_columns = ( + "name", + "assigned_object", + "type", + "rule_count", + "default_action", + "tags", + ) class ACLInterfaceAssignmentTable(NetBoxTable): """ Defines the table view for the AccessList model. """ + pk = columns.ToggleColumn() id = tables.Column( - linkify=True + linkify=True, ) access_list = tables.Column( - linkify=True + linkify=True, ) direction = ChoiceFieldColumn() host = tables.TemplateColumn( - template_code=COL_HOST_ASSIGNMENT - + template_code=COL_HOST_ASSIGNMENT, ) assigned_object = tables.Column( linkify=True, orderable=False, - verbose_name='Assigned Interface' + verbose_name="Assigned Interface", ) tags = columns.TagColumn( - url_name='plugins:netbox_access_lists:aclinterfaceassignment_list' + url_name="plugins:netbox_access_lists:aclinterfaceassignment_list", ) class Meta(NetBoxTable.Meta): model = ACLInterfaceAssignment - fields = ('pk', 'id', 'access_list', 'direction', 'host', 'assigned_object', 'tags') - default_columns = ('id', 'access_list', 'direction', 'host', 'assigned_object', 'tags') + fields = ( + "pk", + "id", + "access_list", + "direction", + "host", + "assigned_object", + "tags", + ) + default_columns = ( + "id", + "access_list", + "direction", + "host", + "assigned_object", + "tags", + ) class ACLStandardRuleTable(NetBoxTable): """ Defines the table view for the ACLStandardRule model. """ + access_list = tables.Column( - linkify=True + linkify=True, ) index = tables.Column( - linkify=True + linkify=True, ) action = ChoiceFieldColumn() tags = columns.TagColumn( - url_name='plugins:netbox_access_lists:aclstandardrule_list' + url_name="plugins:netbox_access_lists:aclstandardrule_list", ) class Meta(NetBoxTable.Meta): model = ACLStandardRule fields = ( - 'pk', 'id', 'access_list', 'index', 'action', 'actions', 'remark', 'tags', 'description', 'source_prefix', + "pk", + "id", + "access_list", + "index", + "action", + "actions", + "remark", + "tags", + "description", + "source_prefix", ) default_columns = ( - 'access_list', 'index', 'action', 'actions', 'remark', 'source_prefix', 'tags' + "access_list", + "index", + "action", + "actions", + "remark", + "source_prefix", + "tags", ) @@ -119,25 +168,47 @@ class ACLExtendedRuleTable(NetBoxTable): """ Defines the table view for the ACLExtendedRule model. """ + access_list = tables.Column( - linkify=True + linkify=True, ) index = tables.Column( - linkify=True + linkify=True, ) action = ChoiceFieldColumn() tags = columns.TagColumn( - url_name='plugins:netbox_access_lists:aclextendedrule_list' + url_name="plugins:netbox_access_lists:aclextendedrule_list", ) protocol = ChoiceFieldColumn() class Meta(NetBoxTable.Meta): model = ACLExtendedRule fields = ( - 'pk', 'id', 'access_list', 'index', 'action', 'actions', 'remark', 'tags', 'description', - 'source_prefix', 'source_ports', 'destination_prefix', 'destination_ports', 'protocol' + "pk", + "id", + "access_list", + "index", + "action", + "actions", + "remark", + "tags", + "description", + "source_prefix", + "source_ports", + "destination_prefix", + "destination_ports", + "protocol", ) default_columns = ( - 'access_list', 'index', 'action', 'actions', 'remark', 'tags', - 'source_prefix', 'source_ports', 'destination_prefix', 'destination_ports', 'protocol' + "access_list", + "index", + "action", + "actions", + "remark", + "tags", + "source_prefix", + "source_ports", + "destination_prefix", + "destination_ports", + "protocol", ) diff --git a/netbox_access_lists/template_content.py b/netbox_access_lists/template_content.py index 0d1eeee..b5b10b6 100644 --- a/netbox_access_lists/template_content.py +++ b/netbox_access_lists/template_content.py @@ -1,70 +1,87 @@ - from django.contrib.contenttypes.models import ContentType from extras.plugins import PluginTemplateExtension from .models import AccessList, ACLInterfaceAssignment __all__ = ( - 'AccessLists', + "AccessLists", "ACLInterfaceAssignments", - 'DeviceAccessLists', - 'VirtualChassisAccessLists', - 'VMAccessLists', - 'DeviceACLInterfaceAssignments', - 'VMAACLInterfaceAssignments', + "DeviceAccessLists", + "VirtualChassisAccessLists", + "VMAccessLists", + "DeviceACLInterfaceAssignments", + "VMAACLInterfaceAssignments", ) class ACLInterfaceAssignments(PluginTemplateExtension): - def right_page(self): - obj = self.context['object'] + 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 in ["interface", "vminterface"]: + acl_interface_assignments = ACLInterfaceAssignment.objects.filter( + assigned_object_id=obj.pk, assigned_object_type=ctype + ) - return self.render('inc/assigned_interface/access_lists.html', extra_context={ - 'acl_interface_assignments': acl_interface_assignments, - 'type': ctype.model if ctype.model == 'device' else ctype.name.replace(' ', '_'), - }) + return self.render( + "inc/assigned_interface/access_lists.html", + extra_context={ + "acl_interface_assignments": acl_interface_assignments, + "type": ctype.model + if ctype.model == "device" + else ctype.name.replace(" ", "_"), + }, + ) class AccessLists(PluginTemplateExtension): - def right_page(self): - obj = self.context['object'] + 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) + 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(' ', '_'), - }) + 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' + model = "dcim.device" class VirtualChassisAccessLists(AccessLists): - model = 'dcim.virtualchassis' + model = "dcim.virtualchassis" class VMAccessLists(AccessLists): - model = 'virtualization.virtualmachine' + model = "virtualization.virtualmachine" class DeviceACLInterfaceAssignments(ACLInterfaceAssignments): - model = 'dcim.interface' + model = "dcim.interface" class VMAACLInterfaceAssignments(ACLInterfaceAssignments): - model = 'virtualization.vminterface' + model = "virtualization.vminterface" -template_extensions = [DeviceAccessLists, VirtualChassisAccessLists, VMAccessLists, DeviceACLInterfaceAssignments, VMAACLInterfaceAssignments] +template_extensions = [ + DeviceAccessLists, + VirtualChassisAccessLists, + VMAccessLists, + DeviceACLInterfaceAssignments, + VMAACLInterfaceAssignments, +] diff --git a/netbox_access_lists/templates/inc/assigned_host/assigned_access_lists.html b/netbox_access_lists/templates/inc/assigned_host/assigned_access_lists.html index f7111dc..f7ce8a3 100644 --- a/netbox_access_lists/templates/inc/assigned_host/assigned_access_lists.html +++ b/netbox_access_lists/templates/inc/assigned_host/assigned_access_lists.html @@ -24,4 +24,4 @@
None found
-{% endif %} \ No newline at end of file +{% endif %} diff --git a/netbox_access_lists/urls.py b/netbox_access_lists/urls.py index 10b6e42..0f4f4c3 100644 --- a/netbox_access_lists/urls.py +++ b/netbox_access_lists/urls.py @@ -8,51 +8,152 @@ from netbox.views.generic import ObjectChangeLogView from . import models, views urlpatterns = ( - # Access Lists - path('access-lists/', views.AccessListListView.as_view(), name='accesslist_list'), - path('access-lists/add/', views.AccessListEditView.as_view(), name='accesslist_add'), - #path('access-lists/edit/', views.AccessListBulkEditView.as_view(), name='accesslist_bulk_edit'), - path('access-lists/delete/', views.AccessListBulkDeleteView.as_view(), name='accesslist_bulk_delete'), - path('access-lists//', views.AccessListView.as_view(), name='accesslist'), - path('access-lists//edit/', views.AccessListEditView.as_view(), name='accesslist_edit'), - path('access-lists//delete/', views.AccessListDeleteView.as_view(), name='accesslist_delete'), - path('access-lists//changelog/', ObjectChangeLogView.as_view(), name='accesslist_changelog', kwargs={ - 'model': models.AccessList - }), - + path("access-lists/", views.AccessListListView.as_view(), name="accesslist_list"), + path( + "access-lists/add/", views.AccessListEditView.as_view(), name="accesslist_add" + ), + # path('access-lists/edit/', views.AccessListBulkEditView.as_view(), name='accesslist_bulk_edit'), + path( + "access-lists/delete/", + views.AccessListBulkDeleteView.as_view(), + name="accesslist_bulk_delete", + ), + path("access-lists//", views.AccessListView.as_view(), name="accesslist"), + path( + "access-lists//edit/", + views.AccessListEditView.as_view(), + name="accesslist_edit", + ), + path( + "access-lists//delete/", + views.AccessListDeleteView.as_view(), + name="accesslist_delete", + ), + path( + "access-lists//changelog/", + ObjectChangeLogView.as_view(), + name="accesslist_changelog", + kwargs={ + "model": models.AccessList, + }, + ), # Access List Interface Assignments - path('interface-assignments/', views.ACLInterfaceAssignmentListView.as_view(), name='aclinterfaceassignment_list'), - path('interface-assignments/add/', views.ACLInterfaceAssignmentEditView.as_view(), name='aclinterfaceassignment_add'), - #path('interface-assignments/edit/', views.ACLInterfaceAssignmentBulkEditView.as_view(), name='aclinterfaceassignment_bulk_edit'), - path('interface-assignments/delete/', views.ACLInterfaceAssignmentBulkDeleteView.as_view(), name='aclinterfaceassignment_bulk_delete'), - path('interface-assignments//', views.ACLInterfaceAssignmentView.as_view(), name='aclinterfaceassignment'), - path('interface-assignments//edit/', views.ACLInterfaceAssignmentEditView.as_view(), name='aclinterfaceassignment_edit'), - path('interface-assignments//delete/', views.ACLInterfaceAssignmentDeleteView.as_view(), name='aclinterfaceassignment_delete'), - path('interface-assignments//changelog/', ObjectChangeLogView.as_view(), name='aclinterfaceassignment_changelog', kwargs={ - 'model': models.ACLInterfaceAssignment - }), - + path( + "interface-assignments/", + views.ACLInterfaceAssignmentListView.as_view(), + name="aclinterfaceassignment_list", + ), + path( + "interface-assignments/add/", + views.ACLInterfaceAssignmentEditView.as_view(), + name="aclinterfaceassignment_add", + ), + # path('interface-assignments/edit/', views.ACLInterfaceAssignmentBulkEditView.as_view(), name='aclinterfaceassignment_bulk_edit'), + path( + "interface-assignments/delete/", + views.ACLInterfaceAssignmentBulkDeleteView.as_view(), + name="aclinterfaceassignment_bulk_delete", + ), + path( + "interface-assignments//", + views.ACLInterfaceAssignmentView.as_view(), + name="aclinterfaceassignment", + ), + path( + "interface-assignments//edit/", + views.ACLInterfaceAssignmentEditView.as_view(), + name="aclinterfaceassignment_edit", + ), + path( + "interface-assignments//delete/", + views.ACLInterfaceAssignmentDeleteView.as_view(), + name="aclinterfaceassignment_delete", + ), + path( + "interface-assignments//changelog/", + ObjectChangeLogView.as_view(), + name="aclinterfaceassignment_changelog", + kwargs={ + "model": models.ACLInterfaceAssignment, + }, + ), # Standard Access List Rules - path('standard-rules/', views.ACLStandardRuleListView.as_view(), name='aclstandardrule_list'), - path('standard-rules/add/', views.ACLStandardRuleEditView.as_view(), name='aclstandardrule_add'), - path('standard-rules/delete/', views.ACLStandardRuleBulkDeleteView.as_view(), name='aclstandardrule_bulk_delete'), - path('standard-rules//', views.ACLStandardRuleView.as_view(), name='aclstandardrule'), - path('standard-rules//edit/', views.ACLStandardRuleEditView.as_view(), name='aclstandardrule_edit'), - path('standard-rules//delete/', views.ACLStandardRuleDeleteView.as_view(), name='aclstandardrule_delete'), - path('standard-rules//changelog/', ObjectChangeLogView.as_view(), name='aclstandardrule_changelog', kwargs={ - 'model': models.ACLStandardRule - }), - + path( + "standard-rules/", + views.ACLStandardRuleListView.as_view(), + name="aclstandardrule_list", + ), + path( + "standard-rules/add/", + views.ACLStandardRuleEditView.as_view(), + name="aclstandardrule_add", + ), + path( + "standard-rules/delete/", + views.ACLStandardRuleBulkDeleteView.as_view(), + name="aclstandardrule_bulk_delete", + ), + path( + "standard-rules//", + views.ACLStandardRuleView.as_view(), + name="aclstandardrule", + ), + path( + "standard-rules//edit/", + views.ACLStandardRuleEditView.as_view(), + name="aclstandardrule_edit", + ), + path( + "standard-rules//delete/", + views.ACLStandardRuleDeleteView.as_view(), + name="aclstandardrule_delete", + ), + path( + "standard-rules//changelog/", + ObjectChangeLogView.as_view(), + name="aclstandardrule_changelog", + kwargs={ + "model": models.ACLStandardRule, + }, + ), # Extended Access List Rules - path('extended-rules/', views.ACLExtendedRuleListView.as_view(), name='aclextendedrule_list'), - path('extended-rules/add/', views.ACLExtendedRuleEditView.as_view(), name='aclextendedrule_add'), - path('extended-rules/delete/', views.ACLExtendedRuleBulkDeleteView.as_view(), name='aclextendedrule_bulk_delete'), - path('extended-rules//', views.ACLExtendedRuleView.as_view(), name='aclextendedrule'), - path('extended-rules//edit/', views.ACLExtendedRuleEditView.as_view(), name='aclextendedrule_edit'), - path('extended-rules//delete/', views.ACLExtendedRuleDeleteView.as_view(), name='aclextendedrule_delete'), - path('extended-rules//changelog/', ObjectChangeLogView.as_view(), name='aclextendedrule_changelog', kwargs={ - 'model': models.ACLExtendedRule - }), - + path( + "extended-rules/", + views.ACLExtendedRuleListView.as_view(), + name="aclextendedrule_list", + ), + path( + "extended-rules/add/", + views.ACLExtendedRuleEditView.as_view(), + name="aclextendedrule_add", + ), + path( + "extended-rules/delete/", + views.ACLExtendedRuleBulkDeleteView.as_view(), + name="aclextendedrule_bulk_delete", + ), + path( + "extended-rules//", + views.ACLExtendedRuleView.as_view(), + name="aclextendedrule", + ), + path( + "extended-rules//edit/", + views.ACLExtendedRuleEditView.as_view(), + name="aclextendedrule_edit", + ), + path( + "extended-rules//delete/", + views.ACLExtendedRuleDeleteView.as_view(), + name="aclextendedrule_delete", + ), + path( + "extended-rules//changelog/", + ObjectChangeLogView.as_view(), + name="aclextendedrule_changelog", + kwargs={ + "model": models.ACLExtendedRule, + }, + ), ) diff --git a/netbox_access_lists/views.py b/netbox_access_lists/views.py index cf59763..c2ad663 100644 --- a/netbox_access_lists/views.py +++ b/netbox_access_lists/views.py @@ -9,26 +9,26 @@ from netbox.views import generic from . import filtersets, forms, models, tables __all__ = ( - 'AccessListView', - 'AccessListListView', - 'AccessListEditView', - 'AccessListDeleteView', - 'AccessListBulkDeleteView', - 'ACLInterfaceAssignmentView', - 'ACLInterfaceAssignmentListView', - 'ACLInterfaceAssignmentEditView', - 'ACLInterfaceAssignmentDeleteView', - 'ACLInterfaceAssignmentBulkDeleteView', - 'ACLStandardRuleView', - 'ACLStandardRuleListView', - 'ACLStandardRuleEditView', - 'ACLStandardRuleDeleteView', - 'ACLStandardRuleBulkDeleteView', - 'ACLExtendedRuleView', - 'ACLExtendedRuleListView', - 'ACLExtendedRuleEditView', - 'ACLExtendedRuleDeleteView', - 'ACLExtendedRuleBulkDeleteView', + "AccessListView", + "AccessListListView", + "AccessListEditView", + "AccessListDeleteView", + "AccessListBulkDeleteView", + "ACLInterfaceAssignmentView", + "ACLInterfaceAssignmentListView", + "ACLInterfaceAssignmentEditView", + "ACLInterfaceAssignmentDeleteView", + "ACLInterfaceAssignmentBulkDeleteView", + "ACLStandardRuleView", + "ACLStandardRuleListView", + "ACLStandardRuleEditView", + "ACLStandardRuleDeleteView", + "ACLStandardRuleBulkDeleteView", + "ACLExtendedRuleView", + "ACLExtendedRuleListView", + "ACLExtendedRuleEditView", + "ACLExtendedRuleDeleteView", + "ACLExtendedRuleBulkDeleteView", ) @@ -36,24 +36,26 @@ __all__ = ( # AccessList views # + class AccessListView(generic.ObjectView): """ Defines the view for the AccessLists django model. """ + queryset = models.AccessList.objects.all() def get_extra_context(self, request, instance): """ Depending on the Access List type, the list view will return the required ACL Rule using the previous defined tables in tables.py. """ - if instance.type == 'extended': + if instance.type == "extended": table = tables.ACLExtendedRuleTable(instance.aclextendedrules.all()) - elif instance.type == 'standard': + elif instance.type == "standard": table = tables.ACLStandardRuleTable(instance.aclstandardrules.all()) table.configure(request) return { - 'rules_table': table + "rules_table": table, } @@ -61,8 +63,9 @@ class AccessListListView(generic.ObjectListView): """ Defines the list view for the AccessLists django model. """ + queryset = models.AccessList.objects.annotate( - rule_count=Count('aclextendedrules') + Count('aclstandardrules') + rule_count=Count("aclextendedrules") + Count("aclstandardrules"), ) table = tables.AccessListTable filterset = filtersets.AccessListFilterSet @@ -73,15 +76,17 @@ class AccessListEditView(generic.ObjectEditView): """ Defines the edit view for the AccessLists django model. """ + queryset = models.AccessList.objects.all() form = forms.AccessListForm - template_name = 'netbox_access_lists/accesslist_edit.html' + template_name = "netbox_access_lists/accesslist_edit.html" class AccessListDeleteView(generic.ObjectDeleteView): """ Defines the delete view for the AccessLists django model. """ + queryset = models.AccessList.objects.all() @@ -90,14 +95,17 @@ class AccessListBulkDeleteView(generic.BulkDeleteView): filterset = filtersets.AccessListFilterSet table = tables.AccessListTable + # # ACLInterfaceAssignment views # + class ACLInterfaceAssignmentView(generic.ObjectView): """ Defines the view for the ACLInterfaceAssignments django model. """ + queryset = models.ACLInterfaceAssignment.objects.all() @@ -105,6 +113,7 @@ class ACLInterfaceAssignmentListView(generic.ObjectListView): """ Defines the list view for the ACLInterfaceAssignments django model. """ + queryset = models.ACLInterfaceAssignment.objects.all() table = tables.ACLInterfaceAssignmentTable filterset = filtersets.ACLInterfaceAssignmentFilterSet @@ -115,15 +124,17 @@ class ACLInterfaceAssignmentEditView(generic.ObjectEditView): """ Defines the edit view for the ACLInterfaceAssignments django model. """ + queryset = models.ACLInterfaceAssignment.objects.all() form = forms.ACLInterfaceAssignmentForm - template_name = 'netbox_access_lists/aclinterfaceassignment_edit.html' + template_name = "netbox_access_lists/aclinterfaceassignment_edit.html" class ACLInterfaceAssignmentDeleteView(generic.ObjectDeleteView): """ Defines the delete view for the ACLInterfaceAssignments django model. """ + queryset = models.ACLInterfaceAssignment.objects.all() @@ -142,6 +153,7 @@ class ACLStandardRuleView(generic.ObjectView): """ Defines the view for the ACLStandardRule django model. """ + queryset = models.ACLStandardRule.objects.all() @@ -149,6 +161,7 @@ class ACLStandardRuleListView(generic.ObjectListView): """ Defines the list view for the ACLStandardRule django model. """ + queryset = models.ACLStandardRule.objects.all() table = tables.ACLStandardRuleTable filterset = filtersets.ACLStandardRuleFilterSet @@ -159,6 +172,7 @@ class ACLStandardRuleEditView(generic.ObjectEditView): """ Defines the edit view for the ACLStandardRule django model. """ + queryset = models.ACLStandardRule.objects.all() form = forms.ACLStandardRuleForm @@ -167,6 +181,7 @@ class ACLStandardRuleDeleteView(generic.ObjectDeleteView): """ Defines the delete view for the ACLStandardRules django model. """ + queryset = models.ACLStandardRule.objects.all() @@ -175,6 +190,7 @@ class ACLStandardRuleBulkDeleteView(generic.BulkDeleteView): filterset = filtersets.ACLStandardRuleFilterSet table = tables.ACLStandardRuleTable + # # ACLExtendedRule views # @@ -184,6 +200,7 @@ class ACLExtendedRuleView(generic.ObjectView): """ Defines the view for the ACLExtendedRule django model. """ + queryset = models.ACLExtendedRule.objects.all() @@ -191,6 +208,7 @@ class ACLExtendedRuleListView(generic.ObjectListView): """ Defines the list view for the ACLExtendedRule django model. """ + queryset = models.ACLExtendedRule.objects.all() table = tables.ACLExtendedRuleTable filterset = filtersets.ACLExtendedRuleFilterSet @@ -201,6 +219,7 @@ class ACLExtendedRuleEditView(generic.ObjectEditView): """ Defines the edit view for the ACLExtendedRule django model. """ + queryset = models.ACLExtendedRule.objects.all() form = forms.ACLExtendedRuleForm @@ -209,8 +228,10 @@ class ACLExtendedRuleDeleteView(generic.ObjectDeleteView): """ Defines the delete view for the ACLExtendedRules django model. """ + queryset = models.ACLExtendedRule.objects.all() + class ACLExtendedRuleBulkDeleteView(generic.BulkDeleteView): queryset = models.ACLExtendedRule.objects.all() filterset = filtersets.ACLExtendedRuleFilterSet diff --git a/setup.py b/setup.py index 4dc7fdc..9014601 100644 --- a/setup.py +++ b/setup.py @@ -1,20 +1,20 @@ -#import codecs -#import os.path +# import codecs +# import os.path # from setuptools import find_packages, setup # -#with open("README.md", "r") as fh: +# with open("README.md", "r") as fh: # long_description = fh.read() # # -#def read(rel_path): +# def read(rel_path): # here = os.path.abspath(os.path.dirname(__file__)) -# with codecs.open(os.path.join(here, rel_path), 'r') as fp: +# with codecs.open(os.path.join(here, rel_path), "r") as fp: # return fp.read() # # -#def get_version(rel_path): +# def get_version(rel_path): # for line in read(rel_path).splitlines(): # if line.startswith('__version__'): # delim = '"' if '"' in line else "'" @@ -24,13 +24,13 @@ from setuptools import find_packages, setup # setup( - name='netbox-access-lists', - version='0.1.0', - #version=get_version('netbox_access_lists/version.py'), - description='A NetBox plugin for Access List management', - #long_description=long_description, + name="netbox-access-lists", + version="0.1.0", + # version=get_version("netbox_access_lists/version.py"), + description="A NetBox plugin for Access List management", + # long_description=long_description, long_description_content_type="text/markdown", - url='https://github.com/ryanmerolle/netbox-access-lists', + url="https://github.com/ryanmerolle/netbox-access-lists", install_requires=[], packages=find_packages(), include_package_data=True,