cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
41726
Views
25
Helpful
87
Comments
Joe Clarke
Cisco Employee
Cisco Employee

In preparing for CiscoLive! in San Diego, I am provisioning our access layer 3560-E switches.  Since things have a tendency to change a lot at an event like CiscoLive! I thought it would be best to make sure our port descriptions are always up-to-date when it comes to reflecting what devices are connected.  To help me do that, I wrote up this small EEM applet policy.  It will update the port's description based on the CDP neighbor learned on that port.  This policy requires EEM 3.2, so you're looking at 12.2(55)SE or higher for the 3560s.  It will also work on 3750s and ISR G2 routers running 15.x code.

event manager applet update-port-description

event neighbor-discovery interface regexp GigabitEthernet.* cdp add

action 1.0 cli command "enable"

action 2.0 cli command "config t"

action 3.0 cli command "interface $_nd_local_intf_name"

action 4.0 cli command "description $_nd_cdp_entry_name:$_nd_port_id"

The result of this will be a description like the following on switch ports:

description SDCC_IDF_1.11:TenGigabitEthernet0/1
Comments
dennis_range
Level 1
Level 1

Forgive me for being daft but what if the Capability is Host? It seems to be interfering with the variable $host. action 4.4  cli command "description $host:$int" is what is in the script.

 

Jul 23 14:55:29.548 EDT: %HA_EM-3-FMPD_UNKNOWN_ENV: fh_parse_var: could not find environment variable: host
Jul 23 14:55:29.683 EDT: %HA_EM-3-FMPD_UNKNOWN_ENV: fh_parse_var: could not find environment variable: host
Jul 23 14:55:29.683 EDT: %HA_EM-3-FMPD_ERROR: Error executing applet auto-update-port-description statement 4.4

 

Tommy Vindvik
Level 1
Level 1

Dennis,

 

action 1.1  regexp "(Switch|Router|AIR)" "$_nd_cdp_capabilities_string"

would ensure that only interfaces with capabillities Switch|Router|AIR are triggered upon.

Anyhow, the CDP capabillity is actually stored in the (built in) variable $_nd_cdp_capabilities_string

 

I think you might be trying this script on a switch with no domain name set? I suspect that in some cases, the trimming of domain name below could cause a empty variable $host.

 

action 2.0  comment "Trim domain name"

action 2.1  regexp "^([^\.]+)\." "$_nd_cdp_entry_name" match host

 

Regards

Tommy V

c.baugh
Level 1
Level 1

Hello.  I have a question.

I configured my switch with the actions listed above. I plugged in an access point and the port description was populated as expected.  I then moved the access point to another port and it worked again.

 

However, now I have two ports with the same description, but the WAP is not plugged into one of the ports.  How would I get the port to reset or clear the description if the port is down/down, or populate the description with the mac address of the currently connected device (if it does not do CDP) ???  Just clearing the CDP table does not help. 

Your help is greatly appreciated. //Craig

Joe Clarke
Cisco Employee
Cisco Employee

At CiscoLive, I use a complimentary applet to default the port.  However, the initial idea of this was to be able to find missing APs.  If the port was up, then the description was valid.  If down, that was the previous spot of the AP.  If you want to add the compliment, have a look at:

 

event manager applet reset-port authorization bypass
 event syslog pattern "LINK-3-UPDOWN.*Interface GigabitEthernet.*changed state to down"
 action 001  regexp "Interface ([^,]+)" $_syslog_msg match intf
 action 002  cli command "enable"
 action 003  cli command "show int $intf | inc Description:"
 action 004  regexp "STATIC:" $_cli_result
 action 005  if $_regexp_result eq 1
 action 006   exit 0
 action 007  end
 action 008  cli command "config t"
 action 009  cli command "default interface $intf"
 action 010  cli command "interface $intf"
 action 011  cli command "switchport trunk encapsulation dot1q"
 action 012  cli command "switchport access vlan 2000"
 action 013  cli command "load-interval 30"
 action 014  cli command "srr-queue bandwidth share 1 30 35 5"
 action 015  cli command "priority-queue out"
 action 016  cli command "udld port aggressive"
 action 017  cli command "mls qos trust dscp"
 action 020  cli command "spanning-tree link-type point-to-point"
 action 021  cli command "end"

 

