Application: "LDAP 389-AS/DS v1.3", "Zabbix v3/4".
Задача: наладить посредством системы мониторинга "Zabbix" отслеживание текущего состояния LDAP-сервиса "389 Directory Server", хранения статистики и уведомления о недоступности критически важных компонентов.
Общий принцип действия выработанного решения таков:
1. Раз в час "Zabbix" обращается за списком актуальных объектов мониторинга (в данном случае репликационных связей) к "Zabbix Agent"-у на стороне сервера "389-AS/DS", ожидая его в JSON-массиве.
2. Для полученного перечня объектов мониторинга сервером "Zabbix", в соответствии с заготовками в специализированном шаблоне, по спецификации "Low-Level Discovery (LLD)" создаются необходимые элементы.
3. Практически все запросы обрабатываются запускаемыми "Zabbix Agent"-ом самодельными скриптами, извлекающими данные через CLI-утилиту "ldapsearch".
2. Для полученного перечня объектов мониторинга сервером "Zabbix", в соответствии с заготовками в специализированном шаблоне, по спецификации "Low-Level Discovery (LLD)" создаются необходимые элементы.
3. Практически все запросы обрабатываются запускаемыми "Zabbix Agent"-ом самодельными скриптами, извлекающими данные через CLI-утилиту "ldapsearch".
Получившееся полностью автоматизированное решение отслеживает состояние локального LDAP-сервера и репликационных связей с другими LDAP-серверами по следующим позициям:
Наличие процесса сервиса "389-DS" (item/trigger, every 30sec);
Наличие открытого порта TCP:636 (item/trigger, every 30sec);
Доступность LDAP-сервиса для клиентских подключений (trigger, every 120sec);
Статистика количества текущих клиентских соединений (item/graph, every 60sec);
Статистика запрошенных клиентом и выполненных сервером операций (item/graph, every 60sec);
Статус каждого соединения репликации по отдельности (item/trigger, every 5min);
Задержки между репликациями для каждого соединения (item/graph, every 5min);
Информирование о длительном периоде без репликации (trigger, every 5hour).
Наличие открытого порта TCP:636 (item/trigger, every 30sec);
Доступность LDAP-сервиса для клиентских подключений (trigger, every 120sec);
Статистика количества текущих клиентских соединений (item/graph, every 60sec);
Статистика запрошенных клиентом и выполненных сервером операций (item/graph, every 60sec);
Статус каждого соединения репликации по отдельности (item/trigger, every 5min);
Задержки между репликациями для каждого соединения (item/graph, every 5min);
Информирование о длительном периоде без репликации (trigger, every 5hour).
Предварительная подготовка.
На стороне LDAP-сервера должен быть установлен "Zabbix Agent" и CLI-утилиты для обращения к LDAP, а также утилита проверки синтаксиса JSON:
# aptitude install zabbix-agent ldap-utils jq
Перед всеми дальнейшими работами потребуется применить заранее подготовленный мною специализированный шаблон для системы мониторинга:
Очень желательно сразу проверить возможность прохождения запроса от сервера мониторинга "Zabbix" к запущенному на стороне LDAP-сервера "Zabbix Agent"-у:
# sudo -u zabbix -s zabbix_get -s ldap0.example.net -k "proc.num[ns-slapd]"
Настраиваем "Zabbix Agent".
Учитывая то, что процедуры сбора данных и отправки их на сервер мониторинга осуществляется клиентом "Zabbix", то конфигурационные файл и скрипты расположим в его директории:
# mkdir -p /etc/zabbix/scripts
# mkdir -p /etc/zabbix/zabbix_agents.conf.d
# mkdir -p /etc/zabbix/zabbix_agents.conf.d
Определяем параметры "Zabbix-Agent"-а, запросы к которым будут обслуживаться внешними приложениями:
# vi /etc/zabbix/zabbix_agentd.conf.d/ldap389.conf
UserParameter=ldap389.discovery, /etc/zabbix/scripts/ldap389_discovery.sh
UserParameter=ldap389.stat[*], /etc/zabbix/scripts/ldap389_stat.sh $1 $2 $3 $4
UserParameter=ldap389.stat[*], /etc/zabbix/scripts/ldap389_stat.sh $1 $2 $3 $4
Установленной по умолчанию двухсекундной задержки при ожидании ответа от "Zabbix-Agent"-а на практике недостаточно - продлеваем до пяти секунд:
# vi /etc/zabbix/zabbix_agentd.conf
....
### Option: Timeout
Timeout=5
....
### Option: Timeout
Timeout=5
....
Для применения изменений в конфигурации "Zabbix Agent" необходимо перезапустить:
# /etc/init.d/zabbix-agent restart
Настраиваем "389-AS/DS".
Создаём пароль, с которым "Zabbix Agent" будет подключаться к LDAP, и сохраняем его рядом с использующим его скриптами, в отдельном текстовом файле:
# vi /etc/zabbix/scripts/.389-ds
Закрываем посторонним доступ к файлу с паролем:
# chown zabbix:zabbix /etc/zabbix/scripts/.389-ds
# chmod go-rwx /etc/zabbix/scripts/.389-ds
# chmod go-rwx /etc/zabbix/scripts/.389-ds
Создаём пользователя, предназначенного для подключения системы мониторинга:
$ ldapmodify -h 127.0.0.1 -D "cn=Directory Manager" -W
dn: cn=Zabbix Monitor,cn=config
changetype: add
cn: Zabbix Monitor
objectClass: inetorgperson
objectClass: person
objectClass: top
sn: Zabbix Monitoring System Bind DN Entry
userPassword: ***
passwordExpirationTime: 20380119031407Z
passwordGraceUserTime: 0
nsIdleTimeout: 0
^d
changetype: add
cn: Zabbix Monitor
objectClass: inetorgperson
objectClass: person
objectClass: top
sn: Zabbix Monitoring System Bind DN Entry
userPassword: ***
passwordExpirationTime: 20380119031407Z
passwordGraceUserTime: 0
nsIdleTimeout: 0
^d
Наделяем пользователя минимально необходимыми правами только чтения записей со статистикой и сведениями о состоянии репликационных связей:
$ ldapmodify -h 127.0.0.1 -D "cn=Directory Manager" -W
dn: cn=monitor
changetype: modify
add: aci
aci: (targetattr = "*") (version 3.0; acl "Allow ROnly for Zabbix Monitoring System";
allow (read,compare,search) (userdn = "ldap:///cn=Zabbix Monitor,cn=config");)
dn: cn=mapping tree,cn=config
changetype: modify
add: aci
aci: (targetattr = "*") (version 3.0; acl "Allow ROnly for Zabbix Monitoring System";
allow (read,compare,search) (userdn = "ldap:///cn=Zabbix Monitor,cn=config");)
^d
changetype: modify
add: aci
aci: (targetattr = "*") (version 3.0; acl "Allow ROnly for Zabbix Monitoring System";
allow (read,compare,search) (userdn = "ldap:///cn=Zabbix Monitor,cn=config");)
dn: cn=mapping tree,cn=config
changetype: modify
add: aci
aci: (targetattr = "*") (version 3.0; acl "Allow ROnly for Zabbix Monitoring System";
allow (read,compare,search) (userdn = "ldap:///cn=Zabbix Monitor,cn=config");)
^d
Есть смысл сразу проверить возможность подключения нашего специализированного пользователя к объекту мониторинга:
$ ldapsearch -x -LLL -h 127.0.0.1 -D "cn=Zabbix Monitor,cn=config" -w `head -n1 /etc/zabbix/scripts/.389-ds` -b "cn=monitor" -s sub "(objectClass=*)"
$ ldapsearch -x -LLL -h 127.0.0.1 -D "cn=Zabbix Monitor,cn=config" -w `head -n1 /etc/zabbix/scripts/.389-ds` -b "cn=mapping tree,cn=config" -s sub "(objectClass=nsDS5ReplicationAgreement)"
Пишем и тестируем скрипт "Zabbix Auto Discovery (LLD)".
Подготовим простейший Bash-скрипт, по запросу подключающийся к "389-DS", запрашивающий перечень объектов мониторинга и формирующий соответствующий требования "Zabbix Auto Discovery" JSON-массив:
# cd /etc/zabbix/scripts
# vi ./ldap389_discovery.sh
# vi ./ldap389_discovery.sh
#!/bin/bash
# usage: ./ldap389_discovery.sh
# Задаём переменные рабочего окружения
LOG="/var/log/zabbix-agent/zabbix-ldap389-error.log"
DATE=$(date +"%Y-%m-%d.%H:%M:%S")
# Проверяем наличие ожидаемых утилит
[ -x "$(command -v ldapsearch)" ] && [ -x "$(command -v jq)" ] || { echo "${DATE}: Не обнаружены необходимые для работы утилиты. Процедура создания списка активных связей реплицирования прервана." >> ${LOG}; exit 1; }
# Запрашиваем у LDAP-сервиса перечень его связей реплицирования
REPLS=$(ldapsearch -x -LLL -h 127.0.0.1 -D "cn=Zabbix Monitor,cn=config" -w `head -n1 /etc/zabbix/scripts/.389-ds` -b "cn=mapping tree,cn=config" -s sub "(objectClass=nsDS5ReplicationAgreement)" dn | awk 'match($0, /^dn:\s*cn=(.*),cn=replica,/, result) {print result[1];}')
# Если перечень связей реплицирования не пуст, то формируем JSON для "Zabbix Low-Level Discovery (LLD)"
if [ ! -z "${REPLS}" ] ; then
# Задаём начало JSON
JSONZLLD="{\"data\":["
FIRST=1
# Перебираем блоки конфигурации
for REPLICA in ${REPLS} ; do
# Проставляем разделитель между элементами JSON
if [ ${FIRST} == 0 ] ; then
JSONZLLD=${JSONZLLD}","
fi
FIRST=0
# Вводим имя задания в качестве элмента JSON
JSONZLLD=${JSONZLLD}"{\"{#REPLICA}\":\"${REPLICA}\"}"
done
# Завершаем JSON
JSONZLLD=${JSONZLLD}"]}"
# Проверяем синтаксическую корректность JSON
if jq -e . 1>/dev/null 2>&1 <<< "${JSONZLLD}" ; then
# Отдаём JSON на STDOUT
echo ${JSONZLLD}
fi
fi
exit ${?}
# usage: ./ldap389_discovery.sh
# Задаём переменные рабочего окружения
LOG="/var/log/zabbix-agent/zabbix-ldap389-error.log"
DATE=$(date +"%Y-%m-%d.%H:%M:%S")
# Проверяем наличие ожидаемых утилит
[ -x "$(command -v ldapsearch)" ] && [ -x "$(command -v jq)" ] || { echo "${DATE}: Не обнаружены необходимые для работы утилиты. Процедура создания списка активных связей реплицирования прервана." >> ${LOG}; exit 1; }
# Запрашиваем у LDAP-сервиса перечень его связей реплицирования
REPLS=$(ldapsearch -x -LLL -h 127.0.0.1 -D "cn=Zabbix Monitor,cn=config" -w `head -n1 /etc/zabbix/scripts/.389-ds` -b "cn=mapping tree,cn=config" -s sub "(objectClass=nsDS5ReplicationAgreement)" dn | awk 'match($0, /^dn:\s*cn=(.*),cn=replica,/, result) {print result[1];}')
# Если перечень связей реплицирования не пуст, то формируем JSON для "Zabbix Low-Level Discovery (LLD)"
if [ ! -z "${REPLS}" ] ; then
# Задаём начало JSON
JSONZLLD="{\"data\":["
FIRST=1
# Перебираем блоки конфигурации
for REPLICA in ${REPLS} ; do
# Проставляем разделитель между элементами JSON
if [ ${FIRST} == 0 ] ; then
JSONZLLD=${JSONZLLD}","
fi
FIRST=0
# Вводим имя задания в качестве элмента JSON
JSONZLLD=${JSONZLLD}"{\"{#REPLICA}\":\"${REPLICA}\"}"
done
# Завершаем JSON
JSONZLLD=${JSONZLLD}"]}"
# Проверяем синтаксическую корректность JSON
if jq -e . 1>/dev/null 2>&1 <<< "${JSONZLLD}" ; then
# Отдаём JSON на STDOUT
echo ${JSONZLLD}
fi
fi
exit ${?}
Переводим файл во владение "Zabbix Agent"-а и делаем его исполняемым:
# chown zabbix:zabbix ./ldap389_discovery.sh && chmod ug+x,o-rwx ./ldap389_discovery.sh
Пример получаемого в ответ на запрос JSON-файла для "Zabbix LLD", с обнаруженными активными объектами мониторинга:
{
"data":[
{"{#REPLICA}":"ldap1.example.net"},
{"{#REPLICA}":"ldap2.example.net"}
]
}
"data":[
{"{#REPLICA}":"ldap1.example.net"},
{"{#REPLICA}":"ldap2.example.net"}
]
}
Проверяем корректность отрабатывания скрипта "Auto Discovery (LLD)":
# sudo -u zabbix -s zabbix_get -s ldap0.example.net -k "ldap389.discovery"
Пишем и тестируем скрипт получения запрашиваемых параметров.
Создаём специализированный Bash-скрипт, принимающий от "Zabbix Agent"-а запросы на получение данных по ряду интересующих нас параметров, обращающийся посредством CLI-утилиты "ldapsearch" к серверу "389-DS" и нормализующий их перед выдачей:
# cd /etc/zabbix/scripts
# vi ./ldap389_stat.sh
# vi ./ldap389_stat.sh
#!/bin/bash
# usage: ./ldap389_stat.sh "targetObjectName" "objectParam" {Level}
# Задаём переменные рабочего окружения
LOG="/var/log/zabbix-agent/zabbix-ldap389-error.log"
PSWD=$(head -n1 /etc/zabbix/scripts/.389-ds)
DATE=$(date +"%Y-%m-%d.%H:%M:%S")
unset ANSWER
# Проверяем наличие ожидаемых утилит
[ -x "$(command -v ldapsearch)" ] || { echo "${DATE}: Не обнаружены необходимые для работы утилиты. Процедура запроса статистики прервана." >> ${LOG}; exit 1; }
# Проверяем корректность вводимых данных и выводим подсказку в журнал событий при необходимости
OITARGET="${1}"
OIPARAM="${2}"
#
[ ! "${OITARGET}" ] && { echo "${DATE}: Запрос: \"$(basename $0) $@\". Не указан субъект. Процедура запроса статуса прервана." >> ${LOG}; exit 1; }
[ ! "${OIPARAM}" ] && { echo "${DATE}: Запрос: \"$(basename $0) $@\". Не указан запрашиваемый параметр. Процедура запроса статуса прервана." >> ${LOG}; exit 1; }
# В зависимости от целевого объекта применяем разные подходы
if [[ "${OITARGET}" == "local" ]] ; then
# Запрашиваем глобальную статистику сервера
if [ "${OIPARAM}" == "currentconnections" ] ; then
# Выдаём сведения о количестве клиентских подключений в данный момент
ANSWER=$(ldapsearch -x -LLL -h 127.0.0.1 -D "cn=Zabbix Monitor,cn=config" -w ${PSWD} -b "cn=monitor" -s base "(objectClass=*)" currentconnections | grep -i currentconnections | awk '{print $2}')
elif [ "${OIPARAM}" == "opsinitiated" ] ; then
# Выдаём сведения о количестве инициированных клиентами операций
ANSWER=$(ldapsearch -x -LLL -h 127.0.0.1 -D "cn=Zabbix Monitor,cn=config" -w ${PSWD} -b "cn=monitor" -s base "(objectClass=*)" opsinitiated | grep -i opsinitiated | awk '{print $2}')
elif [ "${OIPARAM}" == "opscompleted" ] ; then
# Выдаём сведения о количестве выполненных сервером операций
ANSWER=$(ldapsearch -x -LLL -h 127.0.0.1 -D "cn=Zabbix Monitor,cn=config" -w ${PSWD} -b "cn=monitor" -s base "(objectClass=*)" opscompleted | grep -i opscompleted | awk '{print $2}')
fi
else
# Проверяем наличие запрашиваемого набора параметров
RCHECK=$(ldapsearch -x -LLL -h 127.0.0.1 -D "cn=Zabbix Monitor,cn=config" -w ${PSWD} -b "cn=mapping tree,cn=config" -s sub "(&(objectClass=nsDS5ReplicationAgreement)(cn=${OITARGET}))" dn)
if [ ! -z "${RCHECK}" ] ; then
# Запрашиваем статистику связи репликации
if [ "${OIPARAM}" == "lastupdatestart" ] ; then
# Выдаём дату и время в удобном для восприятия человеком формате
ANSWER=$(ldapsearch -x -LLL -h 127.0.0.1 -D "cn=Zabbix Monitor,cn=config" -w ${PSWD} -b "cn=mapping tree,cn=config" -s sub "(&(objectClass=nsDS5ReplicationAgreement)(cn=${OITARGET}))" nsds5replicaLastUpdateSTart | grep -i nsds5replicaLastUpdateStart | awk '{print $2}' | sed -E "s/([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})Z/\1-\2-\3 \4:\5:\6Z/" | date '+%Y-%m-%d %H:%M:%S' -f- 2>/dev/null)
elif [ "${OIPARAM}" == "timesincelastupdate" ] ; then
# Выдаём временную задержку от последней репликации до текущего момента (в секундах)
STARTTIME=$(ldapsearch -x -LLL -h 127.0.0.1 -D "cn=Zabbix Monitor,cn=config" -w ${PSWD} -b "cn=mapping tree,cn=config" -s sub "(&(objectClass=nsDS5ReplicationAgreement)(cn=${OITARGET}))" nsds5replicaLastUpdateStart | grep -i nsds5replicaLastUpdateStart | awk '{print $2}' | sed -E "s/([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})Z/\1-\2-\3 \4:\5:\6Z/" | date +%s -f- 2>/dev/null)
let "ANSWER = $(date +%s) - STARTTIME"
elif [ "${OIPARAM}" == "lastupdatestatus" ] ; then
# Выдаём преобразованный в удобрый для "Zabbix" формат статус последней репликации
# (https://directory.fedoraproject.org/docs/389ds/FAQ/replication-update-status.html)
RSTATUS=$(ldapsearch -x -LLL -h 127.0.0.1 -D "cn=Zabbix Monitor,cn=config" -w ${PSWD} -b "cn=mapping tree,cn=config" -s sub "(&(objectClass=nsDS5ReplicationAgreement)(cn=${OITARGET}))" nsds5replicaLastUpdateStatus | grep -i nsds5replicaLastUpdateStatus | grep -i "Error\s(0)\s\|Error\s(1)\s")
if [ ! -z "${RSTATUS}" ] ; then
ANSWER="1"
else
ANSWER="0"
# Для понимания, что пошло не так, сохраняем в журнале неположительный статус репликации
ldapsearch -x -LLL -h 127.0.0.1 -D "cn=Zabbix Monitor,cn=config" -w ${PSWD} -b "cn=mapping tree,cn=config" -s sub "(&(objectClass=nsDS5ReplicationAgreement)(cn=${OITARGET}))" nsds5replicaLastUpdateStatus | grep -i nsds5replicaLastUpdateStatus >> "${LOG}"
fi
fi
fi
fi
# Отдаём значение запрашиваемого параметра (ничего не отвечаем, если параметр не поддерживается)
# (важно отдавать значение не заключая его в кавычки, иначе нулевое значение до "Zabbix" не доходит)
[ ! -z "${ANSWER}" ] && echo ${ANSWER}
exit ${?}
# usage: ./ldap389_stat.sh "targetObjectName" "objectParam" {Level}
# Задаём переменные рабочего окружения
LOG="/var/log/zabbix-agent/zabbix-ldap389-error.log"
PSWD=$(head -n1 /etc/zabbix/scripts/.389-ds)
DATE=$(date +"%Y-%m-%d.%H:%M:%S")
unset ANSWER
# Проверяем наличие ожидаемых утилит
[ -x "$(command -v ldapsearch)" ] || { echo "${DATE}: Не обнаружены необходимые для работы утилиты. Процедура запроса статистики прервана." >> ${LOG}; exit 1; }
# Проверяем корректность вводимых данных и выводим подсказку в журнал событий при необходимости
OITARGET="${1}"
OIPARAM="${2}"
#
[ ! "${OITARGET}" ] && { echo "${DATE}: Запрос: \"$(basename $0) $@\". Не указан субъект. Процедура запроса статуса прервана." >> ${LOG}; exit 1; }
[ ! "${OIPARAM}" ] && { echo "${DATE}: Запрос: \"$(basename $0) $@\". Не указан запрашиваемый параметр. Процедура запроса статуса прервана." >> ${LOG}; exit 1; }
# В зависимости от целевого объекта применяем разные подходы
if [[ "${OITARGET}" == "local" ]] ; then
# Запрашиваем глобальную статистику сервера
if [ "${OIPARAM}" == "currentconnections" ] ; then
# Выдаём сведения о количестве клиентских подключений в данный момент
ANSWER=$(ldapsearch -x -LLL -h 127.0.0.1 -D "cn=Zabbix Monitor,cn=config" -w ${PSWD} -b "cn=monitor" -s base "(objectClass=*)" currentconnections | grep -i currentconnections | awk '{print $2}')
elif [ "${OIPARAM}" == "opsinitiated" ] ; then
# Выдаём сведения о количестве инициированных клиентами операций
ANSWER=$(ldapsearch -x -LLL -h 127.0.0.1 -D "cn=Zabbix Monitor,cn=config" -w ${PSWD} -b "cn=monitor" -s base "(objectClass=*)" opsinitiated | grep -i opsinitiated | awk '{print $2}')
elif [ "${OIPARAM}" == "opscompleted" ] ; then
# Выдаём сведения о количестве выполненных сервером операций
ANSWER=$(ldapsearch -x -LLL -h 127.0.0.1 -D "cn=Zabbix Monitor,cn=config" -w ${PSWD} -b "cn=monitor" -s base "(objectClass=*)" opscompleted | grep -i opscompleted | awk '{print $2}')
fi
else
# Проверяем наличие запрашиваемого набора параметров
RCHECK=$(ldapsearch -x -LLL -h 127.0.0.1 -D "cn=Zabbix Monitor,cn=config" -w ${PSWD} -b "cn=mapping tree,cn=config" -s sub "(&(objectClass=nsDS5ReplicationAgreement)(cn=${OITARGET}))" dn)
if [ ! -z "${RCHECK}" ] ; then
# Запрашиваем статистику связи репликации
if [ "${OIPARAM}" == "lastupdatestart" ] ; then
# Выдаём дату и время в удобном для восприятия человеком формате
ANSWER=$(ldapsearch -x -LLL -h 127.0.0.1 -D "cn=Zabbix Monitor,cn=config" -w ${PSWD} -b "cn=mapping tree,cn=config" -s sub "(&(objectClass=nsDS5ReplicationAgreement)(cn=${OITARGET}))" nsds5replicaLastUpdateSTart | grep -i nsds5replicaLastUpdateStart | awk '{print $2}' | sed -E "s/([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})Z/\1-\2-\3 \4:\5:\6Z/" | date '+%Y-%m-%d %H:%M:%S' -f- 2>/dev/null)
elif [ "${OIPARAM}" == "timesincelastupdate" ] ; then
# Выдаём временную задержку от последней репликации до текущего момента (в секундах)
STARTTIME=$(ldapsearch -x -LLL -h 127.0.0.1 -D "cn=Zabbix Monitor,cn=config" -w ${PSWD} -b "cn=mapping tree,cn=config" -s sub "(&(objectClass=nsDS5ReplicationAgreement)(cn=${OITARGET}))" nsds5replicaLastUpdateStart | grep -i nsds5replicaLastUpdateStart | awk '{print $2}' | sed -E "s/([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})Z/\1-\2-\3 \4:\5:\6Z/" | date +%s -f- 2>/dev/null)
let "ANSWER = $(date +%s) - STARTTIME"
elif [ "${OIPARAM}" == "lastupdatestatus" ] ; then
# Выдаём преобразованный в удобрый для "Zabbix" формат статус последней репликации
# (https://directory.fedoraproject.org/docs/389ds/FAQ/replication-update-status.html)
RSTATUS=$(ldapsearch -x -LLL -h 127.0.0.1 -D "cn=Zabbix Monitor,cn=config" -w ${PSWD} -b "cn=mapping tree,cn=config" -s sub "(&(objectClass=nsDS5ReplicationAgreement)(cn=${OITARGET}))" nsds5replicaLastUpdateStatus | grep -i nsds5replicaLastUpdateStatus | grep -i "Error\s(0)\s\|Error\s(1)\s")
if [ ! -z "${RSTATUS}" ] ; then
ANSWER="1"
else
ANSWER="0"
# Для понимания, что пошло не так, сохраняем в журнале неположительный статус репликации
ldapsearch -x -LLL -h 127.0.0.1 -D "cn=Zabbix Monitor,cn=config" -w ${PSWD} -b "cn=mapping tree,cn=config" -s sub "(&(objectClass=nsDS5ReplicationAgreement)(cn=${OITARGET}))" nsds5replicaLastUpdateStatus | grep -i nsds5replicaLastUpdateStatus >> "${LOG}"
fi
fi
fi
fi
# Отдаём значение запрашиваемого параметра (ничего не отвечаем, если параметр не поддерживается)
# (важно отдавать значение не заключая его в кавычки, иначе нулевое значение до "Zabbix" не доходит)
[ ! -z "${ANSWER}" ] && echo ${ANSWER}
exit ${?}
Переводим файл во владение "Zabbix Agent"-а и делаем его исполняемым:
# chown zabbix:zabbix ./ldap389_stat.sh && chmod ug+x,o-rwx ./ldap389_stat.sh
Аналогично предыдущим этапам проверяем корректность прохождения запросов к "389-DS" от сервера мониторинга "Zabbix":
# sudo -u zabbix -s zabbix_get -s ldap0.example.net -k "ldap389.stat[ldap0.example.net,lastupdatestatus]"
Эксплуатация.
Как легко понять из вышеприведённых скриптов механизм актуализации перечня объектов мониторинга происходит полностью автоматически максимум спустя один час после изменения конфигурации LDAP-сервера "389-DS" - это удобно. Каких-то особых замечаний к схеме нет и она легко дополняется желаемыми параметрами.