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.

16 comments:

  1. Thanks!

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

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

    ReplyDelete
  3. 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.

    ReplyDelete
  4. @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.

    ReplyDelete
  5. 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.

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

    ReplyDelete
  7. 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

    ReplyDelete
  8. 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.

    ReplyDelete
  9. 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

    ReplyDelete
  10. 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.

    ReplyDelete
  11. 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!

    ReplyDelete
  12. 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"

    ReplyDelete
  13. 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

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

    ReplyDelete
  15. Hi all,
    I have an issue with trying to create a script that will handle the "yes/no" question that arises during the shutting down of a active Transcoder.
    What I need to perform via a TCL script is:
    conf t
    dspfarm profile 8 trancode
    shutdown
    exit
    exit


    Of course a typeahead "yes\n" doesn't seem to help due, perhaps due to the fact that the ios_config uses a separate VTY context to issue the its commands.

    I have tried to use the EEM with no success:
    event manager applet disableProf
    event none
    action 1.0 cli command "conf t"
    action 1.1 cli command "dspfarm profile 8 transcode"
    action 1.2 cli command "yes\n"
    action 1.3 cli command "exit"
    action 1.4 cli command "exit"

    But the transcoder profile remains active.

    It seems user prompt questions within the processing via the "exec" construct seems to be possible to handle, however does anyone know of a way to programmatically answer prompted questions with the "ios_config" construct ?

    If the answer is no, then can anyone think of other ways to shutdown a transcoder profile ? (could it be achieved via TCL via the SNMP accessing functionality?

    Here is the actually prompt text for those who haven’t seen a prompted question within the conf t prompt:
    Router(tcl)#ios_config "conf t" "dspfarm profile 8 transcode" "shutdown" "exit"
    Disabling profile will disconnect active TRANSCODING calls,
    do you want to continue ? [yes/no]
    Must be yes or no


    Thanks for all that read this.
    Thanks to Ivan for his excellent blog space.

    ReplyDelete
  16. This might help you write an EEM applet:

    http://blog.ioshints.info/2007/12/execute-cli-commands-with-prompts-in.html

    Good luck!
    Ivan

    ReplyDelete

You don't have to log in to post a comment, but please do provide your real name/URL. Anonymous comments might get deleted.

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.