Массовое добавление устройств в 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

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

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

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

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

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

Автоматизация подключения к недоступному оборудованию

Здесь опишу логику работы, скрипт напишу позже.

Особенность работы наших железок на объекте – маршрутизаторы и каналы резервируются, но OSPF между ними разорван. Поэтому когда отваливается один из каналов, доступ на маршрутизатор есть только с другого роутера. Хочу автоматизировать процесс подключения к таким устройствам, чтобы не ломиться сначала на рабочую железку.

Например, есть два лупбека. 192.168.10.10 и 192.168.10.11. Есть сетка для интерконнекта между маршрутизаторами, которая не роутится. Например 1912.168.20.0/30. Допустим, второй маршрутизатор не доступен. Последовательность действий:

  • Стучусь на первую железку
  • Ищу сабинтерфейс .11
  • Вытаскиваю сетку из интерфейса, сетка /30 настроена везде (типовая схема).
  • Считаю её.
  • Сравниваю адреса. Если адрес интерфейса равен первому адресу, значит надо зайти на второй адрес. Если равен второму, то на первый.
  • Зайти на адрес с локальными логином и паролем

Python-скрипт для автоматизации выключения Smart Install на оборудовании cisco

Недавно были проблемы из-за уязвимости в фиче vstack у коммутаторов Cisco. Ссылка на официальную страницу здесь. Написал небольшой скрипт, который заходит на оборудование Cisco с обнаруженной уязвимостью ( nmap -n -p T:4786 -Pn 192.168.100.0/24) и делает no vstack. Потом в лог выводится результат выполнения команды vstack. Возможные ошибки (нет ssh например) так же пишутся в лог. Для работы скрипта нужна библиотека netmiko, можно установить с помощью pip – pip install netmiko. Скрипт написан для python2. Ссылка здесь

В планах:

  • Так как таким образом vstack не отключается на старых версиях IOS (можно порт только заблокировать), хочу сделать проверку на выключение (парсить вывод)
  • Что-то ещё крутилось в голове, пока забыл. Потом добавлю может

Автоматизация управления сетью. Системный подход

С коллегами прослушали курс NPDESI который направлен на знакомство сетевых инженеров с автоматизацией и разработкой ПО. В очередной раз задавшись вопросом, как же получить большую кнопку с надписью сделать хорошо, получили ответ от инструктора:

  • Автоматизация ради автоматизации не имеет смысла. Это нулевой постулат.
  •  В первую очередь необходимо проанализировать бизнес-процессы и выяснить, какие из них можно и имеет смысл автоматизировать. Для системного подхода к управлению можно ознакомиться с ITIL, TAGAF, COBRA
  • Во-вторых мы должны определить, как управлять оборудованием. Какое оборудование есть, какие протоколы оно поддерживает (ssh, NETCONF, REST)
  • Прибыль, которую мы получим от автоматизации. Этот пункт скорее менеджерам, для меня его можно назвать скорее как профит, который я получу при избавлении от рутины – свободное время и т. д.

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

P.S. Различные продукты для управления – всяческие контроллеры, ansible и прочее это всего лишь инструменты, и относиться к ним нужно соответственно.

Ansible, Mikrotik. Часть первая

Продолжаю мучть ansible. Начало здесь.
Пробовал сегодня делать шаблоны. Пока не всё получается, но всё же опишу то, что удалось сделать.
Во первых, для будущего проекта создам роль, ансибл будет смотреть в директории этой роли. Следуя документации получается следующая иерархия:
Домашняя директория:
ansible# pwd
/etc/ansible
Создаю директорию role:
mkdir roles
cd roles
В ней:
roles]# ls -R
.:
router //пока единственная роль router

./router:
site.yml  tasks  templates  vars

./router/tasks:
main.yml

./router/templates:
hotspot.j2

./router/vars:

site.yml – “главный” файл, отсюда запускаю генератор шаблонов.
[root@localhost router]# cat site.yml

– name: Generate configuration files
vars_files: #файлы с переменными
– vars/hotspots
– vars/ap-1
hosts: localhost #где запускаю сценарий

roles: # какие включаю роли.
– router

tasks/main.yml – отсюда запускаю собственно генератор:
[root@localhost router]# cat tasks/main.yml

– name: Generate configuration files
template: src=hotspot.j2 dest=/home/tarasko/”{{ hostname }}”.src //Двойные кавычки нужны для экранирования специального символа {

