Header Only - DO NOT REMOVE - Extreme Networks

Netsight TCL Scripting - Modifying Switch Banners


Userlevel 2
I want to be able to make modifications to the after-login banner on my 4,000 switches. I would like to use a TCL script from within Netsight to do it.

I have the entire script working except that I found that the "configure banner" command is uniquely problematic. The command needs to be issued and then the text of the banner typed out in a terminal and finished with a blank line to denote the end of the banner.

The problem within a script is that when I issue the "configure banner after-login" command, there is no response of any kind from the switch. I want to be able to send the text of the banner, and I thought I could do it with:

CLI $bannerText

but that just times out.

In other situations where further input is required the idiom is typically:

SAVE config secondary
regexp {.*overwrite it?.*} ${CLI.OUT} foundit
IF ([info exists foundit]) THEN
CLI yes
ENDIF [/code]
So you issue a command and match on the CLI.OUT contents.

In this case it seems like the script just hangs on the banner command and times out.

JUST WONDERING IF ANYBODY HAS FOUND A WAY AROUND THIS.
I have a TCL script outside of Netsight that can do this but it's much better to allow all my colleagues to run the script from inside our management system.

6 replies

Userlevel 7
Hi,

I haven't found a way about that command, and asking around, still haven't found someone with a solution neither. Not sure this is achievable. I can think of a dirty trick, but that's not great: the command will be taken in account, and the timeout will work as that blank line so... just do a script for the banner with a very short timeout.

Ugly, yes, just as I said 🙂
Userlevel 7
Grosjean, Stephane wrote:

Hi,

I haven't found a way about that command, and asking around, still haven't found someone with a solution neither. Not sure this is achievable. I can think of a dirty trick, but that's not great: the command will be taken in account, and the timeout will work as that blank line so... just do a script for the banner with a very short timeout.

Ugly, yes, just as I said 🙂

oh, and btw, starting with EMC 8.0.4 you have access to Python scripting too. I tested the dirty trick on an EXOS VM with Python.
Userlevel 2
Grosjean, Stephane wrote:

Hi,

I haven't found a way about that command, and asking around, still haven't found someone with a solution neither. Not sure this is achievable. I can think of a dirty trick, but that's not great: the command will be taken in account, and the timeout will work as that blank line so... just do a script for the banner with a very short timeout.

Ugly, yes, just as I said 🙂

Thanks Stephane. I haven't seen much documentation on the Python scripting but I certainly want to give it a go - want to learn Python anyway ( I know Perl and I learned TCL for the Extreme environment )

I found that even when my script timed out, I wasn't completing the banner command.
I couldn't find a method of sending the command plus the banner text at the switch. Assuming I had a string with the command and banner text in it, how would I use it to issue the command to the switch?

I tried:

configure banner after-login $bannerTextWithLeadingNewline

but that didn't seem to work ( maybe I missed the trailing blank line and newline ? )

There seems to be a command like:

CLI $string

but I can't find documentation beyond its use in some sample scripts.

Thanks for your help with this BTW.

Ed.
Userlevel 7
Grosjean, Stephane wrote:

Hi,

I haven't found a way about that command, and asking around, still haven't found someone with a solution neither. Not sure this is achievable. I can think of a dirty trick, but that's not great: the command will be taken in account, and the timeout will work as that blank line so... just do a script for the banner with a very short timeout.

Ugly, yes, just as I said 🙂

ah, documentation... Python scripting is very new with 8.0.4.

quickly:

- emc_vars : this is a dictionary with all the regular TCL variables

ex: myVar = emc_vars["deviceIP"]

to trigger port selection from the user:

ports = emc_vars["port"]

- emc_cli : to send command and have the output.

cli_results = emc_cli.send("show vlan")
cli_output = cli_results.getOutput()

1st line is the command itself
then the output
last line is the prompt

you may want to get rid of that:

'\n'.join(cli_output.splitlines()[1:-1])

---

for your need, I simply tested on an EXOS VM (22.2) a simple script like that:

emc_cli.send("config banner after-login")
emc_cli.send("this is a banner")

