def get_mpls_vpn(self): r = [] # VPLS try: v = self.cli("display vsi verbose") except self.CLISyntaxError: return [] for block in self.rx_vsi_split.split(v)[1:]: block = self.rx_vsi_pw_split.split(block) if len(block) == 2: block, pw_info = block else: block = block[0] p = {} ifaces = [] for iface in self.rx_l2vc_iface.finditer(block): ifaces += [ self.profile.convert_interface_name( iface.group("iface_name")) ] # vsi, pwsignal, iface = block.split("\n\n") # for b in block.split("\n\n"): p.update(parse_kv(self.vsi_instance_map, block)) r += [{ "type": "VPLS", "status": p.get("vsi_state") == "up", "name": p["name"], "vpn_id": p.get("vpn_id"), "interfaces": ifaces, }] # VPWS try: v = self.cli("display mpls l2vc brief") except self.CLISyntaxError: return [] for block in self.rx_l2vc_split.split(v)[1:]: p = parse_kv(self.l2vc_map, block) r += [{ "type": "VLL", "status": p["state"] == "up", "name": p["vpn_id"], "vpn_id": p["vpn_id"], "interfaces": [self.profile.convert_interface_name(p["interface"])], }] return r
def execute_cli(self, **kwargs): r = [] try: lldp = self.cli("show lldp neighbors") except self.CLISyntaxError: raise NotImplementedError for block in lldp.split("\n\n"): neighbors = [] if not block: continue n = parse_kv(self.lldp_map, block) loca_iface = n.pop("local_interface") if is_mac(n["remote_chassis_id"]): n["remote_chassis_id_subtype"] = LLDP_CHASSIS_SUBTYPE_MAC else: n["remote_chassis_id_subtype"] = LLDP_CHASSIS_SUBTYPE_LOCAL if is_mac(n["remote_port"]): n["remote_port_subtype"] = LLDP_PORT_SUBTYPE_MAC else: n["remote_port_subtype"] = LLDP_PORT_SUBTYPE_LOCAL neighbors += [n] if neighbors: r += [{"local_interface": loca_iface, "neighbors": neighbors}] return r
def get_fan(self): r = defaultdict(list) k_map = { "state": "state", "numfan": "numfan", "partinfo": "partinfo", "revision": "rev" } try: v = self.cli("show fans detail") except self.CLISyntaxError: return {} slot = 1 for block in self.rx_fans_split.split(v): if "Slot-" in block: slot = int(block.split("-")[1].strip()) continue d = parse_kv(k_map, block) if d.get("state") in ["Empty", None] or "partinfo" not in d: continue serial_no, part_no = d["partinfo"].split() r[slot] += [{ "type": "FAN", "number": 1, "description": "FanTray", "vendor": "EXTREME", "part_no": part_no, "revision": d["rev"], "serial": serial_no, }] return r
def get_psu(self): r = defaultdict(list) k_map = {"state": "state", "partinfo": "partinfo"} try: v = self.cli("show power detail") except self.CLISyntaxError: return {} slot = 1 number = None for block in self.rx_power_split.split(v): if is_int(block): if int(block.strip()) < number: slot += 1 number = int(block.strip()) continue d = parse_kv(k_map, block) if d.get("state") in ["Empty", "Powered Off", None ] or "partinfo" not in d: continue partinfo = d["partinfo"].split() r[slot] += [{ "type": "PSU", "number": number, "description": "".join(partinfo[:-2]), "vendor": "EXTREME", "part_no": partinfo[-1], "serial": partinfo[-2], }] return r
def execute_cli(self, **kwargs): r = [] try: lldp = self.cli("lldpctl", cached=True) except self.CLISyntaxError: return [] for block in lldp.split("----"): neighbors = [] if not block: continue n = parse_kv(self.lldp_map, block) if not n: continue n["local_interface"] = n["local_interface"].split(",")[0] loca_iface = n.pop("local_interface") if n["remote_chassis_id"].startswith("mac"): n["remote_chassis_id_subtype"] = LLDP_CHASSIS_SUBTYPE_MAC elif n["remote_chassis_id"].startswith("ifname"): n["remote_chassis_id_subtype"] = LLDP_CHASSIS_SUBTYPE_INTERFACE_NAME else: n["remote_chassis_id_subtype"] = LLDP_CHASSIS_SUBTYPE_LOCAL n["remote_chassis_id"] = n["remote_chassis_id"].split(" ")[1] if n["remote_port"].startswith("mac"): n["remote_port_subtype"] = LLDP_PORT_SUBTYPE_MAC elif n["remote_port"].startswith("ifname"): n["remote_port_subtype"] = LLDP_PORT_SUBTYPE_NAME else: n["remote_port_subtype"] = LLDP_PORT_SUBTYPE_LOCAL n["remote_capabilities"] = 0 n["remote_port"] = n["remote_port"].split(" ")[1] neighbors += [n] if neighbors: r += [{"local_interface": loca_iface, "neighbors": neighbors}] return r
def parse_interface_block(self, block): r = parse_kv(self.interface_map, block) if "mtu" not in r and self.rx_mtu.search(block): r["mtu"] = self.rx_mtu.search(block).group(1) if self.rx_mac.search(block): r["mac"] = self.rx_mac.search(block).group(1) ip_match = self.rx_ip.search(block) if ip_match: r["ip"] = ip_match.group(1) if "tagged_vlans" in r and self.rx_sub_default_vlan.search( r["tagged_vlans"]): r["tagged_vlans"] = r["tagged_vlans"].replace("(default vlan)", "") if "vlan_passing" in r and self.rx_sub_default_vlan.search( r["vlan_passing"]): r["vlan_passing"] = r["vlan_passing"].replace("(default vlan)", "") if "vlan_permitted" in r and self.rx_sub_default_vlan.search( r["vlan_permitted"]): r["vlan_permitted"] = r["vlan_permitted"].replace( "(default vlan)", "") if "untagged_vlan" not in r and "pvid" in r: r["untagged_vlan"] = r["pvid"] if "untagged_vlan" in r: r["untagged_vlan"] = self.rx_parse_interface_vlan.match( r["untagged_vlan"]).group(1) return r
def execute_cli(self): v = self.cli("about", cached=True) s = parse_kv({"mac address": "mac"}, v) if s: s = s["mac"].replace(" ", ":") return [{"first_chassis_mac": MAC(s), "last_chassis_mac": MAC(s)}] else: raise self.NotSupportedError
def execute_cli(self, **kwargs): r = [] try: v = self.cli("display lldp neighbor brief") except self.CLISyntaxError: raise NotImplementedError il = self.rx_iface_sep.findall(v) if not il: return r for local_iface in il: neighbors = [] ne = self.cli("display lldp neighbor port %s" % local_iface) n = parse_kv( { "chassisid subtype": "remote_chassis_id_subtype", "chassisid": "remote_chassis_id", "portid subtype": "remote_port_subtype", "portid": "remote_port", "port description": "remote_port_description", "system capabilities enabled": "remote_capabilities", "system name": "remote_system_name", "system description": "remote_system_description", }, ne, ) # Convert chassis id n["remote_chassis_id_subtype"] = self.CHASSIS_TYPES[ n["remote_chassis_id_subtype"].lower()] if n["remote_chassis_id_subtype"] == 3: n["remote_chassis_id"] = MACAddressParameter().clean( n["remote_chassis_id"]) # Convert port id n["remote_port_subtype"] = self.PORT_TYPES[ n["remote_port_subtype"].lower()] if n["remote_port_subtype"] == 3: n["remote_port"] = MACAddressParameter().clean( n["remote_port"]) if n.get("remote_port_description") in ["-", "NA", "N/A"]: del n["remote_port_description"] if n.get("remote_system_description") in ["-", "NA", "N/A"]: del n["remote_system_description"] if n.get("remote_system_name") in ["-", "NA", "N/A"]: del n["remote_system_name"] # Process capabilities caps = 0 cs = n.get("remote_capabilities", "").replace(",", " ") for c in cs.split(): caps |= self.CAPS[c.lower().strip()] n["remote_capabilities"] = caps neighbors += [n] if neighbors: r += [{"local_interface": local_iface, "neighbors": neighbors}] return r
def part_parse_s8500(self): """ Parse S85XX inventory :param items: :param slot_num: :return: """ self.logger.info("Use S85XX parse function") slot_num, slots = self.get_device_inventory() r = [{ "type": "CHASSIS", "number": 0, "vendor": "Huawei", "description": "", "part_no": [{ 14: "S8512", 10: "S8508", 7: "S8505", 4: "S8502" }[slot_num]], }] for slot in slots: slot_n, subslot_n, part_no = slot["slot"], 0, slot["part_no"] # @todo CHASSIS ! # Slot No. Brd Type Brd Status Subslot Num Sft Ver # @todo 6 LSB1XP4CA0 Normal 1 S8500-VRP310-R1648P02 # https://www.manualslib.com/manual/1216852/Huawei-Quidway-S8500-Series.html?page=52 item_type, slot_n, part_no = self.get_type(slot_n, sub=subslot_n, part_no=part_no) v = self.cli("display device manuinfo slot %d" % slot["slot"]) r += [{ "type": item_type, "number": slot_n, "vendor": "Huawei", "description": "", "part_no": [part_no], }] r[-1].update( parse_kv( { "board_serial_number": "serial", "device_serial_number": "serial", "manufacturing_date": "mfg_date", "vendor_name": "vendor", }, v, )) return r
def execute(self): v = self.cli("show version", cached=True) r = parse_kv(self.kv_map, v, sep=":") return { "vendor": "Raisecom", "platform": r["platform"], "version": r["version"], "attributes": { "Serial Number": r["serial"], "Boot PROM": r["bootprom"], "HW version": r["hw_version"], }, }
def get_info(self): # For QSW-3470-10T 3.0.1-R1-BETA3 fw try: v = self.cli("show info") except self.CLISyntaxError: return {} r = parse_kv(self.info_map, v, ":") platform = self.fix_platform(r["sysid"]) return { "vendor": "Qtech", "platform": platform, "version": "%s (%s)" % (r["fw_ver"], r["fw_date"]), }
def get_ip_sla_udp_jitter_metrics_cli(self, metrics): """ Returns collected ip sla metrics in form probe id -> { rtt: RTT in seconds } :return: """ setup_metrics = { tuple(m.labels): m.id for m in metrics if m.metric in {"SLA | JITTER", "SLA | UDP RTT"} } v = self.cli("show ip sla statistics") metric_map = { "ipsla operation id": "name", "latest rtt": "rtt", "source to destination jitter min/avg/max": "sd_jitter", "destination to source jitter min/avg/max": "ds_jitter", "number of rtt": "num_rtt", } r_v = self.rx_ipsla_probe.split(v) if len(r_v) < 3: return {} for probe_id, data in zip(r_v[1::2], r_v[2::2]): p = parse_kv(metric_map, data) if (f"noc::sla::name::{probe_id}", ) not in setup_metrics: continue if "rtt" in p: # Latest RTT: 697 milliseconds rtt = p["rtt"].split()[0] try: self.set_metric( id=("SLA | UDP RTT", (f"noc::sla::name::{probe_id}", )), metric="SLA | UDP RTT", value=float(rtt) * 1000, multi=True, ) except ValueError: pass if "sd_jitter" in p: # Source to Destination Jitter Min/Avg/Max: 0/8/106 milliseconds jitter = p["sd_jitter"].split()[0].split("/")[1] self.set_metric( id=("SLA | JITTER", (f"noc::sla::name::{probe_id}", )), metric="SLA | JITTER", value=float(jitter) * 1000, multi=True, )
def execute(self): v = self.cli("show version", cached=True) r = parse_kv(self.kv_map, v, sep=":") if "prod_version" in r: r["prod_version"] = r["prod_version"].split(":")[-1].strip(" .") return [{ "type": "CHASSIS", "number": "0", "vendor": "Raisecom", "part_no": r["platform"], "revision": r["prod_version"], "serial": r["serial"], "description": "", }]
def execute_cli(self, interface=None): # @todo without stack slot (Members | Ids) # show ports transceiver information r = [] if interface is not None: ifaces = [interface.split(":")] elif self.has_capability("Stack | Member Ids"): ifaces = [(s_id, None) for s_id in self.capabilities["Stack | Member Ids"].split(" | ")] else: ifaces = [(None, None)] for slot, port in ifaces: cmd = "debug hal show optic-info ddmi " if port is not None: cmd += "slot %s, port %s" % (slot, port) elif slot is not None: cmd += "slot %s" % slot try: v = self.cli(cmd) except self.CLISyntaxError: return [] for block in self.rx_trans_split.split(v): if is_int(block): port = block.strip() continue if self.rx_no_trans.match(block) or not port: continue d = parse_kv(self.k_map, block) if slot is not None: port = "%s:%s" % (slot, port) if not d: continue r += [{ "interface": port, "temp_c": self.normalize_output(d.get("temp_c")), "voltage_v": self.normalize_output(d.get("voltage_v")), "current_ma": self.normalize_output(d.get("current_ma")), "optical_rx_dbm": self.normalize_output(d.get("optical_rx_dbm")), "optical_tx_dbm": self.normalize_output(d.get("optical_tx_dbm")), }] return r
def parse_elabel(self, out): """ Function parse 'display elabel' :param out: 'display elabel output' :type out: str :return: :rtype: inventory_item """ r = [] parent = None for match in self.rx_int_elabel_universal.finditer(out): match = match.groupdict() if not match: continue elif match["role"] in {"Slot", "Rack"}: parent = match["sec_name"] if not match["properties"]: self.logger.debug( "[%s] Empty [Board Properties] section. Skipping...", match["sec_name"] ) continue p = parse_kv(self.inv_property_map, match["properties"], sep="=") if "vendor" not in p and "type" not in p: raise self.UnexpectedResultError("Partial parsed properties") elif "vendor" not in p and p["type"].startswith("H"): p["vendor"] = "Huawei" elif "vendor" not in p or not p["vendor"]: self.logger.debug("[%s] Empty Vendor Properties. Skipping...", match["sec_name"]) continue try: num = int(match["num"] or 0) except ValueError: num = match["num"] r += [ self.inventory_item( **{ "name": match["sec_name"], "num": num, "parent": parent, "description": p.get("description"), "type": p.get("type"), "vendor": p.get("vendor", "Unknown"), "barcode": p.get("barcode"), "mnf_date": p.get("mnf_date"), } ) ] return r
def execute_cli(self): # Not worked for Menu CLI m = self.motd if m: match = self.rx_platform.search(m) if not match: match = self.rx_platform1.search(m) platform = match.group("platform").strip() version = self.re_search(self.rx_fwver, m).group("version") else: v = self.cli("upsabout") d = parse_kv({"model": "platform", "firmware revision": "version"}, v) platform = d["platform"] version = d["version"] return {"vendor": "APC", "platform": platform, "version": version}
def fix_last_port_description(self, interfaces): """ For last N interfaces fill description and MAC :param interfaces: :return: """ for ifname in list(sorted(interfaces, reverse=True, key=alnum_key))[:3]: v = self.cli("show port description %s" % ifname) if not v: continue r = parse_kv(self.description_map, v, sep=".") if "description" in r: interfaces[ifname]["description"] = r["description"].strip( ". ") if "mac" in r: interfaces[ifname]["mac"] = r["mac"].strip(". ")
def execute_ne(self, interface=None): """ NE series GigabitEthernet0/3/4 Port Physical Status : UP Physical Down Reason : none Loopback : none Duplex mode : full-duplex negotiation : enable Pause Flowcontrol : Receive Enable and Send Enable SFP imformation: The Vendor PN is SFP-WDM57.36 The Vendor Name is OptiCin, Port BW: 1G, Transceiver BW: 1G, Transceiver Mode: SingleMode WaveLength: 1570nm, Transmission Distance: 140km Rx Power: -31.54dBm, Warning range: [-33.979, -9.003]dBm Tx Power: 3.03dBm, Warning range: [1.999, 6.999]dBm :param interface: :return: """ cmd = "display interface phy-option" if interface is not None: cmd += " %s" % interface try: c = self.cli(cmd) except self.CLISyntaxError: return [] r = [] for block in c.split("\n\n"): if not block.strip() or "transceiver offline" in block: continue iface = {"interface": block.splitlines()[0]} res = parse_kv(self.ne_map, block) if "rx_power" in res: # Rx Power: -10.44dBm, Warning range: [-17.011, 0.000]dBm iface["optical_rx_dbm"] = float( res["rx_power"].split(",")[0][:-3]) if "tx_power" in res: # Tx Power: 3.35dBm, Warning range: [0.999, 5.000]dBm iface["optical_tx_dbm"] = float( res["tx_power"].split(",")[0][:-3]) if len(iface) == 1: # No metrics continue r += [iface] return r
def execute(self): v = self.cli("show sysinfo", cached=True) pkv = parse_kv( { "1.hardware version": "hw", "2.software version": "sw", "3.serial number": "serial" }, v) return { "vendor": "Nateks", "platform": "ACE", "version": pkv["sw"], "attributes": { "HW version": pkv["hw"], "Serial Number": pkv["serial"] }, }
def get_switchport(self): r = {} v = self.cli("show interface * switchport") for block in v.split("\n\n"): if not block: continue b = parse_kv(self.switchport_map, block) if b["mode"] == "trunk": r[b["name"]] = { "tagged_vlans": ranges_to_list(b["tagged"]), "untagged_vlan": b["native"], } else: r[b["name"]] = { "tagged_vlans": [], "untagged_vlan": b["untagged"] } return r
def get_ip_sla_icmp_echo_metrics_cli(self, metrics): """ Returns collected ip sla metrics in form probe id -> { rtt: RTT in seconds } :return: """ setup_metrics = { tuple(m.path): m.id for m in metrics if m.metric == "SLA | ICMP RTT" and m.sla_type == "icmp-echo" } if not setup_metrics: self.logger.info("No icmp-echo sla probes.") return v = self.cli("show ip sla statistics") metric_map = { "ipsla operation id": "name", "latest rtt": "rtt", "number of rtt": "num_rtt" } r_v = self.rx_ipsla_probe.split(v) if len(r_v) < 3: return for probe_id, data in zip(r_v[1::2], r_v[2::2]): p = parse_kv(metric_map, data) if ("", str(probe_id)) not in setup_metrics: continue if "rtt" in p: # Latest RTT: 697 milliseconds rtt = p["rtt"].split()[0] try: self.set_metric( id=setup_metrics[("", str(probe_id))], metric="SLA | ICMP RTT", path=("", probe_id), value=float(rtt) * 1000, multi=True, ) except ValueError: pass
def part_parse_s8500(self, item_type, number, part_no, content): self.logger.info("Use S85XX parse function") r = { "type": item_type, "number": number, "vendor": "Huawei", "description": "", "part_no": [part_no], } r.update( parse_kv( { "board_serial_number": "serial", "device_serial_number": "serial", "manufacturing_date": "mfg_date", "vendor_name": "vendor", }, content, ) ) return [r]
def execute_cli(self): result = [] v = self.cli("show lldp entry") for entry in self.rx_splitter.split(v): if not entry: continue r = parse_kv(self.kv_map, entry) remote_port_match = self.rx_lldp_subtype.match(r["remote_port"]) if not remote_port_match: self.logger.warning("Unknown remote port_id format: %s", r["remote_port"]) continue remote_match = self.rx_lldp_subtype.match(r["chassis"]) if not remote_match: self.logger.warning("Unknown remote chassis format: %s", r["chassis"]) continue chassis_id, chassis_subtype = remote_match.groups() remote_port, remote_port_type = remote_port_match.groups() if chassis_subtype.lower() == "mac address": chassis_id = chassis_id.replace(".", ":") neighbor = { "remote_chassis_id_subtype": self.chassis_subtype[chassis_subtype.lower()], "remote_chassis_id": chassis_id, "remote_port_subtype": self.port_subtype[remote_port_type.lower()], "remote_port": remote_port, } if "remote_description" in r: neighbor["remote_port_description"] = r["remote_description"] if "sysname" in r: neighbor["remote_system_name"] = r["sysname"] result += [{"local_interface": r["port"], "neighbors": [neighbor]}] return result
def execute_cli(self, **kwargs): # "EXISTSH ALL" r = [] # boards = self.profile.get_boards(self) try: v = self.cli("ginv all", cached=True) except self.CLISyntaxError: raise NotImplementedError for line in self.rx_table_spliter.split(v): if not line.startswith("|"): continue row = [x.strip() for x in line.strip("|\n").split("|")] if row[0] == "SH": # header continue shelf, slot, port, mani, _, sw_ver, boot_ver, hw_ver, serial, _, _ = row if int(port): continue detail = self.cli("ginv %s %s %s %s" % (shelf, slot, port, mani)) if not detail: continue x = parse_kv(self.slot_detail_map, detail) r += [{ "type": "LINECARD", "number": slot, "vendor": "ECI", "part_no": [x["hw_descr"], x["order_num"]] if x.get("order_num") else [x["hw_descr"]], "serial": serial, "revision": smart_text(smart_bytes(x["rev"]), errors="ignore"), "description": "", }] return r
def execute_cli(self, **kwargs): r = [] ups_map = { "model": "model", "sku": "part_no", "serial number": "serial", "manufacture date": "mfg_date", "battery sku": "battery_part_no", } v = self.cli("upsabout") d = parse_kv(ups_map, v) if d.get("mfg_date"): try: if len(d["mfg_date"]) == 8: d["mfg_date"] = datetime.datetime.strptime( d["mfg_date"], "%m/%d/%y") else: d["mfg_date"] = datetime.datetime.strptime( d["mfg_date"], "%m/%d/%Y") d["mfg_date"] = d["mfg_date"].strftime("%Y-%m-%d") except ValueError: self.logger.warning("Unknown format manufacture date field") d["mfg_date"] = None if "part_no" not in d and "model" in d: # Try normalize d["part_no"] = self.part_no_detect(d["model"]) if d.get("part_no"): r += [{ "type": "CHASSIS", "number": 1, "vendor": "APC", "serial": d["serial"], "mfg_date": d.get("mfg_date", "00-00-00"), "description": d["model"], "part_no": d["part_no"], }] mgmt_card_map = { "model number": "part_no", "serial number": "serial", "hardware revision": "revision", "manufacture date": "mfg_date", "battery sku": "battery_part_no", } v = self.cli("about", cached=True) d = parse_kv(mgmt_card_map, v) if d.get("mfg_date"): try: if len(d["mfg_date"]) == 8: # 08/19/14 d["mfg_date"] = datetime.datetime.strptime( d["mfg_date"], "%m/%d/%y") else: # 08/19/2014 d["mfg_date"] = datetime.datetime.strptime( d["mfg_date"], "%m/%d/%Y") d["mfg_date"] = d["mfg_date"].strftime("%Y-%m-%d") except ValueError: self.logger.warning("Unknown format manufacture date field") d["mfg_date"] = None if "part_no" in d: r += [{ "type": "MGMT", "number": 1, "vendor": "APC", "serial": d["serial"], "description": "Management card", "mfg_date": d.get("mfg_date", "00-00-00"), "revision": d["revision"], "part_no": d["part_no"], }] return r
def get_transiever(self, slot=None): r = [] k_map = { "sfp/sfp+ vendor": "vendor", "vendor": "vendor", "sfp/sfp+ part number": "part_no", "partnumber": "part_no", "sfp/sfp+ serial number": "serial", "serialnumber": "serial", "manufacturedate": "mfg_date", "sfp/sfp+ manufacture date": "mfg_date", "connector": "connector", "type": "type", "wavelength": "wavelength", "sfp or sfp+": "sfp_type", "rev": "rev", } if slot: v = "debug hal show optic-info slot %d" % slot else: v = "debug hal show optic-info" try: v = self.cli(v) except self.CLISyntaxError: return r port = None for block in self.rx_trans_split.split(v): if is_int(block): port = block.strip() continue if self.rx_no_trans.match(block) or not port: continue d = parse_kv(k_map, block) # 1300Mb/sec-1310nm-LC-20.0km(0.009mm) # description = "" description = "-".join([ d.get("type", "").strip(), d.get("wavelength", "").strip() + "nm", d.get("connector", "").strip() # d["Transfer Distance(meter)"].strip() + "m" ]) if "part_no" not in d: continue if "mfg_date" in d: try: if len(d["mfg_date"]) > 6: d["mfg_date"] = d["mfg_date"][:6] d["mfg_date"] = datetime.datetime.strptime( d["mfg_date"], "%y%m%d") d["mfg_date"] = d["mfg_date"].strftime("%Y-%m-%d") except ValueError: self.logger.error( "Unconverted format manufactured date: %s, on port: %s" % (d["mfg_date"], port)) d["mfg_date"] = None r += [{ "type": "XCVR", "number": port, "vendor": d.get("vendor", "NONAME"), "part_no": d["part_no"].strip(), "serial": d.get("serial", ""), "description": description, "mfg_date": d.get("mfg_date", "00-00-00"), }] if "rev" in d: r[-1]["revision"] = d["rev"] port = None return r
def execute_ar(self, interface=None): """ AR Series GigabitEthernet0/0/0 information: ------------------------------------------------------------- Electronic label information: Description :1300Mb/sec-1570nm-SC-SM-140km(0.009mm) Type :SFP-WDM57.36 Manufacturer :OptiCin HuaweiPartNumber : ------------------------------------------------------------- Alarm information: SFP Module Authentication Fail ------------------------------------------------------------- Realtime information: Temperature(Ўж) :42 Temperature High Threshold(Ўж) :95 Temperature Low Threshold(Ўж) :-42 Voltage(V) :3.25 Voltage High Threshold(V) :3.50 Voltage Low Threshold(V) :3.05 Bias Current(mA) :35.46 Bias High Threshold(mA) :80.00 Bias Low Threshold(mA) :3.00 Current Rx Power(dBM) :-22.03 Default Rx Power High Threshold(dBM) :-8.99 Default Rx Power Low Threshold(dBM) :-33.97 Current Tx Power(dBM) :2.95 Default Tx Power High Threshold(dBM) :6.99 Default Tx Power Low Threshold(dBM) :2.00 User Set Rx Power High Threshold(dBM) :-8.99 User Set Rx Power Low Threshold(dBM) :-33.97 User Set Tx Power High Threshold(dBM) :6.99 User Set Tx Power Low Threshold(dBM) :2.00 ------------------------------------------------------------- :param interface: :return: """ cmd = "dis transceiver verbose" if interface is not None: cmd = "dis transceiver interface %s verbose" % interface try: c = self.cli(cmd) except self.CLISyntaxError: return [] r = [] for block in c.strip("\n\r").split("\n\n"): if not block.strip() or "Realtime information:" not in block: continue iface = { "interface": block.splitlines()[0].split("information")[0].strip() } res = parse_kv(self.ar_map, block) if "rx_power" in res: # Rx Power: -10.44dBm, Warning range: [-17.011, 0.000]dBm iface["optical_rx_dbm"] = float(res["rx_power"]) if "tx_power" in res: # Tx Power: 3.35dBm, Warning range: [0.999, 5.000]dBm iface["optical_tx_dbm"] = float(res["tx_power"]) if "current" in res: # Tx Power: 3.35dBm, Warning range: [0.999, 5.000]dBm iface["current_ma"] = float(res["current"]) if "temp" in res: # Tx Power: 3.35dBm, Warning range: [0.999, 5.000]dBm iface["temp_c"] = float(res["temp"]) if "voltage" in res: # Tx Power: 3.35dBm, Warning range: [0.999, 5.000]dBm iface["voltage_v"] = float(res["voltage"]) if len(iface) == 1: # No metrics self.logger.info("No metrics for iface %s", iface) continue r += [iface] return r
def execute_cli(self, **kwargs): """ VRP5 style :return: """ r = [] if self.match_version(version__startswith=r"3."): try: v = self.cli("display lldp neighbor-information") except self.CLISyntaxError: raise self.NotSupportedError() else: try: v = self.cli("display lldp neighbor") except self.CLISyntaxError: raise self.NotSupportedError il = self.rx_iface_sep.split(v)[1:] if not il: il = self.rx_iface3_sep.split(v)[1:] for local_iface, data in zip(il[::2], il[1::2]): neighbors = [] for ndata in self.rx_neighbor_split.split(data)[1:]: n = parse_kv( { "chassis type": "remote_chassis_id_subtype", "chassisidsubtype": "remote_chassis_id_subtype", "chassis id": "remote_chassis_id", "chassisid": "remote_chassis_id", "port id type": "remote_port_subtype", "portidsubtype": "remote_port_subtype", "port id subtype": "remote_port_subtype", "port id": "remote_port", "portid": "remote_port", "port description": "remote_port_description", "portdesc": "remote_port_description", "system capabilities enabled": "remote_capabilities", "syscapenabled": "remote_capabilities", "system name": "remote_system_name", "sysname": "remote_system_name", "system description": "remote_system_description", "sysdesc": "remote_system_description", }, ndata, ) # Convert chassis id n["remote_chassis_id_subtype"] = self.CHASSIS_TYPES[ n["remote_chassis_id_subtype"].lower() ] if n["remote_chassis_id_subtype"] == 3: n["remote_chassis_id"] = MACAddressParameter().clean(n["remote_chassis_id"]) # Convert port id n["remote_port_subtype"] = self.PORT_TYPES[n["remote_port_subtype"].lower()] if n["remote_port_subtype"] == 3: n["remote_port"] = MACAddressParameter().clean(n["remote_port"]) if n.get("remote_port_description") in ["--", "NA", "N/A"]: del n["remote_port_description"] if n.get("remote_system_description") in ["--", "NA", "N/A"]: del n["remote_system_description"] if n.get("remote_system_name") in ["--", "NA", "N/A"]: del n["remote_system_name"] # Process capabilities caps = 0 cs = n.get("remote_capabilities", "").replace(",", " ") for c in cs.split(): caps |= self.CAPS[c.lower().strip()] n["remote_capabilities"] = caps neighbors += [n] if neighbors: r += [{"local_interface": local_iface, "neighbors": neighbors}] return r
def execute_cli(self, **kwargs): r = {} # v = self.cli("display ont info 0 all") for c in ("display ont info 0 all", "display ont version 0 all"): v = self.cli(c) for table in v.split("\n\n"): tables_data = [] parts = self.splitter.split(table) parts = parts[1:] while len(parts) > 2: header, body = parts[:2] parts = parts[2:] header = header.splitlines() if len(header[0]) - len(header[0].lstrip()) - 2: # pylint: disable=line-too-long # Align first line by two whitespace if header: # ' -----------------------------------------------------------------------------', # ' F/S/P ONT SN Control Run Config Match Protect', # ' ID flag state state state side', # ' -----------------------------------------------------------------------------' header[0] = header[0][len(header[0]) - len(str.lstrip(header[0])) - 2:] head = parse_table_header(header) del head[2] # remove empty header tables_data += self.profile.parse_table1(body, head) else: pass # summary = parts for t in tables_data: if "Config state" in t and t["Config state"][ 0] in self.INACTIVE_STATE: continue if "ONT-ID" in t: ont_id = "%s/%s" % (t["F/S/P"][0].replace( " ", ""), t["ONT-ID"][0]) if ont_id in r: r[ont_id]["description"] = t["Description"][0] continue if "F/S/P/ONT-ID" in t: ont_id = t["F/S/P/ONT-ID"][0].replace(" ", "") if ont_id in r: r[ont_id].update({ "vendor": t["Vendor ID"][0], "model": t["ONT"][0] + t["Model"][0] if t["Model"] else "", "version": t["Software Version"][0] if t["Software Version"] else "", }) continue status = "other" if "ONT ID" in t: ont_id, serial = t["ONT ID"][0].split() status = self.status_map[t["Run state"][0]] elif "ONT" in t: # ----------------------------------------------------------------------------- # F/S/P ONT SN Control Run Config Match Protect # ID flag state state state side # ----------------------------------------------------------------------------- # self.logger.warning("Shift header row. %s" % header) ont_id, serial = t["ONT"][0].split() status = self.status_map[t["Run ID"][0]] # else: # self.logger.warning("Unknown ID") # continue ont_id = "%s/%s" % (t["F/S/P"][0].replace(" ", ""), ont_id) r[ont_id] = { "interface": t["F/S/P"][0].replace(" ", ""), "status": status, "id": ont_id, "global_id": serial + t["SN"][0], "type": "ont", "serial": serial + t["SN"][0], "description": "", "location": "", } for ont_id in r: # if r[ont_id]["status"] != "active": # continue v = self.cli("display ont info %s %s %s %s" % tuple(ont_id.split("/"))) parts = self.splitter.split(v) parse_result = parse_kv(self.detail_map, parts[1]) try: r[ont_id]["distance"] = float( parse_result.get("ont_distance", 0)) except ValueError: pass address = parse_result.get("ont_address", "") if address: r[ont_id]["ip"] = parse_result.get("ont_address", "").split("/")[0] return list(six.itervalues(r))
def collect_cpe_metrics_cli(self, metrics): # ifaces = set(m.path[-1].split("/")[:2] for m in metrics) onts = self.scripts.get_cpe_status() # Getting ONT List self.cli("config") iface = None for cc in sorted(onts, key=lambda x: x["interface"].split("/")): if cc.get("status", "") != "active": continue frame, slot, port, cpe_id = cc["id"].split("/") if iface != (frame, slot): if iface is not None: self.cli("quit") iface = (frame, slot) self.cli("interface gpon %s/%s" % iface) # Fix from cpes ipath = [cc["global_id"], "", "", "0"] mpath = ["", "", "", "/".join([frame, slot, port])] v = self.cli("display ont optical-info %s %s" % (port, cpe_id)) m = parse_kv(self.kv_map, v) self.logger.debug("Collect %s, %s, %s", m, ipath, mpath) if m.get("temp_c", "-") != "-": self.set_metric( id=("Interface | DOM | Temperature", mpath), metric="Interface | DOM | Temperature", path=ipath, value=float(m["temp_c"]), multi=True, ) if m.get("voltage_v", "-") != "-": self.set_metric( id=("Interface | DOM | Voltage", mpath), metric="Interface | DOM | Voltage", path=ipath, value=float(m["voltage_v"]), multi=True, ) if m.get("optical_rx_dbm", "-") != "-": self.set_metric( id=("Interface | DOM | RxPower", mpath), metric="Interface | DOM | RxPower", path=ipath, value=float(m["optical_rx_dbm"]), multi=True, ) if m.get("optical_rx_dbm_cpe", "-") != "-": self.set_metric( id=("Interface | DOM | RxPower", mpath), metric="Interface | DOM | RxPower", path=["", "", "", cc["interface"], cc["id"]], value=float(m["optical_rx_dbm_cpe"] if "," not in m["optical_rx_dbm_cpe"] else m["optical_rx_dbm_cpe"].split(",")[0]), multi=True, ) if m.get("current_ma", "-") != "-": self.set_metric( id=("Interface | DOM | Bias Current", mpath), metric="Interface | DOM | Bias Current", path=ipath, value=float(m["current_ma"]), multi=True, ) if m.get("optical_tx_dbm", "-") != "-": self.set_metric( id=("Interface | DOM | TxPower", mpath), metric="Interface | DOM | TxPower", path=ipath, value=float(m["optical_tx_dbm"]), multi=True, ) v = self.cli("display statistics ont-line-quality %s %s" % (port, cpe_id)) m = parse_kv(self.kv_map, v) if m.get("optical_errors_bip_out", "-") != "-": self.set_metric( id=("Interface | Errors | BIP | Out", mpath), metric="Interface | Errors | BIP | Out", path=ipath, value=int(m["optical_errors_bip_out"]), multi=True, ) if m.get("optical_errors_bip_in", "-") != "-": self.set_metric( id=("Interface | Errors | BIP | In", mpath), metric="Interface | Errors | BIP | In", path=ipath, value=int(m["optical_errors_bip_in"]), multi=True, ) self.cli("quit") self.cli("quit")