Поўная сінхранізацыя агульных тэчак, кантактаў, календароў паміж размеркаванымі серверамі Kerio Connect

Добры дзень, Хабр!

Задача

У маёй арганізацыі выкарыстоўваюць паштовы сервер на платформе Kerio Connect, у розных гарадах устаноўлены паштовыя серверы, якія абслугоўваюць сваіх карыстальнікаў. Размеркаванай структуры першапачаткова не было, бо дамены адрозніваюцца на трэцім узроўні з указаннем горада пляцоўкі. Усё працавала і ўсіх уладкоўвала. Аднаго дня - кіраўніцтва паставіла задачу, агульны каляндар спраў паміж усімі пляцоўкамі!

перадгісторыя

Першапачаткова ідэя была падняць Размеркаваны паштовы дамен Kerio і ён сам усё зробіць. Сказана, зроблена размеркаваны дамен быў створаны, але не тут-то было, сервер гатовы быў сінхранізаваць календары, тэчкі, кантакты - паміж даменамі змешчанымі на адным серверы, але зусім не збіраўся сінхранізаваць дадзеныя паміж некалькімі серверамі.

Такога падвоху я, вядома, не чакаў і доўга не мог паверыць у адсутнасць неабходнага мне функцыяналу. Пазней знайшоў дакументальнае пацвярджэнне гэтаму факту. Чым быў вельмі моцна збянтэжаны і расчараваны.

Задача плаўна перацякла ў праблему.

Якія былі варыянты

  • Стварыць двух кліентаў на розных серверах, якія нейкім іншым ПЗ абменьвалі неабходныя дадзеныя. Трэба было знайсці гэта самае іншае ПЗ, якое б рэалізоўвала дадзены функцыянал - не люблю такія граблі, але здавалася што гэта адзіна хуткае рашэнне.
  • Напісаць свой уласны скрыпт сінхранізацыі даных паміж серверамі. Справа ў тым, што Kerio захоўвае кожны аб'ект як асобны файл, адпаведна патрабавалася распрацаваць скрыпт працы з файламі, але ў выглядзе дастатковай кол-ва крыніц задача здавалася некалькі складанай, тым больш што трэба было выконваць множныя праверкі карэктнасці дадзеных, раптам хтосьці створыць задачу ў аднолькавы прамежак часу і тд і тп.

Забягаючы наперад скажу, што Kerio хоць і захоўвае аб'ект як асобны файл, ён не настолькі дурны, каб пры кожным звароце да аб'екта пытаць як справы ў файлавай сістэмы.

Выдаткаваўшы на разважанні вялікая колькасць часу, вымаляваўшы кучу паперак з планамі "па захопе варожай тэрыторыі", у 6 гадзіне ўра я прыняў два дакладных рашэння:

  • Першае рашэнне - рабіць сваё і нічога іншага не шукаць.
  • Другое рашэнне - ісці спаць.

Ужо раніцай я прачнуўся з адной адзіна і дакладнай думкай, якая скарацілася да некалькіх літар - DFS

рашэнне

Само рашэнне выглядала наступным чынам

  • прывесці ўсе серверы, якія будуць удзельнічаць у сінхранізацыі да OS Windows. (Частка была на Linux. патрабавалася міграцыя паштовых дадзеных на іншую OS)
  • Вызначыцца са структурай каталогаў, якія будуць удзельнічаць у сінхранізацыі - яны павінны быць ідэнтычныя.
  • Вызначыць усе паштовыя серверы пад адзін дамен з адзіным DFS прасторай.
  • Стварыць вышэй згаданы размеркаваны дамен Kerio, бо ў маім выпадку патрабуецца сінхранізацыя дадзеных, не толькі паміж серверамі але і паміж даменамі, другім можа займацца сервер Kerio самастойна. (у адрозненне ад першага)
  • Нацкаваць сінхранізаваныя каталогі на прастору DFS.
  • Прыдумаць які-небудзь мыліц (бо без мыліцы нельга)

Рэалізацыя

Прыклад на двух паштовых серверах (можа быць больш)

1. Kerio Distributed domain

Поўная сінхранізацыя агульных тэчак, кантактаў, календароў паміж размеркаванымі серверамі Kerio Connect

Master не ўдзельнічае ў сінхранізацыі, але гэта не абавязковая ўмова.

Распісваць, як падняць размеркаваны дамен Kerio не буду, нічога складанага ў гэтым няма, можна вывучыць афіцыйны махнуў

У канчатковым выніку ў кансолі адміністравання вы павінны ўбачыць наступную карцінку:

Поўная сінхранізацыя агульных тэчак, кантактаў, календароў паміж размеркаванымі серверамі Kerio Connect

Поўная сінхранізацыя агульных тэчак, кантактаў, календароў паміж размеркаванымі серверамі Kerio Connect

Далей мяне цікавілі агульныя тэчкі, на серверы Master можна пазначыць наступныя варыянты:

Поўная сінхранізацыя агульных тэчак, кантактаў, календароў паміж размеркаванымі серверамі Kerio Connect

Поўная сінхранізацыя агульных тэчак, кантактаў, календароў паміж размеркаванымі серверамі Kerio Connect

Адмысловая для кожнага дамена - сервер не будзе сінхранізаваць агульнадаступныя тэчкі паміж даменамі

Агульныя для ўсіх даменаў - усе серверы адмовяцца ад існых агульных тэчак у кожным дамене і створаць новыя адзіныя тэчкі для ўсіх даменаў на кожным з паштовым серверы.

Увага! Дадзеная опцыя хоць і змяняе палітыку налады на ўсіх серверах, сінхранізацыю вырабляе асобна ад кожнага з сервераў (гэта значыць – без адзінай агульнай прасторы)

У адміністратара - застанецца магчымасць, размяркоўваць доступы паміж карыстальнікамі.
у маім выпадку - усе свае і мне патрэбна поўная сінхранізацыя (У вашым выпадку рашэнне можа быць іншым) на кожным серверы трэба стварыць аднолькавыя наборы даменаў якія неабходна сінхранізаваць.

2. Каталогі дадзеных Kerio

Цяпер неабходна стварыць аднолькавыя агульныя каталогі, якія неабходна сінхранізаваць на кожным з сервераў. Тэчкі, Календары, Кантакты.

Савет - стварайце каталогі на англійскай мове, у тым выпадкі, калі вы створыце іх на лацінцы, дырэкторыя будзе мець назву ў нейкай незразумелай кадоўцы, гэта як мінімум няёмка.

Зараз неабходна знайсці фізічныя шляхі паштовых тэчак на кожным серверы.

Агульныя для ўсіх даменаў ~DataMailmail#publicСинхронизируемый каталог#msgs
Адмысловая для кожнага дамена ~DataMailmail**Domain**#publicСинхронизируемый каталог#msgs

Звярніце ўвазе, што мы будзем сінхранізаваць не ўвесь каталог, а толькі кантэйнер з дадзенымі #msgs - Тут захоўваюцца самі аб'екты, усе астатнія дадзеныя для кожнага з сервераў павінны быць свае.

3. DFS

Падрабязна як наладжваць DFS, таксама распісваць не буду, інфармацыі па дадзеным пытанні дастаткова.

DFS – гэта служба ролі ў Windows Server, якая дае магчымасць аб'яднання агульных тэчак, змешчаных на розных серверах
Спасылка на дакумент MS DFS

Перад наладай DFS – неабходна спыніць усе паштовыя серверы, якія будуць удзельнічаць у сінхранізацыі дадзеных.

Па канчатку налады вы павінны атрымаць наступную карцінку для кожнай з сінхранізаваных тэчак

Поўная сінхранізацыя агульных тэчак, кантактаў, календароў паміж размеркаванымі серверамі Kerio Connect

публікаваць якія рэплікуюцца тэчкі нам натуральна не трэба.

Поўная сінхранізацыя агульных тэчак, кантактаў, календароў паміж размеркаванымі серверамі Kerio Connect

Пасля таго як адбудзецца рэпліцыраванне (а рэплецыраваць там асабліва няма чаго - тэчкі пустыя) паштовыя сервера можна запусціць.

Далей можна напоўніць дадзенымі адзін з паштовых сервераў і праверыць што дадзеныя рэплікуюцца карэктна.

4. Кастыль

Апісанне разважанні

Як вы можаце пераканацца пасля таго як дадзеныя пачалі сінхранізавацца (DFS), у тым выпадкі калі вы што або стварылі на першым серверы - на другім серверы нешта неяк нічога не з'яўляецца, або з'яўляецца але неяк не заўсёды.

Адчайваецца не варта яно вядома рана ці позна там з'явіцца, але лепш рана, чым позна. Бо позна гэта праз 6 – 12 гадзін.

Уся справа ў тым, што як толькі вы нешта стварылі на першым серверы, на другім і наступных файл вядома адразу ж з'явіцца дзякуючы сістэме DFS, аднак у тым выпадку, калі дадзены паштовы каталог ужо быў кімсьці прачытаны раней і яго запытаюць паўторна, сервер не будзе перачытваць тэчку #msgs а выплюне дадзеныя са свайго ўласнага азначніка, які можа ўжо даўно не адпавядаць нашай рэчаіснасці.

У Kerio ёсць механізм перачытвання азначніка, але ён можа спрацаваць гадзін гэтак праз шэсць, пры гэтым за гэтыя 6 гадзін актуальнасць задачы ў календары можа быць некалькі згублена.
Для таго каб праверыць працу сінхранізацыі прамы цяпер, можна выдаліць файл у які адпавядае сінхранізаваным каталогу index.fld, пасля паўторнага звароту да тэчкі на паштовым серверы і пры адсутнасці дадзенага файла Kerio перачытае каталог і дадзеныя з'явяцца. Здавалася б, вось яно рашэнне, выдаляй файл пры змене дадзеных, але гэта працуе не кожны раз, а толькі першы раз, далей Kerio чамусьці губляе ўсякую цікавасць да index.fld
Так і яшчэ пачынае выплёўваць незразумелыя для карыстальніка паведамлення - пра нейкі індэкс і што ён там ужо нешта робіць.

Ёсць яшчэ варыянт, штосьці стварыць – у момант стварэння новага аб'екта сервер раптам зразумее, што імя файла, якое ён жадаў прысвоіць ужо занята, але тут снежны ком і гэта тупіковы варыянт.

Як жа быць?

Калі яшчэ раз звярнуць увагу на ўжо знаёмую нам карцінку.

Поўная сінхранізацыя агульных тэчак, кантактаў, календароў паміж размеркаванымі серверамі Kerio Connect

Але ў іншай плоскасці, можна заўважыць вельмі цікавую і патрэбную нам зараз кнопку - Пераіндэксаваць тэчкі

І сапраўды. Калі націснуць на дадзеную кнопку на паштовым серверы, які не ведае пра тое, што ў яго ўжо нешта змянілася ў сінхранізаваным #msgs, мы атрымаем стабільны, хуткі вынік. Усё схаванае стане відавочным.

У часопісе можна паглядзець, колькі займае часу дадзены працэс, у маім выпадкі з некалькімі тысячамі (15 тыс) запісаў каля 3-4 хвілін.

Засталіся толькі прыдумаць, як уласна націснуць на дадзеную кнопку, тады калі нам гэта трэба.

Аказваецца ў Kerio ёсць свой API

Апісанне
Дакументацыя

Функцыя, якая выконвае нашу задачу, выглядае так -
session = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)

З усяго вышэй выкладзенага нам трэба напісаць скрыпт, які маніторыў бы стан якія цікавяць тэчак і ў тым выпадкі, калі нешта змянілася, выконваў для нас патрэбную нам функцыю.

Жадаю сказаць, што я напісаў некалькі розных версій скрыптоў якія выконваюць розныя праверкі, спыніўся на тым, які ўсе высновы будуе зыходзячы з колькасці файлаў.

Рэалізацыя скрыпту

Прыклад скрыпту CMD і апісанне

Re-index.bat

@echo off
set dir=%~dp0
%dir:~0,2%
CD "%~dp0"
md "%CD%LOG"
md "%CD%Setup"

ECHO -Start- >> "%CD%LOG%Computername%.log"
ECHO Start -> %Computername% %Date% %Time% >> "%CD%LOG%Computername%.log"

SetLocal EnableDelayedExpansion
for /f "UseBackQ Delims=" %%A IN ("%CD%Setup%Computername%.List") do (
  set /a c+=1
  set "m!c!=%%A"
)

set d=%c%
Echo Folder = %c%
ECHO Folder = %c% >> "%CD%LOG%Computername%.log"
ECHO.
ECHO. >> "%CD%LOG%Computername%.log"

:start
cls
if %c% LSS 1 exit
set /a id=1
set R=0

:Find
REM PF-Start
if "%id%" gtr "%c%" if %R% == 1 Goto Reindex 
if "%id%" gtr "%c%" timeout 60 && Goto start

For /F "tokens=1-3" %%a IN ('Dir "!m%id%!#msgs" /-C/S/A:-D') Do Set 2DirSize!id!=!DS!& Set DS=%%c
if "2DirSize!id!" == "" set 1DirSize!id!=!2DirSize%id%!

echo %id%
ECHO !m%id%!
echo Count        [ !1DirSize%id%! -- !2DirSize%id%! ]

if "!1DirSize%id%!" == "!2DirSize%id%!" ECHO Synk

REM DEL index.fld
if "!1DirSize%id%!" NEQ "!2DirSize%id%!" del /f /q !m%id%!index.fld && del /f /q !m%id%!indexlog.fld && del /f /q !m%id%!search.fld && set R=1 && ECHO RE-index Count && ECHO RE-index Count %Date% %Time% - Delete !m%id%! >> "%CD%LOG%Computername%.log"

set 1DirSize!id!=!2DirSize%id%!

ECHO.
ECHO.

set /a id+=1
goto Find

:Reindex
ECHO. >> "%CD%LOG%Computername%.log"
ECHO --- RE-INDEX - Start - %Date% %Time% --- >> "%CD%LOG%Computername%.log"
ECHO. >> ----------------------------------- >> "%CD%LOG%Computername%.log"
call PublicFolders.py
timeout 60
goto start

exit

Копія скрыпту запускаецца на кожным паштовым серверы (можна ў якасці службы, Адм правы не патрабуюцца)

Скрыпт чытае файл Setup%Computername%.List

Дзе %Computername% — імя бягучага сервера (Дырэкторыя можа змяшчаць адразу спісы ўсіх сервераў.)

Файл %Computername%.List – утрымоўвае поўныя шляхі якія сінхранізуюцца дырэкторый, кожны шлях запісаны ў новым радку, пустых радкоў утрымоўваць не павінен.

Пасля першага запуску скрыпт выконвае працэдуру індэксацыі, у не залежнасці неабходна яна ці не, таксама скрыпт стварае індэкс колькасці файлаў у кожнай з сінхранізаванай дырэкторыі.

Задача скрыпту зводзіцца да падліку ўсіх файлаў у паказанай дырэкторыі.

Па канчатку падліку кожнай дырэкторыі, калі хаця б у адной дырэкторыі бягучае значэнне файлаў, не супадае з папярэднім, скрыпт выдаляе файлы з каранёвай дырэкторыі сінхранізаванага паштовага каталога: index.fld, indexlog.fld, search.fld і запускае працэс індэксацыі - агульных паштовых тэчак.

У дырэкторыю LOG звальваецца інфармацыя аб выкананні задач.

Працэс індэксацыі
Працэс індэксацыі зводзіцца да выканання функцыі API Kerio
Session = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)

Прыклад выканання прыведзены на - python
PublicFolders.py

import json
import urllib.request
import http.cookiejar
""" Cookie storage is necessary for session handling """
jar = http.cookiejar.CookieJar()
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(jar))
urllib.request.install_opener(opener)
""" Hostname or ip address of your Kerio Control instance with protocol, port and credentials """

server = "http://127.0.0.1:4040"
username = "user"
password = "password"

def callMethod(method, params, token = None):
    """
    Remotely calls given method with given params.
    :param: method string with fully qualified method name
    :param: params dict with parameters of remotely called method
    :param: token CSRF token is always required except login method. Use method "Session.login" to obtain this token.
    """
    data =  {"method": method ,"id":1, "jsonrpc":"2.0", "params": params}

    req = urllib.request.Request(url = server + '/admin/api/jsonrpc/')
    req.add_header('Content-Type', 'application/json')
    if (token is not None):
        req.add_header('X-Token', token)    

    httpResponse = urllib.request.urlopen(req, json.dumps(data).encode())

    if (httpResponse.status == 200):
        body = httpResponse.read().decode()
        return json.loads(body)

session = callMethod("Session.login", {"userName":username, "password":password, "application":{"vendor":"Kerio", "name":"Control Api-Local", "version":"Python"}})
token = session["result"]["token"]
print (session)

session = callMethod("Domains.checkPublicFoldersIntegrity",{"domainId": "test2.local"}, token)
print (session)

callMethod("Session.logout",{}, token)

http://127.0.0.1:4040 можна пакінуць як ёсць, аднак калі вам патрабуецца HTTPS - python павінен давяраць сертыфікату Kerio.

Таксама ў файле неабходна пазначыць уліковы запіс з правамі на выкананне дадзенай функцыі (Адм – агульных паштовых тэчак) паштовага сервера.

Спадзяюся, мой артыкул будзе карысны адміністратарам Kerio Connect.

Крыніца: habr.com

Дадаць каментар