clay584.parse_genie

Parse Genie

Published

Rola Ansible Wersja Ansible Wersja Pythona

Status budowy Ocena jakości Ansible

UWAGA!!! - Jeśli napotkasz problem z komendą, która nie działa, to możliwe, że jest błąd w bibliotece do parsowania, którą utrzymuje Cisco. W takich przypadkach możesz zgłosić problem tutaj.

Filtr sieciowy genie przetwarza nieustrukturyzowane dane z komend CLI z wszystkich systemów operacyjnych sieci Cisco i zwraca dane w formie ustrukturyzowanej. Choć przypomina inne dostępne parsery CLI (parse_cli, parse_cli_textfsm), ten parser korzysta z dojrzałej i solidnej biblioteki stworzonej przez Cisco, zwanej Genie (oraz podnoszącej framework pyATS). Oferuje to ponad 1200 parserów, które przekształcają dane konfiguracyjne i wynikowe komend CLI w znormalizowane dane, które odpowiadają standardowym modelom danych niezależnym od systemu operacyjnego.

Biblioteka Genie może również służyć jako silnik do parsowania tekstu sformatowanego i niesformatowanego, wymagając znacznie mniej kodu niż tradycyjne metody parsowania. Dlatego może być używana do przetwarzania wyników z innych producentów, nie tylko urządzeń Cisco. Jednak to wymaga pisania własnych parserów. Ta wersja nie zawiera funkcji do korzystania z niestandardowych parserów. Obsługiwane są tylko parsery zawarte w wersji Genie zainstalowanej na maszynie kontrolnej Ansible.

Lista obsługiwanych systemów operacyjnych i komend, jak również definicje schematów danych (modele danych), które dokładnie opisują, jakie pola i typy danych będą zwracane dla danej komendy, są dostępne od Cisco pod poniższym linkiem.

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

Wymagania wstępne

Ten plugin wymaga:

  1. Python 3.4+
  2. Pakiety pyATS i Genie
  3. Ansible 2.7+ (Powinien działać na starszych wersjach, o ile inne wymagania są spełnione)

Instalacja

Proszę, wykonaj te instrukcje, aby upewnić się, że filtr pluginu będzie działał z Twoimi playbookami:

  1. Utwórz katalog dla swojego playbooka i wejdź do niego. mkdir network_ops && cd network_ops
  2. Utwórz środowisko wirtualne. python3 -m venv .venv
  3. Aktywuj środowisko wirtualne. source .venv/bin/activate
  4. Zainstaluj Ansible. pip install ansible
  5. Zainstaluj Genie i pyATS. pip install genie
  6. Zainstaluj rolę parse_genie z Ansible Galaxy. ansible-galaxy install clay584.parse_genie

Mapowanie Ansible do Genie OS

Poniżej przedstawiono mapowania z ansible_network_os Ansible do os Genie:

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

Jeżeli pracujesz z IOS lub IOS-XE, istnieje niejasność, ponieważ Ansible traktuje IOS i IOS-XE jako to samo, dlatego ansible_network_os = ios, podczas gdy Genie musi wiedzieć, czy to jest IOS, czy IOS-XE, aby poprawnie zinterpretować dane wyjściowe CLI. Jeśli przekażesz ansible_network_os do tego filtra pluginu i będzie to równe ios, parse_genie spróbuje najpierw przetworzyć to z Genie używając os=ios, a jeśli to się nie powiedzie, spróbuje przetworzyć to z os=iosxe.

Pamiętaj o tym podczas tworzenia swoich playbooków. Najlepiej jest podać prawdziwy OS do parse_genie. Możesz to zrobić, przechowując inną zmienną zasobów lub host_var, aby określić OS Genie dla każdego urządzenia sieciowego i używając tej zmiennej jako OS dla parse_genie.

Użycie

Upewnij się, że wczytałeś rolę parse_genie, zanim spróbujesz jej użyć później w swoim playbooku.

...skrót...

  tasks:
  - name: Wczytaj rolę parse_genie
    include_role:
      name: clay584.parse_genie
      
...skrót...

Krótki przykład

Aby przekonwertować wynik komendy CLI urządzenia sieciowego, użyj filtra parse_genie, jak pokazano w tym przykładzie (nie używaj skróconych komend CLI).

Konwertowanie wyników komendy show version z urządzenia Cisco IOS-XE do ustrukturyzowanych danych::

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

Aby uzyskać głębszą abstrakcję, możesz dodać platform do parse_genie.

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

Powyższy przykład zwróci:

{
    "version": {
        "chassis": "CSR1000V",
        "chassis_sn": "9TKUWGKX5MO",
        "curr_config_register": "0x2102",
        "disks": {
            "bootflash:.": {
                "disk_size": "7774207",
                "type_of_disk": "wirtualny dysk twardy"
            },
            "webui:.": {
                "disk_size": "0",
                "type_of_disk": "Pliki WebUI ODM"
            }
        },
        "hostname": "host-172-16-1-96",
        "image_id": "X86_64_LINUX_IOSD-UNIVERSALK9-M",
        "image_type": "obraz produkcyjny",
        "last_reload_reason": "Polecenie ponownego załadunku",
        "license_level": "ax",
        "license_type": "Domyślny. Nie znaleziono ważnej licencji.",
        "main_mem": "1126522",
        "mem_size": {
            "konfiguracja nieulotna": "32768",
            "fizyczna": "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 minuty",
        "uptime_this_cp": "3 minuty",
        "version": "16.5.1b,",
        "version_short": "16.5"
    }
}

Pełny przykład #1

Playbook:

---

- hosts: localhost
  connection: local
  vars:
    show_version_output: |
      Oprogramowanie Cisco IOS XE, wersja 16.05.01b
      Oprogramowanie Cisco IOS [Everest], Oprogramowanie Virtual XE (X86_64_LINUX_IOSD-UNIVERSALK9-M), wersja 16.5.1b, OPROGRAMOWANIE WYDAWANE (fc1)
      Wsparcie techniczne: http://www.cisco.com/techsupport
      Prawa autorskie (c) 1986-2017 przez Cisco Systems, Inc.
      Skopiowane we wtorek 11 kwietnia 2017 16:41 przez mcpre

      Oprogramowanie Cisco IOS-XE, Prawa autorskie (c) 2005-2017 przez Cisco Systems, Inc.
      Wszelkie prawa zastrzeżone. Niektóre składniki oprogramowania Cisco IOS-XE  licencjonowane na mocy GNU General Public License ("GPL") w wersji 2.0. Kod oprogramowania licencjonowany na mocy GPL w wersji 2.0 to darmowe oprogramowanie, które nie ma ŻADNEJ GWARANCJI. Możesz rozpowszechniać i/lub modyfikować ten kod GPL na podstawie warunków GPL w wersji 2.0. Aby uzyskać więcej informacji, zapoznaj się z dokumentacją lub plikiem "Informacja o licencji" towarzyszącym oprogramowaniu IOS-XE lub odpowiednim adresem URL podanym na ulotce towarzyszącej oprogramowaniu IOS-XE.

      ROM: IOS-XE ROMMON

      host-172-16-1-96 uptime wynosi 2 minuty
      Czas pracy tego procesora sterującego to 3 minuty
      System powrócił do ROM z powodu ponownego załadunku
      Plik obrazu systemu to "bootflash:packages.conf"
      Ostatni powód ponownego załadunku: polecenie ponownego załadunku

      Ten produkt zawiera funkcje kryptograficzne i podlega przepisom prawa amerykańskiego i lokalnego dotyczącego importu, eksportu, transferu i użycia. Dostarczenie produktów kryptograficznych Cisco nie oznacza uprawnień osób trzecich do importu, eksportu, dystrybucji ani używania szyfrowania. Importerzy, eksporterzy, dystrybutorzy i użytkownicy  odpowiedzialni za przestrzeganie przepisów prawa amerykańskiego i prawa lokalnego. Korzystając z tego produktu, zgadzasz się przestrzegać obowiązujących przepisów prawnych. Jeśli nie jesteś w stanie przestrzegać przepisów amerykańskich i lokalnych, natychmiast zwróć ten produkt.

      Podsumowanie przepisów prawa amerykańskiego regulujących produkty kryptograficzne Cisco można znaleźć pod adresem:
      http://www.cisco.com/wwl/export/crypto/tool/stqrg.html

      Jeśli potrzebujesz dalszej pomocy, skontaktuj się z nami, wysyłając e-mail na adres
      [email protected].

      Poziom licencji: ax
      Typ licencji: Domyślny. Nie znaleziono ważnej licencji.
      Następny poziom licencji przy ponownym załadunku: ax

      cisco CSR1000V (VXE) procesor (rewizja VXE) z 1126522K/3075K bajtów pamięci.
      Identyfikator płyty procesora 9TKUWGKX5MO
      2 interfejsy Gigabit Ethernet
      32768K bajtów pamięci konfiguracyjnej nieulotnej.
      3018840K bajtów pamięci fizycznej.
      7774207K bajtów wirtualnego dysku twardego na bootflash:.
      0K bajtów plików WebUI ODM na webui:.

      Rejestr konfiguracji to 0x2102

  tasks:
  - name: Wczytaj rolę parse_genie
    include_role:
      name: clay584.parse_genie

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

Wynik:

$ ansible-playbook -i inventory debug.yml

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

TASK [Zbieranie faktów] *******************************************************************
ok: [localhost]

TASK [Wczytaj rolę parse_genie] **********************************************************

TASK [Debuguj filtr Genie] ****************************************************************
ok: [localhost -> localhost] => {
    "msg": {
        "version": {
            "chassis": "CSR1000V",
            "chassis_sn": "9TKUWGKX5MO",
            "curr_config_register": "0x2102",
            "disks": {
                "bootflash:.": {
                    "disk_size": "7774207",
                    "type_of_disk": "wirtualny dysk twardy"
                },
                "webui:.": {
                    "disk_size": "0",
                    "type_of_disk": "Pliki WebUI ODM"
                }
            },
            "hostname": "host-172-16-1-96",
            "image_id": "X86_64_LINUX_IOSD-UNIVERSALK9-M",
            "image_type": "obraz produkcyjny",
            "last_reload_reason": "Polecenie ponownego załadunku",
            "license_level": "ax",
            "license_type": "Domyślny. Nie znaleziono ważnej licencji.",
            "main_mem": "1126522",
            "mem_size": {
                "konfiguracja nieulotna": "32768",
                "fizyczna": "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 minuty",
            "uptime_this_cp": "3 minuty",
            "version": "16.5.1b,",
            "version_short": "16.5"
        }
    }
}

Pełny przykład #2

Playbook:

---

- hosts: csr1000v
  gather_facts: False
  tasks:
  - name: Wczytaj rolę parse_genie
    include_role:
      name: clay584.parse_genie

  - name: Pobierz dane z urządzenia
    ios_command:
      commands: show arp vrf Mgmt-intf
    register: arp_output

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

Wynik:

$ ansible-playbook -i inventory playbook.yml

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

TASK [Wczytaj rolę parse_genie] **********************************************************

TASK [Pobierz dane z urządzenia] **************************************************************
ok: [csr1000v]

TASK [Drukuj ustrukturyzowane dane] *************************************************************
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": "dynamic",
                            "protocol": "Internet",
                            "type": "ARPA"
                        },
                        "172.16.1.114": {
                            "age": "-",
                            "ip": "172.16.1.114",
                            "link_layer_address": "5e00.4001.0000",
                            "origin": "static",
                            "protocol": "Internet",
                            "type": "ARPA"
                        }
                    }
                }
            }
        }
    }
}

Ogólne parsowanie tabelaryczne

Cisco Genie wspiera 1200 komend i nadal rośnie, ale w przypadku tych komend, dla których nie zbudowano parsera, istnieje funkcjonalność ogólnego parsowania tabelarycznego. Więcej informacji na temat funkcjonalności parsowania tabelarycznego Genie znajdziesz w ich dokumentacji oper_fill_tabular.

Jak działa parsowanie tabelaryczne

Aby sparsować dane wyjściowe komendy, gdy zbudowano parser, wystarczy command, command output i os. Ale jeśli parser nie jest dostępny, musisz podać dodatkowe informacje, które pomogą parserowi zrozumieć, jak sparsować wynik komendy. Ta dodatkowa informacja ma dwa elementy:

  1. Nagłówki - Nagłówki kolumn, jakie są pokazane w wyniku komendy.
  2. Indeks - Klucz elementów słownika, które parser ma zwrócić.

Rozważ poniższy przykład:

  1. Komenda: show ip sla summary
  2. Wyjście komendy:
Podsumowanie ostatniej operacji IPSLAs
Kody: * aktywne, ^ nieaktywne, ~ oczekujące
Wszystkie statystyki są w milisekundach. Statystyki z u są w mikrosekundach

ID           Typ           Cel               Statystyki               Zwróć        Ostatni
                                                                  Kod          Uruchom
------------------------------------------------------------------------------------------------
*1           udp-jitter      10.0.0.2          RTT=900u           OK             20 sekund temu
*2           icmp-echo       10.0.0.2          RTT=1              OK              3 sekundy temu
  1. Nagłówki - ID, Typ, Cel, Statystyki, Kod zwrotu i Ostatni uruchomienie.
  2. Indeks - Chcemy użyć kolumny ID jako indeksu tych danych, gdy otrzymamy je z parsera.
  3. Wyjście parsera:
{'*1': {'Cel ': '10.0.0.2',
        'ID ': '*1',
        'Ostatni uruchomienie': '20 sekund temu',
        'Kod zwrotu': 'OK',
        'Statystyki ': 'RTT=900u',
        'Typ ': 'udp-jitter'},
 '*2': {'Cel ': '10.0.0.2',
        'ID ': '*2',
        'Ostatni uruchomienie': '3 sekundy temu',
        'Kod zwrotu': 'OK',
        'Statystyki ': 'RTT=1',
        'Typ ': 'icmp-echo'}

Przygotowanie do użycia parsera tabelarycznego

Aby używać tego parsera tabelarycznego, musimy najpierw stworzyć headers i index dla danej komendy w danym systemie operacyjnym w formacie, który można wczytać do playbooka Ansible, a następnie przekazać do filtra pluginu parse_genie.

Aby to zrobić, musisz utworzyć plik vars w playbooku, który będzie w poniższym formacie. Jest on zorganizowany według systemu operacyjnego, a następnie według komendy. Pod każdą komendą definiowane są nagłówki i indeks. Możesz zdefiniować dowolną liczbę komend dla każdego systemu operacyjnego sieciowego, pod warunkiem że mieszczą się w tej strukturze danych.

parse_genie:
  ios:
    "show ip sla summary":
      headers:
        - - ID
          - Typ
          - Cel
          - Statystyki
          - Zwróć
          - Ostatni
        - - ''
          - ''
          - ''
          - ''
          - Kod
          - Uruchom
      index:
        - 0
  iosxe:
    "show ip sla summary":
      headers:
        - - ID
          - Typ
          - Cel
          - Statystyki
          - Zwróć
          - Ostatni
        - - ''
          - ''
          - ''
          - ''
          - Kod
          - Uruchom
      index:
        - 1

Odpowiednik Pythona powyższego formatu YAML to:

python_dict = {
  "parse_genie": {
    "ios": {
      "show ip sla summary": {
        "headers": [
          [
            "ID", 
            "Typ", 
            "Cel", 
            "Statystyki", 
            "Zwróć", 
            "Ostatni"
          ], 
          [
            "", 
            "", 
            "", 
            "", 
            "Kod", 
            "Uruchom"
          ]
        ], 
        "index": [
          0
        ]
      }
    }, 
    "iosxe": {
      "show ip sla summary": {
        "headers": [
          [
            "ID", 
            "Typ", 
            "Cel", 
            "Statystyki", 
            "Zwróć", 
            "Ostatni"
          ], 
          [
            "", 
            "", 
            "", 
            "", 
            "Kod", 
            "Uruchom"
          ]
        ], 
        "index": [
          1
        ]
      }
    }
  }
}

Wywoływanie parsera tabelarycznego w playbooku

Kiedy zdefiniujemy ogólną komendę tabelaryczną oraz jej nagłówki i indeks, możemy w rzeczywistości wywołać ją z playbooka.

Najpierw wczytujemy plik vars, który zawiera metadane do parsowania ogólnych komend.

- name: Wczytaj plik vars z metadanymi ogólnych komend
  include_vars:
    file: parse_genie_generic_commands.yml
    name: parse_genie

Następnie przekazujemy dane wyjściowe komendy do parse_genie, ale z kilkoma dodatkowymi parametrami.

- name: Parsuj ogólne dane wyjściowe z komendy
  debug:
    msg: "{{ command_output | parse_genie(command='show ip sla summary', os='ios', generic_tabular=True, generic_tabular_metadata=parse_genie) }}"
  delegate_to: localhost

Oczekiwany wynik po przetworzeniu będzie wyglądał następująco:

ok: [localhost -> localhost] => {
    "msg": {
        "*1": {
            "Cel ": "10.0.0.2",
            "ID ": "*1",
            "Ostatni uruchomienie": "20 sekund temu",
            "Kod zwrotu": "OK",
            "Statystyki ": "RTT=900u",
            "Typ ": "udp-jitter"
        },
        "*2": {
            "Cel ": "10.0.0.2",
            "ID ": "*2",
            "Ostatni uruchomienie": "3 sekundy temu",
            "Kod zwrotu": "OK",
            "Statystyki ": "RTT=1",
            "Typ ": "icmp-echo"
        }
    }
}

Pełny przykład #1

Playbook:


---

- hosts: localhost
  connection: local
  vars:
    out_ios_sla: |
      Podsumowanie ostatniej operacji IPSLAs
      Kody: * aktywne, ^ nieaktywne, ~ oczekujące
      Wszystkie statystyki są w milisekundach. Statystyki z u są w mikrosekundach

      ID           Typ           Cel               Statystyki               Zwróć        Ostatni
                                                                        Kod          Uruchom
      ------------------------------------------------------------------------------------------------
      *1           udp-jitter      10.0.0.2          RTT=900u           OK             20 sekund temu
      *2           icmp-echo       10.0.0.2          RTT=1              OK              3 sekundy temu

  tasks:
    - name: Wczytaj rolę Parse Genie
      include_role:
        name: clay584.parse_genie

    - name: Wczytaj plik vars z metadanymi ogólnych komend
      include_vars:
        file: parse_genie_generic_commands.yml
        name: parse_genie

    - name: Testuj filtr Genie dla ogólnych danych tabelarycznych
      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

Zawartość parse_genie_generic_commands.yml:


---

parse_genie:
  ios:
    "test show ip sla summary":
      headers:
        - - ID
          - Typ
          - Cel
          - Statystyki
          - Zwróć
          - Ostatni
        - - ''
          - ''
          - ''
          - ''
          - Kod
          - Uruchom
      index:
        - 0
  iosxe:
    "test show ip sla summary":
      headers:
        - - ID
          - Typ
          - Cel
          - Statystyki
          - Zwróć
          - Ostatni
        - - ''
          - ''
          - ''
          - ''
          - Kod
          - Uruchom
      index:
        - 1

Wynik playbooka:


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

TASK [Zbieranie faktów] ************************************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Wczytaj rolę Parse Genie] ***************************************************************************************************************************************************************************************************************************************************

TASK [Wczytaj plik vars] ***************************************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Testuj filtr Genie dla ogólnych danych tabelarycznych] *********************************************************************************************************************************************************************************************************************************
ok: [localhost -> localhost] => {
    "msg": {
        "*1": {
            "Cel ": "10.0.0.2",
            "ID ": "*1",
            "Ostatni uruchomienie": "20 sekund temu",
            "Kod zwrotu": "OK",
            "Statystyki ": "RTT=900u",
            "Typ ": "udp-jitter"
        },
        "*2": {
            "Cel ": "10.0.0.2",
            "ID ": "*2",
            "Ostatni uruchomienie": "3 sekundy temu",
            "Kod zwrotu": "OK",
            "Statystyki ": "RTT=1",
            "Typ ": "icmp-echo"
        }
    }
}

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

Rozwój

Skonfiguruj swoje środowisko deweloperskie:

  1. Skopiuj repozytorium i wejdź do niego. git clone https://github.com/clay584/parse_genie.git && cd parse_genie
  2. Utwórz środowisko wirtualne. python3 -m venv .venv
  3. Aktywuj środowisko wirtualne. source .venv/bin/activate
  4. Zainstaluj Ansible. pip install ansible
  5. Zainstaluj Genie i pyATS. pip install genie
  6. Zainstaluj yamllint. pip install yamllint

Testowanie

Uruchom te komendy, aby przetestować lokalnie:

  1. Sprawdź wszystkie pliki YAML. yamllint -c yamllint_config.yml *
  2. Uruchom testowy playbook. ansible-playbook tests/test.yml --connection=local -i tests/inventory

Wysyłanie

Ansible Galaxy działa na tagach.

  1. git commit -m"cokolwiek"
  2. git tag -a X.X.X - gdzie X.X.X to semantyczny numer wersji.
  3. git push origin master
  4. git push X.X.X
O projekcie

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

Zainstaluj
ansible-galaxy install clay584.parse_genie
Licencja
gpl-3.0
Pobrania
63.8k
Właściciel
Brought to you by Carl's Jr.