Python SSH script to log into Extreme switch, run command and save output

  • 0
  • 2
  • Question
  • Updated 3 months ago
  • Answered
  • (Edited)
I have been trying to write a python script that logins to Extreme switch via SSH2, runs commands and shows output.  I looked at Extreme's github page but can't seem to find it.  Is there a example script that someone can share that login and runs commands.  I also heard there is a better way to screen scrap Extreme.

Thanks
Damon
Photo of Marvell Kay

Marvell Kay

  • 280 Points 250 badge 2x thumb

Posted 5 months ago

  • 0
  • 2
Photo of David Coglianese

David Coglianese, Embassador

  • 5,774 Points 5k badge 2x thumb
If you're just trying to run a command or two, what about using NetSight.

Or if you don't have that you might consider secure crt instead of putty. CRT would allow you to run commands on groups of switches.
Photo of Marvell Kay

Marvell Kay

  • 280 Points 250 badge 2x thumb
I can't use SecureCRT as it will be a web service.  I was looking for just a script to SSH and run commands .. maybe paramiko/pextect?  I could not find any example.

I tried something simple like this but it didn't work:

import pexpect
import sys

switch_ip = "10.10.10.1"
switch_un = "user"
switch_pw = "pass"

child = pexpect.spawn('ssh %s@%s' % (switch_un, switch_ip))
child.logfile = sys.stdout
child.timeout = 4
child.expect('Password:')
child.sendline(switch_pw)
child.expect('#')
(Edited)
Photo of Dave Hammers

Dave Hammers, Dir SW Engineering

  • 3,502 Points 3k badge 2x thumb
If you are running EXOS 21.x or later, you can use the JSONRPC interface.
https://github.com/extremenetworks/EXOS_Apps/tree/master/JSONRPC. If your scripting is in Python, you can import the jsonrpc.py module as a base class.

You can send CLI commands over http(s). For show commands you get the data used to construct the display in JSON format. There is no need to screen scrape.

If you are running EXOS 15.6.2 - 16.x, ssh/telnet are the only interfaces for this, but you can still get the same screen output as JSON data by using the embedded script cli2json.py which formats the results in the same way that the JSONRPC interface does.

E.g.
run script cli2json.py -d show port 1 config no-refresh
[
  {
    "CLIoutput": "Port Configuration\nPort     Virtual    Port  Link  Auto   Speed      Duplex   Flow  Load   Media\n         router     State State Neg  Cfg Actual Cfg Actual Cntrl Master Pri Red\n================================================================================\n1        VR-Default E       R    ON  AUTO       AUTO                    UTP          \n================================================================================\n> indicates Port Display Name truncated past 8 characters\nLink State: A-Active, R-Ready, NP-Port Not Present, L-Loopback\nPort State: D-Disabled, E-Enabled, L-License Disabled\nMedia: !-Unsupported, $-Unlicensed\nMedia Red: * - use \"show port info detail\" for redundant media type\nFlow Cntrl: Shows link partner's abilities. NONE if Auto Neg is OFF\n"
  },
  {
    "show_ports_config": {
      "duplexActual": null,
      "duplexCfg": "AUTO",
      "flowControl": null,
      "isAutoNegOn": 1,
      "licenseDisable": 0,
      "linkState": 0,
      "port": 1,
      "portList": 1,
      "portState": 1,
      "primaryMedia": " UTP",
      "speedActual": null,
      "speedCfg": "AUTO",
      "vrName": "VR-Default"
    },
    "status": "SUCCESS"
  }
]
Photo of OscarK

OscarK, ESE

  • 7,692 Points 5k badge 2x thumb
class SSH2EXOS:
    def __init__(self, switch, user='admin',password=''):
        self.connected = True
        self.client = paramiko.SSHClient()
        self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        self.client.connect(switch,username=user,password=password)
        stdin, stdout, stderr = self.client.exec_command("disable clipaging")
        stdin.close()

    def cmdFast(self,cmd,timeout=30):
        stdin, stdout, stderr = self.client.exec_command(cmd)
        stdin.close()
        return cmd+"\n"+stdout.read()

    def exit(self):
        self.client.close()
        self.connected = False

    def exitwithsave(self,save):
        if save == "Y":
            print "Saving config"
            try:
                stdin, stdout, stderr = self.client.exec_command('save')
                stdin.flush()
                print stdout.read()
                self.client.close()
                self.connected = False
            except:
                print "except"
        self.client.close()
        self.connected = False


    def isConnected(self):
        if self.connected:
            return True
        else:
            return False

def main():
    parser = argparse.ArgumentParser(description='Connect to switch(es) and delete xsf files')
    parser.add_argument("-u", dest="user", default="admin", help="Username")
    parser.add_argument("-p", dest="password", default="", help="Password, leave out for none")
    parser.add_argument("-s", dest="switch", default=None, help="Switch IP address")
    args = parser.parse_args()
    
    mlagfilters = None
    if args.switch:
        print "Connecting to :",args.switch
        xos = SSH2EXOS(checkIP(args.switch), user=args.user, password=args.password)
        if xos.isConnected():
            print "Connected."
            info = xos.cmdFast("show switch")
            for line in info.splitlines():
                m = re.search(r'SysName:\s+(\S+)',line)
                if m:
                    switchname = m.group(1)
            xos.exit()
Photo of Marvell Kay

Marvell Kay

  • 280 Points 250 badge 2x thumb
Thanks!!!  I will look into JSONRPC but since we have mixture of codes in out env I don't think it is going to work.

I tried the second code but when i run it on by Linux machine, it shows nothing.  It does run without giving me any errors but no output.  I have a test device with user "user12" and password "1password2" with ip "10.10.10.1".  Here is how I edited the code.  Can you please check and see if I missed something.  I am not familiar with classes.

I also added a print in main and I don't see that either.

class SSH2EXOS:
    def __init__(self, switch, user='user12',password='1password2'):
        self.connected = True
        self.client = paramiko.SSHClient()
        self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        self.client.connect(switch,username=user,password=password)
        stdin, stdout, stderr = self.client.exec_command("disable clipaging")
        stdin.close()
    def cmdFast(self,cmd,timeout=30):
        stdin, stdout, stderr = self.client.exec_command(cmd)
        stdin.close()
        return cmd+"\n"+stdout.read()
    def exit(self):
        self.client.close()
        self.connected = False
    def exitwithsave(self,save):
        if save == "Y":
            print "Saving config"
            try:
                stdin, stdout, stderr = self.client.exec_command('save')
                stdin.flush()
                print stdout.read()
                self.client.close()
                self.connected = False
            except:
                print "except"
        self.client.close()
        self.connected = False

    def isConnected(self):
        if self.connected:
            return True
        else:
            return False
def main(): print "Main"
    parser = argparse.ArgumentParser(description='Connect to switch(es) and delete xsf files')
    parser.add_argument("-u", dest="user", default="user12", help="Username")
    parser.add_argument("-p", dest="password", default="1password2", help="Password, leave out for none")
    parser.add_argument("-s", dest="switch", default=None, help="10.10.10.1")
    args = parser.parse_args() 
    mlagfilters = None
    if args.switch:
        print "Connecting to :",args.switch
        xos = SSH2EXOS(checkIP(args.switch), user=args.user, password=args.password)
        if xos.isConnected():
            print "Connected."
            info = xos.cmdFast("show switch")
            for line in info.splitlines():
                m = re.search(r'SysName:\s+(\S+)',line)
                if m:
                    switchname = m.group(1)
            xos.exit()
(Edited)
Photo of OscarK

OscarK, ESE

  • 7,692 Points 5k badge 2x thumb
Yes, the script I provided only connects to a switch and exits, to print something you need to add more.
Just before xos.exit() enter lines for commands like:
print xos.cmd("show vlan")
Photo of Ludovico Stevens

Ludovico Stevens, Employee

  • 160 Points 100 badge 2x thumb
Also add a last line with:
main()
But argparse needs to be imported from somewhere..
Photo of Norbert Elitzer

Norbert Elitzer

  • 70 Points
or something like:
#with SSH login without password and authentication keys enabled
import subprocess
try:
  out = subprocess.check_output(['printf "show config\n" | ssh -o ForwardX11=no -T admin@10.0.0.1'], shell=True)
except subprocess.CalledProcessError as e:
  out = e.output
  print out
  exit(1)
print "Switch output: %s\n" %  out
(Edited)
Photo of tknv

tknv, Employee

  • 134 Points 100 badge 2x thumb
I think using netmiko is easy for python SSH scripting.
Very simple example:
from netmiko import ConnectHandler

extrm_X460 = {
    'device_type': 'extreme',
    'ip':   '172.16.10.2',
    'username': 'admin',
    'password': 'verysecret',
    'port' : 12322,          # optional, defaults to 22
}

net_connect = ConnectHandler(**extrm_X460)

output = net_connect.send_command('show switch')
print(output)