Commit 990f93f2 authored by Dmitry Lukhtionov's avatar Dmitry Lukhtionov
Browse files

Merge branch 'update_NSN.TIMOS' into 'master'

update NSN.TIMOS

See merge request noc/noc!5875
parents 591b94e6 8d5bfe17
# ----------------------------------------------------------------------
# NSN.TIMOS.get_capabilities
# ----------------------------------------------------------------------
# Copyright (C) 2007-2020 The NOC Project
# Copyright (C) 2007-2021 The NOC Project
# See LICENSE for details
# ----------------------------------------------------------------------
......@@ -19,7 +19,10 @@ class Script(BaseScript):
name = "NSN.TIMOS.get_capabilities"
cache = True
CHECK_SNMP_GET = {"BRAS | IPoE": "1.3.6.1.4.1.6527.3.1.2.33.1.107.1.65.1"}
CHECK_SNMP_GET = {
"BRAS | IPoE": "1.3.6.1.4.1.6527.3.1.2.33.1.107.1.65.1",
"BRAS | PPPoE": "1.3.6.1.4.1.6527.3.1.2.33.5.9.1.2.1",
}
rx_lldp = re.compile(r"Admin Enabled\s+: True")
rx_port = re.compile(
r"^(?P<port>\d+/\d+/\d+)\s+(?:Up|Down)\s+(?:Yes|No)\s+"
......
# ---------------------------------------------------------------------
# NSN.TIMOS..get_dom_status
# ---------------------------------------------------------------------
# Copyright (C) 2007-2021 The NOC Project
# See LICENSE for details
# ---------------------------------------------------------------------
# NOC modules
from noc.core.script.base import BaseScript
from noc.sa.interfaces.igetdomstatus import IGetDOMStatus
class Script(BaseScript):
name = "NSN.TIMOS.get_dom_status"
interface = IGetDOMStatus
def execute_snmp(self, interface=None, **kwargs):
r = []
names = {v: k for k, v in self.scripts.get_ifindexes(name_oid="IF-MIB::ifName").items()}
for (
index,
temp_c,
voltage_v,
current_ma,
optical_tx_dbm,
optical_rx_dbm,
) in self.snmp.get_tables(
[
"1.3.6.1.4.1.6527.3.1.2.2.4.31.1.1",
"1.3.6.1.4.1.6527.3.1.2.2.4.31.1.6",
"1.3.6.1.4.1.6527.3.1.2.2.4.31.1.11",
"1.3.6.1.4.1.6527.3.1.2.2.4.31.1.16",
"1.3.6.1.4.1.6527.3.1.2.2.4.31.1.21",
],
bulk=False,
):
if temp_c == 2147483647:
continue
iface_index = index.rsplit(".", 1)[-1]
r += [
{
"interface": names[int(iface_index)],
"temp_c": float(temp_c) / 256,
"voltage_v": float(voltage_v) / 1000,
"current_ma": float(current_ma) / 500,
"optical_tx_dbm": float(optical_tx_dbm) / 100.0,
"optical_rx_dbm": float(optical_rx_dbm) / 100.0
if optical_rx_dbm != 2147483647
else 0,
}
]
return r
# ----------------------------------------------------------------------
# NSN.TIMOS.get_interfaces
# ----------------------------------------------------------------------
# Copyright (C) 2007-2020 The NOC Project
# Copyright (C) 2007-2021 The NOC Project
# See LICENSE for details
# ---------------------------------------------------------------------
......@@ -9,7 +9,7 @@
import re
# NOC modules
from noc.core.script.base import BaseScript
from noc.sa.profiles.Generic.get_interfaces import Script as BaseScript
from noc.sa.interfaces.igetinterfaces import IGetInterfaces
from noc.core.validators import is_int, is_ipv6, is_vlan
......
# ----------------------------------------------------------------------
# NSN.TIMOS.get_inventory
# ----------------------------------------------------------------------
# Copyright (C) 2007-2018 The NOC Project
# Copyright (C) 2007-2021 The NOC Project
# See LICENSE for details
# ----------------------------------------------------------------------
......@@ -56,6 +56,29 @@ class Script(BaseScript):
)
rx_date = re.compile(r"(?P<m>\d{2})(?P<d>\d{2})(?P<y>\d{4})")
CHASSIS_TYPES = {
1: "other",
2: "unknown",
3: "CHASSIS",
4: "container",
5: "PSU",
6: "FAN",
7: "sensor",
8: "IOM",
9: "CPM",
10: "CFM",
11: "MDA",
12: "flashDiskModule",
13: "port",
14: "mcm",
15: "CCM",
16: "oesCard",
17: "oesControlCard",
18: "oesUserPanel",
19: "alarmInputModule",
20: "pcm",
}
def get_date(self, d):
match = self.rx_date.search(d)
m = match.group("m")
......@@ -63,10 +86,41 @@ class Script(BaseScript):
y = match.group("y")
return "-".join([y, m, d])
def execute_snmp(self):
r = []
try:
for v in self.snmp.get_tables(
[
"1.3.6.1.4.1.6527.3.1.2.2.1.8.1.4", # part_no
"1.3.6.1.4.1.6527.3.1.2.2.1.8.1.5", # serial
"1.3.6.1.4.1.6527.3.1.2.2.1.8.1.6", # date
"1.3.6.1.4.1.6527.3.1.2.2.1.8.1.7", # type
"1.3.6.1.4.1.6527.3.1.2.2.1.8.1.8", # alias
],
max_retries=1,
):
if v[1] and (v[4] == 3 or v[4] == 8):
types = self.CHASSIS_TYPES[v[4]]
p = {
"type": types,
"vendor": "NSN",
"part_no": [v[1]],
"serial": v[2],
}
if type != "CHASSIS":
num = v[5]
p["number"] = num[-1]
if v[3].isdigit():
p["mfg_date"] = self.get_date(v[3])
r += [p]
except self.snmp.TimeOutError:
pass
return r
def execute_cli(self):
r = []
try:
v = self.cli("show chassis detail")
v = self.cli("show chassis detail ")
except self.CLISyntaxError:
v = self.cli("show chassis")
match = self.rx_ch.search(v)
......@@ -81,43 +135,43 @@ class Script(BaseScript):
p["description"] = match.group("type").strip()
r += [p]
v = self.cli("show card state")
for l in v.split("\n"):
for ll in v.split("\n"):
p = {}
match = self.rx_iom.search(l)
match = self.rx_iom.search(ll)
if match:
number = match.group("number")
p = {
"type": "IOM",
"number": number,
"vendor": "ALU",
"vendor": "NSN",
"part_no": [match.group("name")],
"description": [match.group("comments")],
"description": match.group("comments"),
}
c = self.cli("show card %s detail" % number)
match1 = self.rx_hw.search(c)
if match1:
p["part_no"] = match1.group("part_no")
p["part_no"] = [match1.group("part_no")]
p["serial"] = match1.group("serial")
p["mfg_date"] = self.get_date(match1.group("mfg_date"))
r += [p]
match = self.rx_imm.search(l)
match = self.rx_imm.search(ll)
if match:
number = match.group("number")
p = {
"type": "IMM",
"number": number,
"vendor": "ALU",
"vendor": "NSN",
"part_no": [match.group("name")],
}
c = self.cli("show card %s detail" % number)
match1 = self.rx_hw.search(c)
if match1:
p["part_no"] = match1.group("part_no")
p["part_no"] = [match1.group("part_no")]
p["serial"] = match1.group("serial")
p["mfg_date"] = self.get_date(match1.group("mfg_date"))
p["description"] = match1.group("platform")
r += [p]
match = self.rx_mda.search(l)
match = self.rx_mda.search(ll)
if match:
number = match.group("number")
p = {
......@@ -129,12 +183,12 @@ class Script(BaseScript):
c = self.cli("show mda %s/%s detail" % (match.group("slot"), number))
match1 = self.rx_hw.search(c)
if match1:
p["part_no"] = match1.group("part_no")
p["part_no"] = [match1.group("part_no")]
p["serial"] = match1.group("serial")
p["mfg_date"] = self.get_date(match1.group("mfg_date"))
p["description"] = match1.group("platform")
r += [p]
match = self.rx_sfm.search(l)
match = self.rx_sfm.search(ll)
if match:
number = match.group("number")
p = {
......@@ -146,7 +200,7 @@ class Script(BaseScript):
c = self.cli("show card %s detail" % number)
match1 = self.rx_hw.search(c)
if match1:
p["part_no"] = match1.group("part_no")
p["part_no"] = [match1.group("part_no")]
p["serial"] = match1.group("serial")
p["mfg_date"] = self.get_date(match1.group("mfg_date"))
p["description"] = match1.group("platform")
......@@ -165,7 +219,7 @@ class Script(BaseScript):
"revision": match1.group("revision"),
}
r += [p]
match = self.rx_cpm.search(l)
match = self.rx_cpm.search(ll)
if match:
number = match.group("number")
p = {
......@@ -177,7 +231,7 @@ class Script(BaseScript):
c = self.cli("show card %s detail" % number)
match1 = self.rx_hw.search(c)
if match1:
p["part_no"] = match1.group("part_no")
p["part_no"] = [match1.group("part_no")]
p["serial"] = match1.group("serial")
p["mfg_date"] = self.get_date(match1.group("mfg_date"))
p["description"] = match1.group("platform")
......
# ----------------------------------------------------------------------
# NSN.TIMOS.get_metrics
# ----------------------------------------------------------------------
# Copyright (C) 2007-2018 The NOC Project
# Copyright (C) 2007-2021 The NOC Project
# See LICENSE for details
# ----------------------------------------------------------------------
from noc.sa.profiles.Generic.get_metrics import Script as GetMetricsScript
# NOC modules
from noc.sa.profiles.Generic.get_metrics import Script as GetMetricsScript, metrics
class Script(GetMetricsScript):
name = "NSN.TIMOS.get_metrics"
@metrics(
["Subscribers | Summary"],
has_capability="BRAS | PPPoE",
volatile=False,
access="S",
)
def get_subscribers_metrics_snmp(self, metrics):
for oid, v in self.snmp.getnext("1.3.6.1.4.1.6527.3.1.2.33.1.106.1.2.1", bulk=False):
oid2 = oid.split("1.3.6.1.4.1.6527.3.1.2.33.1.106.1.2.1.")
slot = "slot "
slot += str(oid2[1])
if int(v) > 0:
self.set_metric(
id=("Subscribers | Summary", None),
labels=("noc::chassis::0", f"noc::slot::{slot}"),
value=int(v),
multi=True,
)
names = {x: y for y, x in self.scripts.get_ifindexes().items()}
for oid, v in self.snmp.getnext("1.3.6.1.4.1.6527.3.1.2.33.1.104.1.60.1", bulk=False):
oid2 = oid.split("1.3.6.1.4.1.6527.3.1.2.33.1.104.1.60.1.")
port = names[int(oid2[1])]
if int(v) > 0:
self.set_metric(
id=("Subscribers | Summary", None),
labels=("noc::chassis::0", f"noc::interface::{str(port)}"),
value=int(v),
multi=True,
)
metric = self.snmp.get("1.3.6.1.4.1.6527.3.1.2.33.5.9.1.2.1")
if metric:
self.set_metric(
id=("Subscribers | Summary", None),
labels=("noc::chassis::0",),
value=int(metric),
multi=True,
)
@metrics(
[
"Object | QoS | Dynamic Queue | Usage",
"Object | QoS | Dynamic Queue | Count",
"Object | QoS | Dynamic Policy | Usage",
"Object | QoS | Dynamic Policy | Count",
],
# has_capability="BRAS | PPPoE",
volatile=False,
access="S",
)
def get_qos_queue_metrics_snmp(self, metrics):
# QoS dynamic queue limit
qos_queue_limit = {}
for oid, v in self.snmp.getnext("1.3.6.1.4.1.6527.3.1.2.2.3.46.1.25"):
_, key = oid.split(".25.")
qos_queue_limit[tuple(key)] = float(v)
# QoS dynamic queue value
for oid, v in self.snmp.getnext("1.3.6.1.4.1.6527.3.1.2.2.3.46.1.26"):
_, key = oid.split(".26.")
self.set_metric(
id=("Object | QoS | Dynamic Queue | Count", None),
labels=[f"noc::slot::{key}"],
value=float(v),
multi=True,
)
self.set_metric(
id=("Object | QoS | Dynamic Queue | Usage", None),
labels=[f"noc::slot::{key}"],
value=round(float(v) * 100.0 / qos_queue_limit[tuple(key)]),
multi=True,
)
# QoS dynamic policer limit
qos_policer_limit = {}
for oid, v in self.snmp.getnext("1.3.6.1.4.1.6527.3.1.2.2.3.46.1.29"):
_, key = oid.split(".29.")
qos_policer_limit[tuple(key)] = float(v)
for oid, v in self.snmp.getnext("1.3.6.1.4.1.6527.3.1.2.2.3.46.1.30"):
_, key = oid.split(".30.")
self.set_metric(
id=("Object | QoS | Dynamic Policy | Count", None),
labels=[f"noc::slot::{key}"],
value=float(v),
multi=True,
)
self.set_metric(
id=("Object | QoS | Dynamic Policy | Usage", None),
labels=[f"noc::slot::{key}"],
value=round(float(v) * 100.0 / qos_policer_limit[tuple(key)]),
multi=True,
)
@metrics(
["Environment | Temperature"],
# has_capability="BRAS | PPPoE",
volatile=False,
access="S",
)
def get_temperature_metrics_snmp(self, metrics):
temperature = {}
# Name tmnxHwTemperature
for oid, v in self.snmp.getnext("1.3.6.1.4.1.6527.3.1.2.2.1.8.1.18.1", cached=True):
_, key = oid.split(".8.1.18.1.")
temperature[tuple(key)] = int(v)
# Name tmnxHwName
for oid, v in self.snmp.getnext("1.3.6.1.4.1.6527.3.1.2.2.1.8.1.8.1", cached=True):
_, key = oid.split(".8.1.8.1.")
if temperature[tuple(key)] > -128:
self.set_metric(
id=("Environment | Temperature", None),
labels=[
"noc::chassis::0",
"noc::slot::0",
f"noc::sensor::Temperature Sensor ({v})",
],
value=temperature[tuple(key)],
multi=True,
)
@metrics(
["DHCP | Pool | Used"],
has_capability="BRAS | PPPoE",
volatile=False,
access="S",
)
def get_dhcp_used_metrics_snmp(self, metrics):
for oid, v in self.snmp.getnext("1.3.6.1.4.1.6527.3.1.2.47.1.17.1.21"):
_, key = oid.split(".21.1.")
key = key.split(".")
pool = "".join([chr(int(c)) for c in key[1:-7]])
pool = pool.replace("\t", ":")
pool = pool.replace("\n", ":")
pool_ip = ".".join([c for c in key[-5:-1]])
pool_mask = key[-1:][0]
self.set_metric(
id=("DHCP | Pool | Used", None),
labels=[f"noc::dhcp::pool::{pool}", f"noc::dhcp::net::{pool_ip}/{pool_mask}"],
value=v,
multi=True,
)
@metrics(
["Environment | Sensor Status"],
volatile=False,
access="S",
)
def get_sensor_status(self, metrics):
v = self.snmp.get("1.3.6.1.4.1.6527.3.1.2.2.1.24.1.1.2.3.1.1", cached=True)
if v:
if v == 3:
v = 1
else:
v = 0
self.set_metric(
id=("Environment | Sensor Status", None),
labels=["noc::sensor::State Fan"],
value=v,
multi=True,
)
for oid, v in self.snmp.getnext("1.3.6.1.4.1.6527.3.1.2.2.1.24.2.1.6"):
if v == 3:
v = 1
else:
v = 0
self.set_metric(
id=("Environment | Sensor Status", None),
labels=[f"noc::sensor::State PSU {oid[-1]}"],
value=v,
multi=True,
)
@metrics(
[
"RADIUS | Requests",
"RADIUS | Responses",
],
# has_capability="BRAS | PPPoE",
volatile=False,
access="S",
)
def get_radius_metrics_snmp(self, metrics):
# tmnxRadSrvPlcyStatsTxRequests
for oid, v in self.snmp.getnext("1.3.6.1.4.1.6527.3.1.2.79.1.2.3.1.1"):
_, key = oid.split(".79.1.2.3.1.1.")
key = key.split(".")
name_radius = "".join([chr(int(c)) for c in key])
self.set_metric(
id=("RADIUS | Requests", None),
labels=[f"noc::radius::requests::{name_radius}"],
value=v,
multi=True,
)
# tmnxRadSrvPlcyStatsRxResponses
for oid, v in self.snmp.getnext("1.3.6.1.4.1.6527.3.1.2.79.1.2.3.1.2"):
_, key = oid.split(".79.1.2.3.1.2.")
key = key.split(".")
name_radius = "".join([chr(int(c)) for c in key])
self.set_metric(
id=("RADIUS | Responses", None),
labels=[f"noc::radius::responses::{name_radius}"],
value=v,
multi=True,
)
# ----------------------------------------------------------------------
# NSN.TIMOS.get_version
# ----------------------------------------------------------------------
# Copyright (C) 2007-2018 The NOC Project
# Copyright (C) 2007-2021 The NOC Project
# See LICENSE for details
# ----------------------------------------------------------------------
......@@ -11,6 +11,7 @@ import re
# NOC modules
from noc.core.script.base import BaseScript
from noc.sa.interfaces.igetversion import IGetVersion
from noc.core.mib import mib
class Script(BaseScript):
......@@ -20,6 +21,39 @@ class Script(BaseScript):
rx_sys = re.compile(r"System Type\s+:\s+(?P<platform>.+?)$", re.MULTILINE | re.DOTALL)
rx_ver = re.compile(r"System Version\s+:\s+(?P<version>.+?)$", re.MULTILINE | re.DOTALL)
rx_ver_snmp = re.compile(r"TiMOS-(?P<version>.+?)\s", re.MULTILINE | re.DOTALL)
CHASSIS_TYPES = {
2: "7750 SR-12",
4: "7750 SR-4",
5: "7750 SR-1",
6: "7750 SR-7",
14: "7750 SR-12e",
30: "7750 SR-1e",
31: "7750 SR-2e",
33: "7750 SR-3e",
37: "7750 SR-14s",
39: "7750 SR-1",
44: "7750 SR-7s",
46: "7750 SR-1s",
47: "7750 SR-2s",
}
def execute_snmp(self):
try:
v = self.snmp.get(mib["SNMPv2-MIB::sysDescr.0"], cached=True)
except (self.snmp.TimeOutError, self.snmp.SNMPError):
raise NotImplementedError()
if "TiMOS" in v:
match = self.re_search(self.rx_ver_snmp, v)
version = match.group("version")
for oid, v in self.snmp.getnext("1.3.6.1.4.1.6527.3.1.2.2.1.3.1.4", cached=True):
platform = self.CHASSIS_TYPES[v]
return {
"vendor": "NSN",
"platform": platform,
"version": version,
}
def execute_cli(self):
v = self.cli("show system information")
......
......@@ -2,16 +2,21 @@
# Vendor: NSN
# OS: TIMOS
# ----------------------------------------------------------------------
# Copyright (C) 2007-2018 The NOC Project
# Copyright (C) 2007-2021 The NOC Project
# See LICENSE for details
# ----------------------------------------------------------------------
# Python modules
import re
# NOC modules
from noc.core.profile.base import BaseProfile
class Profile(BaseProfile):
name = "NSN.TIMOS"
pattern_username = "[Ll]ogin: "
pattern_password = "[Pp]assword: "
pattern_prompt = r"^\S+?#"
pattern_more = r"^Press any key to continue.*$"
pattern_syntax_error = r"Error: Bad command\.|Error: Invalid parameter\."
......@@ -20,8 +25,27 @@ class Profile(BaseProfile):
config_volatile = [r"^# Finished.*$", r"^# Generated.*$"]
command_more = " "
rogue_chars = [re.compile(rb"\r\s+\r"), b"\r"]
config_tokenizer = "indent"
config_tokenizer_settings = {"line_comment": "#", "end_of_context": "exit", "string_quote": '"'}
rx_port_name = re.compile(r"(\d+\/\d+\/\d+)")
def convert_interface_name(self, s):
"""
>>> Profile().convert_interface_name("0/1/1")
'port0/1/1'
"""
if self.rx_port_name.match(s):
return "port%s" % s
if "," in s:
s = s.split(",", 1)[0].strip()
return s
INTERFACE_TYPES = {
"port": "physical",
"lag-": "aggregated",
}
@classmethod
def get_interface_type(cls, name):
return cls.INTERFACE_TYPES.get(name[:4].lower())