def convert_cisco_genie_lldp_neighbors_details(device_name, data): """Convert the data returned by Genie for show lldp neighbors detail to Neighbors(). Args: device_name (str): the name of the device where the data was collected data (Dict): the parsed data returned by Genie Returns: Neighbors: List of neighbors in a Pydantic model """ results = Neighbors() if "interfaces" not in data: return results for intf_name, intf_data in data["interfaces"].items(): if "port_id" not in intf_data.keys(): continue # intf_name = canonical_interface_name(intf_name) for nei_intf_name in list(intf_data["port_id"].keys()): # nei_intf_name_long = canonical_interface_name(nei_intf_name) if is_interface_lag(nei_intf_name): LOGGER.debug( "%s | Neighbors, %s is connected to %s but is not a valid interface (lag), SKIPPING", device_name, nei_intf_name, intf_name, ) continue if "neighbors" not in intf_data["port_id"][nei_intf_name]: LOGGER.debug("%s | No neighbor found for %s connected to %s", device_name, nei_intf_name, intf_name) continue if len(intf_data["port_id"][nei_intf_name]["neighbors"]) > 1: LOGGER.warning( "%s | More than 1 neighbor found for %s connected to %s, SKIPPING", device_name, nei_intf_name, intf_name, ) continue neighbor = Neighbor(hostname=list( intf_data["port_id"][nei_intf_name]["neighbors"].keys())[0], port=nei_intf_name) results.neighbors[intf_name].append(neighbor) return results
def convert_cisco_genie_cdp_neighbors_details(device_name, data): """Convert the data returned by Genie for show cdp neighbors detail to Neighbors(). Args: device_name (str): the name of the device where the data was collected data (Dict): the parsed data returned by Genie Returns: Neighbors: List of neighbors in a Pydantic model """ results = Neighbors() if "index" not in data: return results for _, intf_data in data["index"].items(): intf_name = intf_data.get("local_interface", None) nei_intf_name = intf_data.get("port_id", None) neighbor_name = intf_data.get("device_id", None) if not intf_name or not nei_intf_name or not neighbor_name: continue if is_interface_lag(nei_intf_name): LOGGER.debug( "%s | Neighbors, %s is connected to %s but is not a valid interface (lag), SKIPPING", device_name, nei_intf_name, intf_name, ) continue neighbor = Neighbor(hostname=neighbor_name, port=nei_intf_name) results.neighbors[intf_name].append(neighbor) # Ensure each interface no not have more than 1 neighbor for intf_name, value in results.neighbors.items(): if len(value) == 1: continue LOGGER.warning( "%s | More than 1 neighbor found for %s, SKIPPING", device_name, intf_name, ) results.neighbors[intf_name] = [] return results
def add_batfish_interface(self, bf): """ Add a Batfish Interface Object and extract all relevant information if not already defined Input Batfish interfaceProperties object Args: bf: Returns: """ self.bf = bf if not self.local: self.local = Interface(name=self.name) self.local.device_name = self.device_name is_physical = is_interface_physical(self.name) is_lag = is_interface_lag(self.name) if is_lag: self.local.is_lag = True self.local.is_virtual = False elif is_physical == False: # pylint: disable=C0121 self.local.is_virtual = True else: self.local.is_virtual = False if is_physical and self.local.speed: self.local.speed = int(bf.Speed) if self.local.mtu is None: self.mtu = bf.MTU if self.local.switchport_mode is None: self.local.switchport_mode = bf.Switchport_Mode if self.local.switchport_mode == "FEX_FABRIC": self.local.switchport_mode = "NONE" if self.local.active is None and config.main["import_intf_status"]: self.local.active = bf.Active elif not config.main["import_intf_status"]: self.local.active = None if self.local.description is None and bf.Description: self.local.description = bf.Description elif self.local.description is None: self.local.description = "" if (self.local.is_lag is None and self.local.lag_members is None and len(list(bf.Channel_Group_Members)) != 0): self.local.lag_members = list(bf.Channel_Group_Members) self.local.is_lag = True self.local.is_virtual = False elif self.local.is_lag is None: self.local.is_lag = False if self.local.mode is None and self.local.switchport_mode: if bf.Encapsulation_VLAN: self.local.mode = "L3_SUB_VLAN" self.local.allowed_vlans = [bf.Encapsulation_VLAN] else: self.local.mode = self.local.switchport_mode if self.local.mode == "TRUNK": self.local.allowed_vlans = expand_vlans_list(bf.Allowed_VLANs) if bf.Native_VLAN: self.local.access_vlan = bf.Native_VLAN elif self.local.mode == "ACCESS" and bf.Access_VLAN: self.local.access_vlan = bf.Access_VLAN if (self.local.is_lag is False and self.local.is_lag_member is None and bf.Channel_Group): self.local.parent = bf.Channel_Group self.local.is_lag_member = True self.local.is_virtual = False
def test_is_interface_lag(): # pylint: disable=C0121 """ Test is_interface_log """ assert is_interface_lag("port-channel100") is True assert is_interface_lag("Port-Channel100") is True assert is_interface_lag("ae0") is True assert is_interface_lag("ae0.100") is None assert is_interface_lag("Port-Channel100") is True assert is_interface_lag("Port-Channel100.100") is None assert is_interface_lag("GigabitEthernet0/0/2") is None assert is_interface_lag("GigabitEthernet0/0/2.890") is None assert is_interface_lag("GigabitEthernet0/0/2.1") is None assert is_interface_lag("Ethernet0.1") is None assert is_interface_lag("Ethernet1") is None assert is_interface_lag("Serial0/1/0:15") is None assert is_interface_lag("Service-Engine0/1/0") is None assert is_interface_lag("Service-Engine0/1/0.152") is None assert is_interface_lag("GigabitEthernet0") is None assert is_interface_lag("ge-0/0/0") is None assert is_interface_lag("ge-0/0/0.10") is None assert is_interface_lag("lo0.0") is None assert is_interface_lag("Loopback1") is None assert is_interface_lag("Vlan108") is None assert is_interface_lag("Management0/0") is None
def load_batfish_interface(self, site, device, intf, interface_vlans=[]): # pylint: disable=dangerous-default-value,unused-argument,too-many-statements,too-many-branches,too-many-locals """Load an interface for a given device from Batfish Data, including IP addresses and prefixes. Args: site (Site): Site object device (Device): Device object intf (dict): Batfish interface object in Dict format interface_vlans (list[str], optional): List of vlan uis associated with this interface Returns: Interface """ # try: # self._check_batfish_interface_is_valid(intf) # except BatfishObjectNotValid as exc: # LOGGER.warning("Unable to add an interface on %s, the data is not valid (%s)", device.name, str(exc)) # return False # Since it's possible to import vlans from the config and or from the CLI, we need to track 2 differents flags # import_vlans = import the vlans information to the interface, populate allowed_vlans, access_vlan and mode # create_vlans = create the vlans object import_vlans = create_vlans = False if config.SETTINGS.main.import_vlans in ["config", True, "yes"]: create_vlans = True if config.SETTINGS.main.import_vlans not in [False, "no"]: import_vlans = True interface = self.interface( name=intf["Interface"].interface, device_name=device.name, mtu=intf["MTU"], switchport_mode=intf["Switchport_Mode"], ) if "Description" in intf and intf["Description"]: interface.description = intf["Description"].strip() is_physical = is_interface_physical(interface.name) is_lag = is_interface_lag(interface.name) if is_lag: interface.is_lag = True interface.is_virtual = False elif is_physical is False: # pylint: disable=C0121 interface.is_virtual = True else: interface.is_virtual = False if interface.switchport_mode == "FEX_FABRIC": interface.switchport_mode = "NONE" if config.SETTINGS.main.import_intf_status: interface.active = intf["Active"] elif not config.SETTINGS.main.import_intf_status: interface.active = None if interface.is_lag is None and interface.lag_members is None and len( list(intf["Channel_Group_Members"])) != 0: interface.lag_members = list(intf["Channel_Group_Members"]) interface.is_lag = True interface.is_virtual = False elif interface.is_lag is None: interface.is_lag = False if interface.mode is None and interface.switchport_mode: if intf["Encapsulation_VLAN"]: interface.mode = "L3_SUB_VLAN" vlan = self.vlan(vid=intf["Encapsulation_VLAN"], site_name=site.name) vlan, _ = self.get_or_create_vlan(vlan, site) if import_vlans: interface.allowed_vlans = [vlan.get_unique_id()] interface_vlans = interface.allowed_vlans else: interface.mode = interface.switchport_mode if interface.mode == "TRUNK": vids = expand_vlans_list(intf["Allowed_VLANs"]) for vid in vids: vlan = self.vlan(vid=vid, site_name=site.name) if create_vlans: vlan, _ = self.get_or_create_vlan(vlan, site) if import_vlans: interface.allowed_vlans.append(vlan.get_unique_id()) interface_vlans = interface.allowed_vlans if intf["Native_VLAN"]: native_vlan = self.vlan(vid=intf["Native_VLAN"], site_name=site.name) if create_vlans: native_vlan, _ = self.get_or_create_vlan(native_vlan) if import_vlans: interface.access_vlan = native_vlan.get_unique_id() interface_vlans = [interface.access_vlan] elif interface.mode == "ACCESS" and intf["Access_VLAN"]: vlan = self.vlan(vid=intf["Access_VLAN"], site_name=site.name) if create_vlans: vlan, _ = self.get_or_create_vlan(vlan, site) if import_vlans: interface.access_vlan = vlan.get_unique_id() interface_vlans = [interface.access_vlan] if interface.is_lag is False and interface.is_lag_member is None and intf[ "Channel_Group"]: interface.parent = self.interface( name=intf["Channel_Group"], device_name=device.name).get_unique_id() interface.is_lag_member = True interface.is_virtual = False self.add(interface) device.add_child(interface) if "All_Prefixes" not in intf: return interface for prefix in intf["All_Prefixes"]: self.load_batfish_ip_address(site=site, device=device, interface=interface, address=prefix, interface_vlans=interface_vlans) return interface