...

вторник, 3 июня 2014 г.

[Из песочницы] Отправка уведомлений Zabbix в скайп (звонки со скайпа — бонусом)

image

Случилось так что в компании, из-за перебоев электропитания, несколько раз падали сервера, а администраторы узнавали об этом только утром когда сотрудники не смогли приступить к работе.


Основной проблемой стало то, что все уведомления администраторам отправлялись по почте — которая, как можно с легкостью догадатся, тоже лягла.


Тогда у меня и зародилась идея — «А давайте админам звонить в критических ситуациях!»


За реализацией и скриптами — прошу под кат.



За исходную точку приймем уже установленный и настроенный Zabbix которому не хватает лишь системы уведомлений.


В нашей инфраструктуре zabbix развернут на Debian 7 x64 — что привнесло некоторые излишества в процесс уведомления, так как Skype не удалось запустить на данной системе. Тем у кого 32-bit система — головная боль не светит.


Итак, приступим.


Первым делом нам необходимо установить Skype и его зависимости:

Система планируется очень ресурсоэкономичной, потому графической оболочки иметь не будет, как таковой.


1. Устанавливаем базовые компоненты.



# Добавляем юзера Skype из-под которого будет запускаться наш сервис
useradd skype
passwd skype
# Устанавливаем x server
apt-get install xvfb
apt-get install fluxbox x11vnc
# Удовлетворяем требования для skype
apt-get install dbus
apt-get install libasound2 libqt4-dbus libqt4-network libqtcore4 libqtgui4 libxss1 libpython2.6 libqt4-xml libaudio2 libmng1 fontconfig liblcms1
apt-get install lib32stdc++6 lib32asound2 ia32-libs libc6-i386 lib32gcc1
# Качаем инсталяшку скайпа с сайта
wget http://ift.tt/1kzJD8I -O skype.deb
# Устанавливаем скайп
dpkg -i skype.deb


Если остались какие-либо зависимости — apt-get install нам в помощь.


* Стоит заметить что скайп есть только 32-битный. И на Debian 7 x64 его запустить не удалось. Моим решением стала установка еще одной виртуальной машины с Debian 7 32-bit и запуска скайпа на ней


Вторым шагом нам необходимо установить Skype4py — набор Python скриптов\утилит с помощью которых мы можем подключаться к инстансу скайпа.



# Скачиваем Skype4Py
wget 'http://ift.tt/1kzJD8J'
# Распаковуем архив
tar -xzf Skype4Py-1.0.31.0.tar.gz
# Устанавливаем Skype4py
cd Skype4Py-1.0.31.0/
python setup.py install


Итак, на данный момент у нас есть все необходимое для работы.


Третим шагом мы упростим свою дальнейшую работу.

Для этого создадим несколько скриптов для более быстрого запуска сервиса.

1. start-server.sh — данный скрипт будет запускать\останавливать\перезапускать Xvfb, fluxbox и сам Skype:



#!/bin/bash

if [[ "$USER" != 'skype' ]]; then
echo "Please start this script as skype!"
exit 1
fi

export DISPLAY=:1

dnb=`dirname "$0"`


start() {
if [[ `ps aux | grep skype | grep "Xvfb :1" | grep -v grep | wc -l` == '0' ]]; then
echo "starting Xvfb"
Xvfb :1 -screen 0 800x600x16 &
else
echo "Xvfb already running"
fi
if [[ `ps aux | grep skype | grep "fluxbox" | grep -v grep | wc -l` == '0' ]]; then
echo "starting fluxbox"
sleep 1
fluxbox &
else
echo "fluxbox already running"
fi
if [[ `ps -eo pid,user,args | grep skype | awk '{ print $1 " " $3; }' | grep skype | wc -l` == '0' ]]; then
echo "starting skype"
sleep 2
skype &
else
echo "skype already running"
fi
}

stop() {
if [[ `ps -eo pid,user,args | grep skype | awk '{ print $1 " " $3; }' | grep skype | wc -l` == '0' ]]; then
echo "skype is NOT running"
else
echo "killing skype"
killall skype
fi

"$dnb/start-vnc.sh" stop

if [[ `ps aux | grep skype | grep "fluxbox" | grep -v grep | wc -l` == '0' ]]; then
echo "fluxbox is NOT running"
else
echo "Killing fluxbox"
killall fluxbox
fi
if [[ `ps aux | grep skype | grep "Xvfb :1" | grep -v grep | wc -l` == '0' ]]; then
echo "Xvfb is NOT running"
else
echo "Killing Xvfb"
killall Xvfb
fi
}

status() {
i='3'
if [[ `ps aux | grep skype | grep "Xvfb :1" | grep -v grep | wc -l` == '0' ]]; then
echo "Xvfb is NOT running"
else
echo "Xvfb is running"
((i--))
fi
if [[ `ps aux | grep skype | grep "fluxbox" | grep -v grep | wc -l` == '0' ]]; then
echo "fluxbox is NOT running"
else
echo "fluxbox is running"
((i--))
fi
if [[ `ps -eo pid,user,args | grep skype | awk '{ print $1 " " $3; }' | grep skype | wc -l` == '0' ]]; then
echo "skype is NOT running"
else
echo "skype is running"
((i--))
fi
if [[ "$i" == '0' ]]; then
echo "OVERALL STATUS: OK"
exit 0
fi
if [[ "$i" == '1' || "$i" == '2' ]]; then
echo "OVERALL STATUS: NOT RUNNING PROPERLY"

else
echo "OVERALL STATUS: NOT RUNNING"
fi
exit "$i"
}


case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
status)
status
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
esac



2. start-vnc.sh — скрипт для запуска VNC сервера — так как нам необходим графический интерфейс для ввода аккаунта скайпа и подтверждения разрешения на работу с внешним API:



#!/bin/bash

if [[ "$USER" != 'skype' ]]; then
echo "Please start this script as skype!"
exit 1
fi

export DISPLAY=:1

dnb=`dirname "$0"`


start() {
"$dnb/start-server.sh" status
if [[ "$?" == '0' ]]; then
echo "Starting x11vnc"
if [[ `ps aux | grep skype | grep "x11vnc -display :1" | grep -v grep | wc -l` == '0' ]]; then
x11vnc -display :1 -bg -nopw -listen localhost -xkb
else
echo "x11vnc is already running!"
fi
#pid=`ps aux | grep skype | grep "x11vnc -display :1" | grep -v grep | awk '{ print $2; }'`
echo " now use on your machine: ssh -L 5900:127.0.0.1:5900 'skype@`hostname`'"
echo " and connect to your local port with vncviewer!"
else
echo "The server doesn't run."
echo 'Use "'"$dnb"'/start-server.sh" to start the server'
fi

}


status() {
if [[ `ps aux | grep skype | grep "x11vnc -display :1" | grep -v grep | wc -l` == '0' ]]; then
echo "x11vnc isn't running"
exit 1
else
echo "x11vnc is running"
exit 0
fi
}

stop() {
if [[ `ps aux | grep skype | grep "x11vnc -display :1" | grep -v grep | wc -l` == '0' ]]; then
echo "x11vnc isn't running"
else
echo "killing x11vnc"
killall x11vnc
fi
}




case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
status)
status
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
esac


Шаг четвертый — запускаем и настраиваем скайп.

Запускаем оба наших скрипта под юзером skype:

./start-server.sh start

./start-vnc.sh start


Пробрасуем порт VNC сервера (можно и на локальный IP сервера мапить \в скрипте ./start-vnc.sh\ — но для большей универсальности используем такой метод):

ssh -L 5900:127.0.0.1:5900 ‘skype@your.zabbix.server’


Подключаемся любимым VNC вьювером к 127.0.0.1 порт 5900 и видим запущеный скайп

Вводим логин и пароль для аккаунта который будет отправлять нам уведомления И НЕ ЗАБЫВАЕМ ПОСТАВИТЬ ГАЛОЧКУ НА СОХРАНЕНИЕ ПАРОЛЯ


Включаем в скайпе:


no chat history

just people on my list can write me

just people on my list can call me


Прежде чем закрывать окно графического интерфейса нам необходимо разрешить подключения Skype4py к самому скайпу.

Для этого с консоли выполняем (текст скрипта — ниже по тексту):



./sendim.sh ‘USERNAME’ ‘HELLO WORLD’




где USERNAME — имя аккауна КУДА отправлять сообщение

HELLO WORLD — само сообщение

Возвращаемся к окну с VNC и видим что скайп просит нас разрешения — жмем «разрешить и запомнить».


Останавливаем VNC сервер:



./start-vnc.sh stop


И проверяем работу скайпа, отправив еще раз:



./sendim.sh ‘USERNAME’ ‘HELLO WORLD’


Теперь сообщение должно прийти нашему USERNAME.


Шаг последний — настройка zabbix.

1. Ищем в zabbix_server.conf путь для AlertScriptsPath

2. Создаем скрипты для отправки уведомлений


Создаем два скрипта:

sendim.sh — в домашнем каталоге юзера skype и делаем линк в папку AlertScriptsPath



#!/bin/bash

export DISPLAY=:1

python ~skype/sendim.py "$1" "$2"


В данном скрипте первый параметр — имя пользователя (кому отправлять), второй — сообщение.


sendim.py — в домашнем каталоге юзера Skype:



import Skype4Py
import sys
# Create an instance of the Skype class.
skype = Skype4Py.Skype()
# Connect the Skype object to the Skype client.
skype.Attach()
user = sys.argv[1]
msg = ' '.join(sys.argv[2:])
message = skype.SendMessage(user, msg)


Проверяем еще раз:



./sendim.sh username message


Конфигурируем уведомления в Zabbix.

1. Настраиваем Media type

идем в Administration -> Media Types и создаем новый медиа тип:

Name: Skype Type: Script Script name: sendim.sh Enabled: true


2. Определяем пользователей работающих с данными уведомлениями:

идем в Administration -> Users и в свойствах юзверя (-ей) разрешаем наш новый медиа тип и конфигурим юзернеймы для скайпа

Type: Skype Send to: YOUR_SKYPE_NAME

YOUR_SKYPE_NAME — скайп логин кому будем отправлять.

И так для каждого юзера кому хотим отправлять уведомления.


Конфигурируем Actions для отправки уведомлений:


Все что мы хотим отправлять в скайп — должно находится в строке subject (само тело сообщения — не отправляется).


Создаем необходимые Conditions и настраиваем Operations:



Можно тестировать.


* Как я указывал в начале — у нас скайп стоит на отдельном от zabbix сервере и команды выполняются удаленно с помощью



sudo sshpass -p 'skype' ssh skype@IP_ADDRESS "./sendim.sh '$1' '$2'"




где IP_ADDRESS — айпишник сервера со скайпом

Также реализована функция — «звонилка». Скайп звонит Админам по указанным номерам.

Тексты скриптов — ниже. В случае необходимости расскажу как настроить — но это тема отдельного поста )


skype_caller.py — подключаемся и звоним со скайпа:



#!python
# ---------------------------------------------------------------------------------------------
# Python / Skype4Py example that takes a skypename or number from the commandline
# and calls it.
#

import sys
import Skype4Py

# This variable will get its actual value in OnCall handler
CallStatus = 0

# Here we define a set of call statuses that indicate a call has been either aborted or finished
CallIsFinished = set ([Skype4Py.clsFailed, Skype4Py.clsFinished, Skype4Py.clsMissed, Skype4Py.clsRefused, Skype4Py.clsBusy, Skype4Py.clsCancelled]);

def AttachmentStatusText(status):
return skype.Convert.AttachmentStatusToText(status)

def CallStatusText(status):
return skype.Convert.CallStatusToText(status)

# This handler is fired when status of Call object has changed
def OnCall(call, status):
global CallStatus
CallStatus = status
print 'Call status: ' + CallStatusText(status)

# This handler is fired when Skype attatchment status changes
def OnAttach(status):
print 'API attachment status: ' + AttachmentStatusText(status)
if status == Skype4Py.apiAttachAvailable:
skype.Attach()

# Let's see if we were started with a command line parameter..
try:
CmdLine = sys.argv[1]
file = sys.argv[2]
except:
print 'Missing command line parameter'
sys.exit()

# Creating Skype object and assigning event handlers..
skype = Skype4Py.Skype()
skype.OnAttachmentStatus = OnAttach
skype.OnCallStatus = OnCall

# Starting Skype if it's not running already..
if not skype.Client.IsRunning:
print 'Starting Skype..'
skype.Client.Start()

# Attatching to Skype..
print 'Connecting to Skype..'
skype.Attach()

# Make the call
print 'Calling ' + CmdLine + '..'
global cl
cl = skype.PlaceCall(CmdLine)
cl.InputDevice( Skype4Py.callIoDeviceTypeFile ,file )


# Loop until CallStatus gets one of "call terminated" values in OnCall handler
while not CallStatus in CallIsFinished:
pass


skype_caller.sh — вызывалка skype_caller.py:



#!/bin/bash

export DISPLAY=:1

python ~skype/skype_caller.py "$1" "$2"


Всем Хабр.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий