Перейти к содержанию

Глава 41. REST API политик

Все операции с политиками доступны через REST API сервера rapi (порт 8081). Запросы к /api/v1/policy/* требуют JWT-аутентификации (заголовок Authorization: Bearer <token>).

Все ответы обёрнуты в стандартный формат ApiResponse<T>:

{
    "success": true,
    "data": { ... },
    "error": null
}

При ошибке:

{
    "success": false,
    "data": null,
    "error": "Error message"
}

40.1. GET /api/v1/policy/status — статус политики

Описание: Возвращает информацию о текущей загруженной политике. Читает данные из dashboard.policy в shared state (rbus).

Handler: get_policy_status()

Запрос:

GET /api/v1/policy/status
Authorization: Bearer <token>

Ответ — PolicyStatus:

Поле Тип Описание
version u64 Номер версии политики
policy_path string? Путь к файлу политики (по умолчанию /etc/rproxy/policy.cpl, env POLICY_PATH)
loaded bool Загружена ли политика
rules_count usize Количество правил
defines_count usize Количество define-блоков
last_reload string? Время последней перезагрузки (ISO 8601)
last_error string? Последняя ошибка загрузки

Пример ответа:

{
    "success": true,
    "data": {
        "version": 5,
        "policy_path": "/etc/rproxy/policy.cpl",
        "loaded": true,
        "rules_count": 42,
        "defines_count": 10,
        "last_reload": null,
        "last_error": null
    }
}

curl:

curl -s -H "Authorization: Bearer $TOKEN" \
  http://localhost:8081/api/v1/policy/status | jq .

40.2. GET /api/v1/policy/rules — получение CPL-текста

Описание: Возвращает исходный текст CPL и метаинформацию. Читает файл политики с диска (путь из env POLICY_PATH, fallback /etc/rproxy/policy.cpl, второй fallback /policy.cpl).

Handler: get_policy_rules()

Запрос:

GET /api/v1/policy/rules
Authorization: Bearer <token>

Ответ — PolicyRulesResponse:

Поле Тип Описание
name string Имя политики (из dashboard или "default")
version string Версия формата ("1.0")
cpl_source string Полный CPL-текст
total_rules usize Количество правил

Пример ответа:

{
    "success": true,
    "data": {
        "name": "default",
        "version": "1.0",
        "cpl_source": "<Proxy>\n    url.domain=malware.example deny\n    allow\n",
        "total_rules": 2
    }
}

curl:

curl -s -H "Authorization: Bearer $TOKEN" \
  http://localhost:8081/api/v1/policy/rules | jq .

40.3. POST /api/v1/policy/validate — валидация CPL

Описание: Проверяет синтаксис CPL без применения. Содержимое записывается в staging-файл ({POLICY_PATH}.staging), затем отправляется rbus-команда ProxyCommand::ValidatePolicy. Прокси читает staging-файл и выполняет валидацию.

Handler: validate_policy()

Timeout: 35 секунд

Запрос — ValidatePolicyRequest:

POST /api/v1/policy/validate
Authorization: Bearer <token>
Content-Type: application/json
{
    "content": "<Proxy>\n    category=Malware deny\n    allow\n"
}

Ответ — ValidationResult:

Поле Тип Описание
valid bool Результат валидации
layers usize Количество слоёв
rules usize Количество правил
errors string[]? Список ошибок (null при успехе; поле отсутствует, если ошибок нет)

Пример ответа (валидна):

{
    "success": true,
    "data": {
        "valid": true,
        "layers": 1,
        "rules": 2
    }
}

Пример ответа (ошибки):

{
    "success": true,
    "data": {
        "valid": false,
        "layers": 0,
        "rules": 0,
        "errors": [
            "Line 15: Syntax error in rule definition",
            "Line 28: Unknown action 'invalid_action'"
        ]
    }
}

curl:

curl -s -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"content":"<Proxy>\n    category=Malware deny\n    allow\n"}' \
  http://localhost:8081/api/v1/policy/validate | jq .

40.4. POST /api/v1/policy/install — установка политики

Описание: Валидирует и устанавливает новую политику. Содержимое записывается в staging-файл, затем отправляется rbus-команда ProxyCommand::InstallPolicy. Прокси выполняет файловую ротацию: .cpl -> .prev, .staging -> .cpl, затем hot reload.

Handler: install_policy()

Timeout: 35 секунд

Запрос — InstallPolicyRequest:

POST /api/v1/policy/install
Authorization: Bearer <token>
Content-Type: application/json
{
    "content": "<Proxy>\n    category=Malware deny\n    allow\n"
}

Ответ — PolicyReloadResponse:

Поле Тип Описание
version u64 Новая версия политики
duration_ms u64 Время загрузки в миллисекундах
rules_count usize Количество правил
defines_count usize Количество define-блоков
changed bool Отличается ли от предыдущей версии

Пример ответа:

{
    "success": true,
    "data": {
        "version": 6,
        "duration_ms": 234,
        "rules_count": 2,
        "defines_count": 0,
        "changed": true
    }
}

curl:

curl -s -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"content":"<Proxy>\n    category=Malware deny\n    allow\n"}' \
  http://localhost:8081/api/v1/policy/install | jq .

40.5. POST /api/v1/policy/reload — перезагрузка из файла

Описание: Перезагружает политику из файла на диске (/etc/rproxy/policy.cpl). Отправляет rbus-команду ProxyCommand::ReloadPolicy.

Handler: reload_policy()

Timeout: 5 секунд

Запрос:

POST /api/v1/policy/reload
Authorization: Bearer <token>

Тело запроса пустое.

Ответ — PolicyReloadResponse:

Формат аналогичен ответу install (поля: version, duration_ms, rules_count, defines_count, changed).

curl:

curl -s -X POST -H "Authorization: Bearer $TOKEN" \
  http://localhost:8081/api/v1/policy/reload | jq .

40.6. POST /api/v1/policy/rollback — откат

Описание: Восстанавливает предыдущую версию политики. Файловая ротация: .cpl -> .staging, .prev -> .cpl, затем reload. Отправляет rbus-команду ProxyCommand::RollbackPolicy.

Handler: rollback_policy()

Timeout: 5 секунд

Запрос:

POST /api/v1/policy/rollback
Authorization: Bearer <token>

Тело запроса пустое.

Ответ — PolicyRollbackResponse:

Поле Тип Описание
previous_version u64 Версия, с которой откатились
rolled_back_to u64 Версия, на которую откатились

Пример ответа:

{
    "success": true,
    "data": {
        "previous_version": 6,
        "rolled_back_to": 5
    }
}

curl:

curl -s -X POST -H "Authorization: Bearer $TOKEN" \
  http://localhost:8081/api/v1/policy/rollback | jq .

40.7. SSE-события политик

Изменения политик транслируются через Server-Sent Events для обновления WebGUI в реальном времени. Регистрируется 3 типа событий:

GET /api/v1/stats/stream?filter=policy
Authorization: Bearer <token>

Также доступен унифицированный endpoint: GET /api/v1/events?filter=policy.

Зарегистрированные типы событий:

EventType ProxyEvent Когда генерируется Поля данных
PolicyReloaded PolicyReloaded(PolicyReloadResponse) После успешного reload или install version, duration_ms, rules_count, defines_count, changed
PolicyValidated PolicyValidated(ValidationResult) После validate valid, layers, rules, errors
PolicyRolledBack После rollback previous (u64), current (u64)

Обработка на клиенте:

WebGUI обрабатывает SSE-события так: 1. Слушает SSE-события policy_reloaded и policy_rolled_back 2. Если нет несохранённых изменений — автоматически перезагружает политику с сервера 3. Если есть несохранённые изменения — показывает предупреждение с кнопкой перезагрузки

40.8. Механизм file-based staging

Все POST-операции (validate, install) используют промежуточный файл, чтобы обойти ограничение на размер сообщения rbus (224 байта):

Файловая схема (BlueCoat-style rollback):

/etc/rproxy/
    policy.cpl              <- текущая активная
    policy.cpl.prev         <- предыдущая (для rollback)
    policy.cpl.staging      <- staging (для validate/install)

Поток данных:

  1. rapi: записывает содержимое запроса в {POLICY_PATH}.staging
  2. rapi: подписывается на событие EVT_PROXY_EVENT и публикует команду CMD_PROXY_COMMAND (без тела)
  3. proxy-bin: читает .staging, выполняет validate/install, ротирует файлы, публикует EVT_PROXY_EVENT с результатом
  4. rapi: опрашивает события, сопоставляя их по идентификатору запроса (таймаут 35 с для validate/install, 5 с для reload/rollback)
  5. rapi: также транслирует события в SSE

Сопоставление событий по идентификатору запроса исключает потерю результата, если в потоке присутствуют события EVT_PROXY_EVENT от других источников (статистика, сессии).

40.9. Сводная таблица endpoints

Метод Путь Handler Timeout Тело запроса Тип ответа
GET /api/v1/policy/status get_policy_status -- -- PolicyStatus
GET /api/v1/policy/rules get_policy_rules -- -- PolicyRulesResponse
POST /api/v1/policy/reload reload_policy 5s пустое PolicyReloadResponse
POST /api/v1/policy/rollback rollback_policy 5s пустое PolicyRollbackResponse
POST /api/v1/policy/validate validate_policy 35s ValidatePolicyRequest ValidationResult
POST /api/v1/policy/install install_policy 35s InstallPolicyRequest PolicyReloadResponse