Как NetBox с Prometheus подружились
В предыдущем посте мы разобрались зачем нужен NetBox и что он умеет. Сегодня попробуем научить его общаться с мониторингом и навсегда забыть про редактирование targets.yml
Начнем с постановки задачи:
В шестнадцатеричном царстве, в двоичном государстве жил да был Ванька — админ. И была у Ваньки серверная, да сервера в ней. Ванька смышленый паренек был — за серверами следил не сам, а через систему чудную. Система та не одна работала, а в упряжке, словно лошадей тройка. И звали лошадей Promeheus, Grafana да Alertmanager. Механизм сей за состоянием серверов следил, а как заметит что неладное — сразу Ваньке голубя почтового шлёт — мол, погляди боярин, совсем сервера распоясались, CPU жрут как не в себя, накажи их али ресурсов прибавлять пора.
Alertmanager не пропускал ни одного серьезного непослушания, а про мелкие пакости Ваньке просто не говорил — нечего начальника по пустякам беспокоить. Поэтому у Ваньки время было на лугу полежать да книжки умные почитать.

Хозяйство росло, перестал Ванька один справляться. Взял помощников себе. Да давать им в руки вожжи от тройки вороной не хотел — молодые ещё, напортят чего. А сам уже не успевал за Prometheus’ом ухаживать — тут сервер добавить, тут у роутера внешний адрес сменился, а другой сервер подмастерье давно уже удалил, а Alertmanager всё челом бьёт, беспокоится.
Если использовать Ansible для разворачивания системы мониторинга, то получаем ещё один минус в ручном редактировании списка наблюдаемых машин: список составляется из jinja шаблона и адреса машин нужно редактировать в group_vars. Редактирование этих файлов руками нескольких людей да ещё и из разных отделов может привести к ошибкам. Поэтому хорошо было бы брать данные из внешней БД.
Да, я знаю про Consul, но не всем и не всегда он подходит. Поэтому в этом посте будем разбираться с pynetbox
Вспомнил Ванька, что он давно у соседа выторговал за бесценок коробку. Пора и её применить в деле. Добавить надо в NetBox железки свои да виртуалки. Много железок было, руками добавлять лень. Почесал Ванька репу, python подучил, да скрипты нацарапал, чтобы на одни и те же кнопки сотню раз не нажимать.
Часть этих скриптов можно увидеть на гитхабе. У программистов после увиденного возникнет стойкое желание сжигать заживо, а остальным можно поюзать или использовать в качестве примеров. Но лучше этого не делать — ниже будут более правильные примеры
Долго ли, коротко ли Ванька скрипты писал, да в один солнечный денек увидел модуль интересный — pynetbox называется. Да примеры для работы с ним. “Эко счастье привалило. Щас заживём” — подумал наш герой и пошел другие скрипты писать.

В NetBox у нас все сервера да роутеры да разные устройства описаны. Захотел Емелька новую виртуалку поставить — описал всё в нетбоксе — сколько ядер надобно, сколько памяти, какой vlan привязать, да на каком хосте создать. А NetBox взял да создал машину, пнул Ansible, чтоб тот настроил всё, да в мониторинг данные отдал. Не жизнь, а сказка.
Быстро сказка сказывается, да небыстро дело делается. Для proxmox отдельный модуль ученые мужи написали. С Proxmox мы потом разберемся, а сейчас надо нашу тройку чудную с коробкой подружить.
Prometheus про всех знает через file_sd. Скорее всего, можно прямо по API ему данные отдать, но Ванька наш ленивый — через file_sd и решил подружить помощников своих. Такая схема сложилась:
- Спросить у NetBox’a список устройств
- Создать из него yaml для Prometheus
- Положить новый yaml в нужное место
pynetbox сильно помог в этом. Попробуем разобраться в том, что написал наш сказочный герой.
#!/usr/bin/python3
#
from jinja2 import Template, Environment, FileSystemLoader
import os, sys, pynetbox
usage = """Usage: python3 netbox2wmi.py [netbox_ip] [API Token] [manufacturer] [output_file]
e.g. python3 netbox2blackbox.py 10.0.0.10:32769 Gdstwt53t6gdsTGSXHey Microsoft /etc/prometheus/file_sd/targets.yml"""
if len(sys.argv) != 5:
print(usage)
sys.exit(0)
netbox_url = 'http://' + sys.argv[1]
token = sys.argv[2]
# What device manufacturer export to targets.yml
manufacturer = sys.argv[3]
target_file = sys.argv[4]
# Fetch vm list from NetBox
try:
nb = pynetbox.api(url=netbox_url, token=token)
except pynetbox.core.query.RequestError as error:
print(error.error)
sys.exit(1)# Шаблон выходного файла
data = '''
#
# Managed by netbox2wmi.py. DON'T EDIT THIS FILE!!!
#
{% for vm in vms %}
- labels:
vm_name: "{{ vm.name }}"
env: prod
targets: {{ vm.address }}
{% endfor %}
'''
template = Template(data)
### Выборка машин по manufacturer #### Получаем список всех объектов Virtual_machine
vm_group = nb.virtualization.virtual_machines.all()# Инициализируем новый список с нужными нам объектами
vms = []
for vm in vm_group:
if str(vm.platform.manufacturer) == manufacturer: # Именованный список. name - имя машины, address - ip. У адреса срезаем маску - три последних символа
target = {}
target['name'] = vm.name
target['address'] = str(vm.primary_ip)[:-3]# Записываем в новый список с нужными нам объектами
vms.append(target)### Выборка машин по manufacturer #### Создание конфига
config = template.render(vms=vms)# Запись конфига в файл
with open(target_file, 'w') as file:
file.write(config)
Скрипт создает файл со списком windows машин. Запускается из командной строки с аргументами [netbox_ip] [API Token] [manufacturer] [output_file], где manufacturer — в нашем случае Microsoft (будет работать, если ВМ будет с ОС, которая привязана к нашему manufacturer. Возможно, это немного неудобный пример, но проще других. Посмотрите на netbox2mikrotik для другого примера — там в файл пишется название филиала, в котором стоит роутер).
sys.argv считывает аргументы, переданные скрипту. Название скрипта так же является аргументом, поэтому их должно быть пять.
Это шаблон файла, который будет создан:
{% for vm in vms %}
- labels:
vm_name: "{{ vm.name }}"
env: prod
targets: {{ vm.address }}
for vm in vms тут говорит о том, что этот шаблон будет повторятся пока не закончатся объекты в списке vms.
vm.name и vm.address будут подставлены в шаблоны из параметров ВМ, если её manufacturer совпадает с тем, что мы задали в аргументах.
config = template.render(vms=vms)
создает конфиг из наших данных, который затем пишется в файл.
Будем запускать этот скрипт с периодичностью один раз в час. Таким образом, информация в Prometheus будет всегда актуальна с точностью в один час. Если, она актуальна в NetBox’e, конечно. А подерживать в актуальном состоянии NetBox — дело организационное. Нужно объяснить коллегам какие проблемы позволит решить этот инструмент: держать в актуальном состоянии информацию об инфраструктуре, автоматизировать рутину, уменьшить время восстановления после сбоев. Люди начнут пользоваться инструментом, когда поймут, что это облегчит им жизнь,
В следующих частях создадим systemd юнит для скрипта и зальем его на сервер Ansible’ом. В репозитории есть ещё интересные скрипты — посмотрите, вдруг вам что-то подойдет.
Как вам такая подача информации? Продолжать экспериментировать или писать в старом духе?
Многие жалуются, что Medium не дает читать посты без регистрации. Сегодня я столкнулся с тем, что платформа не разрешает мне бесплатно читать посты и просит $5/month.
Telegraph неудобен читателям из России и у него скудная аналитика.
Так на какой платформе лучше писать? Пожалуйста, напишите в комментах здесь или в Telegram