Перейти к основному содержанию

Netbox и Backup Exec

NetBox

Подружим между собой 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 поможет автоматизировать процесс.

Решение

Алгоритм работы скрипта:

  1. Пробегаем циклом по всем виртуальным машинам, которые обработали в прошлый раз. Пишем в Netbox в кастомное поле "<сервер бэкапа> <дата> — отменено". Тем самым мы подстраховываемся на тот случай, если виртуальная машина перестала бэкапиться, а запись о расписании в Netbox есть. Чистим за собой. Список обработанных виртуалок храним в файле.
  2. Получаем список расписаний резервного копирования для виртуальных машин из Backup Exec и вносим данные в Netbox.
  • #---------------------------------------------------------------------------
    # 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, здесь будет храниться список виртуальных машин.

netbox

Работу скрипта можно протестировать вручную в PowerShell. Убедитесь, что модуль BEMCLI у вас присутствует.

netbox

После отработки скрипта у виртуальной машины в кастомном поле появился запись:

netbox

Если резервное копирование отменится, то запись станет такой:

netbox

В web-интерфейсе это выглядит так:

netbox

Расписание

Настроим расписание для ежедневного запуска скрипта. Воспользуемся Планировщиком Заданий — Task Scheduler.

netbox

Создаём новое задание.

netbox

Укажем любое имя. Запускаем с максимальными привилегиями и без логина.

netbox

Переходим к триггерам, создаём новый.

netbox

Выбираем желаемое расписание. Я запускаю ежедневно в 6:30 утра. OK.

netbox

Расписание создано.

netbox

Переходим к действиям, создаём новое. Для запуска PowerShell скрипта выполним программу:

powershell.exe -file "C:\scripts\netbox_vm_backup_schedule.ps1"

netbox

Настраиваем условия. Например, разбудим компьютер для выполнения скрипта.

netbox

Указываем настройки. Например, "Do not start a new instance".

netbox

OK.

netbox

Укажем имя пользователя для запуска скрипта. Естественно, он должен иметь права для доступа к Backup Exec. OK.

netbox

Расписание создано.

Заключение

Мы создали скрипт, который вытаскивает расписание резервного копирования виртуальной машины и записывает его в кастомное поле той же виртуальной машины в 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.

 

Похожие материалы

Veritas Backup Exec 20 — траблшутинг резервирования Linux

Заметки о том, как я пытался забэкапить папку Linux на Ubuntu Server с помощью Veritas Backup Exec 20. Несколько раз наступил на грабли, получил полезный опыт, в итоге резервное копирование было-таки настроено.