cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
3420
Views
0
Helpful
7
Replies

tcl script help -- include interface description in status message

branfarm1
Level 4
Level 4

Hi there,

I'm trying to create a script that will email me when an interface goes down, and include the interface description in the email.  I've found a script that successfully emails me when the status changes, and I found another script that will parse for the interface description, but I can't seem to get them to work together.  I've mashed them up together into the below script:

#------------------------------------------------------------------

# EEM policy that will monitor SYSLOG for Interface status changes.

# If UPDOWN message is detected, send an email with interface information.

#

#------------------------------------------------------------------

### The following EEM environment variables are used:

###

### _email_server

### - A Simple Mail Transfer Protocol (SMTP)

### mail server used to send e-mail.

### Example: _email_server mailserver.example.com

# Register for a Syslog event. Event Detector: Syslog

# Match pattern for Interface Status change

::cisco::eem::event_register_syslog pattern "%LINK-3-UPDOWN"

# NAMESPACE IMPORT

namespace import ::cisco::eem::*

namespace import ::cisco::lib::*

# Set array for event_reqinfo

# Array is populated with additional event information

array set Syslog_info [event_reqinfo]

set msg $Syslog_info(msg)

# Set routername variable for use later

set routername [info hostname]

# Parse output for interface name

if { ! [regexp {: ([^:]+)$} $msg -> info] } {

    action_syslog msg "Failed to parse syslog message"

}

regexp {Line protocol on Interface ([a-zA-Z0-9]+)} $info -> interface 

# ------------------- cli open -------------------

#

if [catch {cli_open} result] {

error $result $errorInfo

} else {

array set cli $result

}

# Go into Enable mode

if [catch {cli_exec $cli(fd) "enable"} result] {

error $result $errorInfo

}

#Find interface description

if [catch {cli_exec $cli(fd) "show interface $interface | inc Description" } description] {

        error $description $errorInfo

}

#

#--------------------- cli close ------------------------

#

cli_close $cli(fd) $cli(tty_id)

set time_now [clock seconds]

set time_now [clock format $time_now -format "%T %Z %a %b %d %Y"]

#

# EMAIL MESSAGE

# This manually creates a text message with specific format to be used by the

# smtp_send_email command later to send an email alert.

#

# Ensure the following are configured:

# ip domain-name <domain.com>

#

# If a hostname is used for mailservername, ensure the following are configured:

# ip name-server <dns-server>

# ip domain-lookup

#

# NOTE: Change environment variable _email_server to your SMTP server

#

# The email below references the following variables:

#

# $routername: hostname of device

# $time_now: time when specific Syslog message was detected

# $msg: Syslog message received

#

#

#

set email_message "Mailservername: $_email_server

From: eem-$routername@mycompany.com

To: $_email_to

Cc:

Subject: EEM: Critical interface status change on $routername

This email is generated by EEM.

$time_now

$msg

$description

"

# Send email message

if {[catch {smtp_send_email $email_message} result]} {

set result "Email send failed"

} else {

set result "Email Sent"

}

# Debug message to check email transmission status

action_syslog msg "$result"

----------------------------------------------------

When I trigger an interface UPDOWN message, I'm getting the following error on the command line:

Oct 17 23:56:19.355 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: can't read "interface": no such variable

Oct 17 23:56:19.355 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl:     while executing

Oct 17 23:56:19.355 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: "cli_exec $cli(fd) "show interface $interface | inc Description" "

Oct 17 23:56:19.355 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl:     invoked from within

Oct 17 23:56:19.355 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: "$slave eval $Contents"

Oct 17 23:56:19.355 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl:     (procedure "eval_script" line 7)

Oct 17 23:56:19.355 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl:     invoked from within

Oct 17 23:56:19.355 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: "eval_script slave $scriptname"

Oct 17 23:56:19.359 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl:     invoked from within

Oct 17 23:56:19.359 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: "if {$security_level == 1} {       #untrusted script

Oct 17 23:56:19.359 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl:      interp create -safe slave

Oct 17 23:56:19.359 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl:      interp share {} stdin slave

Oct 17 23:56:19.359 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl:      interp share {} stdout slave

Oct 17 23:56:19.359 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: ..."

Oct 17 23:56:19.359 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl:     (file "tmpsys:/lib/tcl/base.tcl" line 50)

Oct 17 23:56:19.359 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: Tcl policy execute failed: can't read "interface": no such variable

Can anyone help me figure out where I'm going wrong? 

Thanks in advance,

Brandon

1 Accepted Solution

Accepted Solutions

I got the same errors with your file.  Made some changes and I no longer get the interface error with the attached file.

View solution in original post

7 Replies 7

Dan Frey
Cisco Employee
Cisco Employee

Can you remove this line:

::cisco::eem::event_register_syslog pattern "%LINK-3-UPDOWN"

and replace it with:

::cisco::eem::event_register_syslog pattern "LINEPROTO-5-UPDOWN.*"

Also replace:

regexp {Line protocol on Interface ([a-zA-Z0-9]+)} $info -> interface 

with

regexp {Line protocol on Interface ([\/a-zA-Z0-9]+)} $info -> interface

I believe this will get the interface variable populated correctly.

Dan

Hi Dan,

Thanks for the reply.   I've made the changes you suggested but I'm still getting the error:

Oct 18 21:41:50.446 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: can't read "interface": no such variable

Oct 18 21:41:50.446 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl:     while executing

Oct 18 21:41:50.446 HKT: %HA_EM-6-LOG: CriticalLinkStatus.tcl: "cli_exec $cli(fd) "show int $interface | inc Description""

Is there any additional debugging I could place in my script?  Normally I would try and print the variables after each line to see what's being populated, but I'm not sure how I can test that from within EEM.

--Brandon

Brandon,

Could you upload your script file to this site and I will take a look.

Thanks,

Dan

Script attached

I got the same errors with your file.  Made some changes and I no longer get the interface error with the attached file.

That definitely did the trick -- any insight as to what was wrong with my original version?

I had a fat finger in the orginal one I sent you. 

Originally it had this:

regexp {Line protocol on Interface ([\/a-zA-Z0-9]+)} $info -> interface]

This would make a variable named interface] .   Later in the script it called variable "$interface" (without the left bracket) and this generated the error.

Here is the correct syntax.

regexp {Line protocol on Interface ([\/a-zA-Z0-9]+)} $info -> interface

I did change some variable names in the current policy which made it easier for me to troubleshoot.   If you wanted to change the variable and array names back to what you had the policy should still work.

Dan