cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
6789
Views
0
Helpful
18
Replies

Q: CAN you repeatedly SSH from within a TCL script to, for example, a radio . . .

tproeber
Level 1
Level 1

. .. to get the current Line Rate to then write that speed to the Bandwidth statement for an Interface to make routine protocols more accurate over radio links with varying modulations?

My Googling says tells me that you can log in but any commands you issue will hang.  Can you SSH and retrieve command results from remote hosts in Cisco TCL?

Thanks!

Tim

18 Replies 18

tproeber
Level 1
Level 1

This document on page 15 really seems to say YES WE CAN:

Cisco Embedded Event Manager (EEM)- Technical Deep Dive (IOS Advant...

.. . still hopefull . .

- Tim

Yep.  You can do this given new enough IOS.  The link on that slide goes to an EEM solution that does this.

Thanks Joe!

- Tim

Is it possible to get a stand-alone exapmle of SSH?  The "No Easy Shell" is NOT easy like it says . . .

I've been trying to get a script written or find DETAILED help for a while now.  Ican't even find a contractor to write this.  I have about 1 week left before I switch to RouterBoard.  They have scripting and help available.  Those guys Latvia guys are great!

Thanks,

Tim

At its core the script spawns the SSH command, then uses cli_read_pattern and cli_write to interact with the remote connection.  For example (without error checking):

cli_write $cli(fd) "ssh -l user host.example.com"

cli_read_pattern $cli(fd) "assword:"

cli_write $cli(fd) "mypassword"

cli_read_pattern $cli(fd) "#"

cli_write $cli(fd) "sho ver"

set output [cli_read_pattern $cli(fd) "#"]

puts $output

That help?

YES!

Thanks,

Tim

I guess it needs an cli_open too?

I am realllllllllllllly trying to write a functioning script.

TCL on Cisco gets NO RESPECT at www.oceaneering.com because no one knows about it and they only have ME telling them and I can't get a GD thing to run.

Yes, cli_open is needed as is a cli_close:

array set cli [cli_open]

...

catch {cli_close $cli(fd) $cli(tty_id)}

Note, there are a lot of examples in this community that work and can help get you started with EEM and EEM Tcl.  An easy way to get started with EEM Tcl is to take an applet that does what you want or parts of what you want and put it into http://www.marcuscom.com/convert_applet/ to get the Tcl version.

I'm going one step at a time and want to do a demo of each command I will use. 

Here I am trying to read a sho-run environmental variable called TestVar and then write what I read to a different sho-run enviromental variable called EnvRead.

But it's not working . .

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

#event manager environment TestVar 1

#event manager environment MyVar 129

#event manager environment EnvRead              <----- This is not getting set with TestVar

#event manager directory user policy "flash:/"

#event manager policy test-tcl.tcl

# copy tftp://192.168.104.5/test-tcl.tcl flash:

# ##############################################

::cisco::eem::event_register_timer watchdog time 10

namespace import ::cisco::eem::*

namespace import ::cisco::lib::*

# Open a virtual telnet

if { [catch {cli_open} result] } {

error $result $errorInfo

}

array set cli $result

# Enter Enable Mode

if { [catch {cli_exec $cli(fd) "enable"} result] } {

error $result $errorInfo

}

# Check if the Variable MyVar already exists and if not create and set to 0;

if { ! [info exists MyVar] } {

set MyVar 0

} else {

if { [catch {context_retrieve MyContext MyVar} result] } {

set MyVar 0

} else {

set MyVar $result

}

}

# Increment the retrieved MyVar

incr MyVar

# Now re-save the variable MyVar

catch {context_save MyContext MyVar}

#!!# READ and Save an Environmental Variable

if [catch {cli_exec $cli(fd) "sho event manager environment TestVar"} result] {

error $result $errorInfo

}

else {

set EnVarRead $result

}

####  Enter Config t   ###

if { [catch {cli_exec $cli(fd) "config t"} result] } {

error $result $errorInfo

}

# Write an Envronmental Varible that shows up in the Sho-run

if { [catch {cli_exec $cli(fd) "event manager environment MyVar $MyVar"} result] } {

error $result $errorInfo

}

# Write the test EnVarRead  . .

if { [catch {cli_exec $cli(fd) "event manager environment EnvRead $EnVarRead"} result] } {

error $result $errorInfo

}

# Close the Telnet

catch {cli_close $cli(fd) $cli(tty_id)}

### END ###;

Scott Van de Houten  --  svandeho@cisco.com  is trying to get the TCL script that TAC wrote for the Navy -- that TAC suggested would work for my radio load-balance project.

- Tim

Trying to set an environment variable to the value of CLI output is not a good idea.  The CLI output will not be exactly what you think it is.  If you do:

set l [split $result "\n"]

foreach line [lrange $l 0 end-1] {

    set line [string trim $line]

    if { $line != "" } {

        set EnvVarRead $line

    }

}

I got the Navy script -- it was for load-balancng over 12 TWELVE serial lines!

I surrender!  I'm getting a contractor

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

array set _mar_einfo [event_reqinfo_multi]

set _i 1
foreach _tag [list syslog] {
    if { [info exists _mar_einfo($_tag)] } {
        set _event_tag$_i $_tag
        array set arr_einfo_$_i $_mar_einfo($_tag)
        incr _i
    }
}


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
}

