From eb44575e928c9221ab9844d1efd5dc2272e42ead Mon Sep 17 00:00:00 2001 From: ryanmerolle Date: Tue, 7 Feb 2023 05:09:59 +0000 Subject: [PATCH] draft host logic model --- netbox_acls/models/access_lists.py | 17 +++++++ netbox_acls/tests/test_models.py | 79 ++++++++++++++++++------------ 2 files changed, 66 insertions(+), 30 deletions(-) diff --git a/netbox_acls/models/access_lists.py b/netbox_acls/models/access_lists.py index e65f765..31185ef 100644 --- a/netbox_acls/models/access_lists.py +++ b/netbox_acls/models/access_lists.py @@ -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 @@ -146,6 +147,22 @@ def get_absolute_url(self): args=[self.pk], ) + def clean(self): + super().clean() + + # Get the model type of the assigned interface. + if self.assigned_object_type.model_class() == VMInterface: + interface_host = self.assigned_object.virtual_machine + elif self.assigned_object_type.model_class() == Interface: + interface_host = self.assigned_object.device + # 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] diff --git a/netbox_acls/tests/test_models.py b/netbox_acls/tests/test_models.py index 76fd701..8816b84 100644 --- a/netbox_acls/tests/test_models.py +++ b/netbox_acls/tests/test_models.py @@ -51,27 +51,28 @@ def setUpTestData(cls): device_type=devicetype, device_role=devicerole, ) - virtual_chassis = VirtualChassis.objects.create(name="Virtual Chassis 1") - virtual_chassis_member = Device.objects.create( - name="VC Device", - site=site, - device_type=devicetype, - device_role=devicerole, - virtual_chassis=virtual_chassis, - vc_position=1, - ) - cluster_member = Device.objects.create( - name="Cluster Device", - site=site, - device_type=devicetype, - device_role=devicerole, - ) - clustertype = ClusterType.objects.create(name="Cluster Type 1") - cluster = Cluster.objects.create( - name="Cluster 1", - type=clustertype, - ) + # virtual_chassis = VirtualChassis.objects.create(name="Virtual Chassis 1") + # virtual_chassis_member = Device.objects.create( + # name="VC Device", + # site=site, + # device_type=devicetype, + # device_role=devicerole, + # virtual_chassis=virtual_chassis, + # vc_position=1, + # ) + # cluster_member = Device.objects.create( + # name="Cluster Device", + # site=site, + # device_type=devicetype, + # device_role=devicerole, + # ) + # clustertype = ClusterType.objects.create(name="Cluster Type 1") + # cluster = Cluster.objects.create( + # name="Cluster 1", + # type=clustertype, + # ) virtual_machine = VirtualMachine.objects.create(name="VirtualMachine 1") + virtual_machine.save() prefix = Prefix.objects.create(prefix="10.0.0.0/8") @@ -256,12 +257,12 @@ def setUpTestData(cls): VMInterface(name="Interface 2", virtual_machine=virtual_machine), ) ) - prefixes = Prefix.objects.bulk_create( - ( - Prefix(prefix=IPNetwork("10.0.0.0/24")), - Prefix(prefix=IPNetwork("192.168.1.0/24")), - ) - ) + #prefixes = Prefix.objects.bulk_create( + # ( + # Prefix(prefix=IPNetwork("10.0.0.0/24")), + # Prefix(prefix=IPNetwork("192.168.1.0/24")), + # ) + #) def test_acl_interface_assignment_success(self): """ @@ -272,18 +273,36 @@ def test_acl_interface_assignment_success(self): comments="STANDARD_ACL", type="standard", default_action="permit", - assigned_object_id=1, - assigned_object_type=ContentType.objects.get_for_model(Device), + assigned_object=Device.objects.first(), ) device_acl.save() acl_device_interface = ACLInterfaceAssignment( access_list=device_acl, direction="ingress", - assigned_object_id=1, - assigned_object_type=ContentType.objects.get_for_model(Interface), + assigned_object=Interface.objects.first(), ) 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=Device.objects.first(), + ) + device_acl.save() + acl_vm_interface = ACLInterfaceAssignment( + access_list=device_acl, + direction="ingress", + assigned_object=VMInterface.objects.first(), + ) + with self.assertRaises(ValidationError): + 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.