Utiliser Junos Snapshot Administrator en Python (JSNAPy) dans les playbooks Ansible
Exécutez des tests JSNAPy dans le cadre d’un playbook Ansible pour capturer et auditer les instantanés de l’environnement d’exécution des équipements Junos.
® Junos Snapshot Administrator in Python (JSNAPy) vous permet de capturer et d’auditer les instantanés de l’environnement d’exécution de vos équipements Junos. Vous pouvez capturer et vérifier la configuration et l’état opérationnel d’un appareil, et vérifier les modifications apportées à un appareil. Juniper Networks fournit un module Ansible que vous pouvez utiliser pour exécuter des tests JSNAPy sur des équipements Junos dans le cadre d’un playbook Ansible. Le Tableau 1 présente les modules disponibles.
|
Collecte |
Ensemble de modules |
Nom du module |
|---|---|---|
|
|
Vous devez installer Junos Snapshot Administrator en Python sur le nœud de contrôle Ansible pour utiliser le juniper.device.jsnapy module. Pour obtenir des instructions d’installation et des informations sur la création de fichiers de configuration et de test JSNAPy, reportez-vous à l’administrateur d’instantanés Junos dans la documentation Python.
Les sections suivantes expliquent comment utiliser le module dans les juniper.device.jsnapy playbooks Ansible.
Présentation du module
Le juniper.device.jsnapy module vous permet d’exécuter des fonctions JSNAPy à partir d’un playbook Ansible, notamment :
-
Capture et enregistrement d’un instantané de l’environnement d’exécution
-
Comparaison de deux instantanés
-
Capturer un instantané et l’évaluer immédiatement
Le module nécessite de spécifier l’argument action et soit l’argument, soit l’argument config_file test_files . L’argument action spécifie l’action JSNAPy à effectuer. Le Tableau 2 présente les valeurs valides action et les commandes JSNAPy équivalentes.
|
|
Descriptif |
Commande JSNAPy équivalente |
|---|---|---|
|
|
Comparez deux instantanés existants en fonction des cas de test donnés ou, si aucun cas de test n’est fourni, comparez les instantanés nœud par nœud. |
|
|
|
Prenez des instantanés pour les commandes ou RPC spécifiés dans les fichiers de test après avoir apporté des modifications sur les équipements concernés. |
|
|
|
Prenez des instantanés pour les commandes ou RPC spécifiés dans les fichiers de test avant d’apporter des modifications sur les équipements concernés. |
|
|
|
Prenez des instantanés des commandes ou des RPC spécifiés dans les fichiers de test et évaluez-les immédiatement par rapport à des critères prédéfinis dans les cas de test. |
|
Lorsque vous exécutez JSNAPy sur la ligne de commande, JSNAPy exécute l’action demandée sur les hôtes spécifiés hosts dans la section du fichier de configuration. Le module Ansible, quant à lui, exécute l’action demandée sur les hôtes spécifiés dans le playbook Ansible. Par conséquent, le module peut soit référencer un fichier de configuration, en ignorant la hosts section, soit référencer directement un ou plusieurs fichiers de test.
Ainsi, en plus de l’argument action , le juniper.device.jsnapy module a également besoin de l’argument config_file ou de l’argument test_files pour spécifier le fichier de configuration JSNAPy ou les fichiers de test JSNAPy à utiliser pour l’action donnée. Le Tableau 3 présente les config_file arguments et test_files .
|
Argument Module |
Valeur |
Informations complémentaires |
|---|---|---|
|
|
Chemin d’accès absolu ou relatif à un fichier de configuration JSNAPy. |
Si le chemin est relatif, le module vérifie le fichier de configuration aux emplacements suivants et dans l’ordre indiqué :
Si le fichier de configuration fait référence à des fichiers de test à l’aide d’un chemin de fichier relatif, le module vérifie d’abord les fichiers de test dans le répertoire du playbook. Il vérifie ensuite les fichiers de test dans le répertoire par défaut |
|
|
Chemin d’accès absolu ou relatif à un fichier de test JSNAPy. Il peut s’agir d’un chemin d’accès à un seul fichier ou d’une liste de chemins d’accès à des fichiers. |
Pour chaque fichier de test qui spécifie un chemin relatif, le module vérifie le fichier aux emplacements suivants et dans l’ordre indiqué :
|
Les config_file arguments et test_files peuvent prendre un chemin de fichier absolu ou relatif. Lorsque vous utilisez un chemin de fichier relatif, vous pouvez éventuellement inclure l’argument dir module pour spécifier le répertoire dans lequel résident les fichiers. Si un config_file argument ou test_files utilise un chemin de fichier relatif, le module vérifie d’abord le fichier dans le répertoire du playbook Ansible, même si l’argument dir est présent. Si le fichier n’existe pas dans le répertoire playbook, le module vérifie dans le dir répertoire argument, s’il est spécifié, ou dans le répertoire /etc/jsnapy/testfiles , si l’argument dir est omis. Le playbook génère un message d’erreur si le fichier est introuvable.
Il est important de noter que lorsque vous incluez le dir paramètre, le module vérifie cet emplacement uniquement pour l’argument ou test_files spécifiéconfig_file. Ainsi, lorsque vous spécifiez un fichier de configuration, le module ne vérifie pas le dir répertoire pour les fichiers de test que vous spécifiez dans le fichier de configuration. Si le fichier de configuration fait référence à des chemins relatifs pour les fichiers de test, le module vérifie les fichiers de test uniquement dans le répertoire du playbook et dans le répertoire par défauttestfiles.
Supposons que vous ayez le fichier de configuration JSNAPy suivant, jsnapy_config_base_tests.yaml, qui réside dans le répertoire ~/jsnapy/testfiles et référence plusieurs fichiers de test JSNAPy :
user@ansible-cn:~/ansible$ cat ~/jsnapy/testfiles/jsnapy_config_base_tests.yaml tests: - system_util_baseline.yaml - verify_ldp_neighbors.yaml - verify_ospf_neighbors.yaml - verify_bgp_neighbors.yaml - test_interface_operstate.yaml
L’exemple de playbook suivant exécute l’action snap_pre pour chacun des fichiers de test dans le fichier de configuration jsnapy_config_base_tests.yaml . Si le fichier de configuration n’existe pas dans le répertoire du playbook, le module vérifie le fichier dans le dir répertoire, qui dans ce cas est ~/jsnapy/testfiles. Le fichier de configuration utilise des chemins relatifs pour les fichiers de test. Par conséquent, le module vérifie d’abord les fichiers de test dans le répertoire playbook, puis vérifie les fichiers de test dans le répertoire testfiles par défaut.
---
- name: Junos Snapshot Administrator tests
hosts: dc1a
connection: local
gather_facts: no
tasks:
- name: Take a pre-maintenance snapshot
juniper.device.jsnapy:
action: "snap_pre"
dir: "~/jsnapy/testfiles"
config_file: "jsnapy_config_base_tests.yaml"
jsnapy Le module peut également utiliser le test_files paramètre pour spécifier les fichiers de test individuels à utiliser. Le playbook suivant exécute les mêmes tests que dans l’exemple de playbook précédent. Dans ce cas, le module vérifie d’abord les fichiers de test dans le répertoire playbook, puis vérifie les fichiers de test dans le dir répertoire.
---
- name: Junos Snapshot Administrator tests
hosts: dc1a
connection: local
gather_facts: no
tasks:
- name: Take a pre-maintenance snapshot
juniper.device.jsnapy:
action: "snap_pre"
dir: "~/jsnapy/testfiles"
test_files:
- system_util_baseline.yaml
- verify_ldp_neighbors.yaml
- verify_ospf_neighbors.yaml
- verify_bgp_neighbors.yaml
- test_interface_operstate.yaml
À partir de Junos Snapshot Administrator dans Python version 1.3.0, l’emplacement par défaut des fichiers de configuration et de test est ~/jsnapy/testfiles. Toutefois, l’emplacement par défaut dans un environnement virtuel ou pour les versions antérieures est /etc/jsnapy/testfiles.
Le module effectue l’action demandée sur les hôtes spécifiés dans le playbook Ansible, même s’il fait référence à un fichier de configuration qui inclut une hosts section. Le module signale un échec s’il rencontre une erreur et ne parvient pas à exécuter les tests JSNAPy. Il ne signale pas les échecs si un ou plusieurs des tests JSNAPy échouent. Pour vérifier les résultats du test JSNAPy, enregistrez la réponse du module et utilisez le ansible.builtin.assert module pour vérifier le résultat attendu dans la réponse.
JSNAPy enregistre par défaut les informations relatives à ses opérations dans le fichier /var/log/jsnapy/jsnapy.log . Le juniper.device.jsnapy module peut éventuellement inclure l’argument logfile . Sa valeur spécifie le chemin d’accès à un fichier accessible en écriture sur le nœud de contrôle Ansible. Le niveau de détail et les options de débogage d’Ansible déterminent le niveau d’information enregistré dans le fichier. Par défaut, seuls les messages de niveau de gravité AVERTISSEMENT ou supérieur sont enregistrés. Pour journaliser des messages égaux ou supérieurs au niveau de gravité INFO ou au niveau de gravité DEBUG, exécutez le playbook avec l’option -v de ligne de commande ou -vv , respectivement.
Lorsque vous exécutez des tests JSNAPy dans un playbook Ansible, vous pouvez enregistrer ou résumer les informations relatives aux tests JSNAPy ayant échoué. Pour plus d’informations, consultez Examiner les tests JSNAPy ayant échoué.
Prenez et comparez des instantanés
JSNAPy vous permet de capturer des instantanés de l’environnement d’exécution de vos équipements Junos avant et après une modification, puis de comparer ces instantanés pour vérifier les changements attendus ou identifier les problèmes inattendus. Le juniper.device.jsnapy module vous permet de prendre et de comparer des instantanés JSNAPy dans le cadre d’un playbook Ansible. Le module enregistre chaque instantané de chaque hôte dans un fichier séparé dans le répertoire d’instantanés JSNAPy par défaut à l’aide d’un nom de fichier prédéterminé. Pour plus d’informations sur les fichiers de sortie, consultez Présentation de la sortie du module jsnapy.
Pour prendre des instantanés de base d’un ou de plusieurs appareils avant d’apporter des modifications :
-
Définissez l’argument du
actionmodule sursnap_pre. -
Spécifiez un fichier de configuration ou un ou plusieurs fichiers de test.
Le playbook suivant enregistre les instantanés PRE pour chaque périphérique du groupe d’inventaire Ansible. La tâche fait référence au fichier de configuration jsnapy_config_base_tests.yaml dans le répertoire ~/jsnapy/testfiles et consigne les messages dans le fichier jsnapy_tests.log dans le répertoire du playbook.
---
- name: Junos Snapshot Administrator tests
hosts: dc1
connection: local
gather_facts: no
tasks:
- name: Take a pre-maintenance snapshot
juniper.device.jsnapy:
action: "snap_pre"
dir: "~/jsnapy/testfiles"
config_file: "jsnapy_config_base_tests.yaml"
logfile: "jsnapy_tests.log"
Pour prendre un instantané d’un ou plusieurs appareils après avoir effectué des modifications :
-
Définissez l’argument du
actionmodule sursnap_post. -
Spécifiez un fichier de configuration ou un ou plusieurs fichiers de test.
Le playbook suivant enregistre les instantanés POST pour chaque périphérique du groupe d’inventaire Ansible. La tâche fait référence au même fichier de configuration jsnapy_config_base_tests.yaml dans le répertoire ~/jsnapy/testfiles et consigne les messages dans le fichier jsnapy_tests.log dans le répertoire playbook.
---
- name: Junos Snapshot Administrator tests
hosts: dc1
connection: local
gather_facts: no
tasks:
- name: Take a post-maintenance snapshot
juniper.device.jsnapy:
action: "snap_post"
dir: "~/jsnapy/testfiles"
config_file: "jsnapy_config_base_tests.yaml"
logfile: "jsnapy_tests.log"
Lorsque le juniper.device.jsnapy module effectue une snap_pre action ou une snap_post action, il enregistre chaque instantané de chaque hôte dans un fichier séparé à l’aide de noms de fichiers générés automatiquement qui contiennent respectivement une balise 'PRE' ou 'POST'. Vous pouvez effectuer une check action pour comparer les PRE instantanés et POST afin de vérifier rapidement les mises à jour ou d’identifier les problèmes qui pourraient avoir résulté des modifications.
Lorsque le module effectue une check action, JSNAPy compare les instantanés PRE et POST pour chaque test sur chaque appareil et les évalue par rapport aux critères définis dans la tests: section des fichiers de test. Si les fichiers de test ne définissent aucun cas de test, JSNAPy compare plutôt les instantanés nœud par nœud.
Pour comparer les instantanés PRE et POST :
-
Définissez l’argument du
actionmodule surcheck. -
Spécifiez le même fichier de configuration ou les mêmes fichiers de test que ceux utilisés pour prendre les instantanés.
-
Vérifiez les résultats du test en enregistrant la réponse du module et en utilisant le
ansible.builtin.assertmodule pour vérifier le résultat attendu dans la réponse.
Le playbook suivant compare les instantanés pris pour les exécutions précédentes snap_pre et snap_post les actions pour chaque appareil du groupe d’inventaire Ansible. Les résultats sont évalués à l’aide des critères des fichiers de test référencés dans le fichier de configuration. Le playbook enregistre la réponse du module comme 'test_result' et utilise le ansible.builtin.assert module pour vérifier que tous les tests ont réussi sur l’appareil donné.
---
- name: Junos Snapshot Administrator tests
hosts: dc1
connection: local
gather_facts: no
tasks:
- name: Compare PRE and POST snapshots
juniper.device.jsnapy:
action: "check"
dir: "~/jsnapy/testfiles"
config_file: "jsnapy_config_base_tests.yaml"
logfile: "jsnapy_tests.log"
register: test_result
- name: Verify JSNAPy tests passed
ansible.builtin.assert:
that:
- "test_result.passPercentage == 100"
Lorsque vous exécutez le playbook, les assertions identifient rapidement les équipements qui ont échoué aux tests.
user@host:~$ ansible-playbook jsnapy-baseline-check.yaml
PLAY [Junos Snapshot Administrator tests] *************************************
TASK [Compare PRE and POST snapshots] *****************************************
ok: [dc1a.example.net]
ok: [dc1b.example.net]
TASK [Verify JSNAPy tests passed] *********************************************
ok: [dc1b.example.net] => {
"changed": false,
"msg": "All assertions passed"
}
fatal: [dc1a.example.net]: FAILED! => {
"assertion": "test_result.passPercentage == 100",
"changed": false,
"evaluated_to": false,
"msg": "Assertion failed"
}
to retry, use: --limit @/home/user/jsnapy-baseline-check.retry
PLAY RECAP ********************************************************************
dc1b.example.net : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dc1a.example.net : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
Effectuer des opérations Snapcheck
JSNAPy vous permet de prendre des instantanés pour les commandes ou les RPC spécifiés dans les fichiers de test JSNAPy et d’évaluer immédiatement les instantanés par rapport à des critères prédéfinis dans les cas de test. Le juniper.device.jsnapy module vous permet d’effectuer une opération de vérification d’accrochage JSNAPy dans le cadre d’un playbook Ansible.
Pour prendre un instantané et l’évaluer immédiatement en fonction de l’ensemble de critères prédéfinis dans la tests: section des fichiers de test :
-
Définissez l’argument du
actionmodule sursnapcheck. -
Spécifiez un fichier de configuration ou un ou plusieurs fichiers de test.
-
Vérifiez les résultats du test en enregistrant la réponse du module et en utilisant le
ansible.builtin.assertmodule pour vérifier le résultat attendu dans la réponse.
Par exemple, pour chaque appareil du groupe d’inventaire Ansible, le playbook suivant enregistre un instantané distinct pour chaque commande ou RPC dans les fichiers de test. Il enregistre ensuite la réponse du module et utilise le ansible.builtin.assert module pour vérifier que tous les tests définis dans les fichiers de test ont réussi sur cet appareil.
---
- name: Junos Snapshot Administrator tests
hosts: dc1
connection: local
gather_facts: no
tasks:
- name: Take a snapshot and immediately evaluate it
juniper.device.jsnapy:
action: "snapcheck"
dir: "~/jsnapy/testfiles/"
test_files:
- "test_interface_status.yaml"
- "test_bgp_neighbor.yaml"
logfile: "jsnapy_tests.log"
register: test_result
- name: Verify JSNAPy tests passed
ansible.builtin.assert:
that:
- "test_result.passPercentage == 100"
Comprendre la sortie du module jsnapy
Lorsque le juniper.device.jsnapy module effectue une snap_preaction , snap_postou snapcheck , il enregistre automatiquement les instantanés dans le répertoire des instantanés JSNAPy. Le module utilise les répertoires JSNAPy par défaut, sauf si vous modifiez le fichier de configuration JSNAPy (jsnapy.cfg) pour spécifier un emplacement différent. Le module crée un fichier distinct pour chaque commande ou RPC exécuté sur chaque appareil du groupe d’inventaire Ansible. Le Tableau 4 présente les noms de fichiers des fichiers d’instantané pour chaque valeur de l’argument action .
À partir de Junos Snapshot Administrator dans Python version 1.3.0, les répertoires par défaut pour les fichiers de test et les instantanés JSNAPy sont respectivement ~/jsnapy/testfiles et ~/jsnapy/snapshots. Toutefois, les répertoires par défaut dans un environnement virtuel ou pour les versions antérieures sont /etc/jsnapy/testfiles et /etc/jsnapy/snapshots.
|
|
Fichiers de sortie |
|---|---|
|
|
hostname_PRÉ_hash_.commandformat |
|
|
hostname_POST_hash_.commandformat |
|
|
hostname_snap_temp_hash_.commandformat |
où :
-
hostname: nom d’hôte du périphérique sur lequel la commande ou le RPC est exécuté.
-
(PRE | POST | snap_temp) : balise identifiant l’action. L’opération
snapcheckutilise la balise dans lesPREversions actuelles ; dans les versions antérieures, l’opération utilise lasnap_tempbalise. -
hash: hachage généré à partir de
kwargspour les fichiers de test qui incluent lesrpcclés etkwargs.Si les fichiers de test utilisent le même RPC mais incluent des arguments différents, et que les RPC sont exécutés sur le même hôte, le hachage garantit des noms de fichiers de sortie uniques dans ces cas. Si un fichier de test définit la
commandclé ou si un fichier de test définit larpcclé mais ne l’inclutkwargspas, le hachage est omis. -
command: commande ou RPC exécutée sur le périphérique géré. Le module remplace les espaces et les caractères spéciaux dans la commande ou le nom RPC par des traits de soulignement ( _ ).
-
format: format de la sortie, par exemple, xml.
Le juniper.device.jsnapy module différencie les noms de fichiers d’instantanés pour une action donnée en se basant uniquement sur le nom d’hôte et la commande ou RPC. Par conséquent, si le module prend des instantanés sur le même appareil pour la même action à l’aide de fichiers de test qui définissent la même commande ou RPC, le module générera des instantanés avec le même nom de fichier et le nouveau fichier écrasera l’ancien fichier.
Par exemple, si le module inclut action: "snap_pre" et référence des fichiers de test qui exécutent les commandes et show interfaces terse sur les show chassis fpc appareils dc1a.example.net et dc1b.example.net, les fichiers résultants sont :
user@ansible-cn:~$ ls jsnapy/snapshots dc1a.example.net_PRE_show_chassis_fpc.xml dc1a.example.net_PRE_show_interfaces_terse.xml dc1b.example.net_PRE_show_chassis_fpc.xml dc1b.example.net_PRE_show_interfaces_terse.xml
Si le module inclut action: "snap_post" et référence un fichier de test qui exécute le RPC avec kwargs un élément sur l’dc1a.example.net get-interface-information interface_name: lo0 de l’appareil, le fichier résultant est :
dc1a.example.net_POST_r1w59I99HXxC3u0VXXshbw==_get_interface_information.xml
En plus de générer les fichiers d’instantané, le juniper.device.jsnapy module peut également renvoyer les clés suivantes dans la réponse du module :
-
action: action JSNAPy effectuée par le module. -
changed: indique si l’état du périphérique a changé. Comme JSNAPy ne rapporte que l’état, la valeur est toujoursfalse. -
failed: indique si la tâche du playbook a échoué. -
msg—Résultats des tests JSNAPy.
Passez en revue les tests JSNAPy ayant échoué
Lorsque vous exécutez des tests JSNAPy sur des équipements Junos, vous pouvez vérifier rapidement si tous les tests JSNAPy ont réussi. Vous enregistrez la réponse du juniper.device.jsnapy module et utilisez le ansible.builtin.assert module pour vérifier que le est 100 passPercentage . Cependant, si un ou plusieurs tests échouent, il peut être difficile d’identifier et d’extraire les tests échoués si les résultats sont étendus.
Le juniper.device.jsnapy module fournit les options suivantes pour voir les tests JSNAPy ayant échoué :
-
juniper.device.jsnapyplug-in de rappel : imprime un résumé des tests JSNAPy ayant échoué après la sortie du playbook. -
dest_dirmodule : écrit les tests JSNAPy ayant échoué dans les fichiers du répertoire spécifié.
Le jsnapy plugin de rappel vous permet d’extraire et de résumer facilement les informations pour les tests JSNAPy ayant échoué. Lorsque vous activez le jsnapy plug-in de rappel et exécutez un playbook qui inclut des tests JSNAPy, le plug-in résume les informations des tests JSNAPy ayant échoué après le playbook PLAY RECAP.
Le jsnapy plugin de rappel est désactivé par défaut. Pour activer le plug-in de jsnapy rappel, ajoutez l’instruction callbacks_enabled = juniper.device.jsnapy au fichier de configuration Ansible.
[defaults] callbacks_enabled = juniper.device.jsnapy
Lorsque vous activez le jsnapy plug-in de rappel et exécutez un playbook, le plug-in résume les tests JSNAPy ayant échoué dans un format lisible par l’homme. Par exemple :
...
PLAY RECAP ****************************************************************
qfx10002-01 : ok=3 changed=0 unreachable=0 failed=1
qfx10002-02 : ok=3 changed=0 unreachable=0 failed=1
qfx5100-01 : ok=1 changed=0 unreachable=0 failed=1
JSNAPy Results for: qfx10002-01 *******************************************
Value of 'peer-state' not 'is-equal' at '//bgp-information/bgp-peer' with {"peer-as": "64502", "peer-state": "Active", "peer-address": "198.51.100.21"}
Value of 'peer-state' not 'is-equal' at '//bgp-information/bgp-peer' with {"peer-as": "64510", "peer-state": "Idle", "peer-address": "192.168.0.1"}
Value of 'oper-status' not 'is-equal' at '//interface-information/physical-interface[normalize-space(admin-status)='up' and logical-interface/address-family/address-family-name ]' with {"oper-status": "down", "name": "et-0/0/18"}
JSNAPy Results for: qfx10002-02 *******************************************
Value of 'peer-state' not 'is-equal' at '//bgp-information/bgp-peer' with {"peer-as": "64502", "peer-state": "Active", "peer-address": "198.51.100.21"}
À partir de juniper.device la version 1.0.6, le juniper.device.jsnapy module prend également en charge l’argumentdest_dir. Vous pouvez inclure l’argument et snapcheck check les dest_dir opérations qui évaluent les instantanés en fonction de critères de test. Lorsque vous effectuez une check opération ou snapcheck et incluez l’argumentdest_dir, le module écrit chaque test JSNAPy ayant échoué pour un hôte donné dans un fichier du répertoire de sortie spécifié.
Par exemple, considérons le playbook suivant :
---
- name: Verify BGP
hosts: bgp_routers
connection: local
gather_facts: no
tasks:
- name: Execute snapcheck
juniper.device.jsnapy:
action: "snapcheck"
dir: "~/jsnapy/testfiles"
test_files:
- "jsnapy_test_file_bgp_states.yaml"
- "jsnapy_test_file_bgp_summary.yaml"
logfile: "{{ logfile }}"
dest_dir: "{{ playbook_dir }}/jsnapy_failed_tests"
register: snapcheck_result
Lorsque vous exécutez le playbook, le module génère un fichier dans le dest_dir répertoire pour chaque test échoué sur l’hôte donné. Par exemple, le module a généré les fichiers suivants pour les échecs bgp_neighbor et bgp_summary les tests sur les hôtes r1 et r3.
user@ansible-cn:~/ansible$ ls jsnapy_failed_tests r1_bgp_neighbor_False.text r3_bgp_neighbor_False.text r1_bgp_summary_False.text r3_bgp_summary_False.text
Exemple : Utilisation d’Ansible pour effectuer une opération JSNAPy Snapcheck
Le juniper.device.jsnapy module vous permet d’exécuter des tests JSNAPy sur des équipements Junos dans le cadre d’un playbook Ansible. Cet exemple utilise le jsnapy module pour effectuer une snapcheck action visant à vérifier l’état opérationnel des équipements Junos après l’application de modifications de configuration spécifiques.
- Exigences
- Vue d’ensemble
- La configuration
- Exécuter le guide stratégique
- Vérification
- Résoudre les erreurs du playbook Ansible
Exigences
Cet exemple utilise les composants matériels et logiciels suivants :
-
Nœud de contrôle Ansible en cours d’exécution :
-
Python 3.10 ou version ultérieure
-
Ansible 2.17 ou version ultérieure avec la
juniper.devicecollection installée -
Junos PyEZ version 2.7.3 ou ultérieure
-
Administrateur d’instantanés Junos en Python version 1.3.7 ou ultérieure
-
Avant d’exécuter le playbook Ansible, assurez-vous d’avoir :
-
Équipements Junos sur lesquels NETCONF sur SSH est activé et un compte utilisateur configuré avec les autorisations appropriées
-
Paire de clés publique/privée SSH configurée pour l’utilisateur approprié sur le nœud de contrôle Ansible et l’équipement Junos
-
Fichier d’inventaire Ansible existant avec les hôtes requis définis
Vue d’ensemble
Dans cet exemple, le playbook Ansible configure des sessions d’appairage BGP sur trois équipements Junos et utilise le jsnapy module pour vérifier que la session BGP est établie pour chaque adresse voisine. Si le playbook vérifie que les sessions sont établies sur un appareil, il confirme la validation de la nouvelle configuration. Si le playbook ne confirme pas la validation, l’équipement Junos revient automatiquement à la configuration précédemment validée. Le projet Ansible définit les variables de groupe et d’hôte pour le playbook sous les group_vars répertoires and host_vars , respectivement.
Le livre de jeu comporte deux jeux. La première lecture, Load and commit BGP configuration, génère et assemble la configuration, charge la configuration sur l’appareil et la valide à l’aide d’une opération de validation confirmée. Si la configuration est mise à jour, un gestionnaire est averti. La pièce exécute les tâches suivantes :
Remove build directory |
Supprime le répertoire de construction existant pour le périphérique donné, s’il existe. |
Create build directory |
Crée un nouveau répertoire de construction vide pour l’appareil donné. |
Build BGP configuration |
Utilise le |
Assemble configuration parts |
Utilise le Dans cet exemple, seul le fichier de configuration BGP sera présent et, par conséquent, le fichier de configuration résultant est identique au fichier de configuration BGP rendu dans la tâche précédente. Si vous ajoutez ultérieurement de nouvelles tâches pour générer des fichiers de configuration supplémentaires à partir d’autres modèles, le |
Load and commit config, require confirmation |
Charge la configuration sur l’équipement Junos et valide la configuration à l’aide d’une opération, qui nécessite une Si la configuration demandée est déjà présente sur l’appareil, le |
La deuxième lecture, Verify BGP, effectue une opération JSNAPy snapcheck sur chaque périphérique à l’aide des tests des fichiers de test JSNAPy. Si tous les tests réussissent, le jeu confirme également l’engagement. La pièce exécute les tâches suivantes :
Execute snapcheck |
Effectue une opération JSNAPy Dans cet exemple, le playbook fait directement référence aux fichiers de test JSNAPy en définissant l’argument |
Confirm commit |
Exécute une opération de vérification de validation, qui confirme l’opération de validation précédente, à condition que la première lecture du playbook ait mis à jour la configuration et que tous les tests JSNAPy aient réussi. Si le playbook met à jour la configuration mais ne confirme pas la validation, l’équipement Junos rétablit automatiquement la configuration à la configuration précédemment validée.
Remarque :
Vous pouvez confirmer l’opération de validation précédente avec une |
Verify BGP configuration |
(Facultatif) Indique explicitement si les tests JSNAPy ont réussi ou échoué sur l’équipement donné. Cette tâche n’est pas spécifiquement obligatoire, mais elle identifie plus facilement quand les tests JSNAPy échouent et sur quels équipements. |
La configuration
- Définir les variables de groupe
- Définir le modèle Jinja2 et les variables d’hôte
- Création des fichiers de test JSNAPy
- Créer le playbook Ansible
- Résultats
Définir les variables de groupe
Procédure étape par étape
Pour définir les variables de groupe :
-
Dans le fichier group_vars/all , définissez des variables pour le répertoire de construction et pour les noms de fichiers des fichiers de configuration et journaux.
build_dir: "{{ playbook_dir }}/build_conf/{{ inventory_hostname }}" junos_conf: "{{ build_dir }}/junos.conf" logfile: "junos.log"
Définir le modèle Jinja2 et les variables d’hôte
Définir le modèle Jinja2
Pour créer le modèle Jinja2 utilisé pour générer la configuration BGP :
-
Créez un fichier nommé bgp-template.j2 dans le répertoire playbook du projet.
-
Ajoutez le modèle de configuration BGP au fichier.
interfaces { {% for neighbor in neighbors %} {{ neighbor.interface }} { unit 0 { description "{{ neighbor.name }}"; family inet { address {{ neighbor.local_ip }}/30; } } } {% endfor %} lo0 { unit 0 { family inet { address {{ loopback }}/32; } } } } protocols { bgp { group underlay { import bgp-in; export bgp-out; type external; local-as {{ local_asn }}; multipath multiple-as; {% for neighbor in neighbors %} neighbor {{ neighbor.peer_ip }} { peer-as {{ neighbor.asn }}; } {% endfor %} } } lldp { {% for neighbor in neighbors %} interface "{{ neighbor.interface }}"; {% endfor %} } } routing-options { router-id {{ loopback }}; forwarding-table { export bgp-ecmp; } } policy-options { policy-statement bgp-ecmp { then { load-balance per-packet; } } policy-statement bgp-in { then accept; } policy-statement bgp-out { then { next-hop self; accept; } } }
Définir les variables hôtes
Pour définir les variables hôtes qui sont utilisées avec le modèle Jinja2 pour générer la configuration BGP :
-
Dans le répertoire host_vars du projet, créez un fichier distinct nommé hostname.yaml pour chaque hôte.
-
Définissez les variables de l’hôte r1 dans le fichier r1.yaml .
--- loopback: 192.168.0.1 local_asn: 64521 neighbors: - interface: ge-0/0/0 name: to-r2 asn: 64522 peer_ip: 198.51.100.2 local_ip: 198.51.100.1 peer_loopback: 192.168.0.2 - interface: ge-0/0/1 name: to-r3 asn: 64523 peer_ip: 198.51.100.6 local_ip: 198.51.100.5 peer_loopback: 192.168.0.3 -
Définissez les variables de l’hôte r2 dans le fichier r2.yaml .
--- loopback: 192.168.0.2 local_asn: 64522 neighbors: - interface: ge-0/0/0 name: to-r1 asn: 64521 peer_ip: 198.51.100.1 local_ip: 198.51.100.2 peer_loopback: 192.168.0.1 - interface: ge-0/0/1 name: to-r3 asn: 64523 peer_ip: 198.51.100.10 local_ip: 198.51.100.9 peer_loopback: 192.168.0.3 -
Définissez les variables de l’hôte r3 dans le fichier r3.yaml .
--- loopback: 192.168.0.3 local_asn: 64523 neighbors: - interface: ge-0/0/0 name: to-r1 asn: 64521 peer_ip: 198.51.100.5 local_ip: 198.51.100.6 peer_loopback: 192.168.0.1 - interface: ge-0/0/1 name: to-r2 asn: 64522 peer_ip: 198.51.100.9 local_ip: 198.51.100.10 peer_loopback: 192.168.0.2
Création des fichiers de test JSNAPy
Procédure étape par étape
Le jsnapy module fait référence aux fichiers de test JSNAPy dans le répertoire ~/jsnapy/testfiles . Pour créer les fichiers de test JSNAPy :
-
Créez le fichier jsnapy_test_file_bgp_states.yaml , qui exécute la
show bgp neighborcommande et teste que l’état pair BGP est établi.bgp_neighbor: - command: show bgp neighbor - ignore-null: true - iterate: xpath: '//bgp-peer' id: './peer-address' tests: # Check if peers are in the established state - is-equal: peer-state, Established err: "Test Failed!! peer <{{post['peer-address']}}> state is not Established, it is <{{post['peer-states']}}>" info: "Test succeeded!! peer <{{post['peer-address']}}> state is <{{post['peer-state']}}>" -
Créez le fichier jsnapy_test_file_bgp_summary.yaml , qui exécute la
show bgp summarycommande et affirme que le nombre d’homologues BGP doit être égal à 0.bgp_summary: - command: show bgp summary - item: xpath: '/bgp-information' tests: - is-equal: down-peer-count, 0 err: "Test Failed!! down-peer-count is not equal to 0. It is equal to <{{post['down-peer-count']}}>" info: "Test succeeded!! down-peer-count is equal to <{{post['down-peer-count']}}>"
Créer le playbook Ansible
- Définir la première lecture pour configurer l’appareil
- Définir la deuxième pièce pour effectuer les opérations JSNAPy
Définir la première lecture pour configurer l’appareil
Pour créer la première lecture, qui affiche la configuration, la charge sur l’appareil et valide la configuration en tant qu’opération de validation confirmée :
-
Incluez le passe-partout du playbook et le premier play, qui exécute les modules localement.
--- - name: Load and commit BGP configuration hosts: bgp_routers connection: local gather_facts: no
-
Créez les tâches qui remplacent le répertoire de build existant par un répertoire vide, qui stockera les nouveaux fichiers de configuration.
tasks: - name: Remove build directory file: path: "{{ build_dir }}" state: absent - name: Create build directory file: path: "{{ build_dir }}" state: directory -
Créez la tâche qui affiche la configuration BGP à partir du fichier modèle Jinja2 et des variables hôtes, et stockez-la dans le fichier bgp.conf dans le répertoire de construction de cet hôte.
- name: Build BGP configuration template: src: "{{ playbook_dir }}/bgp-template.j2" dest: "{{ build_dir }}/bgp.conf" -
Créez une tâche pour assembler les fichiers de configuration du répertoire de construction dans le fichier de configuration junos.conf final.
- name: Assemble configuration parts assemble: src: "{{ build_dir }}" dest: "{{ junos_conf }}" -
Créez la tâche qui charge la configuration sur l’appareil, effectue une opération de validation qui nécessite une confirmation et avertit le gestionnaire donné, si la configuration a été modifiée.
- name: Load and commit config, require confirmation juniper.device.config: load: "merge" format: "text" src: "{{ junos_conf }}" confirm: 5 comment: "config by Ansible" logfile: "{{ logfile }}" register: config_result # Notify handler, only if configuration changes. notify: - Waiting for BGP peers to establish connections -
Créez un gestionnaire qui interrompt l’exécution du playbook si la configuration de l’appareil est mise à jour. Définissez le temps de pause sur une valeur appropriée pour votre environnement.
handlers: - name: Waiting for BGP peers to establish connections pause: seconds=60
Définir la deuxième pièce pour effectuer les opérations JSNAPy
Pour créer la deuxième lecture, qui effectue une opération de vérification d’accrochage JSNAPy et confirme la configuration validée, à condition que la configuration ait changé et que les tests JSNAPy aient réussi :
-
Incluez le passe-partout pour la deuxième pièce, qui exécute les modules localement.
- name: Verify BGP hosts: bgp_routers connection: local gather_facts: no
-
Créez une tâche pour effectuer une opération de vérification d’accrochage JSNAPy basée sur les tests dans les fichiers de test JSNAPy donnés, et enregistrez la réponse du module.
tasks: - name: Execute snapcheck juniper.device.jsnapy: action: "snapcheck" dir: "~/jsnapy/testfiles" test_files: - "jsnapy_test_file_bgp_states.yaml" - "jsnapy_test_file_bgp_summary.yaml" logfile: "{{ logfile }}" register: snapcheck_result -
Créez la tâche pour confirmer la validation à condition que les conditions données soient remplies.
# Confirm commit only if configuration changed and JSNAPy tests pass - name: Confirm commit juniper.device.config: check: true commit: false diff: false logfile: "{{ logfile }}" when: - config_result.changed - "snapcheck_result.passPercentage == 100" -
(Facultatif) Créez une tâche qui utilise le
ansible.builtin.assertmodule pour affirmer que les tests JSNAPy ont réussi.- name: Verify BGP configuration ansible.builtin.assert: that: - "snapcheck_result.passPercentage == 100" msg: "JSNAPy test on {{ inventory_hostname }} failed"
Résultats
Sur le nœud de contrôle Ansible, passez en revue le playbook terminé. Si le playbook n’affiche pas le code prévu, répétez les instructions de cette section pour corriger le playbook.
---
- name: Load and commit BGP configuration
hosts: bgp_routers
connection: local
gather_facts: no
tasks:
- name: Remove build directory
file:
path: "{{ build_dir }}"
state: absent
- name: Create build directory
file:
path: "{{ build_dir }}"
state: directory
- name: Build BGP configuration
template:
src: "{{ playbook_dir }}/bgp-template.j2"
dest: "{{ build_dir }}/bgp.conf"
- name: Assemble configuration parts
assemble:
src: "{{ build_dir }}"
dest: "{{ junos_conf }}"
- name: Load and commit config, require confirmation
juniper.device.config:
load: "merge"
format: "text"
src: "{{ junos_conf }}"
confirm: 5
comment: "config by Ansible"
logfile: "{{ logfile }}"
register: config_result
# Notify handler, only if configuration changes.
notify:
- Waiting for BGP peers to establish connections
handlers:
- name: Waiting for BGP peers to establish connections
pause: seconds=60
- name: Verify BGP
hosts: bgp_routers
connection: local
gather_facts: no
tasks:
- name: Execute snapcheck
juniper.device.jsnapy:
action: "snapcheck"
dir: "~/jsnapy/testfiles"
test_files:
- "jsnapy_test_file_bgp_states.yaml"
- "jsnapy_test_file_bgp_summary.yaml"
logfile: "{{ logfile }}"
register: snapcheck_result
# Confirm commit only if configuration changed and JSNAPy tests pass
- name: Confirm commit
juniper.device.config:
check: true
commit: false
diff: false
logfile: "{{ logfile }}"
when:
- config_result.changed
- "snapcheck_result.passPercentage == 100"
- name: Verify BGP configuration
ansible.builtin.assert:
that:
- "snapcheck_result.passPercentage == 100"
msg: "JSNAPy test on {{ inventory_hostname }} failed"
Exécuter le guide stratégique
Pour exécuter le playbook :
-
Exécutez la
ansible-playbookcommande sur le nœud de contrôle et fournissez le chemin du playbook et toutes les options souhaitées.user@ansible-cn:~/ansible$ ansible-playbook ansible-pb-bgp-configuration.yaml PLAY [Load and commit BGP configuration] ************************************* TASK [Remove build directory] ************************************************ changed: [r1] changed: [r2] changed: [r3] TASK [Create build directory] ************************************************ changed: [r1] changed: [r2] changed: [r3] TASK [Build BGP configuration] *********************************************** changed: [r2] changed: [r1] changed: [r3] TASK [Assemble configuration parts] ****************************************** changed: [r3] changed: [r2] changed: [r1] TASK [Load and commit config, require confirmation] ************************** changed: [r2] changed: [r1] changed: [r3] RUNNING HANDLER [Waiting for BGP peers to establish connections] ************* Pausing for 60 seconds (ctrl+C then 'C' = continue early, ctrl+C then 'A' = abort) ok: [r3]
PLAY [Verify BGP] ************************************************************ TASK [Execute snapcheck] ***************************************************** ok: [r2] ok: [r1] ok: [r3] TASK [Confirm commit] ******************************************************** ok: [r2] ok: [r1] ok: [r3] TASK [Verify BGP configuration] ********************************************** ok: [r1] => { "changed": false, "msg": "All assertions passed" } ok: [r2] => { "changed": false, "msg": "All assertions passed" } ok: [r3] => { "changed": false, "msg": "All assertions passed" } PLAY RECAP ******************************************************************* r1 : ok=8 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 r2 : ok=8 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 r3 : ok=9 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Vérification
Vérifiez les voisins BGP
Objet
Vérifiez que la session BGP est établie pour chaque adresse voisine.
Les fichiers de test JSNAPy testent que la session BGP est établie pour chaque adresse voisine et qu’il n’y a pas d’homologues en panne. La sortie de la Verify BGP configuration tâche vous permet de vérifier rapidement que l’appareil donné a réussi tous les tests JSNAPy. Si JSNAPy passPercentage est égal à 100 %, la tâche est incluse "msg": "All assertions passed" dans la sortie de la tâche.
Mesures à prendre
Examinez le résultat de la Verify BGP configuration tâche et vérifiez que chaque périphérique renvoie le All assertions passed message.
TASK [Verify BGP configuration] **********************************************
ok: [r1] => {
"changed": false,
"msg": "All assertions passed"
}
ok: [r2] => {
"changed": false,
"msg": "All assertions passed"
}
ok: [r3] => {
"changed": false,
"msg": "All assertions passed"
}
Signification
Le All assertions passed message indique que les équipements ont correctement établi les sessions BGP.
Résoudre les erreurs du playbook Ansible
- Résoudre les erreurs de charge de configuration
- Dépannage des échecs aux tests JSNAPy
- Dépannage des confirmations de validation ayant échoué
Résoudre les erreurs de charge de configuration
Problème
Le playbook Ansible génère une ConfigLoadError erreur indiquant qu’il n’a pas réussi à charger la configuration sur l’appareil en raison d’une erreur de syntaxe.
fatal: [r1]: FAILED! => {"changed": false, "msg": "Failure loading the configuraton: ConfigLoadError(severity: error, bad_element: protocol, message: error: syntax error\nerror: error recovery ignores input until this point)"}
La solution
Le playbook affiche la configuration Junos OS à l’aide du modèle Jinja2 et des variables hôtes définies pour ce périphérique dans le répertoire host_vars . Le playbook génère une erreur de syntaxe lorsque le modèle Jinja2 produit une configuration non valide. Pour corriger cette erreur, mettez à jour le modèle Jinja2 pour corriger l’élément identifié par la bad_element clé dans le message d’erreur.
Dépannage des échecs aux tests JSNAPy
Problème
La Verify BGP configuration sortie de la tâche indique que l’assertion a échoué, car JSNAPy passPercentage n’était pas égal à 100 %.
TASK [Verify BGP configuration] *************************************************************
fatal: [r1]: FAILED! => {
"assertion": "snapcheck_result.passPercentage == 100",
"changed": false,
"evaluated_to": false,
"msg": "JSNAPy test on r1 failed"
}
L’assertion échoue lorsque l’appareil n’a pas établi la session BGP avec son voisin ou que la session est interrompue. Si l’assertion échoue et que la configuration de cet appareil a été mise à jour lors de la première lecture, le playbook ne confirme pas la validation de la nouvelle configuration sur l’appareil et l’appareil rétablit la configuration précédemment validée.
La solution
Les tests JSNAPy peuvent échouer si l’opération snapcheck est effectuée avant que les pairs puissent établir la session ou parce que les voisins BGP ne sont pas configurés correctement. Si la sortie du playbook indique que la configuration a été correctement chargée et validée sur l’appareil, essayez d’augmenter l’intervalle de pause du gestionnaire à une valeur appropriée pour votre environnement et réexécutez le playbook.
handlers:
- name: Waiting for BGP peers to establish connections
pause: seconds=75
Si les tests échouent toujours, vérifiez que le modèle Jinja2 et les variables hôte de chaque périphérique contiennent les données correctes et que la configuration résultante pour chaque périphérique est correcte.
Dépannage des confirmations de validation ayant échoué
Problème
La configuration n’a pas été confirmée sur un ou plusieurs équipements.
TASK [Confirm commit] *********************************************************************** skipping: [r2] skipping: [r2] skipping: [r3]
La solution
Le playbook ne confirme la configuration que si elle a changé et que les tests JSNAPy réussissent. Si la sortie de la Load and commit config, require confirmation tâche indique que la configuration n’a pas changé, le playbook n’exécute pas la tâche pour confirmer la validation. Si la configuration changeait mais n’était pas confirmée, les tests JSNAPy échouaient. Les tests JSNAPy peuvent échouer si les voisins BGP ne sont pas configurés correctement ou si le playbook ne laisse pas suffisamment de temps entre les lectures pour que les équipements établissent la session BGP. Pour plus d’informations, consultez Dépannage des échecs de tests JSNAPy.