packettracer86
Level 1
Level 1

Hi

i am trying to configure this script on a Cisco C6880-X-LE running

Cisco IOS Software, c6880x Software (c6880x-IPSERVICESK9_NPE-M), Version 15.1(2)SY5, RELEASE SOFTWARE (fc7)


but i can't find the neighbor-discovery event! Is this softwareversion not supported or is it just hidden?

This commands are supported:

 

device_name(config-applet)#event ?
  application        Application specific event
  cli                CLI event
  config             Configuration policy event
  counter            Counter event
  env                Environmental event
  gold               GOLD event
  identity           Identity event
  interface          Interface event
  ioswdsysmon        IOS WDSysMon event
  ipsla              IPSLA Event
  mat                MAC address table event
  nf                 NF Event
  none               Manually run policy event
  oir                OIR event
  rf                 Redundancy Facility event
  routing            Routing event
  rpc                Remote Procedure Call event
  snmp               SNMP event
  snmp-notification  SNMP Notification Event
  snmp-object        SNMP object event
  syslog             Syslog event
  tag                event tag identifier
  timer              Timer event
  track              Tracking object event

Greetings

Joe Clarke
Cisco Employee
Cisco Employee

Seems like a bug to me.  While I haven't played with the 6880-X platform yet, I can't see why the ND event detector would not be included here.  You might want to open a TAC case to have them investigate.

packettracer86
Level 1
Level 1

Okay I will open a TAC Case.

 

Do you have some kind of "workaround" like a script which does the same but i have to start it by my own?

 

Greetings

Joe Clarke
Cisco Employee
Cisco Employee

I have recently expanded my automation approach to include reconfiguration based both new devices as well as periodic sweeps.  The following is the solution (and description of the solution) we use at the IETF network (with some addresses changed).

The Access and IDF layer switches all contain the following Embedded Event Manager (EEM) configuration. This configuration is defined to automatically detect devices connecting to ports; document those devices via port descriptions; and in the case of a new connection, configure the ports for the device in question. When the device disconnects (i.e., the port goes down), the port is reset to a default configuration and the port description is updated accordingly.

event manager applet detect-ap authorization bypass
 event tag nd neighbor-discovery interface regexp ^GigabitEthernet0 cdp add maxrun 45
 event tag timer timer watchdog time 60
 trigger
  correlate event nd or event timer
 action 001 cli command "enable"
 action 002 set intfs ""
 action 003 if $_event_type_string eq "timer watchdog"
 action 004  cli command "show int status | inc connected"
 action 005  set cres $_cli_result
 action 006  foreach line "$cres" "\n"
 action 007   regexp "^([^[:space:]]+)[[:space:]]" "$line" match intf
 action 008   if $_regexp_result eq "1"
 action 009    cli command "show lldp neighbor $intf detail"
 action 010    set lcres $_cli_result
 action 011    set port_id ""
 action 012    set sys_name "-"
 action 013    set plat "UNKNOWN"
 action 014    regexp "Port id: ([^[:space:]]+)" $lcres match port_id
 action 015    regexp "System Name: ([^[:space:]]+)" $lcres match sys_name
 action 016    regexp "K9W7-" $lcres
 action 017    if $_regexp_result eq 1
 action 018     set plat "AP"
 action 019    else
 action 020     regexp "K9W8-" $lcres
 action 021     if $_regexp_result eq 1
 action 022      set plat "LWAP"
 action 023     else
 action 024      regexp "C3560E Software|C3560C Software|Catalyst 4500 L3 Switch Software" $lcres
 action 025      if $_regexp_result eq 1
 action 026       set plat "SWITCH"
 action 027      else
 action 028       regexp "IETF_Probe:([^[:space:]]+)" $lcres match hn
 action 029       if $_regexp_result eq "1"
 action 030        set plat "PROBE"
 action 031        set sys_name $hn
 action 032       else
 action 033        set plat "DEVICE"
 action 034       end
 action 035      end
 action 036     end
 action 037    end
 action 038    append intfs " $intf~$port_id~$sys_name~$plat"
 action 039   end
 action 040  end
 action 041 else
 action 042  regexp "K9W7-" "$_nd_cdp_version"
 action 043  set plat "UNKNOWN"
 action 044  if $_regexp_result eq 1
 action 045   set plat "AP"
 action 046  else
 action 047   regexp "K9W8-" "$_nd_cdp_version"
 action 048   if $_regexp_result eq "1"
 action 049    set plat "LWAP"
 action 050   else
 action 051    regexp "cisco (WS-C3560CG-8PC-S|WS-C3560X)" "$_nd_cdp_platform"
 action 052    if $_regexp_result eq "1"
 action 053     set plat "SWITCH"
 action 054    end
 action 055   end
 action 056  end
 action 057  set intfs "$_nd_local_intf_name~$_nd_port_id~$_nd_cdp_entry_name~$plat"
 action 058 end
 action 059 string trim $intfs
 action 060 cli command "config t"
 action 061 set config_change "0"
 action 062 foreach intf $_string_result
 action 063  regexp "^([^~]+)~([^~]*)~(.*)" "$intf" match lif pid rest
 action 064  regexp "^([^~]*)~([^~]*)" "$rest" match sysn plat
 action 065  cli command "do show interface $lif | inc Description:"
 action 066  set cdescr ""
 action 067  regexp "Description: ([^\n]+)" $_cli_result match cdescr
 action 068  string trim $cdescr
 action 069  set cdescr $_string_result
 action 070  if $plat eq "AP"
 action 071   syslog priority notifications msg "$sysn"
 action 072   cli command "interface $lif"
 action 073   if $cdescr ne "AP : $sysn:$pid"
 action 074    cli command "description AP : $sysn:$pid"
 action 075    set config_change "1"
 action 076   end
 action 077   if $_event_type_string ne "timer watchdog"
 action 078    cli command "switchport mode trunk"
 action 079    cli command "switchport trunk allowed vlan 1,2152,2160,2168,1998,1999,2176"
 action 080    cli command "spanning-tree portfast trunk"
 action 081    set config_change "1"
 action 082   end
 action 083  else
 action 084   if $plat eq "LWAP"
 action 085    cli command "int $lif"
 action 086    if $cdescr ne "AP : $sysn:$pid"
 action 087     cli command "description AP : $sysn:$pid"
 action 088     set config_change "1"
 action 089    end
 action 090    if $_event_type_string ne "timer watchdog"
 action 091     cli command "switchport mode trunk"
 action 092     cli command "switchport trunk allowed vlan 1"
 action 093     cli command "spanning-tree portfast trunk"
 action 094     set config_change "1"
 action 095    end
 action 096   end
 action 097  end
 action 098  if $plat eq "SWITCH"
 action 099   cli command "interface $lif"
 action 100   if $cdescr ne "Core : $sysn:$pid"
 action 101    cli command "description Core : $sysn:$pid"
 action 112    set config_change "1"
 action 113   end
 action 114   if $_event_type_string ne "timer watchdog"
 action 115    wait 1
 action 116    cli command "do ping 10.1.1.1"
 action 117    cli command "do show arp 10.1.1.1"
 action 118    regexp "([0-9a-f\.]+)[[:space:]]+ARPA" "$_cli_result" match mac
 action 119    cli command "do show mac address-table address $mac"
 action 120    regexp "DYNAMIC[[:space:]]+([A-Za-z0-9/]+)" "$_cli_result" match port
 action 121    if $_nd_short_local_intf_name eq "$port"
 action 122     cli command "ip dhcp snooping trust"
 action 123     cli command "no ipv6 nd raguard"
 action 124     cli command "no ipv6 dhcp guard"
 action 125     cli command "ipv6 nd raguard attach-policy uplink-policy"
 action 126    else
 action 127     cli command "no ip dhcp snooping trust"
 action 128     cli command "ipv6 nd raguard"
 action 129     cli command "ipv6 dhcp guard"
 action 130     cli command "no ipv6 nd raguard attach-policy uplink-policy"
 action 131    end
 action 132    set config_change "1"
 action 133   end
 action 134  else
 action 135   if $plat eq "PROBE"
 action 136    if $cdescr ne "Probe : $sysn:$pid"
 action 137     cli command "interface $lif"
 action 138     cli command "description Probe : $sysn:$pid"
 action 139     set config_change "1"
 action 140    end
 action 141   else
 action 142    if $plat eq "DEVICE"
 action 143     if $sysn ne "-"
 action 144      if $cdescr ne "Generic : $sysn:$pid"
 action 145       cli command "interface $lif"
 action 146       cli command "description Generic : $sysn:$pid"
 action 147       set config_change "1"
 action 148      end
 action 149     end
 action 150    end
 action 151   end
 action 152  end
 action 153 end
 action 154 cli command "end"
 action 155 if $config_change eq "1"
 action 156  cli command "write mem"
 action 157 end
!
event manager applet reset-port authorization bypass
 event syslog pattern "LINK-3-UPDOWN.*Interface .*GigabitEthernet0.*changed state to down"
 action 001 regexp "Interface ([^,]+)" "$_syslog_msg" match intf
 action 002 cli command "enable"
 action 003 cli command "show int $intf | inc Description:"
 action 004 regexp "Description: (Was )*([^\n\[]+)" $_cli_result match ignore descr
 action 005 set idescr "default"
 action 006 if $_regexp_result eq 1
 action 007  string trim $descr
 action 008  if $_string_result ne "default"
 action 009   set idescr "Was $_string_result [last seen: $_event_pub_time]"
 action 010  end
 action 011 end
 action 012 cli command "config t"
 action 013 cli command "interface $intf"
 action 014 cli command "description $idescr"
 action 015 cli command "no ip dhcp snooping trust"
 action 016 cli command "ipv6 nd raguard"
 action 017 cli command "ipv6 dhcp guard"
 action 018 cli command "no ipv6 nd raguard attach-policy uplink-policy"
 action 019 cli command "switchport trunk allowed vlan all"
 action 020 cli command "end"
 action 021 cli command "write mem"

This configuration consists of two EEM applet policies. The first few lines of the first policy define the applet that detects new devices.

1 event manager applet detect-ap authorization bypass
2  event tag nd neighbor-discovery interface regexp ^GigabitEthernet0 cdp add maxrun 45
3  event tag timer timer watchdog time 60
4  trigger
5   correlate event nd or event timer

Line 1 defines an applet called "detect-ap" and indicates that it should bypass AAA command authorization (if configured). We do not currently use AAA authz at the IETF.