still a dirty trick, but if it works and helps...
Userlevel 2
Embarrassingly I found that I had made a mistake and hadn't put a double newline at the end of my banner text:

# Join list into one big string
set var myBanner [ join $lineList "\n" ]
# prefix with newline and suffix with two
set var myBanner "\n$myBanner\n\n"
# Issue command
configure banner after-login $myBanner[/code]That worked a treat. Just needed to step away from the problem. Pasted script here in case anybody cares to look at it. Maybe there are some helpful tcl examples for total novices:

#@MetaDataStart
#@DetailDescriptionStart
#############################################################################
# Extreme Networks(R) CLI Scripting Library
#
# Script : Logbook URL Insertion - After Banner
# Revision : 1.0
# Last Updated : Nov 1 2017
#
# When work is performed on a switch that relates to some unique circumstance
# on that switch, it is important to be able to keep a record of that work
# and for that work to be accessible to other technicians. The process is to
# establish a google sites page for a whole location or possibly a single switch
# and to include a shortened URL in the after login banner for the switch
# ( there is a limit of 80 characters on banner lines so full URLs get tricky )
#
# The workflow is as follows:
# - issue arises on a device that warrants some custom action ( port turned down, trap suppressed )
# - establish a Sites page under the URL https://sites.google.com/a/*****/extremenetworking/home/devicehistories
# for the specific location ( e.g. CrystalLakesES )
# - document the issue and action taken against the device ( see example at https://sites.google.com/a/*****/extremenetworking/home/devicehistories/devices254 )
# - shortent the URL for the new page using the Google service https://goo.gl/
# - Insert the short URL at the bottom of the login banner with this script.
#
#####################################################################
#@DetailDescriptionEnd
#############################################################################################
# Define identity management configuration parameters in this section.
#############################################################################################
#@SectionStart (description = Script configuration properties)

#@VariableFieldLabel (description = "Stop on error?"
# type = String,
# scope = global,
# required = yes,
# validValues=[yes,no])
set var abort_when_error yes

#@VariableFieldLabel ( description = "tinyURL",
# type = String,
# scope = global,
# required = yes,
# readonly = no
😵
set var tinyURL https://itssotiny

#@VariableFieldLabel ( description = "urlSeparator",
# type = String,
# scope = global,
# required = yes,
# readonly = no
😵
set var urlSeparator =LBU==========================================================================

#@VariableFieldLabel ( description = "urlBody",
# type = String,
# scope = global,
# required = yes,
# readonly = no
😵
set var urlBody "Logbook URL:"

#@SectionEnd

