clay584.parse_genie

Parse Genie

Publié

Rôle Ansible Version Ansible Version Python

État de construction Score de qualité Ansible

ATTENTION!!! - Si vous rencontrez un problème avec une commande qui échoue à analyser, il est possible qu'il y ait un bug dans la bibliothèque d'analyse maintenue par Cisco. Pour ces problèmes, vous pouvez ouvrir une issue ici.

Le filtre network genie prend la sortie de commandes CLI non structurée de tous les systèmes d'exploitation réseau Cisco et en produit des données structurées. Bien que similaire à d'autres parseurs CLI réseau déjà disponibles (parse_cli, parse_cli_textfsm), ce parseur est alimenté par une bibliothèque très mature et robuste écrite par Cisco appelée Genie (et le cadre sous-jacent pyATS). Cela fournit plus de 1200 parseurs qui transforment la configuration et la sortie CLI en données structurées qui sont normalisées et conformes aux modèles de données standard, indépendants du système d'exploitation.

La bibliothèque Genie peut également servir de moteur pour analyser du texte sous forme tabulaire et non tabulaire, en utilisant beaucoup moins de code que les méthodes de parsing traditionnelles. Par conséquent, elle peut être utilisée pour analyser la sortie de n'importe quel fournisseur, pas seulement celle des appareils Cisco. Cependant, cela nécessiterait d'écrire des parseurs personnalisés. Cette version ne comprend pas la fonctionnalité permettant d'utiliser des parseurs personnalisés. Les parseurs pris en charge sont ceux inclus dans la version de Genie que l'utilisateur a installée sur la machine de contrôle Ansible.

La liste des systèmes d'exploitation et des commandes pris en charge, ainsi que les définitions de schéma des données (modèles de données) qui décrivent exactement quels champs et types de données seront renvoyés pour une commande donnée, sont disponibles auprès de Cisco via le lien ci-dessous.

https://pubhub.devnetcloud.com/media/genie-feature-browser/docs/#/parsers

Prérequis

Ce plugin nécessitera les éléments suivants :

  1. Python 3.4+
  2. Paquets pyATS et Genie
  3. Ansible 2.7+ (Cela devrait fonctionner avec des versions antérieures tant que les autres exigences sont satisfaites)

Installation

Veuillez suivre ces instructions pour garantir que le plugin de filtre fonctionnera avec vos playbooks :

  1. Créez un répertoire pour votre playbook et accédez-y. mkdir network_ops && cd network_ops
  2. Créez un environnement virtuel. python3 -m venv .venv
  3. Activez l'environnement virtuel. source .venv/bin/activate
  4. Installez Ansible. pip install ansible
  5. Installez Genie et pyATS. pip install genie
  6. Installez le rôle parse_genie depuis Ansible Galaxy. ansible-galaxy install clay584.parse_genie

Mappings Ansible à Genie OS

Voici les correspondances de l'ansible_network_os d'Ansible au os de Genie :

Ansible Network OS Genie OS
ios ios, iosxe
nxos nxos
iosxr iosxr
junos junos

Si vous travaillez avec IOS ou IOS-XE, il y a une ambiguïté car Ansible considère IOS et IOS-XE comme identiques, donc ansible_network_os = ios, mais Genie a besoin de savoir spécifiquement s'il s'agit d'IOS ou d'IOS-XE afin d'analyser correctement la sortie CLI. Si vous passez ansible_network_os à ce plugin de filtre et qu'il est égal à ios, parse_genie essaiera d'abord de l'analyser avec Genie en utilisant os=ios, et si cela échoue, il essaiera ensuite de l'analyser avec os=iosxe.

Gardez cela à l'esprit lors de la création de vos playbooks. Il peut être préférable de passer le véritable OS à parse_genie. Vous pouvez le faire en gardant une autre variable d'inventaire ou une variable d'hôte pour spécifier le système d'exploitation Genie pour chaque appareil réseau et en utilisant cette variable comme OS pour parse_genie.

Utilisation

Assurez-vous de lire le rôle parse_genie avant de tenter de l'utiliser plus tard dans votre playbook.

...tronqué...

  tasks:
  - name: Lire le rôle parse_genie
    include_role:
      name: clay584.parse_genie
      
...tronqué...

Exemple court

Pour convertir la sortie d'une commande CLI d'un appareil réseau, utilisez le filtre parse_genie comme montré dans cet exemple (n'utilisez pas de commandes CLI abrégées).

Conversion de la sortie CLI de la commande show version d'un appareil Cisco IOS-XE en données structurées ::

{{ cli_output | parse_genie(command='show version', os='iosxe') }}

Pour une abstraction plus approfondie, vous pourriez vouloir ajouter platform à parse_genie.

{{ cli_output | parse_genie(command='show version', os='iosxe', platform='asr1k') }}

L'exemple ci-dessus donnerait le résultat suivant :

{
    "version": {
        "chassis": "CSR1000V",
        "chassis_sn": "9TKUWGKX5MO",
        "curr_config_register": "0x2102",
        "disks": {
            "bootflash:.": {
                "disk_size": "7774207",
                "type_of_disk": "disque dur virtuel"
            },
            "webui:.": {
                "disk_size": "0",
                "type_of_disk": "Fichiers WebUI ODM"
            }
        },
        "hostname": "host-172-16-1-96",
        "image_id": "X86_64_LINUX_IOSD-UNIVERSALK9-M",
        "image_type": "image de production",
        "last_reload_reason": "Commande de rechargement",
        "license_level": "ax",
        "license_type": "Par défaut. Aucun licence valide trouvée.",
        "main_mem": "1126522",
        "mem_size": {
            "configuration non volatile": "32768",
            "physique": "3018840"
        },
        "next_reload_license_level": "ax",
        "number_of_intfs": {
            "Gigabit Ethernet": "2"
        },
        "os": "IOS-XE",
        "platform": "Virtual XE",
        "processor_type": "VXE",
        "rom": "IOS-XE ROMMON",
        "rtr_type": "CSR1000V",
        "system_image": "bootflash:packages.conf",
        "uptime": "2 minutes",
        "uptime_this_cp": "3 minutes",
        "version": "16.5.1b,",
        "version_short": "16.5"
    }
}

Exemple complet #1

Playbook:

---

- hosts: localhost
  connection: local
  vars:
    show_version_output: |
      Cisco IOS XE Software, Version 16.05.01b
      Cisco IOS Software [Everest], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.5.1b, RELEASE SOFTWARE (fc1)
      Support Technique: http://www.cisco.com/techsupport
      Copyright (c) 1986-2017 par Cisco Systems, Inc.
      Compile Mar 11-Apr-17 16:41 par mcpre


      Logiciel Cisco IOS-XE, Copyright (c) 2005-2017 par Cisco Systems, Inc.
      Tous droits réservés. Certains composants du logiciel Cisco IOS-XE sont
      sous licence de la GNU General Public License ("GPL") Version 2.0. Le
      code logiciel sous licence GPL Version 2.0 est un logiciel libre qui vient
      SANS AUCUNE GARANTIE. Vous pouvez redistribuer et/ou modifier ce code GPL
      sous les termes de la GPL Version 2.0. Pour plus de détails, consultez la
      documentation ou le fichier "License Notice" accompagnant le logiciel IOS-XE,
      ou l'URL applicable donnée sur le flyer accompagnant le logiciel IOS-XE.


      ROM : IOS-XE ROMMON

      host-172-16-1-96 temps de fonctionnement est de 2 minutes
      Temps de fonctionnement pour ce processeur de contrôle est de 3 minutes
      Le système est retourné à ROM par rechargement
      Le fichier image du système est "bootflash:packages.conf"
      Dernière raison de rechargement : Commande de rechargement



      Ce produit contient des fonctionnalités cryptographiques et est soumis aux lois des
      États-Unis et locales concernant l'importation, l'exportation, le transfert et
      l'utilisation. La livraison de produits cryptographiques Cisco n'implique pas
      d'autorité tierce pour importer, exporter, distribuer ou utiliser le chiffrement.
      Les importateurs, exportateurs, distributeurs et utilisateurs sont responsables de
      la conformité avec les lois américaines et locales. En utilisant ce produit, vous
      acceptez de vous conformer aux lois et réglementations applicables. Si vous ntes pas
      en mesure de respecter les lois américaines et locales, renvoyez immédiatement ce produit.

      Un résumé des lois américaines régissant les produits cryptographiques Cisco peut être trouvé à :
      http://www.cisco.com/wwl/export/crypto/tool/stqrg.html

      Si vous avez besoin d'aide supplémentaire, veuillez nous contacter par e-mail à
      [email protected].

      Niveau de licence : ax
      Type de licence : Par défaut. Aucun licence valide trouvée.
      Niveau de licence de rechargement suivant : ax

      cisco CSR1000V (VXE) processeur (révision VXE) avec 1126522K/3075K octets de mémoire.
      ID de la carte processeur 9TKUWGKX5MO
      2 interfaces Gigabit Ethernet
      32768K octets de mémoire de configuration non volatile.
      3018840K octets de mémoire physique.
      7774207K octets de disque dur virtuel à bootflash:.
      0K octets de fichiers WebUI ODM à webui:.

      Le registre de configuration est 0x2102

  tasks:
  - name: Lire le rôle parse_genie
    include_role:
      name: clay584.parse_genie

  - name: Déboguer le filtre Genie
    debug:
      msg: "{{ show_version_output | parse_genie(command='show version', os='iosxe') }}"
    delegate_to: localhost

Sortie :

$ ansible-playbook -i inventory debug.yml

PLAY [localhost] *************************************************************************

TASK [Rassemblement desfaits] *******************************************************************
ok: [localhost]

TASK [Lire le rôle parse_genie] **********************************************************

TASK [Déboguer le filtre Genie] ****************************************************************
ok: [localhost -> localhost] => {
    "msg": {
        "version": {
            "chassis": "CSR1000V",
            "chassis_sn": "9TKUWGKX5MO",
            "curr_config_register": "0x2102",
            "disks": {
                "bootflash:.": {
                    "disk_size": "7774207",
                    "type_of_disk": "disque dur virtuel"
                },
                "webui:.": {
                    "disk_size": "0",
                    "type_of_disk": "Fichiers WebUI ODM"
                }
            },
            "hostname": "host-172-16-1-96",
            "image_id": "X86_64_LINUX_IOSD-UNIVERSALK9-M",
            "image_type": "image de production",
            "last_reload_reason": "Commande de rechargement",
            "license_level": "ax",
            "license_type": "Par défaut. Aucun licence valide trouvée.",
            "main_mem": "1126522",
            "mem_size": {
                "configuration non volatile": "32768",
                "physique": "3018840"
            },
            "next_reload_license_level": "ax",
            "number_of_intfs": {
                "Gigabit Ethernet": "2"
            },
            "os": "IOS-XE",
            "platform": "Virtual XE",
            "processor_type": "VXE",
            "rom": "IOS-XE ROMMON",
            "rtr_type": "CSR1000V",
            "system_image": "bootflash:packages.conf",
            "uptime": "2 minutes",
            "uptime_this_cp": "3 minutes",
            "version": "16.5.1b,",
            "version_short": "16.5"
        }
    }
}

Exemple complet #2

Playbook :

---

- hosts: csr1000v
  gather_facts: False
  tasks:
  - name: Lire le rôle parse_genie
    include_role:
      name: clay584.parse_genie

  - name: Obtenir des données de l'appareil
    ios_command:
      commands: show arp vrf Mgmt-intf
    register: arp_output

  - name: Imprimer les données structurées
    debug:
      msg: "{{ arp_output['stdout'][0] | parse_genie(command='show arp vrf Mgmt-intf', os='iosxe') }}"
    delegate_to: localhost

Sortie :

$ ansible-playbook -i inventory playbook.yml

PLAY [csr1000v] **************************************************************************

TASK [Lire le rôle parse_genie] **********************************************************

TASK [Obtenir des données de l'appareil] **************************************************************
ok: [csr1000v]

TASK [Imprimer les données structurées] *************************************************************
ok: [csr1000v -> localhost] => {
    "msg": {
        "interfaces": {
            "GigabitEthernet1": {
                "ipv4": {
                    "neighbors": {
                        "172.16.1.111": {
                            "age": "0",
                            "ip": "172.16.1.111",
                            "link_layer_address": "5e00.4004.0000",
                            "origin": "dynamique",
                            "protocol": "Internet",
                            "type": "ARPA"
                        },
                        "172.16.1.114": {
                            "age": "-",
                            "ip": "172.16.1.114",
                            "link_layer_address": "5e00.4001.0000",
                            "origin": "statique",
                            "protocol": "Internet",
                            "type": "ARPA"
                        }
                    }
                }
            }
        }
    }
}

Analyse tabulaire générique

Cisco Genie prend en charge 1200 commandes et plus, mais pour ces commandes d'affichage où il n'y a pas de parseur créé par Cisco, il existe la fonctionnalité d'analyse tabulaire générique. Pour plus d'informations sur la fonctionnalité d'analyse tabulaire de Genie, consultez leur oper_fill_tabular documentation.

Comment fonctionne l'analyse tabulaire

Pour analyser la sortie d'une commande lorsqu'un parseur a été construit, il suffit de fournir la commande, la sortie de commande et le os. Mais s'il n'y a pas de parseur, vous devez spécifier des informations supplémentaires pour aider le parseur à déterminer comment analyser la sortie de la commande. Ces données supplémentaires sont de deux types :

  1. En-têtes - Les en-têtes de colonne comme le montre la sortie de la commande.
  2. Index - La clé des éléments du dictionnaire que le parseur renverra.

Considérons l'exemple suivant :

  1. Commande: show ip sla summary
  2. Sortie de commande :
sumé de la dernière opération des IPSLAs
Codes : * actif, ^ inactif, ~ en attente
Toutes les statistiques sont en millisecondes. Les statistiques avec u sont en microsecondes

ID           Type           Destination       Statistiques               Retour        Dernière
                                                                  Code          Exécution
------------------------------------------------------------------------------------------------
*1           udp-jitter      10.0.0.2          RTT=900u           OK             Il y a 20 secondes
*2           icmp-echo       10.0.0.2          RTT=1              OK              Il y a 3 secondes
  1. En-têtes - ID, Type, Destination, Statistiques, Code de retour et Dernière exécution.
  2. Index - Nous voulons utiliser la colonne ID comme index pour ces données lorsque nous les récupérons du parseur.
  3. Sortie du parseur :
{'*1': {'Destination ': '10.0.0.2',
        'ID ': '*1',
        'Dernière exécution': 'Il y a 20 secondes',
        'Code de retour': 'OK',
        'Statistiques ': 'RTT=900u',
        'Type ': 'udp-jitter'},
 '*2': {'Destination ': '10.0.0.2',
        'ID ': '*2',
        'Dernière exécution': 'Il y a 3 secondes',
        'Code de retour': 'OK',
        'Statistiques ': 'RTT=1',
        'Type ': 'icmp-echo'}}

Préparer l'utilisation du parseur tabulaire

Pour utiliser ce parseur tabulaire, nous devons d'abord construire les en-têtes et l'index pour une commande donnée sur un OS donné dans un format pouvant être lu par un playbook Ansible et ensuite transmis au plugin de filtre parse_genie.

Pour ce faire, vous devez créer un fichier de variables dans votre playbook qui a le format suivant. Il est organisé par OS, puis par commande. Sous chaque commande, les en-têtes et l'index sont définis. Vous pouvez définir autant de commandes que vous le souhaitez pour chaque système d'exploitation réseau tant que cela reste dans cette structure de données.

parse_genie:
  ios:
    "show ip sla summary":
      headers:
        - - ID
          - Type
          - Destination
          - Statistiques
          - Retour
          - Dernière
        - - ''
          - ''
          - ''
          - ''
          - Code
          - Exécution
      index:
        - 0
  iosxe:
    "show ip sla summary":
      headers:
        - - ID
          - Type
          - Destination
          - Statistiques
          - Retour
          - Dernière
        - - ''
          - ''
          - ''
          - ''
          - Code
          - Exécution
      index:
        - 1

L'équivalent Python du format YAML ci-dessus est :

python_dict = {
  "parse_genie": {
    "ios": {
      "show ip sla summary": {
        "headers": [
          [
            "ID", 
            "Type", 
            "Destination", 
            "Statistiques", 
            "Retour", 
            "Dernière"
          ], 
          [
            "", 
            "", 
            "", 
            "", 
            "Code", 
            "Exécution"
          ]
        ], 
        "index": [
          0
        ]
      }
    }, 
    "iosxe": {
      "show ip sla summary": {
        "headers": [
          [
            "ID", 
            "Type", 
            "Destination", 
            "Statistiques", 
            "Retour", 
            "Dernière"
          ], 
          [
            "", 
            "", 
            "", 
            "", 
            "Code", 
            "Exécution"
          ]
        ], 
        "index": [
          1
        ]
      }
    }
  }
}

Appeler le parseur tabulaire dans un playbook

Maintenant que nous avons défini une commande tabulaire générique et ses en-têtes et index, nous pouvons réellement l'appeler depuis un playbook.

Tout d'abord, nous lisons le fichier de variables qui contient les métadonnées de la commande d'analyse tabulaire générique.

- name: Inclure le fichier vars avec les métadonnées de commande générique
  include_vars:
    file: parse_genie_generic_commands.yml
    name: parse_genie

Ensuite, nous passons la sortie de la commande à parse_genie, mais avec quelques paramètres supplémentaires.

- name: Analyser la sortie de commande tabulaire générique
  debug:
    msg: "{{ command_output | parse_genie(command='show ip sla summary', os='ios', generic_tabular=True, generic_tabular_metadata=parse_genie) }}"
  delegate_to: localhost

La sortie analysée résultante apparaîtra comme suit :

ok: [localhost -> localhost] => {
    "msg": {
        "*1": {
            "Destination ": "10.0.0.2",
            "ID ": "*1",
            "Dernière exécution": "Il y a 20 secondes",
            "Code de retour": "OK",
            "Statistiques ": "RTT=900u",
            "Type ": "udp-jitter"
        },
        "*2": {
            "Destination ": "10.0.0.2",
            "ID ": "*2",
            "Dernière exécution": "Il y a 3 secondes",
            "Code de retour": "OK",
            "Statistiques ": "RTT=1",
            "Type ": "icmp-echo"
        }
    }
}

Exemple complet #1

Playbook :


---

- hosts: localhost
  connection: local
  vars:
    out_ios_sla: |
      Résumé de la dernière opération des IPSLAs
      Codes : * actif, ^ inactif, ~ en attente
      Toutes les statistiques sont en millisecondes. Les statistiques avec u sont en microsecondes

      ID           Type           Destination       Statistiques               Retour        Dernière
                                                                        Code          Exécution
      ------------------------------------------------------------------------------------------------
      *1           udp-jitter      10.0.0.2          RTT=900u           OK             Il y a 20 secondes
      *2           icmp-echo       10.0.0.2          RTT=1              OK              Il y a 3 secondes

  tasks:
    - name: Inclure le rôle Parse Genie
      include_role:
        name: clay584.parse_genie

    - name: Inclure le fichier vars qui a les métadonnées de commande tabulaire générique
      include_vars:
        file: parse_genie_generic_commands.yml
        name: parse_genie

    - name: Tester le filtre Genie pour les données tabulaires génériques
      debug:
        msg: "{{ out_ios_sla | parse_genie(command='test show ip sla summary', os='ios', generic_tabular=True, generic_tabular_metadata=parse_genie) }}"
      delegate_to: localhost

Contenu de parse_genie_generic_commands.yml :


---

parse_genie:
  ios:
    "test show ip sla summary":
      headers:
        - - ID
          - Type
          - Destination
          - Statistiques
          - Retour
          - Dernière
        - - ''
          - ''
          - ''
          - ''
          - Code
          - Exécution
      index:
        - 0
  iosxe:
    "test show ip sla summary":
      headers:
        - - ID
          - Type
          - Destination
          - Statistiques
          - Retour
          - Dernière
        - - ''
          - ''
          - ''
          - ''
          - Code
          - Exécution
      index:
        - 1

Sortie du playbook :


PLAY [localhost] ******************************************************************************************************************************************************************************************************************************************************************

TASK [Rassemblement des faits] ************************************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Inclure le rôle Parse Genie] ***************************************************************************************************************************************************************************************************************************************************

TASK [Inclure les vars] ***************************************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Tester le filtre Genie pour les données tabulaires génériques] *********************************************************************************************************************************************************************************************************************************
ok: [localhost -> localhost] => {
    "msg": {
        "*1": {
            "Destination ": "10.0.0.2",
            "ID ": "*1",
            "Dernière exécution": "Il y a 20 secondes",
            "Code de retour": "OK",
            "Statistiques ": "RTT=900u",
            "Type ": "udp-jitter"
        },
        "*2": {
            "Destination ": "10.0.0.2",
            "ID ": "*2",
            "Dernière exécution": "Il y a 3 secondes",
            "Code de retour": "OK",
            "Statistiques ": "RTT=1",
            "Type ": "icmp-echo"
        }
    }
}

PLAY RECAP ************************************************************************************************************************************************************************************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0   

Développement

Configurez votre environnement de développement :

  1. Clonez le dépôt et accédez-y. git clone https://github.com/clay584/parse_genie.git && cd parse_genie
  2. Créez un environnement virtuel. python3 -m venv .venv
  3. Activez l'environnement virtuel. source .venv/bin/activate
  4. Installez Ansible. pip install ansible
  5. Installez Genie et pyATS. pip install genie
  6. Installez yamllint. pip install yamllint

Test

Exécutez ces commandes pour tester localement :

  1. Lint tous les fichiers YAML. yamllint -c yamllint_config.yml *
  2. Exécutez le playbook de test. ansible-playbook tests/test.yml --connection=local -i tests/inventory

Pousser

Ansible Galaxy fonctionne sur des tags.

  1. git commit -m"whatever'
  2. git tag -a X.X.X - où X.X.X est un numéro de version sémantique.
  3. git push origin master
  4. git push X.X.X
À propos du projet

Filter plugin for network CLI parsing using Cisco's Genie/pyATS

Installer
ansible-galaxy install clay584.parse_genie
Licence
gpl-3.0
Téléchargements
63.8k
Propriétaire
Brought to you by Carl's Jr.