action_syslog msg "Scan thru HWIC-4T Slot 0 interfaces ..."
foreach int "Serial0/0/0 Serial0/0/1 Serial0/0/2 Serial0/0/3 Serial0/1/0 Serial0/1/1 Serial0/1/2 Serial0/1/3 Serial0/2/0 Serial0/2/1 Serial0/2/2 Serial0/2/3" {
    if [catch {cli_exec $cli1(fd) "show ip int $int | in $int"} _cli_result] {
        error $_cli_result $errorInfo
    }

    set _regexp_result [regexp {line protocol is down} "$_cli_result"]
    if {$_regexp_result == 1} {
        action_syslog msg "$int: line protocol is down; Skip to next ..."
        continue
    }
    if [catch {cli_exec $cli1(fd) "show controller $int | inc (Clock|clock rate)"} _cli_result] {
        error $_cli_result $errorInfo
    }

    set _regexp_result [regexp {clock rate ([0-9]+)} "$_cli_result" ignore clock]
    if {$_regexp_result != 1} {
        set _regexp_result [regexp {clk ([0-9]+)/} "$_cli_result" ignore clock]
    }
    if {$_regexp_result != 1} {
        action_syslog msg "Failed to find clock rate for $int"
        continue
    }
    set _result [expr $clock / 1000]
    set _remainder [expr $clock % 1000]
    set bandwidth "$_result"
    if {$_remainder >= 500} {
        incr bandwidth 
    }
    if {$bandwidth <= 115} {
        action_syslog msg "$int: Bandwidth too low for QoS Policy. Skip it!"
        continue
    } elseif {$bandwidth <= 400} {
        set newQosPolicy "INM"
    } elseif {$bandwidth <= 1200} {
        set newQosPolicy "SATCOM-LOW"
    } elseif {$bandwidth <= 3000} {
        set newQosPolicy "SATCOM-MED"
    } else {
        set newQosPolicy "SATCOM-HI"
    }
    action_syslog msg "$int: for $bandwidth Kbps use Policy $newQosPolicy"
    if [catch {cli_exec $cli1(fd) "config t"} _cli_result] {
        error $_cli_result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "interface $int"} _cli_result] {
        error $_cli_result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "bandwidth $bandwidth"} _cli_result] {
        error $_cli_result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "do show policy-map $newQosPolicy | inc Policy Map"} _cli_result] {
        error $_cli_result $errorInfo
    }

    set _regexp_result [regexp {Policy Map ([A-Za-z0-9\-]+\_*[A-Za-z0-9\-]+)} "$_cli_result" ignore qosPolicyMap]
    if {$_regexp_result != 1} {
        if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
            error $_cli_result $errorInfo
        }

        action_syslog msg "int $int fail to find Policy-Map $newQosPolicy; no adjustment"
        continue
    }
    action_syslog msg "$int: Searching for Policy Map $qosPolicyMap ..."
    if {$newQosPolicy != $qosPolicyMap} {
        if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
            error $_cli_result $errorInfo
        }

        action_syslog msg "fail to find configured qosPolicyMap $qosPolicyMap; no adjustment"
        continue
    }
    if [catch {cli_exec $cli1(fd) "do show run int $int | inc service-policy output"} _cli_result] {
        error $_cli_result $errorInfo
    }

    set _regexp_result [regexp {service-policy output ([A-Za-z0-9\-]+)} "$_cli_result" ignore oldQosPolicy]
    if {$_regexp_result == 1} {
        action_syslog msg "$int: Found: Policy Map $oldQosPolicy"
        if {$newQosPolicy == $oldQosPolicy} {
            if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
                error $_cli_result $errorInfo
            }

            action_syslog msg "$int: QoS Policy $oldQosPolicy already in effect; no change."
        } else {
            if [catch {cli_exec $cli1(fd) "no service-policy output $oldQosPolicy"} _cli_result] {
                error $_cli_result $errorInfo
            }

            action_syslog msg "$int: Remove old QoS policy $oldQosPolicy"
            if [catch {cli_exec $cli1(fd) "service-policy output $newQosPolicy"} _cli_result] {
                error $_cli_result $errorInfo
            }

            action_syslog msg "$int: Applied new QoS policy $newQosPolicy"
            if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
                error $_cli_result $errorInfo
            }

        }
    } else {
        action_syslog msg "$int: No QoS Policy currently configured! Fix it!"
        if [catch {cli_exec $cli1(fd) "service-policy output $newQosPolicy"} _cli_result] {
            error $_cli_result $errorInfo
        }

        action_syslog msg "$int: Applied new QoS policy $newQosPolicy"
        if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
            error $_cli_result $errorInfo
        }

    }
}
action_syslog msg "Scan thru NM-4T Slot 1 interfaces ..."
foreach int "Serial1/0 Serial1/1 Serial1/2 Serial1/3" {
    if [catch {cli_exec $cli1(fd) "show ip int $int | in $int"} _cli_result] {
        error $_cli_result $errorInfo
    }

    set _regexp_result [regexp {line protocol is down} "$_cli_result"]
    if {$_regexp_result == 1} {
        action_syslog msg "$int: line protocol is down; Skip to next ..."
        continue
    }
    if [catch {cli_exec $cli1(fd) "show controller $int | inc (Clock|clock rate)"} _cli_result] {
        error $_cli_result $errorInfo
    }

    set _regexp_result [regexp {clock rate ([0-9]+)} "$_cli_result" ignore clock]
    if {$_regexp_result != 1} {
        set _regexp_result [regexp {clk ([0-9]+)/} "$_cli_result" ignore clock]
    }
    if {$_regexp_result != 1} {
        action_syslog msg "Failed to find clock rate for $int"
        continue
    }
    set _result [expr $clock / 1000]
    set _remainder [expr $clock % 1000]
    set bandwidth "$_result"
    if {$_remainder >= 500} {
        incr bandwidth 
    }
    if {$bandwidth <= 115} {
        action_syslog msg "$int: Bandwidth too low for QoS Policy. Skip it!"
        continue
    } elseif {$bandwidth <= 400} {
        set newQosPolicy "EHF"
    } elseif {$bandwidth <= 1200} {
        set newQosPolicy "SATCOM-LOW"
    } elseif {$bandwidth <= 3000} {
        set newQosPolicy "SATCOM-MED"
    } else {
        set newQosPolicy "SATCOM-HI"
    }
    action_syslog msg "$int: for $bandwidth Kbps use Policy $newQosPolicy"
    if [catch {cli_exec $cli1(fd) "config t"} _cli_result] {
        error $_cli_result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "interface $int"} _cli_result] {
        error $_cli_result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "bandwidth $bandwidth"} _cli_result] {
        error $_cli_result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "do show policy-map $newQosPolicy | inc Policy Map"} _cli_result] {
        error $_cli_result $errorInfo
    }

    set _regexp_result [regexp {Policy Map ([A-Za-z0-9\-]+\_*[A-Za-z0-9\-]+)} "$_cli_result" ignore qosPolicyMap]
    if {$_regexp_result != 1} {
        if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
            error $_cli_result $errorInfo
        }

        action_syslog msg "int $int fail to find Policy-Map $newQosPolicy; no adjustment"
        continue
    }
    action_syslog msg "$int: Searching for Policy Map $qosPolicyMap ..."
    if {$newQosPolicy != $qosPolicyMap} {
        if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
            error $_cli_result $errorInfo
        }

        action_syslog msg "fail to find configured qosPolicyMap $qosPolicyMap; no adjustment"
        continue
    }
    if [catch {cli_exec $cli1(fd) "do show run int $int | inc service-policy output"} _cli_result] {
        error $_cli_result $errorInfo
    }

    set _regexp_result [regexp {service-policy output ([A-Za-z0-9\-]+)} "$_cli_result" ignore oldQosPolicy]
    if {$_regexp_result == 1} {
        action_syslog msg "$int: Found: Policy Map $oldQosPolicy"
        if {$newQosPolicy == $oldQosPolicy} {
            if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
                error $_cli_result $errorInfo
            }

            action_syslog msg "$int: QoS Policy $oldQosPolicy already in effect; no change."
        } else {
            if [catch {cli_exec $cli1(fd) "no service-policy output $oldQosPolicy"} _cli_result] {
                error $_cli_result $errorInfo
            }

            action_syslog msg "$int: Remove old QoS policy $oldQosPolicy"
            if [catch {cli_exec $cli1(fd) "service-policy output $newQosPolicy"} _cli_result] {
                error $_cli_result $errorInfo
            }

            action_syslog msg "$int: Applied new QoS policy $newQosPolicy"
            if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
                error $_cli_result $errorInfo
            }

        }
    } else {
        action_syslog msg "$int: No QoS Policy currently configured! Fix it!"
        if [catch {cli_exec $cli1(fd) "service-policy output $newQosPolicy"} _cli_result] {
            error $_cli_result $errorInfo
        }

        action_syslog msg "$int: Applied new QoS policy $newQosPolicy"
        if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
            error $_cli_result $errorInfo
        }

    }
}
action_syslog msg "Scan thru NM-4T Slot 2 interfaces ..."
foreach int "Serial2/0 Serial2/1 Serial2/2 Serial2/3" {
    if [catch {cli_exec $cli1(fd) "show ip int $int | in $int"} _cli_result] {
        error $_cli_result $errorInfo
    }

    set _regexp_result [regexp {line protocol is down} "$_cli_result"]
    if {$_regexp_result == 1} {
        action_syslog msg "$int: line protocol is down; Skip to next ..."
        continue
    }
    if [catch {cli_exec $cli1(fd) "show controller $int | inc (Clock|clock rate)"} _cli_result] {
        error $_cli_result $errorInfo
    }

    set _regexp_result [regexp {clock rate ([0-9]+)} "$_cli_result" ignore clock]
    if {$_regexp_result != 1} {
        set _regexp_result [regexp {clk ([0-9]+)/} "$_cli_result" ignore clock]
    }
    if {$_regexp_result != 1} {
        action_syslog msg "Failed to find clock rate for $int"
        continue
    }
    set _result [expr $clock / 1000]
    set _remainder [expr $clock % 1000]
    set bandwidth "$_result"
    if {$_remainder >= 500} {
        incr bandwidth 
    }
    if {$bandwidth <= 115} {
        action_syslog msg "$int: Bandwidth too low for QoS Policy. Skip it!"
        continue
    } elseif {$bandwidth <= 400} {
        set newQosPolicy "INM"
    } elseif {$bandwidth <= 1200} {
        set newQosPolicy "SATCOM-LOW"
    } elseif {$bandwidth <= 3000} {
        set newQosPolicy "SATCOM-MED"
    } else {
        set newQosPolicy "SATCOM-HI"
    }
    action_syslog msg "$int: for $bandwidth Kbps use Policy $newQosPolicy"
    if [catch {cli_exec $cli1(fd) "config t"} _cli_result] {
        error $_cli_result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "interface $int"} _cli_result] {
        error $_cli_result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "bandwidth $bandwidth"} _cli_result] {
        error $_cli_result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "do show policy-map $newQosPolicy | inc Policy Map"} _cli_result] {
        error $_cli_result $errorInfo
    }

    set _regexp_result [regexp {Policy Map ([A-Za-z0-9\-]+\_*[A-Za-z0-9\-]+)} "$_cli_result" ignore qosPolicyMap]
    if {$_regexp_result != 1} {
        if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
            error $_cli_result $errorInfo
        }

        action_syslog msg "int $int fail to find Policy-Map $newQosPolicy; no adjustment"
        continue
    }
    action_syslog msg "$int: Searching for Policy Map $qosPolicyMap ..."
    if {$newQosPolicy != $qosPolicyMap} {
        if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
            error $_cli_result $errorInfo
        }

        action_syslog msg "fail to find configured qosPolicyMap $qosPolicyMap; no adjustment"
        continue
    }
    if [catch {cli_exec $cli1(fd) "do show run int $int | inc service-policy output"} _cli_result] {
        error $_cli_result $errorInfo
    }

    set _regexp_result [regexp {service-policy output ([A-Za-z0-9\-]+)} "$_cli_result" ignore oldQosPolicy]
    if {$_regexp_result == 1} {
        action_syslog msg "$int: Found: Policy Map $oldQosPolicy"
        if {$newQosPolicy == $oldQosPolicy} {
            if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
                error $_cli_result $errorInfo
            }

            action_syslog msg "$int: QoS Policy $oldQosPolicy already in effect; no change."
        } else {
            if [catch {cli_exec $cli1(fd) "no service-policy output $oldQosPolicy"} _cli_result] {
                error $_cli_result $errorInfo
            }

            action_syslog msg "$int: Remove old QoS policy $oldQosPolicy"
            if [catch {cli_exec $cli1(fd) "service-policy output $newQosPolicy"} _cli_result] {
                error $_cli_result $errorInfo
            }

            action_syslog msg "$int: Applied new QoS policy $newQosPolicy"
            if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
                error $_cli_result $errorInfo
            }

        }
    } else {
        action_syslog msg "$int: No QoS Policy currently configured! Fix it!"
        if [catch {cli_exec $cli1(fd) "service-policy output $newQosPolicy"} _cli_result] {
            error $_cli_result $errorInfo
        }

        action_syslog msg "$int: Applied new QoS policy $newQosPolicy"
        if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
            error $_cli_result $errorInfo
        }

    }
}

# Close open cli before exit.
catch {cli_close $cli1(fd) $cli1(tty_id)} result

I can see the Line go up when it does the SSH, but the interface description is not changed.  Why?

event manager applet Int-Desc

event timer watchdog time 15

action 010 cli command "enable"

action 020 cli command "ssh -l cobra 192.168.101.1" pattern "assword:"

action 050 cli command "tiger$9" pattern "#"

action 060 cli command "conf t" pattern "#"

action 070 cli command "int g 0/1/7" pattern "#"

action 080 cli command "desc TEST" pattern "#"

action 090 cli command "exit" pattern "#"

action 100 cli command "exit" pattern "#"

Enable "debug event manager action cli" and collect the output.

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:

Innovations in Cisco Full Stack Observability - A new webinar from Cisco