10-08-2013 07:03 AM
I've written a very simple script today... Basically the whole idea is to use the cli_run_interactive command from the EEM cli library extensions. According to this document
http://www.cisco.com/en/US/docs/ios-xml/ios/eem/configuration/xe-3se/5700/eem-cli-library-tcl.pdf
I have to use the ::cisco::eem:: namespace, which I did. Then, again from the same document I found the command cli_run_interactive which does exactly what I need, to execute a command, watch for a predefined command output and react on it, again in a predefined way. Pretty straight forward. Below the script:
::cisco::eem::event_register_none maxrun 36
namespace import ::cisco::eem::*
namespace import ::cisco::lib::*
set cmd1 "clear line 46"
set cmd1_exp1 {[confirm]}
set cmd1_rep1 {y}
set cmd1_response [list [list expect $cmd1_exp1 reply $cmd1_rep1]]
set clist [list " command $cmd1 responses $cmd1_response"]
cli_run_interactive { clist }
So far, so good, I register the script:
Terminal#show runn | sec event manager
event manager directory user policy flash:/
event manager policy run_interactive.tcl type user
Terminal#show event manager policy registered
No. Class Type Event Type Trap Time Registered Name
1 script user none Off Tue Oct 8 17:19:04 2013 run_interactive.tcl
policyname {run_interactive.tcl}
nice 0 queue-priority normal maxrun 36.000
But then, when I try to execute the script:
Terminal#event manager run run_interactive.tcl
Terminal#invalid command name "cli_run_interactive"
while executing
"cli_run_interactive { clist }"
invoked from within
"$slave eval $Contents"
(procedure "eval_script" line 7)
invoked from within
"eval_script slave $scriptname"
invoked from within
"if {$security_level == 1} { #untrusted script
interp create -safe slave
interp share {} stdin slave
interp share {} stdout slave
..."
(file "system:/lib/tcl/base.tcl" line 50)
Tcl policy execute failed: invalid command name "cli_run_interactive"
So it seems to me I've missed a declaration somewhere along the way, but I can not figure out where and what exactly... Any help is appreciated...
Solved! Go to Solution.
10-09-2013 07:56 AM
When I wrote the function, the syntax was:
set cmd1 "first command"
set cmd [list "send" $cmd1 "responses" [list [list "expect" {[confirm]} "reply" "y"]]
array set sendexp $cmd
cli_run_interactive [list [array get sendexp]]
10-09-2013 08:15 AM
Yeah, I forgot a closing ']'. Change "send" to "command". I think the developers made that change when they imported my function.
10-08-2013 08:01 AM
It seems to me that I have a similar issue like the one described in this thread:
10-08-2013 08:25 AM
Hi Joseph,
I think you're right, as always
I tried the script on few different IOS versions I have at my disposal, here are the results:
1. Version 12.4(15)T15
SEC_BB3#more tmpsys:/lib/tcl/cli_lib.tcl
namespace eval ::cisco::eem {
namespace export cli_open cli_exec cli_close
namespace export cli_write cli_read cli_read_pattern
namespace export cli_read_line cli_read_drain
namespace export cli_get_ttyname
So here most of the commands explained in the document I refered to are listed... but not the one I'm trying to use...
2. Version 15.2(4)M3
namespace eval ::cisco::eem {
namespace export cli_open cli_exec cli_close
namespace export cli_write cli_read cli_read_pattern
namespace export cli_read_line cli_read_drain
namespace export cli_get_ttyname
namespace export cli_run cli_run_interactive
namespace export xml_pi_exec xml_pi_parse xml_pi_write xml_pi_read
3. The system where I've executed the script, Version 12.4(13b)
Terminal#more tmpsys:/lib/tcl/cli_lib.tc
^
% Invalid input detected at '^' marker.
So I guess I definatelly need an upgrade at least to IOS version 12.4(15)T15 where I could at least use cli_read_pattern and do the same thing. I'll see what I could do tomorrow and I'll update the thread...
Are you aware of any reference document, so that I could check which is the minimum supproted IOS version?
10-08-2013 09:25 AM
You need at least EEM 3.0 for this function. That would be 12.4(22)T or higher. The cli_read_pattern function is supported in 12.4(13b) (EEM 2.1).
10-09-2013 06:48 AM
Hi Joseph,
I upgraded the system to one of the latest versions 15.1(4)M7.
Terminal#more tmpsys:/lib/tcl/cli_lib.tcl
namespace eval ::cisco::eem {
namespace export cli_open cli_exec cli_close
namespace export cli_write cli_read cli_read_pattern
namespace export cli_read_line cli_read_drain
namespace export cli_get_ttyname
namespace export cli_run cli_run_interactive
namespace export xml_pi_exec xml_pi_parse xml_pi_write xml_pi_read
So this command should be implemented. And indeed it is. But than again, when I try to execute the script, I've got a strange error....
Terminal_Training#event manager run run_interactive.tcl
list must have an even number of elements
while executing
"array set sendexp $cmd"
(procedure "cli_run_interactive" line 19)
invoked from within
"cli_run_interactive { clist }"
invoked from within
"$slave eval $Contents"
(procedure "eval_script" line 7)
invoked from within
"eval_script slave $scriptname"
invoked from within
"if {$security_level == 1} { #untrusted script
interp create -safe slave
interp share {} stdin slave
interp share {} stdout slave
..."
(file "tmpsys:/lib/tcl/base.tcl" line 50)
Tcl policy execute failed: list must have an even number of elements
The error is quite clear, but why? According to the guide
http://www.cisco.com/en/US/docs/ios-xml/ios/eem/configuration/xe-3se/5700/eem-cli-library-tcl.pdf
on page 8, I've just used the example, but with one command only:
set cmd1 "first command"
set cmd1_exp1 {[confirm]}
set cmd1_rep1 {y}
set cmd1_response [list [list expect $cmd1_exp1 reply $cmd1_rep1]]
Am I missing something?
10-09-2013 07:56 AM
When I wrote the function, the syntax was:
set cmd1 "first command"
set cmd [list "send" $cmd1 "responses" [list [list "expect" {[confirm]} "reply" "y"]]
array set sendexp $cmd
cli_run_interactive [list [array get sendexp]]
10-09-2013 08:13 AM
Joseph,
I believe an additional square braket is needed in the line:
set cmd [list "send" $cmd1 "responses" [list [list "expect" {[confirm]} "reply" "y"]]]
Otherwise it does not let me register the policy.
I'm runnint version 15.1(4)M7 on this machine.
Terminal#more tmpsys:/lib/tcl/cli_lib.tcl
namespace eval ::cisco::eem {
namespace export cli_open cli_exec cli_close
namespace export cli_write cli_read cli_read_pattern
namespace export cli_read_line cli_read_drain
namespace export cli_get_ttyname
namespace export cli_run cli_run_interactive
namespace export xml_pi_exec xml_pi_parse xml_pi_write xml_pi_read
Below is the result I've got:
Terminal#event manager run run_interactive.tcl
can't read "sendexp(command)": no such element in array
while executing
"cli_run_interactive [list [array get sendexp]]"
invoked from within
"$slave eval $Contents"
(procedure "eval_script" line 7)
invoked from within
"eval_script slave $scriptname"
invoked from within
"if {$security_level == 1} { #untrusted script
interp create -safe slave
interp share {} stdin slave
interp share {} stdout slave
..."
(file "tmpsys:/lib/tcl/base.tcl" line 50)
Tcl policy execute failed: can't read "sendexp(command)": no such element in array
10-09-2013 08:15 AM
Yeah, I forgot a closing ']'. Change "send" to "command". I think the developers made that change when they imported my function.
10-09-2013 08:28 AM
I can confirm, that changing the script... it finally works
What is the proper way of putting log messages in between the cli commands, so that I could follow the script execution and possibly finding mistakes in my logic?
I mean, this is quite a simple script... even though I've written it using wrong syntax But in a more elaborate scripts, it would be quite nice to follow log messages that are generated at certain points of the script...
I found the following in one example.. somewhere on the net:
action_syslog priority emergencies msg "Log message"
Thank your for your persistence and promptness. I really appreciate it!
Regards,
Boyan
10-09-2013 08:29 AM
action_syslog is the way to go. If the script is synchronous, then you can also use "puts" to print a string to the current terminal.
10-09-2013 08:35 AM
I also noticed that the following debug:
debug event manager tcl cli_library
Produces outputs like these, which are quite nice:
*Oct 9 17:23:41.211: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : CTL : cli_open called.
*Oct 9 17:23:41.383: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : OUT : Terminal#
*Oct 9 17:23:41.383: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : IN : Terminal#enable
*Oct 9 17:23:41.503: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : OUT : Terminal#
*Oct 9 17:23:41.503: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : IN : Terminal#clear line 46
*Oct 9 17:23:41.707: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : OUT : [confirm]
*Oct 9 17:23:41.707: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : IN : y
*Oct 9 17:23:41.923: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : OUT : y [OK]
*Oct 9 17:23:41.923: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : OUT : Terminal#
*Oct 9 17:23:41.923: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : OUT : Terminal#
*Oct 9 17:23:41.923: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : CTL : cli_close called.
So I guess, cli_open and cli_close are implemented withing the cli_run_interactive function and are automatically called upon execution....
10-09-2013 09:10 AM
Yes, it has to in order to open the CLI session. The debug is a good way to see what the commands are doing, but if you want to add your own logic, use puts or action_syslog.
10-08-2013 08:09 AM
You may not have the function. What version of IOS do you have? If you do "more tmpsys:/lib/tcl/cli_lib.tcl" do you see this proc?
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