На оборудовании, которое не поддерживает какого-то программного интерфейса, вывод команд show возвращается в виде строки. И, хотя отчасти она структурирована, но всё же это просто строка. И её надо как-то обработать, чтобы получить объекты Python, например, словарь или список.
Например, можно построчно обрабатывать вывод команды и, используя, например, регулярные выражения, получить объекты Python. Но есть более удобный вариант, чем просто обрабатывать каждый вывод построчно: TextFSM.
TextFSM - это библиотека, созданная Google для обработки вывода с сетевых устройств. Она позволяет создавать шаблоны, по которым будет обрабатываться вывод команды.
Использование TextFSM лучше, чем простая построчная обработка, так как шаблоны дают лучшее представление о том, как вывод будет обрабатываться, и шаблонами проще поделиться. А значит, проще найти уже созданные шаблоны и использовать их, или поделиться своими.
Для начала библиотеку надо установить:
pip install textfsm
Для использования TextFSM надо создать шаблон, по которому будет обрабатываться вывод команды.
Пример вывода команды traceroute:
r2#traceroute 90.0.0.9 source 33.0.0.2 traceroute 90.0.0.9 source 33.0.0.2 Type escape sequence to abort. Tracing the route to 90.0.0.9 VRF info: (vrf in name/id, vrf out name/id) 1 10.0.12.1 1 msec 0 msec 0 msec 2 15.0.0.5 0 msec 5 msec 4 msec 3 57.0.0.7 4 msec 1 msec 4 msec 4 79.0.0.9 4 msec * 1 msec
Например, из вывода надо получить хопы, через которые прошел пакет.
В таком случае шаблон TextFSM будет выглядеть так (файл traceroute.template):
Value ID (\d+) Value Hop (\d+(\.\d+){3}) Start ^ ${ID} ${Hop} -> Record
Первые две строки определяют переменные:
Value ID (\d+)
- эта строка определяет переменную ID, которая описывает регулярное выражение: (\d+)
- одна или более цифрValue Hop (\d+(\.\d+){3})
- эта строка определяет переменную Hop, которая описывает IP-адрес таким регулярным выражением: (\d+(\.\d+){3})
После строки Start начинается сам шаблон. В данном случае он очень простой:
^ ${ID} ${Hop} -> Record
${имя переменной}
Record
в конце означает, что строки, которые попадут под описанный шаблон, будут обработаны и выведены в результаты TextFSM (с этим подробнее мы разберемся в )Скрипт для обработки вывода команды traceroute с помощью TextFSM (parse_traceroute.py):
import textfsm traceroute = ''' r2#traceroute 90.0.0.9 source 33.0.0.2 traceroute 90.0.0.9 source 33.0.0.2 Type escape sequence to abort. Tracing the route to 90.0.0.9 VRF info: (vrf in name/id, vrf out name/id) 1 10.0.12.1 1 msec 0 msec 0 msec 2 15.0.0.5 0 msec 5 msec 4 msec 3 57.0.0.7 4 msec 1 msec 4 msec 4 79.0.0.9 4 msec * 1 msec ''' template = open('traceroute.template') fsm = textfsm.TextFSM(template) result = fsm.ParseText(traceroute) print(fsm.header) print(result)
Результат выполнения скрипта:
$ python parse_traceroute.py ['ID', 'Hop'] [['1', '10.0.12.1'], ['2', '15.0.0.5'], ['3', '57.0.0.7'], ['4', '79.0.0.9']]
Строки, которые совпали с описанным шаблоном, возвращаются в виде списка списков. Каждый элемент - это список, который состоит из двух элементов: номера хопа и IP-адреса.
Разберемся с содержимым скрипта:
template = open('traceroute.template')
- содержимое файла с шаблоном TextFSM считывается в переменную templatefsm = textfsm.TextFSM(template)
- класс, который обрабатывает шаблон и создает из него объект в TextFSMresult = fsm.ParseText(traceroute)
- метод, который обрабатывает переданный вывод согласно шаблону и возвращает список списков, в котором каждый элемент - это обработанная строкаprint(fsm.header)
, который содержит имена переменных и результат обработкиВ этим выводом можно работать дальше. Например, периодически выполнять команду traceroute и сравнивать, изменилось ли количество хопов и их порядок.
Для работы с TextFSM нужны вывод команды и шаблон: