Подружим между собой Netbox и Veritas Backup Exec 20. Symantec Backup Exec 15 тоже удалось подружить.
Задача
- В Netbox внесены виртуальные машины.
- В Veritas Backup Exec 20 настроено резервное копирование виртуальных машин.
Задача простая, в Netbox в кастомное поле "Backup" у виртуальной машины нужно внести расписание, по которому производится резервное копирование.
Нам понадобится:
- Powershell скрипт, который будет всё за нас делать.
- BEMCLI модуль PS, который устанавливается вместе с Backup Exec.
- API Netbox, из коробки. Сгенерируем токен в админке.
- Task Scheduler поможет автоматизировать процесс.
Решение
Алгоритм работы скрипта:
- Пробегаем циклом по всем виртуальным машинам, которые обработали в прошлый раз. Пишем в Netbox в кастомное поле "<сервер бэкапа> <дата> — отменено". Тем самым мы подстраховываемся на тот случай, если виртуальная машина перестала бэкапиться, а запись о расписании в Netbox есть. Чистим за собой. Список обработанных виртуалок храним в файле.
- Получаем список расписаний резервного копирования для виртуальных машин из Backup Exec и вносим данные в Netbox.
-
PowerShell скрипт netbox_vm_backup_schedule.ps1
#--------------------------------------------------------------------------- # Author: Oleg Pchelikov, info@internet-lab.ru # Date: 2020-11-10 # Version: 1.02 # # Скрипт с помощью модуля BEMCLI получает список виртуальных машин VCenter, # которые находятся в Backup Exec в списке джобов. Информация о расписаниях # пишется в netbox в кастомное поле. Предыдущие данные виртуалок помечаются # как отменённые, это позволяет чистить данные после удаления виртуалки из # джоба. # # P.S. # Модуль BEMCLI устанавливается на сервер вместе с Backup Exec. # # АЛГОРИТМ # 1. Если нет файла со списком идентификаторов VM, то создаём его. # 2. Получаем список идентификаторов VM из файла. Всем VM прописываем # в netbox "СЕРВЕР ДАТА - отменено". # 3. Стираем содержимое файла со списком идентификаторов VM. # 4. Из BE формируем список VM и расписаний. Всем VM прописываем # в netbox "СЕРВЕР ДАТА - РАСПИСАНИЕ". Идентификаторы VM пишем в файл. #--------------------------------------------------------------------------- import-module BEMCLI #переменные $workdir = "C:\scripts\" $filevmlistname = "vmlist.txt" $netbox = "https://netbox.example.local" $token = "b67b67b67b67b67b67b67b67b67b67b67b67b67b" $vcenter = "vcenter.example.local" $custom_field = "Backup" $curdate = Get-Date -Format "dd.MM.yyyy HH:mm" $servername = $env:COMPUTERNAME $filevmlist = $workdir + $filevmlistname [Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls" #создаём файл если его нет $filevmlistexist = Test-Path -Path $filevmlist if (-Not $filevmlistexist) { New-Item -Name $filevmlistname -Path $workdir } # кодировка из ISO-8859-1 в UTF-8 function convertFromISOToUtf8([string] $String) { [System.Text.Encoding]::UTF8.GetString([System.Text.Encoding]::GetEncoding(28591).GetBytes($String)) } #стираем предыдущие данные виртуалок из файла foreach($line in [System.IO.File]::ReadLines($filevmlist)) { if ($line -and $line -match '^[0-9]+$'){ #проверяем существование виртуалки по ID $wget1 = Invoke-WebRequest -UseBasicParsing ` -Uri "${netbox}/api/virtualization/virtual-machines/?id=${line}"` -Headers @{ "Accept"="application/json; indent=4"""; "Authorization"="Token ${token}"; "cache-control"="no-cache"; }` -ContentType "application/json; charset=utf-8"` -Method "Get" $JSON1 = convertFromISOToUtf8($wget1.Content) | ConvertFrom-Json #если виртуалка существует, чистим поле if ($JSON1.count -eq 1){ $datajson1 = @{"custom_fields" = @{"$custom_field" = "$servername ${curdate} — отменено"}} | ConvertTo-Json $wget_1 = Invoke-RestMethod -UseBasicParsing ` -Uri "${netbox}/api/virtualization/virtual-machines/${line}/"` -Headers @{ "Accept"="application/json; indent=4"""; "Authorization"="Token ${token}"; "cache-control"="no-cache"; }` -ContentType "application/json; charset=utf-8"` -Method "Patch"` -Body ${datajson1} } } } #стираем содержимое файла Clear-Content $filevmlist #получаем список расписаний и виртуалок из BE $AgentServer = Get-BEAgentServer -Name $vcenter $vmlist = Get-BEJob -AgentServer $AgentServer | Select-Object SelectionSummary,Schedule $vmlist | ForEach-Object { $Schedule = $PSitem.Schedule #расписание $PSitem.SelectionSummary | ForEach-Object {$PSItem.split(",",[System.StringSplitOptions]::RemoveEmptyEntries)} | ForEach-Object { $vm = $PSitem.ToString().Trim() #имя виртуалки $wget2 = Invoke-WebRequest -UseBasicParsing ` -Uri "$netbox/api/virtualization/virtual-machines/?name=$vm"` -Headers @{ "Accept"="application/json; indent=4"""; "Authorization"="Token ${token}"; "cache-control"="no-cache"; }` -ContentType "application/json; charset=utf-8"` -Method "Get" $JSON2 = convertFromISOToUtf8($wget2.Content) | ConvertFrom-Json #если виртуалка существует if ($JSON2.count -eq 1){ #id виртуалки $vmid = $JSON2.results.id #запоминаем в файл Add-Content $filevmlist $vmid #заполняем поле $datajson2 = @{"custom_fields" = @{"$custom_field" = "$servername ${curdate} — $Schedule"}} | ConvertTo-Json $wget_2 = Invoke-RestMethod -UseBasicParsing ` -Uri "${netbox}/api/virtualization/virtual-machines/${vmid}/"` -Headers @{ "Accept"="application/json; indent=4"""; "Authorization"="Token ${token}"; "cache-control"="no-cache"; }` -ContentType "application/json; charset=utf-8"` -Method "Patch"` -Body ${datajson2}` } } }
Скачать: scripts.zip
Здесь:
- $workdir = "C:\scripts\"
Путь к рабочей директории. - $filevmlistname = "vmlist.txt"
Имя файла для хранения имён виртуальных машин. - $netbox = "https://netbox.example.local"
URL к Netbox. - $token = "b67b67b67b67b67b67b67b67b67b67b67b67b67b"
Токен, генерируется в админке Netbox. - $vcenter = "vcenter.example.local"
Имя vCenter в Backup Exec. - $custom_field = "Backup"
Имя кастомного поля в Netbox.
Сохраняем скрипт в папку C:\scripts на сервере Backup Exec. Рядом создаём пустой файл vmlist.txt, здесь будет храниться список виртуальных машин.
Работу скрипта можно протестировать вручную в PowerShell. Убедитесь, что модуль BEMCLI у вас присутствует.
После отработки скрипта у виртуальной машины в кастомном поле появился запись:
Если резервное копирование отменится, то запись станет такой:
В web-интерфейсе это выглядит так:
Расписание
Настроим расписание для ежедневного запуска скрипта. Воспользуемся Планировщиком Заданий — Task Scheduler.
Создаём новое задание.
Укажем любое имя. Запускаем с максимальными привилегиями и без логина.
Переходим к триггерам, создаём новый.
Выбираем желаемое расписание. Я запускаю ежедневно в 6:30 утра. OK.
Расписание создано.
Переходим к действиям, создаём новое. Для запуска PowerShell скрипта выполним программу:
powershell.exe -file "C:\scripts\netbox_vm_backup_schedule.ps1"
Настраиваем условия. Например, разбудим компьютер для выполнения скрипта.
Указываем настройки. Например, "Do not start a new instance".
OK.
Укажем имя пользователя для запуска скрипта. Естественно, он должен иметь права для доступа к Backup Exec. OK.
Расписание создано.
Заключение
Мы создали скрипт, который вытаскивает расписание резервного копирования виртуальной машины и записывает его в кастомное поле той же виртуальной машины в Netbox.
Минусы решения
- Хотелось бы, конечно, внести дату последней резервной копии, но мне не удалось докопаться до списка резервных копий, поэтому я пока ограничился расписанием.
- Если виртуальная машина бэкапится по нескольким расписаниям, то в Netbox записывается только одно.
- Для Symantec Backup Exec 15 пришлось кое-где убрать "-UseBasicParsing" из кода, вероятно, это зависит от версии Powershell и операционной системы Windows Server.
Плюсы решения
- Шарманка работает, автоматизация!
- Если машина перестала бэкапиться, то расписание в Netbox заменяется текстом "<сервер бэкапа> <дата> — отменено".
- Для работы не пришлось устанавливать дополнительное ПО.
Дополнительно
v 1.02 (2020-11-10)
Первый стабильный релиз
v 1.03
Добавлена строка:
[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
Для устранения ошибки:
The request was aborted: Could not create SSL/TLS secure channel.