Используем powershell скрипты в icinga2

в 7:18, , рубрики: icinga2, powershell, системное администрирование

Продолжаем поднимать микромониторинг. Будем исходить из того что, у нас есть парк, в основном состоящий из windows машин, и они находятся в локальных сетях, никак не связанных между собой, но с доступом в интернет. Воспользуемся родным для windows — powershell и научим наши Icinga2 windows агенты отправлять нужные нам сведения без прямого доступа к ним.

В последних версиях Icinga2 агента для windows изменилось расположение конфигурационных файлов, теперь они находятся в каталоге: C:ProgramDataicinga2etcicinga2. На клиенте в файле zones.conf добавим глобальную зону (в новых версиях агента такая зона уже прописана, но закомментирована):

object Zone "global-templates" {
        global = true
}

На сервере создадим директорию /etc/icinga2/zones.d/global-templates, а в ней файл commands.conf со следующим содержимым где определим команду для выполнения powershell скриптов:

object CheckCommand "powershell" {
    import "plugin-check-command"
    timeout = 5m
    command = [ "powershell.exe" ]
    arguments = {
                	"-command" = { skip_key = true
                		value = "$ps_command$"
                    	order = 0
					}
    				"-args" = { skip_key = true
                		value = "$ps_args$"
                    	order = 1
                	}
	}
}

Дополнительные необязательные команды

//Запуск 64 разрядной версии powershell
object CheckCommand "powershell64" {
    import "plugin-check-command"
    timeout = 3m
    command = [ "C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe" ]
    arguments = {
                	"-command" = {
                		value = "$ps_command$"
                    	order = 0
					}
    				"-args" = { skip_key = true
                		value = "$ps_args$"
                    	order = 1
                	}
	}
}

//Запуск powershell без проверки подписи.
object CheckCommand "powershell-bypass" {
    import "plugin-check-command"
    timeout = 3m

    command = [ "powershell.exe" ]
    arguments = {
                "-ExecutionPolicy" = {
                                value = "ByPass"
                        order = 0
                                        }
                        "-File" = {
                                value = "$ps_command$"
                        order = 1
                                        }
                                "-args" = { skip_key = true
                                value = "$ps_args$"
                        order = 2
                        }
     }

}

На сервере в этом же каталоге создадим файл services.conf в котором будут описываться сервисы наших агентов. Для начала добавим сервис обновления скриптов с сервера.

apply Service "upd-powershell-scripts" {
    max_check_attempts = 2
//Сервис будет выполнятся каждые 60 минут
    check_interval = 60m
    retry_interval = 30m
//Сервис будет применяться только на агенте с Windows
    assign where host.vars.os == "Windows" && host.name == NodeName
//Сервис будет игнорироваться на Linux
    ignore where host.vars.os == "Linux"

    check_command = "powershell"
    vars.ps_command = "C:\Scripts\Icinga2\update_icinga2_scripts.ps1"
}

При установке Windows агента в файле etc/conf.d/hosts.conf по умолчанию прописывается переменная vars.os = «Windows» на основе этого и будет применяться данный сервис и игнорироваться на Linux агентах.

Теперь на клиенте в директории c:ScriptsIcinga2 нужно разместить powershell скрипт который будет выполнять обновление скриптов.

Скрипт загрузки powershell скриптов с удаленного сервера

<#
icinga2scripts
Version 0.2
Description: Update powershell from remote host.
Pavel Satin (c) 2016
pslater.ru@gmail.com
#>

$returnStateOK = 0
$returnStateWarning = 1
$returnStateCritical = 2
$returnStateUnknown = 3

$localDir = "c:Scriptsicinga2"

$ScriptHost = "http://наш-веб-сервер"
$ScriptHostPath = $ScriptHost + "/icinga2scripts/"

Try
{
$HttpContent = Invoke-WebRequest -URI $ScriptHostPath -UseBasicParsing

$ArrLinks = $HttpContent.Links | Foreach {$_.href }

Foreach ($ArrStr in  $ArrLinks)
{
if ( $ArrStr.endsWith(".ps1") )
	{
		##Для Apache2
		$NewScriptHostPath = $ScriptHostPath + $ArrStr
		##Для IIS, он отдает ссылки с вместе с виртуальными каталогами
		#$NewScriptHostPath = $ScriptHost + $ArrStr

		$localFile = $localDir + $ArrStr
		Invoke-WebRequest -URI $NewScriptHostPath -UseBasicParsing -OutFile $localFile
		
		$script_count = $script_count + 1

	}
}

	$icinga2_status = "Update OK: Downloads " + $script_count + " scripts."
	
	Write-Host $icinga2_status
	[System.Environment]::Exit($returnStateOK)

}
Catch
{
    $ErrorMessage = $_.Exception.Message
    $FailedItem = $_.Exception.ItemName
	
	Write-Host $ErrorMessage
	[System.Environment]::Exit($returnStateCritical)

}

Через небольшой промежуток времени агенты скачают новую версию глобальной зоны.
Запускаем на сервере обновление конфигурации нод и перегружаем сервис:

icinga2 node update-config
service icinga2 reload

Наш сервис добавлен на агенте и работает.

Используем powershell скрипты в icinga2 - 1

Для примера добавим функционал перезагрузки. Добавим в файл services.conf еще один сервис, который будет выполнять перезагрузку ОС по нашему требованию. Обязательно отключим активную проверку такого сервиса (мы ведь не хотим что бы контролируемый нами сервер перезагружался каждый n минут).

apply Service "reboot-system" {
//Отключаем активную проверку
    enable_active_checks = false
    max_check_attempts = 2

//Сервис будет применяться только на агенте с Windows
    assign where host.vars.os == "Windows" && host.name == NodeName
//Сервис будет игнорироваться на Linux
    ignore where host.vars.os == "Linux"

    check_command = "powershell"
    vars.ps_command = "C:\Scripts\Icinga2\Reboot_System.ps1"
}

Снова на сервере запускаем обновление конфигурации нод и перегружаем сервис, что бы изменения конфигурации вступили в силу:

icinga2 node update-config
service icinga2 reload

Скрипт перезагрузки
<#
icinga2scripts
Version 0.2
Description: Reboot system.
Pavel Satin (c) 2016
pslater.ru@gmail.com
#>

$returnStateOK = 0
$returnStateWarning = 1
$returnStateCritical = 2
$returnStateUnknown = 3

#Проверка аргументов
if ( $args[0] -ne $Null) {
    $ComputerName = $args[0]
} else {
    $ComputerName = "localhost"
}

$result = Test-Connection -ComputerName $ComputerName -Count 2 -Quiet

if ($result)
{

Restart-Computer -computername $ComputerName -force
Write-Host "OK - Command send."
[System.Environment]::Exit($returnStateOK)

} #End if test-connection result
else {
    	Write-Host "Хост $ComputerName не доступен."
	[System.Environment]::Exit($returnStateUnknown)
}

Этот скрипт мы разместим на нашем веб-сервере (который прописан в скрипте загрузки) и агент сам его скачает через определенный промежуток времени. Проверить работоспособность сервиса можно следующей командой на сервере:

/bin/echo "[`date +%s`] SCHEDULE_FORCED_SVC_CHECK;ИмяНоды;reboot-system;`date +%s`" >> /var/run/icinga2/cmd/icinga2.cmd

После чего машина с windows агентом должна перезагрузиться.

Что бы powershell скрипты отрабатывали на агенте, их нужно либо подписывать (Как подписать) либо правильно настроить политику исполнения (Set-ExecutionPolicy). Для того что бы Icinga2 правильно определил состояние сервиса после проверки (норма/предупреждение/критично), скрипт обязательно должен вернуть правильный код возврата.

Основные коды возврата в скриптах мы определили так:

$returnStateOK = 0
$returnStateWarning = 1
$returnStateCritical = 2
$returnStateUnknown = 3

Например при критичном состоянии сервиса мы возвращаем:

    	Write-Host "Хост $ComputerName не доступен."
	[System.Environment]::Exit($returnStateCritical)

Дополнительные данные о производительности из скрипта можно вернуть примерно так:

Write-Host "OK - Данные принтера:"
  "<table><thead><tr><th>_</th><th>Value</th></tr></thead><tbody>"
  "<tr><td>Оставшийся процент тонера:</td><td>" + $catridge_usage_prc + " %</td></tr>"
  "<tr><td>Отпечатано страниц:</td><td>" + $page_count + "</td></tr></tbody></table>"
  "|catridge_usage_prc=$catridge_usage_prc;10;3;100;0"
  "|page_count=$page_count;;;;"
[System.Environment]::Exit($returnStateOK)   

Здесь после пайпа мы отправляем данные производительности в следующем формате:

'label'=value[UOM];[warn];[crit];[min];[max]

В icingaweb2 это будет выглядеть примерно так:

Используем powershell скрипты в icinga2 - 2

Если у вас скрипты с выводом сообщений на кириллице, файлы обязательно должны быть сохранены в кодировке UTF-8 with BOM, иначе могут возникнуть проблемы с отображением этих сообщений в нашем веб интерфейсе или в icingaweb2.

Плагинов для icinga/nagios уже написано огромное количество, но в большинстве случаев они рассчитаны на работу в linux системах. Для windows конечно же есть готовые решения дополняющие стандартные команды icinga2, например: nsclient++, но это дополнительные сущности, дополнительные конфигурации. В нашем же решении все сделано стандартными средствами windows и при этом есть возможность получать дополнительную информацию «на лету», просто добавив дополнительный сервис в конфигурацию Icinga2 и дополнительный powershell скрипт на веб-сервер.

Ссылки

Поднимаем микромониторинг на icinga2 с минимальными затратами
Репозиторий со скриптами
Гайдлайны плагинов мониторинга

Автор: plsatin

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js