Commit 2b22e129 authored by Dmitry Lukhtionov's avatar Dmitry Lukhtionov
Browse files

Add initial support for 3Com Superstack 3 5500

parent 57a800b6
{
"name": "3Com | SuperStack3 | 4500 sysObjectID",
"$collection": "sa.profilecheckrules",
"uuid": "a1e5264a-da4a-4e59-b8c5-31fdc689f6fb",
"description": null,
"preference": 10,
"method": "snmp_v2c_get",
"param": "SNMPv2-MIB::sysObjectID.0",
"match_method": "contains",
"value": "1.3.6.1.4.1.43.1.16.4.3.",
"action": "match",
"profile__name": "3Com.SuperStack3_4500"
}
# ----------------------------------------------------------------------
# 3Com.SuperStack3_4500.get_chassis_id
# ----------------------------------------------------------------------
# Copyright (C) 2007-2016 The NOC Project
# Copyright (C) 2007-2022 The NOC Project
# See LICENSE for details
# ----------------------------------------------------------------------
......@@ -18,11 +18,23 @@ class Script(BaseScript):
interface = IGetChassisID
cache = True
rx_mac = re.compile(r"Hardware address is (?P<mac>\S+)$", re.MULTILINE)
rx_mac = re.compile(
r"(?:Hardware address is|First mac address\s+:|MAC_ADDRESS\s+:|Hardware Address:) "
r"(?P<mac>\S+)\s*$",
re.MULTILINE,
)
def execute(self):
def execute_cli(self):
macs = []
for match in self.rx_mac.finditer(self.cli("display interface")):
try:
v = self.cli("display device manuinfo", cached=True)
match = self.rx_mac.search(v)
if match:
macs += [match.group("mac")]
except self.CLISyntaxError:
pass
v = self.cli("display interface", cached=True)
for match in self.rx_mac.finditer(v):
if match.group("mac") not in macs:
macs += [match.group("mac")]
macs.sort()
......
# ----------------------------------------------------------------------
# 3Com.SuperStack3_4500.get_interfaces
# ----------------------------------------------------------------------
# Copyright (C) 2007-2022 The NOC Project
# See LICENSE for details
# ----------------------------------------------------------------------
# Python modules
import re
# NOC modules
from noc.sa.profiles.Generic.get_interfaces import Script as BaseScript
from noc.sa.interfaces.igetinterfaces import IGetInterfaces
class Script(BaseScript):
name = "3Com.SuperStack3_4500.get_interfaces"
interface = IGetInterfaces
rx_iface = re.compile(
r"^\s*(?P<iface>\S+) current state :\s*(?P<status>(UP|DOWN|ADMINISTRATIVELY DOWN))\s*\n",
re.MULTILINE,
)
rx_descr = re.compile(r"^\s*Description\s*:(?P<description>.+)\s*\n", re.MULTILINE)
rx_mac = re.compile(r"Hardware address is (?P<mac>\S+)")
rx_mtu = re.compile(
r"^\s*The Maximum (?:Frame Length|Transmit Unit) is (?P<mtu>\d+)", re.MULTILINE
)
rx_pvid = re.compile(r"^\s*PVID: (?P<pvid>\d+)", re.MULTILINE)
rx_type = re.compile(r"^\s*Port link-type: (?P<type>access|trunk|stack)", re.MULTILINE)
rx_tagged = re.compile(r"^\s*VLAN permitted: (?P<tagged>.+)\s*\n", re.MULTILINE)
rx_tagged2 = re.compile(r"^\s*Tagged(?:\s+VLAN ID ): (?P<tagged>.+)\s*\n", re.MULTILINE)
rx_ip = re.compile(r"^\s*Internet Address is (?P<ip>\S+) Primary\s*\n", re.MULTILINE)
def execute_cli(self):
interfaces = []
ifaces = self.cli("display interface", cached=True)
for i in ifaces.split("\n\n"):
match = self.rx_iface.search(i)
if match:
ifname = match.group("iface")
o_stat = match.group("status") == "UP"
a_stat = match.group("status") != "ADMINISTRATIVELY DOWN"
iface = {
"name": ifname,
"type": self.profile.get_interface_type(ifname),
"admin_status": a_stat,
"oper_status": o_stat,
"subinterfaces": [],
}
sub = {
"name": ifname,
"admin_status": a_stat,
"oper_status": o_stat,
}
match = self.rx_descr.search(i)
if match:
iface["description"] = match.group("description").strip()
match = self.rx_mac.search(i)
if match:
iface["mac"] = match.group("mac")
sub["mac"] = match.group("mac")
match = self.rx_mtu.search(i)
if match:
iface["mtu"] = match.group("mtu")
sub["mtu"] = match.group("mtu")
match = self.rx_type.search(i)
if match:
sub["enabled_afi"] = ["BRIDGE"]
if match.group("type") in ["trunk", "stack"]:
match = self.rx_tagged.search(i)
if match:
tagged = match.group("tagged")
else:
match = self.rx_tagged2.search(i)
tagged = match.group("tagged")
tagged = tagged.replace("(default vlan)", "")
tagged = tagged.replace("all", "1-4094")
sub["tagged_vlans"] = self.expand_rangelist(tagged)
match = self.rx_pvid.search(i)
sub["untagged_vlan"] = match.group("pvid")
match = self.rx_ip.search(i)
if match:
sub["enabled_afi"] = ["IPv4"]
sub["ipv4_addresses"] = [match.group("ip")]
if ifname.startswith("Vlan-interface"):
vlan_id = ifname[14:]
sub["vlan_ids"] = vlan_id
iface["subinterfaces"] = [sub]
interfaces += [iface]
return [{"interfaces": interfaces}]
......@@ -18,7 +18,7 @@ class Script(BaseScript):
interface = IGetMACAddressTable
rx_line = re.compile(
r"^(?P<mac>\S+)\s+(?P<vlan_id>\d+)\s+(?P<type>\S+)\s+" r"(?P<interfaces>\S+)\s+\S+$",
r"^(?P<mac>\S+)\s+(?P<vlan_id>\d+)\s+(?P<type>\S+)\s+(?P<interfaces>\S+)\s+\S+",
re.MULTILINE,
)
......
# ----------------------------------------------------------------------
# 3Com.SuperStack3_4500.get_version
# ----------------------------------------------------------------------
# Copyright (C) 2007-2016 The NOC Project
# Copyright (C) 2007-2022 The NOC Project
# See LICENSE for details
# ----------------------------------------------------------------------
......@@ -19,19 +19,31 @@ class Script(BaseScript):
cache = True
rx_version = re.compile(
r"^SuperStack 3 Switch (?P<platform>\S+).+" r"Software Version (?P<version>.+)$",
r"^SuperStack 3 Switch (?P<platform>\S+).+Software Version (?P<version>.+)$",
re.MULTILINE,
)
rx_version2 = re.compile(
r"Switch (?P<platform>\S+).+Software Version 3Com OS (?P<version>.+)$",
re.MULTILINE,
)
rx_dev = re.compile(
r"0\s+0\s+\d+\s+(?P<hardware>\S+)\s+\S+\s+\S+\s+(?P<bootprom>\S+)", re.MULTILINE
)
rx_dev2 = re.compile(
r"0\s+\d+\s+(?P<hardware>\S+)\s+\S+\s+\S+\s+(?P<bootprom>\S+)", re.MULTILINE
)
rx_serial = re.compile(r"^\s+Product serial number: (?P<serial>\S)\s+\n", re.MULTILINE)
def execute(self):
def execute_cli(self):
v = self.cli("display version", cached=True)
match = self.rx_version.search(v)
if not match:
match = self.rx_version2.search(v)
v = self.cli("display device", cached=True)
match1 = self.rx_dev.search(v)
return {
if not match1:
match1 = self.rx_dev2.search(v)
r = {
"vendor": "3Com",
"platform": match.group("platform"),
"version": match.group("version"),
......@@ -40,3 +52,11 @@ class Script(BaseScript):
"HW version": match1.group("hardware"),
},
}
try:
v = self.cli("display device manuinfo", cached=True)
match = self.rx_serial.search(v)
if match:
r["attributes"]["Serial Number"] = match.group("serial")
except self.CLISyntaxError:
pass
return r
......@@ -2,10 +2,13 @@
# Vendor: 3Com
# OS: SuperStack3_4500
# ----------------------------------------------------------------------
# Copyright (C) 2007-2016 The NOC Project
# Copyright (C) 2007-2022 The NOC Project
# See LICENSE for details
# ----------------------------------------------------------------------
# Python modules
import re
# NOC modules
from noc.core.profile.base import BaseProfile
......@@ -13,15 +16,29 @@ from noc.core.profile.base import BaseProfile
class Profile(BaseProfile):
name = "3Com.SuperStack3_4500"
pattern_more = [
(rb"^\s+---- More ----$", b" "),
(rb"^ +---- More ----$", b" "),
(rb"The current configuration will be written to the device. Are you sure? [Y/N]:", b"Y"),
(rb"(To leave the existing filename unchanged, press the enter key):", b"\n"),
(rb"flash:/startup.cfg exists, overwrite? [Y/N]:", b"Y"),
]
pattern_prompt = rb"^[<\[]\S+[>\]]"
pattern_syntax_error = rb"^\s+% (Unrecognized|Incomplete) command found at '\^' position.$"
pattern_syntax_error = rb"\s+% (?:Unrecognized|Incomplete) command found at '\^' position."
rogue_chars = [re.compile(rb"\x1b\[42D\s+\x1b\[42D"), b"\r"]
command_save_config = "save"
command_enter_config = "system-view"
command_leave_config = "return"
command_exit = "quit"
convert_interface_name = BaseProfile.convert_interface_name_cisco
INTERFACE_TYPES = {
"Et": "physical", # Ethernet
"Gi": "physical", # GigabitEthernet
"Po": "aggregated", # Aggregated
"Lo": "loopback", # LoopBack
"NU": "null", # NULL
"Vl": "SVI", # Vlan-interface
}
@classmethod
def get_interface_type(cls, name):
return cls.INTERFACE_TYPES.get(name[:2])
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment