clay584.parse_genie
Parse Genie
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:
- Python 3.4+
- pyATS und Genie-Pakete
- 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:
- Erstellen Sie ein Verzeichnis für Ihr Playbook und gehen Sie hinein.
mkdir network_ops && cd network_ops
- Erstellen Sie eine virtuelle Umgebung.
python3 -m venv .venv
- Aktivieren Sie die virtuelle Umgebung.
source .venv/bin/activate
- Installieren Sie Ansible.
pip install ansible
- Installieren Sie Genie und pyATS.
pip install genie
- 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:
- Header - Die Spaltenüberschriften, wie sie in der Ausgabe des Befehls angezeigt werden.
- Index - Der Schlüssel der Wörterbuchelemente, den der Parser zurückgeben wird.
Betrachten Sie folgendes Beispiel:
- Befehl:
show ip sla summary
- 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
- Header -
ID
,Typ
,Zielort
,Statistiken
,Rückgabecode
undLetzte Ausführung
. - Index - Wir möchten die
ID
-Spalte als Index für diese Daten verwenden, wenn wir sie vom Parser zurückbekommen. - 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:
- Klonen Sie das Repository und gehen Sie hinein.
git clone https://github.com/clay584/parse_genie.git && cd parse_genie
- Erstellen Sie eine virtuelle Umgebung.
python3 -m venv .venv
- Aktivieren Sie die virtuelle Umgebung.
source .venv/bin/activate
- Installieren Sie Ansible.
pip install ansible
- Installieren Sie Genie und pyATS.
pip install genie
- Installieren Sie yamllint.
pip install yamllint
Testen
Führen Sie diese Befehle aus, um lokal zu testen:
- Alle YAML-Dateien linten.
yamllint -c yamllint_config.yml *
- Führen Sie das Test-Playbook aus.
ansible-playbook tests/test.yml --connection=local -i tests/inventory
Pushen
Ansible Galaxy arbeitet mit Tags.
git commit -m"was auch immer"
git tag -a X.X.X
- wobei X.X.X eine semantische Versionsnummer ist.git push origin master
git push X.X.X
Filter plugin for network CLI parsing using Cisco's Genie/pyATS
ansible-galaxy install clay584.parse_genie