08-24-2014 03:28 PM
Hi everyone!
I have some TcL scripts that run fine from tclsh, but I'm not sure how to trigger them from EEM.
Any help would be greatly appreciated.
Here's an example...If I don't use the ::cisco::eem...., or namespace import, the rest of .tcl file runs fine. I realize this script doesn't really require tcl, but I'm using it to get the concept of running a *.tcl file from eem.
Example
########################################################
::cisco::eem::event_register_syslog pattern {ip sla 1 state Down->Up}
namespace import ::cisco::eem::*
namespace import ::cisco::lib::*
set HOSTNAME [lindex [exec "show run | i ^hostname"] 1]
set SERVER "10.0.0.20"
set USER "admin"
set PASSWORD "password"
exec "copy run scp://$USER:$PASSWORD@$SERVER/$HOSTNAME.cfg"
#########################################################
BACKUP_WHEN_UP.tcl: invalid command name "exec"
000045: Aug 24 22:11:20.519 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: while executing
Solved! Go to Solution.
08-25-2014 11:04 AM
You cannot use exec in EEM Tcl. You would need to replace it with:
if { [catch {cli_open} result] } {
exit 1
}
array set cli $result
cli_exec $cli(fd) "enable"
cli_exec $cli(fd) "copy run scp://$USER:$PASSWORD@$SERVER/$HOSTNAME.cfg"
catch {cli_close $cli(fd) $cli(tty_id)}
08-26-2014 07:53 AM
The copy command appears to be interactive. You'll need to answer the prompts or disable them (if you can) in order for this to work. Depending on the prompt, you may be able to disable it by configuring "file prompt quiet". Else, you'll need to change cli_exec to cli_write, then follow that up with cli_read_pattern:
cli_write $cli(fd) "copy ..."
cli_read_pattern $cli(fd) "confirm"
cli_write $cli(fd) "\r"
Where "confirm" is a string within the prompt. The following cli_write command should provide the answer to the prompt (whatever it may be).
08-25-2014 11:04 AM
You cannot use exec in EEM Tcl. You would need to replace it with:
if { [catch {cli_open} result] } {
exit 1
}
array set cli $result
cli_exec $cli(fd) "enable"
cli_exec $cli(fd) "copy run scp://$USER:$PASSWORD@$SERVER/$HOSTNAME.cfg"
catch {cli_close $cli(fd) $cli(tty_id)}
08-25-2014 09:36 PM
Hi Joe, I really appreciate your help!
I did try this & I keep getting max run timeouts... Here's the script, with exec removed. I event simlified it to not use some of the variables thinking that was the issue.
Do you mind giving me a little more indicator of what I'm missing? Again, your help is really appreciated & beneficial.
::cisco::eem::event_register_syslog pattern {ip sla 1 state Down->Up}
namespace import ::cisco::eem::*
namespace import ::cisco::lib::*
array set rn [sys_reqinfo_routername]
set HOSTNAME $rn(routername)
#set SERVER "10.0.0.23"
#set USER "admin"
#set PASSWORD "password"
if { [catch {cli_open} result] } {
exit 1
}
array set cli $result
cli_exec $cli(fd) "enable"
#cli_exec $cli(fd) "copy run scp://$USER:$PASSWORD@$SERVER/$HOSTNAME.cfg"
cli_exec $cli(fd) "copy run scp://admin:password@10.0.0.23/test.cfg"
catch {cli_close $cli(fd) $cli(tty_id)}
************************************
logs,
000182: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: Process Forced Exit- MAXRUN timer expired.
000183: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: while executing
000184: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: "if [catch {cli_read $fd} result] {
000185: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: return -code error "error reading the channel: $result"
000186: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: } else {
000187: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: return $result
000188: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: }"
000189: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: (procedure "cli_exec" line 4)
000190: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: invoked from within
000191: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: "cli_exec $cli(fd) "copy run scp://admin:password@10.0.0.23/test.cfg""
000192: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: invoked from within
000193: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: "$slave eval $Contents"
000194: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: (procedure "eval_script" line 7)
000195: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: invoked from within
000196: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: "eval_script slave $scriptname"
000197: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: invoked from within
000198: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: "if {$security_level == 1} { #untrusted script
000199: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: interp create -safe slave
000200: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: interp share {} stdin slave
000201: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: interp share {} stdout slave
000202: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: ..."
000203: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: (file "tmpsys:/lib/tcl/base.tcl" line 50)
000204: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: Tcl policy execute failed:
000205: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: Process Forced Exit- MAXRUN timer expired.
08-26-2014 07:53 AM
The copy command appears to be interactive. You'll need to answer the prompts or disable them (if you can) in order for this to work. Depending on the prompt, you may be able to disable it by configuring "file prompt quiet". Else, you'll need to change cli_exec to cli_write, then follow that up with cli_read_pattern:
cli_write $cli(fd) "copy ..."
cli_read_pattern $cli(fd) "confirm"
cli_write $cli(fd) "\r"
Where "confirm" is a string within the prompt. The following cli_write command should provide the answer to the prompt (whatever it may be).
08-26-2014 09:15 PM
Thanks Joe! That was it. Here's my results:
::cisco::eem::event_register_syslog pattern {ip sla 1 state Down->Up}
namespace import ::cisco::eem::*
namespace import ::cisco::lib::*
array set rn [sys_reqinfo_routername]
set HOSTNAME $rn(routername)
set SERVER "10.0.0.23"
set USER "admin"
set PASSWORD "password"
if { [catch {cli_open} result] } {
exit 1
}
array set cli $result
cli_exec $cli(fd) "enable"
cli_exec $cli(fd) "configure terminal"
cli_exec $cli(fd) "file prompt quiet"
cli_exec $cli(fd) "end"
cli_exec $cli(fd) "enable"
cli_exec $cli(fd) "copy run scp://$USER:$PASSWORD@$SERVER/$HOSTNAME.cfg"
cli_exec $cli(fd) "configure terminal"
cli_exec $cli(fd) "no file prompt quiet"
cli_exec $cli(fd) "end"
catch {cli_close $cli(fd) $cli(tty_id)}
08-25-2014 12:33 PM
Thanks Joe!
Do set commands still work? I'll give this a shot.
~Cory Anderson
08-25-2014 01:53 PM
Yes, set still works. But exec needs to be done using the CLI handle. And the hostname can be obtained using:
array set rn [sys_reqinfo_routername]
set HOSTNAME $rn(routername)
08-15-2024 11:13 PM
Another thing you could do if you already have the TCL script, is run it directly from within the event manager applet. That way you dont have to rewrite everyting into cli_open and can just use exec as you are used to. We run scripts alot on our devices that way:
event manager applet RUNTCLSCRIPT
event timer cron cron-entry "0 2 * * *" maxrun 1800
action 001 cli command "enable"
action 002 cli command "tclsh flash:/company/scripts/alias.tcl arg1 arg2"
You can also point directly to a central TFTP or HTTP source so you do not have to store the scripts locally. Hope this helps someone else in the future that stumbles over this thread.
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide