Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ### Cisco Catalyst Me3400 Series config validation PyRule. 2014
- import re
- @pyrule
- def rule(managed_object, config):
- from noc.main.models import *
- from noc.sa.models import *
- from noc.inv.models import *
- from ciscoconfparse import CiscoConfParse
- parse = CiscoConfParse(config.split('\n'))
- diff = []
- result = []
- good = ['service password-encryption',
- 'service timestamps debug datetime localtime',
- 'service timestamps log datetime localtime',
- 'aaa new-model',
- 'aaa authentication login default group tacacs+ local',
- 'aaa authentication enable default group tacacs+ enable',
- 'aaa authentication ppp default if-needed group tacacs+',
- 'aaa authorization exec default group tacacs+ local',
- 'aaa authorization network default group tacacs+ none',
- 'aaa authorization reverse-access default group tacacs+ local',
- 'aaa accounting exec default start-stop group tacacs+',
- 'aaa accounting network default start-stop group tacacs+',
- 'aaa accounting connection default start-stop group tacacs+',
- 'aaa accounting commands 1 default start-stop group tacacs+',
- 'aaa accounting commands 15 default start-stop group tacacs+',
- 'no cdp run',
- 'mac address-table notification mac-move',
- 'logging facility local0',
- 'logging rate-limit all 10',
- 'memory free low-watermark processor 2048',
- 'process cpu threshold type total rising 80 interval 10',
- 'process cpu threshold type interrupt rising 30 interval 10',
- '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',
- 'cpu traffic qos cos 2',
- 'spanning-tree logging',
- 'spanning-tree mode mst',
- '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',
- 'snmp ifmib ifindex persist',
- 'line vty 0 4\n exec-timeout 0 0\n transport preferred none\n transport input telnet ssh',
- 'line vty 5 15\n exec-timeout 0 0\n transport preferred none\n transport input telnet ssh'
- ]
- bad = ['ip routing',
- 'no spanning-tree vlan 1-4094',
- 'ntp access-group peer 13',
- 'ip tftp source-interface Loopback0'
- ]
- ### Validate local users
- users = [
- 'username noc secret 5 $1$sKOF$eOPKYFCUgep/z8lKD54v./'
- ]
- linespec = "username.+"
- unconfspec = linespec
- diff += parse.req_cfgspec_excl_diff(linespec, unconfspec, users)
- ### Validate logging servers
- logging = [
- 'logging 192.168.1.2',
- ]
- linespec = "logging\s+\d+\.\d+\.\d+\.\d+"
- unconfspec = linespec
- diff += parse.req_cfgspec_excl_diff(linespec, unconfspec, logging)
- ### Validate SNMP communities
- community = ['snmp-server community public RO']
- linespec = "snmp-server\s+community\s+\S+\s+R[OW]"
- unconfspec = linespec
- diff += parse.req_cfgspec_excl_diff(linespec, unconfspec, community)
- ### Validate NTP servers
- ntp = [
- 'ntp server 192.168.1.1',
- ]
- linespec = "ntp\s+server\s+\d+\.\d+\.\d+\.\d+(\s+prefer)?"
- unconfspec = linespec
- diff += parse.req_cfgspec_excl_diff(linespec, unconfspec, ntp)
- ### Validate DNS servers
- dns = [
- 'ip name-server 192.168.1.1',
- ]
- linespec = "ip\s+name-server\s+\d+\.\d+\.\d+\.\d+"
- unconfspec = linespec
- diff += parse.req_cfgspec_excl_diff(linespec, unconfspec, dns)
- not_found = []
- for gline in good:
- if gline not in config:
- diff += [gline]
- found = []
- for bline in bad:
- if bline in config:
- if bline.startswith('no '):
- diff += [bline[3:]]
- else:
- diff += ["no " + bline]
- mo_model = managed_object.get_inventory()[0].model.name
- mo_version = ManagedObjectAttribute.objects.get(managed_object=managed_object, key="version").value
- if ("ME-3400E-24TS-M" in mo_model or "ME-3400EG-12CS-M" in mo_model) and "EZ" in mo_version:
- me3400e_good = ['dying-gasp primary ethernet-oam secondary syslog']
- for gme3400e in me3400e_good:
- if gme3400e not in config:
- diff += [gme3400e]
- ### Validate interface config
- trunks = set()
- uplinks = set()
- tunnels = set()
- m3g = set()
- m4g = set()
- ifaces = parse.find_objects(r"^interface")
- for i in ifaces:
- if "Port-channel" in i.text:
- continue
- elif i.re_search_children(r"switchport\smode\strunk"):
- trunks.add(i)
- elif i.re_search_children(r"switchport\smode\sdot1q-tunnel") or i.re_search_children(r"switchport\smode\saccess"):
- tunnels.add(i)
- if i.re_search_children(r"description\s+3g-"):
- m3g.add(i)
- elif i.re_search_children(r"description\s+4g-"):
- m4g.add(i)
- uplinks = trunks - m3g - m4g
- ### test DV
- tunnels = tunnels - m3g
- # END
- ignore_config = set([
- 'description ',
- 'speed ',
- 'duplex ',
- 'rep ',
- 'no cdp',
- 'switchport access vlan',
- 'switchport port-security',
- 'l2protocol-tunnel ',
- 'media-type',
- 'mvr type receiver',
- 'shutdown',
- 'channel-group',
- 'port-type eni',
- 'service-policy',
- 'udld'
- ])
- linespec = ".+"
- unconfspec = linespec
- #### NETWORK TRUNKS
- uplink_config = set([
- 'port-type nni',
- 'switchport mode trunk',
- 'mvr type source',
- 'load-interval 30',
- 'carrier-delay msec 0',
- 'ethernet oam',
- 'source template NNI'
- ])
- for u in uplinks:
- try:
- uplink_config.remove('mac access-group PVST in')
- except:
- pass
- i_config = set()
- interface_diff = set()
- for c in u.children:
- i_config.add(c.text.strip())
- for ignore in ignore_config:
- if c.text.strip().startswith(ignore):
- i_config.remove(c.text.strip())
- ### Validate PVST mac-acl on ports to ASR9k
- try:
- interface = Interface.objects.get(managed_object = managed_object, name = managed_object.profile.convert_interface_name(u.text.split(" ")[1]))
- if interface.link.other(interface)[0].managed_object.platform in ['Cisco ASR9K', 'Cisco 901']:
- uplink_config.add('mac access-group PVST in')
- except:
- pass
- interface_diff = uplink_config - i_config
- interface_diff_del = i_config - uplink_config
- if len(interface_diff_del) > 0:
- for d in interface_diff_del:
- if d.startswith('no '):
- interface_diff.add(d[3:])
- else:
- interface_diff.add("no " + d)
- if len(interface_diff)>0:
- diff += [u.text]
- for a in interface_diff:
- diff += [" " + a]
- #### GENERAl TUNNELS
- tunnel_config = set([
- 'switchport mode dot1q-tunnel',
- 'load-interval 30',
- 'storm-control broadcast level 1.00',
- 'storm-control multicast level 10.00',
- 'no snmp trap link-status',
- 'ethernet oam',
- 'ethernet oam mode passive'
- ])
- for t in tunnels:
- i_config = set()
- interface_diff = set()
- for c in t.children:
- i_config.add(c.text.strip())
- for ignore in ignore_config:
- if c.text.strip().startswith(ignore):
- i_config.remove(c.text.strip())
- interface_diff = tunnel_config - i_config
- interface_diff_del = i_config - tunnel_config
- if len(interface_diff_del) > 0:
- for d in interface_diff_del:
- if d.startswith('no '):
- interface_diff.add(d[3:])
- else:
- interface_diff.add("no " + d)
- if len(interface_diff)>0:
- diff += [t.text]
- for a in interface_diff:
- diff += [" " + a]
- #### 3G INTERFACES
- m3g_config = set([
- 'load-interval 30',
- 'storm-control broadcast level 1.00',
- 'storm-control multicast level 10.00',
- 'no snmp trap link-status',
- 'switchport block multicast',
- 'ethernet oam',
- 'ethernet oam mode passive'
- ])
- m3g_ignore_config = set([
- 'description ',
- 'switchport mode',
- 'switchport trunk allowed vlan',
- 'speed ',
- 'duplex ',
- 'service-policy output',
- 'switchport access vlan',
- 'l2protocol-tunnel ',
- 'mac access-group',
- 'media-type',
- 'shutdown',
- 'channel-group',
- 'port-type eni',
- # 'switchport block multicast'
- ])
- for m in m3g:
- i_config = set()
- interface_diff = set()
- for x in m.children:
- i_config.add(x.text.strip())
- for ignore in m3g_ignore_config:
- if x.text.strip().startswith(ignore):
- i_config.remove(x.text.strip())
- interface_diff = m3g_config - i_config
- interface_diff_del = i_config - m3g_config
- if len(interface_diff_del) > 0:
- for d in interface_diff_del:
- if d.startswith('no '):
- interface_diff.add(d[3:])
- else:
- interface_diff.add("no " + d)
- if len(interface_diff)>0:
- diff += [m.text]
- for a in interface_diff:
- diff += [" " + a]
- if len(diff) > 0:
- result = ["\nConfig is not valid, you probably want to fix it:\n\n" + "\n".join(diff)]
- return result
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement