Ejecutando comandos con Python 2.7.X en una lista de equipos de red. Parte 1: Telnet utilizando libreria pexpect
En esta entrada veremos como ejecutar comandos con Python (2.7.X) utilizando libreria pexpect en una lista de equipos de red, incluyendo la autenticación con el equipo. La libreria pexpect (Python expect) es una libreria que permite ejecutar comandos y "esperar" ('expect') la respuesta entregada por el equipo, y en base a eso detenerse o continuar ejecutando comandos.
Instalacion de librerias
[root@server]# pip install pexpect
Caso: Telnet hacia equipos Cisco
Queremos verificar si en 10 de nuestros equipos Cisco existe la linea con el comando "logging buffered 64000 debugging" en su running-config.
Para esto ejecutaremos el comando 'show run | include logging buffered 64000 debugging' en cada uno de los 10 equipos.
Puede ejecutarse cualquier comando arbitrario cambiando el comando enviado y no existe ninguna limitante en la cantidad de equipos, se utilizan 10 solo como ejemplo.
Script
#!/usr/bin/python import pexpect import sys '''Variables''' # lista de equipos de red (hosts) por DNS (tambien pueden ser IP) equipos =['r1-ciudad1', 'r2-ciudad2', 'r3-ciudad3', 'r4-ciudad4', 'r5-ciudad5', 'r6-ciudad6', 'r7-ciudad7', 'r8-ciudad8', 'r9-ciudad9', 'r10-ciudad10'] # credenciales user = "test_user" password = "pythonnetworker" def worker(): """Funcion que realiza el trabajo""" # para cada host en la lista de equipos for host in equipos: # generamos un telnet hacia el host c = pexpect.spawn ('telnet ' + str(host)) # definimos que la salida del comando la imprima en terminal c.logfile = sys.stdout print "Verificar en equipo %s" % host # al conectar telnet esperamos que el equipo entregue la linea Username c.expect(['Username:'], timeout=2000) # si es asi le enviamos el usuario c.sendline(user) # si el equipo entrega la linea Password c.expect('Password:') # enviamos el password c.sendline(password) i = c.expect(['Username:', '#']) # si equipo no devuelve el string esperado salir del script if i==0: sys.exit(0) # enviamos el comando deseado cmd = 'show run | include logging buffered 64000 debugging\r' c.sendline(cmd) # rescatamos salida, si comando se completa continuar c.expect('#') # enviar logout para continuar con siguiente host cmd = 'logout' c.sendline(cmd) # llamamos a la funcion worker worker()
Salida
De la salida del script anterior podemos ver que los routers de ciudades 2, 5, 7 ,8 ,9 no tienen el comando esperado "logging buffered 64000 debugging"
[test_user@localhost blog]$ python script_telnet.py
Verificar en equipo r1-ciudad1
Trying 10.20.16.6...
Connected to r1-ciudad1.
Escape character is '^]'.
Router Admin
User Access Verification
Username: test_user
test_user
Password: pythonnetworker
R1-ciudad1#show run | include logging buffered 64000 debugging
show run | include logging buffered 64000 debugging
logging buffered 64000 debugging
R1-ciudad1#logout
Verificar en equipo r2-ciudad2
Trying 10.20.16.70...
Connected to r2-ciudad2.
Escape character is '^]'.
CRouter adminCCRouter Admin
User Access Verification
Username: test_user
test_user
Password: pythonnetworker
r2-ciudad2#show run | include logging buffered 64000 debugging
show run | include logging buffered 64000 debugging
r2-ciudad2#
logout
Verificar en equipo r3-ciudad3
Trying 10.20.16.2...
Connected to r3-ciudad3.
Escape character is '^]'.
Cadmin-router
User Access Verification
Username: test_user
test_user
Password: pythonnetworker
r3-ciudad3#show run | include logging buffered 64000 debugging
show run | include logging buffered 64000 debugging
logging buffered 64000 debugging
r3-ciudad3#logout
Verificar en equipo r4-ciudad4
Trying 10.20.16.50...
Connected to r4-ciudad4.
Escape character is '^]'.
Router Admin
User Access Verification
Username: test_user
test_user
Password: pythonnetworker
r4-ciudad4#show run | include logging buffered 64000 debugging
show run | include logging buffered 64000 debugging
logging buffered 64000 debugging
r4-ciudad4#logout
Verificar en equipo r5-ciudad5
Trying 10.20.16.234...
Connected to r5-ciudad5.
Escape character is '^]'.
User Access Verification
Username: test_user
test_user
Password: pythonnetworker
r5-ciudad5#show run | include logging buffered 64000 debugging
show run | include logging buffered 64000 debugging
r5-ciudad5#logout
Verificar en equipo r6-ciudad6
Trying 172.27.10.253...
Connected to r6-ciudad6.
Escape character is '^]'.
User Access Verification
Username: test_user
test_user
Password: pythonnetworker
r6-ciudad6#show run | include logging buffered 64000 debugging
show run | include logging buffered 64000 debugging
logging buffered 64000 debugging
r6-ciudad6#logout
Verificar en equipo r7-ciudad7
Trying 10.20.16.26...
Connected to r7-ciudad7.
Escape character is '^]'.
User Access Verification
Username: test_user
test_user
Password: pythonnetworker
r7-ciudad7#show run | include logging buffered 64000 debugging
show run | include logging buffered 64000 debugging
r7-ciudad7#logout
Verificar en equipo r8-ciudad8
Trying 10.20.16.154...
Connected to r8-ciudad8.
Escape character is '^]'.
CRouter Admin
User Access Verification
Username: test_user
test_user
Password: pythonnetworker
r8-ciudad8#show run | include logging buffered 64000 debugging
show run | include logging buffered 64000 debugging
r8-ciudad8#logout
Verificar en equipo r9-ciudad9
Trying 10.20.16.62...
Connected to r9-ciudad9.
Escape character is '^]'.
CRouter Admin
User Access Verification
Username: test_user
test_user
Password: pythonnetworker
r9-ciudad9#show run | include logging buffered 64000 debugging
show run | include logging buffered 64000 debugging
r9-ciudad9#logout
Verificar en equipo r10-ciudad10
Trying 10.20.16.46...
Connected to r10-ciudad10.
Escape character is '^]'.
Router Admin
User Access Verification
Username: test_user
test_user
Password: pythonnetworker
r10-ciudad10#show run | include logging buffered 64000 debugging
show run | include logging buffered 64000 debugging
logging buffered 64000 debugging
r10-ciudad10#logout
[test_user@localhost blog]$
Como podemos ver la salida es un poco confusa debido a que esta tal como lo entrega libreria pexpect. Para solucionar esto, podemos hacer que el expect espere el comando especifico de salida, e imprimir un string de acuerdo a si lo encuentra o no. De todas formas en entradas del blog posteriores veremos como utilizar expresiones regulares para rescatar y filtrar la salida de los comandos.
Saludos!


Comentarios
Publicar un comentario