Appearance
Command Manager
Назначение
Централизованный сервис управления командами (исполняемыми единицами работ), коллекциями, диспетчеризацией задач на удалённые раннеры, отслеживанием выполнения с логами и артефактами.
Порты
| Порт | Назначение |
|---|---|
| 8094 | HTTP REST API |
| — | gRPC (для подключения раннеров) |
- БД:
command_manager_db
Ключевые возможности
- CRUD команд с типизированными переменными:
string,number,boolean,date,datetime,array,object - Вложенные коллекции (папки команд с деревевидной структурой)
- Шаринг команд и коллекций с ролями
admin/user/viewerчерезservice-common/sharing - Условные значения переменных (Grule Rule Engine) — см. раздел Условия переменных
- Система задач: создание → очередь
MemoryTask→ диспетчеризация → выполнение - gRPC bidirectional streaming для связи с раннерами (Hello/Pong хендшейк)
- Управление CLI Агентами (
ush connect): подключение серверов, сбор телеметрии, интерактивный веб-терминал, SSH-провижининг и экспорт артефактов из Flow Manager - Tag-based matching: команды и раннеры матчатся по тегам
- Логи и артефакты задач
- Swagger UI:
/swagger/index.html
Условия переменных
Каждая переменная команды может иметь поле conditions — строку с выражением на Grule Rule Engine. Условие определяет, когда данное значение переменной применяется. Вычисляется на стороне сервера при вызове CheckCondition / ValidateCondition.
Как это работает
- При оценке условия переменной значение передаётся как переменная
valueв контекст Grule - Условие подставляется в шаблон правила:
when <condition> then CM.Result = true - Если выражение вычисляется как
true— результатtrue, иначеfalse
Доступные переменные в выражении
| Переменная | Тип | Описание |
|---|---|---|
value | any | Текущее значение переменной, переданное при проверке |
CM | struct | Внутренний объект (с полем Result), не использовать напрямую |
Операторы
| Категория | Операторы |
|---|---|
| Сравнение | ==, !=, >, <, >=, <= |
| Логические | &&, ||, ! |
| Арифметические | +, -, *, /, % |
Примеры условий
Числовые сравнения
grule
value > 10grule
value >= 100grule
value < 50grule
value == 0grule
value != -1Строковые сравнения
grule
value == "approved"grule
value != "pending"grule
value == "production"Логические комбинации
grule
value > 0 && value < 100grule
value == "active" || value == "pending"grule
value != "" && value != "none"grule
!(value == "disabled")Булевы значения
grule
value == truegrule
value == falseAPI для работы с условиями
POST /api/v1/commands/conditions/check
Проверяет выражение условия на валидность синтаксиса (без привязки к переменной).
Request:
json
{
"condition": "value > 10"
}Response:
json
{
"success": true,
"data": true
}POST /api/v1/commands/conditions/validate
Проверяет, вычисляется ли условие как true для переданного значения.
Request:
json
{
"condition": "value == \"approved\"",
"value": "approved"
}Response:
json
{
"success": true,
"data": true
}Пример с числом:
json
{
"condition": "value > 100",
"value": 250
}→ true
Пример с ложным условием:
json
{
"condition": "value == \"rejected\"",
"value": "approved"
}→ false
Клиентская библиотека (Go)
go
client := unishiftclient.NewCommandsClient(baseURL, token)
// Проверка условия
result, err := client.CheckCondition(ctx, unishiftclient.CheckConditionRequest{
Condition: "value > 10",
})
// Валидация с значением
result, err := client.ValidateCondition(ctx, unishiftclient.ValidateConditionRequest{
Condition: "value == \"active\"",
Value: "active",
})Структура БД
| Таблица | Описание |
|---|---|
commands | id, name, description, type, source, owner_id, visible, tags, props, concurrency, execution_count |
command_variables | id, command_id, name, value, description, conditions, order, type |
command_users | id, command_id, user_id, role (admin/user/viewer), created_at, updated_at |
collections | id, name, description, visible, owner_id |
collection_users | id, collection_id, user_id, role (admin/user/viewer), created_at, updated_at |
collection_commands | collection_id, command_id |
collection_collections | parent_collection_id, child_collection_id |
runners | id, name, type, version, tags, ip, jobs, session_timeout, concurrency, paused, temporary |
cli_agents | id, user_id, name, hostname, os, arch, ip, status, metrics, last_seen, created_at, updated_at |
jobs | id, command_id, runner_id, status, variables, result, error |
job_logs | id, job_id, level, message, timestamp |
Таблицы
command_usersиcollection_usersиспользуют модульservice-common/sharing.
CLI Агенты
Подсистема CLI-агентов подключает внешние машины командой ush connect. Сценарий и веб-терминал — CLI → терминал.
Возможности CLI Агентов
- Телеметрия: Клиент
ush connectотправляет метрики системы (загрузка CPU, RAM, Disk, время аптайма, сетевой трафик) каждые 5 секунд по WebSocket. - Интерактивный веб-терминал: Платформа предоставляет терминальный UI в Настройках, транслирующий ввод/вывод команд в PTY-сессию на стороне CLI агента через WebSocket (
/api/v1/cli-agents/:id/terminal). - Автоматическая установка (SSH Provisioning): Из интерфейса настроек можно ввести параметры SSH (хост, порт, логин, пароль/ключ), после чего платформа удаленно установит
ushи автоматически подключит его к текущему экземпляру платформы. - Экспорт артефактов: Пайплайны Flow Manager через
cliAgentNodeмогут передавать сгенерированные файлы и артефакты непосредственно на один из подключенных CLI агентов (/api/v1/cli-agents/:id/export).
API CLI Агентов
| Метод | Путь | Auth | Описание |
|---|---|---|---|
GET | /api/v1/cli-agents | JWT | Список подключенных CLI агентов пользователя |
POST | /api/v1/cli-agents/provision | JWT | Удаленная установка и подключение CLI агента по SSH |
GET | /api/v1/cli-agents/:id | JWT | Информация об агенте и его текущих метриках |
DELETE | /api/v1/cli-agents/:id | JWT | Удалить CLI агент |
GET | /api/v1/cli-agents/ws | Public | WebSocket-эндпоинт для демона ush connect |
GET | /api/v1/cli-agents/:id/terminal | JWT | WebSocket-сессия интерактивного веб-терминала |
POST | /api/v1/cli-agents/:id/export | JWT / Service | Экспорт файла/артефакта на целевой CLI агент |
gRPC Интерфейс
Протокол: runner.v1.RunnerService
- Метод:
Connect(stream RunnerToServer) → stream ServerToRunner - Хендшейк: Runner →
Hello(name, tags, type, version, concurrency) → Сервер →HelloAck(connect_id, server_time) - Совместимость:
Hello.protocol_versionиHello.capabilities; неизвестная версия протокола отклоняется до выдачи задач. - Online availability:
GET /api/v1/runners/availability?type=agent&capability=agent.run.v1читает только активные stream-сессии, а не строки БД. - Задания типа
agentfail-fast требуют capabilityagent.run.v1. - Сервер → Раннер:
TaskAssignment,StopTask - Раннер → Сервер:
Heartbeat,TaskLog,TaskStatus,Ack - Поллинг очереди: каждые 750мс (задачи), 500мс (остановки)
- Аутентификация:
SERVICE_TOKENчерез metadataauthorizationили полеHello.token
Конфигурация
| Переменная | По умолчанию | Описание |
|---|---|---|
PORT | 8094 | Порт сервера |
DB_HOST | — | Адрес PostgreSQL |
DB_PORT | 5432 | Порт PostgreSQL |
DB_USER | — | Пользователь PostgreSQL |
DB_PASSWORD | — | Пароль PostgreSQL |
DB_NAME | — | Имя базы данных |
DB_SSL_MODE | disable | Режим SSL |
SERVICE_TOKEN | — | Токен для gRPC-аутентификации раннеров |
ENV_MANAGER_SERVICE_URL | http://localhost:8097 | URL сервиса env-manager |
MESSAGING_URL | nats://localhost:4222 | URL NATS |
JWT_SECRET | — | Секрет для JWT |
JWT_TTL | 24h | Время жизни токена |