Cisco IOS-XE et RESTCONF / YANG

RESTCONF (RFC 8040) fournit une interface de programmation basée sur des mécanismes standard pour accéder aux données de configuration et d’état, mais aussi pour accéder aux opérations et événements RPC spécifiques au modèle de données défini dans le modèle YANG.

RESTCONF peut être vu comme un sous-ensemble de NETCONF qui expose les modèles YANG au travers d’une API REST (URL) à l’aide d’un transport HTTP ou HTTPS avec un encodage XML ou JSON. Il faut rappeler que RESTCONF ne supporte pas toutes les opérations NETCONF qui peuvent aller plus loin dans la granularité. Il faut également noter que RESTCONF ne gère pas de session, chaque requête possède toutes les informations nécessaires à son traitement. Les opérations supportées par le protocole RESTCONF sont les suivantes :

  • GET – Récupère les données d’une ressource (config / opérationnel).
  • POST – Crée une ressource de données de configuration.
  • PUT – Crée ou remplace une ressource de données de configuration.
  • PATCH – Fusionne les données de configuration avec une ressource cible.
  • DELETE – Supprime une ressource de données de configuration.

Un des outils le plus évolué pour manipuler RESTCONF est Postman. Avec son interface graphique, il permet de construire un ensemble de requêtes de manière organisée et évoluée pour tester les URLs et leurs comportements. L’authorization est passée avec les « headers », au même titre que le format de données XML ou JSON avec lequel on souhaite travailler (« application/yang-data+xml » ou « application/yang-data+json »).

https://192.168.1.98:443/restconf/data/netconf-state/capabilities

Postman IOS-XE RESTCONF
Postman

L’outil Postman, aidé des fonctionnalités de développeur du navigateur web, permet d’analyser tout le dialogue HTTP, avec ses différentes composantes.

HTTP dialogue

L’analyse des capabilities montre trois types de modèles YANG qui traitent des interfaces, deux modèles standards que sont OpenConfig et IETF et un modèle « Vendor Specific » libellé Cisco-IOS-XE. Les trois syntaxes sont proposées ci-dessous. Il est intéressant de constater que les modules OpenConfig et Cisco-IOS-XE proposent plus d’information que le module IETF.

https://192.168.1.98:443/restconf/data/ietf-interfaces:interfaces

https://192.168.1.98:443/restconf/data/openconfig-interfaces:interfaces

https://192.168.1.98:443/restconf/data/Cisco-IOS-XE-interfaces-oper:interfaces

Sur la base du module OpenConfig, voici des syntaxes pour récupérer des informations spécifiques concernant l’interface GigabitEthertnet1.

https://192.168.1.98:443/restconf/data/openconfig-interfaces:interfaces/interface=GigabitEthernet1/config/description

https://192.168.1.98:443/restconf/data/openconfig-interfaces:interfaces/interface=GigabitEthernet1/state/counters/in-octets

De la même façon, il est possible d’utiliser l’opération PATCH, une URL spécifique et une syntaxe dans le « body » pour effectuer une modification d’information sur l’interface GigabitEthernet1.

https://192.168.1.98:443/restconf/data/openconfig-interfaces:interfaces/interface=GigabitEthernet1

{
    "openconfig-interfaces:interface": {
        "config": {
            "description": "EVE-NG Management Interface"
        }
    }
}

Postman possède une fonction appelée « code » qui permet de générer un morceau de programme, associé à la requête construite, dans le langage de programmation souhaité. Cette fonction fait gagner beaucoup de temps pour élaborer un programme Python.

Code Postman
Génération du code associé à la requête
#!/usr/bin/env python
import requests
from urllib3 import disable_warnings
from urllib3.exceptions import InsecureRequestWarning


url = "https://192.168.1.98:443/restconf/data/openconfig-interfaces:interfaces/interface=GigabitEthernet1"
payload = """
{
    "openconfig-interfaces:interface": {
        "config": {
            "description": "EVE-NG Management Interface"
        }
    }
}
"""
headers = {
    'Accept': 'application/yang-data+json',
    'Content-Type': 'application/yang-data+json',
    'Authorization': 'Basic Y2lzY286Y2lzY28='
}

if __name__ == '__main__':
    # disable InsecureRequestWarning
    disable_warnings(InsecureRequestWarning)
    try:
        response = requests.request(
            "PATCH", url, headers=headers, data=payload, verify=False)
        print(response)
    except requests.exceptions.RequestException as e:
        raise SystemExit(e)

Après exécution, la réponse à ce programme Python est <Response [204]>, ce qui indique que la requête a réussi mais qu’aucune information n’avait à être retournée. On notera que la partie « authorization » est passée dans le header avec une syntaxe indiquant le type d’authentification suivi du username:password encodé en Base64.

Une vérification sur la configuration IOS-XE permet de voir que la description a été modifiée sur l’interface GigabitEthernet1.