From 25c8eebb213a0e7c17e07352d7c464c2e924a9bb Mon Sep 17 00:00:00 2001 From: Chris Russell Date: Thu, 19 Sep 2024 20:31:15 +0100 Subject: [PATCH 1/7] Update __init__.py min, max versions --- netbox_acls/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netbox_acls/__init__.py b/netbox_acls/__init__.py index 6e81b98..3dc3491 100644 --- a/netbox_acls/__init__.py +++ b/netbox_acls/__init__.py @@ -17,8 +17,8 @@ class NetBoxACLsConfig(PluginConfig): version = __version__ description = "Manage simple ACLs in NetBox" base_url = "access-lists" - min_version = "4.0.2" - max_version = "4.0.99" + min_version = "4.1.0" + max_version = "4.1.20" config = NetBoxACLsConfig From 7c27db634f2c77ce20f97ef480f186aa3e5f7f54 Mon Sep 17 00:00:00 2001 From: Chris Russell Date: Thu, 19 Sep 2024 20:34:27 +0100 Subject: [PATCH 2/7] Update Docker to v4.1 --- Dockerfile | 2 +- docker-compose.yml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8616db2..b133357 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -ARG NETBOX_VARIANT=v4.0 +ARG NETBOX_VARIANT=v4.1 FROM netboxcommunity/netbox:${NETBOX_VARIANT} diff --git a/docker-compose.yml b/docker-compose.yml index 5ea2ed2..b36e24f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,4 @@ --- -version: '3.4' services: netbox: From e157c8bdabbae5202d777a1263f12aa09c0bf28a Mon Sep 17 00:00:00 2001 From: Chris Russell Date: Thu, 19 Sep 2024 20:40:08 +0100 Subject: [PATCH 3/7] Bump Python version in Docker --- Dockerfile | 2 +- setup.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index b133357..a0abf62 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,4 +6,4 @@ RUN mkdir -pv /plugins/netbox-acls COPY . /plugins/netbox-acls RUN /opt/netbox/venv/bin/python3 /plugins/netbox-acls/setup.py develop && \ - cp -rf /plugins/netbox-acls/netbox_acls/ /opt/netbox/venv/lib/python3.11/site-packages/netbox_acls + cp -rf /plugins/netbox-acls/netbox_acls/ /opt/netbox/venv/lib/python3.12/site-packages/netbox_acls diff --git a/setup.py b/setup.py index 2ac195b..60544f8 100644 --- a/setup.py +++ b/setup.py @@ -54,6 +54,7 @@ def get_version(relative_path): "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Intended Audience :: System Administrators", "Intended Audience :: Telecommunications Industry", "Framework :: Django", From 87fcb9366003d258b99b8d16af797472ee582761 Mon Sep 17 00:00:00 2001 From: Chris Russell Date: Thu, 19 Sep 2024 20:46:09 +0100 Subject: [PATCH 4/7] Change Serializers to nested --- netbox_acls/api/serializers.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/netbox_acls/api/serializers.py b/netbox_acls/api/serializers.py index 3715599..e2e4253 100644 --- a/netbox_acls/api/serializers.py +++ b/netbox_acls/api/serializers.py @@ -5,10 +5,9 @@ from django.contrib.contenttypes.models import ContentType from drf_spectacular.utils import extend_schema_field -from ipam.api.serializers import NestedPrefixSerializer +from ipam.api.serializers import PrefixSerializer from netbox.api.fields import ContentTypeField from netbox.api.serializers import NetBoxModelSerializer -from netbox.constants import NESTED_SERIALIZER_PREFIX from rest_framework import serializers from utilities.api import get_serializer_for_model @@ -81,10 +80,9 @@ class Meta: def get_assigned_object(self, obj): serializer = get_serializer_for_model( obj.assigned_object, - prefix=NESTED_SERIALIZER_PREFIX, ) context = {"request": self.context["request"]} - return serializer(obj.assigned_object, context=context).data + return serializer(obj.assigned_object, nested=True, context=context).data def validate(self, data): """ @@ -145,11 +143,10 @@ class Meta: @extend_schema_field(serializers.DictField()) def get_assigned_object(self, obj): serializer = get_serializer_for_model( - obj.assigned_object, - prefix=NESTED_SERIALIZER_PREFIX, + obj.assigned_object ) context = {"request": self.context["request"]} - return serializer(obj.assigned_object, context=context).data + return serializer(obj.assigned_object, nested=True, context=context).data def validate(self, data): """ @@ -187,10 +184,11 @@ class ACLStandardRuleSerializer(NetBoxModelSerializer): view_name="plugins-api:netbox_acls-api:aclstandardrule-detail", ) access_list = NestedAccessListSerializer() - source_prefix = NestedPrefixSerializer( + source_prefix = PrefixSerializer( required=False, allow_null=True, default=None, + nested=True ) class Meta: @@ -251,15 +249,17 @@ class ACLExtendedRuleSerializer(NetBoxModelSerializer): view_name="plugins-api:netbox_acls-api:aclextendedrule-detail", ) access_list = NestedAccessListSerializer() - source_prefix = NestedPrefixSerializer( + source_prefix = PrefixSerializer( required=False, allow_null=True, default=None, + nested=True ) - destination_prefix = NestedPrefixSerializer( + destination_prefix = PrefixSerializer( required=False, allow_null=True, default=None, + nested=True ) class Meta: From 4af0917274042371d1a0b4e3443aeaff8381d1dd Mon Sep 17 00:00:00 2001 From: Chris Russell Date: Thu, 19 Sep 2024 21:48:45 +0100 Subject: [PATCH 5/7] Filterset fixes --- netbox_acls/forms/filtersets.py | 40 +++++++++------------------------ netbox_acls/forms/models.py | 40 +++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 47 deletions(-) diff --git a/netbox_acls/forms/filtersets.py b/netbox_acls/forms/filtersets.py index 33ac9fb..41715ff 100644 --- a/netbox_acls/forms/filtersets.py +++ b/netbox_acls/forms/filtersets.py @@ -1,12 +1,13 @@ """ Defines each django model's GUI filter/search options. """ - +from django.utils.translation import gettext_lazy as _ from dcim.models import Device, Interface, Region, Site, SiteGroup, VirtualChassis from django import forms from django.utils.translation import gettext as _ from ipam.models import Prefix from netbox.forms import NetBoxModelFilterSetForm +from utilities.forms.rendering import FieldSet from utilities.forms.fields import ( DynamicModelChoiceField, DynamicModelMultipleChoiceField, @@ -90,22 +91,11 @@ class AccessListFilterForm(NetBoxModelFilterSetForm): tag = TagFilterField(model) fieldsets = ( - (None, ("q", "tag")), - ( - "Host Details", - ( - "region", - "site_group", - "site", - "device_id", - "virtual_chassis_id", - "virtual_machine_id", - ), - ), - ("ACL Details", ("type", "default_action")), + FieldSet("region", "site_group", "site", "device_id", "virtual_chassis_id", "virtual_machine_id", name=_("Host Details")), + FieldSet("type", "default_action", name=_('ACL Details')), + FieldSet("q", "tag",name=None) ) - class ACLInterfaceAssignmentFilterForm(NetBoxModelFilterSetForm): """ GUI filter form to search the django AccessList model. @@ -195,12 +185,11 @@ class ACLStandardRuleFilterForm(NetBoxModelFilterSetForm): choices=add_blank_choice(ACLRuleActionChoices), required=False, ) + fieldsets = ( - (None, ("q", "tag")), - ("Rule Details", ("access_list", "action", "source_prefix")), + FieldSet("access_list", "action", "source_prefix", name=_('Rule Details')), + FieldSet("q", "tag",name=None) ) - - class ACLExtendedRuleFilterForm(NetBoxModelFilterSetForm): """ GUI filter form to search the django ACLExtendedRule model. @@ -235,15 +224,6 @@ class ACLExtendedRuleFilterForm(NetBoxModelFilterSetForm): ) fieldsets = ( - (None, ("q", "tag")), - ( - "Rule Details", - ( - "access_list", - "action", - "source_prefix", - "desintation_prefix", - "protocol", - ), - ), + FieldSet("access_list", "action", "source_prefix", "desintation_prefix", "protocol", name=_('Rule Details')), + FieldSet("q", "tag",name=None) ) diff --git a/netbox_acls/forms/models.py b/netbox_acls/forms/models.py index dfba915..162e63d 100644 --- a/netbox_acls/forms/models.py +++ b/netbox_acls/forms/models.py @@ -1,13 +1,14 @@ """ Defines each django model's GUI form to add or edit objects for each django model. """ - +from django.utils.translation import gettext_lazy as _ from dcim.models import Device, Interface, Region, Site, SiteGroup, VirtualChassis from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError from django.utils.safestring import mark_safe from ipam.models import Prefix from netbox.forms import NetBoxModelForm +from utilities.forms.rendering import FieldSet from utilities.forms.fields import CommentField, DynamicModelChoiceField from virtualization.models import ( Cluster, @@ -134,6 +135,11 @@ class Meta: "comments", "tags", ) + fieldsets = ( + FieldSet('region', 'site_group', 'site', 'virtual_machine', 'virtual_chassis', 'device', name=_('Assignment')), + FieldSet('name', 'type', 'default_action', name=_('Access List')), + FieldSet('comments', 'tags', name=_('')), + ) help_texts = { "default_action": "The default behavior of the ACL.", "name": "The name uniqueness per device is case insensitive.", @@ -313,6 +319,11 @@ class Meta: "comments", "tags", ) + fieldsets = ( + FieldSet('device', 'interface', 'virtual_machine', 'vminterface', name=_('Assignment')), + FieldSet('access_list', 'direction', name=_('Access List Details')), + FieldSet('comments', 'tags', name=_('')), + ) help_texts = { "direction": mark_safe( "*Note: CANNOT assign 2 ACLs to the same interface & direction.", @@ -455,6 +466,13 @@ class Meta: "tags", "description", ) + fieldsets = ( + FieldSet("access_list", "description", "tags", name=_('Access List Details')), + FieldSet("index", "action", "remark", "source_prefix", name=_('Rule Definition')) + ) + + + help_texts = { "index": help_text_acl_rule_index, "action": help_text_acl_action, @@ -523,22 +541,6 @@ class ACLExtendedRuleForm(NetBoxModelForm): help_text=help_text_acl_rule_logic, 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", - ), - ), - ) class Meta: model = ACLExtendedRule @@ -555,6 +557,10 @@ class Meta: "tags", "description", ) + fieldsets = ( + FieldSet("access_list", "description", "tags", name=_('Access List Details')), + FieldSet("index", "action", "remark", "source_prefix", "source_ports", "destination_prefix", "destination_ports", "protocol", name=_('Rule Definition')) + ) help_texts = { "action": help_text_acl_action, "destination_ports": help_text_acl_rule_logic, From f950858e55df35cfbca909c6c3d14880b680b161 Mon Sep 17 00:00:00 2001 From: Chris Russell Date: Thu, 19 Sep 2024 22:23:10 +0100 Subject: [PATCH 6/7] move filtersets to models not meta --- netbox_acls/forms/models.py | 44 ++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/netbox_acls/forms/models.py b/netbox_acls/forms/models.py index 162e63d..d25bab2 100644 --- a/netbox_acls/forms/models.py +++ b/netbox_acls/forms/models.py @@ -119,7 +119,12 @@ class AccessListForm(NetBoxModelForm): ) comments = CommentField() - + fieldsets = ( + FieldSet('region', 'site_group', 'site', 'virtual_machine', 'virtual_chassis', 'device', name=_('Assignment')), + FieldSet('name', 'type', 'default_action', name=_('Access List')), + FieldSet('comments', 'tags', name=_('')), + ) + class Meta: model = AccessList fields = ( @@ -135,11 +140,7 @@ class Meta: "comments", "tags", ) - fieldsets = ( - FieldSet('region', 'site_group', 'site', 'virtual_machine', 'virtual_chassis', 'device', name=_('Assignment')), - FieldSet('name', 'type', 'default_action', name=_('Access List')), - FieldSet('comments', 'tags', name=_('')), - ) + help_texts = { "default_action": "The default behavior of the ACL.", "name": "The name uniqueness per device is case insensitive.", @@ -291,6 +292,11 @@ class ACLInterfaceAssignmentForm(NetBoxModelForm): ), ) comments = CommentField() + fieldsets = ( + FieldSet('device', 'interface', 'virtual_machine', 'vminterface', name=_('Assignment')), + FieldSet('access_list', 'direction', name=_('Access List Details')), + FieldSet('comments', 'tags', name=_('')), + ) def __init__(self, *args, **kwargs): # Initialize helper selectors @@ -319,11 +325,7 @@ class Meta: "comments", "tags", ) - fieldsets = ( - FieldSet('device', 'interface', 'virtual_machine', 'vminterface', name=_('Assignment')), - FieldSet('access_list', 'direction', name=_('Access List Details')), - FieldSet('comments', 'tags', name=_('')), - ) + help_texts = { "direction": mark_safe( "*Note: CANNOT assign 2 ACLs to the same interface & direction.", @@ -451,10 +453,9 @@ class ACLStandardRuleForm(NetBoxModelForm): ) fieldsets = ( - ("Access List Details", ("access_list", "description", "tags")), - ("Rule Definition", ("index", "action", "remark", "source_prefix")), + FieldSet("access_list", "description", "tags", name=_('Access List Details')), + FieldSet("index", "action", "remark", "source_prefix", name=_('Rule Definition')) ) - class Meta: model = ACLStandardRule fields = ( @@ -466,10 +467,7 @@ class Meta: "tags", "description", ) - fieldsets = ( - FieldSet("access_list", "description", "tags", name=_('Access List Details')), - FieldSet("index", "action", "remark", "source_prefix", name=_('Rule Definition')) - ) + @@ -541,7 +539,10 @@ class ACLExtendedRuleForm(NetBoxModelForm): help_text=help_text_acl_rule_logic, label="Destination Prefix", ) - + fieldsets = ( + FieldSet("access_list", "description", "tags", name=_('Access List Details')), + FieldSet("index", "action", "remark", "source_prefix", "source_ports", "destination_prefix", "destination_ports", "protocol", name=_('Rule Definition')) + ) class Meta: model = ACLExtendedRule fields = ( @@ -557,10 +558,7 @@ class Meta: "tags", "description", ) - fieldsets = ( - FieldSet("access_list", "description", "tags", name=_('Access List Details')), - FieldSet("index", "action", "remark", "source_prefix", "source_ports", "destination_prefix", "destination_ports", "protocol", name=_('Rule Definition')) - ) + help_texts = { "action": help_text_acl_action, "destination_ports": help_text_acl_rule_logic, From 02f428acb0d85a51342eb63b89ba06e44b557f1e Mon Sep 17 00:00:00 2001 From: Chris Russell Date: Thu, 10 Oct 2024 21:09:11 +0100 Subject: [PATCH 7/7] bump version to 1.7.0 --- README.md | 15 ++++++++------- netbox_acls/__init__.py | 2 +- netbox_acls/version.py | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index fc795e0..11feab5 100644 --- a/README.md +++ b/README.md @@ -36,15 +36,16 @@ See the [CONTRIBUTING](CONTRIBUTING.md) for more information. Each Plugin Version listed below has been tested with its corresponding NetBox Version. -| NetBox Version | Plugin Version | +| NetBox Version | Plugin Version | |:-------------------:|:--------------:| +| 4.1.x | 1.7.0 | | >= 4.0.2 < 4.1.0 | 1.6.1 | -| 3.7 | 1.5.0 | -| 3.6 | 1.4.0 | -| 3.5 | 1.3.0 | -| 3.4 | 1.2.2 | -| 3.3 | 1.1.0 | -| 3.2 | 1.0.1 | +| 3.7.x | 1.5.0 | +| 3.6.x | 1.4.0 | +| 3.5.x | 1.3.0 | +| 3.4.x | 1.2.2 | +| 3.3.x | 1.1.0 | +| 3.2.x | 1.0.1 | ## Installing diff --git a/netbox_acls/__init__.py b/netbox_acls/__init__.py index 3dc3491..aed9081 100644 --- a/netbox_acls/__init__.py +++ b/netbox_acls/__init__.py @@ -18,7 +18,7 @@ class NetBoxACLsConfig(PluginConfig): description = "Manage simple ACLs in NetBox" base_url = "access-lists" min_version = "4.1.0" - max_version = "4.1.20" + max_version = "4.1.99" config = NetBoxACLsConfig diff --git a/netbox_acls/version.py b/netbox_acls/version.py index f49459c..14d9d2f 100644 --- a/netbox_acls/version.py +++ b/netbox_acls/version.py @@ -1 +1 @@ -__version__ = "1.6.1" +__version__ = "1.7.0"