Массовое добавление устройств в netdot с помощью API (pynetdot)

Продолжение этого поста.

Устройства удобно добавлять, имея их список в формате csv. Для добавления порядка ~ 350 устройств я подготовил файл с заголовком:

site_name;name;snmp_target;snmp_version;snmp_community;snmp_managed;entity_id

По заголовкам – в site_name вношу название объекта, где находится ИБП, name – имя устройства, snmp_target – ip-адрес, по которому устройство будет опрашиваться, snmp_version;snmp_community здесь всё понятно, snmp_managed – будет устройство управляться по snmp или нет, entity_id – id компании-владельца в нетдоте (например подрядчик или типа того). csv удобно обрабатывать с помощью библиотеки csv, выглядит это примерно так:

ups_name = row[‘name’]
snmp_ver = row[‘snmp_version’]
snmp_target = row[‘snmp_target’]
snmp_target = snmp_target + ‘/32’
snmp_com = row[‘snmp_community’]
snmp_manag = row[‘snmp_managed’]
site_name = row[‘site_name’].decode(‘utf-8’)
entity_id = row[‘entity_id’]

Скрипт здесь

Работа с netdot через API

Есть такой замечательный инструмент для документирования сети – netdot. Он позволяет вести инвентаризацию оборудования, IPAM, с помощью snmp собирает много полезной инфы – vlan,ы, адресация, маки.. Имеет много плюсов и минусов. Здесь я хочу написать про API. Netdot имеет restfull интерфейс, для python есть соответствующая библиотека – pynetdot. Появилась задача по массовому добавлению устройств в нетдот, а именно ИБП. У нетдота есть discovery, но у нас нет одного диапазона адресов для ИБП, для них выделяются мелкие сети и они разнесены/размазаны по всему диапазону адресов. Итак, начнём.

Подключиться к серверу:

pynetdot.setup(
    url='http://127.0.0.1/netdot',
    username='admin',
    password='pass')

Для привязки ИБП-шника к объекту (Site в терминологии нетдота) необходимо найти id нужного сайта:

site = pynetdot.Site.get_first(name="Суздальский 150")
site_id = site.id

 

Для опроса устройства по snmp ему нужно задать параметр snmp_target, проще говоря ip-адрес. Адрес уже может быть в нетдоте, например в статусе discovery или static, тогда нужно просто взять его id:

ip = pynetdot.Ipblock.get_first(address='192.168.10.1')
ip_id = ip.id

Если его нет по каким-то причинам, придётся создать вручную:

newip = pynetdot.Ipblock(name = ‘suzd150-eaton’)
newip.address = ‘192.168.10.1’ #  need to be in x.x.x.x/32 format
newip.description = ‘suzd150-ups-eaton’
newip.save()
ip_id = newip.id

Что бы не было дублей, можно поискать устройство (Device) с таким ip-адресом:

pynetdot.Device.get_first(snmp_target=ip_id)

Для поиска можно использовать два метода: search или get_first. Search возвращает список (массив) из найденных “объектов”, а  get_first первое совпадение. Причем в качестве snmp_target здесь уже задаём не адрес, а его id (ссылка в mysql-базе нетдота).

Далее необходимо создать dns-запись (имя устройства):

rname = pynetdot.RR(name = ‘suzd150-eaton’)
rname.name = ‘suzd150-eaton’
rname.zone = 9 # zone == ups (suzd150-eaton.ups)
rname.save()

И создаём устройство (экземпляр класса):
device = pynetdot.Device(name=”suzd150-eaton”)

Добавляем snmp-штуки:

device.snmp_managed = 1
device.community = “ololo”
device.snmp_version = “2”
device.snmp_bulk = 1
device.snmp_polling = 1
device.canautoupdate = 1

Добавляем устройству имя, snmp_target, entite(владелец), site:

device.name = rname.id
device.snmp_target = ip_id
device.owner = entity_id
device.site = site_id
device.save() #  At first saved with name: 3386.defaultdomain
device.name = rname.id
device.save() #  All right now

В следующем посте напишу скрипт для добавления этих ИБП.

Организация p2p-связности между конечным и MPLS-роутерами

Часто появляется задача, когда нужно прописать канал по оптике (раньше резерв, например, был по РРЛ). Есть следующая топология:

P80510-202510.jpg

Что нужно сделать:

  • на end_router:
    • Создать сабинтерфейс (или interface vlan)
    • На интерфейсе прописать соответствующий vrf (или использовать по-умолчанию)
    • Прописать дескрипшин
    • Настроить ip-адрес с сеткой
    • Настроить ospf:
      • area
      • network
      • no passive-interface
  • На sw A:
    • Проверить что создаваемого vlan’а нет в конфигурации
    • Создать нужный vlan с именем
    • Проверить фильтры в сторону uplink’а (как правило таких фильтров нет)
  • На sw 1-N, B:
    • Проверить что создаваемого vlan’а нет в конфигурации
    • Создать нужный vlan с именем
    • Проверить фильтры. Скорее всего они будут прописаны в сторону downlink-портов (в сторону site A)
  • на end_router:
    • Создать сабинтерфейс (или interface vlan)
    • На интерфейсе прописать соответствующий vrf (по умолчанию здесь vrf не используется, по любому будет какой-то)
    • Прописать дескрипшин
    • Настроить ip-адрес с сеткой
    • Настроить ospf:
      • area
      • network
      • no passive-interface

Добавить вланы на грядку свитчей достаточно просто. Но, как организовать проверку, где и на каких портах нужно добавлять влан? Так же можно всё вообще ушатать. Проблема в том, что фильтры на vlan прописаны только в сторону downlink-порта. Что надо сделать получается:

  • Найти down-link порт
  • Проверить, настроены ли там фильтры
  • Добавить вланы.

Надо подумать над логикой и реализовать. Может быть проще это сделать с помощью ansible?

 

Парсинг вывода sh int gi0/1 status с помощью TextFSM

Вывод команды:

cgs2520-1#sh int fa0/22 status

Port Name Status Vlan Duplex Speed Type
Fa0/22 AP connected 350 a-full a-100 10/100BaseTX

Задача – распарсить вывод и получить значения следующих полей – статус, скорость, дуплекс, имя и влан.

Результат TextFSM выводит в списке списков. Чтобы сделать из списка списков список:

flat_list = [item for sublist in result for item in sublist]

Собрать в словарь два списка одинаковой длины:

sw=dict(zip(header,flat_list))

Варианты шаблонов для TextFSM здесь

Скрипт здесь. Заходит на железку, смотрит статус интерфейса (переменная задана в скрипте). Вывод записывается в файл, который идентичен ip-адресу железки. Далее вывод парсится по шаблону TextFSM (descr.template). Выводятся порт и дескрипшен.

Cisco CGS2520 поддержка NETCONF

2520 с IOS Cisco IOS Software, CGS2520 Software (CGS2520-LANBASEK9-M), Version 15.2(4)EA5, RELEASE SOFTWARE (fc1) поддерживает netconf. Вроде как..

cgs2520-1#sh netconf schema
New Name Space ‘urn:ietf:params:xml:ns:netconf:base:1.0’
<VirtualRootTag> [0, 1] required
<rpc-reply> [0, 1] required
………………………………………………………………………….

Netconf включается так:

cgs2520-1(config)#netconf ssh

Подключиться к подсистеме netconf можно следующим образом:

ssh -2 -s tar@172.16.1.1 netconf

Что нужно сделать:

  • Разобраться с подключением.
  • Что можно делать (функционал)

Реализация netconf-клиента под python: ncclient

pip install ncclient

 

from ncclient import manager

cisco=manager.connect(host=’ip’, port=’22’, username=’admin’, password=’pass’, allow_agent=False, , look_for_keys=False)

cisco.get()

Выдаёт весь конфиг.

Взаимодействие с Cisco ASR1002x по API

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

Поддерживает REST API, но. Для этого надо скачать модуль поддержки REST. REST API Support for IOS XE – по факту виртуалка, которая устанавливается на ASR. Для того что бы скачать его, нужен сервисный контракт. Печалька..

Настройка SPAN-сессии на ASR-1002X. Генерация шаблонов конфигурации


Настройка локальной SPAN-сессии, с порта на порт.

monitor session 10 type erspan-source
description SPAN-source
source interface Gi0/0/1
destination
erspan-id 10
ip address 10.1.1.1
origin ip address 10.1.1.1
!
!
monitor session 20 type erspan-destination
description SPAN-fdest
destination interface Gi0/0/3 – 4
source
erspan-id 10
ip address 10.1.1.1

Для генерации конфига сделал простой скрипт на python и jinja. Ссылка на гит. Скрипт берёт данные из словаря и на основе шаблона генерирует конфигурацию.

Проверка:

show platform hardware qfp active feature erspan session 20

Автоматизация диагностики каналов связи

Хочу написать скрипт по проверке каналов связи. Опять же здесь логика, реализация позже.

Действия при проверке каналов:

  • Зайти на коммутатор
    • Скрипт для этого уже есть
  • Определить uplink
    • Если это резерв, то порт fa0/22.
    • На нём будет прописан определённый влан
  • Проверить статус порта (up/down, ошибки, скорость, дуплекс, наличие блокировок по errdisable)
  • Проверить состояние STP (блокировка в нужном влане)
  • Проверить mac-адрес на интерфейсе.
UPD. 07.05.2018. Здесь часть логики по определению аплинка и проверки статуса порта. Пока не написаны проверки.