cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
3544
Views
0
Helpful
10
Replies
brillisour
Beginner

Using CDP and EEM to Dynamically Shutdown Ports

Hello I'm new to EEM scripting.  My ultimate goal is to design a script that will shutdown switchports that are connected to wireless access points, and then a few hours later turn them back on.  I've tried combining a shutdown script and also a CDP script (both work on their own), however I'm not getting the results that I want.  Below is one of the many things that I've tried.  Any help would be greatly appreciated.

event manager environment Disable_Wifi

event manager applet Test

event neighbor-discovery interface regexp FastEthernet.* cdp all

action 1.0 if $_nd_cdp_capabilities_string eq "Trans-Bridge" goto 1.2

action 1.1 if $_nd_cdp_capabilities_string ne "Trans-Bridge" goto 1.6

action 1.2 cli command "enable"

action 1.3 cli command "config t"

action 1.4 cli command "interface $_nd_local_intf_name"

action 1.5 cli command "shutdown"

action 1.6 cli command "exit"

event manager applet DisableInterface

event timer cron name DisableInterface cron-entry "00 21 * * *"

action 1.0 cli command "enable"

action 1.1 cli command "configure terminal"

action 1.2 cli command "interface $_nd_local_intf_name"

action 1.3 cli command "shutdown"

event manager applet EnableInterface

event timer cron name EnableInterface cron-entry "00 05 * * *"

action 1.0 cli command "enable"

action 1.1 cli command "configure terminal"

action 1.2 cli command "interface $_nd_local_intf_name"

action 1.3 cli command "no shutdown"

event manager applet EnableAfterReload

action 1.0 cli command "enable"

action 1.1 cli command "configure terminal"

action 1.2 cli command "interface range $_nd_local_intf_name"

action 1.3 cli command "no shutdown"

10 REPLIES 10
Joe Clarke
Hall of Fame Cisco Employee

First I would probably change the "cdp all" to "cdp update".  You also don't need action 1.1 in the first applet.  Next, the variables you're using in your policies won't always work.  The _nd* variables will only be available in the neighbor-discovery policy.  So your choice is that you need to cache the list of interfaces you've shutdown.  With applets, you can do this with contexts or by entering config t mode and creating a new environment variable. 

What would the syntax look like to cache the cdp interfaces they are shutdown, and then recall them to reenable?

Thanks for the help

Neal

The best way would be to spawn a new EEM script with a timer to reenable the port.

You could do something like this:

event manager environment q "

!

event manager applet SPAWN

event neighbor-discovery interface Ethernet0/0 cdp update line-event up

action 1.0 cli command "enable"

action 1.1 cli command "conf t"

action 2.0 cli command "event manager applet ENABLE-$_nd_local_intf_name"

action 2.1 cli command " event timer countdown time 3600"

action 2.2 cli command " action 1.0 cli command $q enable $q "

action 2.3 cli command "action 1.1 cli command $q conf t $q "

action 2.4 cli command "action 2.0 cli command $q interface $_nd_local_intf_name $q "

action 2.5 cli command "action 2.1 cli command $q no shut $q "

action 2.6 cli command "action 3.0 syslog msg $q Interface $_nd_local_intf_name was re-enabled after a CDP-triggered shutdown"

Joe Clarke
Hall of Fame Cisco Employee

While Arie's recommendation is a good one, you'll also need to add another applet (or use multi-event applets) to allow for restoring the interface at reload time.  This could also lead to a lot of applets being configured, and depending on the number of ports, could result in interfaces not being re-enabled at reload time.  You may still want to look at the context or environment variable solution.  The former might look like:

action 1.0 handle-error type ignore

action 1.1 context retrieve key CDPCTXT variable ports

action 1.2 if $_error ne FH_EOK

action 1.3  set ports ""

action 1.4 end

action 1.5 handle-error type exit

action 1.6 cli command "enable"

action 1.7 cli command "config t"

action 1.8 foreach port $ports

action 1.9  cli command "int $port"

action 2.0  cli command "no shut"

action 2.1 end

action 2.2 cli command "end"

To cache a port:

action 1.0 handle-error type ignore

action 1.1 context retrieve key CDPCTXT variable ports

action 1.2 if $_error ne FH_EOK

action 1.3  set ports ""

action 1.4 end

action 1.5 handle-error type exit

action 1.6 append ports "$_nd_local_intf_name "

action 1.7 context save key CDPCTXT variable ports

Thank you both for the advice.  I'm still a little confused on how to tie your recommendations into my original script.  I've read through some of the Cisco EEM documentation, but find it is pretty hard to make sense of.  Does anyone know of a similar script that exists that I could look at to compare?  Any additional help is very much appreciated.

Thanks

I'm finding that when I use the various cdp functions it will affects all ports connected to a Cisco devices rather than just access point.  One variation is below.  I've also tried defining the capability string and platform.  Everything will either not work at all, or will implement the change to all interfaces with Cisco devices as neighbors.  Thoughts?

