Skip to content

129 add community requested source and destination objects #236

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
79acd48
feat: Adding new Source-Fields to ACLStandard Rule
rvveber Sep 2, 2024
3b6c1d8
feat: Adding new Destination-Fields to ACLExtended Rule
rvveber Sep 2, 2024
32f1421
feat: Adding Database Constraint for ACLStandard Rule, so that at max…
rvveber Sep 2, 2024
0eb4a94
feat: Adding Database Constraint for ACLExtended Rule, so that at max…
rvveber Sep 2, 2024
4005d23
feat: Adding Database Constraint for ACLExtended Rule, so that at max…
rvveber Sep 2, 2024
d77539d
refactor: Re-order; Adapt Comments; Use Constants
rvveber Sep 2, 2024
181c954
feat(view): Adding new Source fields to Standard Rule View Set
rvveber Sep 2, 2024
0df3efc
feat(view): Adding new Source fields to Extended Rule View Set
rvveber Sep 2, 2024
8b30a0f
feat(view): Adding new Destination fields to Extended Rule View Set
rvveber Sep 2, 2024
ce2f7d3
feat(view): Adding new Source Fields to ACL Standard Rule Template
rvveber Sep 2, 2024
ce260f7
feat(view): Adding new Source fields to ACL Extended Rule Template
rvveber Sep 2, 2024
c49b326
feat(view): Adding new Destination fields to ACL Extended Rule Template
rvveber Sep 2, 2024
7ede033
feat(view): Adding new Source Fields to the Views of ACLStandardRule
rvveber Sep 2, 2024
2768d99
feat(view): Adding new Source Fields to the Views of ACLExtendedRule
rvveber Sep 2, 2024
b783963
feat(view): Adding new Destination Fields to the Views of ACLExtended…
rvveber Sep 2, 2024
12a2732
feat(form): Adding new Sources to the ACLStandardRule creation form
rvveber Sep 2, 2024
4a11927
feat(form): ACLStandardRule: Instruct new Sources to be displayed as …
rvveber Sep 2, 2024
67d1bb3
feat(form): ACLStandardRule: Change validation to support multiple so…
rvveber Sep 2, 2024
77b4d06
feat(form): Adding new Sources to the ACLExtendedRule creation form
rvveber Sep 2, 2024
00cfcda
feat(form): ACLExtendedRule: Instruct new Sources to be displayed as …
rvveber Sep 2, 2024
7f1207f
feat(form): ACLExtendedRule: Change validation to support multiple so…
rvveber Sep 2, 2024
2ea2da2
feat(form): Adding new Destinations to the ACLExtendedRule creation form
rvveber Sep 2, 2024
3503ba8
feat(form): ACLExtendedRule: Instruct new Destinations to be displaye…
rvveber Sep 2, 2024
ac9de10
feat(form): ACLExtendedRule: Change validation to support multiple de…
rvveber Sep 2, 2024
c1b8318
fix(table): Fix error when sorting host in InterfaceAssignment
rvveber Sep 2, 2024
0bc0dc7
feat(table): ACLStandardRule: Changing Source Prefix to a single Sour…
rvveber Sep 2, 2024
1a83333
feat(table): ACLExtendedRule: Changing Source Prefix to a single Sour…
rvveber Sep 2, 2024
e0009f4
feat(table): ACLExtendedRule: Changing Destination Prefix to a single…
rvveber Sep 2, 2024
1044d7a
feat(filter): ACLStandardRule: Adding new Sources to the filter
rvveber Sep 2, 2024
84d055c
feat(filter): ACLStandardRule: Instruct new Sources to be displayed a…
rvveber Sep 2, 2024
78d4fe7
feat(filter): ACLExtendedRule: Adding new Sources to the filter
rvveber Sep 2, 2024
f0a4653
feat(filter): ACLExtendedRule: Instruct new Sources to be displayed a…
rvveber Sep 2, 2024
7737c5d
feat(filter): ACLExtendedRule: Adding new Destinations to the filter
rvveber Sep 2, 2024
e8bd368
feat(filter): ACLExtendedRule: Instruct new Destinations to be displa…
rvveber Sep 2, 2024
fb0fd3f
feat(serializer): ACLStandardRule: Adding new Source Fields to serial…
rvveber Sep 2, 2024
2c9f8f9
feat(serializer): ACLStandardRule: Change validation to support multi…
rvveber Sep 2, 2024
7e311f2
feat(serializer): ACLExtendedRule: Adding new Source Fields to serial…
rvveber Sep 2, 2024
502cc46
feat(serializer): ACLExtendedRule: Change validation to support multi…
rvveber Sep 2, 2024
0307513
feat(serializer): ACLExtendedRule: Adding new Destination Fields to s…
rvveber Sep 2, 2024
533d987
feat(serializer): ACLExtendedRule: Change validation to support multi…
rvveber Sep 2, 2024
abd0c51
feat(migration): Adding migration for the new sources and destinations
rvveber Oct 17, 2024
80f8532
feat(rebase): rebase from dev 404ad38
alexis-UE Mar 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 137 additions & 23 deletions netbox_acls/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from django.contrib.contenttypes.models import ContentType
from drf_spectacular.utils import extend_schema_field
from ipam.api.serializers import PrefixSerializer
from ipam.api.serializers import PrefixSerializer, IPRangeSerializer, IPAddressSerializer, AggregateSerializer, ServiceSerializer
from netbox.api.fields import ContentTypeField
from netbox.api.serializers import NetBoxModelSerializer
from rest_framework import serializers
Expand All @@ -27,14 +27,20 @@
"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."
# 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."
# Sets a standard error message for ACL rules with an action of remark, but no source/destination is set.
error_message_action_remark_source_set = "Action is set to remark, Source CANNOT be set."
error_message_action_remark_destination_set = "Action is set to remark, Destination 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."
# 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."
# Sets a standard error message for ACL rules when more than one IP/Host sources are set.
error_message_sources_more_than_one = "Only one IP/Host related Source can be specified."
# Sets a standard error message for ACL rules when more than one IP/Host destinations are set.
error_message_destinations_more_than_one = "Only one IP/Host related Destination can be specified."


class AccessListSerializer(NetBoxModelSerializer):
Expand Down Expand Up @@ -190,6 +196,30 @@ class ACLStandardRuleSerializer(NetBoxModelSerializer):
default=None,
nested=True
)
source_iprange = IPRangeSerializer(
required=False,
allow_null=True,
default=None,
nested=True
)
source_ipaddress = IPAddressSerializer(
required=False,
allow_null=True,
default=None,
nested=True
)
source_aggregate = AggregateSerializer(
required=False,
allow_null=True,
default=None,
nested=True
)
source_service = ServiceSerializer(
required=False,
allow_null=True,
default=None,
nested=True
)

class Meta:
"""
Expand All @@ -211,28 +241,39 @@ class Meta:
"custom_fields",
"last_updated",
"source_prefix",
"source_iprange",
"source_ipaddress",
"source_aggregate",
"source_service",
)
brief_fields = ("id", "url", "display")

def validate(self, data):
"""
Validate the ACLStandardRule django model's inputs before allowing it to update the instance:
- Check if action set to remark, but no remark set.
- Check if action set to remark, but source_prefix set.
- Check if action set to remark, but source set.
- Check not more than one source is set.
"""
error_message = {}

sources = ["source_prefix", "source_iprange", "source_ipaddress", "source_aggregate", "source_service"]

if data.get("action") == "remark":
# Check if action set to remark, but no remark set.
if 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,
]
# Check if action set to remark, but source set.
if any(data.get(source) for source in sources):
for source in sources:
error_message[source] = [error_message_action_remark_source_set]

# Check not more than one source is set.
if sum(bool(data.get(source)) for source in sources) > 1:
for source in sources:
error_message[source] = [error_message_sources_more_than_one]

if error_message:
raise serializers.ValidationError(error_message)
Expand All @@ -249,18 +290,68 @@ class ACLExtendedRuleSerializer(NetBoxModelSerializer):
view_name="plugins-api:netbox_acls-api:aclextendedrule-detail",
)
access_list = NestedAccessListSerializer()

source_prefix = PrefixSerializer(
required=False,
allow_null=True,
default=None,
nested=True
)
source_iprange = IPRangeSerializer(
required=False,
allow_null=True,
default=None,
nested=True
)
source_ipaddress = IPAddressSerializer(
required=False,
allow_null=True,
default=None,
nested=True
)
source_aggregate = AggregateSerializer(
required=False,
allow_null=True,
default=None,
nested=True
)
source_service = ServiceSerializer(
required=False,
allow_null=True,
default=None,
nested=True
)

destination_prefix = PrefixSerializer(
required=False,
allow_null=True,
default=None,
nested=True
)
destination_iprange = IPRangeSerializer(
required=False,
allow_null=True,
default=None,
nested=True
)
destination_ipaddress = IPAddressSerializer(
required=False,
allow_null=True,
default=None,
nested=True
)
destination_aggregate = AggregateSerializer(
required=False,
allow_null=True,
default=None,
nested=True
)
destination_service = ServiceSerializer(
required=False,
allow_null=True,
default=None,
nested=True
)

class Meta:
"""
Expand All @@ -280,9 +371,20 @@ class Meta:
"created",
"custom_fields",
"last_updated",

"source_prefix",
"source_ports",
"source_iprange",
"source_ipaddress",
"source_aggregate",
"source_service",

"destination_prefix",
"destination_iprange",
"destination_ipaddress",
"destination_aggregate",
"destination_service",

"source_ports",
"destination_ports",
"protocol",
"remark",
Expand All @@ -292,36 +394,38 @@ def validate(self, data):
"""
Validate the ACLExtendedRule django model's inputs before allowing it to update the instance:
- Check if action set to remark, but no remark set.
- Check if action set to remark, but source_prefix set.
- Check if action set to remark, but source set.
- Check if action set to remark, but destination set.
- Check if action set to remark, but source_ports set.
- Check if action set to remark, but destination_prefix set.
- Check if action set to remark, but destination_ports set.
- Check if action set to remark, but protocol set.
- Check if action set to remark, but protocol set.
- Check not more than one source is set.
- Check not more than one destination is set.
"""
error_message = {}

sources = ["source_prefix", "source_iprange", "source_ipaddress", "source_aggregate", "source_service"]
destinations = ["destination_prefix", "destination_iprange", "destination_ipaddress", "destination_aggregate", "destination_service"]

if data.get("action") == "remark":
# Check if action set to remark, but no remark set.
if 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,
]
# Check if action set to remark, but source set.
if any(data.get(source) for source in sources):
for source in sources:
error_message[source] = [error_message_action_remark_source_set]
# Check if action set to remark, but destination set.
if any(data.get(destination) for destination in destinations):
for destination in destinations:
error_message[destination] = [error_message_action_remark_destination_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.",
]
# 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.",
]
# Check if action set to remark, but destination_ports set.
if data.get("destination_ports"):
error_message["destination_ports"] = [
Expand All @@ -332,6 +436,16 @@ def validate(self, data):
error_message["protocol"] = [
"Action is set to remark, Protocol CANNOT be set.",
]

# Check not more than one source is set.
if sum(bool(data.get(source)) for source in sources) > 1:
for source in sources:
error_message[source] = [error_message_sources_more_than_one]

# Check not more than one destination is set.
if sum(bool(data.get(destination)) for destination in destinations) > 1:
for destination in destinations:
error_message[destination] = [error_message_destinations_more_than_one]

if error_message:
raise serializers.ValidationError(error_message)
Expand Down
6 changes: 3 additions & 3 deletions netbox_acls/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class ACLStandardRuleViewSet(NetBoxModelViewSet):
queryset = models.ACLStandardRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
"source_prefix", "source_iprange", "source_ipaddress", "source_aggregate", "source_service"
)
serializer_class = ACLStandardRuleSerializer
filterset_class = filtersets.ACLStandardRuleFilterSet
Expand All @@ -74,8 +74,8 @@ class ACLExtendedRuleViewSet(NetBoxModelViewSet):
queryset = models.ACLExtendedRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
"destination_prefix",
"source_prefix", "source_iprange", "source_ipaddress", "source_aggregate", "source_service",
"destination_prefix", "destination_iprange", "destination_ipaddress", "destination_aggregate", "destination_service",
)
serializer_class = ACLExtendedRuleSerializer
filterset_class = filtersets.ACLExtendedRuleFilterSet
45 changes: 43 additions & 2 deletions netbox_acls/filtersets.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,17 @@ class Meta:
"""

model = ACLStandardRule
fields = ("id", "access_list", "index", "action")
fields = (
"id",
"access_list",
"index",
"action",
"source_prefix",
"source_iprange",
"source_ipaddress",
"source_aggregate",
"source_service",
)

def search(self, queryset, name, value):
"""
Expand All @@ -191,6 +201,11 @@ def search(self, queryset, name, value):
Q(access_list__name__icontains=value)
| Q(index__icontains=value)
| Q(action__icontains=value)
| Q(source_prefix__icontains=value)
| Q(source_iprange__icontains=value)
| Q(source_ipaddress__icontains=value)
| Q(source_aggregate__icontains=value)
| Q(source_service__icontains=value)
)
return queryset.filter(query)

Expand All @@ -206,7 +221,23 @@ class Meta:
"""

model = ACLExtendedRule
fields = ("id", "access_list", "index", "action", "protocol")
fields = (
"id",
"access_list",
"index",
"action",
"protocol",
"source_prefix",
"source_iprange",
"source_ipaddress",
"source_aggregate",
"source_service",
"destination_prefix",
"destination_iprange",
"destination_ipaddress",
"destination_aggregate",
"destination_service"
)

def search(self, queryset, name, value):
"""
Expand All @@ -217,5 +248,15 @@ def search(self, queryset, name, value):
| Q(index__icontains=value)
| Q(action__icontains=value)
| Q(protocol__icontains=value)
| Q(source_prefix__icontains=value)
| Q(source_iprange__icontains=value)
| Q(source_ipaddress__icontains=value)
| Q(source_aggregate__icontains=value)
| Q(source_service__icontains=value)
| Q(destination_prefix__icontains=value)
| Q(destination_iprange__icontains=value)
| Q(destination_ipaddress__icontains=value)
| Q(destination_aggregate__icontains=value)
| Q(destination_service__icontains=value)
)
return queryset.filter(query)
Loading