Can I combine EEM applets with Tcl shell?

When I've been describing the limitations of kron, ??? quickly asked an interesting question: “as I cannot insert extra input keystrokes with EEM applet, can I run a Tcl script from it with the action sequence cli command "tclsh script" command and use the typeahead function call to get around the limitation?” The only answer I could give at that time was “maybe” … and obviously it was time for a more thorough test. The short result is: YES, you can do it (at least in IOS release 12.4(15)T1).

… and here is the long description of the test. I've started by creating a small Tcl script (see below) that clears the counters on Loopback 0. As the clear counters command requires keyboard input and generates a syslog message, it was a perfect test case.

typeahead "y"
exec "clear counter loop 0"

I've copied this script into the flash:tcl/clearL0.tcl and tested it:

R1#tclsh flash:tcl/clearL0.tcl
%CLEAR-5-COUNTERS: Clear counter on interface Loopback0 by console

So far, so good. Next, I've created an EEM applet with no trigger …

event manager applet Clear
 event none
 action 1.0 cli command "enable"
 action 1.1 cli command "tclsh flash:tcl/clearL0.tcl"

… enabled the EEM CLI debugging and started it:

R1#debug event man action cli
Debug EEM action cli debugging is on
R1#event man run Clear
R1#
%HA_EM-6-LOG: Clear : DEBUG(cli_lib) : : CTL : cli_open called.
%HA_EM-6-LOG: Clear : DEBUG(cli_lib) : : OUT :
%HA_EM-6-LOG: Clear : DEBUG(cli_lib) : : OUT : R1>
%HA_EM-6-LOG: Clear : DEBUG(cli_lib) : : IN : R1>enable
%HA_EM-6-LOG: Clear : DEBUG(cli_lib) : : OUT :
%HA_EM-6-LOG: Clear : DEBUG(cli_lib) : : OUT : R1#
%HA_EM-6-LOG: Clear : DEBUG(cli_lib) : : IN : R1#tclsh flash:tcl/clearL0.tcl
%CLEAR-5-COUNTERS: Clear counter on interface Loopback0 by on vty0 (EEM:Clear)
%HA_EM-6-LOG: Clear : DEBUG(cli_lib) : : OUT :
%HA_EM-6-LOG: Clear : DEBUG(cli_lib) : : OUT : R1#
%HA_EM-6-LOG: Clear : DEBUG(cli_lib) : : CTL : cli_close called.

Great. It works. Let's move on: I've inserted a trigger into the EEM applet that ran the applet when an OSPF neighbor reached FULL adjacency:

event manager applet Clear
 event syslog pattern "OSPF-5-ADJCHG.*to FULL"
 action 1.0 cli command "enable"
 action 1.1 cli command "tclsh flash:tcl/clearL0.tcl"

And now for the final test: after I've enabled the serial interface, OSPF neighbors established adjacency …

R1(config-if)#interface ser 1/0
R1(config-if)#no shutdown
R1(config-if)#
%LINK-3-UPDOWN: Interface Serial1/0, changed state to up
%LINEPROTO-5-UPDOWN: Line protocol on Interface Serial1/0, changed state to up
%OSPF-5-ADJCHG: Process 1, Nbr 10.0.1.2 on Serial1/0 from LOADING to FULL, Loading Done
%CLEAR-5-COUNTERS: Clear counter on interface Loopback0 by on vty0 (EEM:Clear)

… and the counters on Loopback0 were cleared. Test completed :)

You can find more Tclsh-related information in the Tclsh on Cisco IOS tutorial. Sample Tclsh scripts are available in the Tclsh script library. If you need expert help in planning, developing or deploying Tclsh scripts in your network, contact the author.

This article is part of You've asked for it series.

14 comments:

shef said...

Thanks!

Information about EEM is very interesting. We try to use it for monitoring of multicast traffic.

Xavier said...

what about :
action X cli command "clear counters" pattern "confirm"
action X+1 cli command "y"
?

Anonymous said...

