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 хендшейк)
- 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 |
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.
gRPC Интерфейс
Протокол: runner.v1.RunnerService
- Метод:
Connect(stream RunnerToServer) → stream ServerToRunner - Хендшейк: Runner →
Hello(name, tags, type, version, concurrency) → Сервер →HelloAck(connect_id, server_time) - Сервер → Раннер:
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 | Время жизни токена |