Paramiko Script

Mastering Python Networking (Paramiko).

import paramiko, getpass, time

devices = {‘voss-1’: {‘ip’: ‘192.168.1.10’},
‘voss-2’: {‘ip’: ‘192.168.1.11’}}
commands = [‘enable\n’, ‘show software\n’, ‘show sys-info card\n’, ‘exit\n’]

username = input(‘Username: ‘)
password = getpass.getpass(‘Password: ‘)

max_buffer = 65535

def clear_buffer(connection):
if connection.recv_ready():
return connection.recv(max_buffer)

# Starts the loop for devices
for device in devices.keys():
outputFileName = device + ‘_output.txt’
connection = paramiko.SSHClient()
connection.set_missing_host_key_policy(paramiko.AutoAddPolicy())
connection.connect(devices[device][‘ip’], username=username, password=password, look_for_keys=False, allow_agent=False)
new_connection = connection.invoke_shell()
output = clear_buffer(new_connection)
time.sleep(5)
new_connection.send(“terminal more disable\n”)
output = clear_buffer(new_connection)
with open(outputFileName, ‘wb’) as f:
for command in commands:
new_connection.send(command)
time.sleep(5)
output = new_connection.recv(max_buffer)
print(output)
f.write(output)

new_connection.close()

Pexpect Script

Mastering Python Networking (Pexpect).

import getpass
from pexpect import pxssh
import time

devices = {‘VSP-8284XSQ-1’: {‘prompt’: ‘VSP-8284XSQ-1:1>’, ‘ip’: ‘192.168.1.10’}, ‘VSP-8284XSQ-2’: {‘prompt’: ‘VSP-8284XSQ-2:1>’, ‘ip’: ‘192.168.1.11’}}

commands = [‘terminal more disable’, ‘show sys-info card’, ‘terminal more enable’]

username = input(‘Username: ‘)
password = getpass.getpass(‘Password: ‘)

for device in devices.keys():
outputFileName = device + ‘_output.txt’
device_prompt = devices[device] [‘prompt’]
device_ip = devices[device] [‘ip’]
child = pxssh.pxssh()
child.login(devices[device] [‘ip’], username.strip(), password.strip(), auto_prompt_reset=False)
print(‘Logged in to ‘ + device)
with open(outputFileName, ‘wb’) as f:
for command in commands:
child.expect(device_prompt)
child.sendline(command)
time.sleep(1)
f.write(child.before)
child.logout()

Backup Multiple ERS Configurations

Here is a python script which will backup the running-config of multiple ERS switches listed in a text file. This script will send Ctrl + Y code sequence to the switch and run the copy command to a local TFTP server.

Python file sshclientcfg.py:

import paramiko
import time
import getpass

username = raw_input(‘Enter your username: ‘)
password = getpass.getpass()

f = open (‘myswitches.txt’)

for line in f:
ip_address = line.strip()
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_client.connect(hostname=ip_address,username=username,password=password)

print ‘Successful connection’, ip_address

remote_connection = ssh_client.invoke_shell()
remote_connection.send(“\x19”)

print ‘Collecting running-config of ‘ + ip_address

remote_connection.send(‘copy running-config tftp address 192.168.1.100 filename ‘ + ip_address + ‘.asc\n’)

time.sleep(20)
readoutput = remote_connection.recv(655350)
saveoutput = open(‘Log file of ‘ + ip_address, ‘w’)

print ‘Saving to file called Log file of ‘ + ip_address + ‘\n’

saveoutput.write(readoutput)
saveoutput.write(‘\n’)
saveoutput.close

ssh_client.close()

Text file Myswitches.txt:

192.168.1.5
192.168.1.4

Output of script:

$ python sshclientcfg.py

Enter your username: admin

Password:

Successful connection 192.168.1.5

Collecting running-config of 192.168.1.5

Saving to file called Log file of 192.168.1.5

Successful connection 192.168.1.4

Collecting running-config of 192.168.1.4

Saving to file called Log file of 192.168.1.4

Note: The log file captured with the IP of the switch shows the output from the session which is useful to verify if it worked as expected or there was an error. The running-config file generated by the switch will be sent to the TFTP server so look there for the ASCII file.

The line below is used to provide Ctrl + Y response if prompted.

remote_connection.send(“\x19”)

 

 

 

Assigning IP to many VLANs with IP and DHCP-Relay

Assumption: VLANs created 1024-2048

Python script to generate config script file (pass1vlanip.py)…

vl_fr = 1024
vl_to = 1278
pass1oct3 = 0
dhcpsrv = “10.10.10.10”
mask = “255.255.255.0”

for value in range (vl_fr,vl_to):
pass1oct3 = pass1oct3 + 1
ipadd = “1.1.” + str (pass1oct3) + “.1”
with open(‘pass1vlanip.cfg’, ‘a’) as outfile:
outfile.write(“\ninterface vlan ” + str (value))
outfile.write(“\nip address ” + str (ipadd) + ” ” + str (mask))
outfile.write(“\nip dhcp-relay”)
outfile.write(“\nexit”)
outfile.write(“\nip dhcp-relay fwd-path ” + str (ipadd) + ” ” + str (dhcpsrv))
outfile.write(“\nip dhcp-relay fwd-path ” + str (ipadd) + ” ” + str (dhcpsrv) + ” enable”)
outfile.write(“\nip dhcp-relay fwd-path ” + str (ipadd) + ” ” + str (dhcpsrv) + ” mode bootp_dhcp”)

Note: Create multiple files for each “pass” with different value in second octet to create batches of class C subnets 254 hosts (pass1vlanip.py, pass2vlanip.py, etc…).

Part of the output file (ie pass1vlanip.cfg):

interface vlan 1024
ip address 1.1.1.1 255.255.255.0
ip dhcp-relay
exit
ip dhcp-relay fwd-path 1.1.1.1 10.10.10.10
ip dhcp-relay fwd-path 1.1.1.1 10.10.10.10 enable
ip dhcp-relay fwd-path 1.1.1.1 10.10.10.10 mode bootp_dhcp
interface vlan 1025
ip address 1.1.2.1 255.255.255.0
ip dhcp-relay
exit
ip dhcp-relay fwd-path 1.1.2.1 10.10.10.10
ip dhcp-relay fwd-path 1.1.2.1 10.10.10.10 enable
ip dhcp-relay fwd-path 1.1.2.1 10.10.10.10 mode bootp_dhcp
interface vlan 1026
ip address 1.1.3.1 255.255.255.0
ip dhcp-relay
exit
ip dhcp-relay fwd-path 1.1.3.1 10.10.10.10
ip dhcp-relay fwd-path 1.1.3.1 10.10.10.10 enable
ip dhcp-relay fwd-path 1.1.3.1 10.10.10.10 mode bootp_dhcp

Rename .cfg file as .run file and move to .acli folder so that ACLI terminal can source the files.

From ACLI login to switch and type @run pass1ip.run which will run the commands created by the python script. This speeds up the process of creating multiple configuration entries such as VLANs, IP addresses, DHCP etc…

Another example script to delete a range of VLANs (delvlan.py):

vl_fr = 1024
vl_to = 2048

for value in range (vl_fr,vl_to):

with open(‘delvlan.cfg’, ‘a’) as outfile:
outfile.write(“\nvlan delete ” + str (value))
value = value + 1
with open(‘delvlan.cfg’, ‘a’) as outfile:
outfile.write(“\nvlan delete ” + str (value))

Output file (delvlan.cfg):

vlan delete 1024
vlan delete 1025
vlan delete 1026
vlan delete 1027
vlan delete 1028

etc…

Rename delvlan.run and type @run delvlan.run in ACLI terminal will remove long list of VLANs and all underlying VLAN configuration such as the IP address and VRRP. Otherwise have to delete each VLAN individually as there is no range parameter.

Lab4 EMC Python: Take Action

from jsonrpc import JsonRPC

def remote_cli(jsonrpc, cmd):
# ###################################################################
# Use the jsonrpc.cli() method to send CLI commands to an IP address
# cmd = a single CLI command string or a list of CLI command strings
# ###################################################################
response = jsonrpc.cli(cmd)

#print json.dumps(response, indent=2, sort_keys=True) # Uncomment for debugging

if isinstance(response, dict):
result = response.get(‘result’)
for entry in result:
#print “Debug: Entry = “, entry # Uncomment for debugging
if ‘status’ in entry and entry.get(‘status’) == ‘ERROR’:
raise RuntimeError(“Command generated error on switch”)

return result

def main():

familyType = emc_vars[‘family’]
switchIpaddress = emc_vars[‘deviceIP’]
switchUsername = emc_vars[‘deviceLogin’]
switchPassword = emc_vars[‘devicePwd’]

if familyType == ‘VSP Series’:
print “This script uses JSON and can only be used with XOS”
raise RuntimeError(“This script will only work on XOS switches”)

# create a JSONRPC interface object with any defaults
jsonrpcObj = JsonRPC(ipaddress=switchIpaddress, username=switchUsername, password=switchPassword)

cmd = ‘show ports description’
result = remote_cli(jsonrpcObj, cmd)

burnPorts = []
for entry in result:
#print “Debug: Entry = “, entry # Uncomment for debugging
if ‘show_ports_description’ in entry:
port = entry.get(‘show_ports_description’).get(‘port’)
name = entry.get(‘show_ports_description’).get(‘displayString’)
print “Debug: Got port {} with name = {}”.format(port, name)
if name == ‘Burn-now’:
burnPorts.append(port)

if burnPorts:
portList = ‘,’.join(str(x) for x in burnPorts)

cmd = ‘disable ports ‘ + portList
remote_cli(jsonrpcObj, cmd)

cmd = ‘unconfigure ports ‘ + portList + ‘ display-string’
remote_cli(jsonrpcObj, cmd)

cmd = ‘enable ports ‘ + portList
remote_cli(jsonrpcObj, cmd)

print “Successfully burned ports: “, portList

else:
print “No ports to burn!”

main()

Lab3 EMC Python: Edit Ports

#@MetaDataStart
#@VariableFieldLabel (description = “Name of action to perform on (s)Witch port ?”,
#                     type = string,
#                     required = yes,
#                     validValues = [Burn-now, Burn-today, Burn-tomorrow, Burn-anyway],
#                     readOnly = no
#                     )
set var witchPort Burn-tomorrow
#@MetaDataEnd

def main():

try:
selectedPorts = emc_vars[‘port’]
except:
selectedPorts = None

if selectedPorts == None:
print “Performed no action as no ports selected on this switch”
return

assignName = emc_vars[‘witchPort’]

familyType = emc_vars[‘family’]

if familyType == ‘VSP Series’:
emc_cli.send(‘enable’)
emc_cli.send(‘config term’)
cmd = ‘interface gigabitEthernet ‘+selectedPorts
emc_cli.send(cmd)
cmd = ‘name “‘+assignName+'”‘
emc_cli.send(cmd)

elif familyType == ‘Summit Series’:
cmd = ‘configure ports ‘+selectedPorts+’ display-string “‘+assignName+'”‘
emc_cli.send(cmd)

else:
raise RuntimeError(“Unexpected switch family type!!”)

print “Successfully configured ports {} with name ‘{}'”.format(selectedPorts, assignName)

main()

Lab2 EMC Python: Contact

import re

def main():

familyType = emc_vars[‘family’]

if familyType == ‘VSP Series’:
showCmd = ‘show sys-info’
result = emc_cli.send(showCmd)
output = result.getOutput()
match = re.search(‘SysLocation  : (.+)’, output)
location = match.group(1)

elif familyType == ‘Summit Series’:
showCmd = ‘show system’
result = emc_cli.send(showCmd)
output = result.getOutput()
match = re.search(‘SysLocation:      (.+)’, output)
location = match.group(1)
else:
raise RuntimeError(“Unexpected switch family type!!”)

print “Switch has location set to :”, location

if location == ‘Castle of Aarrgh’:
manager = ‘King Arthur’
elif location == ‘Bridge of Death’:
manager = ‘Lancelot’
elif location == ‘Castle Anthrax’:
manager = ‘Patsy’
elif location == ‘Swamp Castle’:
manager = ‘Sir Galahad’
else:
raise RuntimeError(“Unexpected location!!”)

if familyType == ‘VSP Series’:
emc_cli.send(‘enable’)
emc_cli.send(‘config term’)
cmd = ‘snmp-server contact “‘+manager+'”‘
elif familyType == ‘Summit Series’:
cmd = ‘configure snmp sysContact “‘+manager+'”‘
else:
raise RuntimeError(“Unexpected switch family type!!”)

emc_cli.send(cmd)

print “Successfully set switch manager to:”, manager

main()

Lab1 EMC Python: Location

def main():

sysName = emc_vars[‘deviceName’]

if sysName == ‘VSP-1’:
location = ‘Castle of Aarrgh’
elif sysName == ‘VSP-2’:
location = ‘Bridge of Death’
elif sysName == ‘XOS-1’:
location = ‘Castle Anthrax’
elif sysName == ‘XOS-2’:
location = ‘Swamp Castle’
else:
raise RuntimeError(“Unexpected switch!!”)

familyType = emc_vars[‘family’]

if familyType == ‘VSP Series’:
emc_cli.send(‘enable’)
emc_cli.send(‘config term’)
cmd = ‘snmp-server location “‘+location+'”‘
elif familyType == ‘Summit Series’:
cmd = ‘configure snmp sysLocation “‘+location+'”‘
else:
raise RuntimeError(“Unexpected switch family type!!”)

emc_cli.send(cmd)

print “Successfully set switch location to:”, location

main()