Introducción a Teuton

per Victor Carceler darrera modificació 2020-10-19T12:49:55+01:00

240px-Ruby_logo.svg.pnghttps://github.com/teuton-software/teutonEn la pasada edición del FOSDEM tuve el placer de conocer a David Vargas autor de Teuton. Teuton es una magnífica herramienta para hacer tests de infraestructura que permite corregir de manera automática las máquinas configuradas por los alumnos durante las prácticas. Además, si el profesor así lo desea, puede copiar el informe resultante de los tests en las máquinas de los alumnos para que ellos mismos puedan corregir los errores detectados.

Estos días he comenzado a utilizar Teuton en el aula y puedo decir que su instalación y configuración es extremadamente sencilla. Y que durante la formación del alumno, contar con una herramienta que de manera continua comprueba el trabajo realizado y le proporciona un informe al alumno resulta una gran ayuda para su progreso.

Sobre Teuton

Teuton es una herramienta GPLv3 programada en Ruby así que se trata de una herramienta multiplataforma. En el modo de uso básico que he comenzado utilizar basta con instalarla en una máquina que controle el profesor (el ordenador del aula o una máquina virtual) y no necesita ningún agente ni configuración en los ordenadores de los alumnos. Únicamente utiliza SSH para conectar con las máquinas en las que se pasarán los tests.

El listado de alumnos con sus máquinas y credenciales se definen en un fichero YAML y los tests se escriben en un fichero Ruby en el que (en el uso básico que estoy haciendo) para cada test se especifica:

  • El comando a ejecutar en la máquina remota.
  • La salida esperada para dar por válido el test.

Cuando se lanza Teuton comienza a realizar los tests en paralelo en todas las máquinas definidas y proporciona un informe con el resumen de los resultados al profesor. Además guarda en un fichero diferente por alumno el informe detallado y opcionalmente copia este informe en una de las máquinas del alumno.

Yo planeo utilizar Teuton de dos maneras diferentes:

  1. Durante la formación de los alumnos ejecuto Teuton en un bucle del shell cada 5 segundos y copio el informe en la máquina del alumno. Así el alumno tiene una guía de los tests que ya cumple su práctica y aquellos que todavía no los cumple, pudiendo trabajar de manera autónoma.
  2. Durante la evaluación el alumno deberá seguir el enunciado de la actividad sin tener acceso a los informes de Teuton para que no se dedique a cumplir únicamente con los apartados comprobados y se centre en el enunciado. Finalmente una sola ejecución de Teuton valorará la actividad y copiará el informe en las máquinas de los alumnos.

Instalación de Teuton

La instalación de Teuton en una máquina nueva se realiza en dos sencillos pasos:

  1. La instalación de Ruby
    # apt update
    # apt install ruby
  2. La instalación de Teuton
    # gem install teuton

Después ya no es necesario trabajar como administrador y todos los usuarios de la máquina tendrán acceso al comando teuton.

Pero en todos los ordenadores del centro los playbooks de Ansible que utilizamos ya han instalado Ruby de manera que cada usuario puede instalar Teuton localmente con el siguiente comando:

$ gem install --user-install teuton

En este caso la instalación se realiza en $HOME/.gem así es que el usuario deberá añadir a su fichero ~/.bashrc la siguiente línea:

export PATH=$PATH:~/.gem/ruby/2.7.0/bin

Con lo que ya tendrá disponible el comando teuton.

usuario@laika:~$ teuton 
Commands:
  teuton [run] [OPTIONS] DIRECTORY  # Run challenge from directory
  teuton check [OPTIONS] DIRECTORY  # Test or check challenge contents
  teuton help [COMMAND]             # Describe available commands or one specific command
  teuton new DIRECTORY              # Create skeleton for a new project
  teuton readme DIRECTORY           # Create README.md file from challenge contents
  teuton version                    # Show the program version

usuario@laika:~$

Nuevo proyecto: tests sobre el servicio DHCP

He comenzado a utilizar Teuton en el aula con actividades sobre el DHCP, en concreto para repasar el trabajo que realizan los alumnos al preparar dos máquinas virtuales:

  • Un servidor DHCP con isc-dhcp-server.
  • Un cliente del servidor anterior.

El enunciado de la actividad es: https://elpuig.xeill.net/Members/vcarceler/smx-m07/actividades/teuton/dhcp-a1

Cada una de las MVs tendrá una interfaz de red en modo puente con IP fija para que Teuton pueda acceder a la máquina.

En el ordenador del profesor el primer paso será crear un nuevo proyecto:

usuario@laika:~$ teuton new dhcp-a1

[INFO] Creating dhcp-a1 project skeleton
* Create dir        => dhcp-a1
* Create file       => dhcp-a1/config.yaml
* Create file       => dhcp-a1/start.rb
usuario@laika:~$

Lo que definirá un directorio en el cual se encuentran el fichero de configuración (dhcp-a1/config.yaml) y la definición de los tests (dhcp-a1/start.rb).

Fichero dhcp-a1/config.yaml

En nuestro centro se utiliza una subred 192.168.X.0/24 diferente en cada aula. Por ejemplo al aula Torvalds le corresponde la subred 192.168.10.0/24. Los ordenadores del aula comienzan en la IP 192.168.X.100 y en el caso del aula Torvalds, que tiene 24 ordenadores, acaban en 192.168.10.123. El servidor DHCP del centro asigna IPs a clientes desconocidos desde 192.168.10.124 hasta 192.168.10.200.

Normalmente pido a los alumnos que pongan en sus máquinas virtuales las IPs 192.168.10.200+X o 192.168.10.225+X siendo X su número de lista.

Se puede consultar la configuración del servidor DHCP del centro en: https://github.com/vcarceler/cirdan-dhcp/blob/master/dhcpd.conf

Con todo esto se puede definir la siguiente configuración para Teuton:

---
:global:
  :host1_username: usuario
  :host1_password: usuario
  :host2_username: usuario
  :host2_password: usuario
:cases:
- :tt_members: student3
  :host1_ip: 192.168.10.203
  :host2_ip: 192.168.10.228

- :tt_members: student4
  :host1_ip: 192.168.10.204
  :host2_ip: 192.168.10.229


- :tt_members: student6
  :host1_ip: 192.168.10.206
  :host2_ip: 192.168.10.231
  

- :tt_members: student8
  :host1_ip: 192.168.10.208
  :host2_ip: 192.168.10.233
  

- :tt_members: student10
  :host1_ip: 192.168.10.210
  :host2_ip: 192.168.10.235
  

- :tt_members: student11
  :host1_ip: 192.168.10.211
  :host2_ip: 192.168.10.236
  

- :tt_members: student12
  :host1_ip: 192.168.10.212
  :host2_ip: 192.168.10.237
  

- :tt_members: student13
  :host1_ip: 192.168.10.213
  :host2_ip: 192.168.10.238
  

- :tt_members: student14
  :host1_ip: 192.168.10.214
  :host2_ip: 192.168.10.239
  

- :tt_members: student15
  :host1_ip: 192.168.10.215
  :host2_ip: 192.168.10.240
  

- :tt_members: student17
  :host1_ip: 192.168.10.217
  :host2_ip: 192.168.10.241
  

- :tt_members: student18
  :host1_ip: 192.168.10.218
  :host2_ip: 192.168.10.243
  

- :tt_members: student19
  :host1_ip: 192.168.10.219
  :host2_ip: 192.168.10.244
  

- :tt_members: student20
  :host1_ip: 192.168.10.220
  :host2_ip: 192.168.10.245
  

Como todos los alumnos utilizan el mismo usuario y contraseña en sus máquinas se pueden definir en la sección global. Pero si cada estudiante tiene su propio usuario y contraseña se podría definir en el listado de casos. El campo tt_members es descriptivo y host1_ip, host2_ip son las direcciones de las dos máquinas del alumno.

Fichero dhcp-a1/start.rb

En este fichero se configuran:

  1. Cada uno de los tests a realizar indicando:
    • Descripción del test
    • Comando a ejecutar
    • Máquina en la que se ejecuta el comando host1 o host2 en este caso
    • Resultado esperado
  2. Secuencia de trabajo. en este caso:
    • show: Muestra los resultados en el terminal
    • export: Deja los informes detallados en var/dhpc-a1/
    • send :copy_to => :host1 Copia el informe en el host1 del alumno
group "Comprobaciones sobre el servicio DHCP" do

  target "DHCP: Comprobar hostname"
  run "hostname", on: :host1
  expect "dhcp"

  target "DHCP: Comprobar IP en enp0s8"
  run "ip address show dev enp0s8", on: :host1
  expect "172.16.0.1/16"

  target "DHCP: Comprobar gateway"
  run "ip route | grep default", on: :host1
  expect "192.168.10.10"

  target "DHCP: Comprobar DNS"
  run "networkctl status enp0s3 | grep DNS", on: :host1
  expect "192.168.10.10"

  target "DHCP: isc-dhcp-server instalado"
  run "apt show isc-dhcp-server", on: :host1
  expect "APT-Manual-Installed: yes"

  target "DHCP: subnet 172.16.0.0"
  run "cat /etc/dhcp/dhcpd.conf | grep subnet", on: :host1
  expect "subnet 172.16.0.0 netmask 255.255.0.0"

  target "DHCP: pool de clientes"
  run "cat /etc/dhcp/dhcpd.conf | grep range", on: :host1
  expect "range 172.16.250.0 172.16.255.254;"

  target "DHCP: host-name"
  run "cat /etc/dhcp/dhcpd.conf | grep host-name", on: :host1
  expect "option host-name \"cliente\";"

  target "CLIENT: Check IP"
  run "ip address show dev enp0s8", on: :host2
  expect "172.16.250.0/16"

  target "CLIENT: Comprobar gateway"
  run "ip route | grep default", on: :host2
  expect "172.16.0.1"

  target "CLIENT: Comprobar DNS"
  run "networkctl status | grep DNS", on: :host2
  expect "192.168.10.10"

  target "CLIENT: Comprobar NTP"
  run "networkctl status | grep NTP", on: :host2
  expect "192.168.10.10"

  target "CLIENT: Comprobar dominio de búsqueda"
  run "networkctl status | grep Search", on: :host2
  expect "clientes.test"

  target "CLIENT: Acceso a Internet"
  run "ping -c 1 -w 1 8.8.8.8 | grep '1 packets'", on: :host2
  expect "1 packets transmitted, 1 received"

end

play do
  show
  export
  send :copy_to => :host1
end

Ejecución de los tests

Se pueden lanzar los tests con el comando:

teuton dhcp-a1

Que presentará un informe con los resultados de los alumnos:

CASE RESULTS
+------+-----------+-------+-------+
| CASE | MEMBERS | GRADE | STATE |
| 01 | student3 | 29.0 | ? |
| 02 | student4 | 29.0 | ? |
| 03 | student6 | 36.0 | ? |
| 04 | student8 | 50.0 | |
| 05 | student10 | 21.0 | ? |
| 06 | student11 | 50.0 | |
| 07 | student12 | 50.0 | |
| 08 | student13 | 36.0 | ? |
| 09 | student14 | 29.0 | ? |
| 10 | student15 | 50.0 | |
| 11 | student17 | 0.0 | ? |
| 12 | student18 | 29.0 | ? |
| 13 | student19 | 36.0 | ? |
| 14 | student20 | 0.0 | ? |
+------+-----------+-------+-------+

Además de dejar los informes detallados en el directorio var/dhcp-a1

vcarceler@torvalds-100:~$ ls var/dhcp-a1/
case-01.txt case-03.txt case-05.txt case-07.txt case-09.txt case-11.txt case-13.txt moodle.csv
case-02.txt case-04.txt case-06.txt case-08.txt case-10.txt case-12.txt case-14.txt resume.txt
vcarceler@torvalds-100:~$

Y de copiar el informe correspondiente en la primera máquina de cada alumno.