Advertisement
Guest User

Untitled

a guest
Feb 3rd, 2016
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.98 KB | None | 0 0
  1. ### Cisco Catalyst Me3400 Series config validation PyRule. 2014
  2. import re
  3.  
  4. @pyrule
  5. def rule(managed_object, config):
  6. from noc.main.models import *
  7. from noc.sa.models import *
  8. from noc.inv.models import *
  9. from ciscoconfparse import CiscoConfParse
  10.  
  11.  
  12. parse = CiscoConfParse(config.split('\n'))
  13. diff = []
  14. result = []
  15. good = ['service password-encryption',
  16. 'service timestamps debug datetime localtime',
  17. 'service timestamps log datetime localtime',
  18. 'aaa new-model',
  19. 'aaa authentication login default group tacacs+ local',
  20. 'aaa authentication enable default group tacacs+ enable',
  21. 'aaa authentication ppp default if-needed group tacacs+',
  22. 'aaa authorization exec default group tacacs+ local',
  23. 'aaa authorization network default group tacacs+ none',
  24. 'aaa authorization reverse-access default group tacacs+ local',
  25. 'aaa accounting exec default start-stop group tacacs+',
  26. 'aaa accounting network default start-stop group tacacs+',
  27. 'aaa accounting connection default start-stop group tacacs+',
  28. 'aaa accounting commands 1 default start-stop group tacacs+',
  29. 'aaa accounting commands 15 default start-stop group tacacs+',
  30. 'no cdp run',
  31. 'mac address-table notification mac-move',
  32. 'logging facility local0',
  33. 'logging rate-limit all 10',
  34. 'memory free low-watermark processor 2048',
  35. 'process cpu threshold type total rising 80 interval 10',
  36. 'process cpu threshold type interrupt rising 30 interval 10',
  37. 'archive\n log config\n logging enable\n logging size 1000\n notify syslog contenttype plaintext\n hidekeys\n path tftp://192.168.31.200/archive/$h-\n write-memory',
  38. 'cpu traffic qos cos 2',
  39. 'spanning-tree logging',
  40. 'spanning-tree mode mst',
  41. 'spanning-tree mst configuration\n name 1\n revision 1\n instance 1 vlan 1-1000\n instance 2 vlan 1001-2000\n instance 3 vlan 2001-3000\n instance 4 vlan 3001-4000\n instance 5 vlan 4001-4094',
  42. 'snmp ifmib ifindex persist',
  43. 'line vty 0 4\n exec-timeout 0 0\n transport preferred none\n transport input telnet ssh',
  44. 'line vty 5 15\n exec-timeout 0 0\n transport preferred none\n transport input telnet ssh'
  45. ]
  46.  
  47. bad = ['ip routing',
  48. 'no spanning-tree vlan 1-4094',
  49. 'ntp access-group peer 13',
  50. 'ip tftp source-interface Loopback0'
  51. ]
  52. ### Validate local users
  53. users = [
  54. 'username noc secret 5 $1$sKOF$eOPKYFCUgep/z8lKD54v./'
  55. ]
  56.  
  57. linespec = "username.+"
  58. unconfspec = linespec
  59. diff += parse.req_cfgspec_excl_diff(linespec, unconfspec, users)
  60.  
  61. ### Validate logging servers
  62. logging = [
  63. 'logging 192.168.1.2',
  64. ]
  65.  
  66. linespec = "logging\s+\d+\.\d+\.\d+\.\d+"
  67. unconfspec = linespec
  68. diff += parse.req_cfgspec_excl_diff(linespec, unconfspec, logging)
  69.  
  70.  
  71. ### Validate SNMP communities
  72. community = ['snmp-server community public RO']
  73.  
  74. linespec = "snmp-server\s+community\s+\S+\s+R[OW]"
  75. unconfspec = linespec
  76. diff += parse.req_cfgspec_excl_diff(linespec, unconfspec, community)
  77.  
  78. ### Validate NTP servers
  79. ntp = [
  80. 'ntp server 192.168.1.1',
  81. ]
  82.  
  83. linespec = "ntp\s+server\s+\d+\.\d+\.\d+\.\d+(\s+prefer)?"
  84. unconfspec = linespec
  85. diff += parse.req_cfgspec_excl_diff(linespec, unconfspec, ntp)
  86.  
  87. ### Validate DNS servers
  88. dns = [
  89. 'ip name-server 192.168.1.1',
  90. ]
  91.  
  92. linespec = "ip\s+name-server\s+\d+\.\d+\.\d+\.\d+"
  93. unconfspec = linespec
  94. diff += parse.req_cfgspec_excl_diff(linespec, unconfspec, dns)
  95.  
  96. not_found = []
  97. for gline in good:
  98. if gline not in config:
  99. diff += [gline]
  100.  
  101. found = []
  102. for bline in bad:
  103. if bline in config:
  104. if bline.startswith('no '):
  105. diff += [bline[3:]]
  106. else:
  107. diff += ["no " + bline]
  108.  
  109. mo_model = managed_object.get_inventory()[0].model.name
  110. mo_version = ManagedObjectAttribute.objects.get(managed_object=managed_object, key="version").value
  111. if ("ME-3400E-24TS-M" in mo_model or "ME-3400EG-12CS-M" in mo_model) and "EZ" in mo_version:
  112. me3400e_good = ['dying-gasp primary ethernet-oam secondary syslog']
  113. for gme3400e in me3400e_good:
  114. if gme3400e not in config:
  115. diff += [gme3400e]
  116.  
  117. ### Validate interface config
  118. trunks = set()
  119. uplinks = set()
  120. tunnels = set()
  121. m3g = set()
  122. m4g = set()
  123. ifaces = parse.find_objects(r"^interface")
  124.  
  125. for i in ifaces:
  126. if "Port-channel" in i.text:
  127. continue
  128. elif i.re_search_children(r"switchport\smode\strunk"):
  129. trunks.add(i)
  130. elif i.re_search_children(r"switchport\smode\sdot1q-tunnel") or i.re_search_children(r"switchport\smode\saccess"):
  131. tunnels.add(i)
  132. if i.re_search_children(r"description\s+3g-"):
  133. m3g.add(i)
  134. elif i.re_search_children(r"description\s+4g-"):
  135. m4g.add(i)
  136.  
  137. uplinks = trunks - m3g - m4g
  138. ### test DV
  139. tunnels = tunnels - m3g
  140. # END
  141. ignore_config = set([
  142. 'description ',
  143. 'speed ',
  144. 'duplex ',
  145. 'rep ',
  146. 'no cdp',
  147. 'switchport access vlan',
  148. 'switchport port-security',
  149. 'l2protocol-tunnel ',
  150. 'media-type',
  151. 'mvr type receiver',
  152. 'shutdown',
  153. 'channel-group',
  154. 'port-type eni',
  155. 'service-policy',
  156. 'udld'
  157. ])
  158.  
  159. linespec = ".+"
  160. unconfspec = linespec
  161.  
  162. #### NETWORK TRUNKS
  163. uplink_config = set([
  164. 'port-type nni',
  165. 'switchport mode trunk',
  166. 'mvr type source',
  167. 'load-interval 30',
  168. 'carrier-delay msec 0',
  169. 'ethernet oam',
  170. 'source template NNI'
  171. ])
  172. for u in uplinks:
  173. try:
  174. uplink_config.remove('mac access-group PVST in')
  175. except:
  176. pass
  177. i_config = set()
  178. interface_diff = set()
  179. for c in u.children:
  180. i_config.add(c.text.strip())
  181. for ignore in ignore_config:
  182. if c.text.strip().startswith(ignore):
  183. i_config.remove(c.text.strip())
  184.  
  185. ### Validate PVST mac-acl on ports to ASR9k
  186. try:
  187. interface = Interface.objects.get(managed_object = managed_object, name = managed_object.profile.convert_interface_name(u.text.split(" ")[1]))
  188. if interface.link.other(interface)[0].managed_object.platform in ['Cisco ASR9K', 'Cisco 901']:
  189. uplink_config.add('mac access-group PVST in')
  190. except:
  191. pass
  192. interface_diff = uplink_config - i_config
  193. interface_diff_del = i_config - uplink_config
  194. if len(interface_diff_del) > 0:
  195. for d in interface_diff_del:
  196. if d.startswith('no '):
  197. interface_diff.add(d[3:])
  198. else:
  199. interface_diff.add("no " + d)
  200. if len(interface_diff)>0:
  201. diff += [u.text]
  202. for a in interface_diff:
  203. diff += [" " + a]
  204. #### GENERAl TUNNELS
  205. tunnel_config = set([
  206. 'switchport mode dot1q-tunnel',
  207. 'load-interval 30',
  208. 'storm-control broadcast level 1.00',
  209. 'storm-control multicast level 10.00',
  210. 'no snmp trap link-status',
  211. 'ethernet oam',
  212. 'ethernet oam mode passive'
  213. ])
  214. for t in tunnels:
  215. i_config = set()
  216. interface_diff = set()
  217. for c in t.children:
  218. i_config.add(c.text.strip())
  219. for ignore in ignore_config:
  220. if c.text.strip().startswith(ignore):
  221. i_config.remove(c.text.strip())
  222.  
  223. interface_diff = tunnel_config - i_config
  224. interface_diff_del = i_config - tunnel_config
  225. if len(interface_diff_del) > 0:
  226. for d in interface_diff_del:
  227. if d.startswith('no '):
  228. interface_diff.add(d[3:])
  229. else:
  230. interface_diff.add("no " + d)
  231. if len(interface_diff)>0:
  232. diff += [t.text]
  233. for a in interface_diff:
  234. diff += [" " + a]
  235. #### 3G INTERFACES
  236. m3g_config = set([
  237. 'load-interval 30',
  238. 'storm-control broadcast level 1.00',
  239. 'storm-control multicast level 10.00',
  240. 'no snmp trap link-status',
  241. 'switchport block multicast',
  242. 'ethernet oam',
  243. 'ethernet oam mode passive'
  244. ])
  245. m3g_ignore_config = set([
  246. 'description ',
  247. 'switchport mode',
  248. 'switchport trunk allowed vlan',
  249. 'speed ',
  250. 'duplex ',
  251. 'service-policy output',
  252. 'switchport access vlan',
  253. 'l2protocol-tunnel ',
  254. 'mac access-group',
  255. 'media-type',
  256. 'shutdown',
  257. 'channel-group',
  258. 'port-type eni',
  259. # 'switchport block multicast'
  260. ])
  261. for m in m3g:
  262. i_config = set()
  263. interface_diff = set()
  264. for x in m.children:
  265. i_config.add(x.text.strip())
  266. for ignore in m3g_ignore_config:
  267. if x.text.strip().startswith(ignore):
  268. i_config.remove(x.text.strip())
  269.  
  270. interface_diff = m3g_config - i_config
  271. interface_diff_del = i_config - m3g_config
  272. if len(interface_diff_del) > 0:
  273. for d in interface_diff_del:
  274. if d.startswith('no '):
  275. interface_diff.add(d[3:])
  276. else:
  277. interface_diff.add("no " + d)
  278. if len(interface_diff)>0:
  279. diff += [m.text]
  280. for a in interface_diff:
  281. diff += [" " + a]
  282.  
  283.  
  284. if len(diff) > 0:
  285. result = ["\nConfig is not valid, you probably want to fix it:\n\n" + "\n".join(diff)]
  286. return result
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement