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
Предварительные требования
Этот плагин потребует следующее:
- Python 3.4+
- Пакеты pyATS и Genie
- Ansible 2.7+ (должен работать и на более старых версиях, если выполнены остальные требования)
Установка
Пожалуйста, выполните следующие инструкции, чтобы убедиться, что плагин фильтра будет работать с вашими плейбуками:
- Создайте каталог для вашего плейбука и перейдите в него.
mkdir network_ops && cd network_ops
- Создайте виртуальное окружение.
python3 -m venv .venv
- Активируйте виртуальное окружение.
source .venv/bin/activate
- Установите Ansible.
pip install ansible
- Установите Genie и pyATS.
pip install genie
- Установите роль 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
. Но если парсер не создан, вы должны указать дополнительную информацию, чтобы помочь парсеру понять, как обрабатывать вывод команды. Эта дополнительная информация состоит из двух частей:
- Заголовки - Заголовки столбцов, как показано в выводе команды.
- Индекс - Ключ словарных элементов, которые вернет парсер.
Рассмотрим следующий пример:
- Команда:
show ip sla summary
- Вывод команды:
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
- Заголовки -
ID
,Type
,Destination
,Stats
,Return Code
, иLast Run
. - Индекс - Мы хотим использовать столбец
ID
в качестве индекса для этих данных, когда мы получим их обратно от парсера. - Вывод парсера:
{'*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
Разработка
Настройте ваше окружение для разработки:
- Клонируйте репозиторий и перейдите в него.
git clone https://github.com/clay584/parse_genie.git && cd parse_genie
- Создайте виртуальное окружение.
python3 -m venv .venv
- Активируйте виртуальное окружение.
source .venv/bin/activate
- Установите Ansible.
pip install ansible
- Установите Genie и pyATS.
pip install genie
- Установите yamllint.
pip install yamllint
Тестирование
Запустите эти команды для тестирования на локальной машине:
- Проверьте все YAML файлы.
yamllint -c yamllint_config.yml *
- Запустите тестовый плейбук.
ansible-playbook tests/test.yml --connection=local -i tests/inventory
Публикация
Ansible Galaxy работает на тегах.
git commit -m"whatever"
git tag -a X.X.X
- где X.X.X - это номер версии по семантическому версионированию.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