Usar el Administrador de instantáneas de Junos en Python (JSNAPy) en Playbooks de Ansible
Ejecute pruebas JSNAPy como parte de un manual de Ansible para capturar y auditar instantáneas del entorno de ejecución de dispositivos Junos.
El Administrador de instantáneas de Junos® en Python (JSNAPy) le permite capturar y auditar instantáneas del entorno de ejecución de sus dispositivos Junos. Puede capturar y verificar la configuración y el estado operativo de un dispositivo y verificar los cambios en un dispositivo. Juniper Networks proporciona un módulo de Ansible que puede usar para ejecutar pruebas JSNAPy en dispositivos Junos como parte de un manual de Ansible. En el cuadro 1 se describe el módulo disponible.
| Conjunto de contenido |
Nombre del módulo |
|---|---|
|
|
Debe instalar Junos Snapshot Administrator en Python en el nodo de control de Ansible para poder utilizar el juniper.device.jsnapy módulo. Para obtener instrucciones de instalación e información sobre cómo crear archivos de prueba y configuración JSNAPy, consulte la documentación de Junos Snapshot Administrator en Python.
En las siguientes secciones se explica cómo usar el módulo en los playbooks de juniper.device.jsnapy Ansible.
Descripción general del módulo
El juniper.device.jsnapy módulo le permite ejecutar funciones JSNAPy desde un libro de estrategias de Ansible, que incluyen:
-
Capturar y guardar una instantánea del entorno de ejecución
-
Comparación de dos instantáneas
-
Capturar una instantánea y evaluarla inmediatamente
El módulo requiere especificar el action argumento y el config_file o el test_files argumento. El action argumento especifica la acción JSNAPy que se va a realizar. En la Tabla 2 se describen los valores válidos action y los comandos JSNAPy equivalentes.
| valor de la acción |
Descripción |
Comando JSNAPy equivalente |
|---|---|---|
|
|
Compare dos instantáneas existentes según los casos de prueba dados o, si no se proporcionan casos de prueba, compare las instantáneas nodo por nodo. |
|
|
|
Tome instantáneas de los comandos o RPC especificados en los archivos de prueba después de realizar cambios en los dispositivos dados. |
|
|
|
Tome instantáneas de los comandos o RPC especificados en los archivos de prueba antes de realizar cambios en los dispositivos dados. |
|
|
|
Tome instantáneas de los comandos o RPC especificados en los archivos de prueba y evalúe inmediatamente las instantáneas según criterios predefinidos en los casos de prueba. |
|
Cuando ejecuta JSNAPy en la línea de comandos, JSNAPy realiza la acción solicitada en los hosts especificados en la sección del archivo de hosts configuración. El módulo de Ansible, por otro lado, ejecuta la acción solicitada en los hosts especificados en el manual de estrategias de Ansible. Como resultado, el módulo puede hacer referencia a un archivo de configuración, ignorando la hosts sección, o puede hacer referencia directamente a uno o más archivos de prueba.
Por lo tanto, además del action argumento, el juniper.device.jsnapy módulo también requiere que el config_file argumento o el test_files argumento especifiquen el archivo de configuración JSNAPy o los archivos de prueba JSNAPy que se utilizarán para la acción dada. En la Tabla 3 se describen los config_file argumentos y test_files .
| Argumento del módulo |
Valor |
Información adicional |
|---|---|---|
|
|
Ruta de archivo absoluta o relativa a un archivo de configuración JSNAPy. |
Si la ruta es relativa, el módulo comprueba el archivo de configuración en las siguientes ubicaciones y en el orden indicado:
Si el archivo de configuración hace referencia a archivos de prueba mediante una ruta de archivo relativa, el módulo comprueba primero los archivos de prueba en el directorio del playbook y, a continuación, busca los archivos de prueba en el directorio predeterminado |
|
|
Ruta de archivo absoluta o relativa a un archivo de prueba JSNAPy. Puede ser una ruta de un solo archivo o una lista de rutas de archivo. |
Para cada archivo de prueba que especifica una ruta relativa, el módulo comprueba el archivo en las siguientes ubicaciones y en el orden indicado:
|
Los config_file argumentos y test_files pueden tomar una ruta de archivo absoluta o relativa. Cuando se utiliza una ruta de archivo relativa, puede incluir opcionalmente el argumento module dir para especificar el directorio en el que residen los archivos. Si un config_file argumento or test_files utiliza una ruta de archivo relativa, el módulo comprueba primero el archivo en el directorio del playbook de Ansible, incluso si el dir argumento está presente. Si el archivo no existe en el directorio del playbook, el módulo comprueba en el directorio de dir argumentos, si se especifica, o en el directorio /etc/jsnapy/testfiles , si se omite el dir argumento. El manual genera un mensaje de error si no se encuentra el archivo.
Es importante tener en cuenta que cuando se incluye el dir parámetro, el módulo comprueba esa ubicación sólo para el argumento o config_file test_files especificado. Por lo tanto, cuando especifica un archivo de configuración, el módulo no comprueba en el dir directorio los archivos de prueba que especifique en el archivo de configuración. Si el archivo de configuración hace referencia a rutas relativas para los archivos de prueba, el módulo comprueba los archivos de prueba sólo en el directorio del playbook y en el directorio predeterminado testfiles .
Supongamos que tiene el siguiente archivo de configuración JSNAPy, jsnapy_config_base_tests.yaml, que reside en el directorio ~/jsnapy/testfiles y hace referencia a varios archivos de prueba 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
El siguiente manual de ejemplo realiza la snap_pre acción para cada uno de los archivos de prueba del archivo de configuración jsnapy_config_base_tests.yaml . Si el archivo de configuración no existe en el directorio del playbook, el módulo busca el archivo en el dir directorio, que en este caso es ~/jsnapy/testfiles. El archivo de configuración utiliza rutas relativas para los archivos de prueba. Como resultado, el módulo primero busca los archivos de prueba en el directorio del playbook y, a continuación, comprueba los archivos de prueba en el directorio predeterminado testfiles .
---
- 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"
Como alternativa, el jsnapy módulo puede utilizar el test_files parámetro para especificar los archivos de prueba individuales que se van a utilizar. El siguiente manual ejecuta las mismas pruebas que en el ejemplo de manual anterior. En este caso, el módulo comprueba primero los archivos de prueba en el directorio del playbook y, a continuación, comprueba los archivos de prueba en el dir directorio.
---
- 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
A partir de Junos Snapshot Administrator en Python versión 1.3.0, la ubicación predeterminada para los archivos de configuración y prueba es ~/jsnapy/testfiles. Sin embargo, la ubicación predeterminada dentro de un entorno virtual o para versiones anteriores es /etc/jsnapy/testfiles.
El módulo realiza la acción solicitada en los hosts especificados en el manual de estrategias de Ansible, incluso si el módulo hace referencia a un archivo de configuración que incluye una hosts sección. Los informes del módulo fallaron si encuentran un error y no pueden ejecutar las pruebas JSNAPy. No informa de que se ha producido un error si una o varias de las pruebas de JSNAPy fallan. Para comprobar los resultados de la prueba JSNAPy, registre la respuesta del módulo y utilice el ansible.builtin.assert módulo para comprobar el resultado esperado en la respuesta.
El Administrador de instantáneas de Junos en Python registra la información relativa a sus operaciones en el archivo /var/log/jsnapy/jsnapy.log de forma predeterminada. Opcionalmente, el juniper.device.jsnapy módulo puede incluir el logfile argumento, que especifica la ruta a un archivo grabable en el nodo de control de Ansible donde se registra la información de la tarea concreta. El nivel de detalle y las opciones de depuración de Ansible determinan el nivel de información registrado en el archivo. De forma predeterminada, solo se registran los mensajes de nivel de gravedad WARNING o superior. Para registrar mensajes iguales o superiores al nivel de gravedad INFO o al nivel de gravedad DEBUG, ejecute el manual con la -v opción de línea de comandos o -vv , respectivamente.
Al ejecutar pruebas de JSNAPy en un manual de Ansible, puede guardar o resumir la información de las pruebas de JSNAPy fallidas. Para obtener más información, consulte Revisar pruebas JSNAPy fallidas.
Tomar y comparar instantáneas
JSNAPy le permite capturar instantáneas del entorno de ejecución de sus dispositivos Junos antes y después de un cambio y, a continuación, comparar las instantáneas para verificar los cambios esperados o identificar problemas inesperados. El juniper.device.jsnapy módulo le permite tomar y comparar instantáneas JSNAPy como parte de un libro de estrategias de Ansible. El módulo guarda cada instantánea para cada host en un archivo separado en el directorio de instantáneas JSNAPy predeterminado utilizando un nombre de archivo predeterminado. Para obtener más información acerca de los archivos de salida, consulte Descripción de la salida del módulo jsnapy.
Para tomar instantáneas de línea base de uno o más dispositivos antes de realizar cambios, establezca el argumento del action módulo en snap_prey especifique un archivo de configuración o uno o más archivos de prueba.
En el siguiente manual se guardan las instantáneas PRE de cada dispositivo del grupo de inventario de Ansible. La tarea hace referencia al archivo de configuración jsnapy_config_base_tests.yaml en el directorio ~/jsnapy/testfiles y registra los mensajes en el archivo jsnapy_tests.log del directorio 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"
Para tomar una instantánea de uno o más dispositivos después de realizar cambios, establezca el argumento del action módulo en snap_posty especifique un archivo de configuración o uno o más archivos de prueba.
En el siguiente manual se guardan las instantáneas POST de cada dispositivo del grupo de inventario de Ansible. La tarea hace referencia al mismo archivo de configuración jsnapy_config_base_tests.yaml en el directorio ~/jsnapy/testfiles y registra los mensajes en el archivo jsnapy_tests.log del directorio 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"
Cuando el jsnapy módulo realiza una snap_pre acción o una snap_post acción, guarda cada instantánea para cada host en un archivo separado utilizando nombres de archivo generados automáticamente que contienen una etiqueta 'PRE' o 'POST', respectivamente. Para comparar las PRE instantáneas y POST comprobar rápidamente las actualizaciones o identificar cualquier problema que pueda haber resultado de los cambios, establezca el argumento del módulo en checky especifique el mismo archivo de configuración o archivos de action prueba que se usaron para tomar las instantáneas.
Cuando el módulo realiza una check acción, JSNAPy compara las instantáneas PRE y POST para cada prueba en cada dispositivo y las evalúa según los criterios definidos en la tests: sección de los archivos de prueba. Si los archivos de prueba no definen ningún caso de prueba, JSNAPy compara las instantáneas nodo por nodo. Para comprobar los resultados de la prueba, registre la respuesta del módulo y utilice el ansible.builtin.assert módulo para comprobar el resultado esperado en la respuesta.
En el siguiente manual se comparan las instantáneas tomadas para las acciones ejecutadas snap_pre anteriormente y snap_post para cada dispositivo del grupo de inventario de Ansible. Los resultados se evalúan utilizando los criterios de los archivos de prueba a los que se hace referencia en el archivo de configuración. El manual registra la respuesta del módulo como 'test_result' y utiliza el ansible.builtin.assert módulo para verificar que todas las pruebas pasaron en el dispositivo dado.
---
- 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"
Cuando ejecuta el manual, las aserciones identifican rápidamente qué dispositivos no superaron las pruebas.
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
Realizar operaciones de Snapcheck
JSNAPy le permite tomar instantáneas para los comandos o RPC especificados en los archivos de prueba JSNAPy y evaluar inmediatamente las instantáneas según criterios predefinidos en los casos de prueba. El juniper.device.jsnapy módulo le permite realizar una operación de comprobación instantánea JSNAPy como parte de un libro de estrategias de Ansible.
Para tomar una instantánea y evaluarla inmediatamente en función del conjunto de criterios predefinido de la tests: sección de los archivos de prueba, establezca el argumento del action módulo en snapchecky especifique un archivo de configuración o uno o varios archivos de prueba. Para comprobar los resultados de la prueba, registre la respuesta del módulo y utilice el ansible.builtin.assert módulo para comprobar el resultado esperado en la respuesta.
Por ejemplo, para cada dispositivo del grupo de inventario de Ansible, el siguiente manual guarda una instantánea independiente para cada comando o RPC en los archivos de prueba, registra la respuesta del módulo y utiliza el ansible.builtin.assert módulo para comprobar que todas las pruebas definidas en los archivos de prueba pasaron en ese dispositivo.
---
- 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"
Descripción de la salida del módulo jsnapy
Cuando el juniper.device.jsnapy módulo realiza una snap_presnap_post, o snapcheck acción, guarda automáticamente las instantáneas en el directorio de instantáneas JSNAPy. El módulo utiliza los directorios JSNAPy predeterminados a menos que modifique el archivo de configuración JSNAPy (jsnapy.cfg) para especificar una ubicación diferente. El módulo crea un archivo independiente para cada comando o RPC ejecutado en cada dispositivo del grupo de inventario de Ansible. En la tabla 4 se describen los nombres de archivo de los archivos de instantáneas para cada valor del action argumento.
A partir de Junos Snapshot Administrator en Python versión 1.3.0, los directorios predeterminados para los archivos de prueba JSNAPy y las instantáneas son ~/jsnapy/testfiles y ~/jsnapy/snapshots, respectivamente. Sin embargo, los directorios predeterminados dentro de un entorno virtual o para versiones anteriores son /etc/jsnapy/testfiles y /etc/jsnapy/snapshots.
|
|
Archivos de salida |
|---|---|
|
|
hostname_PRE_hash_.commandformat |
|
|
hostname_POST_hash_.commandformat |
| |
hostname_snap_temp_hash_command.format |
Dónde:
-
hostname: nombre de host del dispositivo en el que se ejecuta el comando o RPC.
-
(PRE | PUBLICAR | snap_temp): etiqueta que identifica la acción. La
snapcheckoperación utiliza la etiqueta en lasPREversiones actuales; en versiones anteriores la operación utiliza lasnap_tempetiqueta. -
hash: hash generado a partir de para archivos de
kwargsprueba que incluyen lasrpcclaves ykwargs.Si los archivos de prueba utilizan el mismo RPC pero incluyen argumentos diferentes, y los RPC se ejecutan en el mismo host, el hash garantiza nombres de archivo de salida únicos en esos casos. Si un archivo de prueba define la
commandclave o si un archivo de prueba define larpcclave pero no lakwargsincluye, se omite el hash. -
command: comando o RPC ejecutado en el dispositivo administrado. El módulo reemplaza los espacios en blanco y los caracteres especiales en el nombre del comando o RPC por guiones bajos ( _ ).
-
format—Formato de la salida, por ejemplo, xml.
El jsnapy módulo diferencia los nombres de archivo de instantánea para una acción determinada basándose solo en el nombre de host y el comando o RPC. Como resultado, si el módulo toma instantáneas en el mismo dispositivo para la misma acción utilizando archivos de prueba que definen el mismo comando o RPC, el módulo generará instantáneas con el mismo nombre de archivo y el nuevo archivo sobrescribirá el archivo antiguo.
Por ejemplo, si el módulo incluye action: "snap_pre" y hace referencia a archivos de prueba que ejecutan los show chassis fpc comandos y show interfaces terse en dispositivos dc1a.example.net y dc1b.example.net, los archivos resultantes son:
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 el módulo incluye action: "snap_post" y hace referencia a un archivo de prueba que ejecuta la RPC con kwargs interface_name: lo0 elemento en el get-interface-information dispositivo dc1a.example.net, el archivo resultante es:
dc1a.example.net_POST_r1w59I99HXxC3u0VXXshbw==_get_interface_information.xml
Además de generar los archivos de instantáneas, el jsnapy módulo también puede devolver las siguientes claves en la respuesta del módulo:
-
action: acción JSNAPy realizada por el módulo. -
changed: indica si el estado del dispositivo ha cambiado. Dado que JSNAPy solo informa sobre el estado, el valor es siemprefalse. -
failed: indica si se produjo un error en la tarea del manual. -
msg—Resultados de la prueba JSNAPy.
Revisar las pruebas JSNAPy fallidas
Cuando ejecuta pruebas de JSNAPy en dispositivos Junos, puede verificar rápidamente si todas las pruebas de JSNAPy han sido aprobadas. Registre la respuesta del jsnapy módulo y utilice el ansible.builtin.assert módulo para comprobar que es passPercentage 100. Sin embargo, si una o más pruebas fallan, puede ser difícil identificar y extraer las pruebas fallidas si el resultado es extenso.
El juniper.device.jsnapy módulo proporciona las siguientes opciones para ver las pruebas JSNAPy fallidas:
-
juniper.device.jsnapycomplemento de devolución de llamada: imprima un resumen de las pruebas JSNAPy fallidas después de la salida del playbook. -
dest_dirmodule argument: escribe las pruebas JSNAPy fallidas en archivos del directorio especificado.
El jsnapy complemento de devolución de llamada le permite extraer y resumir fácilmente la información de las pruebas JSNAPy fallidas. Cuando habilita el complemento de devolución de jsnapy llamada y ejecuta un libro de estrategias que incluye pruebas JSNAPy, el complemento resume la información de las pruebas JSNAPy fallidas después del libro PLAY RECAPde estrategias.
El jsnapy complemento de devolución de llamada está deshabilitado de forma predeterminada. Para habilitar el complemento de devolución de jsnapy llamada, agregue la callbacks_enabled = juniper.device.jsnapy instrucción al archivo de configuración de Ansible.
[defaults] callbacks_enabled = juniper.device.jsnapy
Cuando habilita el complemento de devolución de jsnapy llamada y ejecuta un libro de estrategias, el complemento resume las pruebas JSNAPy fallidas en un formato legible por humanos. Por ejemplo:
...
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"}
A partir de juniper.device la versión 1.0.6, el juniper.device.jsnapy módulo también admite el dest_dir argumento. Puede incluir el argumento a favor check y snapcheck las dest_dir operaciones que evalúan las instantáneas según los criterios de prueba. Cuando realiza una check operación o snapcheck e incluye el dest_dir argumento, el módulo escribe cada prueba JSNAPy fallida para un host determinado en un archivo en el directorio de salida especificado.
Por ejemplo, considere el siguiente libro de estrategias:
---
- 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
Cuando ejecuta el libro de estrategias, el módulo genera un archivo en el dest_dir directorio para cada prueba fallida en el host dado. Por ejemplo, se generaron los siguientes archivos para pruebas fallidas bgp_neighbor y bgp_summary en hosts r1 y 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
Ejemplo: Usar Ansible para realizar una operación JSNAPy Snapcheck
El juniper.device.jsnapy módulo le permite ejecutar pruebas JSNAPy en dispositivos Junos como parte de un manual de estrategias de Ansible. En este ejemplo, se utiliza el jsnapy módulo para realizar una snapcheck acción destinada a verificar el estado operativo de los dispositivos Junos después de aplicar cambios de configuración específicos.
- Requisitos
- Visión general
- Configuración
- Ejecute el libro de estrategias
- Verificación
- Solucionar errores del manual de estrategias de Ansible
Requisitos
En este ejemplo se utilizan los siguientes componentes de hardware y software:
-
Nodo de control de Ansible en ejecución:
-
Python 3.10 o posterior
-
Ansible 2.17 o posterior con la
juniper.devicecolección instalada -
Junos PyEZ versión 2.7.3 o posterior
-
Administrador de instantáneas de Junos en Python versión 1.3.7 o posterior
-
Antes de ejecutar el manual de estrategias de Ansible, asegúrese de tener:
-
Dispositivos Junos con NETCONF sobre SSH habilitado y una cuenta de usuario configurada con los permisos adecuados
-
Par de claves pública y privada SSH configurado para el usuario adecuado en el nodo de control de Ansible y en el dispositivo Junos
-
Archivo de inventario de Ansible existente con los hosts necesarios definidos
Visión general
En este ejemplo, el manual de estrategias de Ansible configura sesiones de emparejamiento BGP en tres dispositivos Junos y utiliza el jsnapy módulo para comprobar que la sesión BGP está establecida para cada dirección vecina. Si el manual verifica que las sesiones se han establecido en un dispositivo, confirma la confirmación de la nueva configuración. Si el manual no confirma la confirmación, el dispositivo Junos revierte automáticamente a la configuración confirmada anteriormente. El proyecto Ansible define las variables de grupo y host para el manual de estrategias en los group_vars directorios y host_vars , respectivamente.
El libro de jugadas tiene dos jugadas. La primera reproducción, Load and commit BGP configuration, genera y ensambla la configuración, carga la configuración en el dispositivo y la confirma mediante una operación confirmada de confirmación. Si se actualiza la configuración, se notifica a un controlador. La obra ejecuta las siguientes tareas:
Remove build directory |
Elimina el directorio de compilación existente para el dispositivo dado, si está presente. |
Create build directory |
Crea un nuevo directorio de compilación vacío para el dispositivo dado. |
Build BGP configuration |
Utiliza el |
Assemble configuration parts |
Utiliza el En este ejemplo, solo estará presente el archivo de configuración BGP y, por lo tanto, el archivo de configuración resultante es idéntico al archivo de configuración BGP representado en la tarea anterior. Si más adelante agrega nuevas tareas para generar archivos de configuración adicionales a partir de otras plantillas, el |
Load and commit config, require confirmation |
Carga la configuración en el dispositivo Junos y confirma la configuración mediante una operación que requiere confirmación Si la configuración solicitada ya está presente en el dispositivo, el |
La segunda reproducción, Verify BGP, realiza una operación JSNAPy snapcheck en cada dispositivo mediante las pruebas de los archivos de prueba JSNAPy. Si todas las pruebas pasan, la jugada también confirma la confirmación. La obra ejecuta las siguientes tareas:
Execute snapcheck |
Realiza una operación JSNAPy En este ejemplo, el manual hace referencia directamente a los archivos de prueba JSNAPy estableciendo el |
Confirm commit |
Ejecuta una operación de comprobación de confirmación, que confirma la operación de confirmación anterior, siempre que la primera jugada de playbook actualice la configuración y que se hayan superado todas las pruebas de JSNAPy. Si el manual actualiza la configuración pero no confirma la confirmación, el dispositivo Junos revierte automáticamente la configuración a la configuración confirmada anteriormente.
Nota:
Puede confirmar la operación de confirmación anterior con una |
Verify BGP configuration |
(Opcional) Indica explícitamente si las pruebas JSNAPy se aprobaron o fallaron en el dispositivo dado. Esta tarea no es específicamente necesaria, pero identifica más fácilmente cuándo fallan las pruebas JSNAPy y en qué dispositivos. |
Configuración
- Definir las variables de grupo
- Definir la plantilla Jinja2 y las variables de host
- Crear los archivos de prueba JSNAPy
- Crear el manual de estrategias de Ansible
- Resultados
Definir las variables de grupo
Procedimiento paso a paso
Para definir las variables de grupo:
-
En el archivo group_vars/todo , defina variables para el directorio de compilación y para los nombres de archivo de los archivos de configuración y registro.
build_dir: "{{ playbook_dir }}/build_conf/{{ inventory_hostname }}" junos_conf: "{{ build_dir }}/junos.conf" logfile: "junos.log"
Definir la plantilla Jinja2 y las variables de host
Definir la plantilla Jinja2
Para crear la plantilla Jinja2 que se utiliza para generar la configuración del BGP:
Cree un archivo denominado bgp-template.j2 en el directorio del manual.
Agregue la plantilla de configuración BGP al archivo.
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; } } }
Definir las variables de host
Para definir las variables de host que se utilizan con la plantilla Jinja2 para generar la configuración del BGP:
En el directorio host_vars del proyecto, cree un archivo independiente denominado hostname.yaml para cada host.
Defina las variables para el host r1 en el archivo 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.3Defina las variables para el host r2 en el archivo 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.3Defina las variables para el host r3 en el archivo 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
Crear los archivos de prueba JSNAPy
Procedimiento paso a paso
El jsnapy módulo hace referencia a archivos de prueba JSNAPy en el directorio ~/jsnapy/testfiles . Para crear los archivos de prueba JSNAPy:
Cree el archivo jsnapy_test_file_bgp_states.yaml , que ejecuta el
show bgp neighborcomando y prueba que se ha establecido el estado del par BGP.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']}}>"Cree el archivo jsnapy_test_file_bgp_summary.yaml , que ejecuta el
show bgp summarycomando y afirma que el recuento de pares BGP abajo debe ser 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']}}>"
Crear el manual de estrategias de Ansible
- Definir la primera jugada para configurar el dispositivo
- Defina la segunda jugada para realizar operaciones JSNAPy
Definir la primera jugada para configurar el dispositivo
Para crear la primera jugada, que representa la configuración, la carga en el dispositivo y confirma la configuración como una operación confirmada:
Incluya la plantilla para el libro de estrategias y la primera jugada, que ejecuta los módulos localmente.
--- - name: Load and commit BGP configuration hosts: bgp_routers connection: local gather_facts: no
Cree las tareas que reemplazan el directorio de compilación existente con un directorio vacío, que almacenará los nuevos archivos de configuración.
tasks: - name: Remove build directory file: path: "{{ build_dir }}" state: absent - name: Create build directory file: path: "{{ build_dir }}" state: directoryCree la tarea que representa la configuración del BGP a partir del archivo de plantilla Jinja2 y las variables de host y la almacena en el archivo bgp.conf del directorio de compilación de ese host.
- name: Build BGP configuration template: src: "{{ playbook_dir }}/bgp-template.j2" dest: "{{ build_dir }}/bgp.conf"Cree una tarea para ensamblar los archivos de configuración del directorio de compilación en el archivo de configuración junos.conf final.
- name: Assemble configuration parts assemble: src: "{{ build_dir }}" dest: "{{ junos_conf }}"Cree la tarea que carga la configuración en el dispositivo, realiza una operación de confirmación que requiere confirmación y notifica al controlador especificado, siempre que se haya cambiado la configuración.
- 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 connectionsCree un controlador que detenga la ejecución del manual si se actualiza la configuración del dispositivo. Establezca el tiempo de pausa en un valor adecuado para su entorno.
handlers: - name: Waiting for BGP peers to establish connections pause: seconds=60
Defina la segunda jugada para realizar operaciones JSNAPy
Para crear la segunda reproducción, que realiza una operación de comprobación instantánea de JSNAPy y confirma la configuración confirmada, siempre que la configuración haya cambiado y las pruebas de JSNAPy hayan pasado:
Incluya la plantilla para la segunda reproducción, que ejecuta los módulos localmente.
- name: Verify BGP hosts: bgp_routers connection: local gather_facts: no
Cree una tarea para realizar una operación de comprobación instantánea de JSNAPy basada en las pruebas de los archivos de prueba de JSNAPy dados y registre la respuesta del módulo.
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_resultCree la tarea para confirmar la confirmación siempre que se cumplan las condiciones dadas.
# 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"(Opcional) Cree una tarea que use el
ansible.builtin.assertmódulo para afirmar que se han superado las pruebas JSNAPy.- name: Verify BGP configuration ansible.builtin.assert: that: - "snapcheck_result.passPercentage == 100" msg: "JSNAPy test on {{ inventory_hostname }} failed"
Resultados
En el nodo de control Ansible, revise el manual completado. Si el cuaderno no muestra el código deseado, repita las instrucciones de esta sección para corregir el manual.
---
- 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"
Ejecute el libro de estrategias
Para ejecutar el manual:
-
Ejecute el
ansible-playbookcomando en el nodo de control y proporcione la ruta del manual y las opciones deseadas.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
Verificación
Verificar los vecinos del BGP
Propósito
Compruebe que la sesión BGP está establecida para cada dirección vecina.
Los archivos de prueba JSNAPy prueban que la sesión BGP está establecida para cada dirección vecina y que no hay pares inactivos. La Verify BGP configuration salida de la tarea le permite verificar rápidamente que el dispositivo dado pasó todas las pruebas JSNAPy. Si el JSNAPy passPercentage es igual al 100 por ciento, la tarea se incluye "msg": "All assertions passed" en la salida de la tarea.
Acción
Revise el resultado de la Verify BGP configuration tarea y compruebe que cada dispositivo devuelve el All assertions passed mensaje.
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"
}
Significado
El All assertions passed mensaje indica que las sesiones BGP se han establecido correctamente en los dispositivos.
Solucionar errores del manual de estrategias de Ansible
- Solucionar errores de carga de configuración
- Solucionar problemas de pruebas JSNAPy fallidas
- Solucionar problemas de confirmaciones de confirmación fallidas
Solucionar errores de carga de configuración
Problema
El manual de estrategias de Ansible genera un ConfigLoadError error que indica que no pudo cargar la configuración en el dispositivo debido a un error de sintaxis.
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)"}
Solución
El manual representa la configuración de Junos OS mediante la plantilla Jinja2 y las variables de host definidas para ese dispositivo en el directorio host_vars . El manual genera un error de sintaxis cuando la plantilla Jinja2 produce una configuración no válida. Para corregir este error, actualice la plantilla Jinja2 para corregir el elemento identificado por la bad_element clave en el mensaje de error.
Solucionar problemas de pruebas JSNAPy fallidas
Problema
El Verify BGP configuration resultado de la tarea indica que se produjo un error en la aserción, porque JSNAPy passPercentage no era igual al 100 por ciento.
TASK [Verify BGP configuration] *************************************************************
fatal: [r1]: FAILED! => {
"assertion": "snapcheck_result.passPercentage == 100",
"changed": false,
"evaluated_to": false,
"msg": "JSNAPy test on r1 failed"
}
La aserción falla cuando el dispositivo no ha establecido la sesión BGP con su vecino o la sesión deja de funcionar. Si se produce un error en la aserción y la configuración de ese dispositivo se actualizó en la primera reproducción, el manual no confirma la confirmación de la nueva configuración en el dispositivo y el dispositivo revierte la configuración a la configuración confirmada anteriormente.
Solución
Las pruebas JSNAPy pueden fallar si la snapcheck operación se realiza antes de que los pares puedan establecer la sesión o porque los vecinos del BGP no están configurados correctamente. Si el resultado del manual indica que la configuración se cargó y confirmó correctamente en el dispositivo, intente aumentar el intervalo de pausa del controlador a un valor adecuado para su entorno y vuelva a ejecutar el manual.
handlers:
- name: Waiting for BGP peers to establish connections
pause: seconds=75
Si las pruebas siguen fallando, compruebe que la plantilla Jinja2 y las variables de host para cada dispositivo contienen los datos correctos y que la configuración resultante para cada dispositivo es correcta.
Solucionar problemas de confirmaciones de confirmación fallidas
Problema
La configuración no se confirmó en uno o más dispositivos.
TASK [Confirm commit] *********************************************************************** skipping: [r2] skipping: [r2] skipping: [r3]
Solución
El libro de estrategias solo confirma la configuración si cambió y se realizan las pruebas de JSNAPy. Si el resultado de la Load and commit config, require confirmation tarea indica que la configuración no cambió, el manual no ejecuta la tarea para confirmar la confirmación. Si la configuración cambió pero no se confirmó, las pruebas JSNAPy fallaron. Las pruebas JSNAPy pueden fallar si los vecinos del BGP no están configurados correctamente o si el manual no proporciona suficiente tiempo entre las reproducciones para que los dispositivos establezcan la sesión BGP. Para obtener más información, consulte Solución de problemas de pruebas JSNAPy fallidas.