Мы уже разобрали в прошлых частях как накатить на сетевые устройства Huawei список команд из внешнего файла. И это работает, если у нас сеть состоит из одинаковых устройств. Конечно, в реальной практике такое встречается редко. В этой работе мы рассмотрим как использовать разные конфигурационные файлы для разных устройств Huawei, при этом не выходя за рамки одного скрипта. То есть у нас будет все тот же скрипт на основе Netmiko, но в зависимости от версии устройства, конфиг будет накатываться разный: один конфиг для коммутатора CloudEngine Huawei, другой конфиг для роутера AR3200 Huawei.

Как обычно, полный скрипт приведу в конце статьи, видеодемонстрация доступа по ссылке на Форуме Huawei ICT Club.

Чтобы наглядно продемонстрировать как сложна бывает жизнь сетевого инженера, нужно было найти пример задания, реализация которого отличалась бы в зависимости от вида устройства или программного обеспечения. Далеко ходить не пришлось: недавно на форуме Huawei ICT Club, в рамках создания материалов для HCIP Datacom, показывали как на коммутаторах серии S ограничить обработку ICMP запросов. Эта конфигурация для CloudEngine отличается от конфигурации для AR. Исходя из этого различия, я создал два конфигурационных файла. Один назвал “switch_file_config”, в котором прописал команды для CloudEngine:

icmp rate-limit threshold 5

commit

return

Другой назвал “router_file_config”, в котором прописал команды для AR-роутера:

icmp rate-limit enable

icmp rate-limit threshold 5

return

Как видите, для AR нужно сначала применить команду активации, а для CE нет. Кроме того, для CE важно завершать любую конфигурацию командой commit, иначе конфиг не применится.

Теперь зададимся вопросом: каким будет логика скрипта?

Скрипт подключается к устройству и применяет команду display version, затем ищет в полученном выводе точное совпадение из списка, который мы ему пропишем в переменной list_versions:

list_versions = ['CE6800 V200R005C10SPC607B607',
                 'AR3200 V200R003C00'
                 ]

При этом скрипт сначала выведет на экран надпись “Подключаюсь к устройству” + IP адрес устройства. Затем “Ищу версию ПО” + первое значение из списка list_versions. Если версия совпадет, то скрипт выводит на экран “Найдена версия ПО” + совпавшее значение из списка list_versions. Если не совпадет, то “Не смог найти” + значение из списка list_versions. Реализуем это с помощью цикла for in, который будет работать в основном цикле подключения к устройствам из списка devices, то есть делаем цикл в цикле. Затем используем условную инструкцию if-elif-else для реализации логики «совпадает/не совпадает». И метод find(), которое вернет значение -1, если значение не будет найдено.

# Проверка версии ПО
for software_ver in list_versions:
    print ('Ищу версию ПО ' + software_ver)
    output_version = ssh_connect.send_command('display version')
    int_version = 0 # Сбрасываем цельночисловое значение
    int_version = output_version.find(software_ver) # Проверка версии ПО
    if int_version > 0:
        print ('Найдена версия ПО ' + software_ver)
        break
    else:
        print ('Не смог найти ' + software_ver)

Утверждение break нужно для того, чтобы остановить цикл после успешного совпадения.

После этого остается только прописать за какими командами обращаться в зависимости от полученного результата, а именно: если версия CE6800, то обращаться к командам config_lines_switch, а если AR3200, то к config_lines_router:

if software_ver == 'CE6800 V200R005C10SPC607B607':
    print ('Накатываю команды для ' + software_ver + '...')
    output = ssh_connect.send_config_set(config_lines_switch)
elif software_ver == 'AR3200 V200R003C00':
    print ('Накатываю команды для ' + software_ver + '...')
    output = ssh_connect.send_config_set(config_lines_router)
print(f"\n\n-------------- Сетевое устройство {network_device['ip']} --------------")
print(output)
print("----------------------- Конец ----------------------")

Для эстетики вывода конфигурация будет замыкаться между надписями “Сетевое устройство” + IP, и “Конец”. Например, так:

Видеодемонстрацию наката конфигурации, как и говорил, можете посмотреть по ссылке.

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

from getpass import getpass
from netmiko import ConnectHandler
from netmiko.ssh_exception import NetMikoTimeoutException
from paramiko.ssh_exception import SSHException
from netmiko.ssh_exception import AuthenticationException

username = input('Введите имя пользователя SSH: ')
password = getpass()

with open('switch_file_config') as f:
    config_lines_switch = f.read().splitlines()

with open('router_file_config') as f:
    config_lines_router = f.read().splitlines()

with open('mydevices') as f:
    ip_lines = f.read().splitlines()

for device in ip_lines:
    print ('Подключаюсь к устройству: ' + device)
    ip_address_of_device = device
    network_device = {
        'device_type': 'huawei',
        'ip':   ip_address_of_device,
        'username': username,
        'password': password
    }

    try:
        ssh_connect = ConnectHandler(**network_device)
    except (AuthenticationException):
        print ('Неверные данные аутентификации: ' + ip_address_of_device)
        continue
    except (NetMikoTimeoutException):
        print ('Нет ответа от устройства: ' + ip_address_of_device)
        continue
    except (SSHException):
        print ('SSH недоступен. Проверьте включен ли SSH? ' + ip_address_of_device)
        continue

    # Виды устройств
    list_versions = ['CE6800 V200R005C10SPC607B607',
                     'AR3200 V200R003C00'
                     ]

    # Проверка версии ПО
    for software_ver in list_versions:
        print ('Ищу версию ПО ' + software_ver)
        output_version = ssh_connect.send_command('display version')
        int_version = 0 # Сбрасываем цельночисловое значение
        int_version = output_version.find(software_ver) # Проверка версии ПО
        if int_version > 0:
            print ('Найдена версия ПО ' + software_ver)
            break
        else:
            print ('Не смог найти ' + software_ver)


    if software_ver == 'CE6800 V200R005C10SPC607B607':
        print ('Накатываю команды для ' + software_ver + '...')
        output = ssh_connect.send_config_set(config_lines_switch)
    elif software_ver == 'AR3200 V200R003C00':
        print ('Накатываю команды для ' + software_ver + '...')
        output = ssh_connect.send_config_set(config_lines_router)
    print(f"\n\n-------------- Сетевое устройство {network_device['ip']} --------------")
    print(output)
    print("----------------------- Конец ----------------------")

Другие аспекты скрипта раскрыты в предыдущих постах:

Применение exception при накате Python-скрипта на Huawei

Мой друг Netmiko. Часть 2: Три улучшения Python-скрипта

Мой друг Netmiko

Литература:

https://stackoverflow.com/questions/5563089/raw-input-function-in-python

https://pynet.twb-tech.com/blog/automation/netmiko.html

https://pyneng.readthedocs.io/en/latest/book/18_ssh_telnet/netmiko.html

https://github.com/ktbyers/netmiko

https://github.com/ktbyers/netmiko/blob/master/netmiko/ssh_dispatcher.py

Udemy.com - Python Network Programming for Network Engineers (Python 3) (David Bombal)

https://www.pythoncentral.io/pythons-range-function-explained

Комментарии (13)


  1. divaka
    29.03.2022 17:17
    +1

    Пора, оставить netmiko (paramiko) и автоматизацию через CLI, в 2022 году надо использовать специальные интерфейсы для работы с сетевым оборудованием NETCONF, RESTCONF, REST. у Huawei есть хорошая дока Datacom-Network Automation Developer .

    Современные коробки от Cisco, Huawei имеют на борту даже интерпретатор Python, а некоторые даже умеют и контейнеры с гостевыми OS.

    https://e.huawei.com/en/talent/#/cert/product-details?certifiedProductId=357&authenticationLevel=CTYPE_CARE_HCIP&technicalField=IIC&version=1.0


    1. vasyo Автор
      29.03.2022 19:53

      Пока мои изыская в отношении RESTful на Postman или curl ни к чему не привели: просто нет документации даже, например к CloudEngine ничего не нашел. Если есть у вас опыт, то буду благодарен за инструкцию


      1. divaka
        29.03.2022 22:15
        +1

        Могу порекомендовать книг Натальи Самойленко Питон для сетевых инженеров и что то там про Ansible

        У Huawei в разделе обучения есть специализация Network Automation Developer, закладка Learning, искать

        Training materials: HCIP-Datacom-Network Automation Developer V1.0 Training material.pdf

        Lab Guide: HCIP-Datacom-Network Automation Developer V1.0 Lab Guide.pdf

        https://e.huawei.com/en/talent/#/cert/product-details?certifiedProductId=357&authenticationLevel=CTYPE_CARE_HCIP&technicalField=IIC&version=1.0

        у Cisco есть тоже свое направление DevNET тут не подскажу, где брать.


        1. vasyo Автор
          29.03.2022 23:49
          +1

          Да, для Cisco, конечно, нет проблем найти информацию по настройке. Другое дело Huawei... этот гайд, что вы привели (и спасибо Вам за наводку) это официальная документация, которая имеет свои особенности и свой взгляд, она может хорошо подходить для сдачи экзамена, но не совсем подходить для реальной производственной практике. А ведь именно осмысленных и протестированных самими пользователями материалов и не хватает для Huawei. Опять же методичка Натальи писалась для Cisco и просто так на Huawei ее не перенести: все же логика Huawei от Cisco отличается. Этого может быть не видно на первый взгляд, но тот, кто покопался, знает, что многие вещи отличаются. Поэтому я бы не сравнивал два этих вендоров с точки зрения взаимоиспользования методичек, несмотря на то, что речь идёт об использовании стандартизированных протоколов.


          1. divaka
            30.03.2022 10:04
            +1

            Не соглашусь с вами что логика работы с Huawei сильно отключается от работы с Cisco, различаться команды и их вывод, сам подход к настройке каких либо фич. но это особенности OS, а вот сам порядок работы с CLI он один везде, отправили команду , ждем (и вот тут пробема как отловить конец ответа, к примеру netmiko запоминает промт, и ждем пока не появиться это приглашение, пример из мей практики после команды на смену контекста на Cisco ASA меняется, приглашение и netmmiko на этом валиться не получив ожидаемое приглашение,это решаеться путем доп. настройки что мы ждем перед отправкой комманд.) и парсим ответ.

            вот тут и становятся полезны всякого рода высокоуровневые интерфейсы по типу napalm, Nornir. Они позволяют сосредоточиться на задаче и спрятать особенности OS под капотом. тот же Cisco NSO оперирует абстракциями, а работа с железом вынесена на драйверы.


            1. vasyo Автор
              30.03.2022 16:07

              Я про такие особенности и различия как, например, необходимость указывать в конце команду return при работе с Huawei и конфигурационным файлом, в то время как на Cisco такой дополнительной команды указывать не надо. А ведь на такие детали и мелочи и уходит больше всего времени траблшутинга: вроде бы ничего концептуально различного нет, но конфиг без этой небольшой команды не запустится. Спасибо, что подсказали посмотреть в сторону napalm, Nornir. Они решают такие проблемы в том числе? Я так понимаю, что такие решения зависят от того описана модель данных под конкретную задачу или нет?..


      1. divaka
        29.03.2022 22:23
        +1

        еще бы посоветовал, максимально использовать SNMP чтоб вычитывать версии софта, модели железа, имена устройств и прочее что стандартизировано, поможет избежать лишний парсинг ответа CLI и уменьшить вероятность ошибок. Тот же eSight максимально конфигурирует железо Huawei через SNMP.


    1. Megakazbek
      29.03.2022 20:44
      +2

      А работать приходится не с самым современным оборудованием, а с тем, какое есть. И активно появляться это начало совсем недавно и не везде - например, в энтерпрайз-сети на оборудовании Cisco, построенной всего пару лет назад никаких этих нетконфов нет и в помине.


      1. vasyo Автор
        29.03.2022 21:38

        Действительно, это только у маркетинга все хорошо и просто. А на деле, если продукт есть и есть документация под него, то ещё не факт, что все заработает. Это надо сидеть и колупаться. Restconf и netconf далеко не волшебные палочки. У Huawei, например, надо их ещё активировать на устройствах и SSL сертификат загрузить, а это та ещё задачка.


      1. divaka
        29.03.2022 22:09
        +1

        Соглашусь, что хватает морально устаревшего железа, но я за то чтоб современные задачи решать современными инструментами. я за Ansible, Napalm, pyATS.

        из личного опыта Cisco вся линейка 9000 имеет API, ISG второго поколения умеют ASA имеет на борту REST API, NExus - там python основной язык конфигурации, Cisco свичи 3850 на борту есть python. Arista - REST api, Mikrotik - есть API.

        В свое время сам съел пуд соли со всякими netmiko при автоматизации конфигурации Cisco ASA если там есть контексты то это пытка с их переключением и вводом команд, и нет 100% гарантированного результата. в итоге активировал REST API.


        1. vasyo Автор
          29.03.2022 23:38

          Я работал с Ansible и пришел к выводу, что он очень не гибкий. Во-первых, потому что модели YANG/Netconf пишутся только для Cloud Engine коммутаторов Huawei, а для стареньких моделей S приходится использовать cli. И разные операции в одну задачу не запихаешь: для включения интерфейса используется один модуль, а для ACL, например, другой, и для каждой задачи нужно делать свой накат. Поэтому, здесь Python+cli выигрывают: в один скрипт можно сразу много чего включить.


          1. divaka
            30.03.2022 09:50
            +1

            Хорошо кода вы сами писали и сами эксплуатируете скрипт, а вот придет другой специалист на ваше место и ему читать ваш код, он не разберётся и будет плодить свои скрипты. Ansible в этом плен удобней он описан есть сообщество, а то что каждая задача свой таск это я считаю за плюс. изменения в части одного таска гарантированно не затронет другие задачи. И разве при использовании playbook в каждом таске мы не указываем модуль который будем использовать ?


            1. vasyo Автор
              30.03.2022 16:24

              Да, я поддерживаю ваш взгляд на стандартизацию и с точки зрения управления проектами в длительной перспективе они решают может быть недостаток квалифицированных кадров. Netmiko в данном случае это скорее, да, индивидуальное решение, которое может помочь сетевому инженеру начать автоматизировать сеть самому и начать понимать и чувствовать логику этого процесса. Насчет Ansible, да, модули прописываются в playbook и их можно указать несколько, но дело в том, что одни модули работают только с netconf, а другие только с network_cli. Например, недавно я настраивал роутер, и вот для настройки интерфейсов модуль был для Netconf, а вот для настройки DHCP его уже не было и пришлось делать через network_cli. Ну а для того, чтобы поменять протокол нужно лезть в host файл. Отсюда и следует негибкость. Конечно, эта ограниченность связана только с отсутствием описанных моделей, но работа в этом направлении ведётся...