#@MetaDataEnd
##################################################################
# TCL Procedure for Changing MIB View
##################################################################
proc addURL {
tinyURL
urlSeparator
urlBody
} {
set var urlText "$urlSeparator$urlBody$tinyURL$urlSeparator"
set var CLI.OUT 0
show banner after-login
set var lineList [ split ${CLI.OUT} "\n" ]
# The last value in the list is the switch login prompt so it needs
# to be chopped off
set var lineList [ lreplace $lineList end end ]
delete var CLI.OUT
set var bannerLen [ llength $lineList ]

# Now need to filter out any lines of output that are not really part of the banner
# First split the lines into a list
set var newBannerList [ list ]
set var startCopying 0
foreach line $lineList {
IF ( $TCL(regexp {After-Login} $line isFound) ) THEN
set var startCopying 1
continue
ENDIF
IF ( $startCopying == 1 ) THEN
# start copy lines into the new location
lappend newBannerList $line
ENDIF
}
# Now we don't know if we have a URL section in the banner or not
# We need to remove any existing URL section
# Write the remaining lines back into lineList
set var lineList $newBannerList
set var newBannerList [ list ]
set var urlStartIndex 0
set var urlEndIndex 0
set var listIndex 0
foreach line $lineList {
IF ( $urlStartIndex == 0 ) THEN
IF ( [ regexp {^=LBU} $line isFound ] ) THEN
set var urlStartIndex $listIndex
ENDIF
ELSE
IF ( $urlEndIndex == 0 ) THEN
IF ( [ regexp {^=LBU} $line isFound ] ) THEN
set var urlEndIndex $listIndex
ENDIF
ENDIF
ENDIF
set var listIndex [ expr $listIndex + 1 ]
}
# Replace current URL entry in banner
IF ( $urlStartIndex != 0 && $urlEndIndex != 0 ) THEN
set var lineList [ lreplace $lineList $urlStartIndex $urlEndIndex $urlSeparator $urlBody $tinyURL $urlSeparator ]
ELSE
# Assume there was no previous URL block in the banner so insert before blank line at list end
set var lineList [ linsert $lineList end-1 $urlSeparator $urlBody $tinyURL $urlSeparator ]
ENDIF
# Join list into one big string
set var myBanner [ join $lineList "\n" ]
# prefix with newline and suffix with two
set var myBanner "\n$myBanner\n\n"
# Issue command
configure banner after-login $myBanner
saveToPrimary "Logbook URL:"
return
}
#############################################################################
# TCL Procedure for CLI Script Execution Mode setting
############################################################################
proc setCliErrorHandling {inAbortStatus} {
global abort_when_error

if {![string compare $inAbortStatus "yes"]} {
configure cli mode scripting abort-on-error
} else {
configure cli mode scripting ignore-error
}
}
############################################################################
# TCL Procedure for CLI Script Execution Mode setting
############################################################################
proc saveToPrimary { logSource } {
create log entry "$logSource Saving configuration to primary"
save configuration primary
# handle prompt: Do you want to save configuration to secondary.cfg and overwrite it?
# CLI.OUT system variable has response of the previous CLI command (SAVe config secondary)
# use regex to check if it is prompt, supply response if found
set var CLI.OUT 0
regexp {.*overwrite it?.*} ${CLI.OUT} foundit
IF ([info exists foundit]) THEN
CLI y
ENDIF
delete var CLI.OUT
create log entry "$logSource Saved configuration to primary"
}
############################################################################
enable cli scripting
# enable cli scripting output
setCliErrorHandling $abort_when_error
addURL $tinyURL $urlSeparator $urlBody
disable cli scripting
Userlevel 7
Ed McGuigan wrote:

Embarrassingly I found that I had made a mistake and hadn't put a double newline at the end of my banner text:

# Join list into one big string
set var myBanner [ join $lineList "\n" ]
# prefix with newline and suffix with two
set var myBanner "\n$myBanner\n\n"
# Issue command
configure banner after-login $myBanner[/code]That worked a treat. Just needed to step away from the problem. Pasted script here in case anybody cares to look at it. Maybe there are some helpful tcl examples for total novices:

#@MetaDataStart
#@DetailDescriptionStart
#############################################################################
# Extreme Networks(R) CLI Scripting Library
#
# Script : Logbook URL Insertion - After Banner
# Revision : 1.0
# Last Updated : Nov 1 2017
#
# When work is performed on a switch that relates to some unique circumstance
# on that switch, it is important to be able to keep a record of that work
# and for that work to be accessible to other technicians. The process is to
# establish a google sites page for a whole location or possibly a single switch
# and to include a shortened URL in the after login banner for the switch
# ( there is a limit of 80 characters on banner lines so full URLs get tricky )
#
# The workflow is as follows:
# - issue arises on a device that warrants some custom action ( port turned down, trap suppressed )
# - establish a Sites page under the URL https://sites.google.com/a/*****/extremenetworking/home/devicehistories
# for the specific location ( e.g. CrystalLakesES )
# - document the issue and action taken against the device ( see example at https://sites.google.com/a/*****/extremenetworking/home/devicehistories/devices254 )
# - shortent the URL for the new page using the Google service https://goo.gl/
# - Insert the short URL at the bottom of the login banner with this script.
#
#####################################################################
#@DetailDescriptionEnd
#############################################################################################
# Define identity management configuration parameters in this section.
#############################################################################################
#@SectionStart (description = Script configuration properties)

#@VariableFieldLabel (description = "Stop on error?"
# type = String,
# scope = global,
# required = yes,
# validValues=[yes,no])
set var abort_when_error yes

#@VariableFieldLabel ( description = "tinyURL",
# type = String,
# scope = global,
# required = yes,
# readonly = no
😵
set var tinyURL https://itssotiny

#@VariableFieldLabel ( description = "urlSeparator",
# type = String,
# scope = global,
# required = yes,
# readonly = no
😵
set var urlSeparator =LBU==========================================================================

#@VariableFieldLabel ( description = "urlBody",
# type = String,
# scope = global,
# required = yes,
# readonly = no
😵
set var urlBody "Logbook URL:"

#@SectionEnd

#@MetaDataEnd
##################################################################
# TCL Procedure for Changing MIB View
##################################################################
proc addURL {
tinyURL
urlSeparator
urlBody
} {
set var urlText "$urlSeparator$urlBody$tinyURL$urlSeparator"
set var CLI.OUT 0
show banner after-login
set var lineList [ split ${CLI.OUT} "\n" ]
# The last value in the list is the switch login prompt so it needs
# to be chopped off
set var lineList [ lreplace $lineList end end ]
delete var CLI.OUT
set var bannerLen [ llength $lineList ]

# Now need to filter out any lines of output that are not really part of the banner
# First split the lines into a list
set var newBannerList [ list ]
set var startCopying 0
foreach line $lineList {
IF ( $TCL(regexp {After-Login} $line isFound) ) THEN
set var startCopying 1
continue
ENDIF
IF ( $startCopying == 1 ) THEN
# start copy lines into the new location
lappend newBannerList $line
ENDIF
}
# Now we don't know if we have a URL section in the banner or not
# We need to remove any existing URL section
# Write the remaining lines back into lineList
set var lineList $newBannerList
set var newBannerList [ list ]
set var urlStartIndex 0
set var urlEndIndex 0
set var listIndex 0
foreach line $lineList {
IF ( $urlStartIndex == 0 ) THEN
IF ( [ regexp {^=LBU} $line isFound ] ) THEN
set var urlStartIndex $listIndex
ENDIF
ELSE
IF ( $urlEndIndex == 0 ) THEN
IF ( [ regexp {^=LBU} $line isFound ] ) THEN
set var urlEndIndex $listIndex
ENDIF
ENDIF
ENDIF
set var listIndex [ expr $listIndex + 1 ]
}
# Replace current URL entry in banner
IF ( $urlStartIndex != 0 && $urlEndIndex != 0 ) THEN
set var lineList [ lreplace $lineList $urlStartIndex $urlEndIndex $urlSeparator $urlBody $tinyURL $urlSeparator ]
ELSE
# Assume there was no previous URL block in the banner so insert before blank line at list end
set var lineList [ linsert $lineList end-1 $urlSeparator $urlBody $tinyURL $urlSeparator ]
ENDIF
# Join list into one big string
set var myBanner [ join $lineList "\n" ]
# prefix with newline and suffix with two
set var myBanner "\n$myBanner\n\n"
# Issue command
configure banner after-login $myBanner
saveToPrimary "Logbook URL:"
return
}
#############################################################################
# TCL Procedure for CLI Script Execution Mode setting
############################################################################
proc setCliErrorHandling {inAbortStatus} {
global abort_when_error

if {![string compare $inAbortStatus "yes"]} {
configure cli mode scripting abort-on-error
} else {
configure cli mode scripting ignore-error
}
}
############################################################################
# TCL Procedure for CLI Script Execution Mode setting
############################################################################
proc saveToPrimary { logSource } {
create log entry "$logSource Saving configuration to primary"
save configuration primary
# handle prompt: Do you want to save configuration to secondary.cfg and overwrite it?
# CLI.OUT system variable has response of the previous CLI command (SAVe config secondary)
# use regex to check if it is prompt, supply response if found
set var CLI.OUT 0
regexp {.*overwrite it?.*} ${CLI.OUT} foundit
IF ([info exists foundit]) THEN
CLI y
ENDIF
delete var CLI.OUT
create log entry "$logSource Saved configuration to primary"
}
############################################################################
enable cli scripting
# enable cli scripting output
setCliErrorHandling $abort_when_error
addURL $tinyURL $urlSeparator $urlBody
disable cli scripting

Thanks for sharing!

Reply