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): 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 collect_cpe_metrics(self, metrics): onts = self.scripts.get_cpe_status() # Getting ONT List self.cli("config") self.cli("interface gpon 0/0") # Fix from cpes for cc in onts: if cc.get("status", "") != "active": continue frame, slot, port, cpe_id = cc["id"].split("/") 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") is not None: 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") is not None: 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") is not None: 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") is not None: 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") is not None: 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") is not None: self.set_metric(id=("Interface | DOM | TxPower", mpath), metric="Interface | DOM | TxPower", path=ipath, value=float(m["optical_tx_dbm"]), multi=True) self.cli("quit") self.cli("quit")
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.path): 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 ("", 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=("SLA | UDP RTT", ("", 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", ("", probe_id)), metric="SLA | JITTER", value=float(jitter) * 1000, multi=True, )
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(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 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 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 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 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 get_ip_sla_metrics(self): """ Returns collected ip sla metrics in form probe id -> { rtt: RTT in seconds } :return: """ 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 {} # r = defaultdict(dict) r = {} for probe_id, data in zip(r_v[1::2], r_v[2::2]): p = parse_kv(metric_map, data) if "rtt" in p: # Latest RTT: 697 milliseconds rtt = p["rtt"].split()[0] try: r[("", probe_id, "SLA | UDP RTT")] = float(rtt) * 1000 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] r[("", probe_id, "SLA | JITTER")] = float(jitter) * 1000 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 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": "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 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")
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): 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))