templates/hotspot.j2 – здесь расположен сам шаблон:
cat templates/hotspot.j2
set [ find default-name=wlan1 ] adaptive-noise-immunity=ap-and-client-mode \
band=2ghz-b/g/n channel-width=20/40mhz-Ce country=”united states” \
default-forwarding=no disabled=no distance=indoors frequency={{ freq }} \
frequency-mode=superchannel hw-protection-mode=rts-cts hw-retries=15 mode=\
ap-bridge radio-name=”” scan-list=2400-2500 ssid={{ ssid_name }} tx-power={{ tx_power }} \
tx-power-mode=card-rates wireless-protocol=802.11
/interface bridge
add mtu=1500 name={{ wifi_bridge }} protocol-mode=none
/ip neighbor discovery
set ether1 discover=no
set ether2 discover=no
set ether3 discover=no
set ether4 discover=no
set ether5 discover=no
set wlan1 discover=no
set wifi discover=no
/interface vlan
add interface={{ uplink_interf }} name={{ wifi_vlan_name }} vlan-id={{ wifi_vlan_id }}
add interface={{ uplink_interf }} name={{mgmt_vlan_name}} vlan-id={{ mgmt_vlan_id }}
/ip neighbor discovery
set public_wifi discover=no
/interface wireless security-profiles
set [ find default=yes ] supplicant-identity=MikroTik
/ip ipsec proposal
set [ find default=yes ] enc-algorithms=3des
/snmp community
set [ find default=yes ] read-access=no
add addresses={{snmp_server_1}},{{snmp_server_2}} name={{ snmp_community }}
/system logging action
set 3 bsd-syslog=yes remote={{ syslog_server }} src-address=10.230.5.14 \
syslog-facility=local3
/interface bridge port
add bridge=wifi interface=public_wifi
add bridge=wifi interface=wlan1
/ip address
add address={{ip_address}}/{{mask}} interface={{ mgmt_vlan_name }} network={{ network }}
/ip route
add distance=1 gateway={{ gateway }}
/ip service
set telnet disabled=yes
set ftp disabled=yes
set www disabled=yes
set ssh address={{ mgmt_address }}
set api disabled=yes
set winbox address={{ mgmt_address }}
/snmp
set enabled=yes location={{hostname}}
/system clock
set time-zone-autodetect=no
/system clock manual
set time-zone={{ time_zone }}
/system identity
set name={{hostname}}
/system logging
add action=remote topics=wireless
/system ntp client
set enabled=yes primary-ntp={{ ntp1 }} secondary-ntp={{ ntp2 }}

В {{}} распологаются переменные.

Переменные определяю в
/etc/ansible/group_vars/hotspots //здесь переменные для группы
/etc/ansible/host_vars/ap-1 //здесь переменные для хоста
Переменные для группы будут перезаписаны одинаковыми переменными для хоста.

cat ap-1

hostname: NewStreet_Bar
ip_address: 10.10.5.110
mask: 24
uplink_interf: ether1

[root@localhost router]# cat /etc/ansible/group_vars/hotspots

ntp1: 10.10.8.200
ntp2: 10.10.8.201
mgmt_vlan_id: 149
wifi_vlan_id: 170
mgmt_vlan_name: public_wifi_mgmt
wifi_vlan_name: public_wifi
wifi_bridge: wifi
uplink_interf: ether1
ssid_name: Operator_FREE
default_route: 0.0.0.0/0
default_gateway: 10.10.5.1
tx_power: 27
freq: 2422
snmp_community: strongcommunity
snmp_server_1: 10.10.8.2
snmp_server_2: 10.10.8.3
syslog_server: 10.10.8.24
network: 10.10.5.0
mask: 24
gateway: 10.10.5.1
mgmt_address: 10.10.8.0/24
time_zone: +03:00

Запускаю site.yml
[root@localhost router]# ansible-playbook site.yml

PLAY [Generate configuration files] *******************************************

GATHERING FACTS ***************************************************************
ok: [localhost]

TASK: [router | Generate configuration files] *********************************
changed: [localhost]

PLAY RECAP ********************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0

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

Ansible, Mikrotik, Начало.

Давно хотел попробовать ansible – инструмент по автоматизации. Вообще сейчас он заточен больше под управление серверами, но плюсом является то, что на управляемой системе не нужен клиент, что естественно важно для сетевых устройств (маршрутизаторы, коммутаторы и т.д.)

И так получилось, что встала передо мной задача по настройке 16 микротиков в одной подсети управления, на которых должна быть однотипная конфигурация. В общем я решил что это хороший повод немножко уменьшить количество рутины:)
Устанавливаю ansible:
yum install ansible

Настраиваю хосты, которыми буду управлять:
ansible]# cat /etc/ansible/hosts
[local]
localhost    ansible_connection=local
[hotspots]
10.10.5.2    anisble_connection=paramiko    ansible_ssh_user=ansible
10.10.5.3    anisble_connection=paramiko     ansible_ssh_user=ansible
10.10.5.4    anisble_connection=paramiko     ansible_ssh_user=ansible
10.10.5.5    anisble_connection=paramiko     ansible_ssh_user=ansible
10.10.5.7    anisble_connection=paramiko     ansible_ssh_user=ansible
10.10.5.9    anisble_connection=paramiko     ansible_ssh_user=ansible
10.10.5.10    anisble_connection=paramiko     ansible_ssh_user=ansible
10.10.5.11    anisble_connection=paramiko     ansible_ssh_user=ansible
10.10.5.12    anisble_connection=paramiko     ansible_ssh_user=ansible
10.10.5.14    anisble_connection=paramiko     ansible_ssh_user=ansible
10.10.5.15    anisble_connection=paramiko     ansible_ssh_user=ansible
10.10.5.16     anisble_connection=paramiko     ansible_ssh_user=ansible
10.10.5.18    anisble_connection=paramiko     ansible_ssh_user=ansible
10.10.5.19    anisble_connection=paramiko     ansible_ssh_user=ansible
10.10.5.20    anisble_connection=paramiko     ansible_ssh_user=ansible

paramiko – либа для питона, микротики только с ней отрабатывают нормально по SSH. Дальше пришлось поработать руками – добавить на микротики ssh-ключ и создать пользователя ansible, а также обновить routeros, без этого ключ импортироваться не хотел. Как создать ключ можно посмотреть в инете.
Дальше необходимо написать playbook. Playbook – набор сценариев на языке YAML.
cat /etc/ansible/mikrotik.yml
– – –
– name: Test
hosts: hotspots #Имя группы хостов
serial: 1 #количество систем, котоые будут обрабатываться одновременно
connection: paramiko #тип соединения, по идее уже указан в hosts
user: ansible #пользователь, тоже указан в hosts
gather_facts: no # Перед работой с хостом ансибл собирает с него инфу с помощью питона, естественно на микротике это работать не будет, так что эту фичу выключаем
tasks: #Выполняем нашу задачу
– name: enable our community
raw: /snmp community add addresses=10.100.10.2,10.100.10.3 name=somestrongcommunity #включаю нужное комьюнити. raw – “чистая строка”
– name: disable public
raw: /snmp community set public read-access=no write-access=no #выключаю паблик на чтение и запись
– name: enable snmp
raw: /snmp set enabled=yes #Включаю snmp

Ну и запускаем наш сценарий:
$ ansible-playbook -v /etc/ansible/mikrotik.yml
-v – verbose mode

PLAY RECAP ********************************************************************
10.10.5.10                : ok=6    changed=0    unreachable=0    failed=0
10.10.5.11                : ok=6    changed=0    unreachable=0    failed=0
10.10.5.12                : ok=6    changed=0    unreachable=0    failed=0
10.10.5.14                : ok=6    changed=0    unreachable=0    failed=0
10.10.5.15                : ok=6    changed=0    unreachable=0    failed=0
10.10.5.18                : ok=6    changed=0    unreachable=0    failed=0
10.10.5.19                : ok=6    changed=0    unreachable=0    failed=0
10.10.5.2                 : ok=6    changed=0    unreachable=0    failed=0
10.10.5.20                : ok=6    changed=0    unreachable=0    failed=0
10.10.5.3                 : ok=6    changed=0    unreachable=0    failed=0
10.10.5.4                 : ok=6    changed=0    unreachable=0    failed=0
10.10.5.5                 : ok=6    changed=0    unreachable=0    failed=0
10.10.5.7                 : ok=6    changed=0    unreachable=0    failed=0
10.10.5.9                 : ok=6    changed=0    unreachable=0    failed=0

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

p.s.Так же считаю что нужно сделать контроль за изменениями – проверка параметров перед изменениями – изменение – проверка изменений – запись в change log на гитхаб например.

p.p.s. что там с телнетом я не знаю, может ли ансибл с ним работать то же хз. Во всяком случае работать с ключами удобнее, правда в IOS ключи поддерживаются с 15 версии.