06-12-2024 09:02 AM - edited 10-18-2024 08:18 AM
This code is looking at neighbour discovery, learns remote name and remote interface and push it in the
description of the local interface
Note: the length of the remote interface name can be tuned by set len_intn [value]
::cisco::eem::event_register_neighbor_discovery interface Gig cdp add
namespace import ::cisco::eem::*
namespace import ::cisco::lib::*
##################################################################################
#
# Copyright (c) 2024 Alain Lanssiers <alanssie@cisco.com>
#
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
#Platform
#---------
# Tested on NCS (should work on any ios_xr platform)
# Purpose
# ========
# Grab CDP even and modify the description of the interface coming up
array set arr_einfo [event_reqinfo]
## Number of character of an interface needed, start counting from 0 (1 == 2 characters)
set len_intn 1
if [catch {cli_open} result] {
error $result $errorInfo
} else {
array set cli1 $result
}
if [catch {cli_exec $cli1(fd) "enable"} _cli_result] {
error $_cli_result $errorInfo
}
if [catch {cli_exec $cli1(fd) "config t"} _cli_result] {
error $_cli_result $errorInfo
}
if [catch {cli_exec $cli1(fd) "interface $arr_einfo(local_intf_name)"} _cli_result] {
error $_cli_result $errorInfo
}
if [catch {cli_exec $cli1(fd) "description *** [lindex [split $arr_einfo(cdp_entry_name) "."] 0] [string range $arr_einfo(port_id) 0 $len_intn] ***"} _cli_result] {
error $_cli_result $errorInfo
}
if [catch {cli_exec $cli1(fd) "commit"} _cli_result] {
error $_cli_result $errorInfo
}
if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
error $_cli_result $errorInfo
}
action_syslog msg "EEM script updated description on $arr_einfo(local_intf_name) and commit config"
catch {cli_close $cli1(fd) $cli1(tty_id)} result
::cisco::eem::event_register_neighbor_discovery interface Gig cdp add
namespace import ::cisco::eem::*
namespace import ::cisco::lib::*
##################################################################################
#
# Copyright (c) 2024 Alain Lanssiers <alanssie@cisco.com>
#
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
#Platform
#---------
# Tested on NCS (should work on any ios_r, ios_xe platform)
# Purpose
# ========
# Grab CDP even and modify the description of the interface coming up
# version 2024-0718 added possibility to rstrict length of aplha character but keep the x/y/z/.. after
array set arr_einfo [event_reqinfo]
## Number of character of an interface needed, start counting from 0 (1 == 2 characters)
set len_intn 1
regsub -all {[[:alpha:]]+} $arr_einfo(port_id) {} int_num
if [catch {cli_open} result] {
error $result $errorInfo
} else {
array set cli1 $result
}
if [catch {cli_exec $cli1(fd) "enable"} _cli_result] {
error $_cli_result $errorInfo
}
if [catch {cli_exec $cli1(fd) "config t"} _cli_result] {
error $_cli_result $errorInfo
}
if [catch {cli_exec $cli1(fd) "interface $arr_einfo(local_intf_name)"} _cli_result] {
error $_cli_result $errorInfo
}
if [catch {cli_exec $cli1(fd) "description *** [lindex [split $arr_einfo(cdp_entry_name) "."] 0] [string range $arr_einfo(port_id) 0 $len_intn]$int_num ***"} _cli_result] {
error $_cli_result $errorInfo
}
if [catch {cli_exec $cli1(fd) "commit"} _cli_result] {
error $_cli_result $errorInfo
}
if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
error $_cli_result $errorInfo
}
action_syslog msg "EEM script updated description on $arr_einfo(local_intf_name) and commit config"
catch {cli_close $cli1(fd) $cli1(tty_id)} result
::cisco::eem::event_register_neighbor_discovery interface Gig cdp add
namespace import ::cisco::eem::*
namespace import ::cisco::lib::*
##################################################################################
#
# Copyright (c) 2024 Alain Lanssiers <alanssie@cisco.com>
#
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
#Platform
#---------
# Tested on NCS (should work on any ios_r, ios_xe platform)
# Purpose
# ========
# Grab CDP even and modify the description of the interface coming up
# version 2024-0718 added possibility to rstrict length of aplha character but keep the x/y/z/.. after
# tested on ios-xr
# version 2024-1810 added wr for saving config on ios ios-xe
# tested on ios-xe
array set arr_einfo [event_reqinfo]
## Number of character of an interface needed, start counting from 0 (1 == 2 characters)
set len_intn 1
regsub -all {[[:alpha:]]+} $arr_einfo(port_id) {} int_num
if [catch {cli_open} result] {
error $result $errorInfo
} else {
array set cli1 $result
}
if [catch {cli_exec $cli1(fd) "enable"} _cli_result] {
error $_cli_result $errorInfo
}
if [catch {cli_exec $cli1(fd) "config t"} _cli_result] {
error $_cli_result $errorInfo
}
if [catch {cli_exec $cli1(fd) "interface $arr_einfo(local_intf_name)"} _cli_result] {
error $_cli_result $errorInfo
}
if [catch {cli_exec $cli1(fd) "description *** [lindex [split $arr_einfo(cdp_entry_name) "."] 0] [string range $arr_einfo(port_id) 0 $len_intn]$int_num ***"} _cli_result] {
error $_cli_result $errorInfo
}
if [catch {cli_exec $cli1(fd) "commit"} _cli_result] {
error $_cli_result $errorInfo
}
if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
error $_cli_result $errorInfo
}
if [catch {cli_exec $cli1(fd) "wr"} _cli_result] {
error $_cli_result $errorInfo
}
action_syslog msg "EEM script updated description on $arr_einfo(local_intf_name) and commit config"
catch {cli_close $cli1(fd) $cli1(tty_id)} result
Hi Alan,
on NCS, a IOSXR-Box, it works.
But on a IOSXE, for Example ASR903 or Cat9300, it does not work.
I execute the script in the tclshell with:
source bootflash:EEM-Int-Desc-CDP-IOS-XR.tcl
I´m getting the following error:
invalid command name "::cisco::eem::event_register_neighbor_discovery" ^
% Invalid input detected at '^' marker.
How can I solve this?
@Volker Mueller, this is what we use on our switches:
event manager applet update-port
event neighbor-discovery interface regexp GigabitEthernet.* cdp add
action 100 regexp "(Switch|Trans-Bridge|Router)" "$_nd_cdp_capabilities_string"
action 110 if $_regexp_result eq "1"
action 200 cli command "enable"
action 210 cli command "config t"
action 220 cli command "interface $_nd_local_intf_name"
action 230 regexp "^([^\.]+)" "$_nd_cdp_entry_name" match host
action 240 cli command "description $host"
action 500 end
(This EEM was written by @Joe Clarke.)
The EEM looks at CDP neighbors and filters the "Capabilities" for "Routers", "Switches" and "Trans-Bridge" (aka wireless access points) and updates the interface names with the hostname.
Hi Volker
> > invalid command name "::cisco::eem::event_register_neighbor_discovery" ^
> > % Invalid input detected at '^' marker.
> >How can I solve this?
This registry also exist in ios-xe, so I do not think the script should complain, looking at the ^ after the registration line, I think likely something introduced a hidden character and interpret this as a command.
Note the TCL was done because there is no applet in the ios-xr, I will verify this script later on ios-xe and let you know
Alain
Hi Volker
I tested locally and it ran fine, I think the copy and paste into a file picked up some garbage
so what you need to do is choose your file editor
copy first :
::cisco::eem::event_register_neighbor_discovery interface Gig cdp add
namespace import ::cisco::eem::*
namespace import ::cisco::lib::*
press return after copying all the characters and only character of one line, repeat for each line above
after that copy the rest of the script in your file
save the file
Unfortunately I cannot attach the original file here but I believe the above procedure should help
BTW there will be a version 2024-1810 that will add the "wr" for ios-xe
but since it needs to be published as I did an edit on the first, it might take sometime
Alain
Hi Alain,
first, thank you for your time.
I´ve done as you said.
First with "my" file. Second with the version 2024-1810 on this post.
But I´m getting the same error.
After that I´ve also convert the file with dos2unix before I tranfer it to the device, but with no luck.
I´m getting always this error:
R01(tcl)#source bootflash:EEM-Int-Desc-CDP-IOS-XE.tcl
invalid command name "::cisco::eem::event_register_neighbor_discovery" ^
% Invalid input detected at '^' marker.
R01(tcl)#
So, on which platform do you tested it?
And how do you tested?
I´ve testet it on ASR903 Version 17.12.4 and on Cat9300L Version 17.3.4
Volker
Hi Volker
to register the tcl script source does not really work
example
=======
net1(tcl)#source unix:description_cdp.tcl
invalid command name "::cisco::eem::event_register_neighbor_discovery"
::cisco::eem::event_register_neighbor_discovery interface Ethernet cdp add
^
% Invalid input detected at '^' marker.
But it works fine is you register via the cli
example
net1#conf t
Enter configuration commands, one per line. End with CNTL/Z.
net1(config)#event manager policy description_cdp.tcl authorization bypass
net1(config)#^Z
net1#sh
*Oct 21 06:30:10.784: %SYS-5-CONFIG_I: Configured from console by ww on console
net1#sho event manager policy registered
No. Class Type Event Type Trap Time Registered Name
1 script user neighbor-discovery Off Mon Oct 21 00:30:08 2024 description_cdp.tcl
interface {Ethernet} cdp add
nice 0 queue-priority normal maxrun 20.000 scheduler rp_primary Secu none
Alain
Hi Alain,
sorry for my stupid questions, but I´m new in case of tcl and eem.
After registering the script via CLI, the script will be executed.
But the Interface description is not there.
R01#
014657: Oct 21 09:21:53.290 CEST: %HA_EM-6-LOG: EEM-Int-Desc-CDP-IOS-XE.tcl: EEM script updated description on GigabitEthernet0/4/2 and commit config
R01#sh run int GigabitEthernet0/4/2
Building configuration...
Current configuration : 578 bytes
!
interface GigabitEthernet0/4/2
dampening
bandwidth 1000000
ip address 10.x.x.x 255.255.255.252
Thats my CLI configuration:
event manager directory user policy "bootflash:/SCRIPTS"
event manager applet CDP-VIA-TCL authorization bypass
event none
action 1.0 cli command "EEM-Int-Desc-CDP-IOS-XE.tcl"
event manager policy EEM-Int-Desc-CDP-IOS-XE.tcl
Volker
@Volker Mueller an EEM script needs an event configured to trigger it to run.
As you have configured it now (event none) you could run it manually from CLI but if you want it to run automatically you must configure an event.
Take a look at the example Leo provided above for EEM on IOS-XE, then you don't need to use TCL at all. As Alain says the TCL was only provided for IOS-XR because the applet capability did not exist.
Hi Rich,
I have a network with IOS-XE and IOS-XR devices and I want to take the same procedure to apply the interface description.
In Leos example I only get the Device without the port.
And as I said, the tcl-script from Alain on the IOS-XE box is executet, with event none or with event neighbor-discovery interface regexp .* cdp add, but without description.
Volker
Hi Volker
there needs to be a cdp event in the ios-xe to configure the interface
if you have one interface with cdp neighbor, shut on the remote and wait until cdp neighbor disappear locally
then unshut on the remote
Potentially, debug event manager cli_library to see what the script is effectively writing in the config
Alain
Hi Alain,
the script is OK and works on IOSXE.
The problem was "Command authorization failed."
I thought, if I configure "authorization bypass", the problem was solved. But the problem still exists.
If I configure a AAA-User for EEM, the authorization failed is gone.
Do you know, why "authorization bypass" does not work in action between EEM and TCL?
Or how can I achieve, that the script will be executed without authorization, like "normal" EEM-Applets?
Volker
Hi Volker
> I have a network with IOS-XE and IOS-XR devices and I want to take the same procedure
But they are different operating systems and sometimes you can't use the exact same solution on both.
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: