Прошлый пост был посвящен созданию простой лаборатории EVE-NG с 3 разными поставщиками (Cisco, Juniper и Huawei). В этом посте давайте запачкаем руки и приступим к некоторым действиям по автоматизации сети.
1 В чем разница между Paramiko, Netmiko, NAPALM, Ansible и Nornir?
Прежде чем мы начнем лабораторию сетевой автоматизации, я считаю своим долгом немного поговорить о том, как работают различные инструменты автоматизации и в чем их различия.
Я ни в коем случае не являюсь экспертом ни в одном из следующих инструментов, но я постараюсь изо всех сил описать их в терминах непрофессионала, основываясь на своем опыте.
- Парамико: Просто удобная библиотека Python SSH, используемая для ssh-связи (очевидно) с устройствами.
- Netmiko: Еще одна библиотека Python SSH, основанная на Paramiko, но больше ориентированная на сетевые устройства. В отличие от Paramiko, он поддерживает Telnet. В сочетании со скриптами Python этого инструмента достаточно для запуска автоматизации сети. Очень легко начать работу и распечатать результаты ваших команд и очистить экран с помощью регулярных выражений, или еще лучше, если вы используете шаблоны TextFSM и NTC для анализа результатов. Небольшое предостережение заключается в том, что вы должны самостоятельно справляться с многопоточностью, если намерение состоит в том, чтобы использовать Netmiko для крупномасштабной сети.
- NAPALM: библиотека/фреймворк Python, который поддерживает нескольких поставщиков с помощью API. Это инфраструктура абстракции, и базовые сетевые драйверы NAPALM позволят ей возвращать один и тот же вывод для вашего запроса (например, get_interfaces, get_facts) независимо от того, на каком типе устройства вы работаете. Если ваши устройства не полностью поддерживаются, у вас есть возможность написать свою собственную библиотеку Python (которую я пробовал, но не рекомендую, подробно расскажу позже в этом посте). Фреймворк NAPALM можно использовать в сочетании с Ansible, Salt и Nornir.
- Ansible: Один из самых известных инструментов автоматизации. Дело в том, что в Ansible вам нужно писать сборники сценариев Ansible на YAML, что является своего рода обоюдоострым мечом; он не требует от вас знания программирования на Python, но работа только с YAML снижает гибкость ваших задач автоматизации. Ansible IMO лучше подходит для общей ИТ-среды, а не для сетевых устройств.
- Nornir: Фреймворк на Python, созданный специально для сетевых устройств, разработанный и поддерживаемый теми же ребятами, которые делали NAPALM и Netmiko. Это 100% Python, фреймворк написан на Python, и вы пишете код на Python, чтобы использовать Nornir. Библиотеки NAPALM и Netmiko могут выступать в качестве геттеров и драйверов соединений для Nornir. Кроме того, Nornir многопоточный и невероятно быстрый по сравнению с Ansible.
Есть и другие инструменты автоматизации, о которых я не упомянул; такие как Scrapli, Puppet, Chef, Salt, pyATS и т.д.
2 Тестирование средств автоматизации (Netmiko, NAPALM, Nornir)
В этом разделе я собираюсь показать базовое использование некоторых инструментов, описанных выше.
2.1 Подключение SSH к устройствам
Во-первых, включите SSH на каждом устройстве:
Juniper Junos: 20.4R3.8
set system login user juniper class super-user authentication plain-text-password
set system services ssh root-login allow
set system services ssh protocol-version v2
set system services ssh connection-limit 10
Huawei VRP: 8.180
aaa
local-user huawei password irreversible-cipher $1c$jF...
local-user huawei service-type telnet ssh
local-user huawei state block fail-times 3 interval 5
user-interface vty 0 4
authentication-mode aaa
user privilege level 3
idle-timeout 0 0
stelnet server enable
ssh user huawei
ssh user huawei authentication-type all
ssh user huawei service-type all
ssh authorization-type default password
Cisco IOS-XR: 6.1.3
2.2 Netmiko
Ниже приведен очень простой пример использования Netmiko ConnectHandler для получения вывода команды show с маршрутизаторов. В этом примере метод send_command() вернет описание интерфейса и IP-адреса каждого устройства. Если вы хотите преобразовать результат в структурированные данные, вы можете использовать шаблоны TextFSM и NTC.
Python
#netmiko_test.py
from netmiko import ConnectHandler
juniper_vMX = {
'device_type': 'juniper',
'ip': '192.168.13.11',
'username': 'juniper',
'password': 'Juniper'
}
net_connect = ConnectHandler(**juniper_vMX)
output = net_connect.send_command("show interface terse")
print("Juniper IP:\n\n"+output+"\n---------------------------------------\n")
huawei_vrp = {
'device_type': 'huawei',
'ip': '192.168.13.22',
'username': 'huawei',
'password': 'Admin@1231'
}
net_connect = ConnectHandler(**huawei_vrp)
output = net_connect.send_command("display ip int br")
print("Huawei IP:\n\n"+output+"\n---------------------------------------\n")
ios_xr = {
'device_type': 'cisco_xr',
'ip': '192.168.13.33',
'username': 'cisco',
'password': 'cisco'
}
net_connect = ConnectHandler(**ios_xr)
output = net_connect.send_command("show ip int br")
print("Cisco IP:\n\n"+output+"\n---------------------------------------\n")
2.3 NAPALM
Мой план состоял в том, чтобы получить информацию о соседях BGP с помощью NAPALM. NAPALM - очень простой инструмент, если все типы ваших устройств поддерживаются. Однако в нашем сценарии это не так. Роутеры Huawei официально не поддерживаются NAPALM, существует общественная библиотека NAPALM (NAPALM-Huawei-VRP), но она имеет очень ограниченные встроенные функции. Моим единственным вариантом было написать свои собственные функции на основе версии сообщества, пока я исследовал, обнаружил, что я не единственный, кто пытался это сделать. Я сначала проделал тяжелую работу, но в том моем коде все еще отсутствовали некоторые части. Разверните следующий фрагмент кода для реализации соседа BGP для платформы Huawei VRP. Мой репозиторий github содержит полный код, так что вам не придется изобретать велосипед.
Теперь, когда библиотека NAPALM наконец-то готова к действию, давайте попробуем!
#napalm_test.py
import napalm
def main():
driver_juniper = napalm.get_network_driver("junos")
driver_vrp = napalm.get_network_driver("huawei_vrp")
driver_ios = napalm.get_network_driver("iosxr")
juniper_router = driver_juniper(
hostname = "192.168.13.11",
username = "juniper",
password = "Juniper"
)
vrp_router = driver_vrp(
hostname = "192.168.13.22",
username = "huawei",
password = "Admin@1231"
)
ios_router = driver_ios(
hostname = "192.168.13.33",
username = "cisco",
password = "cisco"
)
print("Connecting to Juniper Router...")
juniper_router.open()
print("Checking Juniper Router BGP Neighbors:")
print(juniper_router.get_bgp_neighbors())
juniper_router.close()
print("Test Completed\n")
print("Connecting to Huawei Router...")
vrp_router.open()
print("Checking Huawei Router BGP Neighbors:")
print(vrp_router.get_bgp_neighbors())
vrp_router.close()
print("Test Completed\n")
print("Connecting to IOS Router...")
ios_router.open()
print("Checking IOS Router BGP Neighbors:")
print(ios_router.get_bgp_neighbors())
ios_router.close()
print("Test Completed\n")
if __name__ == "__main__":
main()
В отличие от того, что сделал Netmiko, NAPALM генерирует структурированный результат для каждого маршрутизатора. Результат BGP neighbors возвращается в виде словаря словарей.
JUNIPER
{
"global": {
"router_id": "1.1.1.1",
"peers": {
"10.0.12.2": {
"local_as": 123,
"remote_as": 123,
"remote_id": "2.2.2.2",
"is_up": True,
"is_enabled": True,
"description": "",
"uptime": 211073,
"address_family": {
"ipv4": {
"received_prefixes": 1,
"accepted_prefixes": 1,
"sent_prefixes": 1,
},
"ipv6": {
"received_prefixes": -1,
"accepted_prefixes": -1,
"sent_prefixes": -1,
},
},
},
"10.0.13.3": {
"local_as": 123,
"remote_as": 123,
"remote_id": "3.3.3.3",
"is_up": True,
"is_enabled": True,
"description": "",
"uptime": 211079,
"address_family": {
"ipv4": {
"received_prefixes": 1,
"accepted_prefixes": 1,
"sent_prefixes": 1,
},
"ipv6": {
"received_prefixes": -1,
"accepted_prefixes": -1,
"sent_prefixes": -1,
},
},
},
},
}
}
HUAWAY
{
"global": {
"router_id": "2.2.2.2",
"peers": {
"10.0.12.1": {
"local_as": 123,
"remote_as": 123,
"remote_id": "1.1.1.1",
"is_up": True,
"is_enabled": True,
"description": "",
"uptime": 211080,
"address_family": {
"ipv4 unicast": {
"received_prefixes": 1,
"accepted_prefixes": 1,
"sent_prefixes": 1,
}
},
},
"10.0.23.3": {
"local_as": 123,
"remote_as": 123,
"remote_id": "3.3.3.3",
"is_up": True,
"is_enabled": True,
"description": "",
"uptime": 211080,
"address_family": {
"ipv4 unicast": {
"received_prefixes": 1,
"accepted_prefixes": 1,
"sent_prefixes": 1,
}
},
},
},
}
}
CISCO
{
"global": {
"peers": {
"10.0.13.1": {
"local_as": 123,
"remote_as": 123,
"remote_id": "1.1.1.1",
"description": "",
"is_enabled": False,
"is_up": True,
"uptime": 211044,
"address_family": {
"ipv4": {
"received_prefixes": 1,
"accepted_prefixes": 1,
"sent_prefixes": 1,
}
},
},
"10.0.23.2": {
"local_as": 123,
"remote_as": 123,
"remote_id": "2.2.2.2",
"description": "",
"is_enabled": False,
"is_up": True,
"uptime": 211062,
"address_family": {
"ipv4": {
"received_prefixes": 1,
"accepted_prefixes": 1,
"sent_prefixes": 1,
}
},
},
},
"router_id": "3.3.3.3",
}
}
С помощью вложенных словарей вы можете легко получить доступ к элементам, используя синтаксис [ ]. Эта строка кода возвращает время работы BGP однорангового узла 10.0.12.2 в секундах.
print (juniper_router.get_bgp_neighbors()['global']['peers']['10.0.12.2']['uptime'])
> 211073
2.4 Норнир (NORNIR)
2.4.1 Инициализация Nornir
В этой лаборатории мы используем плагин SimpleInventory, который хранит все необходимые данные в трех файлах (hosts.yaml, groups.yaml, defaults,yaml).
hosts.yaml
---
router1:
hostname: 192.168.13.11
username: juniper
password: Juniper
groups:
- juniper
router2:
hostname: 192.168.13.22
username: huawei
password: Admin@1231
groups:
- huawei
router2`:
hostname: 192.168.13.22
username: huawei
password: Admin@1231
groups:
- huawei_vrpv8
router3:
hostname: 192.168.13.33
username: cisco
password: cisco
groups:
- cisco
groups.yaml
---
cisco:
platform: ios-xr
huawei:
platform: huawei_vrp
huawei_vrpv8:
platform: huawei_vrpv8
juniper:
platform: junos
defaults,yaml
Нам нужен файл config.yaml, чтобы сообщить Nornir, что у нас есть готовые файлы инвентаризации для Nornir. Вы также можете изменить опцию многопоточности в этом файле.
#config.yaml --- inventory: plugin: SimpleInventory options: host_file: "hosts.yaml" group_file: "groups.yaml" defaults_file: "defaults.yaml" runner: plugin: threaded options: num_workers: 100 Теперь мы можем создать объект Nornir следующим образом: python from nornir import InitNornir nr = InitNornir(config_file="config.yaml")
Как я уже упоминал, Nornir поддерживает сторонние плагины, такие как Netmiko, Scrapli, NAPALM, Ansible, Jinja2, Netbox и т.д.
Давайте посмотрим, как мы можем использовать Netmiko и NAPALM в Nornir.
2.4.2 Nornir с плагином Netmiko
Для начала давайте попробуем плагин Netmiko. Давайте сделаем это более увлекательным с помощью функции фильтра Nornir, чтобы выбрать определенную группу маршрутизаторов в нашем инвентаре и показать информацию о соседе BGP на этом маршрутизаторе с помощью Netmiko. Для получения результата команды необходимо импортировать плагин и запустить всего одну строку кода.
Python
Теперь давайте попробуем плагин NAPALM для Nornir. На этот раз я использую ~F для фильтрации маршрутизаторов, которые не являются "huawei_vrpv8". Затем запустите NAPALM getters для получения информации о соседе BGP.
Python
#nornir_napalm_test.py
from nornir import InitNornir
from nornir_napalm.plugins.tasks import napalm_get
from nornir_utils.plugins.functions import print_result
from nornir.core.filter import F
nr = InitNornir(config_file="config.yaml", dry_run=True)
group2 = nr.filter(~F(groups__contains="huawei_vrpv8"))
results = group2.run(task=napalm_get, getters=["bgp_neighbors"])
print_result(results)
Bug?
Вы заметили, что у меня были дубликаты в файлах hosts.yaml и groups.yaml? Это связано с тем, что Netmiko и NAPALM используют разные названия платформы для маршрутизаторов Huawei VRP, и для исправления несовместимости потребовалось небольшое обходное решение.
Эта лаборатория — лишь малая толика того, чего могут достичь Nornir и другие инструменты автоматизации.
3 Какой инструмент автоматизации использовать?
Никто не может сказать вам, какой инструмент автоматизации лучший; Все зависит от сценария. Отличный способ начать изучение автоматизации — Python в сочетании с Netmiko. Постройте лабораторию на GNS3 или EVE-NG, и написание нескольких скриптов со временем укрепит вашу уверенность в себе. Несмотря на то, что и Netmiko, и NAPALM отлично подходят для лабораторных работ, в реальных случаях использования вам, возможно, придется учитывать масштабируемость и производительность. Ansible и Nornir лучше работают в реальных производственных сетях. Конечно, вы можете создать свой собственный скрипт многопроцессорности/многопоточности с помощью низкоуровневых инструментов автоматизации, но это делает код более сложным, чем необходимо.
На данный момент я лично выбираю инструмент автоматизации Nornir, так как он дает мне гибкость в написании на Python, а также очень мощный в сочетании с различными сторонними инструментами. И это быстро, в соответствии с этим соревнованием на скорость.
Если у вас есть какие-либо мысли или вопросы по этой теме, пожалуйста, не стесняйтесь оставить комментарий или отправить мне сообщение. Я хотел бы продолжить дискуссию и услышать вашу точку зрения.
А также вы всегда можете поддержать меня зайдя на сайт и подписаться https://dzen.ru/kalyuzhnyy.ru и найти больше статей на моих ресурсах https://kalyuzhnyy.ru и https://dev.kalyuzhnyy.ru или на моем канале telegramm https://t.me/nbkalyuzhnyy на котором в будущем будут выкладываться самые актуальные новости и инструкции по навыкам и обучению. Подпишись!