diff --git a/netbox_access_lists/forms.py b/netbox_access_lists/forms.py
index cb18e37..1c969f7 100644
--- a/netbox_access_lists/forms.py
+++ b/netbox_access_lists/forms.py
@@ -1,5 +1,6 @@
from django import forms
from django.core.exceptions import ValidationError
+from django.utils.safestring import mark_safe
from extras.models import Tag
from ipam.models import Prefix
@@ -8,6 +9,8 @@ from utilities.forms import CommentField, DynamicModelChoiceField, DynamicModelM
from .models import AccessList, AccessListExtendedRule, AccessListActionChoices, AccessListProtocolChoices, AccessListTypeChoices, AccessListStandardRule
+acl_rule_logic_help = mark_safe('*Note: CANNOT be set if remark is set.')
+
class AccessListForm(NetBoxModelForm):
comments = CommentField()
tags = DynamicModelMultipleChoiceField(
@@ -15,9 +18,18 @@ class AccessListForm(NetBoxModelForm):
required=False
)
+ fieldsets = [
+ ('Access-List Details', ('name', 'device', 'type', 'default_action', 'tags')),
+ ]
+
class Meta:
model = AccessList
fields = ('name', 'device', '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': 'Sets the type of the ACL & its rules.',
+ }
def clean(self):
cleaned_data = super().clean()
@@ -26,7 +38,7 @@ class AccessListForm(NetBoxModelForm):
name = cleaned_data.get('name')
device = cleaned_data.get('device')
if ('name' in self.changed_data or 'device' in self.changed_data) and AccessList.objects.filter(name__iexact=name, device=device).exists():
- raise forms.ValidationError('An Access-List with this name is already associated to this device.')
+ raise forms.ValidationError('An ACL with this name (case insensitive) is already associated to this device.')
return cleaned_data
class AccessListFilterForm(NetBoxModelFilterSetForm):
@@ -34,7 +46,7 @@ class AccessListFilterForm(NetBoxModelFilterSetForm):
type = forms.MultipleChoiceField(
choices=AccessListTypeChoices,
required=False,
- widget=StaticSelectMultiple()
+ widget=StaticSelectMultiple(),
)
default_action = forms.MultipleChoiceField(
choices=AccessListActionChoices,
@@ -43,29 +55,46 @@ class AccessListFilterForm(NetBoxModelFilterSetForm):
)
tag = TagFilterField(model)
+ fieldsets = (
+ (None, ('q', 'tag')),
+ ('ACL Details', ('type', 'default_action')),
+ )
+
class AccessListStandardRuleForm(NetBoxModelForm):
access_list = DynamicModelChoiceField(
queryset=AccessList.objects.all(),
query_params={
'type': 'standard'
- }
+ },
+ help_text=mark_safe('*Note: This field will only display Standard ACLs.'),
+ )
+ source_prefix = DynamicModelChoiceField(
+ queryset=Prefix.objects.all(),
+ required=False,
+ help_text=acl_rule_logic_help,
)
tags = DynamicModelMultipleChoiceField(
queryset=Tag.objects.all(),
required=False
)
- source_prefix = DynamicModelChoiceField(
- queryset=Prefix.objects.all(),
- required=False
- )
+ fieldsets = (
+ ('Access-List Details', ('access_list', 'index', 'tags')),
+ ('Rule Logic', ('remark', 'action', 'source_prefix')),
+ )
class Meta:
model = AccessListStandardRule
fields = (
- 'access_list', 'index', 'remark', 'action', 'tags', 'source_prefix',
+ 'access_list', 'index', 'remark', 'action', 'source_prefix',
+ 'tags',
)
+ help_texts = {
+ 'action': acl_rule_logic_help,
+ 'index': 'Determines the order of the rule in the ACL processing.',
+ 'remark': mark_safe('*Note: CANNOT be set if source prefix OR action is set.'),
+ }
def clean(self):
cleaned_data = super().clean()
@@ -86,23 +115,29 @@ class AccessListStandardRuleFilterForm(NetBoxModelFilterSetForm):
required=False,
widget=StaticSelectMultiple()
)
- index = forms.IntegerField(
- required=False
- )
tag = TagFilterField(model)
+ source_prefix = forms.ModelMultipleChoiceField(
+ queryset=Prefix.objects.all(),
+ required=False,
+ widget=StaticSelectMultiple()
+ )
action = forms.MultipleChoiceField(
choices=AccessListActionChoices,
required=False,
widget=StaticSelectMultiple()
)
-
+ fieldsets = (
+ (None, ('q', 'tag')),
+ ('Rule Details', ('access_list', 'action', 'source_prefix',)),
+ )
class AccessListExtendedRuleForm(NetBoxModelForm):
access_list = DynamicModelChoiceField(
queryset=AccessList.objects.all(),
query_params={
'type': 'extended'
- }
+ },
+ help_text=mark_safe('*Note: This field will only display Extended ACLs.'),
)
tags = DynamicModelMultipleChoiceField(
queryset=Tag.objects.all(),
@@ -110,20 +145,34 @@ class AccessListExtendedRuleForm(NetBoxModelForm):
)
source_prefix = DynamicModelChoiceField(
queryset=Prefix.objects.all(),
- required=False
+ required=False,
+ help_text=acl_rule_logic_help,
)
destination_prefix = DynamicModelChoiceField(
queryset=Prefix.objects.all(),
- required=False
+ required=False,
+ help_text=acl_rule_logic_help,
+ )
+ fieldsets = (
+ ('Access-List Details', ('access_list', 'index', 'tags')),
+ ('Rule Details', ('remark', 'action', 'source_prefix', 'source_ports', 'destination_prefix', 'destination_ports', 'protocol',)),
)
-
class Meta:
model = AccessListExtendedRule
fields = (
- 'access_list', 'index', 'remark', 'action', 'tags', 'source_prefix',
- 'source_ports', 'destination_prefix', 'destination_ports', 'protocol'
+ 'access_list', 'index', 'remark', 'action', 'source_prefix',
+ 'source_ports', 'destination_prefix', 'destination_ports', 'protocol',
+ 'tags'
)
+ help_texts = {
+ 'action': acl_rule_logic_help,
+ 'destination_ports': acl_rule_logic_help,
+ 'index': 'Determines the order of the rule in the ACL processing.',
+ 'protocol': acl_rule_logic_help,
+ 'remark': mark_safe('*Note: CANNOT be set if a prefix, port, OR action is set.'),
+ 'source_ports': acl_rule_logic_help,
+ }
def clean(self):
cleaned_data = super().clean()
@@ -161,8 +210,23 @@ class AccessListExtendedRuleFilterForm(NetBoxModelFilterSetForm):
required=False,
widget=StaticSelectMultiple()
)
+ source_prefix = forms.ModelMultipleChoiceField(
+ queryset=Prefix.objects.all(),
+ required=False,
+ widget=StaticSelectMultiple()
+ )
+ desintation_prefix = forms.ModelMultipleChoiceField(
+ queryset=Prefix.objects.all(),
+ required=False,
+ widget=StaticSelectMultiple()
+ )
protocol = forms.MultipleChoiceField(
choices=AccessListProtocolChoices,
required=False,
widget=StaticSelectMultiple()
)
+
+ fieldsets = (
+ (None, ('q', 'tag')),
+ ('Rule Details', ('access_list', 'action', 'source_prefix', 'desintation_prefix', 'protocol')),
+ )