Netgear GS728TP CLI and scripting



It's been a long time between posts. I can assure you I'm not dead. At least not that I know of. I've been doing some neat stuff, but have been too lazy to post any of it - because as any dev will tell you - doing documentation is boring.

So, after upgrading my access points to use a Cisco Virtual Wireless Controller, I was using the web interface on my Netgear GS728TP - but it really sucks. It's slow. It's really slow - but it has a fully functioning CLI under the hood. However, the SSH server is old as well, so it needs a whole heap of legacy enablement in the SSH client to function. It is an EoL product, being first released in November 2017 from what I can tell. However they're cheap to find second hand, and have 8x POE+ ports - which means they'll run your high power PoE kit.

I did some work with expect - and came up with this script to do some pretty common functions.

Save as ~/bin/switch.

#!/usr/bin/expect
set switch_password "<switch password>"
set switch_login "admin@<switch ip>"
set TFTPSERVER "<tftp server ip>"
set switch_ssh_opts "-oPubKeyAcceptedAlgorithms=ssh-rsa -oRequiredRSASize=1024 -oKexAlgorithms=diffie-hellman-group1-sha1 -oHostKeyAlgorithms=ssh-rsa,ssh-dss -oCiphers=aes128-cbc,aes128-ctr,aes256-ctr"
set commands(0) "terminal datadump"
set commands(1) "terminal width 0"
set timeout 120

set func [lindex $argv 0]
switch $func {
    if {
        set arg [lindex $argv 1]
        switch $arg {
            description {
                append commands([array size commands]) "show interfaces description"
            }
            detail {
                set port [lindex $argv 2]
                append commands([array size commands]) "show interfaces switchport ge $port"
            }
            reset {
                set port [lindex $argv 2]
                append commands([array size commands]) "config"
                append commands([array size commands]) "interface GigabitEthernet $port"
                append commands([array size commands]) "shutdown"
                append commands([array size commands]) "no shutdown"
                append commands([array size commands]) "exit\rexit\r"
            }
            summary {
                append commands([array size commands]) "show interfaces status detailed"
            }
            default {
                puts "Subcommands:\r"
                puts "\tdescription\r"
                puts "\tdetail <port>\r"
                puts "\treset <port>\r"
                puts "\tsummary\r"
                exit 0
            }
        }
    }
    poe {
        set arg [lindex $argv 1]
        switch $arg {
            consumption {
                append commands([array size commands]) "show power inline consumption"
            }   
            off {
                set port [lindex $argv 2]
                append commands([array size commands]) "config"
                append commands([array size commands]) "interface GigabitEthernet $port"
                append commands([array size commands]) "power inline never"
                append commands([array size commands]) "exit\rexit\r"
            }
            on {
                set port [lindex $argv 2]
                append commands([array size commands]) "config"
                append commands([array size commands]) "interface GigabitEthernet $port"
                append commands([array size commands]) "power inline auto"
                append commands([array size commands]) "exit\rexit\r"
            }
            reset {
                set port [lindex $argv 2]
                append commands([array size commands]) "config"
                append commands([array size commands]) "interface GigabitEthernet $port"
                append commands([array size commands]) "power inline never"
                append commands([array size commands]) "power inline auto"
                append commands([array size commands]) "exit\rexit\r"
            }
            summary {
                append commands([array size commands]) "show power inline"
            }   
            default {
                puts "Subcommands:\r"
                puts "\tconsumption\r"
                puts "\toff <port>\r"
                puts "\ton <port>\r"
                puts "\treset <port>\r"
                puts "\tsummary\r"
                exit 0
            }
        }
    }
    reboot {
        send -- "reload\r"
        expect "(Y/N)"
        send -- "y\r"
        interact
    }
    saveconfig {
        set DATE [clock format [clock seconds] -format {%Y-%m-%d_%H%M}]
        append commands([array size commands]) "copy running-config tftp://$TFTPSERVER/gs728tp/running-config-$DATE.txt"
    }
    vlan {
        append commands([array size commands]) "show vlan"
    }
    default {
        puts "Commands:\r"
        puts "\tif <cmd>\r"
        puts "\tpoe <cmd>\r"
        puts "\treboot\r"
        puts "\tsaveconfig\r"
        puts "\tvlan\r"
        exit
    }
}

eval spawn ssh $switch_ssh_opts $switch_login

expect "assword:"
send -- "$switch_password\r"
for { set index 0 }  { $index < [array size commands] }  { incr index } {
    expect "#"
    send -- "$commands($index)\r"
}
expect "\r\nconsole#"
send -- "exit\r"
expect eof

This gives me a nice little easy to use command set for some very basic stuff - however, if you're like me with a million scripts, I also forget the options :)

As such, I took a dive into the bash-completion universe and managed to come up with this.

Save as ~/.bash_completion.

#/usr/bin/env bash
_switch_completions()
{
  local cur prev

  COMPREPLY=()
  cur=${COMP_WORDS[COMP_CWORD]}
  prev=${COMP_WORDS[COMP_CWORD-1]}

  if [ $COMP_CWORD -eq 1 ]; then
    COMPREPLY=( $(compgen -W "if poe reboot saveconfig vlan" -- $cur) )
  elif [ $COMP_CWORD -eq 2 ]; then
    case "$prev" in
      "if")
        COMPREPLY=( $(compgen -W "description detail reset summary" -- $cur) )
        ;;
      "poe")
        COMPREPLY=( $(compgen -W "consumption off on reset summary" -- $cur) )
        ;;
      *)
        ;;
    esac
  fi

  return 0
} &&
complete -F _switch_completions switch

As an example, if I run switch if summary, I'll get the following output:

spawn ssh -oPubKeyAcceptedAlgorithms=ssh-rsa -oRequiredRSASize=1024 -oKexAlgorithms=diffie-hellman-group1-sha1 -oHostKeyAlgorithms=ssh-rsa,ssh-dss -oCiphers=aes128-cbc,aes128-ctr,aes256-ctr admin@<switch-ip>
admin@<switch-ip>'s password:

console#terminal datadump
console#terminal width 0
console#show interfaces status detailed
                                             Flow Link          Back   Mdix
Port     Type         Duplex  Speed Neg      ctrl State       Pressure Mode
-------- ------------ ------  ----- -------- ---- ----------- -------- -------
g1       1G-Copper    Full    1000  Disabled Off  Up          Disabled On     
g2       1G-Copper      --      --     --     --  Down           --     --    
g3       1G-Copper      --      --     --     --  Down           --     --    
g4       1G-Copper      --      --     --     --  Down           --     --    
g5       1G-Copper      --      --     --     --  Down           --     --    
g6       1G-Copper      --      --     --     --  Down           --     --    
g7       1G-Copper      --      --     --     --  Down           --     --    
g8       1G-Copper      --      --     --     --  Down           --     --    
g9       1G-Copper    Full    1000  Disabled Off  Up          Disabled On     
g10      1G-Copper    Full    1000  Disabled Off  Up          Disabled On     
g11      1G-Copper    Full    1000  Disabled Off  Up          Disabled On     
g12      1G-Copper    Full    1000  Disabled Off  Up          Disabled On     
g13      1G-Copper    Full    100   Enabled  Off  Up          Disabled On     
g14      1G-Copper    Full    100   Enabled  Off  Up          Disabled Off    
g15      1G-Copper      --      --     --     --  Down           --     --    
g16      1G-Copper      --      --     --     --  Down           --     --    
g17      1G-Copper      --      --     --     --  Down           --     --    
g18      1G-Copper      --      --     --     --  Down           --     --    
g19      1G-Copper      --      --     --     --  Down           --     --    
g20      1G-Copper      --      --     --     --  Down           --     --    
g21      1G-Copper      --      --     --     --  Down           --     --    
g22      1G-Copper      --      --     --     --  Down           --     --    
g23      1G-Copper    Full    1000  Enabled  Off  Up          Disabled On     
g24      1G-Copper    Full    100   Enabled  Off  Up          Disabled Off    
g25      1G-Fiber       --      --     --     --  Down           --     --    
g26      1G-Fiber       --      --     --     --  Down           --     --    
g27      1G-Fiber       --      --     --     --  Down           --     --    
g28      1G-Fiber       --      --     --     --  Down           --     --    

                                          Flow    Link        
Ch       Type    Duplex  Speed  Neg      control  State       
-------- ------- ------  -----  -------- -------  ----------- 
po 1        --     --      --      --       --    Not Present 
po 2        --     --      --      --       --    Not Present 
po 3        --     --      --      --       --    Not Present 
po 4        --     --      --      --       --    Not Present 
po 5        --     --      --      --       --    Not Present 
po 6        --     --      --      --       --    Not Present 
po 7        --     --      --      --       --    Not Present 
po 8        --     --      --      --       --    Not Present 
console#exit

So now, not only do I have an easy way to bring up basic details of the switch, when I forget what options do what, you can just use the TAB auto-completion in bash. Yay, yet another thing I don't have to remember in the day-to-day :)

Comments


Comments powered by Disqus