event manager environment Disable_Wifi

event manager applet Test

event neighbor-discovery cdp all interface regexp FastEthernet.*

action 1.0 if $_nd_cdp_entry_name eq "SEP*" goto 1.9

action 1.1 if $_nd_cdp_entry_name ne "SEP*" goto 1.2

action 1.2 cli command "enable"

action 1.3 cli command "config t"

action 1.4 cli command "interface $_nd_local_intf_name"

action 1.5 cli command "power inline never"

action 1.6 wait 120

action 1.7 cli command "interface $_nd_local_intf_name"

action 1.8 cli command "power inline auto"

action 1.9 cli command "exit"

Joe Clarke
Hall of Fame Cisco Employee

This applet won't work for the reason we described earlier.  You'd need to use Arie's at least to allow for the longer wait time.  Additionally, the eq and ne operations don't work with wildcards.  Use a regular expression:

action 1.0 regexp "SEP.*" $_nd_cdp_entry_name

action 1.1 if $_regexp_result eq 0 goto 1.9

Joe Clarke
Hall of Fame Cisco Employee

Arie's example simply replaces your original applet.  Mine replace the actions inside.  For example, if the applet that detects the CDP event, you'd cache the ports in question (i.e., use the second set of actions).  When you need to operate on those ports again, you run the first set of actions to bring the ports back up.

With Arie's script I still lose all Cisco connected ports not just the ones connected to wireless access points.  Additionally, as soon as the port is reenabled it goes down again.  I want the script to deploy once per day at a specific time.  Is this feasible?

event manager environment q "

!

event manager applet SPAWN

event neighbor-discovery interface regexp FastEthernet.* cdp update line-event up

action 1.0 cli command "enable"

action 1.1 cli command "conf t"

action 1.2 cli command "interface $_nd_local_intf_name"

action 1.3 cli command "power inline never"

action 2.0 cli command "event manager applet ENABLE-$_nd_local_intf_name"

action 2.1 cli command " event timer countdown time 60"

action 2.2 cli command " action 1.0 cli command $q enable $q "

action 2.3 cli command "action 1.1 cli command $q conf t $q "

action 2.4 cli command "action 2.0 cli command $q interface $_nd_local_intf_name $q "

action 2.5 cli command "action 2.1 cli command $q power inline auto $q "

action 2.6 cli command "action 3.0 syslog msg $q Interface $_nd_local_intf_name was re-enabled after a CDP-triggered shutdown"

Joe Clarke
Hall of Fame Cisco Employee

For the first issue you'd have to incorporate those lines I mentioned above to match on the SEP string:

action 0.1 regexp "SEP.*" $_nd_cdp_entry_name

action 0.2 if $_regexp_result eq 0 goto 2.7

action 2.7 exit 1

For the second issue, this gets a bit more complicated.  You'd also want to check time.  In fact, you probably don't want this to be a CDP event at all.  Rather you want this to be cron-triggered, then you want to check each CDP neighbor.  This isn't simple to do in EEM applets.  I think this rough hack might work.

event manager applet shutdown-ap-ports

event timer cron cron-entry "0 19 * * *"

action 001 cli command "enable"

action 0011 cli command "config t"

action 002 cli command "do show cdp nei | begin ^Device ID"

action 0021 set intfs ""

action 003 foreach line $_cli_result "\n"

action 004 string trimright $line

action 005 set line $_string_result

action 006 set intf "-1"

action 007 regexp "^[^ ]+ +([A-Za-z]+ [0-9/\.:]+)" $line match intf

action 008 if $_regexp_result eq 0

action 009  regexp "^ +([A-Za-z]+ [0-9/\.:]+)" $line match intf

action 010 end

action 011 if $intf eq "-1"

action 012  exit 1

action 013 end

action 014 regexp " AIR-" $line

action 015 if $_regexp_result eq 1

action 016  append intfs "$intf "

action 017  cli command "interface $intf"

action 018  cli command "power inline never"

action 019 end

action 0191 end

action 020 cli command "event manager applet REENABLE-APS"

action 021 cli command "event timer countdown time 60"

action 022 cli command "action 001 cli command enable"

action 023 cli command "action 002 cli command $q config t$q"

action 024 set i 3

action 0241 set j 0

action 0242 foreach intf $intfs " "

action 025  if $intf ne ""

action 026   cli command "action 0$j$i cli command $q interface $intf$q"

action 027   incr i

action 0271  if $i gt 9

action 0272   set i 0

action 0273   incr j

action 0274 end

action 028   cli command "action 0$j$i cli command $q power inline auto$q"

action 029   incr i

action 0291  if $i gt 9

action 0292   set i 0

action 0293   incr j

action 0294 end

action 030   cli command "action 0$j$i syslog msg $q Interface $intf was re-enabled after a timer-triggered shutdown$q"

action 031   incr i

action 0311  if $i gt 9

action 0312   set i 0

action 0313   incr j

action 0314 end

action 032  end

action 033 end