Persistent EEM variables

Someone has asked me a while ago whether it's possible to retain variable values between invocations of an EEM policy. Since a new copy of Tcl interpreter is started for each event, global variables obviously won't work; they are lost as soon as the Tcl policy is finished. A potential solution is to modify the router's configuration and save the values you wish to preserve in event manager environment, but that's a time-consuming process that interferes with whatever router configuration management process you have.

The real solution is based on the appl_setinfo and appl_reqinfo calls. They work, but like many other Tcl-related IOS features they are … well … weird. This time, the programmers managed to implement WORO (Write-Once-Read-Once) memory:
  • The value you want to preserve is saved with appl_setinfo key name data value function call. Keys must be unique; you can only set the same key once. If you try to set the value of a key multiple times, the function does not overwrite the previous value but fails.
  • You can read the value with appl_reqinfo key name function call. If the key value hasn't been set, it returns an empty string and sets the $_cerrno variable, otherwise it returns a list with 'data' as the first element and your value as the second list element (I have to admit I've seen simpler APIs :).
  • Once you read the key value, it's gone. You cannot read it twice.
If all this sounds a bit strange, don't worry; here's a working example:
::cisco::eem::event_register_cli sync no skip no pattern "show"

namespace import ::cisco::eem::*
namespace import ::cisco::lib::*

Set the variable value to zero (in case we haven't saved the value before) and read the previous value

set lastCnt 0
set getLastCnt [ appl_reqinfo key "showCounter" ]

If the first element in the list is 'data', then the second element is our value.

if { [ lindex $getLastCnt 0 ] == "data" } {
  set lastCnt [ lindex $getLastCnt 1 ]
}

Increase the counter and generate a syslog message

incr lastCnt
action_syslog priority info msg "Show command was executed $lastCnt times"

Save the new value of the counter to be retrieved by the next invocation of the same policy.

appl_setinfo key "showCounter" data $lastCnt

This article is part of You've asked for it series.

Add comment
Sidebar