@@ -182,24 +182,24 @@ def clean(self):
182182 acl_type = cleaned_data .get ("type" )
183183
184184 # Check if more than one host type selected.
185- host_types = self .get_host_types ()
185+ host_types = self ._get_host_types ()
186186
187187 # Check if no hosts selected.
188- self .validate_host_types (host_types )
188+ self ._validate_host_types (host_types )
189189
190190 host_type , host = host_types [0 ]
191191
192192 # Check if duplicate entry.
193- self .validate_duplicate_entry (name , host_type , host , error_message )
193+ self ._validate_duplicate_entry (name , host_type , host , error_message )
194194 # Check if Access List has no existing rules before change the Access List's type.
195- self .validate_acl_type_change (acl_type , error_message )
195+ self ._validate_acl_type_change (acl_type , error_message )
196196
197197 if error_message :
198198 raise forms .ValidationError (error_message )
199199
200200 return cleaned_data
201201
202- def get_host_types (self ):
202+ def _get_host_types (self ):
203203 """
204204 Get host type assigned to the Access List.
205205 """
@@ -213,7 +213,7 @@ def get_host_types(self):
213213 ]
214214 return [x for x in host_types if x [1 ]]
215215
216- def validate_host_types (self , host_types ):
216+ def _validate_host_types (self , host_types ):
217217 """
218218 Check number of host types selected.
219219 """
@@ -227,7 +227,7 @@ def validate_host_types(self, host_types):
227227 "Access Lists must be assigned to a device, virtual chassis or virtual machine." ,
228228 )
229229
230- def validate_duplicate_entry (self , name , host_type , host , error_message ):
230+ def _validate_duplicate_entry (self , name , host_type , host , error_message ):
231231 """
232232 Check if duplicate entry. (Because of GFK.)
233233 """
@@ -246,7 +246,7 @@ def validate_duplicate_entry(self, name, host_type, host, error_message):
246246 "name" : [error_same_acl_name ],
247247 }
248248
249- def validate_acl_type_change (self , acl_type , error_message ):
249+ def _validate_acl_type_change (self , acl_type , error_message ):
250250 """
251251 Check if Access List has no existing rules before change the Access List's type.
252252 """
@@ -374,6 +374,7 @@ class Meta:
374374 ),
375375 }
376376
377+
377378 def clean (self ):
378379 """
379380 Validates form inputs before submitting:
@@ -384,87 +385,126 @@ def clean(self):
384385 - Check for duplicate entry. (Because of GFK)
385386 - Check that the interface does not have an existing ACL applied in the direction already.
386387 """
388+ # Call the parent class's `clean` method
387389 cleaned_data = super ().clean ()
388- error_message = {}
389- access_list = cleaned_data .get ("access_list" )
390- direction = cleaned_data .get ("direction" )
391- interface = cleaned_data .get ("interface" )
392- vminterface = cleaned_data .get ("vminterface" )
393-
394- # Check if both interface and vminterface are set.
395- if interface and vminterface :
396- error_too_many_interfaces = "Access Lists must be assigned to one type of interface at a time (VM interface or physical interface)"
397- error_message |= {
398- "interface" : [error_too_many_interfaces ],
399- "vminterface" : [error_too_many_interfaces ],
400- }
401- elif not (interface or vminterface ):
402- error_no_interface = (
403- "An Access List assignment but specify an Interface or VM Interface."
404- )
405- error_message |= {
406- "interface" : [error_no_interface ],
407- "vminterface" : [error_no_interface ],
408- }
409- else :
410- if interface :
411- assigned_object = interface
412- assigned_object_type = "interface"
413- host_type = "device"
390+
391+ # Get the interface types assigned to the Access List
392+ interface_types = self ._get_interface_types ()
393+
394+ # Initialize an error message variable
395+ error_message = self ._validate_interface_types (interface_types )
396+
397+ if not error_message :
398+ assigned_object_type , assigned_object = interface_types [0 ]
399+ host_type = ("device" if assigned_object_type == "interface" else "virtual_machine" )
400+
401+ # Get the parent host (device or virtual machine) of the assigned interface
402+ if assigned_object_type == "interface" :
414403 host = Interface .objects .get (pk = assigned_object .pk ).device
415404 assigned_object_id = Interface .objects .get (pk = assigned_object .pk ).pk
416405 else :
417- assigned_object = vminterface
418- assigned_object_type = "vminterface"
419- host_type = "virtual_machine"
420406 host = VMInterface .objects .get (pk = assigned_object .pk ).virtual_machine
421407 assigned_object_id = VMInterface .objects .get (pk = assigned_object .pk ).pk
422408
423- assigned_object_type_id = ContentType .objects .get_for_model (
424- assigned_object ,
425- ).pk
426- access_list_host = AccessList .objects .get (pk = access_list .pk ).assigned_object
427-
428- # Check that an interface's parent device/virtual_machine is assigned to the Access List.
429- if access_list_host != host :
430- error_acl_not_assigned_to_host = (
431- "Access List not present on selected host."
432- )
433- error_message |= {
434- "access_list" : [error_acl_not_assigned_to_host ],
435- assigned_object_type : [error_acl_not_assigned_to_host ],
436- host_type : [error_acl_not_assigned_to_host ],
437- }
438- # Check for duplicate entry.
439- if ACLInterfaceAssignment .objects .filter (
440- access_list = access_list ,
441- assigned_object_id = assigned_object_id ,
442- assigned_object_type = assigned_object_type_id ,
443- direction = direction ,
444- ).exists ():
445- error_duplicate_entry = "An ACL with this name is already associated to this interface & direction."
446- error_message |= {
447- "access_list" : [error_duplicate_entry ],
448- "direction" : [error_duplicate_entry ],
449- assigned_object_type : [error_duplicate_entry ],
450- }
451- # Check that the interface does not have an existing ACL applied in the direction already.
452- if ACLInterfaceAssignment .objects .filter (
453- assigned_object_id = assigned_object_id ,
454- assigned_object_type = assigned_object_type_id ,
455- direction = direction ,
456- ).exists ():
457- error_interface_already_assigned = (
458- "Interfaces can only have 1 Access List assigned in each direction."
459- )
460- error_message |= {
461- "direction" : [error_interface_already_assigned ],
462- assigned_object_type : [error_interface_already_assigned ],
463- }
409+ # Get the ContentType id for the assigned object
410+ assigned_object_type_id = ContentType .objects .get_for_model (assigned_object ).pk
411+
412+ if not error_message :
413+ # Check if the parent host is assigned to the Access List
414+ error_message |= self ._check_if_interface_parent_is_assigned_to_access_list (cleaned_data .get ("access_list" ), assigned_object_type , host_type , host )
415+
416+ if not error_message :
417+ # Check for duplicate entries in the Access List
418+ error_message |= self ._check_for_duplicate_entry (cleaned_data .get ("access_list" ), assigned_object_id , assigned_object_type_id , cleaned_data .get ("direction" ),)
419+
420+ if not error_message :
421+ # Check if the interface already has an ACL applied in the specified direction
422+ error_message |= self ._check_if_interface_already_has_acl_in_direction (assigned_object_id , assigned_object_type_id , cleaned_data .get ("direction" ))
464423
465424 if error_message :
466425 raise forms .ValidationError (error_message )
467- return cleaned_data
426+ else :
427+ return cleaned_data
428+
429+
430+ def _get_interface_types (self ):
431+ """
432+ Get interface type/model assigned to the Access List.
433+ """
434+ interface = self .cleaned_data .get ("interface" )
435+ vminterface = self .cleaned_data .get ("vminterface" )
436+ interface_types = [
437+ ("interface" , interface ),
438+ ("vminterface" , vminterface ),
439+ ]
440+ return [x for x in interface_types if x [1 ]]
441+
442+ def _validate_interface_types (self , interface_types ):
443+ """
444+ Check if number of interface type selected is 1.
445+ """
446+ # Check if more than 1 hosts selected.
447+ if len (interface_types ) > 1 :
448+ return "Assignment can only be to one interface at a time (either a interface or vm_interface)."
449+ # Check if no hosts selected.
450+ elif not interface_types :
451+ return "No interface or vm_interface selected."
452+ else :
453+ return {}
454+
455+ def _check_if_interface_parent_is_assigned_to_access_list (self , access_list , assigned_object_type , host_type , host ):
456+ """
457+ Check that an interface's parent device/virtual_machine is assigned to the Access List.
458+ """
459+
460+ access_list_host = AccessList .objects .get (pk = access_list .pk ).assigned_object
461+
462+ if access_list_host != host :
463+ ERROR_ACL_NOT_ASSIGNED_TO_HOST = (
464+ "Access List not present on selected host."
465+ )
466+ return {
467+ "access_list" : [ERROR_ACL_NOT_ASSIGNED_TO_HOST ],
468+ assigned_object_type : [ERROR_ACL_NOT_ASSIGNED_TO_HOST ],
469+ host_type : [ERROR_ACL_NOT_ASSIGNED_TO_HOST ],
470+ }
471+ else :
472+ return {}
473+
474+ def _check_for_duplicate_entry (self , access_list , assigned_object_id , assigned_object_type_id , direction ):
475+ """
476+ Check for duplicate entry. (Because of GFK)
477+ """
478+
479+ if ACLInterfaceAssignment .objects .filter (
480+ access_list = access_list ,
481+ assigned_object_id = assigned_object_id ,
482+ assigned_object_type = assigned_object_type_id ,
483+ direction = direction ,
484+ ).exists ():
485+ return {"access_list" : ["Duplicate entry." ]}
486+ else :
487+ return {}
488+
489+ def _check_if_interface_already_has_acl_in_direction (self , assigned_object_id , assigned_object_type_id , direction ):
490+ """
491+ Check that the interface does not have an existing ACL applied in the direction already.
492+ """
493+ if ACLInterfaceAssignment .objects .filter (
494+ assigned_object_id = assigned_object_id ,
495+ assigned_object_type = assigned_object_type_id ,
496+ direction = direction ,
497+ ).exists ():
498+ error_interface_already_assigned = (
499+ "Interfaces can only have 1 Access List assigned in each direction."
500+ )
501+ return {
502+ "direction" : [error_interface_already_assigned ],
503+ assigned_object_type : [error_interface_already_assigned ],
504+ }
505+ else :
506+ return {}
507+
468508
469509 def save (self , * args , ** kwargs ):
470510 """
0 commit comments