MODELES D’AUTOMATISATION YANG ET YAML

MODELES D’AUTOMATISATION YANG ET YAML

YANG : DEFINITION

Yang est un langage de configuration et de modélisation de données d’état. L’IETF’S net mod a établi le langage de modélisation yang comme norme. Autrement dit, le langage Yang ressemble davantage à un arbre qu’à un élément. Lors du stockage des paramètres, les données de configuration sont organisées sous forme d’arbre.

Cet arbre peut regrouper divers types de données, notamment des listes et des unions. Les modules contiennent les définitions, et chaque module peut compléter l’arbre dans un autre module. Il existe des règles strictes établies pour la modification des modules. Yang peut être traduit d’un format d’encodage à un autre, par exemple en XML ou JSON.

MODELES LIBRES & NATIFS

Il existe deux types de modèles : Open et Native. Des équipes différentes travaillent sur chacun d’eux.

Les modèles open permettent de configurer les périphériques réseau de manière standard, quel que soit le fournisseur qui les fabrique. Les fournisseurs et les organismes de normalisation tels l’IETF, l’UIT et OpenConfig créent des modèles Open YANG.
Les fournisseurs eux-mêmes créent des modèles native. Ils se focalisent sur les caractéristiques et les configurations propres à une plate-forme particulière et sont construits explicitement pour servir d’interface avec elles.

LES ÉLEMENTS CONSTITUTIFS DE YANG

CONTAINER
MODULE
LISTE
FEUILLE
TYPE

Un conteneur est une succession d’informations organisée logiquement. Il peut s’agir d’un conteneur de configuration et d’un conteneur d’état, par exemple.

De multiple listes sont possibles à l’intérieur d’un seul conteneur.
Entendez menu d’options disponibles. Les éléments de la liste sont liés entre eux par une clé.
Notre liste comprend le mot « feuille ». Protéger et stocker toutes nos informations personnelles.
Pour chaque feuille, il existe un type de données particulier auquel elle appartient.

LE DÉPLOIEMENT DU YANG

Les nœuds feuilles peuvent être définis à l’aide de l’une des deux instructions YANG : la feuille ou la liste de feuilles. Un nœud feuille n’a qu’une seule instance, tandis qu’un nœud de liste de feuilles peut en avoir plusieurs.

				
					
leaf enable {
       type Boolean;
       default true;
}
				
			
Les nœuds non-feuilles peuvent être spécifiés en utilisant les instructions conteneur et liste de YANG. Les nœuds de type conteneur n’ont qu’une seule instance, tandis que les nœuds de type liste peuvent avoir un nombre quelconque d’instances (les entrées de la liste sont identifiées par des clés qui les distinguent les unes des autres)
				
					container timeout {
       leaf access-timeout {
             type uint16;
             }
       leaf retries {
             type uint8;
             }
}
				
			
Le type adresse IP, par exemple, est défini comme l’union de deux types dérivés supplémentaires :
				
					
typedef ip-address {
       type union {
             type ipv4-address;
             type ipv6-address;
             }
}
				
			

Un nœud de choix ne peut sélectionner qu’un seul choix à la fois dans un ensemble de choix. Les cas de sous-instructions définissent les branches d’un arbre de décision. L’arbre de données ne comporte que les nœuds d’une seule branche de choix (le nœud de choix lui-même n’existe pas dans l’arbre de données).

				
					
choice route-distinguisher {
       case ip-address-based {
             leaf ip-address {
                    type ipv4-address;
                    }
             leaf ip-address-number {
                    type uint16;
                    }
             }
       case asn32-based {
             leaf asn32 {
                    type uint32;
             }
             leaf two-byte-number {
                    type uint16;
             }
}
				
			

Un regroupement identifie un ensemble de nœuds qui peuvent être réutilisés. Un regroupement de terminaux avec deux nœuds feuilles est défini ici

				
					grouping endpoint {
       leaf address {
             type ip-address;
             }
       leaf port {
             type port-number;
             }
}
				
			

L’instruction « use » permet de transférer les nœuds indiqués par une définition de groupement d’un autre arbre de schéma dans l’arbre de schéma actuel. Ainsi, nous pouvons par exemple recourir au groupement endpoint pour définir la source et la destination de la connexion :

				
					container connection {
       container source {
             uses endpoint {
                    refine port {
                          default 150;
                          }
                    }
             }
       container destination {
             uses endpoint {
                    refine port {
                          default 150;
                          }
                    }
             }
}
				
			

Si vous utilisez l’instruction « must », vous exprimez les exigences auxquelles chaque nœud de la structure doit répondre avant d’être considéré comme valide. Pour exprimer les contraintes « must », nous utilisons des

expressions XPath. Une expression non-192. * ou non-127. * L’adresse IP du réseau est modélisée comme suit :

				
					
leaf mirrorIp {
       type ip-address;
       default 0.0.0.0;
             must “false() = starts-with(current(), ‘192’)” {
                    error-message “The mirrorIp is in the forbidden “+
                          “192.* network”;
                    }
             must “false() = starts-with(current(), ‘127’)” {
                    error-message “The mirrorIp is in the occupied “+
                          “127.* network”;
                    }
}
				
			

Yang au service des réseaux

Yang au service de Cisco

Cisco IOS XR prend en charge les modèles de données pour configurer et collecter les données opérationnelles d’un périphérique réseau de manière programmatique. Ils se substituent au processus de configuration manuel propriétaire et essentiellement basé sur le texte. Les modèles de données sont écrits et publiés dans un langage défini par l’industrie pour automatiser les tâches de configuration et récupérer les données opérationnelles des périphériques réseau hétérogènes.

Bien que les configurations CLI soient plus simples, l’automatisation de la configuration à l’aide d’une capacité de programme orienté modèle permet d’atteindre une échelle plus importante. L’utilisation d’une approche orientée modèle pour la programmation des périphériques offre aux développeurs un cadre convivial mais puissant. Un dispositif IOS XR peut être interfacé avec plusieurs options de transport, de protocole et de codage grâce à ce cadre. Pour une meilleure adaptabilité, ces options ont été dissociées des modèles.

NETCONF (Network Configuration Protocol)

Une application s’exécutant sur une plate-forme d’administration intégrée peut requérir des données de configuration ou de fonctionnement structurées selon la norme YANG via NETCONF, qui fournit le transport permettant de connecter le dispositif OEM. Un utilisateur peut concevoir ou solliciter des données de fonctionnement en programmation XML (Extensible Markup Language). Si une partie de la requête de configuration échoue, l’ensemble de la requête de configuration est annulée. Il s’agit là de l’un des services contractuels qu’il fournit.

Il utilise une méthode intégrée RPC (Remote Procedure Call) pour faciliter l’interaction client-serveur (commutateur ou routeur Cisco). Secure Shell (SSH) reste la couche de transmission entre les périphériques réseau. Quelques exemples de tâches NETCONF sont les suivants : Get, get-config, edit-config et RPC.

LES MODELES YANG AU SERVICE DES PLATEFORMES CISCO

De ce fait, la navigation dans l’arbre n’aura jamais été aussi conviviale. L’objectif est d’automatiser la création de ces éléments et d’éliminer la nécessité de les générer manuellement

				
					$ pyang -f tree openconfig-vlan.yang

module: openconfig-vlan

   +--rw vlans

      +--rw vlan* [vlan-id]

         +--rw vlan-id    -> ../config/vlan-id

         +--rw config

         |  +--rw vlan-id?   oc-vlan-types:vlan-id

         |  +--rw name?      string

         |  +--rw status?    enumeration

         |  +--rw tpid?      identityref

         +--ro state

         |  +--ro vlan-id?   oc-vlan-types:vlan-id

         |  +--ro name?      string

         |  +--ro status?    enumeration

         |  +--ro tpid?      identityref

         +--rw members

            +--ro member*

               +--ro interface-ref

                  +--ro state

                     +--ro interface?      -> /oc-if:interfaces/interface/name

                     +--ro subinterface?   -> /oc-if:interfaces/interface[oc-if:name=current()/../interface]/subinterfaces/subinterface/index

augment /oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface:

   +--rw vlan

      +--rw config

      |  +--rw vlan-id?   union

      +--ro state

         +--ro vlan-id?   union

augment /oc-if:interfaces/oc-if:interface/oc-eth:ethernet:

   +--rw switched-vlan

      +--rw config

      |  +--rw interface-mode?   oc-vlan-types:vlan-mode-type

      |  +--rw native-vlan?      union

      |  +--rw access-vlan?      union

      |  +--rw trunk-vlans*      union

      +--ro state

         +--ro interface-mode?   oc-vlan-types:vlan-mode-type

         +--ro native-vlan?      union

         +--ro access-vlan?      union

         +--ro trunk-vlans*      union

augment /oc-if:interfaces/oc-if:interface/oc-lag:aggregation:

   +--rw switched-vlan

      +--rw config

      |  +--rw interface-mode?   oc-vlan-types:vlan-mode-type

      |  +--rw native-vlan?      union

      |  +--rw access-vlan?      union

      |  +--rw trunk-vlans*      union

      +--ro state

         +--ro interface-mode?   oc-vlan-types:vlan-mode-type

         +--ro native-vlan?      union

         +--ro access-vlan?      union

         +--ro trunk-vlans*      union

augment /oc-if:interfaces/oc-if:interface:

   +--rw routed-vlan

      +--rw config

      |  +--rw vlan?   union

      +--ro state

         +--ro vlan?   union
				
			

YAML : DÉFINITION

Initialement, le surnom de YAML, attribué par les créateurs du projet, était « Yet Another Markup Language » Toutefois, au fil du temps, l’acronyme a évolué en « YAML Ain’t a MarkUp language ». YAML est un acronyme récursif car il se rapporte à lui-même. Le langage YAML peut être utilisé pour stocker des données et des paramètres sous une forme facilement assimilable par les utilisateurs. La courbe d’apprentissage de YAML est relativement faible. Il est facile à suivre et à comprendre, grâce à ses constructions simples.

Les créateurs de YAML voulaient ainsi résoudre les difficultés liées à la compréhension d’autres langages de balisage, qui sont plus difficiles à appréhender que YAML. Nous nous basons toujours sur un projet pratique pour rendre l’apprentissage plus commode. Le présent projet est hébergé sur GitHub sous une licence MIT, ce qui le rend libre d’accès pour quiconque souhaite apporter des modifications et envoyer un pull request.

LES AVANTAGES DU YAML

CRÉATION D’UN FICHIER YAML

Les règles suivantes sont fondamentales dans la création d’un fichier YAML :

YAML est doté d’une disposition de clavier qui n’est pas sensible à la casse.
Il ne doit pas y avoir de tabulation dans ces fichiers car les YAML sams n’autorisent pas les tabulations lors de la création de fichiers YAML.

YAML ASSOCIÉ À ANSIBLE

Les processus informatiques peuvent être orchestrés à l’aide de playbooks Ansible. Chaque système possède un ou plusieurs playbooks, et ces playbooks sont utilisés pour définir l’état souhaité de celui-ci. Chaque play peut exécuter une ou plusieurs tâches, chaque tâche faisant appel à un module Ansible différent. Dans Ansible, les tâches d’automatisation sont exécutées au moyen de modules. Tout langage capable de renvoyer du JSON peut créer des modules Ansible, notamment Ruby, Python et bash.

Les cartes et les listes constituent un playbook Ansible. Les listes YAML peuvent générer des playbooks en créant d’abord une liste avec le nom du play, puis en listant toutes les fonctions du play une par une dans la liste.

				
					---

- name: Update web servers

  hosts: webservers

  remote_user: root

 

  tasks:

  - name: Ensure apache is at the latest version

    ansible.builtin.yum:

      name: httpd

      state: latest

  - name: Write the apache config file

    ansible.builtin.template:

      src: /srv/httpd.j2

      dest: /etc/httpd.conf

 

- name: Update db servers

  hosts: databases

  remote_user: root

 

  tasks:

  - name: Ensure postgresql is at the latest version

    ansible.builtin.yum:

      name: postgresql

      state: latest

  - name: Ensure that postgresql is started

    ansible.builtin.service:

      name: postgresql

      state: started
				
			

Rappelez-vous que l’indentation n’indique pas nécessairement un ordre d’héritage logique. Supposez que chaque ligne représente un type de données YAML (une liste ou une carte). Les utilisateurs d’Ansible peuvent automatiser des activités répétitives à l’aide de modèles YAML, éliminant ainsi la nécessité d’apprendre un langage de programmation complexe.

De haut en bas, un playbook suit un ensemble d’instructions. De même, les tâches de chaque play sont exécutées dans l’ordre chronologique, en commençant par le haut et en progressant vers le bas. Pour les installations multi-machines, les playbooks comportant plusieurs « plays » peuvent exécuter un play sur vos serveurs Web, un autre sur vos serveurs de base de données, puis le troisième sur votre infrastructure réseau.

YAML ASSOCIÉ À CISCO

Le modèle YANG et les noms des fichiers de configuration YAML sont envoyés à un script Python 1 send yaml.py. Pour envoyer la configuration à l’appareil, il crée d’abord une instance de la classe YdkModel, puis exécute l’action de création. Les données de configuration YAML suivantes sont stockées dans un fichier BGP.yaml, tel qu’indiqué dans l’exemple :

				
					+++

router:

  bgp:

    - id: 100

      bgp:

        router_id: 1.1.1.1

        fast_external_fallover: null

        update_delay: 15

      neighbor:

        - id: 2.2.2.2

          remote_as: 200

        - id: 3.3.3.3

          remote_as: 300

      redistribute:

        connected: {}
				
			

Par conséquent, sur un appareil IOS XE, la configuration ressemblerait à ceci:

				
					router bgp 100

 bgp router-id 1.1.1.1

 bgp log-neighbor-changes

 bgp update-delay 15

 redistribute connected

 neighbor 2.2.2.2 remote-as 200

 neighbor 3.3.3.3 remote-as 300
				
			
Facebook
Twitter
LinkedIn