AEM is the event handler for Arista. It can be used to automate tasks giving the user the ability to customise alerts and actions. There are three parts to ARM; Event Manager, Event Monitor and Linux Tools.
Send XMPP Message on Interface Change
Download script and execute if startup-config present
Using variables in AEM
Running Script Before EOS Has Finished Booting
Send XMPP Messages on Interface Change
This has been taken from a previous post about XMPP.
AEM is the event manager. It works as an event, trigger and action sequence. More details about AEM can be found on the Arista website.
This example will show a switch that reports a message when an interface status is changed.
All of the config is applied to the switch spine1 in the AEM config.
0 1 2 3 4 |
event-handler Eth2IntTest trigger on-intf ethernet 2 operstatus action bash FastCli -p 15 -c "xmpp send admin@securitydemo.lab message 'Ethernet2 has changed state'" |
Shutting down the interface eth2
should trigger the event and send a message to the admin in the chat client. A no shut
will also trigger the same message. This is due to the trigger being a change in interface state.
I did try to modify this to get the switch to send the message to the chat group. The command runs, but I do not get any output in the chat or any other switches. I cannot see anywhere in the documentation that states this is not possible. It would be nice for the switches to use the switch group to send the message. Running show commands works, it is just the messages that seem to fail.
Download Script and Execute if startup-config Present
This is an extension of the ZTP script that I wrote in a previous post. In this previous post, ZTP would not correctly run the Python script for an unknown reason. I did correct this by using a config file and AEM, details can be found here
In this example version, I have updated the python script to add in lines for AEM. The ZTP script is below, the difference here is the AEM configuration commands that will on startup check if there is a startup-conig. If so, it will trigger the action to download a file called startup-event-test.txt.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
#!/usr/bin/python from collections import Counter import subprocess import sys output = subprocess.Popen(["/usr/bin/FastCli", "-c", "show lldp neigh"], stdout=subprocess.PIPE).communicate()[0] out2 = list(iter(output.split())) # Count interfaces for spine lookup = ["Ethernet1", "Ethernet2", "Ethernet3", "Ethernet4"] all_counts = Counter(out2) counts = {k: all_counts[k] for k in lookup} # Determine if spine or leaf for value in counts.values(): if value >= 4: switch = "spine" break else: switch = "leaf" # Determine spine number for key, value in counts.items(): if value >= 4: spine_num = key[8:] break # Assing spine number hostname and IP if switch == "spine": hostname = "spine{}".format(spine_num) ip_addr = "172.17.3.10{}".format(spine_num) # Determine and assign leaf hostname and IP if switch == "leaf": out3 = list(iter(output.splitlines())) intnum = out3[8].split()[2][8:] hostname = "leaf{}".format(intnum) ip_addr = "172.17.3.{}".format(intnum) # Create startup-config file f = open("/mnt/flash/startup-config", "w") f.write("\nhostname {}".format(hostname)) f.write("\ninterface Management1\nip address {}/24".format(ip_addr)) f.write("\nip routing") f.write("\nip route 0.0.0.0/0 172.17.3.254") # Configure AEM to download TFTP config file f.write("\nevent-handler TEST-STARTUP") f.write("\ntrigger on-startup-config") f.write("\naction bash FastCli -p 15 -c 'copy tftp:172.17.2.10/startup-event-test.txt flash:'") f.close() |
In the switch logs it shows that the AEM is run on boot. Below the log is the AEM configuration.
0 1 2 |
Dec 22 22:35:18 leaf1 EventMgr: %SYS-6-EVENT_TRIGGERED: Event handler TEST-STARTUP was activated |
0 1 2 3 4 5 |
leaf1#sh run | sec event event-handler TEST-STARTUP trigger on-startup-config action bash FastCli -p 15 -c 'copy tftp:172.17.2.10/startup-event-test.txt flash:' |
In the above example, the AEM is only downloading the file, it is not doing anything else with it. AEM can perform multiple actions in a single command. This example is taken from my previous ZTP post.
0 1 2 3 4 |
event-handler ZTP1 trigger on-startup-config action bash `FastCli -p 15 -c 'copy tftp:172.17.2.10/ZTP1.py flash:'`; `FastCli -p 15 -c 'copy tftp:172.17.2.10/ZTP2.py flash:'`; python /mnt/flash/ZTP1.py; `FastCli -p 15 -c 'reload in 1 force reason ZTP1 provisioning'` |
Using Variables in AEM
AEM can be used to assign the output of a command, EOS CLI or bash to a variable that may be used. For this demonstration I have taken the example of configuring the XMPP username. In a previous post I have configured XMPP, with each switch having a the XMPP username as the switch hostname. I did this so from the the IM client Gajim I can differentiate the switches. The all switches chat group is shown below to illustrate the usernames of each switch.
Configuring the XMPP username command is quite simple, but is yet another thing to be done manually, that can easily be done in the setup of a switch. I have two methods for the configuration;
– Apply the configuration as commands in EOS
– Create a temporary file containing the XMPP configuration, and then copy it to the running config
The first method of applying the configuration as commands in EOS uses;
– Regex in bash to create the hostname variable $HOSTNAME
, but only selecting character 2 to end of the string
– Echos the hostname variable
– Multi line FastCli command that uses the $HOSTNAME
variable to apply the configuration.
0 1 2 3 4 |
event-handler ADD_xMPP_USER trigger on-boot action bash export {HOSTNAME:2-1}=`FastCli -p 15 -c 'show hostname | grep -Eo "[:]\s\w.*"'`; echo $HOSTNAME; FastCli -p 15 -c $'conf t \n management xmpp \n username '$HOSTNAME'@securitydemo.lab password 7 122A1112140A02567A7974' |
0 1 2 3 4 5 6 7 8 9 |
Dec 26 02:27:23 leaf1 EventMgr: %SYS-6-EVENT_TRIGGERED: Event handler ADD_xMPP_USER was activated ! management xmpp username leaf1@securitydemo.lab password 7 122A1112140A02567A7974 domain securitydemo.lab ! |
For the second method, this is to create the file and copy the contents into the running config file. The running config is a virtual file that commands are added or removed using the no
command. Arista file configuration information can be found here.
0 1 2 |
bash export {HOSTNAME:2-1}=`FastCli -p 15 -c 'show hostname | grep -Eo "[:]\s\w.*"'`; echo $'management xmpp \n username' $HOSTNAME'@securitydemo.lab password 7 122A1112140A02567A7974' >> /mnt/flash/tmp_config.cfg; FastCli -p 15 -c 'copy flash:tmp_config.cfg running-config' |
0 1 2 3 4 5 6 7 8 9 |
leaf1#bash export {HOSTNAME:2-1}=`FastCli -p 15 -c 'show hostname | grep -Eo "[:]\s\w.*"'`; echo $'management xmpp \n username' $HOSTNAME'@securitydemo.lab password 7 122A1112140A02567A7974' >> /mnt/flash/tmp_config.cfg; FastCli -p 15 -c 'copy flash:tmp_config.cfg running-config' /bin/bash: line 0: export: `{HOSTNAME:2-1}=:': not a valid identifier Copy completed successfully. leaf1# leaf1#more flash:tmp_config.cfg management xmpp username leaf1@securitydemo.lab password 7 122A1112140A02567A7974 leaf1# |
0 1 2 3 4 5 6 7 |
Dec 26 02:34:16 leaf1 EventMgr: %SYS-6-EVENT_TRIGGERED: Event handler ADD_xMPP_USER was activated Dec 26 02:34:16 leaf1 ConfigAgent: %SYS-5-CONFIG_I: Configured from flash:/tmp_config.cfg by root on UnknownTty (UnknownIpAddr) leaf1#more flash:tmp_config.cfg management xmpp username leaf1@securitydemo.lab password 7 122A1112140A02567A7974 |
Running Script Before EOS Has Finished Booting
This isn’t part of AEM, as it runs before EOS has finished booting. To run a script before EOS has finished booting, the script can be placed into a file named /mnt/flash/rc.eos
. The contents of this file will be executed during the boot process. It allows for modifications to the device. The below example has been taken from Arista documentation. As shown, this is a bash script that is running a python script depending on the switch version.