Details
-
Type: New Feature
-
Status: Resolved
-
Priority: Minor
-
Resolution: Fixed
-
Affects Version/s: 0.7(4)
-
Fix Version/s: 0.8
-
Component/s: SA
-
Labels:
-
Environment:
./scripts/about
NOC 0.7(4)r6933 OS FreeBSD stats.line-r.ru 8.2-RELEASE-p2 FreeBSD 8.2-RELEASE-p2 #0: Mon Aug 15 13:33:26 MSD 2011 netroot@stats.line-r.ru:/usr/obj/usr/src/sys/GENERIC amd64 Python 2.7.2 (default, Aug 15 2011, 15:18:22) [GCC 4.2.1 20070719 [FreeBSD]] PostgreSQL PostgreSQL 9.0.4 MongoDB 2.0.6 (64bit) Python Path .:..:/usr/local/noc/scripts:/usr/local/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg:/usr/local/lib/python2.7/site-packages/flup-1.0.2-py2.7.egg:/usr/local/lib/python2.7/site-packages/Pygments-1.4-py2.7.egg:/usr/local/lib/python2.7/site-packages/MarkupSafe-0.15-py2.7-freebsd-8.2-RELEASE-p2-amd64.egg:/usr/local/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg:/usr/local/lib/python2.7/site-packages/Sphinx-1.0.7-py2.7.egg:/usr/local/lib/python2.7/site-packages/South-0.7.3-py2.7.egg:/usr/local/lib/python2.7/site-packages/pyasn1-0.0.13-py2.7.egg:/usr/local/lib/python2.7/site-packages/pysnmp-4.1.16c-py2.7.egg:/usr/local/lib/python2.7/site-packages/coverage-3.5-py2.7-freebsd-8.2-RELEASE-p2-amd64.egg:/usr/local/lib/python2.7/site-packages/WebOb-1.1rc1-py2.7.egg:/usr/local/lib/python2.7/site-packages/python_creole-0.7.3-py2.7.egg:/usr/local/lib/python2.7/site-packages/protobuf-2.4.1-py2.7.egg:/usr/local/lib/python2.7/site-packages/PyICU-1.1-py2.7-freebsd-8.2-RELEASE-p2-amd64.egg:/usr/local/lib/python2.7/site-packages/pymongo-2.2-py2.7-freebsd-8.2-RELEASE-p2-amd64.egg:/usr/local/lib/python2.7/site-packages/pycrypto-2.6-py2.7-freebsd-8.2-RELEASE-p2-amd64.egg:/usr/local/lib/python2.7/site-packages/psycopg2-2.4.5-py2.7-freebsd-8.2-RELEASE-p2-amd64.egg:/usr/local/lib/python2.7/site-packages/netifaces-0.8-py2.7-freebsd-8.2-RELEASE-p2-amd64.egg:/usr/local/lib/python2.7/site-packages/gmpy-1.15-py2.7-freebsd-8.2-RELEASE-p2-amd64.egg:/usr/local/lib/python27.zip:/usr/local/lib/python2.7:/usr/local/lib/python2.7/plat-freebsd8:/usr/local/lib/python2.7/lib-tk:/usr/local/lib/python2.7/lib-old:/usr/local/lib/python2.7/lib-dynload:/usr/local/lib/python2.7/site-packages psycopg2 2.4.5 (dt dec pq3 ext) pymongo 2.2 Sphinx 1.0.7 protobuf 2.4.1 tornado 2.2 python-creole 0.2.4 mongoengine 0.6.20 django 1.4.1 docutils 0.7 Pygments 1.2.2 Jinja2 2.2.1 coverage 3.5.1 pysnmp 4.2.1 pyasn1 0.1.2 south 0.7.3 django-tagging 0.3.1 ./scripts/about NOC 0.7(4)r6933 OS FreeBSD stats.line-r.ru 8.2-RELEASE-p2 FreeBSD 8.2-RELEASE-p2 #0: Mon Aug 15 13:33:26 MSD 2011 netroot@stats.line-r.ru:/usr/obj/usr/src/sys/GENERIC amd64 Python 2.7.2 (default, Aug 15 2011, 15:18:22) [GCC 4.2.1 20070719 [FreeBSD] ] PostgreSQL PostgreSQL 9.0.4 MongoDB 2.0.6 (64bit) Python Path .:..:/usr/local/noc/scripts:/usr/local/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg:/usr/local/lib/python2.7/site-packages/flup-1.0.2-py2.7.egg:/usr/local/lib/python2.7/site-packages/Pygments-1.4-py2.7.egg:/usr/local/lib/python2.7/site-packages/MarkupSafe-0.15-py2.7-freebsd-8.2-RELEASE-p2-amd64.egg:/usr/local/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg:/usr/local/lib/python2.7/site-packages/Sphinx-1.0.7-py2.7.egg:/usr/local/lib/python2.7/site-packages/South-0.7.3-py2.7.egg:/usr/local/lib/python2.7/site-packages/pyasn1-0.0.13-py2.7.egg:/usr/local/lib/python2.7/site-packages/pysnmp-4.1.16c-py2.7.egg:/usr/local/lib/python2.7/site-packages/coverage-3.5-py2.7-freebsd-8.2-RELEASE-p2-amd64.egg:/usr/local/lib/python2.7/site-packages/WebOb-1.1rc1-py2.7.egg:/usr/local/lib/python2.7/site-packages/python_creole-0.7.3-py2.7.egg:/usr/local/lib/python2.7/site-packages/protobuf-2.4.1-py2.7.egg:/usr/local/lib/python2.7/site-packages/PyICU-1.1-py2.7-freebsd-8.2-RELEASE-p2-amd64.egg:/usr/local/lib/python2.7/site-packages/pymongo-2.2-py2.7-freebsd-8.2-RELEASE-p2-amd64.egg:/usr/local/lib/python2.7/site-packages/pycrypto-2.6-py2.7-freebsd-8.2-RELEASE-p2-amd64.egg:/usr/local/lib/python2.7/site-packages/psycopg2-2.4.5-py2.7-freebsd-8.2-RELEASE-p2-amd64.egg:/usr/local/lib/python2.7/site-packages/netifaces-0.8-py2.7-freebsd-8.2-RELEASE-p2-amd64.egg:/usr/local/lib/python2.7/site-packages/gmpy-1.15-py2.7-freebsd-8.2-RELEASE-p2-amd64.egg:/usr/local/lib/python27.zip:/usr/local/lib/python2.7:/usr/local/lib/python2.7/plat-freebsd8:/usr/local/lib/python2.7/lib-tk:/usr/local/lib/python2.7/lib-old:/usr/local/lib/python2.7/lib-dynload:/usr/local/lib/python2.7/site-packages psycopg2 2.4.5 (dt dec pq3 ext) pymongo 2.2 Sphinx 1.0.7 protobuf 2.4.1 tornado 2.2 python-creole 0.2.4 mongoengine 0.6.20 django 1.4.1 docutils 0.7 Pygments 1.2.2 Jinja2 2.2.1 coverage 3.5.1 pysnmp 4.2.1 pyasn1 0.1.2 south 0.7.3 django-tagging 0.3.1
-
Difficulty:Medium
Description
Update profile EdgeCore.ES for supporting MRV MR2228N-4C (same with ES3528M)
Updated:
- get_interfaces.py
- get_portchannel.py
- get_switchport.py
- get_version.py
get_interfaces.py
# -*- coding: utf-8 -*- ##---------------------------------------------------------------------- ## EdgeCore.ES.get_interfaces ##---------------------------------------------------------------------- ## Copyright (C) 2007-2012 The NOC Project ## See LICENSE for details ##---------------------------------------------------------------------- """ """ # Python modules import re from collections import defaultdict # NOC modules from noc.lib.ip import IPv4 from noc.sa.script import Script as NOCScript from noc.sa.interfaces import IGetInterfaces, InterfaceTypeError, MACAddressParameter class Script(NOCScript): name = "EdgeCore.ES.get_interfaces" implements = [IGetInterfaces] TIMEOUT = 240 cache = True types = { "Eth": "physical", "Trunk": "aggregated", "VLAN": "SVI" } rx_ip_if_35 = re.compile(r".*?IP Address and Netmask:\s+(?P<ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+(?P<mask>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+on\s+(?P<name>[^\n]+?),\n", re.MULTILINE | re.IGNORECASE | re.DOTALL) rx_svi_name_stat_4612 = re.compile(r"(?P<name>Vlan[^\n]+?)\s+is\s+(?P<stat>up|down)", re.MULTILINE | re.IGNORECASE | re.DOTALL) rx_ip_if_4612 = re.compile(r".*?Interface address is\s+(?P<ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}),\s+mask is\s+(?P<mask>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})", re.MULTILINE | re.IGNORECASE | re.DOTALL) rx_svi_name_stat_3510MA = re.compile(r"(?P<name>Vlan[^\n]+?)\s+is Administrative\s+(?P<a_stat>Up|Down)\s+-\s+Link\s+(?P<o_stat>Up|Down)", re.MULTILINE | re.IGNORECASE | re.DOTALL) rx_ip_if_3510MA = re.compile(r".*?IP address:\s+(?P<ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+Mask:\s+(?P<mask>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})", re.MULTILINE | re.IGNORECASE | re.DOTALL) rx_lldp_35xx = re.compile(r"\s+LLDP Enable\s+\:\s+Yes", re.MULTILINE | re.IGNORECASE | re.DOTALL) rx_lldp_ports_35xx = re.compile(r".*?(?P<name>(Eth|Trunk)[^\n]+\d)\s+\|\s+(Rx|Tx-Rx)", re.MULTILINE | re.IGNORECASE | re.DOTALL) def execute(self): ifaces = {} current = None is_bundle = False is_svi = False vlan_ids = [] mac_svi = "" name_ = {} mac_ = {} snmp_ifindex_ = {} descr_ = {} stat_ = {} tagged_ = {} untagged_ = {} end_if = False # Tested only ES3510MA, ES3510, ES3526XAv2, ES3528M, ES3552M, ES4612, MRV MR2228N-4C if (self.match_version(platform__contains="4626")): raise self.NotSupportedError() # Get interface status for p in self.scripts.get_interface_status(): intf = p["interface"] name_[intf] = intf mac_[intf] = p["mac"] if "description" in p: descr_[intf] = p["description"] stat_[intf] = p["status"] if "snmp_ifindex" in p: snmp_ifindex_[intf] = p["snmp_ifindex"] # Get switchport's for p in self.scripts.get_switchport(): intf = p["interface"] if "tagged" in p: tagged_[intf] = p["tagged"] if "untagged" in p: untagged_[intf] = p["untagged"] # Get LLDP lldp = set() buf = self.cli("sh lldp config") for p in buf.splitlines(): match = self.rx_lldp_35xx.match(p) if match: for v in buf.splitlines(): match = self.rx_lldp_ports_35xx.match(v) if match: lldp.add(self.profile.convert_interface_name(match.group("name"))) # Get SVI interfaces on 4612 if (self.match_version(platform__contains="4612")): for ls in self.cli("show ip interface").splitlines(): match = self.rx_svi_name_stat_4612.search(ls) if match: ip_addr = [] sub = {} namesviif = match.group("name").upper() stat = match.group("stat") match = self.rx_ip_if_4612.search(ls) if match: ip = match.group("ip") mask = match.group("mask") ip_addr += [IPv4(ip, netmask = mask).prefix] if (ls.strip().startswith("Split")): if not ip_addr: continue type = "SVI" vlan_ids = [int(namesviif[5:])] mac_svi = mac_[namesviif] enabled_afi = ["IPv4"] sub = { "name": namesviif, "admin_status": stat == "up", "oper_status": stat == "up", "is_ipv4": True, "enabled_afi": enabled_afi, "ipv4_addresses": ip_addr, "vlan_ids": vlan_ids, "mac": mac_svi, } ifaces[namesviif] = { "name": namesviif, "admin_status": stat == "up", "oper_status": stat == "up", "type": type, "mac": mac_svi, "subinterfaces": [sub], } # Dirty-hack 3510/3526/3528/3552 managment SVI interface if (self.match_version(platform__contains="3510") or self.match_version(platform__contains="3526") or self.match_version(platform__contains="3528") or self.match_version(platform__contains="2228N") or self.match_version(platform__contains="3552")): # Dirty-hack 3510MA managment SVI interface if (self.match_version(platform__contains="3510MA")): for ls in self.cli("show ip interface").splitlines(): match = self.rx_svi_name_stat_3510MA.search(ls) if match: ip_addr = [] sub = {} namesviif = match.group("name").upper() a_stat = match.group("a_stat") o_stat = match.group("o_stat") match = self.rx_ip_if_3510MA.search(ls) if match: ip = match.group("ip") mask = match.group("mask") ip_addr = [IPv4(ip, netmask = mask).prefix] type = "SVI" enabled_afi = ["IPv4"] vlan_ids = [int(namesviif[5:])] if namesviif in mac_: mac_svi = mac_[namesviif] sub = { "name": namesviif, "admin_status": a_stat == "Up", "oper_status": o_stat == "Up", "is_ipv4": True, "enabled_afi": enabled_afi, "ipv4_addresses": ip_addr, "vlan_ids": vlan_ids, } if mac_svi: sub["mac"] = mac_svi ifaces[namesviif] = { "name": namesviif, "admin_status": a_stat == "Up", "oper_status": o_stat == "Up", "type": type, "subinterfaces": [sub], } if mac_svi: ifaces[namesviif]["mac"] = mac_svi # 3510/3526/3528/3552 for ls in self.cli("show ip interface").splitlines(): match = self.rx_ip_if_35.search(ls + "\n") if match: ip = match.group("ip") mask = match.group("mask") namesviif = match.group("name") ip_addr = IPv4(ip, netmask = mask).prefix status = "Up" type = "SVI" enabled_afi = ["IPv4"] vlan_ids = [int(namesviif[5:])] if namesviif in mac_: mac_svi = mac_[namesviif] sub = { "name": namesviif, "admin_status": status == "Up", "oper_status": status == "Up", "is_ipv4": True, "enabled_afi": enabled_afi, "ipv4_addresses": [ip_addr], "vlan_ids": vlan_ids, } if mac_svi: sub["mac"] = mac_svi ifaces[namesviif] = { "name": namesviif, "admin_status": status == "Up", "oper_status": status == "Up", "type": type, "subinterfaces": [sub], } if mac_svi: ifaces[namesviif]["mac"] = mac_svi # Pre-process portchannel members portchannel_members = {} for pc in self.scripts.get_portchannel(): i = pc["interface"] t = pc["type"] == "L" for m in pc["members"]: portchannel_members[m] = (i, t) # Simulate hard working # set name ifaces for current in name_: is_svi = current.startswith("VLAN") if is_svi: continue ifaces[current] = { "name": current } # other for current in ifaces: is_svi = current.startswith("VLAN") if is_svi: continue is_bundle = current.startswith("Trunk") if is_bundle: enabled_afi = ["BRIDGE"] ifaces[current]["mac"] = mac_[current] ifaces[current]["admin_status"] = stat_[current] ifaces[current]["oper_status"] = stat_[current] ifaces[current]["type"] = "aggregated" ifaces[current]["enabled_protocols"] = [] # Sub-interface sub = { "name": current, "admin_status": stat_[current], "oper_status": stat_[current], "is_bridge": True, "enabled_afi": enabled_afi, "tagged_vlans": tagged_[current], "untagged_vlan": untagged_[current], "mac": mac_[current], } if current in lldp: ifaces[current]["enabled_protocols"] += ["LLDP"] if current in descr_: ifaces[current]["description"] = descr_[current] sub["description"] = descr_[current] if current in snmp_ifindex_: sub["snmp_ifindex"] = snmp_ifindex_[current] ifaces[current]["subinterfaces"] = [sub] else: ifaces[current]["mac"] = mac_[current] ifaces[current]["admin_status"] = stat_[current] ifaces[current]["oper_status"] = stat_[current] ifaces[current]["type"] = "physical" ifaces[current]["enabled_protocols"] = [] enabled_afi = ["BRIDGE"] sub = { "name": current, "admin_status": stat_[current], "oper_status": stat_[current], "is_bridge": True, "enabled_afi": enabled_afi, "mac": mac_[current], } if current in lldp: ifaces[current]["enabled_protocols"] += ["LLDP"] if current in descr_: ifaces[current]["description"] = descr_[current] sub["description"] = descr_[current] if current in tagged_: sub["tagged_vlans"] = tagged_[current] if current in untagged_: sub["untagged_vlan"] = untagged_[current] if current in snmp_ifindex_: sub["snmp_ifindex"] = snmp_ifindex_[current] ifaces[current]["subinterfaces"] = [sub] # Portchannel member if current in portchannel_members: ai, is_lacp = portchannel_members[current] ifaces[current]["aggregated_interface"] = ai ifaces[current]["is_lacp"] = is_lacp ifaces[current]["enabled_protocols"] += ["LACP"] # Get VRFs and "default" VRF interfaces r = [] seen = set() vpns = [{ "name": "default", "type": "ip", "interfaces": [] }] for fi in vpns: # Forwarding instance rr = { "forwarding_instance": fi["name"], "type": fi["type"], "interfaces": [] } rd = fi.get("rd") if rd: rr["rd"] = rd # create ifaces rr["interfaces"] = ifaces.values() r += [rr] # Return result return r
get_portchannel.py
# -*- coding: utf-8 -*- ##---------------------------------------------------------------------- ## EdgeCore.ES.get_portchannel ##---------------------------------------------------------------------- ## Copyright (C) 2007-2009 The NOC Project ## See LICENSE for details ##---------------------------------------------------------------------- """ """ ## Python modules import re ## NOC modules from noc.sa.script import Script as NOCScript from noc.sa.interfaces import IGetPortchannel class Script(NOCScript): name = "EdgeCore.ES.get_portchannel" implements = [IGetPortchannel] cache = True rx_chan_line_3526 = re.compile(r"Information of (?P<interface>Trunk \d+).*?Member Ports(|\s+): (?P<members_str>[^\n]+)", re.IGNORECASE | re.DOTALL | re.MULTILINE) @NOCScript.match(platform__contains="4612") @NOCScript.match(platform__contains="3526") @NOCScript.match(platform__contains="3510") @NOCScript.match(platform__contains="2228N") @NOCScript.match(platform__contains="3528") @NOCScript.match(platform__contains="3552") def execute_3526(self): status = self.cli("show interface status") r = [] for match in self.rx_chan_line_3526.finditer(status): members = match.group("members_str").strip().rstrip(",").replace("Eth", "Eth ") r += [{ "interface": match.group("interface"), "members": members.split(", "), "type": "S" }] return r rx_chan_line_4626 = re.compile(r"Port-group number : (?P<number>\d+)", re.IGNORECASE | re.MULTILINE) rx_memb_line_4626 = re.compile(r"\n\d+\s+(?P<member>\S+)\s+(?P<mode>[^\n]+)", re.IGNORECASE | re.DOTALL | re.MULTILINE) @NOCScript.match(platform__contains="4626") def execute_4626(self): channels = self.cli("show port-group brief") r = [] for match in self.rx_chan_line_4626.finditer(channels): details = self.cli("show port-group %s port-channel" % match.group("number")) r += [{ "interface": "Port-Channel" + match.group("number"), "members": [memb.group("member") for memb in self.rx_memb_line_4626.finditer(details)], "type": "S", # <!> TODO: port-channel type detection }] return r @NOCScript.match() def execute_other(self): raise self.NotSupportedError()
get_switchport.py
# -*- coding: utf-8 -*- ##---------------------------------------------------------------------- ## EdgeCore.ES.get_switchport ##---------------------------------------------------------------------- ## Copyright (C) 2007-2011 The NOC Project ## See LICENSE for details ##---------------------------------------------------------------------- """ """ # Python modules import re # NOC modules from noc.sa.script import Script as NOCScript from noc.sa.interfaces import IGetSwitchport class Script(NOCScript): """ EdgeCore.ES.get_switchport @todo: ES4626 support @todo: QinQ """ name = "EdgeCore.ES.get_switchport" implements = [IGetSwitchport] cache = True rx_interface_3526 = re.compile(r"Information of (?P<interface>[^\n]+?)\n", re.MULTILINE | re.IGNORECASE | re.DOTALL) rx_interface_swport_3526 = re.compile( r"Information of (?P<interface>[^\n]+?)\n.*?VLAN Membership Mode(|\s+):\s+(?P<mode>[^\n]+?)\n.*?Native VLAN(|\s+):\s+(?P<native>\d+).*?Allowed VLAN(|\s+):\s+(?P<vlans>.*?)Forbidden VLAN(|\s+):", re.MULTILINE | re.IGNORECASE | re.DOTALL) rx_interface_qinq_3526 = re.compile( r"802.1Q-tunnel Status(|\s+):\s+(?P<qstatus>\S+).*?802.1Q-tunnel Mode(|\s+):\s+(?P<qmode>\S+)", re.MULTILINE | re.IGNORECASE | re.DOTALL) rx_interface_swport_4626 = re.compile( r"(?P<interface>[^\n]+)\n.*?Mode\s+:(?P<mode>\S+).*?Port VID\s+:(?P<pvid>\d+).*?", re.MULTILINE | re.IGNORECASE | re.DOTALL) def execute(self): r = [] # Get portchannels portchannel_members = {} # member -> (portchannel, type) for s in self.scripts.get_portchannel(): portchannel_members[s["interface"]] = s["members"] interface_status = {} # Interface -> status # Get interfaces status for s in self.scripts.get_interface_status(): interface_status[s["interface"]] = s["status"] if (self.match_version(platform__contains="3526") or self.match_version(platform__contains="3510") or self.match_version(platform__contains="2228N") or self.match_version(platform__contains="3528") or self.match_version(platform__contains="3552") or self.match_version(platform__contains="4612")): cmd = self.cli("show interface switchport") for block in cmd.rstrip("\n\n").split("\n\n"): matchint = self.rx_interface_3526.search(block) name = matchint.group("interface") swport = { "interface": name, "members": portchannel_members.get(name, ""), "802.1ad Tunnel": False, "802.1Q Enabled": False, "tagged": "", "status": interface_status.get(name, False) } if re.search(r"Member port of trunk \d+", block): # skip portchannel members r += [swport] continue match = self.rx_interface_swport_3526.search(block) if match.group("mode").lower() in ["hybrid", "trunk"]: swport["802.1Q Enabled"] = "True" # QinQ mqinq = self.rx_interface_qinq_3526.search(block) if mqinq and mqinq.group("qstatus").lower() == "enable": if mqinq.group("qmode").lower() in ["access"]: swport["802.1ad Tunnel"] = True # untagged/tagged p = re.compile("\)([^,]+?)(\d)") vlans = p.sub(r"),\g<2>", match.group("vlans").rstrip(",\n ")) vlans = vlans.replace(" ", "") untagged = None tagged = [] for i in vlans.split(","): m = re.search("(?P<vlan>\d+)\((?P<tag>u|t)\)", i) if m.group("tag") == "u": if m.group("vlan") == match.group("native"): untagged = m.group("vlan") else: tagged += [m.group("vlan")] if untagged: swport["untagged"] = untagged swport["tagged"] = tagged r += [swport] elif self.match_version(platform__contains="4626"): cmd = self.cli("show interface switchport") for block in cmd.split("\n\n"): match = self.rx_interface_swport_4626.search(block) name = match.group("interface") swport = {"interface": name, "members": portchannel_members.get(name, ""), "802.1ad Tunnel": False, "802.1Q Enabled": False, "tagged": "", "status": interface_status.get(name, False)} if re.search(r"Type :Aggregation member", block): # skip portchannel members r += [swport] continue if match.group("mode").lower() == "trunk": swport["802.1Q Enabled"] = "True" swport["untagged"] = match.group("pvid") tagged = [] p = re.search("Trunk allowed Vlan: (?P<tagged>[^\n]+?)(\n|$)", block) if p: swport["tagged"] = self.expand_rangelist( p.group("tagged").replace(";", ",")) r += [swport] else: raise self.NotSupportedError() return r
get_version.py
# -*- coding: utf-8 -*- ##---------------------------------------------------------------------- ## EdgeCore.ES.get_version ##---------------------------------------------------------------------- ## Copyright (C) 2007-2012 The NOC Project ## See LICENSE for details ##---------------------------------------------------------------------- """ """ ## Python modules import re ## NOC Modules from noc.sa.script import Script as NOCScript from noc.sa.interfaces import IGetVersion class Script(NOCScript): name = "EdgeCore.ES.get_version" cache = True implements = [IGetVersion] ## ## Main dispatcher ## def execute(self): s = "" if self.snmp and self.access_profile.snmp_ro: # Trying SNMP try: # SNMPv2-MIB::sysDescr.0 s = self.snmp.get("1.3.6.1.2.1.1.1.0", cached=True) # SNMPv2-MIB::sysObjectID.0 oid = self.snmp.get("1.3.6.1.2.1.1.2.0", cached=True) if oid == "": raise self.snmp.TimeOutError # Fallback to CLI if ", " in oid: oid = oid[1: -1].replace(", ", ".") if oid[-3:] == "2.4": # 3528M-SFP OID (v1.4.x.x) v = self.snmp.get(oid[: -3] + "1.4.1.1.3.1.6.1", cached=True) else: # 3526-Style OID v = self.snmp.get(oid + ".1.1.3.1.6.1", cached=True) if v == "": # 4626-Style OID v = self.snmp.get(oid + ".100.1.3.0", cached=True) if v == "": raise self.snmp.TimeOutError # Fallback to CLI if self.rx_sys_4.search(s): return self.get_version_4xxx(s, v) return self.get_version_35xx("System description : " + s, v) except self.snmp.TimeOutError: pass if s == "": # Trying CLI try: s = self.cli("show system", cached=True) except self.CLISyntaxError: # Get 4xxx version return self.get_version_4xxx(None, None) return self.get_version_35xx(s, None) ## ## 35xx ## rx_sys_35 = re.compile( r"^\s*System description\s*:\s(?P<platform>.+?)\s*$", re.MULTILINE | re.IGNORECASE) rx_ver_35 = re.compile( r"^\s*Operation code version\s*:\s*(?P<version>\S+)\s*$", re.MULTILINE | re.IGNORECASE) rx_ser_35 = re.compile( r"^\s*Serial Number\s*:\s*(?P<serial>\S+)\s*$", re.MULTILINE | re.IGNORECASE) rx_hw_35 = re.compile( r"^\s*Hardware Version\s*:\s*(?P<hardware>\S+)\s*$", re.MULTILINE | re.IGNORECASE) rx_boot_35 = re.compile( r"^\s*Boot ROM Version\s+:\s+(?P<boot>.+)\s*$", re.MULTILINE | re.IGNORECASE) def get_version_35xx(self, show_system, version): # Vendor default vendor = "EdgeCore" # Detect version if not version: v = self.cli("show version", cached=True) match = self.re_search(self.rx_ver_35, v) version = match.group("version") # Detect platform match = self.rx_sys_35.search(show_system) platform = match.group("platform") if "ES3526XA" in platform: # Detect ES3626XA hardware version sub = version.split(".") if sub[0] == "1": platform = "ES3526XA-V2" elif sub[0] == "2" and sub[1] == "3": if int(sub[2]) & 1 == 1: platform = "ES3526XA-38" else: platform = "ES3526XA-1-SL-38" else: raise self.NotSupportedError(platform) elif "3510MA" in platform: platform = "ES3510MA" elif "3510" in platform: platform = "ES3510" elif "3552M" in platform: platform = "ES3552M" elif "ES3528M" in platform: platform = "ES3528M" elif "ES3526S" in platform: pass elif "MR2228N" in platform: vendor = "MRV" elif platform.lower() == "8 sfp ports + 4 gigabit combo ports l2/l3/l4 managed standalone switch": platform = "ES4612" else: raise self.NotSupportedError(platform) r = { "vendor": vendor, "platform": platform, "version": version, "attributes": {} } v = self.cli("show version", cached=True) match = self.rx_boot_35.search(v) if match: r["attributes"].update({"Boot PROM": match.group("boot")}) match = self.rx_hw_35.search(v) if match: r["attributes"].update({"HW version": match.group("hardware")}) match = self.rx_ser_35.search(v) if match: r["attributes"].update({"Serial Number": match.group("serial")}) return r ## ## ES4626 ## rx_sys_4 = re.compile(r"(?P<platform>ES.+?) Device, Compiled", re.MULTILINE | re.DOTALL | re.IGNORECASE) rx_ver_4 = re.compile( r"SoftWare (Package )?Version.*?(?:_|Vco\.)(?P<version>\d.+?)$", re.MULTILINE | re.DOTALL | re.IGNORECASE) rx_boot_4 = re.compile( r"BootRom Version (\S+_)?(?P<boot>\d.+?)$", re.MULTILINE | re.DOTALL | re.IGNORECASE) rx_hw_4 = re.compile( r"HardWare Version (\S+_)?(?P<hardware>\S+)$", re.MULTILINE | re.DOTALL | re.IGNORECASE) rx_ser_4 = re.compile( r"Device serial number (\S+_)?(?P<serial>\S+)$", re.MULTILINE | re.DOTALL | re.IGNORECASE) def get_version_4xxx(self, v, version): if not v: v = self.cli("show version 1", cached=True) match_sys = self.re_search(self.rx_sys_4, v) if not version: match_ver = self.re_search(self.rx_ver_4, v) version = match_ver.group("version") r = { "vendor": "EdgeCore", "platform": match_sys.group("platform"), "version": version, "attributes": {} } match = self.rx_boot_4.search(v) if match: r["attributes"].update({"Boot PROM": match.group("boot")}) match = self.rx_hw_4.search(v) if match: r["attributes"].update({"HW version": match.group("hardware")}) match = self.rx_ser_4.search(v) if match: r["attributes"].update({"Serial Number": match.group("serial")}) return r