В прошлой статье я рассказывал о том, какможно использовать командный интерфейс CommuniGate Pro. Там же я отметил, что у этого инструмента нет возможность конвеерной передачи команд (например, pipeline в PowerShell или Bash). Покопавшись в документации я наткнулся на модуль Python для CommuniGate Pro. Этот модуль в каком-то роде позволяет обойти это ограничение и предлагает немного больше гибкости в работе с назовем его API CGP.
В этой публикации я постараюсь рассказать и наглядно показать основы работы с модулем Python.
Зачем нужен модуль Python для CommuniGate Pro
Как я уже сказал у стандартного командного интерфейс CommuniGate Pro отсутствует возможность конвейерной передачи вывода одной команды на вход другой команды (pipeline). Например, такой подход я крайне часто использую в сценариях PowerShell. Используя модуль Python для CGP вы можете обойти этот недостаток. К тому, если вы знакомы с Python, то вы будите чувствовать себя гораздо увереннее. Например, сможете написать нужные вам сценарии на языке Python.
Единственный нюанс – на момент подготовки статьи модуль Python последний раз обновлялся в октябре 2021 года. Есть вероятность, что он может не содержать все поддерживаемых команд, которые есть в командном интерфейсе CGP.
Установка модуля
Для установки модуля необходим Python версии 3.6 или новее.
Посмотреть версию Python можно следующей командой:
python3 --version
Установка модуля CGPCLI довольно тривиальная операция, если у вас уже установлен Python:
pip install CGPCLI
Если при выполнении команды выше вы получаете ошибку вида:
Command 'pip' not found, but can be installed with:
sudo apt install python3-pip
Значит у вас не установлен модуль pip. Установить его можно командой из подсказки:
sudo apt install python3-pip
После установки модуля pip повторно запустите установку модуля CGPCLI.
Базовый пример
Поскольку блок кода для импорта необходимых объектов и подключения к серверу CommuniGate Pro бдует идентичен для всех примеров, то я вынесу его в отдельный раздел.
В последующих примерах я буду опускать строки кода по импорту объектов и подключения/отключения к серверу.
Базовый пример выглядит следующим образом:
# Импорт класса Servdr
from CGPCLI import Server
# Создаем объект типа Server, где в качестве параметра передаем имя или IP-адрес сервера CommuniGate Pro
server = Server('10.10.10.154')
# Выполняем подключение к серверу
server.connect()
# Аутентифицируемся на сервере. Методу login в качестве параметров передаются логин и пароль пользователя, от имени которого необходимо выполнить аутентификацию
server.login('postmaster', 'Qwerty123')
# Один из поддерживаемых методов - get_account_info. Этот метод выводим информацию по текущему пользователю. Встроенная команда print выводит строковое представление вывода команды get_account_info
print(server.get_account_info('*'))
# Завершаем нашу сессию на сервере CommuniGate Pro
server.disconnect()
Пример вывода скрипта:
{'header': '201', 'body': {'Created': '19-07-2022_23:23:06', 'DeviceTokens': {'fjNEyX5eTdigSslSN0dcBo:APA91bFCxo7cnUTRCYTVmKCCed0ducdSzcM-lQZqdg1wwu_bAfpESlvf8FEWPytqJk0U4F5imZyIkamytlzwtzhbThdDxeIWQ65uyhi-qieaqJR2pn9CSFRDkQbnAVBHnNviKMXxzWgN': {'Date': datetime.datetime(2022, 8, 7, 7, 0, 14), 'appName': 'samoware-android', 'type': 'FCM'}}, 'FileCache': {}, 'FileCacheTime': datetime.datetime(2022, 7, 23, 0, 37, 26), 'IncomingFlow': '1-20220724130957', 'LastAddress': '[10.10.10.40]', 'LastLogin': datetime.datetime(2022, 11, 4, 15, 6, 10), 'LastNamedSession': datetime.datetime(2022, 8, 7, 7, 7, 14), 'MailboxSeq': 1658278, 'OutgoingFlow': '1-20220724131007', 'OutgoingFlowRcpt': '1-20220724131007', 'PrevLogin': datetime.datetime(2022, 11, 4, 6, 43, 1), 'PrevLoginAddress': '[10.10.10.44]', 'SplitInfoFile': 'YES', 'StorageUsed': '2885'}}
Как видно из вывода мы получаем тип структуры данных словарь. Отмечу, что нас интересует только секция Body. Если вам будет удобнее, то можете в ответе выводить только секцию body. Например:
pprint.pprint(accounts.get('body'))
Вы можете немного модифицировав код (используя модуль pprint) сделать вывод немного более удобочитаемым:
from CGPCLI import Server
import pprint
server = Server('10.10.10.154')
server.connect()
server.login('postmaster', 'Qwerty123')
pprint.pprint(server.get_account_info('*'))
server.disconnect()
Пример вывода при использовании модулья pprint:
{'body': {'Created': '19-07-2022_23:23:06',
'DeviceTokens': {'fjNEyX5eTdigSslSN0dcBo:APA91bFCxo7cnUTRCYTVmKCCed0ducdSzcM-lQZqdg1wwu_bAfpESlvf8FEWPytqJk0U4F5imZyIkamytlzwtzhbThdDxeIWQ65uyhi-qieaqJR2pn9CSFRDkQbnAVBHnNviKMXxzWgN': {'Date': datetime.datetime(2022, 8, 7, 7, 0, 14),
'appName': 'samoware-android',
'type': 'FCM'}},
'FileCache': {},
'FileCacheTime': datetime.datetime(2022, 7, 23, 0, 37, 26),
'IncomingFlow': '1-20220724130957',
'LastAddress': '[10.10.10.40]',
'LastLogin': datetime.datetime(2022, 11, 4, 15, 21, 43),
'LastNamedSession': datetime.datetime(2022, 8, 7, 7, 7, 14),
'MailboxSeq': 1658278,
'OutgoingFlow': '1-20220724131007',
'OutgoingFlowRcpt': '1-20220724131007',
'PrevLogin': datetime.datetime(2022, 11, 4, 15, 6, 10),
'PrevLoginAddress': '[10.10.10.40]',
'SplitInfoFile': 'YES',
'StorageUsed': '2885'},
'header': '201'}
Примеры использования модуля Python
Возьмем пару примеров из предыдущей публикации про использование командного интерфейса CGP.
Получение списка пользователей
Начнем с простого. Получим список всех пользователей.
pprint.pprint(server.list_accounts())
Пример вывода команды:
{'body': {'adm': 'macnt',
'pbx': 'macnt',
'pf01mig': 'macnt',
'pf02mig': 'macnt',
'postmaster': 'macnt',
'public': 'macnt',
'u1': 'macnt',
'u2': 'macnt',
'u3': 'macnt',
'u4': 'macnt',
'u5': 'macnt',
'u6': 'macnt',
'u7': 'macnt',
'uu1': 'macnt'},
'header': '201'}
Получение подробной информации о конкретном пользователе
Теперь давайте попробуем получить информацию о конкретном пользователе:
pprint.pprint(server.get_account_effective_settings('u6'))
Пример вывода команды:
{'body': {'AccessModes': 'All',
'AddMailpprint.pprint(accounts.get('body'))Trailer': 'YES',
'AddWebBanner': 'YES',
'AirSyncAllowed': '*',
'AirSyncSessionLimit': '10',
'ArchiveMessagesAfter': 'never',
'AuthURI': 'ldaps://dc01.itproblog.ru:636/*@itproblog.ru',
'CallInpFlow': ['-1', '3600'],
'CallLogs': 'YES',
'CallOutFlow': ['-1', '3600'],
'CallsLimit': '-1',
'DefaultMailboxType': 'SlicedMailbox',
'DefaultWebPage': 'default.html',
'DeleteMessagesAfter': 'never',
'DialogInfo': 'YES',
'DialogToPresence': 'NO',
'EncryptedMailboxesAllowed': 'NO',
'EraseDeletedMessages': 'NO',
'ExtPassTTL': 'immediately',
'ExtRcptTo': '*',
'ExternalINBOX': 'NO',
'FailedLoginFlow': ['10', '60'],
'HiddenLanguages': '',
'HiddenSkins': '',
'HiddenXIMSSModules': '',
'IMAPSeesNonMail': 'NO',
'IMAPSessionLimit': '20',
'IMLogs': 'YES',
'LogLogin': 'NO',
'LogProtocols': 'NO',
'MailInpFlow': ['20', '15'],
'MailOutFlow': ['-1', '30'],
'MailOutFlowRcpt': ['-1', '30'],
'MailOutMaxRcpt': '20',
'MailToAll': 'YES',
'MaxAccountSize': 'unlimited',
'MaxFileSize': 'unlimited',
'MaxMailOutSize': 'unlimited',
'MaxMailboxes': '-1',
'MaxMessageSize': 'unlimited',
'MaxRosterItems': '20',
'MaxSignalContacts': '10',
'MaxWebFiles': '1000',
'MaxWebSize': '100M',
'NotifyOutFlow': ['100', '15'],
'OSUserName': '*',
'POPSessionFlow': ['5', '300'],
'POPSessionLimit': '5',
'PSTNAreaCode': '7(499)',
'PSTNEmergency': 'call=sip:112@telnum',
'PSTNFromName': '$',
'PSTNGatewayAuthName': 'trial-*domain*',
'PSTNGatewayDomain': 'pstn.communigate.ru',
'PSTNGatewayPassword': 'dummy',
'PSTNSMSHost': '',
'PWDAllowed': 'YES',
'Password': '\\001Dpvgpj8)9',
'PasswordChangeInterval': 'never',
'PasswordComplexity': '',
'PasswordEncryption': 'A-crpt',
'PasswordMinLength': '6',
'PasswordRecovery': 'YES',
'QuotaAlert': '80',
'QuotaNotice': '90',
'QuotaSuspend': '100',
'RPOPAllowed': 'NO',
'RSIPAllowed': 'NO',
'RealName': 'u6',
'RequireAPOP': 'NO',
'RestrictFromAddr': '',
'RestrictFromName': '',
'RulesAllowed': 'Filter Only',
'SIPIMMode': 'YES',
'SignalRulesAllowed': 'Any',
'SyncMode': 'NO',
'SyncServer': '',
'SyncUserName': '^0',
'SyncUserPassword': '^0',
'UBFactor': '5',
'UseAppPassword': 'YES',
'UseCertificateAuth': 'NO',
'UseExtPassword': 'NO',
'UseKerberosPassword': 'YES',
'UseSysPassword': 'NO',
'WebUserSessionLimit': '10',
'X2AuthCoolout': '1d',
'X2AuthForAll': 'NO',
'X2AuthForWebUser': 'NO',
'X2AuthForXIMSS': 'NO',
'XIMSSSessionLimit': '10',
'XMPPSessionLimit': '10'},
'header': '201'}
Получить список настроенных доменов на сервере
Пример запроса:
pprint.pprint(server.list_domains())
Пример ответа от сервера:
{'body': ['itproblog.ru'], 'header': '201'}
Обновление пароля пользователя
Пример запроса:
pprint.pprint(server.set_account_password('u6','Qwerty123'))
Отчет сервера
{'body': 'OK', 'header': '200'}
Создание пользователя
Теперь попробуем создать нового пользователя. Эта операция составная, т.е. сначала нам потребует создать пользователя, а затем установить пароль для этого пользователя:
pprint.pprint(server.create_account('u8'))
pprint.pprint(server.set_account_password('u8','Qwerty123'))
Сервер два раза отправляет нам подтверждение о том, что команда была выполнена успешно:
{'body': 'OK', 'header': '200'}
{'body': 'OK', 'header': '200'}
Пример массовой операции через модуль Python для CommuniGate
А теперь о самом главном. О том, чего не хватало в командном интерфейсе CGP – pipeline. Непосредственно пайплайна у модуля Python для CGP нет, но поскольку здесь мы уже работаем с полноценными объектами, то мы можем использовать все возможности языка. Например, давайте массово обновим пароль для всех пользователей CommuniGate Pro.
Полный текст скрипта для массового обновления пароля будет примерно следующий:
from CGPCLI import Server
import pprint
server = Server('10.10.10.154')
server.connect()
server.login('postmaster', 'Qwerty123')
# Сначала получаем перечень учетных записей. Из ответа сервера возвращаем только секцию body
accounts = server.list_accounts().get('body')
# В цикле обходим каждую учетную запись и устанавливаем новый пароль для неё. Поскольку переменная accounts это словарь, то через цикл for мы можем обойти все её ключи. В ключах как раз хранятся имена пользователей
for account in accounts:
server.set_account_password(account,'Qwerty123')
server.disconnect()
В целом вы можете эту же операцию проделать и в Bash, но, как по мне, в Python эта операция выполняется немного удобнее. Тут дело вкуса.
Вместо заключения
Если вам интересно программирование CGP более сложное, чем Python, то есть еще вариант – CG/PL. Это уже более сложный материал, но он гораздо более мощный, чем модуль Python для CGP.