En los posts anteriores sobre RESTCONF me concentré en explicar la forma de realizar configuraciones sobre un dispositivo de red. En RESTCONF: Una guía práctica de uso buscamos la forma de traducir comandos CLI a transacciones vía RESTCONF.
El objetivo de el post de hoy es seguir ahondando en el uso de RESTCONF, pero buscando traer información del estado operacional del dispositivo. Como no vamos a realizar cambios, el método a usar será exclusivamente GET. Vamos a repasar algunos módulos para traer información común de red (estado de interfaces, tablas, etc).


Herramientas Utilizadas

Para trabajar con RESTCONF, mis herramientas de trabajo son:

  • Postman, para realizar peticiones a los equipos sin tener que escribir scripts.
  • Python3.6 con la librería “requests”.
  • Pyang, para explorar los modelos de YANG
  • Un editor de código, Visual Studio Code por ejemplo.
  • Un laboratorio con al menos un equipo con IOS-XE. Se puede utilizar los CSRv disponibles en DevNet con este fin.

Módulo “ietf-interfaces”

Con este módulo estándar podemos traer información del estado de las interfaces en el dispositivo. Con pyang podemos ver que tiene dos contenedores:

El contenedor “interfaces” nos permite configurar las interfaces, mientras que “interfaces-state” trae estado operacional de las mismas. En este último nos vamos a enfocar.
Como siempre, la URI a usar se compone del módulo y el contenedor. En este caso:

GET https://<IP:Puerto>/restconf/data/ietf-interfaces:interfaces-state/interface

Nota: “/interface” al final no es estrictamente necesario, pero al ser el único elemento dentro del contenedor (ver output de pyang) podemos usarlo para reducir un nivel la profundidad de la respuesta.

Una consulta a dicha URI nos trae la información mostrada a continuación. Para destacar, tenemos el estado operacional de cada interfaz, su dirección física, y estadísticas de tráfico entrante/saliente.

Nota: se borraron algunas interfaces por brevedad.

Si quisiéramos filtrar la consulta a una interfaz específica, modificamos la URI para traer la información deseada (reemplazando <INTERFACE-NAME> por el nombre de la interfaz deseada).

GET https://<IP:Puerto>/restconf/data/ietf-interfaces:interfaces-state/interface=<INTERFACE-NAME>

Nota: nótese que el identificador de la interfaz es “name”, esto está indicado en el modelo YANG. Si se hace una revisión del resultado del árbol creado por pyang anteriormente, se puede ver claramente el identificador entre corchetes a la derecha del contenedor.

+--ro interface* [name]

Nota 2: al escribir el nombre de la interfaz en la URI el mismo debe codificarse. En particular el símbolo “/” se transforma en “%2F”. Por lo tanto, “GigabitEthernet0/1” se codifica como “GigabitEthernet0%2F1”.


Módulo “ietf-routing”

El módulo “ietf-routing” es otro módulo estándar. Con él podemos obtener información de enrutamiento de los dispositivos, como por ejemplo la FIB de cada VRF o los protocolos de enrutamiento utilizados. Al igual que como sucedía con “ietf-interfaces” que el módulo tiene dos contenedores, uno para configuración (“routing”) y otro para estado (“routing-state”). Esto podemos verlo con pyang:

Dentro de “routing-state” vamos a encontrar una lista de “routing-instance”. Cada “routing instance” es una VRF, y podemos identificarla con su nombre.
La URI básica para usar el contenedor es la siguiente:

GET https://<IP:Puerto>/restconf/data/ietf-routing:routing-state/routing-instance

Nota: al igual que con “ietf-interfaces”, indicar “/routing-instance” al final de la URI no es necesario si no se va a filtrar.

Debido a la longitud de la respuesta sin filtrar, preferí no incluirla. En cambio, veamos algunos filtros útiles usando este contenedor: información por VRF, tabla de enrutamiento y búsqueda prefijo específico.

Filtrado por VRF

Como el nombre de la VRF es el identificador de cada routing instance, es facil filtrar. La URI sería (reemplazando <VRF-NAME> por el nombre de la VRF):

