08-04-2014 08:49 AM
We would like to implement a feature either through EEM or TACACS such that if an identified primary link is shutdown the user is given a second prompt that they must positively verify before the link is actually shutdown.
i.e.:
conf t
int e0/0
shutdown
Are you sure you wish to shutdown this core link? Y
Link e0/0 down
Is something like this possible?
08-04-2014 06:26 PM
Save the example below to a tcl file on your routers flash eg:ifshut.tcl
Add the following lines to your config to specify the user policy directory and increase the script thread count.
event manager directory user policy "flash:/"
event manager scheduler script thread class default number 10
Register the policy
event manager policy ifshut.tcl
::cisco::eem::event_register_cli tag m1 occurs 1 pattern "^interface (.*)$" sync yes
::cisco::eem::event_register_cli tag m2 occurs 1 pattern "^shut(.*)$" sync yes
::cisco::eem::trigger {
::cisco::eem::correlate event m1 or event m2
}
namespace import ::cisco::eem::*
namespace import ::cisco::lib::*
# Create an array and store the message content as CliCommand variable
array set CliData [event_reqinfo]
set CliCommand $CliData(msg)
# Setup procedure to run configuration commands so we can call this simply
proc CLIConfigProc {cmds} {
if [catch {cli_open} result] {
error $result
} else {
array set cli1 $result
}
if [catch {cli_exec $cli1(fd) "enable"} result] {
error $result
}
if [catch {cli_exec $cli1(fd) "term len 0"} result] {
error $result
}
if [catch {cli_exec $cli1(fd) "conf t"} result] {
error $result
}
foreach a_cmd $cmds {
if [catch {cli_exec $cli1(fd) $a_cmd} result] { Body
error $result
} else {
lappend cmd_output $result
}
}
if [catch {cli_close $cli1(fd) $cli1(tty_id)} result] {
error $result
}
return $cmd_output
}
# Create procedure to lappend commands and send to CLIConfigProc
# this allows for structured command application procedures with only a single CLIConfigProc to execute them
proc IFShutProc { IFNAME } {
lappend INTSHUT "interface $IFNAME\r\n"
lappend INTSHUT "shut\r\n"
CLIConfigProc $INTSHUT
}
# Extract the interface name from the cli message and set it to a temp memory location
# reading the interface name will occur in the tag m1 cli event and then exit without processing the remainder of the script
if { [ regexp -nocase {^interface (.+)} $CliCommand ignore intf] } {
appl_reqinfo key "INTID"
appl_setinfo key "INTID" data "$intf"
exit 1
}
# Code from this point forward will run on event tag m2 trigger
# we set the IFID variable by reading the appl_requinfo key INTID
# if the read data is "data" we move the index forward to get the actual data to overcome errors
set IFID [appl_reqinfo key "INTID"]
if { [ lindex $IFID 0 ] == "data" } {
set IFID [ lindex $IFID 1 ]
}
# create a while loop to ensure that we get valid input from the user
set proceed 0
while {$proceed<=0} {
puts ""
puts -nonewline "Do you wish to shutdown interface $IFID (Y/N)? "
flush stdout
set YN [gets stdin]
# trim spaces from the end of the input
set YN [string trim $YN]
if {[regexp -nocase {([y]+)} $YN]} {
# As the appl_setinfo key is deleted when ever it is read, we reset the key value read from the previous step
# in case we are going through repeated shut no shut on interface before changing interface
appl_setinfo key "INTID" data "$IFID"
# send the interface name to the IFShutProc procedure to shut the interface if the user input was yes
IFShutProc $IFID
flush stdout
# set the variable "proceed" to 1 to exit the while loop
set proceed 1
}
if {[regexp -nocase {([n]+)} $YN]} {
# As the appl_setinfo key is deleted when ever it is read, we reset the key value read from the previous step
# in case the user does not says no and then changes his mind before entering another interface
appl_setinfo key "INTID" data "$IFID"
flush stdout
# set the variable "proceed" to 1 to exit the while loop
set proceed 1
}
}
Below is some validation of operation showing the creation of a loopback, shutting and no shutting the interface and the prompts / responses that are provided.
Router#conf t
Enter configuration commands, one per line. End with CNTL/Z.
Router(config)#int loop 133
Router(config-if)#
000154: *Aug 5 01:05:25.131 GMT: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback133, changed state to up
Router(config-if)#shut
Do you wish to shutdown interface loop 133 (Y/N)? n
Router(config-if)#shut
Do you wish to shutdown interface loop 133 (Y/N)? y
Router(config-if)#
000155: *Aug 5 01:05:38.359 GMT: %LINK-5-CHANGED: Interface Loopback133, changed state to administratively down
000156: *Aug 5 01:05:39.359 GMT: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback133, changed state to down
Router(config-if)#
Router(config-if)#no shut
Router(config-if)#
000157: *Aug 5 01:05:49.579 GMT: %LINK-3-UPDOWN: Interface Loopback133, changed state to up
000158: *Aug 5 01:05:50.579 GMT: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback133, changed state to up
Router(config-if)#
Router(config-if)#shut
Do you wish to shutdown interface loop 133 (Y/N)? y
Router(config-if)#
000159: *Aug 5 01:05:58.627 GMT: %LINK-5-CHANGED: Interface Loopback133, changed state to administratively down
000160: *Aug 5 01:05:59.627 GMT: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback133, changed state to down
Router(config-if)#
08-13-2014 04:20 PM
Did the script solve your issue ?
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