Пример #1
0
def has_vlan(vlan_filter, vlan):
    """
    Check VLAN is within vlan_filter
    :param vlan_filter:
    :param vlan:
    :return:
    """
    if not isinstance(vlan, int):
        vlan = int(vlan)
    if not is_vlan(vlan):
        return False
    for p in vlan_filter.split(","):
        p = p.strip()
        if not p:
            continue
        if "-" in p:
            # Range
            match = rx_range.match(p)
            if match:
                try:
                    f, t = [int(x) for x in match.groups()]
                    if f <= vlan <= t:
                        return True
                except ValueError:
                    pass
        else:
            # Single value
            try:
                v = int(p)
                if v == vlan:
                    return True
            except ValueError:
                pass
    return False
Пример #2
0
 def get_switchport(
         self) -> DefaultDict[int, Dict[str, Union[int, list, None]]]:
     result = defaultdict(lambda: {
         "tagged_vlans": [],
         "untagged_vlan": None
     })
     pid_ifindex_mappings = self.get_bridge_ifindex_mappings()
     self.logger.debug("PID <-> ifindex mappings: %s", pid_ifindex_mappings)
     for oid, pvid in self.snmp.getnext(
             mib["Q-BRIDGE-MIB::dot1qPvid"],
             max_repetitions=self.get_max_repetitions(),
             max_retries=self.get_getnext_retires(),
             timeout=self.get_snmp_timeout(),
     ):
         if not pvid:
             # if pvid is 0
             continue
         elif not is_vlan(pvid):
             # on Alcatel DSLAM it 16777217
             self.logger.warning(
                 "Bad value for untagged vlan.Skipping.. oid %s: vlan %s",
                 oid, pvid)
             continue
         o = int(oid.split(".")[-1])
         if o in pid_ifindex_mappings:
             o = pid_ifindex_mappings[o]
         else:
             self.logger.warning(
                 "PortID %s not in ifindex mapping. Use as is", o)
         result[o]["untagged_vlan"] = pvid
     for oid, ports_mask in self.snmp.getnext(
             mib["Q-BRIDGE-MIB::dot1qVlanCurrentEgressPorts"],
             max_repetitions=self.get_max_repetitions(),
             max_retries=self.get_getnext_retires(),
             display_hints={
                 mib["Q-BRIDGE-MIB::dot1qVlanCurrentEgressPorts"]:
                 render_bin
             },
             timeout=self.get_snmp_timeout(),
     ):
         vlan_num = int(oid.split(".")[-1])
         # Getting port as mask,  convert to vlan: Iface list
         for port, is_egress in enumerate(chain.from_iterable(
                 "{0:08b}".format(mask) for mask in ports_mask),
                                          start=1):
             if is_egress == "0":
                 continue
             elif port not in pid_ifindex_mappings:
                 self.logger.error("Port %s not in PID mappings", port)
                 continue
             elif vlan_num == result[
                     pid_ifindex_mappings[port]]["untagged_vlan"]:
                 continue
             result[pid_ifindex_mappings[port]]["tagged_vlans"] += [
                 vlan_num
             ]
     return result
Пример #3
0
 def execute_snmp(self, interface=None, vlan=None, mac=None):
     r = []
     iface_map = self.get_iface_mapping()
     self.logger.debug("Interface map: %s", iface_map)
     port_oid = mib["Q-BRIDGE-MIB::dot1qTpFdbPort"]
     status_oid = mib["Q-BRIDGE-MIB::dot1qTpFdbStatus"]
     if vlan:
         port_oid = mib["Q-BRIDGE-MIB::dot1qTpFdbPort", vlan]
         status_oid = mib["Q-BRIDGE-MIB::dot1qTpFdbStatus", vlan]
     mac_port = {}
     for r_oid, iface in self.snmp.getnext(
             port_oid,
             max_repetitions=self.get_max_repetitions(),
             max_retries=self.get_getnext_retires(),
             bulk=self.get_bulk(),
     ):
         if not iface:
             # For iface == 0
             continue
         r_oid = tuple(r_oid.rsplit(".", 7)[-7:])
         if iface not in iface_map:
             self.logger.error(
                 "Unknown interface index %s, for MAC: %s",
                 iface,
                 ":".join("%02x" % int(c) for c in r_oid[1:]),
             )
             continue
         iface = iface_map[iface]
         if interface and iface != interface:
             continue
         mac_port[r_oid] = iface
     # Apply status
     for r_oid, status in self.snmp.getnext(
             status_oid,
             max_repetitions=self.get_max_repetitions(),
             max_retries=self.get_getnext_retires(),
             bulk=self.get_bulk(),
     ):
         r_oid = tuple(r_oid.rsplit(".", 7)[-7:])
         if r_oid not in mac_port:
             continue
         vlan_id, mac = r_oid[0], ":".join("%02x" % int(c)
                                           for c in r_oid[1:])
         # Some devices return CPU/management vlan as 0
         if vlan_id != "0" and not is_vlan(vlan_id):
             # Found vlan `4155` on Eltex MES-3124F fw 2.5.48.6
             self.logger.error(
                 "Invalid vlan number %s, for MAC: %s, Port: %s", vlan_id,
                 mac, mac_port[r_oid])
             continue
         r += [{
             "interfaces": [mac_port[r_oid]],
             "mac": mac,
             "type": self.mac_status_map[status],
             "vlan_id": max(int(vlan_id), 1),
         }]
     return r
Пример #4
0
    def execute_cli(self):
        # Get switchports and fill tagged/untagged lists if they are not empty
        switchports = self.get_switchport_cli()
        # Get portchannels
        portchannel_members = {}
        for pc in self.scripts.get_portchannel():
            i = pc["interface"]
            t = pc["type"] == "L"
            for m in pc["members"]:
                portchannel_members[m] = (i, t)
        # Get IPv4 interfaces
        ipv4_interfaces = defaultdict(list)  # interface -> [ipv4 addresses]
        c_iface = None
        for line in self.cli("display ip interface").splitlines():
            match = self.rx_dis_ip_int.search(line)
            if match:
                c_iface = self.profile.convert_interface_name(match.group("interface"))
                continue
            # Primary ip
            match = self.rx_ip.search(line)
            if not match:
                continue
            ip = match.group("ip")
            ipv4_interfaces[c_iface] += [ip]
        #
        interfaces = {}
        # Get OSPF interfaces
        ospfs = self.get_ospfint()
        # Get NDP interfaces
        ndps = self.get_ndpint()
        # Get ifindexes
        ifindexes = self.get_ifindex()
        # Get STP interfaces
        stps = self.get_stpint()
        # Get LLDP interfaces
        lldps = self.get_lldpint()
        # Get VRRP interfaces
        vrrps = self.get_vrrpint()

        v = self.cli("display interface", cached=True)
        il = self.rx_iface_sep.split(v)[1:]
        for full_ifname, data in zip(il[::2], il[1::2]):
            ifname = self.profile.convert_interface_name(full_ifname)
            if ifname.startswith("NULL"):
                continue
            # I do not known, what are these
            if ifname.startswith("DCN-Serial") or ifname.startswith("Cpos-Trunk"):
                continue
            sub = {
                "name": ifname,
                "admin_status": True,
                "oper_status": True,
                "enabled_protocols": [],
                "enabled_afi": [],
            }
            if ifname in switchports and ifname not in portchannel_members:
                # Bridge
                sub["enabled_afi"] += ["BRIDGE"]
                u, t = switchports[ifname]["untagged"], switchports[ifname].get("tagged")
                if u:
                    sub["untagged_vlan"] = u
                if t:
                    sub["tagged_vlans"] = t
            elif ifname in ipv4_interfaces:
                # IPv4
                sub["enabled_afi"] = ["IPv4"]
                sub["ipv4_addresses"] = ipv4_interfaces[ifname]
            if ifname in ospfs:
                # OSPF
                sub["enabled_protocols"] += ["OSPF"]
            if ifname.lower().startswith("vlanif"):
                # SVI
                sub["vlan_ids"] = [int(ifname[6:].strip())]
            if ifname.lower().startswith("vlan-interface"):
                # SVI
                sub["vlan_ids"] = [int(ifname[14:].strip())]
            # Parse data
            ifindex = self.rx_inline_ifindex.search(data)
            a_stat, data = data.split("\n", 1)
            a_stat = a_stat.lower().endswith("up")
            o_stat = None
            for line in data.splitlines():
                line = line.strip()
                # Oper. status
                if o_stat is None:
                    match = self.rx_line_proto.search(line)
                    if match:
                        o_stat = match.group("o_state").lower().endswith("up")
                        continue
                # Process description
                if line.startswith("Description:"):
                    d = line[12:].strip()
                    if d != "---":
                        sub["description"] = d
                    continue
                # Process description
                if line.startswith("Description :"):
                    d = line[13:].strip()
                    if d != "---":
                        sub["description"] = d
                    continue
                # MAC
                if not sub.get("mac"):
                    match = self.rx_mac.search(line)
                    if match and match.group("mac") != "0000-0000-0000":
                        sub["mac"] = match.group("mac")
                        continue
                # Static vlans
                match = self.rx_pvid.search(line)
                if match and "untagged_vlan" not in sub:
                    sub["untagged_vlan"] = int(match.group("pvid"))
                    if "BRIDGE" not in sub["enabled_afi"]:
                        sub["enabled_afi"] += ["BRIDGE"]
                    continue
                # Static vlans
                if line.startswith("Encapsulation "):
                    enc = line[14:]
                    if enc.startswith("802.1Q"):
                        sub["vlan_ids"] = [enc.split(",")[2].split()[2]]
                    continue
                # MTU
                match = self.rx_mtu.search(line)
                if match:
                    sub["mtu"] = int(match.group("mtu"))
                    continue
                # IP Unnumbered
                match = self.rx_ipv4_unnumb.search(line)
                if match:
                    sub["ip_unnumbered_subinterface"] = match.group("iface")
                    sub["enabled_afi"] = ["IPv4"]
                    continue
            if "." not in ifname:
                if o_stat is None:
                    o_stat = False
                match = self.rx_iftype.match(ifname)
                iftype = self.profile.get_interface_type(match.group(1))
                if iftype is None:
                    self.logger.info("Iface name %s, type unknown", match.group(1))
                    continue  # Skip ignored interfaces
                iface = {
                    "name": ifname,
                    "admin_status": a_stat,
                    "oper_status": o_stat,
                    "type": iftype,
                    "enabled_protocols": [],
                    "subinterfaces": [sub],
                }
                if ifname in ifindexes:
                    iface["snmp_ifindex"] = int(ifindexes[ifname], 16)
                elif ifindex:
                    iface["snmp_ifindex"] = int(ifindex.group("ifindex"))
                if "mac" in sub:
                    iface["mac"] = sub["mac"]
                if "description" in sub:
                    iface["description"] = sub["description"]
                if ifname in ndps:
                    # NDP
                    iface["enabled_protocols"] += ["NDP"]
                if ifname in stps:
                    # STP
                    iface["enabled_protocols"] += ["STP"]
                if ifname in lldps:
                    # LLDP
                    iface["enabled_protocols"] += ["LLDP"]
                if ifname in vrrps.keys():
                    # VRRP
                    sub["enabled_protocols"] += ["VRRP"]
                    sub["ipv4_addresses"] += vrrps[ifname]
                # Portchannel member
                if ifname in portchannel_members:
                    ai, is_lacp = portchannel_members[ifname]
                    iface["aggregated_interface"] = ai
                    iface["subinterfaces"] = []
                    if is_lacp:
                        iface["enabled_protocols"] += ["LACP"]
                interfaces[ifname] = iface
            else:
                if ifindex:
                    sub["snmp_ifindex"] = int(ifindex.group("ifindex"))
                ifname, vlan_id = ifname.split(".")
                if is_vlan(vlan_id):
                    sub["vlan_ids"] = [vlan_id]
                interfaces[ifname]["subinterfaces"] += [sub]
        # VRF and forwarding_instance proccessed
        vrfs, vrf_if_map = self.get_mpls_vpn_mappings()
        for i in interfaces.keys():
            iface_vrf = "default"
            subs = interfaces[i]["subinterfaces"]
            interfaces[i]["subinterfaces"] = []
            if i in vrf_if_map:
                iface_vrf = vrf_if_map[i]
                vrfs[vrf_if_map[i]]["interfaces"] += [interfaces[i]]
            else:
                vrfs["default"]["interfaces"] += [interfaces[i]]
            for s in subs:
                if s["name"] in vrf_if_map and vrf_if_map[s["name"]] != iface_vrf:
                    vrfs[vrf_if_map[s["name"]]]["interfaces"] += [
                        {
                            "name": s["name"],
                            "type": "other",
                            "enabled_protocols": [],
                            "subinterfaces": [s],
                        }
                    ]
                else:
                    interfaces[i]["subinterfaces"] += [s]
        return list(vrfs.values())
Пример #5
0
    def get_base_router(self):
        fi = {"forwarding_instance": "default", "type": "ip", "interfaces": []}
        port_info = self.cli("show port")
        for line in port_info.splitlines():
            match = self.re_port_info.search(line)
            if match:
                port_detail = self.cli("show port %s detail" % match.group("name"))
                match_detail = self.re_port_detail_info.search(port_detail)
                if not match_detail:
                    match_detail = self.re_port_detail_info_sr.search(port_detail)
                my_dict = match.groupdict()
                my_dict.update(match_detail.groupdict())
                if "aggregated_interface" in my_dict:
                    if is_int(my_dict["aggregated_interface"]):
                        my_dict["aggregated_interface"] = "-".join(
                            ["lag", my_dict["aggregated_interface"]]
                        )
                    else:
                        del my_dict["aggregated_interface"]
                my_dict["type"] = "physical"
                my_dict["subinterfaces"] = []
                my_dict.pop("bad_stat")
                my_dict["description"] = my_dict["description"].replace("\n", "")
                fi["interfaces"].append(my_dict)
        lag_info = self.cli("show lag detail")

        lags = self.re_lag_split.split(lag_info)

        for lag in lags[1:]:
            match = self.re_lag_detail.search(lag)
            if match:
                my_dict = match.groupdict()
                my_dict["type"] = "aggregated"
                if my_dict["name"]:
                    my_dict["name"] = "-".join(["lag", my_dict["name"]])
                my_dict["subinterfaces"] = []
                saps = self.cli(
                    "show service sap-using sap %s | match invert-match [" % my_dict["name"]
                )
                for sapline in saps.splitlines():
                    sap = self.re_lag_subs.match(sapline)
                    if sap:
                        if sap.group("physname"):
                            vlans = sap.group("sapname")
                            s = {
                                "name": ":".join([sap.group("physname"), vlans]),
                                "admin_status": self.fix_status(sap.group("admin_status")),
                                "oper_status": self.fix_status(sap.group("admin_status")),
                            }
                            if "." in vlans and "*" not in vlans:
                                up_tag, down_tag = vlans.split(".")
                                if is_vlan(down_tag):
                                    s["vlan_ids"] = [int(up_tag), int(down_tag)]
                                else:
                                    s["vlan_ids"] = [int(up_tag)]
                            elif "*" in vlans:
                                s["vlan_ids"] = []
                            elif int(vlans) == 0:
                                s["vlan_ids"] = []
                            else:
                                s["vlan_ids"] = [int(vlans)]
                            my_dict["subinterfaces"].append(s)
                my_dict["oper_status"] = self.fix_status(my_dict["oper_status"])
                my_dict["admin_status"] = self.fix_status(my_dict["admin_status"])
                if my_dict["protocols"].lower() == "enabled":
                    my_dict["protocols"] = ["LACP"]
                else:
                    my_dict["protocols"] = []
                my_dict["description"] = my_dict["description"].replace("\n", "")
                fi["interfaces"].append(my_dict)
        intf = self.cli('show router "Base" interface detail')
        fi["interfaces"] += self.parse_interfaces(intf, fi["interfaces"])

        return fi
Пример #6
0
    def parse_interfaces(self, data, vrf):
        ifaces = self.re_int.split(data)
        result = []
        iftypeVPRN = ": VPRN"
        iftypeNetwork = ": Network"
        iftypeSubsc = ": VPRN Sub"
        iftypeGroup = ": VPRN Grp"
        iftypeRed = ": VPRN Red"
        iftypeIES = ": IES"

        for iface in ifaces[1:]:
            parent_iface = ""
            my_dict = {}
            if iftypeGroup in iface:
                match_obj = self.re_int_desc_group.search(iface)
                if match_obj:
                    my_dict = match_obj.groupdict()
                    if not my_dict["mac"] or my_dict["mac"] == "":
                        del my_dict["mac"]
                    my_dict["type"] = "other"
                    my_dict["subinterfaces"] = []
            elif iftypeSubsc in iface:
                match_obj = self.re_int_desc_subs.search(iface)
                my_dict = match_obj.groupdict()
                my_dict["subinterfaces"] = [{}]
                my_dict["type"] = "loopback"
                my_sub = {
                    "oper_status": my_dict["oper_status"],
                    "admin_status": my_dict["admin_status"],
                    "name": my_dict["name"],
                }
                if "enabled_afi" in my_dict:
                    my_sub["enabled_afi"] = my_dict["enabled_afi"]
                    my_dict.pop("enabled_afi")
                if "ipv4_addresses" in my_dict:
                    my_sub["ipv4_addresses"] = my_dict["ipv4_addresses"]
                    my_dict.pop("ipv4_addresses")
                if "ipv6_addresses" in my_dict:
                    my_sub["ipv6_addresses"] = my_dict["ipv6_addresses"]
                    my_dict.pop("ipv6_addresses")
                my_dict["subinterfaces"][0].update(my_sub)
            elif iftypeRed in iface:
                match_obj = self.re_int_desc_vprn.search(iface)
                my_dict = match_obj.groupdict()
                if "subinterfaces" in my_dict:
                    my_dict["subinterfaces"] = [
                        {"name": my_dict["subinterfaces"], "type": "tunnel"}
                    ]
                my_dict["type"] = "tunnel"
            elif iftypeNetwork in iface or iftypeVPRN in iface or iftypeIES in iface:
                match_obj = self.re_int_desc_vprn.search(iface)
                if match_obj:
                    my_dict = match_obj.groupdict()
                    if not my_dict.get("mac"):
                        del my_dict["mac"]
                    if "subinterfaces" in my_dict:
                        if my_dict["subinterfaces"].startswith("sdp"):
                            my_dict["type"] = "tunnel"
                        elif my_dict["subinterfaces"].startswith("loopback"):
                            my_dict["type"] = "loopback"
                        match = self.re_iface.search(my_dict["subinterfaces"])
                        if match:
                            parent_iface = match.group("iface")
                            if ":" in my_dict["subinterfaces"]:
                                vlans = my_dict["subinterfaces"].split(":")[1]
                                if "." in vlans and "*" not in vlans:
                                    up_tag, down_tag = vlans.split(".")
                                    if is_vlan(down_tag):
                                        my_dict["vlan_ids"] = [int(up_tag), int(down_tag)]
                                    else:
                                        my_dict["vlan_ids"] = [int(up_tag)]
                                elif "*" in vlans:
                                    my_dict["vlan_ids"] = []
                                elif int(vlans) == 0:
                                    my_dict["vlan_ids"] = []
                                else:
                                    my_dict["vlan_ids"] = [int(vlans)]
                        my_dict["subinterfaces"] = [{"name": my_dict["name"]}]
                else:
                    continue
            else:
                continue
            if my_dict["description"] == "(Not Specified)":
                my_dict.pop("description")
            proto = my_dict["protocols"]
            my_dict["protocols"] = self.fix_protocols(my_dict["protocols"])
            if "srrp" in my_dict:
                my_dict["protocols"] += ["SRRP"]
                my_dict.pop("srrp")
            my_dict["oper_status"] = self.fix_status(my_dict["oper_status"])
            my_dict["admin_status"] = self.fix_status(my_dict["admin_status"])
            if "ipaddr_section" in my_dict:
                my_dict.update(self.fix_ip_addr(my_dict["ipaddr_section"]))
                my_dict.pop("ipaddr_section")
            if "subinterfaces" in my_dict:
                if not isinstance(my_dict["subinterfaces"], (list, dict)):
                    my_dict["subinterfaces"] = [my_dict["subinterfaces"]]
                if len(my_dict["subinterfaces"]) == 1:
                    my_sub = {
                        "oper_status": my_dict["oper_status"],
                        "admin_status": my_dict["admin_status"],
                        "protocols": my_dict["protocols"],
                    }
                    my_dict.pop("protocols")
                    if "enabled_afi" in my_dict:
                        my_sub["enabled_afi"] = my_dict["enabled_afi"]
                        my_dict.pop("enabled_afi")
                    if "ipv4_addresses" in my_dict:
                        my_sub["ipv4_addresses"] = my_dict["ipv4_addresses"]
                        my_dict.pop("ipv4_addresses")
                    if "ipv6_addresses" in my_dict:
                        my_sub["ipv6_addresses"] = my_dict["ipv6_addresses"]
                        my_dict.pop("ipv6_addresses")
                    if "vlan_ids" in my_dict:
                        my_sub["vlan_ids"] = my_dict["vlan_ids"]
                        my_dict.pop("vlan_ids")
                    if "MPLS" in proto:
                        if "enabled_afi" in my_sub:
                            my_sub["enabled_afi"] += ["MPLS"]
                        else:
                            my_sub["enabled_afi"] = ["MPLS"]
                    if "mac" in my_dict and my_dict["mac"]:
                        my_sub["mac"] = my_dict["mac"]
                    if "mtu" in my_dict:
                        my_sub["mtu"] = my_dict["mtu"]
                        my_dict.pop("mtu")
                    my_dict["subinterfaces"][0].update(my_sub)
                    if vrf:
                        found = False
                        for i in vrf:
                            if i["name"] == parent_iface:
                                my_sub["name"] = my_dict["name"]
                                i["subinterfaces"] += [my_sub]
                                found = True
                                break
                        if found:
                            continue
            if "type" not in my_dict:
                my_dict["type"] = "unknown"
            result += [my_dict]
        return result
Пример #7
0
    def execute_cli(self):
        untagged = {}
        tagged = {}
        l3_ids = {}
        vlans_requested = False
        interfaces = {}
        ifaces = []

        v = self.cli("show interfaces media | match interface:")
        ifaces = self.rx_phys.findall(v)

        for iface in ifaces:
            if not self.filter_interface(0, iface, True):
                continue
            v = self.cli("show interfaces %s" % iface)
            L = self.rx_log_split.split(v)
            phy = L.pop(0)
            phy = phy.replace(" )", "")
            match = self.rx_phy_name.search(phy)
            name = match.group("ifname")
            if name.endswith(")"):
                name = name[:-1]
            # Do not remove, additional verification
            if not self.filter_interface(0, name, True):
                continue
            # Detect interface type
            if name.startswith("lo"):
                iftype = "loopback"
            elif name.startswith(("fxp", "me")):
                iftype = "management"
            elif name.startswith(("ae", "reth", "fab", "swfab")):
                iftype = "aggregated"
            elif name.startswith(("vlan", "vme")):
                iftype = "SVI"
            elif name.startswith("irb"):
                iftype = "SVI"
            elif name.startswith(
                ("fc", "fe", "ge", "xe", "sxe", "xle", "et", "fte")):
                iftype = "physical"
            elif name.startswith(("gr", "ip", "st")):
                iftype = "tunnel"
            elif name.startswith("em"):
                if self.is_work_em:
                    iftype = "physical"
                else:
                    iftype = "management"
            else:
                iftype = "unknown"

            # Get interface parameters
            iface = {
                "name": name,
                "admin_status": match.group("admin").lower() == "enabled",
                "oper_status": match.group("oper").lower() == "up",
                "type": iftype,
            }
            def_si = {
                "name": name,
                "admin_status": match.group("admin").lower() == "enabled",
                "oper_status": match.group("oper").lower() == "up",
            }
            # Get description
            match = self.rx_phy_description.search(phy)
            if match and match.group("description") != "-=unused=-":
                iface["description"] = smart_text(match.group("description"),
                                                  errors="ignore",
                                                  encoding="ascii")
            # Get ifindex
            match = self.rx_phy_ifindex.search(phy)
            if match:
                iface["snmp_ifindex"] = match.group("ifindex")
            # Get MAC
            mac = None
            match = self.rx_phy_mac.search(phy)
            if match:
                mac = match.group("mac")
                iface["mac"] = mac
                def_si["mac"] = mac
            match = self.rx_mtu.search(phy)
            if match:
                def_si["mtu"] = match.group("mtu")
            # Process subinterfaeces
            subs = []
            for s in L:
                match = self.rx_log_name.search(s)
                sname = match.group("name")
                if not self.profile.valid_interface_name(self, sname):
                    continue
                si = {
                    "name": sname,
                    "snmp_ifindex": match.group("ifindex"),
                    "admin_status": True,
                    "oper_status": True,
                    "enabled_afi": [],
                }
                if mac:
                    si["mac"] = mac
                # Get MTU
                match = self.rx_mtu.search(s)
                if match:
                    si["mtu"] = match.group("mtu")
                # Get description
                match = self.rx_phy_description.search(s)
                if match:
                    si["description"] = smart_text(match.group("description"),
                                                   errors="ignore",
                                                   encoding="ascii")
                # Get vlans
                vlan_ids = []
                match = self.rx_flags_vlan.search(s)
                if match:
                    # Skip like this

                    #  Logical interface ge-0/0/13.0 (Index 143) (SNMP ifIndex 551)
                    #    Flags: Up 0x0 VLAN-Tag [ 0x0000.0 ]  Encapsulation: ENET2
                    #    Protocol aenet, AE bundle: ae0.0

                    if is_vlan(match.group("vlan")):
                        vlan_ids = [int(match.group("vlan"))]
                    if match.group("vlan2") and is_vlan(match.group("vlan2")):
                        vlan_ids += [int(match.group("vlan2"))]
                # `irb` and `vlan` interfaces display other,
                # then `eth-switch` protocol
                if l3_ids.get(sname):
                    vlan_ids = [l3_ids[sname]]
                # Process protocols
                for p in self.rx_log_protocol.split(s)[1:]:
                    match = self.rx_log_pname.search(p)
                    proto = match.group("proto")
                    local_addresses = self.rx_log_address.findall(p)
                    if proto == "iso":
                        # Protocol ISO
                        si["enabled_afi"] += ["ISO"]
                        if local_addresses:
                            si["iso_addresses"] = local_addresses
                    elif proto == "mpls":
                        # MPLS protocol
                        si["enabled_afi"] += ["MPLS"]
                    elif proto == "inet":
                        # Protocol IPv4
                        si["enabled_afi"] += ["IPv4"]
                        si["ipv4_addresses"] = [
                            "%s/32" % a for a in local_addresses
                        ]
                        # Find connected networks
                        for match in self.rx_log_netaddress.finditer(p):
                            net, addr = match.groups()
                            n, m = net.split("/")
                            si["ipv4_addresses"] += ["%s/%s" % (addr, m)]
                    elif proto == "inet6":
                        # Protocol IPv6
                        si["enabled_afi"] += ["IPv6"]
                        si["ipv6_addresses"] = [
                            "%s/128" % a for a in local_addresses
                        ]
                        # Find connected networks
                        for match in self.rx_log_netaddress6.finditer(p):
                            net, addr = match.groups()
                            n, m = net.split("/")
                            si["ipv6_addresses"] += ["%s/%s" % (addr, m)]
                    elif proto == "aenet":
                        # Aggregated
                        match = self.rx_log_ae.search(p)
                        if match:
                            bundle = match.group("bundle")
                            iface["aggregated_interface"] = bundle
                    elif proto.lower() == "eth-switch" or proto.lower(
                    ) == "multiservice":
                        if proto.lower() == "eth-switch":
                            si["enabled_afi"] += ["BRIDGE"]
                        if not vlans_requested:
                            if self.is_switch and (
                                    self.profile.command_exist(self, "vlans")
                                    or self.profile.command_exist(
                                        self, "vlan")):
                                v = self.cli("show vlans detail")
                                untagged, tagged, l3_ids = self.get_vlan_port_mapping(
                                    v)
                                if not l3_ids:
                                    # Found in ex4500, Junos: 15.1R7.8
                                    v = self.cli("show vlans extensive")
                                    untagged1, tagged1, l3_ids = self.get_vlan_port_mapping(
                                        v)
                            vlans_requested = True
                        if untagged.get(si["name"]):
                            si["untagged_vlans"] = untagged[si["name"]]
                        if tagged.get(si["name"]):
                            si["tagged_vlans"] = sorted(tagged[si["name"]])
                        # Set vlan_ids for EX series
                        if l3_ids.get(si["name"]):
                            si["vlan_ids"] = [l3_ids[si["name"]]]
                        # x = untagged.get(si["name"])
                        # if x:
                        #     si["untagged_vlans"]
                    """
                    Why we are setting vlan_ids only on IP interfaces ?

                    # Set vlan_ids
                    if vlan_ids and (
                        "IPv4" in si["enabled_afi"] or
                        "IPv6" in si["enabled_afi"]
                    ):
                        si["vlan_ids"] = vlan_ids
                    """
                    if vlan_ids:
                        si["vlan_ids"] = vlan_ids
                if self.rx_flags_unnumbered.search(s):
                    match = self.rx_iface_unnumbered.search(s)
                    if match:
                        si["ip_unnumbered_subinterface"] = match.group("name")
                # Get tunnel type
                if iface["type"] == "tunnel":
                    si["tunnel"] = {}
                    if sname.startswith("ip"):
                        si["tunnel"]["type"] = "IPIP"
                    elif sname.startswith("st"):
                        si["tunnel"]["type"] = "IPsec"
                    elif sname.startswith("gr"):
                        si["tunnel"]["type"] = "GRE"
                        match = self.rx_ppp_address.search(s)
                        if match and int(match.group("proto")) == 47:  # GRE
                            si["tunnel"]["local_address"] = match.group("src")
                            si["tunnel"]["remote_address"] = match.group("dst")
                    else:
                        raise self.NotSupportedError("Unknown tunnel type")
                # Append to subinterfaces list
                subs += [si]
            if not subs:
                subs += [def_si]
            # Append to collected interfaces
            iface["subinterfaces"] = subs
            interfaces[name] = iface
            time.sleep(1)
        # VRF and forwarding_instance proccessed
        vrfs, vrf_if_map = self.get_mpls_vpn_mappings()
        for i in interfaces.keys():
            iface_vrf = "default"
            subs = interfaces[i]["subinterfaces"]
            interfaces[i]["subinterfaces"] = []
            if i in vrf_if_map:
                iface_vrf = vrf_if_map[i]
                vrfs[vrf_if_map[i]]["interfaces"] += [interfaces[i]]
            else:
                vrfs["default"]["interfaces"] += [interfaces[i]]
            for s in subs:
                if s["name"] in vrf_if_map and vrf_if_map[
                        s["name"]] != iface_vrf:
                    vrfs[vrf_if_map[s["name"]]]["interfaces"] += [{
                        "name":
                        s["name"],
                        "type":
                        "other",
                        "enabled_protocols": [],
                        "subinterfaces": [s],
                    }]
                else:
                    interfaces[i]["subinterfaces"] += [s]
        return list(vrfs.values())
Пример #8
0
    def execute_snmp(self, **kwargs):
        ifaces = {}  # For interfaces
        subifaces = {}  # For subinterfaces like Fa 0/1.XXX
        switchports = self.get_switchport()
        portchannels = self.get_portchannels()  # portchannel map
        ips = self.get_ip_ifaces()

        # Getting initial iface info, filter result if needed
        for iface in self.scripts.get_interface_properties(
                enable_ifindex=True, enable_oper_status=True):
            if not self.filter_interface(iface["ifindex"], iface["interface"],
                                         iface.get("oper_status")):
                continue
            if "." in iface["interface"]:
                subifaces[iface["ifindex"]] = {
                    "name": iface["interface"],
                    "snmp_ifindex": iface["ifindex"],
                    "oper_status": iface.get("oper_status", True),
                }
                # if "mac" in iface:
                #     subifaces[iface["ifindex"]]["mac"] = iface["mac"]
            else:
                ifaces[iface["ifindex"]] = {
                    "name": iface["interface"],
                    "snmp_ifindex": iface["ifindex"],
                    "oper_status": iface.get("oper_status", True),
                    "enabled_protocols": [],
                    "subinterfaces": [],
                }
                # if "mac" in iface:
                #     ifaces[iface["ifindex"]]["mac"] = iface["mac"]
        # Fill interface info
        iter_tables = []
        iter_tables += [
            self.iter_iftable(
                "admin_status",
                self.SNMP_ADMIN_STATUS_TABLE,
                ifindexes=ifaces,
                clean=self.clean_status,
            )
        ]
        iter_tables += [
            self.iter_iftable("mac",
                              self.SNMP_MAC_TABLE,
                              ifindexes=ifaces,
                              clean=self.clean_mac)
        ]
        iter_tables += [
            self.iter_iftable(
                "description",
                self.SNMP_IF_DESCR_TABLE,
                ifindexes=chain(ifaces, subifaces),
                clean=self.clean_ifdescription,
            )
        ]
        iter_tables += [
            self.iter_iftable("mtu",
                              "IF-MIB::ifMtu",
                              ifindexes=chain(ifaces, subifaces),
                              clean=self.clean_mtu)
        ]
        # Collect and merge results
        data = self.merge_tables(*tuple(iter_tables))
        if not ifaces:
            # If empty result - raise error
            raise NotImplementedError
        # Format result to ifname -> iface
        interfaces = {}
        for ifindex, iface in ifaces.items():
            if ifindex in data:
                iface.update(data[ifindex])
            iface["type"] = self.clean_iftype(iface["name"], ifindex)
            if not iface["type"]:
                self.logger.error("Unknown type for interface %s",
                                  iface["name"])
                continue
            if ifindex in ips:
                iface["subinterfaces"] += [{
                    "name":
                    iface["name"],
                    "enabled_afi": ["IPv4"],
                    "ipv4_addresses": [IPv4(*i) for i in ips[ifindex]],
                }]
            if ifindex in switchports:
                sub = {
                    "name": iface["name"],
                    "enabled_afi": ["BRIDGE"],
                }
                sub.update(switchports[ifindex])
                iface["subinterfaces"] += [sub]
            if ifindex in portchannels:
                iface["aggregated_interface"] = ifaces[
                    portchannels[ifindex]]["name"]
                iface["enabled_protocols"] = ["LACP"]
            interfaces[iface["name"]] = iface
        # Proccessed subinterfaces
        for ifindex, sub in subifaces.items():
            ifname, num = sub["name"].split(".", 1)
            if ifname not in interfaces:
                self.logger.info("Sub %s for ignored iface %s", sub["name"],
                                 ifname)
                continue
            if ifindex in data:
                sub.update(data[ifindex])
            if ifindex in ips:
                sub["enabled_afi"] = ["IPv4"]
                sub["ipv4_addresses"] = [IPv4(*i) for i in ips[ifindex]]
            if num.isdigit():
                vlan_ids = int(sub["name"].rsplit(".", 1)[-1])
                if is_vlan(vlan_ids):
                    sub["vlan_ids"] = vlan_ids
            interfaces[ifname]["subinterfaces"] += [sub]
        # VRF and forwarding_instance proccessed
        vrfs, vrf_if_map = self.get_mpls_vpn_mappings()
        for i in interfaces.keys():
            iface_vrf = "default"
            subs = interfaces[i]["subinterfaces"]
            interfaces[i]["subinterfaces"] = []
            if i in vrf_if_map:
                iface_vrf = vrf_if_map[i]
                vrfs[vrf_if_map[i]]["interfaces"] += [interfaces[i]]
            else:
                vrfs["default"]["interfaces"] += [interfaces[i]]
            for s in subs:
                if s["name"] in vrf_if_map and vrf_if_map[
                        s["name"]] != iface_vrf:
                    vrfs[vrf_if_map[s["name"]]]["interfaces"] += [{
                        "name":
                        s["name"],
                        "type":
                        "other",
                        "enabled_protocols": [],
                        "subinterfaces": [s],
                    }]
                else:
                    interfaces[i]["subinterfaces"] += [s]
        return list(vrfs.values())
