¿Cómo instalar PyATS en Ubuntu Linux? Empezando el Viaje
Introducción
Python Automated Test Systems mejor conocido por sus siglas PyATS, es una infraestructura de automatización de pruebas basada en Python 3. Se desarrolló como la infraestructura de automatización de pruebas interna de Cisco. Luego Cisco decidió liberarla al público como un proyecto Open Source para que usuarios y clientes que demandaban este tipo de soluciones pudieran sacarle provecho. Actualmente es compatible con las herramientas e infraestructura existentes y cuenta con el respaldo oficial del equipo ejecutivo de Cisco.
Aunque este sistema fue desarrollado por Cisco principalmente para equipos de su marca, también se puede adaptar a otros fabricantes. Cisco oficialmente ha desarrollado módulos para trabajar con equipos Juniper, pero yo personalmente también he adaptado mis pruebas a equipos Huawei.
En este tutorial de varios que estaremos desarrollando sobre PyATS, aprenderemos a como instalarlo y dar los pasós más básicos para hacer un Script de Pruebas funcional. Veremos lo fácil que es de instalar y rápido de poner en marcha.
Paso #1 – Instalación de Dependencias
Según la documentación oficial de PyATS, este actualmente es compatible con Python v3.5.x, v3.6.xy v3.7.x. Las recientes versiones de Ubuntu vienen con Python3 instalado por lo que es posible que no tengas que instalarlo. Para validar si tienes Python3 instalado en tu Ubuntu con una de las versiones soportadas por PyATS se puede ejecutar este comando:
python3 -V
La salida debería ser similar a esta:
Python 3.6.9
En caso de que no tengas Python3 o la versión compatible, puedes instalar Python3 desde los repositorios de Ubuntu ejecutando:
#Actualizar lista de repositorios
sudo apt-get update
#Si deseas instalar la versión 3.6 de Python
sudo apt-get install python3.6
#o si deseas instalar la versión 3.7 de Python
sudo apt-get install python3.7
Otra importante dependencia, es tener instalado el administrador de paquetes Python llamado PIP3. Para instalar PIP3 puedes ejecutar el siguiente comando:
sudo apt-get install python3-pip
Ya estamos listo para instalar PyATS.
Paso #2 – Instalación de PyATS
PyATS es un sistema de herramientas unificadas y este te permite instalar los módulos de PyATS que quieras instalar. En nuestro caso vamos a instalarlo FULL, con todos sus módulos y opciones.
pip3 install pyats[full]
Se descargaran todas las librerías y módulos necesarios para su funcionamiento. Esto puede tomar alrededor de un minuto o más dependiendo de la velocidad de tu conexión a Internet.
Valida la instalación de PyATS y sus módulos ejecutando el comando el comando:
pyats version check
La salida debería ser similar a esta:
You are currently running pyATS version: 20.5 Python: 3.6.9 [64bit] Package Version
genie 20.5 genie.libs.clean 20.5 genie.libs.conf 20.5 genie.libs.filetransferutils 20.5 genie.libs.ops 20.5 genie.libs.parser 20.5
genie.libs.robot 20.5 genie.libs.sdk 20.5 genie.telemetry 20.5 genie.trafficgen 20.5 pyats 20.5 pyats.aereport 20.5 pyats.aetest 20.5 pyats.async 20.5
pyats.connections 20.5 pyats.contrib 20.5 pyats.datastructures 20.5 pyats.easypy 20.5 pyats.kleenex 20.5 pyats.log 20.5 pyats.reporter 20.5
pyats.results 20.5 pyats.robot 20.5 pyats.tcl 20.5 pyats.topology 20.5 pyats.utils 20.5 unicon 20.5 unicon.plugins 20.5
Paso #3 – Describe el Testbed(Banco de Pruebas)
PyATS está diseñado en torno al concepto de Testbed(bancos de pruebas), donde describes sus equipos bajo prueba en formato YAML.
A continuación vamos a ver un ejemplo sencillo que te permitirá construir tu propio Testbed en formato YAML. Este ejemplo describe dos routers Cisco con el sistema operativo IOS.
#Ejemplo #coding_networks_ios_testbed.yaml # #Variables globales del Testbed. Como credenciales para #acceder a los equipos testbed: name: coding_networks_ios_testbed credentials: default: username: codingnetworks password: cisco enable: password: cisco #Definicion de los equipos devices: ios1: # <----- debe ser igual al nombre del hostname os: ios type: ios connections: vty: protocol: ssh ip: 192.168.56.11 ios2: os: ios type: ios connections: vty: protocol: ssh ip: 192.168.56.12 #Definicion de la topologia. Como se interconectan los equipos. topology: ios1: interfaces: Gi0/1: ipv4: 172.17.10.1/30 link: link-ios1-ios2 type: ethernet ios2: interfaces: Gi0/1: ipv4: 172.17.10.1/30 link: link-ios1-ios2 type: ethernet
Lo llamativo del Testbed en formato YAML es que es muy fácil de leer y entender lo que se está definiendo en su estructura. De todos modos aunque el código es auto explicativo dejé algunos comentarios para aclarar dudas que pueden surgir.
Guardemos el código construido bajo el nombre “coding_networks_ios_testbed.yaml”.
Paso #4 – Conectate a los equipos y valida su funcionalidad ejecutando comandos
En este paso vamos a probar lo configurado en el archivo .yaml y validar que podemos conectarnos a los equipos y ejecutar comandos.
Usaremos modo interactivo de Python para realizar esta prueba e ingresar cada uno de los comandos aquí mostrados. Para iniciar el modo interactivo de Python ejecutar el siguiente comando en el prompt:
python3
#Carga el archivo .yaml en un objeto llamado testbed
from pyats.topology import loader
testbed = loader.load('coding_networks_ios_testbed.yaml')
Si al ejecutar estos comandos no se presenta ningún error, significa que la estructura dentro del archivo coding_networks_ios_testbed.yaml está bien definida. En cambio, si presenta algún error, este nos dirá en cuales línea de código encontró los errores.
#Vamos a acceder a los dos routers ios1 = testbed.devices['ios1']
ios1.connect() ios2 = testbed.devices['ios2'] ios2.connect()
Estos comandos ejecutados nos permiten separar los routers en los objetos ios1 y ios2. Al correr el método “.connect()” iniciamos sesión en los equipos. Veremos que en la pantalla se arrojan información del Log in a los equipos.
Es momento de que ejecutemos algunos comandos y ver los resultados:
#Ejecutemos algunos comandos
print(ios1.execute('show version'))
print(ios2.execute('show version'))
print(ios1.execute('show interface desc'))
print(ios2.execute('show interface desc'))
Si todo ha salido bien, veremos en pantalla la salida de los comandos enviados. Con esto ya podemos decir que estamos listo para diseñar el script de pruebas.
Paso #5 – Diseña tu script de pruebas
PyATS se trata de pruebas; y la piedra angular absoluta en las pruebas es el script de prueba real. En pyATS, los scripts de prueba se escriben y ejecutan a través del módulo AEtest.
Los scripts de prueba son archivos estructurados de Python que contienen y describen las pruebas que deseas realizar. Un script de prueba limpio y elegante es escalable y genera resultados y registros de prueba fáciles de leer.
Veamos a continuación un script de prueba en el que vamos a probar la conectividad entre los dos routers utilizando el comando ping.
# Ejemplo. Este ejemplo es una modificacion del ejemplo que se encuentra # en la documentacion oficial de PyATS # ------- # # connectivity_check.py from pyats import aetest import re, logging #crear un logger para este modulo logger = logging.getLogger(name) class CommonSetup(aetest.CommonSetup): @aetest.subsection def check_topology(self, testbed, ios1_name = 'ios1', ios2_name = 'ios2'): ios1 = testbed.devices[ios1_name] ios2 = testbed.devices[ios2_name] # Agregar los objetos de los routers a los parametros de TestScript self.parent.parameters.update(ios1 = ios1, ios2 = ios2) # Obtener los enlaces de interconexion entre ios1 y ios2 links = ios1.find_links(ios2) assert len(links) >= 1, 'requiere un enlace entre ios1 y ios2' @aetest.subsection def establish_connections(self, steps, ios1, ios2): with steps.start('Conectando a %s' % ios1.name): ios1.connect() with steps.start('Conectando a %s' % ios1.name): ios2.connect() @aetest.loop(device=('ios1', 'ios2')) class PingTestcase(aetest.Testcase): @aetest.test.loop(destination=('172.17.10.1', '172.17.10.2')) def ping(self, device, destination): try: result = self.parameters[device].ping(destination) except Exception as e: self.failed('Ping {} from device {} failed with error: {}'.format( destination, device, str(e), ), goto = ['exit']) else: match = re.search(r'Success rate is (?P<rate>\d+) percent', result) success_rate = match.group('rate') logger.info('Ping {} with success rate of {}%'.format( destination, success_rate, ) ) class CommonCleanup(aetest.CommonCleanup): @aetest.subsection def disconnect(self, steps, ios1, ios2): with steps.start('Desconectando a %s' % ios1.name): ios1.disconnect() with steps.start('Desconectando a %s' % ios2.name): ios2.disconnect() if __name__ == '__main__': import argparse from pyats.topology import loader parser = argparse.ArgumentParser() parser.add_argument('--testbed', dest = 'testbed', type = loader.load) args, unknown = parser.parse_known_args() aetest.main(**vars(args))
Paso #6 – Corre tu Script de Pruebas
Con nuestro script escrito y guardado, puedo ejecutarlo desde la línea de comandos:
$ python3 connectivity_check.py --testbed coding_networks_ios_testbed.yaml
Al correr el comando anterior la prueba correrá y veremos en pantalla el detalle de todo lo que sucede. Al final veremos un reporte del resultado de la prueba indicando si Pasó o Falló.
Esta es la forma más rápida de ver el script de prueba en acción: todo se imprime directamente en la pantalla, para que pueda editar, ejecutar, editar y volver a ejecutar hasta que la prueba se ajuste a la perfección.
Paso #7 – Crear un Job
Un Job es un paso anterior simplemente ejecutando pruebas de script como ejecutables y obteniendo resultados en STDOUT. Los archivos de trabajo permiten la ejecución de scripts de prueba como tareas en un entorno de tiempo de ejecución estandarizado, lo que permite que los scripts de prueba se ejecuten en serie o en paralelo, y agrega sus registros y resultados en un formato más manejable.
# Example: coding_networks_ios_job.py # ------------------- # # Un archivo Job en su forma mas simple para correr el codigo anterior. from pyats.easypy import run def main(): # La funcion run, ejecuta un script de prueba como una tarea individual. run('connectivity_check.py')
Para iniciar un Job, se utiliza el comando “pyats”. El plugin manejador de los Testbeds utiliza el argumento –testbed-file, para cargar el archivo .yaml y lo analiza automáticamente.
Cuando se inicia, cada scriptcript llamado por la API run () dentro del trabajo se ejecuta como un proceso secundario, y el contenido dentro de su bloque if __name__ == ‘__main__’ se ignora. Agregue el argumento –html-logs para permitir la generación de archivos de registro HTML; son más fáciles de leer.
bash$ pyats run job coding_networks_ios_job.py --testbed-file coding_networks_ios_testbed.yaml --html-logs --liveview-host 192.168.56.56 --liveview-port 8080
La salida es muy parecida a cuando ejecutamos el script utilizando el comando Python3. Sin embargo, vía un Job, de manera predeterminada, los resultados de un Job son guardados una carpeta comprimida que contiene archivos que describen el entorno de tiempo de ejecución, lo que se ejecutó, los archivos XML de resultados y los archivos de registro.
Toda esta información la podemos ver vía un navegador web en formato HTML utilizando el siguiente comando:
$ pyats logs view
Salida:
Logfile: /home/codingnetworks/.pyats/archive/20-Jun/coding_networks_ios_job.2020Jun21_16:35:11.778120.zip
View at:
http://localhost:62118/
Press Ctrl-C to exit
Continua aprendiendo
Ya ahora comprendes los componentes básicos de pyATS. Esto es solo el comienzo, existen muchas más funciones en pyATS para explorar. En la página de Developer Cisco podrán encontrar mas información sobre PyATS .
Si tienen preguntas o dudas sobre lo que vieron en este post o sobre lo que encuentren en la documentación oficial, comenten debajo y con gusto aclararemos sus dudas.