diff --git a/sa/profiles/SKS/SKS/get_interfaces.py b/sa/profiles/SKS/SKS/get_interfaces.py index 2f800859d9cc27ec9bfd4e5a462dae61cca9fda7..3ede668b61c4fb2d9072651bd99f65686783c8a2 100644 --- a/sa/profiles/SKS/SKS/get_interfaces.py +++ b/sa/profiles/SKS/SKS/get_interfaces.py @@ -58,6 +58,8 @@ class Script(BaseScript): IFTYPES = { "100BASE-TX": "physical", "Giga-TX": "physical", + "Giga-FX": "physical", + "Giga-FX-SFP": "physical", "Giga-Combo-TX": "physical", "EtherSVI": "SVI", "Null": "null" diff --git a/sa/profiles/SKS/SKS/get_lldp_neighbors.py b/sa/profiles/SKS/SKS/get_lldp_neighbors.py index d8b4d327988451d7b427cd214505d982928090ae..5b44f22de1a47adc8305d20feb593f691d97720c 100644 --- a/sa/profiles/SKS/SKS/get_lldp_neighbors.py +++ b/sa/profiles/SKS/SKS/get_lldp_neighbors.py @@ -6,6 +6,9 @@ # See LICENSE for details # --------------------------------------------------------------------- + +# Python modules +import re # NOC modules from noc.core.script.base import BaseScript from noc.sa.interfaces.igetlldpneighbors import IGetLLDPNeighbors @@ -17,6 +20,18 @@ class Script(BaseScript): name = "SKS.SKS.get_lldp_neighbors" interface = IGetLLDPNeighbors + rx_neighbor = re.compile( + r"^chassis id: (?P\S+)\s*\n" + r"^port id: (?P\S+)\s*\n" + r"^port description:(?P.*)\n" + r"^system name:(?P.*)\n" + r"^system description:(?P.*)\n" + r"^Time remaining: \d+\s*\n" + r"^system capabilities:.*\n" + r"^enabled capabilities:(?P.*?)\n", + re.MULTILINE | re.DOTALL + ) + def execute(self): r = [] try: @@ -79,4 +94,57 @@ class Script(BaseScript): "local_interface": i[0], "neighbors": [neighbor] }] + if t == []: + for iface in self.scripts.get_interface_status(): + c = self.cli( + "show lldp neighbors interface %s" % iface["interface"], + ignore_errors=True + ) + c = c.replace("\n\n", "\n") + match = self.rx_neighbor.search(c) + if match: + chassis_id = match.group("chassis_id") + if is_ipv4(chassis_id) or is_ipv6(chassis_id): + chassis_id_subtype = 5 + elif is_mac(chassis_id): + chassis_id_subtype = 4 + else: + chassis_id_subtype = 7 + port_id = match.group("port_id") + if is_ipv4(port_id) or is_ipv6(port_id): + port_id_subtype = 4 + elif is_mac(port_id): + port_id_subtype = 3 + else: + port_id_subtype = 7 + caps = 0 + if match.group("caps").strip(): + for c in match.group("caps").split(): + c = c.strip() + if c: + caps |= { + "O": 1, "P": 2, "B": 4, + "W": 8, "R": 16, "r": 16, "T": 32, + "C": 64, "S": 128 + }[c] + neighbor = { + "remote_chassis_id": chassis_id, + "remote_chassis_id_subtype": chassis_id_subtype, + "remote_port": port_id, + "remote_port_subtype": port_id_subtype, + "remote_capabilities": caps + } + port_descr = match.group("port_descr").strip() + system_name = match.group("system_name").strip() + system_descr = match.group("system_descr").strip() + if bool(port_descr): + neighbor["remote_port_description"] = port_descr + if bool(system_name): + neighbor["remote_system_name"] = system_name + if bool(system_descr): + neighbor["remote_system_description"] = system_descr + r += [{ + "local_interface": iface["interface"], + "neighbors": [neighbor] + }] return r diff --git a/sa/profiles/SKS/SKS/get_spanning_tree.py b/sa/profiles/SKS/SKS/get_spanning_tree.py index 2c40bcb10984b95cd8362c22f3b1495020234d85..108744828ca6aa928742065453353319ba4a3d74 100644 --- a/sa/profiles/SKS/SKS/get_spanning_tree.py +++ b/sa/profiles/SKS/SKS/get_spanning_tree.py @@ -18,8 +18,9 @@ class Script(BaseScript): name = "SKS.SKS.get_spanning_tree" interface = IGetSpanningTree - rx_mode = re.compile( + rx_mode1 = re.compile( r"^\s*Spanning tree enabled mode (?P\S+)") + rx_mode2 = re.compile("^\s*(?P\S+STP)\s+\(running\)") rx_mstp = re.compile( r"^\s*Name: (?P\S+)\s*\n" r"^\s*Revision: (?P\d+)", re.MULTILINE) @@ -45,8 +46,14 @@ class Script(BaseScript): "^\s*Root ID\s+ Priority\s+(?P\d+)\s*\n" "^\s*Address\s+(?P\S+)\s*\n" "^\s*This switch is the root\s*\n", re.MULTILINE) + rx_inst3 = re.compile( + "^\s*The bridge has priority (?P\d+), " + r"address (?P\S+)\s*\n" + r"^\s*Configured hello time \d+, max age \d+, forward time \d+\s*\n" + r"^\s*We are the root of the spanning tree\s*\n", + re.MULTILINE) rx_vlans = re.compile("^0\s+(?P\S+)\s+enabled", re.MULTILINE) - rx_port = re.compile( + rx_port1 = re.compile( "^\s*Port (?P\S+) (?:enabled|disabled)\s*\n" "^\s*State: (?P\S+)\s+Role: (?P\S+)\s*\n" "^\s*Port id: (?P\S+)\s+Port cost: (?P\d+)\s*\n" @@ -57,13 +64,32 @@ class Script(BaseScript): "^\s*Designated port id: (?P\S+)\s+" "Designated path cost: \d+\s*\n", re.MULTILINE) + rx_port2 = re.compile( + r"^\s*Port \d+ \((?P\S+)\) of RSTP is (?P\S+)\s*\n" + r"^\s*Edge port\(\S+\), Link type is .+\n" + r"^\s*Port Identifier (?P\S+), Port role (?P\S+)\s*\n" + r"^\s*Port path cost \d+, Port priority (?P\d+)\s*\n" + r"^\s*Designated root has priority \d+, address \S+\s*\n" + r"^\s*Designated bridge has priority " + r"(?P\d+), address " + r"(?P\S+)\s*\n" + r"^\s*Designated port id is (?P\S+)", + re.MULTILINE) + PORT_STATE = { + "Forwarding": "forwarding" + } + PORT_ROLE = { + "DesignatedPort": "designated" + } def execute(self): try: v = self.cli("show spanning-tree detail") except self.CLISyntaxError: return {"mode": "None", "instances": []} - match = self.rx_mode.search(v) + match = self.rx_mode1.search(v) + if not match: + match = self.rx_mode2.search(v) mode = match.group("mode") stp = {"mode": mode, "instances": []} if mode == "MSTP": @@ -102,19 +128,28 @@ class Script(BaseScript): inst["vlans"] = "1-4095" else: match = self.rx_inst2.search(v) - inst = match.groupdict() - inst["id"] = 0 - inst["bridge_priority"] = inst["root_priority"] - inst["bridge_id"] = inst["root_id"] - inst["interfaces"] = [] - try: - c = self.cli("show spanning-tree mst-configuration") - match = self.rx_vlans.search(c) - inst["vlans"] = match.group("vlans") - except self.CLISyntaxError: + if match: + inst = match.groupdict() + inst["id"] = 0 + inst["bridge_priority"] = inst["root_priority"] + inst["bridge_id"] = inst["root_id"] + inst["interfaces"] = [] + try: + c = self.cli("show spanning-tree mst-configuration") + match = self.rx_vlans.search(c) + inst["vlans"] = match.group("vlans") + except self.CLISyntaxError: + inst["vlans"] = "1-4095" + else: + match = self.rx_inst3.search(v) + inst = match.groupdict() + inst["id"] = 0 + inst["bridge_priority"] = inst["root_priority"] + inst["bridge_id"] = inst["root_id"] + inst["interfaces"] = [] inst["vlans"] = "1-4095" for port in v.split("\n\n"): - match = self.rx_port.search(port) + match = self.rx_port1.search(port) if match: iface = match.groupdict() iface["point_to_point"] = "Type: P2P" in port @@ -122,5 +157,17 @@ class Script(BaseScript): match.group("port_id").split(".")[0] iface["edge"] = False inst["interfaces"] += [iface] + else: + match = self.rx_port2.search(port) + if not port.strip().startswith("Port"): + continue + iface = match.groupdict() + iface["point_to_point"] = "auto ptop" in port + # iface["priority"] = \ + # match.group("port_id").split(".")[0] + iface["edge"] = "Edge port(TRUE)" in port + iface["role"] = self.PORT_ROLE[iface["role"]] + iface["state"] = self.PORT_STATE[iface["state"]] + inst["interfaces"] += [iface] stp["instances"] = [inst] return stp