Эксплуатация плагинов: внедрение, ограничения, публикация
Эта страница поможет администратору выбрать подходящий тип плагина, настроить
реестры и подписи и опубликовать свой пакет. Пошаговая установка описана в
Плагинах, создание — в Написании плагинов.
Формы развёртывания
Выберите способ установки с учётом вашего развёртывания Mockarty:
- Один узел: загрузите
.zipв Администрирование → Плагины. Загрузка файла работает и с PostgreSQL, и с SQLite. - Кластер: используйте ту же страницу. Административные узлы разделяют установленные пакеты и их состояние, поэтому не нужно загружать файл на каждый узел. Перед включением плагина проверьте соединение узлов с общей базой данных и службой кластерных сообщений.
- Desktop: файл можно установить без сети. Для просмотра удалённого реестра нужно подключение к нему.
- Изолированная установка: загрузите локальный файл. Удалённый реестр необязателен и выключен, пока его не настроят.
Для управляемых нативных программ действуют дополнительные ограничения размещения: многоузловой кластер их отклоняет. Перед включением проверьте предварительный просмотр установки. Комплекты моков, контент и плагины WebAssembly в песочнице не требуют нативной программы.
Переменные окружения
| Переменная | По умолчанию | Эффект |
|---|---|---|
MOCKARTY_PLUGINS_ENABLED |
вкл | Рубильник. false / 0 / off убирает API, раздел UI и агентские тулы плагинов целиком. |
MOCKARTY_PLUGINS_REGISTRY_URL |
выключен | URL index.json реестра (например, GitHub raw URL или внутренний каталог). Если переменная не задана, внешний реестр отключён и запросов к нему нет. Укажите URL явно, чтобы включить каталог, или off, чтобы отключить источник, заданный в другом месте. |
MOCKARTY_PLUGINS_REGISTRY_ALLOW_HTTP |
выкл | Dev-режим: разрешает http:// download-ссылки только для loopback-хостов — автор плагина прогоняет полный цикл list→install против локального статического сервера. В продакшне не нужен. |
MOCKARTY_PLUGINS_REGISTRY_ALLOW_PRIVATE |
выкл | Корпоративный режим: реестр может жить в интранете (без доступа к GitHub) — приватные диапазоны и plain http:// допускаются только для клиента реестра. Cloud-metadata и link-local остаются заблокированы в любом случае. Используйте с внутренним статическим хостом, отдающим index.json + zip’ы. |
MOCKARTY_PLUGINS_TRUSTED_KEYS |
не задан | Base64-ключи ed25519 через запятую. Бандлы с подписью одного из них получают signatureStatus: trusted. |
MOCKARTY_PLUGINS_REQUIRE_SIGNATURE |
выкл | true — отказ устанавливать неподписанные бандлы и бандлы с недоверенной подписью (для регулируемых контуров). |
MOCKARTY_WIKI_IFRAME_ALLOWLIST |
не задан | (Wiki) ограничивает хосты для !iframe:-вставок; none запрещает внешние вставки. |
Политика установки в пространство
Может ли владелец пространства сам ставить no-code плагины в своё
пространство — это переключатель администратора в интерфейсе (Admin →
Plugins), а не переменная окружения: он меняет поведение продукта, поэтому
живёт там, где администратор включает его без передеплоя. По умолчанию ВЫКЛ.
Когда включено, владелец пространства может установить только no-code бандлы
(mock-киты, контент-паки, wiki-макросы, типы связей, пресеты коннекторов) из
видимого его пространству маркетплейса, с областью действия только внутри
этого пространства; WASM-модули, UI-панели, типы событий и типы задач
по-прежнему ставит администратор. Каждая установка аудируется
(plugin_ns_installed), и у администратора остаётся kill-switch — он видит и
может удалить плагины пространств в том же табе.
Жёсткие лимиты
Проверяются при установке и падают со структурным кодом ошибки; не
настраиваются:
| Лимит | Значение |
|---|---|
| Размер zip-бандла (сжатый) | 32 MiB |
| Файлов в бандле | 2000 |
| Распакованный объём всего / на файл | 64 MiB / 16 MiB |
| Вкладов на семейство (kits, packs, links, …) | 50 |
| Длина name / description | 200 / 4000 символов |
| Имя plugin task-type | префикс plugin-, ≤ 19 символов |
| Имя plugin event-type | префикс plugin. |
Модель безопасности (что плагин может и чего не может)
- Декларативные вклады (мок-киты, контент-паки, коннекторы, связи,
event/task-типы) — это данные. Хост сам их отрисовывает и применяет; они
ничего не исполняют. - Код исполняется только в WebAssembly-песочнице: без диска, сети, часов и
памяти хоста — с лимитами топлива, времени и памяти на вызов. Сломанный или
медленный модуль роняет только собственный вызов, никогда запрос или процесс. - UI-панели живут в sandboxed iframe со строгой Content-Security-Policy на
opaque origin: ни сессии хоста, ни cookie, ни доступа к DOM. Хост передаёт
панели её (несекретные) настройки черезpostMessage. - Загрузки пиннятся и охраняются. Установка из реестра сверяет sha256
бандла с индексом; установка по ссылке принимает опциональный sha256-пин; обе
идут через SSRF-защищённый HTTP-клиент, отвергающий loopback и приватные
адреса. - Секретов в манифесте не бывает. Коннектор-плагины поставляют шаблоны
конфигурации; учётные данные вводятся per-namespace в Настройки → Интеграции
и шифруются при хранении. - Мультитенантность: администратор устанавливает один раз; каждый
неймспейс независимо включает/выключает плагин и переопределяет его
настройки. Все каталоги и hot-path чтения фильтруются по неймспейсу. - Аудит: каждая установка, включение, выключение, удаление и
неймспейс-переключение попадает в журнал аудита с действующим пользователем.
Структурные коды ошибок
Ошибки плагин-API возвращают {"error": "<детали>", "code": "<стабильный код>"}.
UI показывает локализованное сообщение по коду; агенты и скрипты ветвятся по нему:
bundle_too_large, bundle_invalid, manifest_missing, manifest_invalid,
asset_missing, signature_invalid, host_incompatible,
contribution_conflict, not_found, storage_error, internal.
Публикация в реестр
Реестр — это статический index.json плюс скачиваемые zip’ы; эталонная
конфигурация — GitHub-репозиторий с Releases, но подойдёт любой статический
хостинг.
- Соберите и проверьте бандл:
mockarty-cli plugin pack ., затем
mockarty-cli plugin inspect <zip>. - Сгенерируйте запись индекса:
mockarty-cli plugin publish <zip> --download-url https://github.com/<org>/<repo>/releases/download/<id>-v<version>/<zip>
— команда печатает готовый JSON-объект с корректным sha256. - Загрузите zip как Release-ассет ровно по этому URL и добавьте объект в
массивpluginsфайлаindex.jsonрепозитория (в общем реестре — через
pull request). - Укажите серверам raw-URL индекса в
MOCKARTY_PLUGINS_REGISTRY_URL. Каталог
появится в Админ → Плагины; установка сверит sha256.
Дайджест — это дайджест того файла, который вы загружаете, а не заново
упакованного исходника. Повторная упаковка одного и того же плагина может
дать другие байты: архив хранит mtime и права файлов, а компрессор зависит от
сборки. Поэтому sha256, снятый с бандла, собранного на вашей машине, может не
совпасть с артефактом в релизе — и установка будет отклонена с ошибкой
downloaded bundle sha256 … does not match the registry index. Берите дайджест
у того файла, который реально публикуете (mockarty-cli plugin publish <загруженный.zip>его печатает), и перезапускайте публикацию записи всякий раз,
когда заменяете ассет.
Обновление версии — по месту: публикация 1.1.0 и установка поверх 1.0.0
сохраняет состояние «включён» и атомарно меняет вклады.
Kill-switch возможностей
Всё, что вносит плагин или внешняя интеграция — компоненты миссий, типы
задач раннера — перечислено в едином каталоге возможностей
(GET /api/v1/capabilities) рядом со встроенными. Когда динамическую
возможность нужно погасить немедленно — скомпрометированный поставщик,
некорректно ведущая себя интеграция — администратор открывает Автономные
миссии → Возможности и нажимает Отключить. Для автоматизации та же
операция доступна одним вызовом:
curl -X POST "$MOCKARTY_URL/api/v1/capabilities/<key>/revoke" \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"reason": "ключ поставщика скомпрометирован"}'
Причина обязательна и показывается везде, где возможность появилась бы.
Одного вызова достаточно:
- возможность становится недоступной в каталоге:
availability.reason: "revoked"и ваша причина вrevokedReason— и
человек, и агент видят, почему, прежде чем строить планы вокруг неё; - управляемые оператором строки содержат
operatorManaged: true,
managementKeyи точныйmanagementNamespace; интерфейс миссий использует
эту устойчивую идентичность для отключения и восстановления, не угадывая её
по отображаемому фасету и не смешивая локальную строку пространства с
политикой всего инстанса; - если возможность пришла из плагина, этот плагин выключается на всех узлах
тем же вызовом (ответ называет его вsourceDisabled); - переустановка или повторное включение источника не воскрешает
возможность — попытка завершается ошибкойcontribution_conflictс
сохранённой причиной, пока запрет не снят явно.
Операция работает fail-closed. Если Mockarty не может выключить источник
плагина либо прочитать/сохранить устойчивое состояние kill-switch, он
возвращает 503 и не заявляет об успешном запрете, пока исполняемые вклады
могут оставаться активными. После восстановления базы/хранилища плагинов
повторите вызов; уже выключенный плагин во время повтора остаётся выключенным.
Снятие запрета — осознанное решение из двух шагов:
POST /api/v1/capabilities/<key>/restore убирает отметку, а
плагин-источник всё равно нужно включить вручную. Внешние возможности,
зарегистрированные, но не исполняемые на этом сервере, отображаются в
каталоге с availability.reason: "declared" — видны для планирования, но
не являются обещанием исполнения. Администратор также может зарегистрировать
такую строку через Автономные миссии → Возможности → Зарегистрировать.
Все три операции доступны только администратору и попадают в журнал аудита.
Диагностика
- Плагин установлен, но ничего не появилось — он специально
устанавливается выключенным; нажмите Включить. Если включён и всё равно не
виден в неймспейсе — проверьте неймспейс-переключатель (Админ → Плагины →
Включить здесь) и флагdefault_offплагина. healthy: falseв статусе плагина — узел не смог применить вклад (чаще
всего WASM-модуль собран под WASI вместоwasm-unknown, либо конфликт ключа
с другим плагином). Причина — в логе сервера.- Список реестра пуст — это ожидаемо, пока не задан
MOCKARTY_PLUGINS_REGISTRY_URLили не добавлен управляемый оператором источник.
Если источник настроен, индекс может быть недоступен или не пройти валидацию. Ответ API во всех
случаях содержит подсказку: адрес источника проверяется ещё при добавлении, а
«дошли, но это не реестр» отдаётся как 400, а не 502. - Установка по ссылке падает с
bundle_invalid— URL должен быть http(s)
и доступен без обращения к приватным адресам; закрепите sha256, чтобы
исключить повреждённую загрузку.