1515from module .netbox import *
1616from module .common .logging import get_logger
1717from module .common .misc import grab
18- from module .sources .common .excluded_vlan import ExcludedVLANName , ExcludedVLANID
18+ from module .sources .common .handle_vlan import FilterVLANByName , FilterVLANByID
1919
2020log = get_logger ()
2121
@@ -247,27 +247,26 @@ def add_update_interface(self, interface_object, device_object, interface_data,
247247
248248 Parameters
249249 ----------
250- interface_object: NBVMInterface, NBInterface, None
250+ interface_object: NBVMInterface | NBInterface | None
251251 object handle of the current interface (if existent, otherwise None)
252- device_object: NBVM, NBDevice
252+ device_object: NBVM | NBDevice
253253 device object handle this interface belongs to
254254 interface_data: dict
255255 dictionary with interface attributes to add to this interface
256256 interface_ips: list
257257 a list of ip addresses which are assigned to this interface
258- vmware_object: ( vim.HostSystem, vim.VirtualMachine)
258+ vmware_object: vim.HostSystem | vim.VirtualMachine
259259 object to add to list of objects to reevaluate
260260
261261 Returns
262262 -------
263- objects: tuple((NBVMInterface, NBInterface), list)
263+ objects:
264+ tuple of NBVMInterface | NBInterface and list
264265 tuple with interface object that was added/updated and a list of ip address objects which were
265266 added to this interface
266267 """
267268
268- ip_tenant_inheritance_order = None
269- if "ip_tenant_inheritance_order" in self .settings :
270- ip_tenant_inheritance_order = self .settings .ip_tenant_inheritance_order
269+ ip_tenant_inheritance_order = self .settings .ip_tenant_inheritance_order
271270
272271 if not isinstance (interface_data , dict ):
273272 log .error (f"Attribute 'interface_data' must be a dict() got { type (interface_data )} ." )
@@ -572,7 +571,7 @@ def add_update_interface(self, interface_object, device_object, interface_data,
572571 f"untagged interface VLAN." )
573572
574573 if matching_untagged_vlan is not None :
575- vlan_interface_data ["untagged_vlan" ] = matching_untagged_vlan
574+ vlan_interface_data ["untagged_vlan" ] = self . add_vlan_group ( matching_untagged_vlan , site_name )
576575 if grab (interface_object , "data.mode" ) is None :
577576 vlan_interface_data ["mode" ] = "access"
578577
@@ -591,7 +590,7 @@ def add_update_interface(self, interface_object, device_object, interface_data,
591590 matching_tagged_vlan = None
592591
593592 if matching_tagged_vlan is not None :
594- compiled_tagged_vlans .append (matching_tagged_vlan )
593+ compiled_tagged_vlans .append (self . add_vlan_group ( matching_tagged_vlan , site_name ) )
595594
596595 if len (compiled_tagged_vlans ) > 0 :
597596 vlan_interface_data ["tagged_vlans" ] = compiled_tagged_vlans
@@ -633,12 +632,68 @@ def patch_data(object_to_patch, data, overwrite=False):
633632
634633 return data_to_update
635634
635+ def add_vlan_group (self , vlan_data , vlan_site ) -> NBVLAN | dict :
636+ """
637+ This function will try to find a matching VLAN group according to the settings.
638+ Name matching will take precedence over ID matching.
639+
640+ If nothing matches the input data from 'vlan_data' will be returned
641+
642+ Parameters
643+ ----------
644+ vlan_data: dict | NBVLAN
645+ A dict or NBVLAN object
646+ vlan_site: str | None
647+ name of site for the VLAN
648+
649+ Returns
650+ -------
651+ NBVLAN | dict: the input vlan_data enriched with VLAN group if a match was found
652+
653+ """
654+
655+ # get VLAN details
656+ if isinstance (vlan_data , NBVLAN ):
657+ vlan_name = grab (vlan_data , "data.name" )
658+ vlan_id = grab (vlan_data , "data.vid" )
659+ elif isinstance (vlan_data , dict ):
660+ vlan_name = vlan_data .get ("name" )
661+ vlan_id = vlan_data .get ("vid" )
662+ else :
663+ return vlan_data
664+
665+ # check existing Devices for matches
666+ log .debug2 (f"Trying to find a matching VLAN Group based on the VLAN name '{ vlan_name } ' and VLAN ID '{ vlan_id } '" )
667+
668+ vlan_group = None
669+ for vlan_filter , vlan_group_name in self .settings .vlan_group_relation_by_name or list ():
670+ if vlan_filter .matches (vlan_name , vlan_site ):
671+ vlan_group = self .inventory .get_by_data (NBVLANGroup , data = {"name" : vlan_group_name })
672+
673+ if vlan_group is None :
674+ for vlan_filter , vlan_group_name in self .settings .vlan_group_relation_by_id or list ():
675+ if vlan_filter .matches (vlan_id , vlan_site ):
676+ vlan_group = self .inventory .get_by_data (NBVLANGroup , data = {"name" : vlan_group_name })
677+
678+ if vlan_group is not None :
679+ log .debug2 (f"Found matching VLAN group '{ vlan_group .get_display_name ()} '" )
680+ if isinstance (vlan_data , NBVLAN ):
681+ vlan_data .update (data = {"group" : vlan_group })
682+ elif isinstance (vlan_data , dict ):
683+ vlan_data ["group" ] = vlan_group
684+ else :
685+ log .debug2 ("No matching VLAN group found" )
686+
687+ print (vlan_data )
688+
689+ return vlan_data
690+
636691 def get_vlan_object_if_exists (self , vlan_data = None , vlan_site = None ):
637692 """
638693 This function will try to find a matching VLAN object based on 'vlan_data'
639694 Will return matching objects in following order:
640- * exact match: VLAN id and site match
641- * global match: VLAN id matches but the VLAN has no site assigned
695+ * exact match: VLAN ID and site match
696+ * global match: VLAN ID matches but the VLAN has no site assigned
642697 If nothing matches the input data from 'vlan_data' will be returned
643698
644699 Parameters
@@ -664,10 +719,10 @@ def get_vlan_object_if_exists(self, vlan_data=None, vlan_site=None):
664719 raise ValueError ("Value of 'vlan_data' needs to be a dict." )
665720
666721 # check existing Devices for matches
667- log .debug2 (f"Trying to find a { NBVLAN .name } based on the VLAN id '{ vlan_data .get ('vid' )} '" )
722+ log .debug2 (f"Trying to find a { NBVLAN .name } based on the VLAN ID '{ vlan_data .get ('vid' )} '" )
668723
669724 if vlan_data .get ("vid" ) is None :
670- log .debug ("No VLAN id set in vlan_data while trying to find matching VLAN." )
725+ log .debug ("No VLAN ID set in vlan_data while trying to find matching VLAN." )
671726 return vlan_data
672727
673728 if vlan_site is None :
@@ -703,7 +758,7 @@ def get_vlan_object_if_exists(self, vlan_data=None, vlan_site=None):
703758 vlan_object_without_site .get_display_name (including_second_key = True )))
704759
705760 else :
706- log .debug2 ("No matching existing VLAN found for this VLAN id ." )
761+ log .debug2 ("No matching existing VLAN found for this VLAN ID ." )
707762
708763 return return_data
709764
@@ -724,25 +779,14 @@ def add_vlan_object_to_netbox(self, vlan_data, site_name=None):
724779
725780 """
726781
727- # get config data
728- disable_vlan_sync = False
729- vlan_sync_exclude_by_name : List [ExcludedVLANName ] = list ()
730- vlan_sync_exclude_by_id : List [ExcludedVLANID ] = list ()
731- if "disable_vlan_sync" in self .settings :
732- disable_vlan_sync = self .settings .disable_vlan_sync
733- if "vlan_sync_exclude_by_name" in self .settings :
734- vlan_sync_exclude_by_name = self .settings .vlan_sync_exclude_by_name
735- if "vlan_sync_exclude_by_id" in self .settings :
736- vlan_sync_exclude_by_id = self .settings .vlan_sync_exclude_by_id
737-
738782 # VLAN is already an existing NetBox VLAN, then it can be reused
739783 if isinstance (vlan_data , NetBoxObject ):
740784 return True
741785
742786 if vlan_data is None :
743787 return False
744788
745- if disable_vlan_sync is True :
789+ if self . settings . disable_vlan_sync is True :
746790 return False
747791
748792 # get VLAN details
@@ -757,11 +801,11 @@ def add_vlan_object_to_netbox(self, vlan_data, site_name=None):
757801 log .warning (f"Skipping sync of invalid VLAN '{ vlan_name } ' ID: '{ vlan_id } '" )
758802 return False
759803
760- for excluded_vlan in vlan_sync_exclude_by_name or list ():
804+ for excluded_vlan in self . settings . vlan_sync_exclude_by_name or list ():
761805 if excluded_vlan .matches (vlan_name , site_name ):
762806 return False
763807
764- for excluded_vlan in vlan_sync_exclude_by_id or list ():
808+ for excluded_vlan in self . settings . vlan_sync_exclude_by_id or list ():
765809 if excluded_vlan .matches (vlan_id , site_name ):
766810 return False
767811
0 commit comments