Подружим между собой Netbox и Veritas Backup Exec 20. Symantec Backup Exec 15 тоже удалось подружить.
Netbox — документируем сеть
Задача
- В 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.