Пример #9
0
 def execute_cli(self):
     interfaces = []
     v = self.cli("show interfaces")
     for match in self.rx_iface.finditer(v):
         ifname = match.group("ifname")
         admin_status = match.group("admin_status") == "up"
         oper_status = match.group("oper_status") == "up"
         iface = {
             "name": ifname,
             "type": self.profile.get_interface_type(ifname),
             "admin_status": admin_status,
             "oper_status": oper_status,
         }
         sub = {
             "name": ifname,
             "admin_status": admin_status,
             "oper_status": oper_status
         }
         if iface["type"] == "physical":
             sub["enabled_afi"] = ["BRIDGE"]
             if ifname.startswith("Gi"):
                 sw_ifname = "gigabitethernet %s" % ifname[2:]
             elif ifname.startswith("Fa"):
                 sw_ifname = "fastethernet %s" % ifname[2:]
             elif ifname.startswith("Ex"):
                 sw_ifname = "extreme-ethernet %s" % ifname[2:]
             elif ifname.startswith("Te"):
                 sw_ifname = "tengigabitethernet %s" % ifname[2:]
             elif ifname.startswith("Po"):
                 sw_ifname = "port-channel %s" % ifname[2:]
             c = self.cli("show interfaces switchport %s" % sw_ifname)
             for i in parse_table(c, footer="^Forbidden VLANs:"):
                 vlan_id = i[0]
                 if not is_vlan(vlan_id):
                     continue
                 if i[2] == "Untagged":
                     sub["untagged_vlan"] = vlan_id
                 else:
                     if "tagged_vlans" in sub:
                         sub["tagged_vlans"] += [vlan_id]
                     else:
                         sub["tagged_vlans"] = [vlan_id]
         if iface["name"].startswith("vlan"):
             sub["vlan_ids"] = iface["name"][4:]
         if match.group("mac"):
             mac = match.group("mac").strip()
             iface["mac"] = mac
             sub["mac"] = mac
         if match.group("descr"):
             descr = match.group("descr").strip()
             iface["description"] = descr
             sub["description"] = descr
         iface["subinterfaces"] = [sub]
         interfaces += [iface]
     v = self.cli("show ip interface")
     for match in self.rx_ip_iface.finditer(v):
         ifname = match.group("ifname")
         for i in interfaces:
             if i["name"] == ifname:
                 i["subinterfaces"][0]["enabled_afi"] = ["IPv4"]
                 i["subinterfaces"][0]["ipv4_addresses"] = [
                     match.group("ip")
                 ]
                 break
     return [{"interfaces": interfaces}]
Пример #10
0
def test_is_vlan(raw, expected):
    assert is_vlan(raw) is expected