Automating the turning on/off the mail forwarding in Zimbra
Система состоит из 6 исполняемых файлов-скриптов, 5 на shell-script, 1 на #awk, разбитых на две группы: ввод данных и обработка.
Ввод (и частичная обработка) выполняется по цепочке:
zimtest --> zimtest1
zimtest1 вызывает rrgtest и при необходимости zmonoff
Автоматическая обработка по расписанию выполняется zimparser, который вызывает zimawk.awk и zmonoff.
ZIMTEST
Сценарий-обёртка. При запуске без параметров выдает наикратчайшую справку. Запускается с параметрами:
zimtest дата_начала дата_окончания кого на_кого
Все параметры обязательны.
Обе
даты задавать в русском формате
дд.мм.гггг,
год обязательно 4 цифрами. В качестве разделителя полей даты можно
использовать точку, прямой слэш или их комбинацию - все разделители
потом приводятся к слэшам.
В качестве
кого можно
указывать как полный емайл (напр. pupkin_vasya@наш_домен), так и только
именную его часть (pupkin_vasya) - при проверке имени зимброй работают
оба варианта.
На_кого - только полный емайл, поскольку эта строка просто будет вписана в соответствующее поле LDAP для
кого. (однако, валидность этого адреса тоже проверяется и вписать несуществующего получателя не удастся)
Емайлы должны принадлежать нашему домену - автоматическая настройка автоматической пересылки на другие домены не разрешается.
ZIMTEST1
Основной скрипт ввода. Использует два скрипта -
rregtest и
zmonoff - для выполнения отдельных операций.
rregtest используется
как подключаемая библиотека, содержащая функцию проверки допустимости
даты. Поскольку со времени начальной разработки эта функция сильно
упростилась (я отдал все лишние проверки операционной системе), то
возможно, что функция будет включена в состав
zimtest1, а
rregtest будет исключен из "комплекса".
zmonoff
(ZiMbra ON/OFF) - скрипт, выполняющий, собственно, включение/выключение
переадресации. Используется здесь в случаях, когда дата начала
переадресации уже прошла или наступила сегодня для немедленного
включения переадресации, либо когда дата отключения уже прошла или
наступила сегодня, для немедленного отключения.
Переданные даты отдаются на проверку сценарию
rregtest,
а емайлы проверяются внутри скрипта силами зимбры. Изначально, опять
же, я писал валидатор для емайлов, но потом отказался от него и запускаю
zmprov ga. Чтобы не делать пустую проверку, для красоты
получаю в ее ходе от зимбры человеческое имя пользователя. Пока оно
просто выводится на экран, но в теории может пригодиться для чего-нибудь
полезного.
Для тех же красивостей вычисляется количество дней
между начальной и конечной датами действия переадресации. Сходный
алгоритм используется чуть позже для вычисления времени, оставшегося до
включения/отключения переадресации.
После проверки "а не указана
ли конечная дата раньше начальной?" начинается собственно формирование
файла данных для обработки по крону.
Если выясняется, что
переданная дата уже наступила, то действие выполняется немедленно и в
файл данных для дальнейшей обработки ничего не заносится. Проверка на
случай, когда обе даты в прошлом, не делается и если так и есть, то
сначала переадресация включается, а потом сразу выключается. Не очень
оптимально, но уже лень было делать лишнюю проверку.
Если же переданная дата еще не наступила, то информация о ней дописывается в конец файла данных
zmsched.dat в виде строки:
@секунды:действие:аккаунт_кого:емайл_на_кого:дата_по-русски
Например:
Переадресовывать почту Васи Пупкина на Петю Попкина с 25.09.2013
@1380027600:on:pupkin_vasya:popkin_petya@my.domain:25.09.2013
Отменить с 25.09.2013 переадресацию почты Васи Пупкина. Поле
емайл_на_кого пусто, но оно есть - это строка нулевой длины между третьим и четвертым двоеточиями.
@1380027600:off:pupkin_vasya::25.09.2013
@секунды - дата выполнения действия в формате
date -d "дата 0:00" +@%s
то есть, количество секунд с начала "эпохи" до нуля часов нужного дня. Такой формат выбран для удобства сравнения в обработчике.
действие - принимает одно из трех возможных значений:
on, off, skip. Действие
skip будет описано ниже в описании обработчика zimawk.awk. Действия
on и
off самоочевидны: включить или выключить переадресацию для
аккаунт_кого, указав, в случае включения
емайл_на_кого.
аккаунт_кого
- либо имя пользователя либо емайл пользователя, чью почту
переадресовывать. Как говорилось выше, в этом поле достаточно
использовать только имя аккаунта. Емайл тоже можно, но это целесообразно
только при наличии на сервере нескольких доменов. Когда домен один,
достаточно имени пользователя.
емайл_на_кого - емайл и
только емайл, на который будет переадресовываться почта. Это просто
строка, которая будет помещаться в соответствующее поле в LDAP-записи
про
аккаунт_кого. Если указано
действие off, то содержимое этого поля может быть пустым - оно никак не анализируется в такой ситуации, хотя и обязано присутствовать.
дата_по-русски - то же самое, что
@секунды,
но в формате дд.мм.гггг. Поле добавлено только для удобочитаемости
человеком. Теоретически возможно отказаться от первого поля
@секунды, чтобы файл можно было править вообще вручную.
RREGTEST
Подключаемая библиотека-сценарий. Содержит только одну функцию
validdate(), которая изначально задумывалась как полноценный валидатор дат, но позже была упрощена.
Дата проверяется на минимальную правильность по шаблону, примерно соответствующему дате в русском формате
дд.мм.гггг.
Причем этот шаблон очень нечеткий и допускает, например, 39.00.2016
(тридцать девятое число нулевого месяца). Это сделано умышленно, чтобы
просто удостовериться, что в параметре передана именно дата, а не что-то
другое: при любом большем несоответствии скрипт вываливается с
exit 1, останавливая работу вызвавших его скриптов.
Дальше дата разбирается на запчасти и день меняется местами с месяцем, образуя дату в американском формате
мм/дд/гггг: увы и ах, но юниксы были написаны американцами и штатная
date никак не воспринимает на входе русский формат. Японский гггг/мм/дд, кстати, тоже.
Сформированную дату пытаемся вывести на экран, и тут уже пусть
date сама проверяет ее допустимость. Неправильно что-то? Вываливаемся!
На
случай, если дата допустимая, отдельно проверяется год - он должен быть
не меньше предыдущего и не больше следующего. Сейчас просто выводится
сообщение, если год неправильный, но это можно использовать для
каких-нибудь более жестких проверок
ZIMPARSER
Скрипт-обёртка,
запускаемый по крону. Устанавливает некоторые служебные переменные и
вызывает собственно обработчик файла настроек.
Файл со скриптом
обработчика и файл настроек должны находиться в одном с ним каталоге.
Возможно, в будущем их местоположение будет передаваться в параметрах.
ZIMAWK.AWK
Основной обработчик файла данных
zimsched.dat. Файл считывается построчно и если строка проходит ряд проверок, выполняется указанное в ней действие.
Проверки:
1. если в строке не пять полей, то строка считается неправильной и не обрабатывается, о чем делается запись в логе
2. если указано действие
skip, то эта строка была обработана на прошлом проходе и ее обработка не требуется. Строка пропускается.
Прошедшая
эти проверки строка считывается в массив для последующего
переформирования файла данных. Если дата действия еще не наступила, то
строка дальше не обрабатывается.
В подходящих для обработки строках действие заменяется с
on или
off на
skip, чтобы удалить их на следующем проходе, и вызывается
zmonoff для выполнения нужной операции.
После обработки всего файла создается временный файл
zmsched.new, в который первой строкой выводится дата/время его создания, а далее построчно дописывается содержимое массива.
Старый файл данных переименовывается в
zmsched.DOW, где DOW - номер дня недели, одна цифра, что позволяет вести историю изменений файла данных за последнюю неделю.
Файл
zmsched.new копируется под именем
zmsched.dat и система готова к новому циклу.
---
Использовались материалы:
Bash Scripting Guide
AWK
Еще awk и sed.
Под катом исходники.