Skip to content

Commit

Permalink
draft host logic model
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanmerolle committed Feb 6, 2023
1 parent 6fd9fba commit 15fa8ff
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 2 deletions.
20 changes: 20 additions & 0 deletions netbox_acls/models/access_lists.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from dcim.models import Device, Interface, VirtualChassis
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django.db import models
from django.urls import reverse
Expand Down Expand Up @@ -146,6 +147,25 @@ def get_absolute_url(self):
args=[self.pk],
)

def clean(self):
super().clean()

# A list of the possible host objects that an interface can be assigned to.
gfk_host_data = [self.assigned_object.device, self.assigned_object.virtual_machine]

# Check to see if interface is assigned to a device or virtual machine.
interface_host = next(
(host_data for host_data in gfk_host_data if host_data is not None),
None,
)
# Check if the assigned interface's host is the same as the host assigned to the access list.
if interface_host != self.access_list.assigned_object:
raise ValidationError(
{
"assigned_object": "The assigned object must be the same as the device assigned to it."
}
)

@classmethod
def get_prerequisite_models(cls):
return [AccessList]
Expand Down
27 changes: 25 additions & 2 deletions netbox_acls/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,15 +190,17 @@ def test_valid_acl_choices(self):
)

for default_action, acl_type in valid_acl_choices:
valid_acl_choice = AccessList(
invalid_acl_choice = AccessList(
name=f"TestACL_Valid_Choice_{default_action}_{acl_type}",
comments=f"VALID ACL CHOICES USED: {default_action=} {acl_type=}",
type=acl_type,
default_action=default_action,
assigned_object_type=ContentType.objects.get_for_model(Device),
assigned_object_id=1, # TODO - replace with Device.objects.first()
)
valid_acl_choice.full_clean()

with self.assertRaises(ValidationError):
invalid_acl_choice.full_clean()

def test_invalid_acl_choices(self):
"""
Expand Down Expand Up @@ -284,6 +286,27 @@ def test_acl_interface_assignment_success(self):
)
acl_device_interface.full_clean()

def test_aclinterface_assignment_fail(self):
"""
Test that ACLInterfaceAssignment passes validation if the ACL is assigned to the host and not already assigned to the vminterface and direction.
"""
device_acl = AccessList(
name="STANDARD_ACL",
comments="STANDARD_ACL",
type="standard",
default_action="permit",
assigned_object_id=1,
assigned_object_type=ContentType.objects.get_for_model(Device),
)
vm_acl.save()
acl_vm_interface = ACLInterfaceAssignment(
access_list=device_acl,
direction="ingress",
assigned_object_id=1,
assigned_object_type=ContentType.objects.get_for_model(VMInterface),
)
acl_vm_interface.full_clean()

def test_acl_vminterface_assignment_success(self):
"""
Test that ACLInterfaceAssignment passes validation if the ACL is assigned to the host and not already assigned to the vminterface and direction.
Expand Down

0 comments on commit 15fa8ff

Please sign in to comment.