Is there any way to create the Tcl script from the router CLI?

I'm using Dynagen to learn the EEM. Don't want to connect the Dynagen routers to my network, and accidentally have one of my test labs affect the network.

For a quick short Tcl script it would be convenient to be able to create the script from the router CLI.

Ivan Pepelnjak said...

@anonymous: If you find a Tcl-based text editor and install it on your router, then you'll be able to create any text file (including Tcl script) from the CLI. No, I haven't found it yet.

As for the other part of your question, search the forums about the use of loopback interface.

Mike said...

There is a TCL based version of ed that I have. Of course ed has a very steep learning curve and is difficult even for most well versed cli folks to use unless they have been using UNIX since the mid-70's. I can send it to you if you are interested. I use it on nearly a daily basis to change EEM scripts on my lab routers.

Ivan Pepelnjak said...

I found a simple Tcl-based editor in the meantime, I just have to find time to port it to IOS. Any volunteers?

Gustavo said...

If you have a ios 12.3(2)T version or above you should have a tcl shell in your ios. Just type tclsh and start scripting.

I would like to put a question as well.
I can combine eem applets with tcl scripts. But, if I want to start the tcl script based on the syslog msg?
How can I get the syslog message into the script?

Thanks,

Gustavo

mtimmsj said...

gustavo: If you have applets (i.e. EEM) and you have Tcl it's easier to just use an EEM Tcl script to do that. Tcl in EEM has added the event_reqinfo command which can be called to get info about the event that triggered the script to be run and one of the items in the list that is returned is msg which contains the message that caused the policy to be triggered.

If you really do want to pass the syslog message to a "pure" Tcl script, the tclsh accepts arguments after the filename so you may be able to pass something in there from the applet. For example, applets that were triggered by the syslog event detector will have the $_syslog_msg variable set. So you could use that variable in the applet. I have never tried it, but it might be possible.

Gustavo said...

Thanks a lot, u´ve been very helpful.
I´ve run into a couple more problems, though, and I would appreciate some more help...

when i use cli_open to get a command-line interface i get the following error:

cannot get pty for exec: Error opening vty no tty lines available, minimum of 2 required by EEM

do you know how i can get past this?

Also, can anyone tell me how to increase the time limit for script execution? the default value is 20 seconds and I would like to increase it

Ivan Pepelnjak said...

To increase the number of VTY lines, use the "line vty" configuration command, specifying higher upper limit (for example, line vty 0 50). If you've changed the default configuration of VTY lines 0-4, you have to change the configuration of lines 5-50 as well.

To change the default timeout, use the maxrun parameter in the event_register_xxx line in your Tcl policy.

Gustavo said...

Thanks a lot Ivan Pepelnjak.
It works with the maxrun option! and.. with your help I just fixed some mistakes in my script :D


I´m trying to find how can I copy (append) a file to a ftp.
The end of my script will create a file into flash with the output. I would like to copy that file to ftp. With the command copy flash:filename ftp://.... it will overwritte. I just want to append...
Do you know how to do that?

Thanks a lot for the help!

Arie Vayner said...

Another approach to achieve the same, but without an external TCL script can be done with the following config:

event manager applet t
event none
action 1.0 cli command "enable"
action 2.0 cli command "tclsh"
action 2.1 cli command "typeahead \"y\" ; exec \"clear counter\""
action 3.0 cli command "exit"

Chris H said...

Vayner's above tcl in an eem script looks interesting, but I can't get it to work. It would be nice to be able to have the ability to embed it into the config file and not a separate script.

Can anyone verify the syntax? I can get it to work on the console, but not in eem

Ivan Pepelnjak said...

You can use the "pattern" option of the "action cli command". Search my blog & wiki for examples.

Ivan Pepelnjak, CCIE#1354, is the chief technology advisor for NIL Data Communications. He has been designing and implementing large-scale data communications networks as well as teaching and writing books about advanced technologies since 1990. See his full profile, contact him or follow @ioshints on Twitter.