En utilisant EEM (Embedded Event Manager) et python on-box pris en charge par les routeurs et commutateurs Cisco, l'itinéraire de la table de routage a changé. Un exemple qui notifie un service externe (Cisco Spark) comme déclencheur.
Le contenu à notifier est le réseau modifié, le contenu modifié (ajout / suppression, etc.) et la cause modifiée (OSPF, EIGRP, BGP, CONNECTED, etc.), et ceux-ci sont fournis par EEM. Le script EEM est écrit en Python. L'appareil utilisé était le Catalyst 3850 que j'avais sous la main.
Vidéo de démonstration (YouTube ouvre)
※référence [Python et Bash sur Cisco Catalyst IOS-XE](http://qiita.com/kikuta1978/items/1739d7d7063a20b1736f#eem%E3%81%8B%E3%82%89%E5%AE%9F%E8%A1 % 8C) Exécution de scripts Tcl à l'aide de Cisco IOS EEM (http://qiita.com/kikuta1978/items/5d7d92e7f35d0a03922b) Partager les événements de périphérique du conteneur de commutateur Catalyst vers Cisco Spark
Cat3850-3#sh ver | i .bin
System image file is "flash:cat3k_caa-universalk9.16.06.01.SPA.bin"
La politique EEM écrite en script Python est installée dans Flash of Catalyst.
routewatch.py
Cat3850-3#dir | i routewatch.py
54679 -rw- 1043 Aug 29 2017 13:28:46 +09:00 routewatch.py
Les paramètres de commande IOS sont dans les deux lignes suivantes. Spécifiez le chemin du script EEM et enregistrez le script réel (décrit plus loin). Exécutez la deuxième ligne ci-dessous pour compiler le script et l'exécuter en mémoire.
event manager directory user policy "flash:/"
event manager policy routewatch.py type user
routewatch.py
::cisco::eem::event_register_routing network 1.1.1.0/24 type all ge 24
#::cisco::eem::event_register_routing network 1.1.1.0/24 type all ge 24 ratelimit 60
import requests
import sys
import eem
ACCESS_TOKEN = "<my_access_token>"
ROOM_ID = "<my_room_id>"
#Création d'en-tête
def setHeaders():
accessToken_hdr = 'Bearer ' + ACCESS_TOKEN
spark_header = {'Authorization': accessToken_hdr, 'Content-Type': 'application/json; charset=utf-8'}
return spark_header
#Publier un message dans la salle Spark
def postMsg(the_header,roomId,message):
message = '{"roomId":"' + roomId + '","text":"' + message +'"}'
uri = 'https://api.ciscospark.com/v1/messages'
resp = requests.post(uri, data=message, headers=the_header)
print resp
#Obtenez les informations fournies en interne pour chaque événement EEM et rédigez un message
event = eem.event_reqinfo()
message = '!!! RoutingTable Change Detected by EEM: !!! -> ' + event['network'] + '-' + event['type'] + '-BY-' + event['protocol']
header=setHeaders()
postMsg(header,ROOM_ID,message)
Voici quelques points.
Before
Cat3850-3#sh ip route
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
E1 - OSPF external type 1, E2 - OSPF external type 2
i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
ia - IS-IS inter area, * - candidate default, U - per-user static route
o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
a - application route
+ - replicated route, % - next hop override, p - overrides from PfR
Gateway of last resort is not set
1.0.0.0/32 is subnetted, 2 subnets
C 1.1.1.1 is directly connected, Loopback100
O 1.1.1.100 [110/2] via 192.168.1.2, 01:10:05, Vlan1
192.168.1.0/24 is variably subnetted, 2 subnets, 2 masks
C 192.168.1.0/24 is directly connected, Vlan1
L 192.168.1.1/32 is directly connected, Vlan1
After1
Cat3850-3#sh ip route
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
E1 - OSPF external type 1, E2 - OSPF external type 2
i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
ia - IS-IS inter area, * - candidate default, U - per-user static route
o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
a - application route
+ - replicated route, % - next hop override, p - overrides from PfR
Gateway of last resort is not set
1.0.0.0/32 is subnetted, 3 subnets
C 1.1.1.1 is directly connected, Loopback100
O 1.1.1.100 [110/2] via 192.168.1.2, 01:11:55, Vlan1
O 1.1.1.200 [110/2] via 192.168.1.2, 00:00:34, Vlan1 <---★★ Ajouté
192.168.1.0/24 is variably subnetted, 2 subnets, 2 masks
C 192.168.1.0/24 is directly connected, Vlan1
L 192.168.1.1/32 is directly connected, Vlan1
After2
Cat3850-3#sh ip route
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
E1 - OSPF external type 1, E2 - OSPF external type 2
i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
ia - IS-IS inter area, * - candidate default, U - per-user static route
o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
a - application route
+ - replicated route, % - next hop override, p - overrides from PfR
Gateway of last resort is not set
1.0.0.0/32 is subnetted, 2 subnets
C 1.1.1.1 is directly connected, Loopback100
O 1.1.1.200 [110/2] via 192.168.1.2, 00:03:21, Vlan1
192.168.1.0/24 is variably subnetted, 2 subnets, 2 masks
C 192.168.1.0/24 is directly connected, Vlan1
L 192.168.1.1/32 is directly connected, Vlan1
After3
Cat3850-3#sh ip route
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
E1 - OSPF external type 1, E2 - OSPF external type 2
i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
ia - IS-IS inter area, * - candidate default, U - per-user static route
o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
a - application route
+ - replicated route, % - next hop override, p - overrides from PfR
Gateway of last resort is not set
1.0.0.0/32 is subnetted, 3 subnets
C 1.1.1.1 is directly connected, Loopback100
C 1.1.1.30 is directly connected, Loopback300 <---★★ Ajouté
O 1.1.1.200 [110/2] via 192.168.1.2, 00:05:57, Vlan1
192.168.1.0/24 is variably subnetted, 2 subnets, 2 masks
C 192.168.1.0/24 is directly connected, Vlan1
L 192.168.1.1/32 is directly connected, Vlan1
Vous pouvez faire quelque chose de similaire avec CLI. Voici un exemple de la façon d'écrire un événement qui détecte tout changement d'itinéraire et affiche les variables générées par l'événement dans Syslog.
IOS-Config
event manager applet routewatch-applet
event routing network 0.0.0.0/0 type all
action 101 syslog msg "_event_type_string is $_event_type_string"
action 102 syslog msg "_routing_network is $_routing_network"
action 103 syslog msg "_routing_protocol is $_routing_protocol"
action 104 syslog msg "_routing_type is $_routing_type"
Exemple d'opération
Cat3850-3#
Aug 29 16:07:09.331: %HA_EM-6-LOG: routewatch-applet: _event_type_string is routing
Aug 29 16:07:09.331: %HA_EM-6-LOG: routewatch-applet: _routing_network is 1.1.1.100
Aug 29 16:07:09.331: %HA_EM-6-LOG: routewatch-applet: _routing_protocol is OSPF
Aug 29 16:07:09.331: %HA_EM-6-LOG: routewatch-applet: _routing_type is add
IOS EEM peut détecter divers événements et prendre des mesures, mais c'est pratique car il capture non seulement les modifications de routage comme dans cet exemple, mais fournit également le contenu modifié en interne.
Il existe une commande pratique pour vérifier les variables (tableau) générées pour chaque événement (plus pratique que le manuel en ligne). Dans la sortie de commande suivante, en plus de la notation d'événement EEM, le tableau event_reqinfo Tcl peut être confirmé, mais il peut également être utilisé dans des scripts Python comme cet exemple de code.
Bien sûr, vous pouvez également récupérer des valeurs avec une applet (CLI), les envoyer par Syslog ou par courrier, écrire dans des fichiers internes et effectuer de petits traitements de branchement et de boucle.
Cat3850-3#show event manager detector routing detailed
No. Name Version Node Type
1 routing 03.00 node0/0 RP
Tcl Configuration Syntax:
::cisco::eem::event_register_routing
[tag <tag-val>]
network <network>/<length>
[ge <ge-length>]
[le <le-length>]
[ne <ne-length>]
[type {add | remove | modify | all}]
[protocol <protocol-val>]
[queue_priority {normal | low | high | last}]
[maxrun <sec.msec>]
[ratelimit <sec.msec>]
[vrf {all | default | name=regex}]
[nice {0 | 1}]
Tcl event_reqinfo Array Names:
event_id
job_id
event_type
event_type_string
event_pub_time
event_pub_sec
event_pub_msec
event_trigger_num
event_severity
network
mask
prefix_len
protocol
type
lastgateway
distance
time
time_sec
time_msec
metric
afi
lastinterface
Applet Configuration Syntax:
[ no ] event [tag <tag-val>] routing
network <network>/<length>
[ge <ge-length>]
[le <le-length>]
[ne <ne-length>]
[type {add | remove | modify | all}]
[protocol <protocol-val>]
[maxrun <sec.msec>]
[ratelimit <sec.msec>]
[vrf {all | default | name <regex>}]
Applet Built-in Environment Variables:
$_event_id
$_job_id
$_event_type
$_event_type_string
$_event_pub_time
$_event_pub_sec
$_event_pub_msec
$_event_severity
$_routing_network
$_routing_mask
$_routing_prefix_len
$_routing_protocol
$_routing_type
$_routing_tag_name
$_routing_vrf_name
$_routing_topo_name
$_routing_lastgateway
$_routing_distance
$_routing_time
$_routing_time_sec
$_routing_time_msec
$_routing_metric
$_routing_lastinterface
$_routing_afi
Ci-dessous, vous pouvez vérifier event_reqinfo pour chaque événement qui peut être utilisé avec IOS-XE 16.6 de Cat3850, donc si vous regardez quelque chose, votre imagination se développera.
Cat3850-3#show event manager detector ?
all All available event detectors
application Application event detector
cli CLI event detector
config Config event detector
counter Counter event detector
env Environmental event detector
generic Generic event detector
gold GOLD event detector
identity Identity event detector
interface Interface event detector
ioswdsysmon Ioswdsysmon event detector
ipsla IPSLA event detector
mat mac-address-table event detector
neighbor-discovery neighbor discovery event detector
nf NF event detector
none None event detector
oir OIR event detector
rf RF event detector
routing Routing event detector
rpc RPC event detector
snmp Snmp event detector
snmp-notification Snmp notification event detector
snmp-object Snmp Object event detector
syslog Syslog event detector
test Test event detector
timer Timer event detector
Surveiller le cache NetFlow et la table d'adresses MAC, détecter les connexions avec CDP / LLDP, etc. semble être amusant.
Cat3850-3#show event manager detector nf detailed
No. Name Version Node Type
1 nf 01.00 node0/0 RP
Tcl Configuration Syntax:
::cisco::eem::event_register_nf
[tag <tag-val>]
monitor_name <monitor-name value>
event_type <create|update|delete>
exit_event_type <create|update|delete>
event1-event4 <subevent-description>
[maxrun <sec.msec>]
[ratelimit <sec.msec>]
[nice {0 | 1}]
where <subevent-description> can be
field <field value>
rate_interval <rate interval value> (event1 only)
entry_value <entry value>
entry_op {eq|ge|gt|le|lt|wc}
[exit_value <exit value>]
[exit_op {eq|ge|gt|le|lt|wc}]
[exit_rate_interval <exit rate interval value>](event1 only)
Tcl event_reqinfo Array Names:
event_id
job_id
event_type
event_type_string
event_pub_time
event_pub_sec
event_pub_msec
event_trigger_num
event_severity
monitor_name
event_type
ip_protocol
source_address
source_port
dest_address
dest_port
app_name
event[1-4]_field
event[1-4]_value
Applet Configuration Syntax:
[ no ] event [tag <tag-val>] nf
monitor-name <monitor-name value>
event-type <create|update|delete>
exit-event-type <create|update|delete>
event1-event4 <subevent-description>
[maxrun <sec.msec>]
[ratelimit <sec.msec>]
where <subevent-description> can be
field <field value>
rate-interval <rate interval value> (event1 only)
entry-value <entry value>
entry-op {eq|ge|gt|le|lt|wc}
[exit-value <exit value>]
[exit-op {eq|ge|gt|le|lt|wc}]
[exit-rate-interval <exit rate interval value>](event1 only)
Applet Built-in Environment Variables:
$_event_id
$_job_id
$_event_type
$_event_type_string
$_event_pub_time
$_event_pub_sec
$_event_pub_msec
$_event_severity
$_nf_monitor_name
$_nf_event_type
$_nf_ip_protocol
$_nf_source_address
$_nf_source_port
$_nf_dest_address
$_nf_dest_port
$_nf_app_name
$_nf_event[1-4]_field
$_nf_event[1-4]_value
Cela faisait longtemps, mais en résumé, c'était un article sur lequel il était amusant de regarder event_reqinfo () dans Cisco IOS. J'espère que la programmabilité On-box peut compléter les choses gênantes qui peuvent être faites avec Off-box. Je pense que vous pouvez essayer EEM et event_reqinfo () sur Cisco 1812J et 892J. Si vous voulez écrire EEM en Python, IOS-XE16.5 ou supérieur est requis, donc pour l'instant vous avez besoin d'un périphérique tel que Cat3850 ou ISR4000 / ASR1000.
Embedded Event Manager Configuration Guide, Cisco IOS Release 15M&T Programmability Configuration Guide, Cisco IOS XE Everest 16.6.1
Recommended Posts