Advertisement
Guest User

Untitled

a guest
Feb 6th, 2014
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.30 KB | None | 0 0
  1. stats:/usr/local/noc#> cat ./sa/profiles/Cisco/IOS/get_inventory.py
  2. # -*- coding: utf-8 -*-
  3. ##----------------------------------------------------------------------
  4. ## Cisco.IOS.get_inventory
  5. ##----------------------------------------------------------------------
  6. ## Copyright (C) 2007-2013 The NOC Project
  7. ## See LICENSE for details
  8. ##----------------------------------------------------------------------
  9.  
  10. ## Python modules
  11. import re
  12. from itertools import groupby
  13. ## NOC modules
  14. from noc.sa.script import Script as NOCScript
  15. from noc.sa.interfaces.igetinventory import IGetInventory
  16. from noc.sa.interfaces.base import InterfaceTypeError
  17.  
  18.  
  19. class Script(NOCScript):
  20. name = "Cisco.IOS.get_inventory"
  21. implements = [IGetInventory]
  22.  
  23. rx_item = re.compile(
  24. r"^NAME: \"(?P<name>[^\"]+)\", DESCR: \"(?P<descr>[^\"]+)\"\n"
  25. r"PID:\s+(?P<pid>\S+)?\s*,\s+VID:\s+(?P<vid>[\S ]+)?\s*, SN: (?P<serial>\S+)",
  26. re.MULTILINE | re.DOTALL
  27. )
  28. rx_trans = re.compile("((?:100|1000|10G)BASE\S+)")
  29. rx_cvend = re.compile("(CISCO.(?P<ven>\S{3,15}))")
  30. rx_idprom = re.compile(
  31. r"\s*Vendor Name\s+(:|=)(\s+)?(?P<t_vendor>\S+[\S ]*)\n"
  32. r"(\s*Vendor OUI\s+(:|=)(\s+)?[\S+ ]*(\s+)?\n)?"
  33. r"\s*Vendor (PN|Part No.|Part Number)\s+(:|=)(\s+)?(?P<t_part_no>\S+[\S ]*)\n"
  34. r"\s*Vendor (rev|Revision|Part Rev.)\s+(:|=)(\s+)?(?P<t_rev>\S+[\S ]*)?\n"
  35. r"\s*Vendor (SN|Serial No.|Serial Number)\s+(:|=)(\s+)?(?P<t_sn>\S+)(\s+)?\n",
  36. re.IGNORECASE | re.MULTILINE | re.DOTALL
  37. )
  38.  
  39. IGNORED_SERIAL = set([
  40. "H22L714"
  41. ])
  42.  
  43. IGNORED_NAMES = set([
  44. "c7201"
  45. ])
  46.  
  47. GBIC_MODULES = set([
  48. "WS-X6K-SUP2-2GE"
  49. ])
  50.  
  51. def get_inv(self):
  52. objects = []
  53. v = self.cli("show inventory")
  54. for match in self.rx_item.finditer(v):
  55. vendor, serial = "", ""
  56. if match.group("name") in self.IGNORED_NAMES:
  57. continue
  58. type, number, part_no = self.get_type(
  59. match.group("name"), match.group("pid"),
  60. match.group("descr"), len(objects)
  61. )
  62. serial = match.group("serial")
  63. if not part_no:
  64. if "XCVR" in type:
  65. # Last chance to get idprom
  66. vendor, t_sn, t_rev, part_no = self.get_idprom(
  67. match.group("name"), match.group("descr").upper()
  68. )
  69. if not serial:
  70. serial = t_sn
  71. if not part_no:
  72. print "!!! UNKNOWN: ", match.groupdict()
  73. continue
  74. else:
  75. print "!!! UNKNOWN: ", match.groupdict()
  76. continue
  77. if serial in self.IGNORED_SERIAL:
  78. serial = None
  79. if not vendor:
  80. if "NoName" in part_no or "Unknown" in part_no:
  81. vendor = "NONAME"
  82. else:
  83. vendor = "CISCO"
  84. objects += [{
  85. "type": type,
  86. "number": number,
  87. "vendor": vendor,
  88. "serial": serial,
  89. "description": match.group("descr"),
  90. "part_no": [part_no],
  91. "revision": match.group("vid"),
  92. "builtin": False
  93. }]
  94.  
  95. # if gbic slots in module
  96. if (part_no in self.GBIC_MODULES or
  97. "GBIC ETHERNET" in match.group("descr").upper()):
  98. # Need get transceivers from idprom
  99. objects += self.get_transceivers("sh int " +
  100. "status module " + str(number))
  101.  
  102. return objects
  103.  
  104.  
  105. def get_transceivers(self, cmd):
  106. try:
  107. # Get phy interfaces
  108. i = self.cli(cmd)
  109. objects = []
  110. for s in i.split("\n"):
  111. if (not s or "BaseTX" in s or s.startswith("Po")
  112. or "No Transceiver" in s):
  113. continue
  114. else:
  115. t_num = s.split()[0].split("/")[-1]
  116. t_vendor, t_sn, t_rev, pid = self.get_idprom(s.split()[0], s.split()[-1].upper())
  117. objects += [{
  118. "type": "XCVR",
  119. "number": t_num,
  120. "vendor": t_vendor,
  121. "serial": t_sn,
  122. "description": s.split()[-1] + " Transceiver",
  123. "part_no": [pid],
  124. "revision": t_rev,
  125. "builtin": False
  126. }]
  127. return objects
  128. except self.CLISyntaxError:
  129. print "sh idprom command not supported"
  130.  
  131. def get_idprom(self, int, descr):
  132. try:
  133. t = self.cli("show idprom int " + int + " | i Vendor")
  134. match = self.rx_idprom.search(t)
  135. if match:
  136. v = self.rx_cvend.search(match.group("t_vendor").upper())
  137. if v and "SYSTEMS" not in v.group("ven"):
  138. t_vendor = v.group("ven")
  139. elif ("SYSTEMS" in match.group("t_vendor").upper()
  140. and "CISCO" in match.group("t_vendor").upper()):
  141. # Different variations of "CISCO@/-/_SYSTEMS" vendor
  142. t_vendor = "CISCO"
  143. elif "OEM" in match.group("t_vendor").upper():
  144. # China noname products with "OEM" vendor
  145. t_vendor = "NONAME"
  146. else:
  147. # Others vendors
  148. t_vendor = match.group("t_vendor").upper().strip()
  149.  
  150. # Ignored serial
  151. t_sn = match.group("t_sn") if match.group("t_sn") not in self.IGNORED_SERIAL else None
  152.  
  153. # Decode hex revision (need rewrite)
  154. if match.group("t_rev"):
  155. t_rev = match.group("t_rev").strip()
  156. else:
  157. t_rev = None
  158. if self.rx_trans.search(match.group("t_part_no").upper().replace("-", "")):
  159. pid = self.get_transceiver_pid(match.group("t_part_no"))
  160. else:
  161. if ("GBIC" in match.group("t_part_no") and
  162. "Gi" in int):
  163. pid = self.get_transceiver_pid("1000BASE" + match.group("t_part_no")[5:].strip())
  164. else:
  165. if "NONAME" in t_vendor and self.rx_trans.search(descr):
  166. pid = self.get_transceiver_pid(descr)
  167. else:
  168. pid = match.group("t_part_no").strip()
  169. return t_vendor, t_sn, t_rev, pid
  170. else:
  171. return None, None, None, None
  172. except self.CLISyntaxError:
  173. print "sh idprom command not supported"
  174.  
  175.  
  176. def get_type(self, name, pid, descr, lo):
  177. """
  178. Get type, number and part_no
  179. """
  180. if pid is None:
  181. pid = ""
  182. if ("Transceiver" in descr or
  183. name.startswith("GigabitEthernet") or
  184. name.startswith("TenGigabitEthernet") or
  185. pid.startswith("X2-") or
  186. pid.startswith("XENPAK")):
  187. # Transceivers
  188. # Get number
  189. if name.startswith("Transceiver "):
  190. # Get port number
  191. _, number = name.rsplit("/", 1)
  192. elif name.startswith("GigabitEthernet"):
  193. number = name.split(" ", 1)[0].split("/")[-1]
  194. elif name.startswith("Te"):
  195. if " " in name:
  196. number = name.split(" ", 1)[0].split("/")[-1]
  197. else:
  198. number = name.split("/")[-1]
  199. else:
  200. number = None
  201. if pid in ("", "N/A", "Unspecified") or self.rx_trans.search(pid) \
  202. or len(list(groupby(pid))) == 1:
  203. # Non-Cisco transceivers
  204. pid = self.get_transceiver_pid(descr)
  205. if not pid:
  206. return "XCVR", number, None
  207. else:
  208. return "XCVR", number, pid
  209. else:
  210. # Normalization of pids "GBIC_LX/LH/BX"
  211. if (pid.startswith("GBIC_") and ("gigabit" in descr.lower()
  212. or "gigabit" in name.lower())):
  213. pid = self.get_transceiver_pid("1000BASE" + pid[5:])
  214. return "XCVR", number, pid
  215. elif ((lo == 0 or pid.startswith("CISCO") or pid.startswith("WS-C"))
  216. and not pid.startswith("WS-CAC-") and not "Clock" in descr
  217. and not "VTT FRU" in descr):
  218. try:
  219. number = int(name)
  220. except ValueError:
  221. number = None
  222. return "CHASSIS", number, pid
  223. elif (("SUP" in pid or "S2U" in pid)
  224. and "supervisor" in descr):
  225. # Sup2
  226. try:
  227. number = int(name)
  228. except ValueError:
  229. number = None
  230. return "SUP", number, pid
  231. elif name.startswith("module "):
  232. # Linecards or supervisors
  233. if (pid.startswith("RSP")
  234. or ((pid.startswith("WS-SUP") or pid.startswith("VS-S"))
  235. and "Supervisor Engine" in descr)):
  236. return "SUP", name[7:], pid
  237. else:
  238. return "LINECARD", name[7:], pid
  239. elif ((pid.startswith("WS-X64") or pid.startswith("WS-X67")
  240. or pid.startswith("WS-X65")) and "port" in descr):
  241. try:
  242. number = int(name)
  243. except ValueError:
  244. number = None
  245. return "LINECARD", number, pid
  246. elif ((pid.startswith("WS-SUP") or pid.startswith("VS-S"))
  247. and "Supervisor Engine" in descr):
  248. try:
  249. number = int(name)
  250. except ValueError:
  251. number = None
  252. return "SUP", number, pid
  253. elif "-DFC" in pid or "-CFC" in pid or "sub-module" in name:
  254. # DFC subcard
  255. return "DFC", None, pid
  256. elif name.startswith("PS "):
  257. # Power supply
  258. return "PSU", name.split()[1], pid
  259. elif name.startswith("Power Supply "):
  260. return "PSU", name.split()[2], pid
  261. elif pid.startswith("FAN"):
  262. # Fan module
  263. return "FAN", name.split()[1], pid
  264. elif "Clock FRU" in descr:
  265. # Clock module
  266. return "CLK", name.split()[1], pid
  267. elif "VTT FRU" in descr:
  268. # Clock module
  269. return "VTT", name.split()[1], pid
  270. # Unknown
  271. return None, None, None
  272.  
  273. def get_transceiver_pid(self, descr):
  274. match = self.rx_trans.search(descr.upper().replace("-", ""))
  275. if match:
  276. return "Unknown | Transceiver | %s" % match.group(1).upper()
  277. return None
  278.  
  279. @NOCScript.match(platform__regex=r"C2960")
  280. def execute_2960(self):
  281. objects = self.get_inv()
  282. objects += self.get_transceivers("show int status")
  283. return objects
  284.  
  285. @NOCScript.match()
  286. def execute_others(self):
  287. objects = self.get_inv()
  288. return objects
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement