parse_genie

Parse Genie

ВНИМАНИЕ!!! - Если у вас возникла проблема с выполнением команды, которая не может быть распознана, возможно, это ошибка в библиотеке анализа, которая поддерживается Cisco. Для таких проблем вы можете открыть обращение здесь.

Фильтр сети Genie принимает неструктурированный вывод команд CLI из всех сетевых операционных систем Cisco и выводит структурированные данные. Хотя он похож на другие доступные парсеры CLI (parse_cli, parse_cli_textfsm), этот парсер работает на основе очень развитой и надежной библиотеки, написанной Cisco, под названием Genie (и её основного фреймворка pyATS).

Это предоставляет более 1200 парсеров, которые преобразуют конфигурации и выходные данные CLI в структурированные данные, которые нормализованы и соответствуют стандарту, независимому от операционной системы.

Библиотека Genie также может служить движком для анализа табличных и не табличных текстов, требуя гораздо меньше кода, чем традиционный парсинг. Следовательно, ее можно использовать для разбора выходных данных любых вендоров; не только оборудованию Cisco. Однако это потребует написания пользовательских парсеров. В этом релизе нет функциональности для использования пользовательских парсеров. Поддерживаемые парсеры - это те, что включены в выпуск Genie, установленный на управляющей машине Ansible.

Список поддерживаемых операционных систем и команд, а также определения схемы данных (модели данных), которые описывают, какие поля и типы данных будут возвращены для данной команды, доступен по следующей ссылке от Cisco.

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

Предварительные требования

Этот плагин потребует следующее:

  1. Python 3.4+
  2. Пакеты pyATS и Genie
  3. Ansible 2.7+ (должен работать и на более старых версиях, если выполнены остальные требования)

Установка

Пожалуйста, выполните следующие инструкции, чтобы убедиться, что плагин фильтра будет работать с вашими плейбуками:

  1. Создайте каталог для вашего плейбука и перейдите в него. mkdir network_ops && cd network_ops
  2. Создайте виртуальное окружение. python3 -m venv .venv
  3. Активируйте виртуальное окружение. source .venv/bin/activate
  4. Установите Ansible. pip install ansible
  5. Установите Genie и pyATS. pip install genie
  6. Установите роль parse_genie из Ansible Galaxy. ansible-galaxy install clay584.parse_genie

Соответствия Ansible и Genie OS

Ниже приведены соответствия между ansible_network_os Ansible и os Genie:

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

Если вы работаете с IOS или IOS-XE, существует неопределенность, так как Ansible считает IOS и IOS-XE одинаковыми и, следовательно, ansible_network_os = ios, но Genie нужно знать конкретно, является ли это IOS или IOS-XE, чтобы правильно обработать выходные данные CLI. Если вы передаете ansible_network_os этому плагину фильтра, и оно равно ios, parse_genie сначала попытается разобрать его с Genie, используя os=ios, и если это не удастся, то попробует разобрать его с os=iosxe.

Имейте это в виду при создании ваших плейбуков. Возможно, лучше передавать реальную ОС в parse_genie. Вы можете сделать это, сохранив другую переменную инвентаря или host_var, чтобы указать Genie OS для каждого сетевого устройства и используя эту переменную как ОС для parse_genie.

Использование

Обязательно ознакомьтесь с ролью parse_genie, прежде чем пытаться использовать ее позже в вашем плейбуке.

Короткий пример

Для преобразования вывода команды CLI сетевого устройства используйте фильтр parse_genie, как показано в этом примере (не используйте сокращенные команды CLI).

Преобразование вывода CLI команды show version с устройства Cisco IOS-XE в структурированные данные:

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

Для большей абстракции вы можете добавить platform в parse_genie.

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

Вышеприведенный пример даст следующий результат:

{
    "version": {
        "chassis": "CSR1000V",
        "chassis_sn": "9TKUWGKX5MO",
        ...
        "version_short": "16.5"
    }
}

Полный пример #1

Плейбук:

---
- hosts: localhost
  connection: local
  vars:
    show_version_output: |
      Cisco IOS XE Software, Version 16.05.01b
      ...
      Last reload reason: Reload Command
      ...
  tasks:
    - name: Read in parse_genie role
      include_role:
        name: clay584.parse_genie

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

Вывод:

$ ansible-playbook -i inventory debug.yml

PLAY [localhost] *************************************************************************
...
TASK [Debug Genie Filter] ****************************************************************
ok: [localhost -> localhost] => {
    "msg": {
        "version": {
            "chassis": "CSR1000V",
            ...
            "version_short": "16.5"
        }
    }
}

Полный пример #2

Плейбук:

---
- hosts: csr1000v
  gather_facts: False
  tasks:
    - name: Read in parse_genie role
      include_role:
        name: clay584.parse_genie

    - name: Get Data From Device
      ios_command:
        commands: show arp vrf Mgmt-intf
      register: arp_output

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

Вывод:

$ ansible-playbook -i inventory playbook.yml

PLAY [csr1000v] **************************************************************************
...
TASK [Print Structured Data] *************************************************************
ok: [csr1000v -> localhost] => {
    "msg": {
        "interfaces": {
            "GigabitEthernet1": {
                "ipv4": {
                    "neighbors": {
                        "172.16.1.111": {
                            "age": "0",
                            ...
                        },
                        "172.16.1.114": {
                            "age": "-",
                            ...
                        }
                    }
                }
            }
        }
    }
}

Общее табличное парсирование

Cisco Genie поддерживает 1200 команд и количество увеличивается, но для тех команд отображения, для которых парсер не был создан компанией Cisco, существует функциональность общего табличного парсинга. Для получения дополнительной информации о функциональности табличного парсинга Genie смотрите их документацию по oper_fill_tabular.

Как работает табличное парсирование

Чтобы обработать вывод команды, когда парсер создан, необходимо просто указать command, output команды и os. Но если парсер не создан, вы должны указать дополнительную информацию, чтобы помочь парсеру понять, как обрабатывать вывод команды. Эта дополнительная информация состоит из двух частей:

  1. Заголовки - Заголовки столбцов, как показано в выводе команды.
  2. Индекс - Ключ словарных элементов, которые вернет парсер.

Рассмотрим следующий пример:

  1. Команда: show ip sla summary
  2. Вывод команды:
IPSLAs Latest Operation Summary
Codes: * active, ^ inactive, ~ pending
All Stats are in milliseconds. Stats with u are in microseconds

ID           Type           Destination       Stats               Return        Last
                                                                  Code          Run
------------------------------------------------------------------------------------------------
*1           udp-jitter      10.0.0.2          RTT=900u           OK             20 seconds ago
*2           icmp-echo       10.0.0.2          RTT=1              OK              3 seconds ago
  1. Заголовки - ID, Type, Destination, Stats, Return Code, и Last Run.
  2. Индекс - Мы хотим использовать столбец ID в качестве индекса для этих данных, когда мы получим их обратно от парсера.
  3. Вывод парсера:
{'*1': {'Destination ': '10.0.0.2',
        'ID ': '*1',
        ...
        'Type ': 'udp-jitter'},
 '*2': {'Destination ': '10.0.0.2',
        'ID ': '*2',
        ...
        'Type ': 'icmp-echo'}}

Подготовка к использованию табличного парсера

Чтобы использовать этот табличный парсер, мы сначала должны создать headers и index для данной команды на заданной ОС в формате, который можно считать в Ansible playbook, и затем передать в плагин фильтра parse_genie.

Для этого необходимо создать файл vars в вашем плейбуке в следующем формате. Он организован по ОС, затем по команде. Затем под каждой командой определяются заголовки и индекс. Вы можете определить столько команд, сколько хотите для каждой сетевой ОС, пока это в пределах этой структуры данных.

parse_genie:
  ios:
    "show ip sla summary":
      headers:
        - - ID
          - Type
          - Destination
          - Stats
          - Return
          - Last
        - - ''
          - ''
          - ''
          - ''
          - Code
          - Run
      index:
        - 0

Python-эквивалент вышеуказанного формата yaml:

python_dict = {
  "parse_genie": {
    "ios": {
      "show ip sla summary": {
        "headers": [
          [
            "ID", 
            "Type", 
            "Destination", 
            "Stats", 
            "Return", 
            "Last"
          ], 
          [
            "", 
            "", 
            "", 
            "", 
            "Code", 
            "Run"
          ]
        ], 
        "index": [
          0
        ]
      }
    }
  }
}

Вызов табличного парсера в плейбуке

Теперь, когда мы определили общую табличную команду и ее заголовки и индекс, мы можем на самом деле вызвать ее из плейбука.

Сначала читаем файл vars, который содержит метаданные парсинга для табличной команды.

- name: Include vars file with generic command metadata
  include_vars:
    file: parse_genie_generic_commands.yml
    name: parse_genie

Затем мы передаем вывод команды в parse_genie, добавив несколько дополнительных параметров.

- name: Parse generic tabular command output
  debug:
    msg: "{{ command_output | parse_genie(command='show ip sla summary', os='ios', generic_tabular=True, generic_tabular_metadata=parse_genie) }}"
  delegate_to: localhost

Результирующий распарсенный вывод будет выглядеть следующим образом:

ok: [localhost -> localhost] => {
    "msg": {
        "*1": {
            "Destination ": "10.0.0.2",
            ...
            "Type ": "udp-jitter"
        },
        "*2": {
            "Destination ": "10.0.0.2",
            ...
            "Type ": "icmp-echo"
        }
    }
}

Полный пример #1

Плейбук:

---
- hosts: localhost
  connection: local
  vars:
    out_ios_sla: |
      IPSLAs Latest Operation Summary
      ...
      ID           Type           Destination       Stats           Return        Last
      ...
  
  tasks:
    - name: Include Parse Genie Role
      include_role:
        name: clay584.parse_genie

    - name: Include vars file that has generic tabular command metadata
      include_vars:
        file: parse_genie_generic_commands.yml
        name: parse_genie

    - name: Test Genie Filter for generic tabular data
      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:

---
parse_genie:
  ios:
    "test show ip sla summary":
      headers:
        - - ID
          - Type
          - Destination
          - Stats
          - Return
          - Last
        - - ''
          - ''
          - ''
          - ''
          - Code
          - Run
      index:
        - 0

Вывод плейбука:

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

TASK [Gathering Facts] *********************************************************************************************************************
ok: [localhost]

TASK [Include Parse Genie Role] ************************************************************************************************************

TASK [Include vars] *************************************************************************************************************************
ok: [localhost]

TASK [Test Genie Filter for generic tabular data] *******************************************************************************************
ok: [localhost -> localhost] => {
    "msg": {
        "*1": {
            "Destination ": "10.0.0.2",
            ...
            "Type ": "udp-jitter"
        },
        "*2": {
            "Destination ": "10.0.0.2",
            ...
            "Type ": "icmp-echo"
        }
    }
}

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

Разработка

Настройте ваше окружение для разработки:

  1. Клонируйте репозиторий и перейдите в него. git clone https://github.com/clay584/parse_genie.git && cd parse_genie
  2. Создайте виртуальное окружение. python3 -m venv .venv
  3. Активируйте виртуальное окружение. source .venv/bin/activate
  4. Установите Ansible. pip install ansible
  5. Установите Genie и pyATS. pip install genie
  6. Установите yamllint. pip install yamllint

Тестирование

Запустите эти команды для тестирования на локальной машине:

  1. Проверьте все YAML файлы. yamllint -c yamllint_config.yml *
  2. Запустите тестовый плейбук. ansible-playbook tests/test.yml --connection=local -i tests/inventory

Публикация

Ansible Galaxy работает на тегах.

  1. git commit -m"whatever"
  2. git tag -a X.X.X - где X.X.X - это номер версии по семантическому версионированию.
  3. git push origin master
  4. git push X.X.X
О проекте

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

Установить
ansible-galaxy install clay584/parse_genie
Лицензия
gpl-3.0
Загрузки
59212
Владелец
Brought to you by Carl's Jr.