Skip to content

Commit 15fa8ff

Browse files
committed
draft host logic model
1 parent 6fd9fba commit 15fa8ff

File tree

2 files changed

+45
-2
lines changed

2 files changed

+45
-2
lines changed

netbox_acls/models/access_lists.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from dcim.models import Device, Interface, VirtualChassis
66
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
77
from django.contrib.contenttypes.models import ContentType
8+
from django.core.exceptions import ValidationError
89
from django.core.validators import RegexValidator
910
from django.db import models
1011
from django.urls import reverse
@@ -146,6 +147,25 @@ def get_absolute_url(self):
146147
args=[self.pk],
147148
)
148149

150+
def clean(self):
151+
super().clean()
152+
153+
# A list of the possible host objects that an interface can be assigned to.
154+
gfk_host_data = [self.assigned_object.device, self.assigned_object.virtual_machine]
155+
156+
# Check to see if interface is assigned to a device or virtual machine.
157+
interface_host = next(
158+
(host_data for host_data in gfk_host_data if host_data is not None),
159+
None,
160+
)
161+
# Check if the assigned interface's host is the same as the host assigned to the access list.
162+
if interface_host != self.access_list.assigned_object:
163+
raise ValidationError(
164+
{
165+
"assigned_object": "The assigned object must be the same as the device assigned to it."
166+
}
167+
)
168+
149169
@classmethod
150170
def get_prerequisite_models(cls):
151171
return [AccessList]

netbox_acls/tests/test_models.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,15 +190,17 @@ def test_valid_acl_choices(self):
190190
)
191191

192192
for default_action, acl_type in valid_acl_choices:
193-
valid_acl_choice = AccessList(
193+
invalid_acl_choice = AccessList(
194194
name=f"TestACL_Valid_Choice_{default_action}_{acl_type}",
195195
comments=f"VALID ACL CHOICES USED: {default_action=} {acl_type=}",
196196
type=acl_type,
197197
default_action=default_action,
198198
assigned_object_type=ContentType.objects.get_for_model(Device),
199199
assigned_object_id=1, # TODO - replace with Device.objects.first()
200200
)
201-
valid_acl_choice.full_clean()
201+
202+
with self.assertRaises(ValidationError):
203+
invalid_acl_choice.full_clean()
202204

203205
def test_invalid_acl_choices(self):
204206
"""
@@ -284,6 +286,27 @@ def test_acl_interface_assignment_success(self):
284286
)
285287
acl_device_interface.full_clean()
286288

289+
def test_aclinterface_assignment_fail(self):
290+
"""
291+
Test that ACLInterfaceAssignment passes validation if the ACL is assigned to the host and not already assigned to the vminterface and direction.
292+
"""
293+
device_acl = AccessList(
294+
name="STANDARD_ACL",
295+
comments="STANDARD_ACL",
296+
type="standard",
297+
default_action="permit",
298+
assigned_object_id=1,
299+
assigned_object_type=ContentType.objects.get_for_model(Device),
300+
)
301+
vm_acl.save()
302+
acl_vm_interface = ACLInterfaceAssignment(
303+
access_list=device_acl,
304+
direction="ingress",
305+
assigned_object_id=1,
306+
assigned_object_type=ContentType.objects.get_for_model(VMInterface),
307+
)
308+
acl_vm_interface.full_clean()
309+
287310
def test_acl_vminterface_assignment_success(self):
288311
"""
289312
Test that ACLInterfaceAssignment passes validation if the ACL is assigned to the host and not already assigned to the vminterface and direction.

0 commit comments

Comments
 (0)