This applet will react to two events. Line 2 defines the first event: react to the addition of a new CDP neighbor. If a new neighbor is learned on a port that matches the regular expression of ^GigabitEthernet0 (note: this is for 3560X switches; 3560CG will use "GigabitEthernet0/[1-8]$"), then the applet will trigger. The reason for these limiting regular expressions is to prevent detection from happening on typical uplink ports. Those are statically configured and their descriptions will be handled via the second event (as they don't need reconfiguration). The "maxrun 45" parameter says that this applet policy is allowed to run for 45 seconds and no more. The default maximum runtime is 20 seconds, but because of the logic and commands within the applet, it could run longer than 20. If the policy is still running after 45 seconds, it is forcibly terminated.

Line 3 defines the second event. This event will trigger the policy to run every 60 seconds.

Line 5 says that the policy will run if either the CDP neighbor event occurs or the timer pops.

 action 001 cli command "enable"
 action 002 set intfs ""
 action 003 if $_event_type_string eq "timer watchdog"
 action 004  cli command "show int status | inc connected"
 action 005  set cres $_cli_result
 action 006  foreach line "$cres" "\n"
 action 007   regexp "^([^[:space:]]+)[[:space:]]" "$line" match intf
 action 008   if $_regexp_result eq "1"
 action 009    cli command "show lldp neighbor $intf detail"
 action 010    set lcres $_cli_result
 action 011    set port_id ""
 action 012    set sys_name "-"
 action 013    set plat "UNKNOWN"
 action 014    regexp "Port id: ([^[:space:]]+)" $lcres match port_id
 action 015    regexp "System Name: ([^[:space:]]+)" $lcres match sys_name
 action 016    regexp "K9W7-" $lcres
 action 017    if $_regexp_result eq 1
 action 018     set plat "AP"
 action 019    else
 action 020     regexp "K9W8-" $lcres
 action 021     if $_regexp_result eq 1
 action 022      set plat "LWAP"
 action 023     else
 action 024      regexp "C3560E Software|C3560C Software|Catalyst 4500 L3 Switch Software" $lcres
 action 025      if $_regexp_result eq 1
 action 026       set plat "SWITCH"
 action 027      else
 action 028       regexp "IETF_Probe:([^[:space:]]+)" $lcres match hn
 action 029       if $_regexp_result eq "1"
 action 030        set plat "PROBE"
 action 031        set sys_name $hn
 action 032       else
 action 033        set plat "DEVICE"
 action 034       end
 action 035      end
 action 036     end
 action 037    end
 action 038    append intfs " $intf~$port_id~$sys_name~$plat"
 action 039   end
 action 040  end

This next set of code is executed only if the timer pops. It will not execute when the new CDP neighbor event occurs. This code will run through the output of show int status | inc connected then checking each connected port for its LLDP neighbor. Each port with a neighbor is added to the intfs string with the values of the local port name, the remote port name, the remote system name, and the remote platform type. We use '~' to delimit these values as ';' is special to Rancid, and other delimiters might actually appear in interface names. The following device types are called out specifically:

  • AP (autonomous access-point)
  • LWAP (lightweight access-point)
  • SWITCH (inter-switch infrastructure link)
  • PROBE (Raspberry Pi probe)
  • DEVICE (any other generic device that uses LLDP)
 action 042  regexp "K9W7-" "$_nd_cdp_version"
 action 043  set plat "UNKNOWN"
 action 044  if $_regexp_result eq 1
 action 045   set plat "AP"
 action 046  else
 action 047   regexp "K9W8-" "$_nd_cdp_version"
 action 048   if $_regexp_result eq "1"
 action 049    set plat "LWAP"
 action 050   else
 action 051    regexp "cisco (WS-C3560CG-8PC-S|WS-C3560X)" "$_nd_cdp_platform"
 action 052    if $_regexp_result eq "1"
 action 053     set plat "SWITCH"
 action 054    end
 action 055   end
 action 056  end
 action 057  set intfs "$_nd_local_intf_name~$_nd_port_id~$_nd_cdp_entry_name~$plat"
 action 058 end

This next block parses the built-in variables for the new CDP neighbor event. This code is only executed when the new CDP neighbor event occurs. It is designed to detect an AP, LWAP or SWITCH. Note how it doesn't detect the Catalyst 4500X. This is because that switch (the core) will only show up on uplink ports (e.g., Ten1/1) which are not looked at for new CDP neighbors.

 action 059 string trim $intfs
 action 060 cli command "config t"
 action 061 set config_change "0"
 action 062 foreach intf $_string_result
 action 063  regexp "^([^~]+)~([^~]*)~(.*)" "$intf" match lif pid rest
 action 064  regexp "^([^~]*)~([^~]*)" "$rest" match sysn plat
 action 065  cli command "do show interface $lif | inc Description:"
 action 066  set cdescr ""
 action 067  regexp "Description: ([^\n]+)" $_cli_result match cdescr
 action 068  string trim $cdescr
 action 069  set cdescr $_string_result
 action 070  if $plat eq "AP"
 action 071   syslog priority notifications msg "$sysn"
 action 072   cli command "interface $lif"
 action 073   if $cdescr ne "AP : $sysn:$pid"
 action 074    cli command "description AP : $sysn:$pid"
 action 075    set config_change "1"
 action 076   end
 action 077   if $_event_type_string ne "timer watchdog"
 action 078    cli command "switchport mode trunk"
 action 079    cli command "switchport trunk allowed vlan 1,2152,2160,2168,1998,1999,2176"
 action 080    cli command "spanning-tree portfast trunk"
 action 081    set config_change "1"
 action 082   end
 action 083  else
 action 084   if $plat eq "LWAP"
 action 085    cli command "int $lif"
 action 086    if $cdescr ne "AP : $sysn:$pid"
 action 087     cli command "description AP : $sysn:$pid"
 action 088     set config_change "1"
 action 089    end
 action 090    if $_event_type_string ne "timer watchdog"
 action 091     cli command "switchport mode trunk"
 action 092     cli command "switchport trunk allowed vlan 1"
 action 093     cli command "spanning-tree portfast trunk"
 action 094     set config_change "1"
 action 095    end
 action 096   end
 action 097  end
 action 098  if $plat eq "SWITCH"
 action 099   cli command "interface $lif"
 action 100   if $cdescr ne "Core : $sysn:$pid"
 action 101    cli command "description Core : $sysn:$pid"
 action 112    set config_change "1"
 action 113   end
 action 114   if $_event_type_string ne "timer watchdog"
 action 115    wait 1
 action 116    cli command "do ping 10.1.1.1"
 action 117    cli command "do show arp 10.1.1.1"
 action 118    regexp "([0-9a-f\.]+)[[:space:]]+ARPA" "$_cli_result" match mac
 action 119    cli command "do show mac address-table address $mac"
 action 120    regexp "DYNAMIC[[:space:]]+([A-Za-z0-9/]+)" "$_cli_result" match port
 action 121    if $_nd_short_local_intf_name eq "$port"
 action 122     cli command "ip dhcp snooping trust"
 action 123     cli command "no ipv6 nd raguard"
 action 124     cli command "no ipv6 dhcp guard"
 action 125     cli command "ipv6 nd raguard attach-policy uplink-policy"
 action 126    else
 action 127     cli command "no ip dhcp snooping trust"
 action 128     cli command "ipv6 nd raguard"
 action 129     cli command "ipv6 dhcp guard"
 action 130     cli command "no ipv6 nd raguard attach-policy uplink-policy"
 action 131    end
 action 132    set config_change "1"
 action 133   end
 action 134  else
 action 135   if $plat eq "PROBE"
 action 136    if $cdescr ne "Probe : $sysn:$pid"
 action 137     cli command "interface $lif"
 action 138     cli command "description Probe : $sysn:$pid"
 action 139     set config_change "1"
 action 140    end
 action 141   else
 action 142    if $plat eq "DEVICE"
 action 143     if $sysn ne "-"
 action 144      if $cdescr ne "Generic : $sysn:$pid"
 action 145       cli command "interface $lif"
 action 146       cli command "description Generic : $sysn:$pid"
 action 147       set config_change "1"
 action 148      end
 action 149     end
 action 150    end
 action 151   end
 action 152  end
 action 153 end
 action 154 cli command "end"

This next [large] block of code walks through each interface listed in the intfs string and checks the resulting platform. Actions 063 and 064 might looks weird. The regexp action can only accept a total of four match variables (and the first is the whole match itself). So, in order to match four parameters, the pattern needs to be broken into two pieces. The lines that follow the regexp actions will apply the necessary configuration changes to the given port (if needed). If the event is a timer-triggered event, only the port description will ever be changed. If a new CDP neighbor triggered the event, then additional configuration will be applied.

For an autonomous AP, the port will be configured to be a trunk carrying the typical user VLANs. For a lightweight AP, the port will be reconfigured to be a trunk only carrying VLAN 1 (the management VLAN). For an inter-switch link, the port will be reconfigured to be a trunk. Then things can get interesting. The switch will ping the default gateway on VLAN 1. It will then see if the ARP that is learned for that IP is through the port for which the new CDP neighbor event occurred. If it is, then this is configured to be an uplink port and EEM will mark the port as such by adding the RA guard policy and trusting the port for DHCP snooping. If the ARP is learned through a different port, then the port is protected as a downlink trunk port.

For probes or other generic devices, the port is left as it currently is with only the description being changed. For all ports regardless of the event that triggered the policy, the port's description will be updated to reflect the device that is hanging off of it.

 action 155 if $config_change eq "1"
 action 156  cli command "write mem"
 action 157 end

This last little bit will trigger a write mem (copy the running config to startup) if the configuration was actually changed. By checking this we can save the flash from excessive writes.

So, why use CDP instead of LLDP for the new neighbor event? That's how it started out, and for the config changes we need to do, the devices already support CDP. Therefore, I didn't see a need to change at this point.

The second applet handles the case when the port goes down. It's much simpler because all ports should be reset to a more common config.

1 event manager applet reset-port authorization bypass
2  event syslog pattern "LINK-3-UPDOWN.*Interface .*GigabitEthernet0.*changed state to down"

Line 1 defines the applet itself, and line 2 says that the event that will trigger this applet is a syslog event that checks if a port went down that matches the regular expression "GigabitEthernet0" (note: this is for 3560X switches; for 3560CG switches the pattern is "GigabitEthernet0/[1-8],"). Just like the first applet, we ignore typical (statically pre-configured) uplink ports (e.g., Ten1/1 on 3560X and Gi0/10 on 3560CG).

 action 001 regexp "Interface ([^,]+)" "$_syslog_msg" match intf
 action 002 cli command "enable"
 action 003 cli command "show int $intf | inc Description:"
 action 004 regexp "Description: (Was )*([^\n\[]+)" $_cli_result match ignore descr
 action 005 set idescr "default"
 action 006 if $_regexp_result eq 1
 action 007  string trim $descr
 action 008  if $_string_result ne "default"
 action 009   set idescr "Was $_string_result [last seen: $_event_pub_time]"
 action 010  end
 action 011 end

The biggest piece of logic in this applet is here. The applet extracts the current description of the port and creates a new description in the format of, "Was ORIGINAL_DESCRIPTION [last seen: TIME]". The TIME here is the time of the event. This way, we know what was connected to the port and when it was last seen.

 action 012 cli command "config t"
 action 013 cli command "interface $intf"
 action 014 cli command "description $idescr"
 action 015 cli command "no ip dhcp snooping trust"
 action 016 cli command "ipv6 nd raguard"
 action 017 cli command "ipv6 dhcp guard"
 action 018 cli command "no ipv6 nd raguard attach-policy uplink-policy"
 action 019 cli command "switchport trunk allowed vlan all"
 action 020 cli command "end"
 action 021 cli command "write mem"

The config applied is the default config for the port, waiting for a new device (or end user host) to plugin.

last year (i think in november) i open a tac case.

the response was: wait for the new firmware. i still wait

greetz

flo

arno.streuli
Level 1
Level 1

Hello,

Great script!

But I have a problem with the Trim domain name part.

Some of my host doesn't have the domaine name on it.

and in this case the $host is empty.

I try to change for the following regex (who work on a simulator on internet): ^([^\.]*)\.

for a name like wa-cht-03 it's empty

but it doesn't work at all on Cisco !?

What is the flavor of the regex ?

And how can I trim host id to take all until the first .

thanks,

arno

Joe Clarke
Cisco Employee
Cisco Employee

Use the regexp:

"^([^\.]+)"

arno.streuli
Level 1
Level 1

Thanks it works well.

I have another problem with this line:

action 4.23 regexp "Description: ([a-zA-Z0-9:/\-]*)([a-zA-Z0-9:/\-\ ]*)" "$_cli_result" olddesc olddesc_sub1

My description on the port end like this:

SE-UST-221 / WS-C3560V2-24PS / Gi0/2

and on the log I got this:

Aug 16 11:16:47.935: %HA_EM-6-LOG: auto-update-port-description: EEM script updated description on TenGigabitEthernet1/1/22 from Description: SE-UST-221 / WS to Description: SE-UST-221 / WS-C3560V2-24PS / Gi0/2 and saved config

On $olddesc I have:Description: SE-UST-221 / WS

and on $olddesc_sub1: SE-UST-221

so it's not stripping out Description: and not filling $olddesc_sub1 correctly

And the test (if an updated is needed) is based on $olddesc_sub1 but the logging information is based on $olddesc

why is that ?

Joe Clarke
Cisco Employee
Cisco Employee

You seem to be using Colin's policy as an example.  If you look at the big one I posted above, I use this to get the current description:

 action 067  regexp "Description: ([^\n]+)" $_cli_result match cdescr

Then the value you want is stored in the $descr variable.

Ken DeShong
Level 1
Level 1

I'm using the following script that was published earlier in this discussion and its working fine.  I want to trim the output but not being a script guy, I can't find where it does this.  I don't want the neighbor port to be written out (Gi0). Here is how it looks now:    SWITCH1-2:Gi0  

event manager applet auto-update-port-description authorization bypass
description "Auto-update port-description based on CDP neighbor info"
event neighbor-discovery interface regexp .*GigabitEthernet[0-9]/[0-9]+$ cdp add
action 0.0 comment "Event line regexp: Deside which interface to auto-update description on"
action 1.0 comment "Verify CDP neighbor to be Switch or Router"
action 2.0 comment "Trim domain name"
action 2.1 regexp "^([^\.]+)" "$_nd_cdp_entry_name" match host
action 3.0 comment "Convert long interface name to short"
action 3.1 string first "Ethernet" "$_nd_port_id"
action 3.2 if $_string_result eq "7"
action 3.21 string replace "$_nd_port_id" 0 14 "Gi"
action 3.3 elseif $_string_result eq 10
action 3.31 string replace "$_nd_port_id" 0 17 "Te"
action 3.4 elseif $_string_result eq 4
action 3.41 string replace "$_nd_port_id" 0 11 "Fa"
action 3.5 end
action 3.6 set int "$_string_result"
action 4.0 comment "Check old description if any, and do no change if same host:int"
action 4.1 cli command "enable"
action 4.11 cli command "config t"
action 4.2 cli command "do show interface $_nd_local_intf_name | incl Description:"
action 4.21 set olddesc "<none>"
action 4.22 set olddesc_sub1 "<none>"
action 4.23 regexp "Description: ([a-zA-Z0-9:/\-]*)([a-zA-Z0-9:/\-\ ]*)" "$_cli_result" olddesc olddesc_sub1
action 4.24 if $olddesc_sub1 eq "$host:$int"
action 4.25 syslog msg "EEM script did NOT change desciption on $_nd_local_intf_name, since remote host and interface is unchanged"
action 4.26 exit 10
action 4.27 end
action 4.3 cli command "interface $_nd_local_intf_name"
action 4.4 cli command "description $host:$int"
action 4.5 cli command "do write"
action 4.6 syslog msg "EEM script updated description on $_nd_local_intf_name from $olddesc to Description: $host:$int and saved config"
action 6.0 exit 1
!
end
clear cdp table
wr

Collin Clark
VIP Alumni
VIP Alumni

Ken-

Change line 4.24 to

action 4.4 cli command "description $host"

Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: