Размер шрифта:
Глава 3. Работа с сетями через API и движимое намерениями проектирование сетей - Полное руководство работы с сетями на Python

Глава 3. Работа с сетями через API и движимое намерениями проектирование сетей - Полное руководство работы с сетями на Python

Глава 3. Работа с сетями через API и движимое намерениями проектирование сетей

В своей предыдущей главе мы рассмотрели способы интерактивного взаимодействия со своими устройствами при помощи Pexpext и Paramiko. Оба этих инструмента применяют непрерывно действующий сеанс для имитации набора пользователем команд так, как если бы он находился за своим терминалом. Это прекрасно работает до определённого момента. Достаточно просто отправлять команды для исполнения на определённом устройстве и перехватывать обратный вывод. Однако когда ваш вывод становится содержащим несколько строк символов, вычислительной программе становится сложным интерпретировать имеющийся вывод. Для того чтобы наша простая вычислительная программа смогла автоматизировать часть того что мы выполняем, нам необходимо интерпретировать свои возвращаемые результаты и осуществлять последующие действия на основании этих возвращаемых результатов. Когда мы не можем точно и предсказуемо интерпретировать все возвращённые результаты, мы не можем ответственно выполнить свою следующую команду.

К счастью интернет сообщество разрешило данную проблему. Представим имеющуюся разницу между некоторыми компьютером и человеком читающими какую- то веб страницу. Данный живой оператор видит слова, картинки и пробелы интерпретируемые его браузером; такой компьютер же видит строки кода HTML, символы Юникода и двоичные файлы. Что происходит когда некий вебсайт должен стать какой- то веб службой для другого компьютера? Не кажется ли вам данная проблема похожей на одну из тех, которые мы представляли ранее? Ответ кроется в прикладном программном интерфейсе, или для краткости API (Application Programming Interface). Согласно Wikipedia понятие API это:

В вычислительном программировании некий API ( Прикладной программный интерфейс , Application Programming Interface) является набором определений процедур, протоколов и инструментов для построения прикладных программ. В общем смысле это некий набор чётко определённых методов взаимодействия между различными программными компонентами. Хороший API делает более простой разработку некоторой вычислительной программы предоставляя все необходимые строительные блоки, которые складываются воедино программистом разработчиком.

В нашем случае такой набор чётко определённых методов взаимодействия должен иметься между нашей программой Python и её устройством назначения.

В данной главе мы рассмотрим следующие темы:

Трактовку инофраструктуры как кода и модели данных

Cisco NX-API и инфраструктура сосредоточенная на приложении

Juniper NETCONF и PyEZ

Arista eAPI и pyeapi

Инфраструктура как код Python

В идеальном мире сетевые инженеры и люди, которые разрабатывают сетевые среды и управляют ими, должны сосредотачиваться на том чего они хотят достичь от такой сетевой среды вместо того чтобы возиться с взаимодействием на уровне устройства. В моей первой должности в качестве интерна для некоторого локального ISP, когда я воспринимал всё широко открытыми глазами и был взолнован, я получил своё первое задание установить некий маршрутизатор на площадке клиента чтобы включить его секцию соединения ретрансляции кадров (frame relay, помните такое?) Как мне это сделать? , спросил я себя. Я был вооружён некоторой стандартной процедурой для включения соединений ретрансляции кадров. Я поехал на площадку к потребителю, вслепую набрал все команды и посмотрев на мерцающие зелёные светодиоды счастливо упаковал свой багаж и отправился восвояси с чувством хорошо выполненной работы. Я просто следовал инструкциям не размышляя о собственно реализации всех набранных мной команд. Что мне было делать если бы светодиод стал красным вместо зелёного? Я полагаю, мне следовало обратиться назад в свой офис.

Конечно, сетевой инженер это не про то как вводить команды в некое устройство, а это тот, кто строит некий способ, который позволит службам доставляться из одного пункта в другой с наименьшими трениями по возможности. Все команды, которые нам приходится применять и тот вывод, который мы должны интерпретировать просто некое средство сделать это. Я бы хотел этим аргументировать что нам следует больше сосредотачиваться насколько это возможно на сетевых замыслах для сетевых сред, движимом намерениями проектировании сетей, и абстрагироваться от взаимодействия на уровне определённого устройства на основе потребностей по мере их необходимости.

По моему убеждению, именно применение некоторого API позволит нам приблизиться к некоторому состоянию проектирования сетей, отвечающего определённым целям (intent-driven networking). Коротко говоря, благодаря своему абстрагированию от того уровня. на котором определённая особая команда исполняется на целевом устройстве, мы сосредотачиваемся на своих целеполаганиях вместо того чтобы решать проблему доставки конкретной команды в данное устройство. Например, если наши намерения состоят в запрете некоторого IP для входа в нашу сетевую среду, мы можем применять список доступа группу доступа в каком- то Cisco и список фильтров в некотором Juniper. Однако, при использовании API наша программа может начать запрашивать исполняющую сторону то чего хотят от него достичь и при этом маскировать какой вид физического устройства будет за это отвечать.

Сопоставление анализа терминальных данных и структурированного вывода API

Представим себе некий распространённый сценарий, при котором нам необходимо зарегистрироваться в определённом устройстве и убедиться что все все имеющиеся в этом устройстве интерфейсе в состоянии up/up (и состояние, и протокол отображаются как up ). Для нашего живого сетевого инженера, получившего доступ к некоторому устройству Cisco NX-OS, достаточно просто выполнить соответствующую команду show IP interface brief чтобы с лёгкостью сказать по результатам вывода какие интерфейсы подняты:

Переход на новую строку, пробелы и самая первая строка имеющихся колонок заголовка легко различаются человеческим глазом. На самом деле, они имеются здесь чтобы помочь нам выстроить, скажем, все IP адреса всех интерфейсов из строки 1 к строке 2 и 3. Если мы поместим себя на место компьютера, все такие пробелы и переходы на новую строку только уводят прочь от на самом деле важного вывода, а именно: какие интерфейсы пребывают в состоянии up/up? Для иллюстрации данного момента мы можем вновь взглянуть на вывод нашего Paramiko:

Если бы нам пришлось выполнить синтаксический разбор этих данных, тогда, естественно, имеется множество способов сделать это, но вот что я бы сделал в виде некоторого псевдокода:

Отделить каждую строку строчным разрывом.

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

Изъять во второй строке всё вплоть до самого VRF и сохранить его в некоторой переменной, так как мы желаем знать вывод какого именно виртуального маршрутизатора отображается.

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

Затем мы расщепляем эту строку на три раздела при помощи пробела, причём каждый из них составляют собственно имя данного интерфейса, IP адрес и затем само состояние этого интерфейса.

Само состояние интерфейса затем расщепляется снова при помощи обратного слэша ( / ), что даёт нам состояния самого протокола, линии и нашего администратора.

Ох, столько работы просто для чего- то, что некий человек может сказать бросив один взгляд! У вас должна иметься возможность оптимизировать данный код и общее число строк, но в целом это именно то что нам необходимо для анализа какого- то экранного вывода, который неким образом не структурирован. Имеется множество подводных камней в данном методе, однако самые большие проблемы, которые я вижу, это:

Масштабируемость : Мы тратим так много времени на доставляющие головную боль подробности для каждого вывода, что трудно представить себе что мы можем сделать это для сотен обычно выполняемых нами команд.

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

Привязанность к производителю и программному обеспечению : Возможно самая большая проблема состоит в том, что раз мы тратим такое время на синтаксический разбор всего вывода для данного конкретного производителя и определённую версию программного продукта, в нашем случае Cisco NX-OS, нам потребуется повторить данный процесс для следующего производителя, которого мы выберем. Не знаю как насчёт вас, но если бы мне пришлось оценивать нового производителя, то такой новый производитель будет иметь сразу один серьёзный недостаток на борту если я вынужден буду переписывать весь свой код анализа экранного вывода вновь.

Давайте сравним это с неким выводом из вызова NX-API для того же самого отображения краткой команды IP интерфейса. Позже в данной главе мы пройдём особенности получения такого вывода от своего устройства, но то что важно здесь, так это сравнить приведённый ниже вывод с предыдущими этапами анализа экранного вывода:

NX-API может возвращать результаты в XML или JSON, и это именно тот вывод JSON, который мы искали. Прямо сейчас вы можете видеть, что все ответы структурированы и могут напрямую соответствовать имеющейся в Python структуре данных словаря. Не требуется никакого синтаксического разбора, поэтому просто указывайте тот ключ, который желаете и выбираете то значение, которое связано с этим ключом. Имеется также некое дополнительное преимущество в некотором коде для указания успешности или отказа команды, при наличии сообщения, говорящего все относящиеся к успеху или отказу основания отправителя. Вам больше не придётся сохранять отслеживание исполнения данной команды, так как она уже возвращена в имеющемся поле input . Также присутствуют некие метаданные, например, текущая версия NX-API.

Такой тип вывода делает более простой жизнь как для производителя, так и для операторов. С точки зрения производителя, они могут более простым способом передавать информацию о настройках и состоянии и выстраивать свою инфраструктуру вокруг этого. Обычно не вызывает сомнений то, что автоматизация во многом необходима и является полезной вещью. Как вы можете обнаружить позже в данной главе , под зонтиком API пребывает множество соперничающих технологий, что касается только самой транспортной стороны дела, у нас помимо всего прочего имеются REST API, NETCONF и RESTCONF. В конечном счёте всё определит всеобъемлющий рынок, но в то же время мы должны вернуться на шаг обратно и решить какая именно технология наилучшим образом отвечает нашим потребностям.

Моделирование данных для инфраструктуры как код

"Какая либо модель данных является некоторой абстрактной моделью, которая организует элементы данных и стандартизирует то, как они соотносятся друг с другом и со свойствами сущностей самого реального мира. Например, некая модель данных может определять, что имеющиеся элементы данных представляют некую машину, могут составлять ряд прочих элементов которые, в свою очередь, представляют цвет и размер данной машины, а также определяют её владельца."

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

Рисунок 1

Что касается сетевых сред, мы можем применить данную концепцию как некую абстрактную модель, которая определяет нашу сеть, будь то ЦОД, кампус или глобальная Всемирная сеть связи (WAN, Wide Area Network). Если мы пристальнее рассмотрим некий физический ЦОД, некий коммутатор Ethernet 2 уровня может представляться как некий прибор, содержащий какую- то таблицу Mac адресов, соответствующих каждому порту. Наша модель коммутации описывает как эти Mac адреса должны храниться в таблице, которая содержит все ключи, дополнительные характеристики (представьте себе VLAN и частную VLAN), и тому подобное. Аналогично мы можем выйти за пределы устройств и представить в виде некоторой модели свой ЦОД. Мы можем начать с общего числа устройств на каждом из уровней доступа, распределения, ядра, как они взаимосвязаны и как должны вести себя в некоторой промышленной среде. Например, если у нас имеется сеть FatTree, сколько связей должен иметь каждый из имеющихся маршрутизаторов ствола, сколько маршрутизаторов он должен содержать и сколько последующих прыжков (hop) имеет каждый из определённых префиксов. Такие характеристики могут быть поставлены в соответствие в некотором формате, на который можно ссылаться как на то идеальное состояние, которое нам следует всегда проверять.

Одним из относительно новых языков моделирования сетевых данных, который набирает силу, является YANG. Yet Another Next Generation ( YANG , Ещё одно новое поколение, несмотря на распространённое мнение, некоторые из рабочих групп IETF не лишены чувства юмора). Он впервые был опубликован в RFC 6020 в 2010 и получил поддержку со стороны производителей и операторов. На момент написания данной книги общая поддержка YANG сильно варьируется в зависимости от производителей платформ. Имеющаяся скорость адаптации в промышленности, таким образом, относительно низкая. Однако это именно та технология, за которой стоит стоит следить одним глазом.

API и ACI Cisco

Cisco aystems, являющаяся 362 килограммовой гориллой в сетевом пространстве, не упустила данную тенденцию сетевой автоматизации. Основная проблема всегда заключается в имеющейся путанице между различными продуктовыми линиями Cisco и их уровнями технической поддержки. С продуктовыми линейками из маршрутизаторов, коммутаторов, межсетевых экранов, серверов (унифицированные вычисления), беспроводной связи, программного обеспечения и оборудования для совместной работы, а также аналитического программного обепечения, причём это далеко не полный перечень, трудно понять с чего начать.

Посколку данная книга сосредоточена на Python и сетевых средах, мы выберем сферой тот раздел, который относится к самым основным сетевым продуктам, мы рассмотрим следующее:

Автоматизацию продуктов Nexus с помощью NX-API

Cisco NETCONF и примеры YANG

Сосредоточенную на приложениях инфраструктуру Cisco для ЦОД

Сосредоточенную на приложениях инфраструктуру Cisco для корпораций

Для представленных здесь примеров NX-API и NETCONF, мы можем применять либо всегда доступные через Интернет лабораторные устройства Cisco DevNet, либо локально исполнять Cisco VIRL. Так как ACI является неким отдельным продуктом и лицензируется поверх физического коммутатора, для всех последующих примеров ACI я рекомендую применять доступные лабораторные DevNet для получения представления об этих инструментах, если, конечно, вы не один из тех счастливчиков, которые имеют некую частную ACI лабораторию которой вы можете воспользоваться.

Cisco NX-API

Nexus является продуктовой линейкой коммутаторов ЦОД Cisco. NXAPI позволяет работающему с ним инженеру взаимодействовать с данным коммутатором извне данного устройства с применением различных транспортных протоколов, включающих в себя SSH, HTTP и HTTPS.

Установка лабораторного ПО и подготовка устройства

Вот те пакеты Ubuntu, которые мы установим, причём вы уже можете иметь некоторые из этих пакетов, такие как разработка Pthon, pip и Git:

Если вы применяете Python 2, воспользуйтесь вместо приведённой команды такой строкой:

Библиотека ncclient является библиотекой Python для клиентов NETCONF, поэтому мы установим её из репозитория GitHub чтобы установить самую последнюю версию:

По умолчанию NX-API отключён в устройствах Nexus, поэтому нам необходимо его включить. Мы можем либо применить того пользователя, который уже создан, либо создать некоего нового пользователя для всех процедур NETCONF:

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

Теперь мы готовы ознакомиться с нашим первым примером NX-API.

Примеры NX-API

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

Рисунок 2

В своём следующем примере я выбрал JSON-RPC и тип команд CLI для вызова команды show version :

Рисунок 3

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

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

Все параметры соединения достаточно объясняют себя сами: хост, порт, имя пользователя и пароль. Параметр самого устройства определяет тот вид устройства, к которому подключается данный клиент. Мы также увидим некую дифференциацию в разделе NETCONF Juniper. hostkey_verify bypass пробрасывает соответствующие known_host требующиеся для SSH, в противном все хосты необходимо перечислить в файле

/.ssh/known_hosts . Параметр look_for_keys отключает аутентификацию по общедоступному ключу и применяет для аутентификации имя пользователя и пароль.

Полученный вывод отобразит тот факт, что XML и NETCONF являются поддерживаемыми свойствами для данной версии NX-OS:

Применение ncclient и NETCONF поверх SSH это великолепно, поскольку приближает нас к естественным реализации и синтаксису. Мы будем применять эту библиотеку много раз в дальнейшем. Что касается NX-API, лично я полагаю, что проще иметь дело с HTTPS и JSON-RPC. На нашем предыдущем экранном снимке NX-API Developer Sandbox , если вы сделаете пометку в блоке Request , будет иметься некий блок, помеченный как Python . Если вы кликните по нему, у вас появится возможность получать автоматически преобразуемый сценарий Python на основе библиотеки requests.

Requests является очень популярной, самопровозглашённой HTTP библиотекой для самого Человека, используемая такими компаниями как Amazon, Google, NSA и многими другими. Вы можете обнаружить дополнительную информацию по ней на официальном сайте http://docs.python-requests.org/en/master/.

Для нашего примера show version вам будет автоматически создан такой приводимы ниже сценарий Python. Я просто перепостил весь вывод без каких либо изменений:

В файле cisco_nxapi_2.py вы обнаружите, что я изменил только поля URL, имени пользователя и пароля из приведённого выше файла и выполнил синтаксический разбор получаемого вывода только на предмет версии данного программного обеспечения. Вот данный вывод:

Самая лучшая часть данного метода стотоит в том, что тот же самый синтаксис работает как с командами настройки, так и с командами отображения. Это проиллюстрировано в нашем файле cisco_nxapi_3.py . для настроек со множеством строк вы можете применять имеющееся поле id для определения необходимого порядка действий. В файле cisco_nxapi_4.py приводимая ниже полезная нагрузка перечислена для изменения имеющегося определения нашего интерфейса Ethernet 2/12 в режиме настройки данного интерфейса:

В нашем следующем разделе мы рассмотрим соответствующие примеры для Cisco NETCONF и модели YANG.

Cisco и модель YANG

Ранее в этой главе мы рассмотрели имеющуюся возможность выражения имеющейся сетевой среды при помощи языка моделирования данных YANG. Давайте взглянем на него чуточку поближе.

Прежде всего, мы должны уяснить, что YANG определяет только те типы данных, которые отправляются поверх протокола NETCONF, причём NETCONF присутствует как некий отдельно стоящий протокол, как мы уже видели в разделе с NX-API. YANG, будучи относительным новичком, имеет пятнистую поддержку по производителям и продуктовым линейкам. Например, если мы исполним тот же самый сценарий обмена возможностями, что мы применяли ранее, к Cisco 1000v под управлением IOS-XE, мы обнаружим следующее:

Сравним данный вывод с тем что мы уже видели; ясно что IOS-XE понимает модель YANG лучше чем NX-OS. Широкое моделирование сетевых данных в отрасли очевидно является чем- то что привносит преимущества в сетевую автоматизацию. Однако представленная неравномерная поддержка по производителям и продуктам не является чем- то тем, что является достаточно зрелым для применения по всем промышленным сетевым средам, по крайней мере с моей точки зрения. Для данной книги я включил некий сценарий с названием cisco_yang_1.py , который показывает как выполнять синтаксический разбор вывода NETCONF XML с применением фильтров YANG имеющих название urn:ietf:params:xml:ns:yang:ietf-interfaces в качестве некоторой отправной точки для просмотра имеющегося тега возможнстей.

Вы можете проверить все самые последние поддержки производителей на странице проекта YANG GitHub.

Cisco ACI

Cisco ACI ( Application Centric Infrastructure , Ориентированная на приложение инфраструктура) предназначена для предоставления некоторого централизованного подхода ко всем имеющимся сетевым компонентам. В контексте ЦОД это означает что имеющийся центральный контроллер осведомлён и управляет всеми коммутаторами ствола, листьев, TOR (top of rack), а также всеми имеющимися функциями сетевых служб. Это может выполняться через GUI, CLI или API. Имеется аргументация что данный ACI Cisco отвечает имеющемуся обширному программно- определяемому построению сетей.

Одним их сбивающих с толку моментов в ACI является имеющаяся разница между ACI и ACI-EM. Если кратко, ACI сосредоточена на операциях ЦОД, в то время как ACI-EM в основном фокусируется на корпоративных модулях. Оба предлагают некий централизованный просмотр и управление всеми сетевыми компонентами, но каждый имеет свои собственные средоточия и совместные инструменты. Например, достаточно часто можно обнаружить как любой ЦОД равёртывает предназначенную для пользователей инфраструктуру беспроводной связи, однако беспроводные сети сегодня являются критически важной частью корпораций сегодня. Другим примером были бы имеющиеся различия в подходах к сетевой безопасности. Хотя безопасность важна в любой сетевой среде, в имеющейся среде ЦОД большая часть политик безопасности вытесняется на краевые узлы сервера для целей масштабируемости; в корпоративной безопасности политики являются чем- то, что совместно используется всеми сетевыми устройствами и серверами.

В отличие от NETCONF RPC, ACI API следует модели REST для применения глаголов HTTP ( GET , POST , PUT , DELETE ) чтобы определять намеченные операции.

Мы можем взглянуть на свой файл cisco_apic_em_1.py , который является некоторой модификацией версии кода примера Cisco lab2-1-get-network-devicelist.py .

Здесь перечислены сокращённые разделы без комментариев и пробелов.

Самая первая функция с названием getTicket() применяет HTTPS POST в своём контроллере с вызываемым путём /api/vi/ticket и именем пользователя и паролем встроенными в сам заголовок. Затем синтаксический разбор возвращает отклик для какого- то сертификата (ticket) с некоторым ограничением по времени:

Наша вторая функция затем вызывает другой путь называемый /api/v1/network-devices с более новым полученным сертификатом (ticker), встроенным в сам заголовок, а затем делает синтаксический разбор полученных результатов:

Получаемый вывод отображает и сырой вывод отклика JSON и некую таблицу синтаксического разбора. Здесь приводится частичный вывод при исполнении для лабораторного контроллера DevNet:

Как мы можем увидеть, мы опросили некое отдельное устройство контроллера, однако мы способны получить некий обзор на верхнем уровне всех имеющихся сетевых устройств, о которых осведомлён данный контроллер. Обратной стороной, конечно, является то, что такой контроллер ACI поддерживает только устройства Cisco на данный момент.

API Python для сетевых сред Juniper

Сетевое оборудование Juniper всегда было предпочитаемо фанами среди толп поставщиков услуг. Если мы отступим на шаг назад и взглянем на имеющуюся вертикаль поставщиков услуг, можно ощутить, что оборудование с автоматизацией сетевой среды всегда находится в верхних строчках их сознания. Задолго до восхода ЦОД облачного масштаба поставщики услуг были одними из тех, кто имел наилучшее сетевой оборудование. Типичная корпорация могла иметь несколько резервируемых Интернет соединений в своей корпоративной штабквартире, а также иметь несколько удалённых площадок для размещения всех сетевых соединений обратно со своими головными офисами неким образом хаба и спиц для осуществления доступа к ресурсам штабквартиры, таким как почта и базы данных. Однако, что касается поставщиков услуг, они были именно теми, кому было необходимо строить, предоставлять, управлять и искать неисправности для подобных соединений и всех лежащих в основе сетевых сред. Они делали свои деньги на продаже имеющейся полосы пропускания помимо обладающих дополнительными возможностями управляемых служб. Для таких поставщиков сетевых служб имело смысл вкладываться в автоматизацию, чтобы использовать как можно меньший объём инженерных часов для жужжания сети, а автоматизация является ключом к этому.

По моему мнению, основное отличие между потребностями каких- то поставщиков сетевых услуг при сопоставлении с их аналогами для облачных ЦОД заключалось с том, что обычно поставщики услуг соединяют всё в некое отделное устройство с добавленными службами. Хорошим примером может послужить MPLS ( Multiprotocol Label Switching , Многопротокольная коммутация по меткам), которую предоставляют почти все сетевые поставщики, однако она редко применяется в сетевых средех корпораций и ЦОД. Juniper, поскольку они были очень успешными, определили эту потребность и преуспели в выполнении требований поставщика услуг в вопросах автоматизации. Давайте взглянем на некоторые API автоматизации Juniper.

Juniper и NETCONF

Протокол NETCONF ( Network Configuration Protocol , Протокол сетевой настройки) является неким стандартом IETF, который впервые был опубликован в 2006 как RFC 4741, который позже был пересмотрен как RFC 6241. В оба этих RFC Juniper внёс большой вклад; фактически в RFC 4741 Juniper был единственным автором. Это имело смысл, так как устройства Juniper полностью поддерживают NETCONF, а он служит базовым уровнем для большей части их средств и инфраструктур автоматизации. Некоторые из основных свойств NETCONF включают в себя:

Для кодирования данных ин применяет XML ( Extensible Markup Language , Расширяемого языка разметки).

Он применяет RPC ( Remote Procedure Calls , Удалённый вызов процедур), поэтому в случае применения HTTP(s) в качестве транспортного протокола, имеющаяся конечная точка URL всегда идентична, в то время как сама применяемая операция указывается в самом теле данного запроса.

Он концептуально построен на уровнях; с самого верха донизу, причём они включают само содержимое, операции, сообщения и транспорт:

Рисунок 4

Juniper networks предоставляет громадное руководство разработчика протокола управления NETCONF XML в своей технической библиотеке. Давайте бросим взгляд на его применение.

Подготовка устройства

Чтобы начать использование устройства NETCONF, давайте создадим некоторого отдельного пользователя, а также включим необходимую службу:

Для целей своей лаборатории устройств Juniper и использую некую древнюю, не поддерживаемую платформу с названием Juniper Olive . Она используется исключительно для лабораторных целей. Вы можете воспользоваться предпочитаемым вами поисковым механизмом чтобы обнаружить некоторые интересные факты и историю Juniper Olive.

На данном устройстве Juniper вы всегда можете взглянуть на все настройки или в виде некоторого обычного текстового файла, или в формате XML. Имеющийся обычный текстовый файл удобен когда вам необходимо определить команду в одну строку для внесения изменений в настройку:

Формат XML становится удобным, огда вам нужно просмотреть всю структуру XML вашей нстройки:

Мы установили все необходимые библиотеки Linux и нужную нам библиотеку Python ncclient в своём разделе Cisco. Если вы не сделали этого, вернитесь обратно в этот раздел и установите все необходимые пакеты.

Теперь мы готовы рассмотреть свой первый пример Juniper NETCONF.

Примеры Juniper NETCONF

Мы воспользуемся достаточно прямолинейным примером для выполнения show version . Мы назовём данный файл junos_netconf_1.py :

Все поля в данном примере в достаточной степени объясняют себя сами, за исключением device_params . Начиная с ncclient 0.4.1, имеющийся для определения различных производителей и платформ был добавлен определённый обработчик устройства, например, его названием может быть juniper, CSR, Nexus или Huawei. Мы также добавили hostkey_verify=False , так как мы применяем в своём устройстве Juniper самоподписываемый сертификат.

Весь возвращаемый вывод является неким rpc-reply , закодированном в XML при помощи элемента output :

Мы можем выполнить синтаксический разбор всоего вывода XML чтобы просто включить текст вывода:

В junos_netconf_2.py мы внесём изменения в настройку данного устройства. Мы начнём с некоторого нового импорта для построения новых элементов XML и соединения с диспетчером объекта:

Мы заблокируем данную настройку и внесём изменения в конфигурацию:

Из отображаемого XML вы можете увидеть что вся структура данного узла с ' system ' является определённым родителем для ' host-name ' и ' domain-name ':

Затем мы можем выполнит активную доставку данной конфигурации и фиксацию настройки. Это обычные этапы практики применения изменений настроек Juniper:

В целом, все этапы NETCONF достаточно хорошо соответствуют всему, что мы делали на этапах своего CLI. Взгляните, пожалуйста, на наш сценарий junos_netconf_3.py , который комбинирует все наши предыдущие примеры и пример работы.

Juniper PyEZ для разработчиков

PyEZ является некоторой реализацией верхнего уровня Python, которая лучше интегрируется с имеющимся у вас кодом Python. При применении API Python вы можете выполнять общие операции и задачи настройки без наличия углублённого знания CLI Junos.

Juniper осуществляет сопровождение впечатляющего руководства разработчика Junos PyEZ в своей технической библиотеке. Если вас интересует использование PyEZ, я настоятельно рекомендую по крайней мере взглянуть на различные заголовки данного руководства.

Установка и подготовка

Все необходимые инструкции по установке для всех операционных систем можно найти на странице Installing Junos PyEZ. Далее мы отобразим необходимые инструкции по установке для Ubuntu 16.04.

Имеются некоторые зависимые пакеты, причём многие из них уже должны иметься в данном устройстве:

Пактеы PyEZ packages могут быть установлены при помощи pip. Здесь я выполняю установку и для Python 3, и для Python 2:

На самом устройстве NETCONF должен быть настроен как предоставляющий XML API для PyEZ:

Для аутентификации пользователя мы можем применять как аутентификацию по паролю, так и пару ключей ssh. Создание необходимого локального пользователя достаточно непосредственно:

Для аутентификации по ключам ssh вначале создадим пару ключей:

По умолчанию наш общедоступный ключ будет иметь название id_rsa.pub и располагаться в

/.ssh/ , в то время как частный ключ именуется id_rsa в том же самом каталоге. Рассматривайте частный ключ в качестве пароля, который вы никогда не желаете совместно использовать. Ваш общедоступный ключ может свободно распространяться; однако, в данном случае мы переместим его в свой каталог /tmp и разрешим модулю сервера HTTP Python 3 создать некий достижимый URL:

Для Python 2 вместо этого воспользуйтесь python -m SimpleHTTPServer .

На текущий момент мы можем создать нужного пользователя и связанный с ним общедоступный ключ:

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

Давайте убедимся, что данные методы аутентификации работает с PyEZ. Давайте попробуем комбинацию имени пользователя и пароля:

Мы также можем воспользоваться аутентификацией по ключу ssh:

Великолепно! Иеперь мы готовы посмотреть на некоторые примеры для PyEZ.

Примеры PyEZ

В своём предыдущем интерактивном приглашении на ввод мы уже видели что когда данное устройство подключается, сам объект уже автоматически извлекает некоторые факты об этом устройстве. В нашем первом примере, junos_pyez_1.py мы подключались к своему устройству и выполняли вызов RPC для show interface em1 :

Наш класс устройства имеет некоторое надлежащее свойство rpc , которое содержит все исполняемые команды. Это несколько настораживает, так как нет склейки между тем что мы можем делать в CLI с API. Хитрость в том, что мы должны найти теговый элемент xml rpc . В нашем первом примере как мы узнали что show interface em1 эквивалентно get_interface_information ? У нас есть три способа нахождения информации об этом:

Мы можем обратиться к Junos XML API Operational Developer Reference .

Мы также можем воспользоваться CLI и отобразить все эквиваленты XML RPC с заменой тире - между всеми словами на подчёркивание _ .

Мы можем запрограммировать это при помощи имеющейся библиотеки PyEZ.

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

Однако третий вариант также осуществим:

Конечно, нам необходимо выполнить также изменения настроек. В своём примере junos_pyez_2.py мы импортируем некий дополнительный метод Config() из PyEZ:

Мы воспользуемся тем же самым блоком для соединения с неким устройством:

Наш новый метод Config() загрузит все данные XML и внесёт все необходимые изменения настроек:

Все примеры PyEZ просты в построении, но, надеюсь, демонстрируют все способы которыми вы можете усилить свои потребности автоматизации Junos с помощью PyEZ.

API Python Arista

Arista Networks всегда была сосредоточена на сетевых средах ЦОД крупного масштаба. На своей странице корпоративного профиля они постулируют следующее:

"Arista Networks была основана чтобы быть первооткрывателем и поставщиком движимых программным обеспечением облачных сетевых решений для крупный ЦОД сред хранения и вычисления."

Обратите внимание, что данный постулат намеренно называет наш крупный ЦОД , который, как мы уже знаем, подорван серверами, базами данных и, да, сетевым оборудованием тоже. Таким образом в их сознании всегда присутствует автоматизация. На самом деле они имеют в фундаменте Linux в качестве своей операционной системы, затем EOS имеет много дополнительных преимуществ, таких как наличие уже встроенного Python с API Linux.

История автоматизации Arista состоит из трёх подходов:

Рисунок 5

Как и в случае с их сетевыми конкурентами, вы можете взаимодействовать с устройствами Arcsta напрямую через eAPI или можете выбрать с целью усиления их библиотеку Python для осуществления взаимодействия. Мы рассмотрим примеры обоих вариантов. В следующих главах мы взглянем на интеграцию с Arista для Ansible.

Управление eAPI Arista

eAPI Arista впервые был представлен в EOS 4.12 несколько лет назад. Он выполняет транспорт некоторого перечня команд отображения или настройки через HTTP или HTTPS и предоставляет ответы в виде JSON. Некоторое существенное отличие состоит в том, что он является RPC ( Remote Procedure Call , Вызовом удалённых процедур) и JSON-RPC, вместо предоставления передачи состояния и REST, даже хотя самим транспортным уровнем является HTTP(S). Для наших намерений и целей основная разница в том, что мы делаем сам запрос к одному и тому же URL оконечной точки, применяя один и тот же метод HTTP ( POST ). Вместо применения глаголов HTTP ( GET , POST , PUT , DELETE ) для выражения нашего действия, мы просто устанавливаем желаемое нами действие в теле своего запроса. В случае с eAPI мы будем определять ключ method с некоторым значением runCmds для своих намерений.

Для всех последующих примеров я применяю некий физический коммутатор Arista под управлением EOS 4.16.

Подготовка eAPI

Имеющийся в устройстве Arista агент eAPI по умолчанию отключён, поэтому нам необходимо разрешить его в своём устройстве прежде чем мы сможем им воспользоваться:

Вы можете видеть, что мы отключили сервер HTTP и применяем вместо этого для транспорта HTTPS. Начиная с нескольких более ранних версий EOS сам интерфейс управления по умолчанию, располагающийся в VRF имеет название management (Управление). В моей топологии я осуществляю доступ к своему устройству через имеющийся интерфейс Управления; таким образом я особым образом определяю свою VRF (виртуальную маршрутизацию и защиту межсетевым экраном). При помощи соответствующей команды отображения вы можете убедиться что управление API включено:

После включения данного агента у вас имеется возможность осуществлять доступ к странице обследования для eAPI посредством перехода на IP адрес данного устройства. Если вы изменили значение порта по умолчанию, просто добавьте его в самый конец. Выполняющаяся аутентификация привязана к тому методу, который имеется у данного коммутатора; в данном случае это имя пользователя и пароль, которые были настроены локально. По умолчанию будет применяться самоподписываемый сертификат.

Рисунок 6

Вы перенесётесь на некую страницу Проводника в которой вы сможете набрать необходимую команду CLI и получить чудесный вывод для тела своего запроса. Например, если я желаю увидеть как выполнить некое тело запроса для show version , в своём проводнике я обнаружу следующий вывод:

Рисунок 7

Обозреваемая ссылка предоставит вам определённый пример использования и лежащую в основе информацию, в то время как вся документация по данной команде будет предоставлена в виде точки ссылки для возможного отображения команд. Каждая из эталонных команд будет содержать имя поля возвращаемого значения, тип и краткое описание. Ссылка на доступный через Интернет сценарий от Arista применяет jsonrpclib, который мы также применяем. Однако, что касается данной книги, он имеет зависимости Python 2.6+ и пока не портирован в Python 3; таким образом, для своих примеров мы применяем Python 2.7.

На тот момент, когда вы читаете данную книгу, возможно, состояние обновилось. Пожалуйста, прочтите запрос GitHub и GitHub README для ознакомления с самым последним состоянием.

Установка прямолинейна и выполняется посредством easy_install или pip :

Примеры eAPI

Затем мы можем написать некую простую программ с названием eapi_1.py чтобы посмотреть не текст своего отклика:

Отметим, что так как это Python 2, я применяю в своём сценарии from __future__ import print_function чтобы сделать миграцию в дальнейшем более простой. Все соответствующие строки ssl предназначены для Python > 2.7.9, за дополнительными сведениями обращайтесь к https://www.python.org/dev/peps/pep-0476/.

Вот тот отклик, который я получил от своего предыдущего метода runCms() :

Как вы можете видеть, это некий список, содержащий один элемент словаря. Если нам необходимо вычленить имеющийся серийный номер, мы можем просто сослаться на номер элемента и имеющийся в строке 12 ключ:

Полученный вывод будет содержать только сам серийной номер:

Чтобы дополнительно ознакомиться с руководством по командам, я рекомендую вам кликнуть по ссылке Command Documentation на странице API и сопоставить ваш вывод с выводом version в имеющейся документации.

Как уже отмечалось ранее, в отличии от REST, клиент JSON-RPC использует один и тот же URL конечной точки для вызова всех ресурсов данного сервера. Вы можете почерпнуть из предыдущего примера, что имеющийся метод runCmds() потребляет некий список команд. Для самого исполнения команд настройки вы можете последовать той де самой структуре и поместить необходимый перечень команд внутри второго аргумента.

Вот пример команд настройки, вызываемых eapi_2.py :

Вот вывод исполнения всех этих команд:

Теперь выполним быструю проверку в самом коммутаторе чтобы проверить исполнение команд:

В целом eAPI достаточно прямолинеен и прост в применении. Большинство языков программирования имеют библиотеки, аналогичные jsonrpclib , которые абстрагируются от внутреннего устройства JSON-RPC. При помощи всего нескольких команд вы можете начать интеграцию автоматизации Arista EOS в своей сетевой среде.

Библиотека Arista Pyeapi

Сам клиент Python для имеющихся библиотек eAPI и Pyeapi (http://pyeapi.readthedocs.io/en/master/index.html) является естественной обёрткой вокруг eAPI. Он предоставляет некий набор связываний для настройки узлов Arista EOS. Зачем нам нужен Pyeapi, когда у нас уже имеется eAPI and eAPI? Так как мы должны применять Python для демонстрации eAPI, держите в уме что единственным требованием для eAPI является некий JSON-RPC совместимый клиент. Таким образом, он совместим с большинством языком программирования. Что касается лично меня, я считаю, что eAPI является общим знаменателем по всем различным языкам. Когда я впервые начал работать в полях, доминирующим языком для сценариев и сетевой автоматизации являлся Perl. Имелось большое число корпораций, которые полагались на сценарии Perl как на свои первичные средства автоматизации. Либо в ситуации, когда определённая корпорация уже инвестировала некую тонну ресуросв и кодов, основанных на другом языке, eAPI с JSON-RPC будут наилучшим вариантом чтобы пройти через это.

Однако для тех из нас, кто предпочитает кодировать на Python, естественная библиотека Python означает, более натуральные ощущения при написании нашего кода. Это несомненно делает более простым расширение некоторой программы Python для поддержки нашего EOS узла. Это также уберегает нас от самых последних изменений в Python более простым образом. Например, мы можем применять c Pyeapi Python 3!

На момент написания, поддержка Python 3 (3.4+) официально постулировалась как работа в исполнении (http://pyeapi.readthedocs.io/en/master/requirements.html) а документации. Пожалуйста, сверьтесь с имеющейся документацией!

Установка Pyeapi

Установка прямолинейно осуществляется при помощи pip:

Отметим, что pip также установит необходимую библиотеку netaddr, так как она является частью имеющегося состояния (requirements) для Pyeapy.

По умолчанию клиент Pyeapy осуществит поиск некоторого скрытого (с точкой в начале имени) файла в стиле INI с названием eapi.conf в вашем домашнем каталоге. Вы можете изменить такое поведение, определив свой путь к данному файлу eapi.conf , однако это неплохая идея обычно отделять ваши полномочия соединения и блокировать их от самого сценария. Вы можете просмотреть документацию Pyeapy (http://pyeapi.readthedocs.io/en/master/configfile.html#configfile) на предмет описания всех полей, содержащихся в данном файле; вот тот файл, который я применяю в своей лаборатории:

Самая первая строка с названием [connection:Arista1] содержит то имя, которое мы будем применять в своём Pyeapy соединении; все оставшиеся поля должны быть понятны сами по себе. Вы можете заблокировать данный файл доступностью только на чтение для тех пользователей, которые намереваются вызывать его:

Примеры PyEZ

Теперь мы готовы взглянуть на использование. Давайте начнём с подключения к узлу EOS путём создания некоего объекта:

Мы можем выполнять команды отображения на данном узле и принимать обратно их вывод:

Само поле настройки может быть либо некоторой отдельной командой, или списком команд, применяющим имеющийся метод config() :

Отметим, что сокращение команд ( show run вместо show running-config ) и некоторые расширения могут не работать:

Однако вы всегда можете перехватить все результаты обратно и получить желаемой значение:

До сих пор мы выполняли то, что мы делали с eAPI для команд отображения и настройки. Pyeapi предлагает различные API чтобы сделать жизнь проще. В приводимом ниже примере мы соединимся с нужным узлом, вызовем VLAN API и начнём работать с имеющимися у этого устройства параметрами VLAN. Давайте взглянем на это:

Давайте проверим VLAN 10, которую мы создали при помощи VLAN API в данном устройстве:

Как вы можете видеть, естественный API Python во всех объектах EOS в действительности даёт превосходство Pyeapy над eAPI, так как он абстрагируется от признаков самого нижнего уровня в объекте данного устройства.

Для полного перечня даже ещё большего превосходства Pyeapy над eAPI cверьтесь c официальной документацей: (http://pyeapi.readthedocs.io/en/master/api_modules/_list_of_modules.html).

Сворачивая данную главу, давайте предположим, что мы повторили все предыдущие шаги достаточно чтобы мы могли захотеть написать другой класс Python чтобы сохранить нам некую работу под названием pyeapi_1.py :

Как вы можете увидеть, мы автоматически подключились к требуемому узлу и установили необходимые имя хоста и running_config на протяжении данного соединения. Мы также создали некий метод для данного класса, который создаёт VLAN при помощи VLAN API. Давайте попробуем его:

Нейтральные к производителю библиотеки

Имеется целый ряд усилий нейтральных к производителям библиотек, таких как Netmiko и napalm. Так как эти библиотеки не поставляются естественным способом сос тороны самого производителя устройства, они порой на ступень медленнее в поддержке самых последних платформ или свойств. Они также являются поддерживаемыми сообществом, что означает, что они не обязательно идеально подходят, раз вам необходимо полагаться на кого либо ещё чтобы исправлять ошибки без каких- либо обязательств по уровню обслуживания.

Выводы

В данной главе мы рассмотрели различные способы взаимодействия с сетевыми устройствами от Cisco, Juniper и Arista, а также управления ими. Мы рассмотрели оба способа взаимодействия, и NETCONF, и REST, а также применение создаваемых самим производителем библиотек, таких как PyEZ и Pyeapi. Имеются различные уровни абстракции, что означает предоставление некоторого способа программно управлять вашими сетевыми устройствами без вмешательства со стороны персонала.

В следующей главе мы взглянем на некий более высокий уровень нейтральной по отношению к производителю абстракции инструментов с названием Ansible . Ansible является средством автоматизации для общих целей с открытым исходным кодом, написанном на Python. Он может применяться для автоматизации серверов, сетевых устройств, балансировщиков нагрузки, и многого другого. Конечно, для своих целей мы сосредоточимся на его применении для инфраструктуры автоматизации сетевых устройств.

📎📎📎📎📎📎📎📎📎📎