ВЫ ИСПОЛЬЗУЕТЕ МЕХАНИЗМ СКРИПТОВ, КОТОРЫЙ ЗАПУСКАЕТСЯ ОТ ИМЕНИ ROOT БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ,
НА ВАШЕ УСМОТРЕНИЕ. ЛИЦЕНЗИАР ЯВНО ОТКАЗЫВАЕТСЯ ОТ ВСЕХ ГАРАНТИЙ, ЯВНЫХ, ПОДРАЗУМЕВАЕМЫХ ИЛИ
УСТАНОВЛЕННЫХ ЗАКОНОДАТЕЛЬСТВОМ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ПОДРАЗУМЕВАЕМЫМИ ГАРАНТИЯМИ ТОВАРНОЙ ПРИГОДНОСТИ, ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ И НЕНАРУШЕНИЯ ПРАВ.
В ПОЛНОЙ МЕРЕ, РАЗРЕШЕННОЙ ЗАКОНОМ, ЛИЦЕНЗИАР НЕ НЕСЕТ ОТВЕТСТВЕННОСТИ ЗА КОСВЕННЫЕ, СЛУЧАЙНЫЕ,
СПЕЦИАЛЬНЫЕ, ПОСЛЕДУЮЩИЕ УБЫТКИ ИЛИ УБЫТКИ В ВИДЕ УПУЩЕННОЙ ВЫГОДЫ ИЛИ ВЫРУЧКИ, ВОЗНИКШИЕ ВСЛЕДСТВИЕ ИЛИ СВЯЗАННЫЕ С ДАННЫМ СОГЛАШЕНИЕМ ИЛИ ВАШИМ ИСПОЛЬЗОВАНИЕМ МЕХАНИЗМА.
Введение
Движок скриптов позволяет вам писать и использовать произвольный код Python для запуска автоматизаций,
инициируемых событием, по расписанию или даже вручную пользователем через веб-форму.
Загружать скрипты и настраивать их запуск через Веб-форму, Действия по событию, Действия по расписанию могут администраторы системы в разделе Настройки > Автоматизация и маршрутизация > Скрипты
Вопросы безопасности и производительности
Скрипты выполняются внутри контейнера, поэтому у них нет доступа к аппаратному узлу / виртуальной машине,
на которой установлена Swarmica.
Однако сценарии имеют доступ к общим разделам диска и основной базе данных, используемой Swarmica,
поэтому будьте осторожны при выполнении потенциально опасных операций, таких как удаление и изменение
любых данных или файлов.
Кроме того, ресурсы памяти/процессора используются совместно со всем инсталляцией Swarmica, поэтому
настоятельно рекомендуется минимизировать импорт библиотек и модулей до только необходимого
минимального набора функций.
Например, вместо импорта всего модуля import datetime импортируйте только необходимую вам функцию:
from datetime import timedelta.
Обзор движка времени выполнения
Есть несколько способов запуска сценария:
[Триггер события] ---> +context --\
\
[Расписание] --------> +context----\
>----> Runner.run(kwargs={data: **params, **context})
[CLI] -------------> +params-------/
/
[API/WEB] ---------> +params-----/
Итак, в основном, если сценарий времени выполнения запускается Триггером События или по Расписанию,
то данные события и пользовательские контекстные данные, настроенные в соответствующем триггере /
расписании, передаются в параметры сценария.
Допустим, сценарий запускается событием UserEvent, тогда контекст можно разобрать следующим образом:
class Runner(BaseRunner):
def run(self, *args, **kwargs):
data = kwargs.get('data', {})
if not data or 'event_id' not in data:
logger.error(f"No event_id passed, exiting")
return
event = UserEvent.objects.filter(id=data['event_id']).first()
if not event:
logger.error(f"No event with {data['event_id']} found, exiting")
return
Если мы настроим Триггер События на передачу дополнительного контекста в скрипт, например, списка
email-адресов для получения оповещения при изменении учетной записи пользователя, то он также будет
передан в скрипт.
При условии, что пользовательский контекст Триггера События выглядит так:
{
"recipients": [
"user1@domain.tld",
"user2@domain.tld"
]
}
Теперь вы можете получить доступ к значению переменной внутри скрипта следующим образом:
data = kwargs.get('data', None)
if data:
recipients = data.get('recipients', None)
Вы также можете настроить скрипт так, чтобы у него была собственная веб-форма, которая может принимать,
проверять и передавать параметры в скрипт.
Допустим, мы пишем скрипт, который генерирует пользовательский отчет в Excel и отправляет его списку
email-получателей. И мы хотим, чтобы пользователи передавали даты начала и окончания отчета и список
получателей, разделенный запятыми.
В веб-интерфейсе Swarmica в настройках скрипта мы настраиваем следующие параметры веб-формы:
[
{
"name": "start_date",
"type": "datetime",
"readonly": false,
"displayName": "Report start date"
},
{
"name": "end_date",
"type": "datetime",
"readonly": false,
"displayName": "Report end date"
},
{
"name": "recipients",
"type": "text",
"displayName": "Comma-separated recipients"
}
]
Теперь мы можем получить доступ к этим параметрам в скрипта следующим образом:
params = kwargs.get('data', {})
if params:
if 'recipients' in params:
recipients = params.get('recipients')
if recipients:
recipients = [x.strip() for x in recipients.split(',') if '@' in x]
if not recipients:
logger.info("Input error: empty/invalid list of 'recipients' specified")
return
start_date = params.get('start_date', None)
if isinstance(start_date, str) and start_date.strip():
report_start_date = parse_datetime(start_date)
end_date = params.get('end_date', None)
if isinstance(end_date, str) and end_date.strip():
report_end_date = parse_datetime(end_date)
if not report_end_date:
report_end_date = now().replace(hour=23, minute=30, second=0, microsecond=0).replace(tzinfo=default_time_zone)
if not report_start_date:
report_start_date = report_end_date - timedelta(days=1)
Доступ к объектам Swarmica
Обычно вам нужно манипулировать моделями и наборами запросов (querysets) для объектов Swarmica в
ваших скриптах.
Поскольку Swarmica использует Django в качестве фреймворка, большинство методов моделей и наборов
запросов также работают здесь.
Смотрите полную справку по методам моделей Django и наборов запросов на официальном сайте документации:
Большинство объектов, которые вам могут понадобиться, находятся в пакете core, за исключением объектов
User - они находятся в пакете swarmica_auth.
Также вам, как правило, потребуется импортировать общие константы, используемые Swarmica,
следующим образом:
from swarmica import defs
print(defs.USER_ROLES_INTERNAL)
Давайте рассмотрим некоторые типичные операции в действии.
Работа с набором Заявок (Tickets)
Давайте выведем ID заявки, тему и имя назначенного исполнителя для всех новых и открытых заявок,
созданных между указанными датами начала и окончания:
from swarmica import defs
from core.models import Ticket
class Runner(BaseRunner):
def run(self, *args, **kwargs):
params = kwargs.get('data', {})
if not params:
return
start_date = params.get('start_date', None)
if isinstance(start_date, str) and start_date.strip():
report_start_date = parse_datetime(start_date)
end_date = params.get('end_date', None)
if isinstance(end_date, str) and end_date.strip():
report_end_date = parse_datetime(end_date)
if not report_end_date:
report_end_date = now().replace(hour=23, minute=30, second=0, microsecond=0).replace(tzinfo=default_time_zone)
if not report_start_date:
report_start_date = report_end_date - timedelta(days=1)
tickets = Ticket.objects.filter(created_at__range=(report_start_date,report_end_date),
status__in=[defs.TICKET_STATUSES_NEW, defs.TICKET_STATUSES_OPEN])
for ticket in ticket:
print(f"#{ticket.id}: {ticket.subject} ({ticket.assignee.name})")
Работа с Пользователями
Давайте отключим все email-уведомления для заблокированных пользователей:
from swarmica import defs
from swarmica_auth.models import User
class Runner(BaseRunner):
def run(self, *args, **kwargs):
users = User.objects.filter(role=defs.USER_ROLES_BLOCKED)
for user in users:
user.email_notifications.clear()
Доступные сторонние библиотеки:
Ряд предустановленных библиотек доступен для импорта и использования в ваших скриптах.
Смотрите список доступных методов в документации соответствующей библиотеки:
import re # Для работы с регулярными выражениями
import os # Для работы с вещами ОС, такими как пути к файлам и т.д.
import bs4 # Для парсинга HTML, XML и т.д. с помощью BeautifulSoup
import csv # Для чтения и записи CSV
import json # Для парсинга JSON
import time # Для работы с текущим временем, например, генерации временных меток
import pandas # Для работы с наборами данных
import urllib # Для парсинга и записи параметров URL, urlencode и т.д.
import dateutil # Для работы с датами, например, парсинга даты из строки
import datetime # Для работы с объектами datetime, например, вычисления длительностей и т.д.
import openpyxl # Для чтения и записи Excel
import requests # Для работы с удаленными API и вебхуками