GET https://<IP:Puerto>/restconf/data/ietf-routing:routing-state/routing-instance=<VRF-NAME>

En el siguiente ejemplo se trae la información de una VRF llamada Dummy para mostrar la respuesta. Puede verse que para dicha VRF se detallan las interfaces que pertenecen a la misma, las RIB (IPv4 e IPv6) y los protocolos de enrutamiento configurados.

Ver tabla de enrutamiento

A partir de la respuesta a la consulta del ejemplo anterior se puede ver que si en la URI se sigue la ruta específica “/ribs/rib” podemos obtener la tabla de enrutamiento. En el output de pyang para el módulo “ietf-routing” podemos notar que se puede usar el nombre de la RIB para filtrar cada una de ellas.
De esta forma tenemos las URIs para las RIBs IPv4 e IPv6 (podemos traer ambas en una consulta única eliminando el filtro):

GET https://<IP:Puerto>/restconf/data/ietf-routing:routing-state/routing-instance=<VRF-NAME>/ribs/rib=ipv4-default
GET https://<IP:Puerto>/restconf/data/ietf-routing:routing-state/routing-instance=<VRF-NAME>/ribs/rib=ipv6-default

Dado que la respuesta es un subgrupo de la vista en el ejemplo anterior, no la vuelvo a copiar aquí para mantener el post lo más conciso posible.

Información de un prefijo específico

Podemos ir un paso más allá y traer un prefijo de la RIB (ya sea IPv4 o IPv6). Siguiendo la lógica del ejemplo anterior y revisando lo que obtuvimos con pyang se deduce que hay que llegar a la lista “ribs/rib/routes/route”. En esta lista el identificador es el prefijo en notación CIDR. Para más claridad, en este caso uso un ejemplo para entender la URI. Buscamos el prefijo 172.16.0.0/16 dentro de la tabla IPv4 de la VRF “Dummy”

GET https://<IP:Puerto>/restconf/data/ietf-routing:routing-state/routing-instance=Dummy/ribs/rib=ipv4-default/routes/route=172.16.0.0%2F16

Nota: %2F es el carácter “/” codificado para poder ser pasado en la URI. Por lo tanto “172.16.0.0/16” se convierte en “172.16.0.0%2F16”.

Nota 2: si el prefijo exacto no existe en la tabla de enrutamiento, obtendremos un error 404 comp status code de la respuesta.


Módulo “Cisco-IOS-XE-interfaces-oper”

El módulo nativo de Cisco equivalente a “ietf-interfaces” es “Cisco-IOS-XE-interfaces-oper”. Este módulo trae un poco más de información respecto a las interfaces de red. En la misma respuesta agrega información de la configuración actual de las interfaces: VRF, IPs, MTU, etc.
Es una alternativa al modelo estándar, que tiene la contrapartida que sólo es soportado por equipos Cisco. Se puede aplicar la misma lógica que en los demás módulos para filtrar y traer distintos campos. Se deja la URI base para quienes deseen probarlo:

GET https://<IP:Puerto>/restconf/data/Cisco-IOS-XE-interfaces-oper:interfaces

Nota: recomiendo a quienes quieran usar el módulo estudiarlo primero con pyang para entender la estructura.


Módulo “Cisco-IOS-XE-fib-oper”

Veamos ahora brevemente un equivalente nativo al módulo “ietf-routing”, o al menos a una parte del mismo. “Cisco-IOS-XE-fib-oper” trae la información de las FIB del dispositivo. Lo que no tendremos en este módulo es información de los protocolos de enrutamiento en cada VRF, como sucedía en el módulo estándar. En el caso de los modelos nativos, la información operacional de los distintos protocolos de enrutamiento se encuentran en módulos diferentes (existe uno por protocolo).
Para quienes lo necesiten usar, la URI es la siguiente:

GET https://<IP:Puerto>/restconf/data/Cisco-IOS-XE-fib-oper:fib-oper-data

Nota: recomiendo a quienes quieran usar el módulo estudiarlo primero con pyang para entender la estructura.


Otros módulos

Como referencia dejo otros módulos que podrían ser de interés. Recuerden que los módulos deben ser soportados por la release de IOS-XE a utilizar. En el caso de Cisco, los módulos de variables operacionales terminan en “-oper”. Por lo tanto, pueden revisar aquí los módulos existentes por release (en cada versión suelen agregarse nuevos).

  • Cisco-IOS-XE-arp-oper trae información de la tabla ARP del router por VRF.
    • GET https://<IP:puerto>/restconf/data/Cisco-IOS-XE-arp-oper:arp-data
  • Cisco-IOS-XE-ip-sla-oper información sobre IP SLAs.
    • GET https://<IP:puerto>/restconf/data/Cisco-IOS-XE-ip-sla-oper:ip-sla-stats
  • Cisco-IOS-XE-nat-oper información sobre NAT.
    • GET https://<IP:puerto>/restconf/data/Cisco-IOS-XE-nat-oper:nat-data
  • Cisco-IOS-XE-ospf-oper toda la información referida a los procesos de OSPF. Existen módulos similares para BGP y EIGRP.
    • GET https://<IP:puerto>/restconf/data/Cisco-IOS-XE-ospf-oper:ospf-oper-data

El parámetro “fields”

Aunque podemos filtrar los campos útiles en el script desde donde estemos realizando las llamadas, cuando las consultas traen una cantidad muy grande de información podemos elegir qué campos incluir en la respuesta. Para esto, en el RFC 8040 define el parámetro “fields”. Podemos incluir este parámetro para reducir la cantidad de información recibida. Voy a concluir este post con algunos ejemplos de su uso.

Si queremos traer nodos específicos dentro de la respuesta, los indicamos en el parámetro “fields” separados por “;”. Por ejemplo, para traer solo el nombre y el estado operacional de las interfaces, podemos modificar la URI de la consulta como sigue:

GET https://<IP:Puerto>/restconf/data/ietf-interfaces:interfaces-state/interface?fields=name;oper-status

Una consulta a esta URI y nos devuelve algo como lo siguiente:

Pero ahora, ¿y si queremos filtrar por campos que están dentro de otro contenedor en el modelo YANG? Para esto navegamos el camino relativo usando “/” como separador. Por ejemplo, los errores entrantes de una interfaz están identificados con el campo “in-errors” dentro del campo “statistics” cuando se usa el módulo “ietf-interfaces”. Si queremos traer este conteo de errores para la interfaz GigabitEthernet1, podemos armar una URI como la que se muestra a continuación:

GET https://<IP:Puerto>/restconf/data/ietf-interfaces:interfaces-state/interface=GigabitEthernet1?fields=statistics/in-errors

El resultado es la siguiente respuesta:

Además, si se desea traer más de un nodo hijo, en lugar de usar “/” podemos indicarlos entre paréntesis como muestra el ejemplo a continuación (separados cada nodo con “;”). En el ejemplo, se desea obtener en la respuesta tanto los errores entrantes como los salientes de la interfaz GigabitEthernet1:

GET https://<IP:Puerto>/restconf/data/ietf-interfaces:interfaces-state/interface=GigabitEthernet1?fields=statistics(in-errors;out-errors)

Combinación de los campos anteriores

En el último ejemplo no era necesario especificar la interfaz. El parámetro funciona sobre todas las interfaces como se puede ver en el primer ejemplo. Pero por lo menos en IOS-XE 16.9.3 no funciona en combinación con otros campos. Por ejemplo, la siguiente URI no funciona como se espera (debería traer nombre y errores, pero trae toda la información).

GET https://<IP:Puerto>/restconf/data/ietf-interfaces:interfaces-state/interface?fields=statistics/in-errors;name

No es tan útil el resultado del último ejemplo entonces sin filtrar por interfaz, ya que al no poder incluir el nombre se hace difícil luego la identificación de cada interfaz.


Hasta aquí el post de hoy. Para el próximo, algunas operaciones sobre el dispositivo usando RESTCONF. Cualquier duda o sugerencia se pueden contactar conmigo en los comentarios o vía email (o Twitter).

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *