Коротко. Model API — REST-интерфейс к модели системы на порту 8443, только по mTLS: без клиентского сертификата сервер отвечает 400 сразу, и это норма. Чтение — GET /model/<сущность>/, изменение — PUT документа или его поля, после чего запускается задача configure. Латентность API — быстрый индикатор здоровья: миллисекунды в норме, десятки секунд означают, что модель ждёт mongod, а не «медленный GUI».
1. Что это и как устроено
Модель — база описания системы: машины, сети, диски, колонки, окружение, приложения, правила конфигурации. Продукт не хранит конфиги «руками»: он рендерит файлы служб из модели. Поэтому изменение через Model API — штатный путь, а правка файла на диске будет перезаписана при следующем применении конфигурации.
Схема запроса:
клиент → nginx :8443 (mTLS) → Model API → mongod (management_model)
Три модели данных живут в отдельных кластерах mongod: management_model (основная),
environment_data (окружение) и federated_model (федерация). Порты 27017/27018/27019
соответствуют им; путать кластеры нельзя — это разные базы.
2. Доступ: mTLS и сертификаты
- Порт —
8443, TLS обязателен, клиентский сертификат обязателен. - Сертификаты продукта лежат в каталоге mTLS-конфигурации:
machine.certиmachine.key. Они root-only, поэтому запрос от обычного пользователя даётHTTP 000— TLS просто не поднимается. Все вызовы с узла — черезsudo. - Каталог сертификатов версионируется (
ssl.<hash>, рядом симлинкssl): путь берётся через симлинк, хеш не хардкодится. - Без клиентского сертификата ответ
400приходит мгновенно — это признак того, что служба жива и правильно настроена, а не ошибка.
Проверка живости (на узле, root):
sudo curl -sk https://127.0.0.1:8443/ -o /dev/null -w '%{http_code}\n'
Ожидается 400. Если 000 — TLS не поднялся (нет прав на сертификат) либо служба не слушает.
Рабочий вызов:
cd "$(ls -dt /opt/ampli/cfg/marvin/ssl* | head -1)"
sudo curl -sk --cert machine.cert --key machine.key \
https://127.0.0.1:8443/model/machine/ | jq '.machine[] | {name, role, status}'
3. Адресация сущностей
Путь строится как /model/<сущность>/ или /model/<сущность>/<guid>/. Основные сущности:
| Сущность | Что содержит |
|---|---|
machine |
узлы: роль, статус, hardwaretype, rackunit, приложения |
column |
колонки хранения, статус, размеченная ёмкость (resources) |
disk |
диски, привязка к полкам/слотам |
location |
локации: стойка, площадка; серийный номер стойки |
networkswitch |
коммутаторы, участвующие в топологии |
environment |
окружение: выбранная политика, параметры модели |
configrule |
правила, из которых рендерятся конфиги служб |
task |
задачи: статус, прогресс, ошибки |
taskschedule |
периодические задачи: enabled, last_run_at |
Вложенные объекты адресуются через родителя: NIC — /model/machine/<MGUID>/nic/<NGUID>/,
действия — /model/<сущность>/<guid>/action/<имя>/.
Ответ на коллекцию — JSON-объект с ключом, равным имени сущности ({"machine": [...]}), а не
голый массив. GET без limit на больших коллекциях может быть тяжёлым (см. §6).
4. GET, PUT и типовые коды
Чтение. GET /model/<сущность>/ или /model/<сущность>/<guid>/. Ничего не меняет.
Запись. PUT документа целиком либо отдельного поля:
PUT /model/machine/<guid>/ телом {"rackunit": 12}; для backend-машины —
PUT /model/column/<cg>/action/proxy/machine/<mg>/.
Типовые ответы и их смысл:
| Код | Причина | Что делать |
|---|---|---|
200 |
принято | проверить документ повторным GET |
400 |
нет клиентского сертификата, либо нет Content-Type: application/json |
добавить сертификат и заголовок |
423 LOCKED |
висит незавершённая задача на этом объекте | снять задачу, см. §5 |
503 |
клиент не видит PRIMARY mongod («no replica set members match Primary()») | повторить запрос или переждать транзиент |
500 |
ошибка схемы/валидации значения | сверить допустимые значения поля с живым документом |
Заголовок Content-Type: application/json обязателен: без него PUT отвечает 400, и это
самая частая «ошибка модели», которой на самом деле нет.
Значения полей не угадываются. Например, category политики хранения — жёсткий список
(balanced, lower_overhead, lowest_overhead, 2site_replicated, custom); своё имя вроде
balanced-8 даёт 500 ValidationError. Своя политика создаётся в слоте custom, а схема полей
читается из живого документа. Подробнее — Формула политики DSS.
5. Задачи: как изменение становится применённым
PUT в модель — это только новое описание. Чтобы оно дошло до служб, запускается задача
configure:
sudo curl -sk --cert machine.cert --key machine.key \
-X POST -H "Content-Type: application/json" \
-d '{"targets": "<MGUID>"}' \
https://127.0.0.1:8443/model/machine/<MGUID>/nic/<NGUID>/action/configure/
Ответ содержит объект task с полем guid. Дальше задача читается по guid:
GET /model/task/<guid>/. Ожидаемые статусы — QUEUED, STARTED, SUCCESS; ошибочные —
FAILURE, REVOKED. «Залипшая» задача в STARTED держит блокировку и приводит к 423 LOCKED
на следующих изменениях; её снимают штатным действием terminate:
sudo curl -sk --cert machine.cert --key machine.key \
-X POST https://127.0.0.1:8443/model/task/<guid>/action/terminate/
Периодические задачи (taskschedule) — отдельная история. Оборванный install-ng оставляет
column_bucket_update, logs_pruner, reconcile_federateddata выключенными: он выключает их
на старте и включает только в самом конце успешного прогона. Признак — пустая витрина
durability и «не дозревающие» метрики. Точечное включение — тот же вызов, что делает продукт:
PUT /model/taskschedule/<guid>/enabled/True.
6. Латентность модели: главный диагностический признак
Латентность GET — самый быстрый способ отличить «модель думает» от «UI врёт»:
| Наблюдение | Значение |
|---|---|
| Норма на здоровом кластере | десятки миллисекунд |
| Точечное чтение задачи по guid | 0.1–0.4 с |
| Модель ждёт mongod (например, после потери питания) | порядка 30 с вместо ~20 мс |
Полный GET /model/task/ без limit при раздутой истории |
порядка 27 с и десятки МБ |
Два последних случая — разные. Первый означает, что модель не получила базу: пока mongod не
поднялся, GUI выглядит как «не принимает пароль», а API отвечает медленно (разбор —
GUI «не принимает пароль» и
mongod не поднялся). Второй — просто
раздутая история задач: продукт читает задачи по guid и с limit, полный список в горячий путь
не входит, поэтому «распухшие» задачи сами по себе установку не ломают. Уборка — штатная:
уменьшить retention_config в документе environment (число дней хранения) и дать пройти
периодической задаче очистки.
7. Границы и правила
- Только штатные сущности. Правка mongod напрямую — не путь: модель кэширует и валидирует, прямой документ разойдётся со схемой.
- Файлы служб не править. Продукт рендерит их из
configrule; ручная правка исчезнет при следующемconfigure. Сертификаты S3/GUI — тоже через модель, см. S3-домен и сертификат. - Бэкап до изменения. Сохранить текущий документ (
GET) и правило (configrule) вне каталогов продукта. - Читать перед записью. Смотреть живой документ, а не предполагать формат:
settingsу правил бывает массивом по узлам, а не объектом. - Не путать
400с поломкой. Мгновенный400без серта — норма mTLS.
Читать модель без curl удобнее через консоль: cli.ha.get('/model/...') возвращает строку JSON,
которую надо разобрать. См. CLI sherpa.
8. Источники
- Quantum Software Documentation Center (7.3) (2026-11-07)
- ActiveScale Z200 datasheet — REST API в перечне интерфейсов управления
- Наша практика (обезличенно): mTLS-вызовы,
PUT/POSTи задачи проверены на кластере из трёх нод, ActiveScale 7.3.1.2; латентность ~30 с против ~20 мс наблюдалась после полной потери питания, пока mongod не поднялся; полный список задач — 27 с / ~40 МБ при раздутой истории. - Обновлено: 2026-11-07.