cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
3755
Views
0
Helpful
9
Replies

TCL cli_read_pattern

jakehull123
Level 1
Level 1

Folks,

            I have a TCL script that copies the contents of  file nat.cfg to the running configs of an ASR. The file can ether have commands to add NAT or remove

e.g.  ip nat inside source static 10.116.108.12 192.122.108.12 vrf test OR

         no ip nat inside source static 10.116.108.12 192.122.108.12 vrf test

The below script works well to add NAT and also to remove NAT that is not in use. However, if the NAT is active the router prompts for:

Static entry in use, do you want to delete child entries? [no]:

So, after the file is copied to the running configs of the Router. I need to check if there is a CLI pattern. If there is, I need to add no. However, if there is not a CLI pattern, I need to exit out of the script. I'm suck at this point.

If I assume there is a CLI pattern and write "yes" and actually there is not one the script hangs for some time. This is time critical so can't afford it to hang.


::cisco::eem::event_register_none

namespace import ::cisco::eem::*

namespace import ::cisco::lib::*


array set arr_einfo [event_reqinfo]



if [catch {cli_open} result] {

error $result $errorInfo

} else {

array set cli1 $result

}


if [catch {cli_write $cli1(fd) "copy http://$server_ip/nat/nat.cfg running-config"} _cli_result] {

error $_cli_result $errorInfo

}


if [catch {cli_read_pattern $cli1(fd) "running-config"} _cli_result] {

error $_cli_result $errorInfo

}


if [catch {cli_exec $cli1(fd) "running-config"} _cli_result] {

error $_cli_result $errorInfo

}

AT THIS POINT:

1) EITHER ANOTHER PATTERN FOR "no" WILL SHOW UP AND THE SCRIPT NEEDS TO SEND "yes"

2) OR IF No (nothing) PATTERN SHOWS UP, THE SCRIPT NEEDS TO EXIT


catch {cli_exec $cli1(fd)} _cli_result]

error $_cli_result $errorInfo

puts "CLI EROR IS $_cli_result

1 Accepted Solution

Accepted Solutions

Joe Clarke
Cisco Employee
Cisco Employee

I seem to recall answering this on another thread.  Can you not clear ip nat trans before running this script, or is that too extreme?

If it is too extreme, what you can do with cli_read_pattern is this:

if [catch {cli_read_pattern $cli1(fd) "yes|#"} _cli_result] {

    error $_cli_result $errorInfo

}

if { [regexp {yes} $_cli_result] } {

    cli_write ...

}

exit 0

View solution in original post

9 Replies 9

Joe Clarke
Cisco Employee
Cisco Employee

I seem to recall answering this on another thread.  Can you not clear ip nat trans before running this script, or is that too extreme?

If it is too extreme, what you can do with cli_read_pattern is this:

if [catch {cli_read_pattern $cli1(fd) "yes|#"} _cli_result] {

    error $_cli_result $errorInfo

}

if { [regexp {yes} $_cli_result] } {

    cli_write ...

}

exit 0

Hi Joseph,

                         Thank you for your quick reply.  Yes, you may have been asked the same question via some internal sources.  The issue with clear ip nat is that we are running VRF so each clear ip nat needs to be dynamically generated for the VRF. I tried the generic clear ip NAT forced via EEM but that did not seem to help.

What I have pasted about is my first TCL script so I am not too comfortable with the the launguage yet. Below is what I tested but it seems to error out. Any help is appreciated.

::cisco::eem::event_register_none

namespace import ::cisco::eem::*

namespace import ::cisco::lib::*

array set arr_einfo [event_reqinfo]

if [catch {cli_open} result] {

    error $result $errorInfo

} else {

    array set cli1 $result

}

if [catch {cli_write $cli1(fd) "copy http://IP ADD/nat/http.cfg running-config"} _cli_result] {

    error $_cli_result $errorInfo

}

if [catch {cli_read_pattern $cli1(fd) "running-config"} _cli_result] {

    error $_cli_result $errorInfo

}

if [catch {cli_exec $cli1(fd) ""} _cli_result] {

    error $_cli_result $errorInfo

}

if [catch {cli_read_pattern $cli1(fd) "no|#"} _cli_result] {

    error $_cli_result $errorInfo

}

if { [regexp {no} $_cli_result] } {

           if [catch {cli_write $cli1(fd) "yes"} _cli_result]

            {

              error $_cli_result $errorInfo

             }

}

# Close open cli before exit.

catch {cli_close $cli1(fd) $cli1(tty_id)} result

Debugging INFO

May  9 02:52:55.026: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : CTL : cli_open called.

May  9 02:52:55.152: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT :  ###

May  9 02:52:55.152: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : ###########################################################################

May  9 02:52:55.152: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : ##########################################################################

May  9 02:52:55.152: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT :

May  9 02:52:55.152: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : VASR#

May  9 02:52:55.153: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : IN  : ASR#copy http://IP OF SERVER/nat/http.cfg running-config

May  9 02:52:55.453: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : Destination filename [running-config]?

May  9 02:52:55.453: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : IN  :

May  9 02:52:55.460: %PARSER-4-BADCFG: Unexpected end of configuration file.

May  9 02:52:55.563: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : Accessing http://IP OF SERVER/nat/http.cfg...

May  9 02:52:55.563: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : Loading http://IP OF SERVER/nat/http.cfg

May  9 02:52:55.563: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : 66 bytes copied in 0.005 secs (13200 bytes/sec)

May  9 02:52:55.563: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : R-ASR#

    while executing

"after 100"

    (procedure "cli_read_pattern" line 11)

    invoked from within

"cli_read_pattern $cli1(fd) "yes|#""

    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: Process Forced Exit- MAXRUN timer expired.

____

What is the best way to run this script? Everytime I update the script I have to do the following:

copy http://SERVER WITH TCL SCRIPT/nat/test.tcl bootflash:


conf t

event man dir user policy bootflash:

no event man policy test.tcl

event man policy test.tcl

end

event manager run test.tcl


On newer versions of IOS, I like to use this command to reregister a script.  It will take care of the copy and the reregister:

event manager update user policy name test.tcl repository http://SERVER/nat

I assume you have it working with my last reply and the conditional read_pattern?

Hello again Joseph,

                                  No, I was not able to get the script to work.  Could please take a look? I really appreciate your help.

::cisco::eem::event_register_none

namespace import ::cisco::eem::*

namespace import ::cisco::lib::*

array set arr_einfo [event_reqinfo]

if [catch {cli_open} result] {

    error $result $errorInfo

} else {

    array set cli1 $result

}

if [catch {cli_write $cli1(fd) "copy http://IP ADD/nat/http.cfg running-config"} _cli_result] {

    error $_cli_result $errorInfo

}

if [catch {cli_read_pattern $cli1(fd) "running-config"} _cli_result] {

    error $_cli_result $errorInfo

}

if [catch {cli_exec $cli1(fd) ""} _cli_result] {

    error $_cli_result $errorInfo

}

This is the pattern that we need to catch:

Static entry in use, do you want to delete child entries? [no]:

In the sample code you provided, you had put yes, I changed it to no based on the above

if [catch {cli_read_pattern $cli1(fd) "no|#"} _cli_result] {

    error $_cli_result $errorInfo

}

if { [regexp {no} $_cli_result] } {

           if [catch {cli_write $cli1(fd) "yes"} _cli_result]

            {

              error $_cli_result $errorInfo

             }

}

# Close open cli before exit.

catch {cli_close $cli1(fd) $cli1(tty_id)} result

Debugging INFO

May  9 02:52:55.026: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : CTL : cli_open called.

May  9 02:52:55.152: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT :  ###

May  9 02:52:55.152: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : ###########################################################################

May  9 02:52:55.152: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : ##########################################################################

May  9 02:52:55.152: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT :

May  9 02:52:55.152: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : VASR#

May  9 02:52:55.153: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : IN  : ASR#copy http://IP OF SERVER/nat/http.cfg running-config

May  9 02:52:55.453: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : Destination filename [running-config]?

May  9 02:52:55.453: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : IN  :

May  9 02:52:55.460: %PARSER-4-BADCFG: Unexpected end of configuration file.

May  9 02:52:55.563: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : Accessing http://IP OF SERVER/nat/http.cfg...

May  9 02:52:55.563: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : Loading http://IP OF SERVER/nat/http.cfg

May  9 02:52:55.563: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : 66 bytes copied in 0.005 secs (13200 bytes/sec)

May  9 02:52:55.563: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : R-ASR#

    while executing

"after 100"

    (procedure "cli_read_pattern" line 11)

    invoked from within

"cli_read_pattern $cli1(fd) "yes|#""

    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: Process Forced Exit- MAXRUN timer expired.

Your stack trace still say "yes|#", so I'm a bit confused.  Have you properly reregistered the script after making the right changes?

My appoligies. I had pasted the wrong output. Below is the updated script and the output:

SCRIPT:

::cisco::eem::event_register_none

namespace import ::cisco::eem::*

namespace import ::cisco::lib::*

array set arr_einfo [event_reqinfo]

if [catch {cli_open} result] {

    error $result $errorInfo

} else {

    array set cli1 $result

}

if [catch {cli_write $cli1(fd) "copy http://SERVER/nat/http.cfg running-config"} _cli_result] {

    error $_cli_result $errorInfo

}

if [catch {cli_read_pattern $cli1(fd) "running-config"} _cli_result] {

    error $_cli_result $errorInfo

}

if [catch {cli_exec $cli1(fd) ""} _cli_result] {

    error $_cli_result $errorInfo

}

#This is the pattern that we need to catch:

#Static entry in use, do you want to delete child entries? [no]:

#If the pattern exists, issue a yes. If no pattern, exit the script

if [catch {cli_read_pattern $cli1(fd) "no|#"} _cli_result] {

    error $_cli_result $errorInfo

}

if { [regexp {no} $_cli_result] } {

puts "NEED TO EXEC yes here" <<--- I put this here to check if I get this far. Also not sure yet what the                                                                                  command   format will look like for  cli_write

}

# Close open cli before exit.

catch {cli_close $cli1(fd) $cli1(tty_id)} result

DEBUGGING:

May  9 21:03:15.432: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : CTL : cli_open called.

May  9 21:03:15.561: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT :  ###

May  9 21:03:15.561: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : ###########################################################################

May  9 21:03:15.561: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : ##########################################################################

May  9 21:03:15.561: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT :

May  9 21:03:15.562: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : RTR-ASR#

May  9 21:03:15.562: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : IN  : RTR-ASR#copy http://SERVER/nat/http.cfg running-config

May  9 21:03:15.976: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : Destination filename [running-config]?

May  9 21:03:15.976: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : IN  :

May  9 21:03:15.994: %PARSER-4-BADCFG: Unexpected end of configuration file.

May  9 21:03:16.192: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : Accessing http://SERVER/nat/http.cfg...

May  9 21:03:16.192: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : Loading http://SERVER/nat/http.cfg

May  9 21:03:16.192: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : 65 bytes copied in 0.012 secs (5417 bytes/sec)

May  9 21:03:16.192: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : RTR-ASR#Process Forced Exit- MAXRUN timer expired.

    while executing

"after 100"

    (procedure "cli_read_pattern" line 11)

    invoked from within

"cli_read_pattern $cli1(fd) "no|#""

    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: Process Forced Exit- MAXRUN timer expired.



Try changing the pattern to "Loading|no|#" and see if that works.

Thanks. Tested it but didn’t seem to help. I ran the TCL script two times. First with commands in the http.cfg file that will not require a "yes" (no CLI pattern) and then with commands in the http.cfg file that will require a "yes" to be entered. Below are the two debugs.  I really appreciate your help.

Debug with "yes" not required (no CLI pattern):

May 10 16:19:06.332: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : CTL : cli_open called.

May 10 16:19:06.458: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT :  ###

May 10 16:19:06.458: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : ###########################################################################

May 10 16:19:06.458: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : ##########################################################################

May 10 16:19:06.458: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT :

May 10 16:19:06.458: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : RTR-ASR#

May 10 16:19:06.459: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : IN  : RTR-ASR#copy http://SERVER/nat/http.cfg running-config

May 10 16:19:06.759: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : Destination filename [running-config]?

May 10 16:19:06.759: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : IN  :

May 10 16:19:06.768: %PARSER-4-BADCFG: Unexpected end of configuration file.

May 10 16:19:06.869: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : Accessing http://SERVER/nat/http.cfg...

May 10 16:19:06.869: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : Loading http://SERVER/nat/http.cfg

May 10 16:19:06.869: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : 65 bytes copied in 0.007 secs (9286 bytes/sec)

May 10 16:19:06.869: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : RTR-ASR#Process Forced Exit- MAXRUN timer expired.

    while executing

"after 100"

    (procedure "cli_read_pattern" line 11)

    invoked from within

"cli_read_pattern $cli1(fd) "Loading|no|#""

    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: Process Forced Exit- MAXRUN timer expired.

Debug with "yes" required

_______________

May 10 16:21:34.605: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : CTL : cli_open called.

May 10 16:21:34.731: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT :  ###

May 10 16:21:34.731: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : ###########################################################################

May 10 16:21:34.731: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : ##########################################################################

May 10 16:21:34.731: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT :

May 10 16:21:34.731: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : RTR-ASR#

May 10 16:21:34.732: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : IN  : RTR-ASR#copy http://SERVER/nat/http.cfg running-config

May 10 16:21:35.032: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : OUT : Destination filename [running-config]?

May 10 16:21:35.032: %HA_EM-6-LOG: test.tcl : DEBUG(cli_lib) : IN  : Process Forced Exit- MAXRUN timer expired.

    while executing

"error $_cli_result $errorInfo"

    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: Process Forced Exit- MAXRUN timer expired.

RTR-ASR#

May 10 16:21:54.438: %PARSER-4-BADCFG: Unexpected end of configuration file.

May 10 16:21:54.439: tty is now going through its death sequence

Try adding "Accessing" to the list of patterns.  You should also make sure your configlet file ends with the word "end".