Tables et vues avec Junos Pyez

(Nayan Gadre) (12 septembre 2020)

Ce sont des notes créées pendant travailler avec la bibliothèque Junos pyez pour lautomatisation du réseau. Junos fournit des tables et des vues pour définir et extraire des données de configuration personnalisées. Tout le code pyez et ncclient est open source sous licence Apache 2.0

Vous définissez une table et une vue dans un fichier Yaml au lib / jnpr / junos / ressources
telles que «  user.yml  » et son correspondant fichier du chargeur en tant que «  user.py  »

user.yml
user.py

Le » user.py « est utilisé pour convertir les définitions Table et View du fichier yaml en éléments de dictionnaire global de python. Ici \_\_file \_\_ pointe vers le «  user.py  » qui sera. puis être converti en nom de fichier « user.yml ». Le loadyaml de junos pyez convertira alors le «  user.yml « dans un dictionnaire pour lajouter au dictionnaire globals () .

Les définitions de table et de vue dans le yaml sont convertis en classes en python. loadyaml est une méthode dusine et est exposée en tant quAPI publique à laide de \_\_ all \_\_ déclaration pythonique. Il fournit un dictionnaire de définitions de nom délément et de classe délément comme on peut le voir dans laccrochage dune ligne.

Le fichier user.yml est divisé en 2 clés de niveau supérieur: «  UserTable  » et «  UserView  » donc le loadyaml renverra 2 classes avec ces noms.

dictionnaire converti à partir du dictionnaire user.yml

Ce dictionnaire est transmis à FactoryLoader.load ( ) pour générer des classes:

FactoryLoader (). load (yaml.load (open (path, “r”), Loader = yaml.FullLoader))

Le but de la classe Factory Loader

La méthode items () des dictionnaires r et renvoie un objet de vue qui contient une liste de tuples contenant des paires clé-valeur.

La façon dont le chargeur dusine décide si la table et le schéma de vue fournis sont destinés à la configuration ou aux opérations se fait via les clés présentes dans le schéma . Par exemple: «  set  » et «  get  » en ferait une table de configuration,
«  rpc  » alors cest une opération table, «  commande  » ou «  title  » alors cest une table de commandes, il y a aussi une combinaison déroutante de «  item  » «  view « et » * « qui dicte également sil sagit dune table de commandes.

Puisque nous nous concentrons sur le «  user.yml  » nous pouvons voir quil « est une table de configuration, car il a un » set  » dans sa hiérarchie. Par conséquent, nous allons remplir le \_item\_cfgtables avec le UserTable clé.

Il sagit de la fonction de générateur de classe pour générer la classe de table pour les tables de type de configuration.

La classe Table contient une référence à la classe View, doù sil y a une vue définie dans la section table, nous allons créer une classe pour cette vue en utilisant la méthode \_build\_view () et définir la classe comme valeur de la clé « view ».

La méthode du dictionnaire get () , permet de définir une valeur par défaut si la clé nest pas présente , ici la clé «  view\_name  » sera absente, donc la \_build\_view ( view\_name ) créera une classe et associera la classe en tant que valeur au view\_name clé. Il extraira également les groupes, eval, champs et les stockera dans les champs internes des objets de vue.

Nous allons dabord vérifier comment le conteneur CFGTABLE est créé à \_CFGTBL
\_CFGTBL = FactoryCfgTable

Python vous permet pour créer des classes ou des types dynamiques à laide de la méthode «  type « .
Si «  type « est passé un objet existant, il renvoie son type. Cependant, si «  type  » reçoit 3 arguments, «  nom de classe « , » tuple de base « , » dict « puis il renvoie une nouvelle classe. Il existe également une méthode «  vars « , qui renvoie \_\_dict\_\_ , qui stocke les attributs inscriptibles des objets. Python crée dautres classes en utilisant des métaclasses.

Nous pouvons passer le nom de la classe dont la nouvelle classe héritera comme un seul tuple: Par exemple: new\_cls = type (nom\_table, (CfgTable,), {})

Si «  set ”mot-clé est présent sous la section Table:
par exemple: set: system / login / user
Nous devons donc également passer la classe de base de configuration pour créer notre classe UserTable:
Par exemple: new\_cls = type (nom\_table, (CfgTable, Config), {})

champs qui sont automatiquement renseignés dans la classe

Une fois la classe est créé, nous lajouterons au catalogue des classes factoryLoader: self.catalog [table\_name] = cls

Passons maintenant à la construction de la classe de vue:

view\_name = tbl\_dict [ » view « ]
tbl\_dict [ » view « ] = self.catalog.get (view\_name, self.\_build\_view (view\_name))

Le view\_name défini dans le fichier «  user.yml  » est «  userView « .

Enfin, » load ”Va renvoyer un catalogue de classes créées par la classe FactoryLoader .

Pour résumer le chemin:

Cela complète juste une partie où le yml est converti en classes qui peuvent ensuite être utilisées pour fonctionner. Ensuite, nous commençons par créer un objet de notre classe UserTable.

user\_table = UserTable (dev)

Depuis le UserTable hérite de CfgTable et les classes de base Config, nous hériterons du constructeur et de toutes les méthodes définies dans ces classes de base. Dès que nous créons un nouvel objet UserTable , il appelle le \_\_init\_\_ des classes parentes. Puisque « set » est mentionné dans le fichier yml, nous appellerons également le constructeur de config classe de base.

Ensuite, appelez la méthode get () pour récupérer les données de configuration pour hiérarchie système / login / utilisateur .
Nous vérifierons dabord loption namesonly = false .

Rappelez-vous que la hiérarchie de lexpression xpath était déjà définie via set: system / login / user Instruction » user.yml « . Une fonction \_build\_xml traduit cela en un fichier. XML comme ci-dessous:

Si lutilisateur a spécifié un nom dutilisateur spécifique, appelé «  namekey « , nous avons besoin pour linsérer dans le xml généré ci-dessus. Par exemple: get (user = ”regress”) insérerait lélément de nom avec la valeur regress:

regress

tout est emballé dans get\_cmd et envoyé à self.RPC.get\_config (get\_cmd)
Un XML typique- RPC ressemble à ceci ci-dessous:

format de lappel de méthode XML RPC XML

Notre XML pour obtenir les informations utilisateur ressemble à ceci:

Ce XML-RPC est converti en requête HTTP POST et envoyé au serveur: exécute un XML RPC et renvoie les résultats au format XML ou python natif

Lappel rpc réel est effectué via la méthode rpc de ncclient via ssh pour que les données soient chiffrées.

La gestion RPC de le rpc\_cmd\_e est. fait par ncclient qui fournit limplémentation de netconf sur ssh. Il deviendra difficile de comprendre où la méthode rpc dans lobjet Manager () du package ncclient est réellement définie. Après avoir étudié la bibliothèque ncclient, jai trouvé quelle est définie comme un dictionnaire de méthodes avec «rpc» = ExecuteRpc , et ce dictionnaire est spécifique au fournisseur. Cliquez ici pour en savoir plus .

Cette opération complète de nommage du dictionnaire est créée pour chaque demande de connexion basée sur le fournisseur et renvoyée.

Le RPC XML final envoyé sur le serveur ssh aussi netconf sur lappareil Junos

Un rapide résumé du lancement et de léchange de session netconf:

Le client doit initier une connexion netconf au port 830 sur ssh. Le serveur doit envoyer son message HELLO tout de suite, et le client doit également faire de même. Lensemble du message bonjour > spécifie les capacités du client et du serveur. Le serveur doit alors attendre de traiter toutes les requêtes rpc > et doit envoyer un rpc-reply >. Le client peut ajouter autant dattributs XML à lélément rpc > quil le souhaite, et le Le serveur retournera tous ces attributs dans lélément rpc-reply >.

La réponse est analysée, pour ok > et rpc-error > balises indiquant aucune / aucune erreur. Ensuite, il est transformé dans un format dépendant de lappareil / du fournisseur, supprimez les balises despace de noms, etc.

La réponse est finalement reçue comme suit:

[(regress, [(user, regress), (uid, 928), (class\_name, superuser), (password, abc123 @ # $ # $ ^)])]