clay584.parse_genie

Parse Genie

Published

Ansible-Rolle Ansible-Version Python-Version

Build-Status Ansible-Qualitätsbewertung

ACHTUNG!!! - Wenn Sie ein Problem haben, bei dem ein Befehl nicht geparst werden kann, könnte es einen Fehler in der Parsing-Bibliothek geben, die von Cisco gewartet wird. Für solche Probleme können Sie hier ein Issue öffnen: hier.

Der Netzwerk-Giebel-Filter nimmt unstrukturierte Ausgaben von Netzwerk-CLI-Befehlen aus allen Cisco-Netzbetriebssystemen und gibt strukturierte Daten aus. Während er ähnlich wie andere Netzwerk-CLI-Parser ist (parse_cli, parse_cli_textfsm), wird dieser Parser von einer sehr ausgereiften und robusten Bibliothek betrieben, die von Cisco geschrieben wurde und Genie heißt (und das zugrunde liegende Framework pyATS). Dies bietet über 1200 Parser, die Konfigurationen und CLI-Ausgaben in strukturierte Daten umwandeln, die standardisiert und OS-unabhängig sind.

Die Genie-Bibliothek kann auch als Engine verwendet werden, um tabellarische und nicht-tabellarische Freitexte mit viel weniger Code zu parsen als traditionelle Parser benötigen. Daher kann sie verwendet werden, um Ausgaben von verschiedenen Anbietern zu parsen, nicht nur von Cisco-Geräten. Dies würde jedoch das Schreiben benutzerdefinierter Parser erfordern. Diese Version enthält nicht die Funktionalität, um benutzerdefinierte Parser zu verwenden. Die unterstützten Parser sind die, die in der Genie-Version enthalten sind, die der Benutzer auf der Ansible-Controllmaschine installiert hat.

Die Liste der unterstützten Betriebssysteme und Befehle sowie die Schema-Definitionen der Daten (Datenmodelle), die genau beschreiben, welche Felder und Datentypen für einen bestimmten Befehl zurückgegeben werden, sind über den folgenden Cisco-Link verfügbar:

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

Voraussetzungen

Dieses Plugin benötigt Folgendes:

  1. Python 3.4+
  2. pyATS und Genie-Pakete
  3. Ansible 2.7+ (Es sollte auch mit älteren Versionen funktionieren, solange die anderen Anforderungen erfüllt sind)

Installation

Bitte folgen Sie diesen Anweisungen, um sicherzustellen, dass das Filter-Plugin mit Ihren Playbooks funktioniert:

  1. Erstellen Sie ein Verzeichnis für Ihr Playbook und gehen Sie hinein. mkdir network_ops && cd network_ops
  2. Erstellen Sie eine virtuelle Umgebung. python3 -m venv .venv
  3. Aktivieren Sie die virtuelle Umgebung. source .venv/bin/activate
  4. Installieren Sie Ansible. pip install ansible
  5. Installieren Sie Genie und pyATS. pip install genie
  6. Installieren Sie die parse_genie-Rolle aus Ansible Galaxy. ansible-galaxy install clay584.parse_genie

Ansible-zu-Genie-OS-Zuordnungen

Unten stehen die Zuordnungen von Ansibles ansible_network_os zu Genies os:

Ansible Netzwerk-OS Genie OS
ios ios, iosxe
nxos nxos
iosxr iosxr
junos junos

Wenn Sie mit IOS oder IOS-XE arbeiten, gibt es eine Unklarheit, da Ansible IOS und IOS-XE als gleich betrachtet und somit ansible_network_os = ios angibt, aber Genie genau wissen muss, ob es sich um IOS oder IOS-XE handelt, um die CLI-Ausgabe korrekt zu parsen. Wenn Sie ansible_network_os an dieses Filter-Plugin übergeben und es gleich ios ist, wird parse_genie zuerst versuchen, es mit Genie unter Verwendung von os=ios zu parsen, und falls das fehlschlägt, dann mit os=iosxe.

Behalten Sie das im Hinterkopf, wenn Sie Ihre Playbooks erstellen. Es kann am besten sein, das echte OS an parse_genie zu übergeben. Sie können das tun, indem Sie eine weitere Inventarvariable oder host_var verwenden, um das Genie-OS für jedes Netzwerkgerät anzugeben und diese Variable als OS für parse_genie zu verwenden.

Nutzung

Stellen Sie sicher, dass Sie die parse_genie-Rolle lesen, bevor Sie versuchen, sie später in Ihrem Playbook zu verwenden.

...abgekürzt...

  Aufgaben:
  - name: parse_genie-Rolle einlesen
    include_role:
      name: clay584.parse_genie
      
...abgekürzt...

Kurzes Beispiel

Um die Ausgabe eines Netzwerkgeräte-CLI-Befehls zu konvertieren, verwenden Sie den parse_genie-Filter wie im folgenden Beispiel gezeigt (verwenden Sie keine abgekürzten CLI-Befehle).

Konvertieren der CLI-Ausgabe des Befehls show version von einem Cisco IOS-XE-Gerät in strukturierte Daten::

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

Für eine tiefere Abstraktion möchten Sie möglicherweise platform zu parse_genie hinzufügen.

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

Das obige Beispiel würde folgendes ergeben:

{
    "version": {
        "chassis": "CSR1000V",
        "chassis_sn": "9TKUWGKX5MO",
        "curr_config_register": "0x2102",
        "disks": {
            "bootflash:.": {
                "disk_size": "7774207",
                "type_of_disk": "virtual hard disk"
            },
            "webui:.": {
                "disk_size": "0",
                "type_of_disk": "WebUI ODM Files"
            }
        },
        "hostname": "host-172-16-1-96",
        "image_id": "X86_64_LINUX_IOSD-UNIVERSALK9-M",
        "image_type": "production image",
        "last_reload_reason": "Reload Command",
        "license_level": "ax",
        "license_type": "Default. No valid license found.",
        "main_mem": "1126522",
        "mem_size": {
            "non-volatile configuration": "32768",
            "physical": "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"
    }
}

Vollständiges Beispiel #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)
      Technischer Support: http://www.cisco.com/techsupport
      Copyright (c) 1986-2017 von Cisco Systems, Inc.
      Kompiliert Tue 11-Apr-17 16:41 von mcpre


      Cisco IOS-XE Software, Copyright (c) 2005-2017 von Cisco Systems, Inc.
      Alle Rechte vorbehalten. Bestimmte Komponenten der Cisco IOS-XE-Software sind
      unter der GNU General Public License ("GPL") Version 2.0 lizenziert. Der
      unter der GPL Version 2.0 lizenzierte Softwarecode ist freie Software, die
      ABSOLUT NULL GARANTIE mit sich bringt. Sie können solchen GPL-Code unter den Bedingungen der GPL-Version 2.0 weitergeben und/oder ändern. Für weitere Informationen siehe die
      Dokumentation oder die Datei "Lizenzhinweis" zur IOS-XE-Software
      oder die entsprechende URL in dem Flyer zur IOS-XE-Software.


      ROM: IOS-XE ROMMON

      host-172-16-1-96 läuft seit 2 Minuten
      Die Betriebszeit dieses Steuerprozessors beträgt 3 Minuten
      System wurde wegen Neustart an ROM zurückgegeben
      Systembilddatei ist "bootflash:packages.conf"
      Letzte Neustart-Grund: Neustart-Befehl


      Dieses Produkt enthält kryptografische Funktionen und unterliegt
      den Gesetzen der Vereinigten Staaten und den örtlichen Gesetzen zur Regulierung des Imports, Exports, Transfers und der Nutzung. Die Lieferung von Cisco-kryptografischen Produkten impliziert nicht
      die Autorität Dritter, Verschlüsselung zu importieren, zu exportieren, zu verteilen oder zu nutzen.
      Importeure, Exporteure, Verteiler und Benutzer sind verantwortlich für
      die Einhaltung der US-amerikanischen und der örtlichen Gesetze. Durch die Verwendung dieses Produkts stimmen Sie zu, die geltenden Gesetze und Vorschriften einzuhalten. Wenn Sie nicht
      in der Lage sind, die US-amerikanischen und örtlichen Gesetze einzuhalten, geben Sie dieses Produkt sofort zurück.

      Eine Zusammenfassung der US-Gesetze, die Cisco-kryptografische Produkte betreffen, finden Sie unter:
      http://www.cisco.com/wwl/export/crypto/tool/stqrg.html

      Wenn Sie weitere Unterstützung benötigen, kontaktieren Sie uns bitte per E-Mail an
      [email protected].

      Lizenzstufe: ax
      Lizenztyp: Standard. Keine gültige Lizenz gefunden.
      Nächste Neustart-Lizenzstufe: ax

      cisco CSR1000V (VXE) Prozessor (Revision VXE) mit 1126522K/3075K Byte Speicher.
      Prozessorkarten-ID 9TKUWGKX5MO
      2 Gigabit-Ethernet-Schnittstellen
      32768K Byte nichtflüchtiger Konfigurationsspeicher.
      3018840K Bytes physischer Speicher.
      7774207K Bytes virtueller Massenspeicher bei bootflash:.
      0K Bytes WebUI ODM-Dateien bei webui:.

      Konfigurationsregister ist 0x2102

  tasks:
  - name: parse_genie-Rolle einlesen
    include_role:
      name: clay584.parse_genie

  - name: Genie-Filter debuggen
    debug:
      msg: "{{ show_version_output | parse_genie(command='show version', os='iosxe') }}"
    delegate_to: localhost

Ausgabe:

$ ansible-playbook -i inventory debug.yml

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

TASK [Sammeln von Fakten] *******************************************************************
ok: [localhost]

TASK [parse_genie-Rolle einlesen] **********************************************************

TASK [Genie-Filter debuggen] ****************************************************************
ok: [localhost -> localhost] => {
    "msg": {
        "version": {
            "chassis": "CSR1000V",
            "chassis_sn": "9TKUWGKX5MO",
            "curr_config_register": "0x2102",
            "disks": {
                "bootflash:.": {
                    "disk_size": "7774207",
                    "type_of_disk": "virtuelle Festplatte"
                },
                "webui:.": {
                    "disk_size": "0",
                    "type_of_disk": "WebUI ODM Dateien"
                }
            },
            "hostname": "host-172-16-1-96",
            "image_id": "X86_64_LINUX_IOSD-UNIVERSALK9-M",
            "image_type": "Produktionsbild",
            "last_reload_reason": "Neustart-Befehl",
            "license_level": "ax",
            "license_type": "Standard. Keine gültige Lizenz gefunden.",
            "main_mem": "1126522",
            "mem_size": {
                "nicht-flüchtige Konfiguration": "32768",
                "physisch": "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 Minuten",
            "uptime_this_cp": "3 Minuten",
            "version": "16.5.1b,",
            "version_short": "16.5"
        }
    }
}

Vollständiges Beispiel #2

Playbook:

---

- hosts: csr1000v
  gather_facts: False
  tasks:
  - name: parse_genie-Rolle einlesen
    include_role:
      name: clay584.parse_genie

  - name: Daten vom Gerät abrufen
    ios_command:
      commands: show arp vrf Mgmt-intf
    register: arp_output

  - name: Strukturierte Daten drucken
    debug:
      msg: "{{ arp_output['stdout'][0] | parse_genie(command='show arp vrf Mgmt-intf', os='iosxe') }}"
    delegate_to: localhost

Ausgabe:

$ ansible-playbook -i inventory playbook.yml

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

TASK [parse_genie-Rolle einlesen] **********************************************************

TASK [Daten vom Gerät abrufen] **************************************************************
ok: [csr1000v]

TASK [Strukturierte Daten drucken] *************************************************************
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": "dynamisch",
                            "protocol": "Internet",
                            "type": "ARPA"
                        },
                        "172.16.1.114": {
                            "age": "-",
                            "ip": "172.16.1.114",
                            "link_layer_address": "5e00.4001.0000",
                            "origin": "statisch",
                            "protocol": "Internet",
                            "type": "ARPA"
                        }
                    }
                }
            }
        }
    }
}

Allgemeines Tabular Parsing

Cisco Genie unterstützt 1200 Befehle und mehr, aber für diese Befehle, für die kein Parser von Cisco gebaut wurde, gibt es die allgemeine tabellarische Parsing-Funktionalität. Weitere Informationen zur tabellarischen Parsing-Funktionalität von Genie finden Sie in ihrer oper_fill_tabular Dokumentation.

Wie Tabular Parsing funktioniert

Um eine Befehlsausgabe zu parsen, wenn ein Parser erstellt wurde, sind lediglich der command, die command output und das os erforderlich. Wenn jedoch kein Parser vorhanden ist, müssen Sie einige zusätzliche Informationen angeben, um dem Parser zu helfen, wie die Befehlsausgabe geparst werden soll. Diese zusätzlichen Daten sind zweifach:

  1. Header - Die Spaltenüberschriften, wie sie in der Ausgabe des Befehls angezeigt werden.
  2. Index - Der Schlüssel der Wörterbuchelemente, den der Parser zurückgeben wird.

Betrachten Sie folgendes Beispiel:

  1. Befehl: show ip sla summary
  2. Befehlsausgabe:
IPSLAs Neueste Betrieb Zusammenfassung
Codes: * aktiv, ^ inaktiv, ~ ausstehend
Alle Statistiken sind in Millisekunden. Statistiken mit u sind in Mikrosekunden

ID           Typ           Zielort          Statistiken            Rückgabe      Letztes
                                                                 Code          Ausführung
------------------------------------------------------------------------------------------------
*1           udp-jitter      10.0.0.2          RTT=900u           OK             Vor 20 Sekunden
*2           icmp-echo       10.0.0.2          RTT=1              OK              Vor 3 Sekunden
  1. Header - ID, Typ, Zielort, Statistiken, Rückgabecode und Letzte Ausführung.
  2. Index - Wir möchten die ID-Spalte als Index für diese Daten verwenden, wenn wir sie vom Parser zurückbekommen.
  3. Parser-Ausgabe:
{'*1': {'Zielort ': '10.0.0.2',
        'ID ': '*1',
        'Letzte Ausführung': 'Vor 20 Sekunden',
        'Rückgabecode': 'OK',
        'Statistiken ': 'RTT=900u',
        'Typ ': 'udp-jitter'},
 '*2': {'Zielort ': '10.0.0.2',
        'ID ': '*2',
        'Letzte Ausführung': 'Vor 3 Sekunden',
        'Rückgabecode': 'OK',
        'Statistiken ': 'RTT=1',
        'Typ ': 'icmp-echo'}}

Vorbereitung zur Verwendung des Tabular Parsers

Um diesen tabellarischen Parser zu verwenden, müssen wir zuerst die headers und index für einen bestimmten Befehl auf einem bestimmten OS in einem Format erstellen, das in ein Ansible-Playbook gelesen und anschließend in das parse_genie-Filter-Plugin eingespeist werden kann.

Dazu müssen Sie eine vars-Datei in Ihrem Playbook erstellen, die im folgenden Format vorliegt. Sie ist nach OS organisiert, dann nach Befehl. Dann sind unter jedem Befehl die Header und der Index definiert. Sie können so viele Befehle definieren, wie Sie für jedes Netzwerk-OS möchten, solange es innerhalb dieser Datenstruktur bleibt.

parse_genie:
  ios:
    "show ip sla summary":
      headers:
        - - ID
          - Typ
          - Zielort
          - Statistiken
          - Rückgabe
          - Letzte
        - - ''
          - ''
          - ''
          - ''
          - Code
          - Ausführung
      index:
        - 0
  iosxe:
    "show ip sla summary":
      headers:
        - - ID
          - Typ
          - Zielort
          - Statistiken
          - Rückgabe
          - Letzte
        - - ''
          - ''
          - ''
          - ''
          - Code
          - Ausführung
      index:
        - 1

Das Äquivalent des obigen YAML-Formats in Python ist:

python_dict = {
  "parse_genie": {
    "ios": {
      "show ip sla summary": {
        "headers": [
          [
            "ID", 
            "Typ", 
            "Zielort", 
            "Statistiken", 
            "Rückgabe", 
            "Letzte"
          ], 
          [
            "", 
            "", 
            "", 
            "", 
            "Code", 
            "Ausführung"
          ]
        ], 
        "index": [
          0
        ]
      }
    }, 
    "iosxe": {
      "show ip sla summary": {
        "headers": [
          [
            "ID", 
            "Typ", 
            "Zielort", 
            "Statistiken", 
            "Rückgabe", 
            "Letzte"
          ], 
          [
            "", 
            "", 
            "", 
            "", 
            "Code", 
            "Ausführung"
          ]
        ], 
        "index": [
          1
        ]
      }
    }
  }
}

Aufrufen des Tabular Parsers in einem Playbook

Jetzt, da wir einen generischen tabellarischen Befehl und dessen Header und Index definiert haben, können wir ihn tatsächlich von einem Playbook aus aufrufen.

Zuerst lesen wir die Vars-Datei ein, die die Metadaten des generischen Befehlsparsing enthält.

- name: Variablen-Datei mit generischen Befehl-Metadaten einfügen
  include_vars:
    file: parse_genie_generic_commands.yml
    name: parse_genie

Anschließend übergeben wir die Befehlsausgabe an parse_genie, jedoch mit ein paar zusätzlichen Parametern.

- name: Generische tabellarische Befehlsausgabe parsen
  debug:
    msg: "{{ command_output | parse_genie(command='show ip sla summary', os='ios', generic_tabular=True, generic_tabular_metadata=parse_genie) }}"
  delegate_to: localhost

Die resultierende geparste Ausgabe zeigt sich wie folgt:

ok: [localhost -> localhost] => {
    "msg": {
        "*1": {
            "Zielort ": "10.0.0.2",
            "ID ": "*1",
            "Letzte Ausführung": "Vor 20 Sekunden",
            "Rückgabecode": "OK",
            "Statistiken ": "RTT=900u",
            "Typ ": "udp-jitter"
        },
        "*2": {
            "Zielort ": "10.0.0.2",
            "ID ": "*2",
            "Letzte Ausführung": "Vor 3 Sekunden",
            "Rückgabecode": "OK",
            "Statistiken ": "RTT=1",
            "Typ ": "icmp-echo"
        }
    }
}

Vollständiges Beispiel #1

Playbook:

---

- hosts: localhost
  connection: local
  vars:
    out_ios_sla: |
      IPSLAs Neueste Betrieb Zusammenfassung
      Codes: * aktiv, ^ inaktiv, ~ pending
      Alle Statistiken sind in Millisekunden. Statistiken mit u sind in Mikrosekunden

      ID           Typ           Zielort          Statistiken            Rückgabe      Letztes
                                                                        Code          Ausführung
      ------------------------------------------------------------------------------------------------
      *1           udp-jitter      10.0.0.2          RTT=900u           OK             Vor 20 Sekunden
      *2           icmp-echo       10.0.0.2          RTT=1              OK              Vor 3 Sekunden

  tasks:
    - name: Parse Genie-Rolle einfügen
      include_role:
        name: clay584.parse_genie

    - name: Variablen-Datei einfügen, die die generischen tabellarischen Befehlsmetadaten hat
      include_vars:
        file: parse_genie_generic_commands.yml
        name: parse_genie

    - name: Genie-Filter für generische tabellarische Daten testen
      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

parse_genie_generic_commands.yml Inhalt:


---

parse_genie:
  ios:
    "test show ip sla summary":
      headers:
        - - ID
          - Typ
          - Zielort
          - Statistiken
          - Rückgabe
          - Letzte
        - - ''
          - ''
          - ''
          - ''
          - Code
          - Ausführung
      index:
        - 0
  iosxe:
    "test show ip sla summary":
      headers:
        - - ID
          - Typ
          - Zielort
          - Statistiken
          - Rückgabe
          - Letzte
        - - ''
          - ''
          - ''
          - ''
          - Code
          - Ausführung
      index:
        - 1

Playbook-Ausgabe:


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

TASK [Sammeln von Fakten] ************************************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Parse Genie-Rolle einfügen] ***************************************************************************************************************************************************************************************************************************************************

TASK [Variablen-Datei einfügen] ***************************************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Genie-Filter für generische tabellarische Daten testen] *********************************************************************************************************************************************************************************************************************************
ok: [localhost -> localhost] => {
    "msg": {
        "*1": {
            "Zielort ": "10.0.0.2",
            "ID ": "*1",
            "Letzte Ausführung": "Vor 20 Sekunden",
            "Rückgabecode": "OK",
            "Statistiken ": "RTT=900u",
            "Typ ": "udp-jitter"
        },
        "*2": {
            "Zielort ": "10.0.0.2",
            "ID ": "*2",
            "Letzte Ausführung": "Vor 3 Sekunden",
            "Rückgabecode": "OK",
            "Statistiken ": "RTT=1",
            "Typ ": "icmp-echo"
        }
    }
}

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

Entwicklung

Richten Sie Ihre Entwicklungsumgebung ein:

  1. Klonen Sie das Repository und gehen Sie hinein. git clone https://github.com/clay584/parse_genie.git && cd parse_genie
  2. Erstellen Sie eine virtuelle Umgebung. python3 -m venv .venv
  3. Aktivieren Sie die virtuelle Umgebung. source .venv/bin/activate
  4. Installieren Sie Ansible. pip install ansible
  5. Installieren Sie Genie und pyATS. pip install genie
  6. Installieren Sie yamllint. pip install yamllint

Testen

Führen Sie diese Befehle aus, um lokal zu testen:

  1. Alle YAML-Dateien linten. yamllint -c yamllint_config.yml *
  2. Führen Sie das Test-Playbook aus. ansible-playbook tests/test.yml --connection=local -i tests/inventory

Pushen

Ansible Galaxy arbeitet mit Tags.

  1. git commit -m"was auch immer"
  2. git tag -a X.X.X - wobei X.X.X eine semantische Versionsnummer ist.
  3. git push origin master
  4. git push X.X.X
Über das Projekt

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

Installieren
ansible-galaxy install clay584.parse_genie
Lizenz
gpl-3.0
Downloads
63.8k
Besitzer
Brought to you by Carl's Jr.