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

API управления

Справочник HTTP API, которым управляется плагин S3R: адрес, аутентификация, формат ответа, разделы маршрутов. Он нужен тому, кто автоматизирует администрирование или подключает хранилище к внешней системе управления. Консоль управления целиком построена на этом API, поэтому всё, что описано в разделах о тенантах, пользователях, квотах и обслуживании, доступно и запросом.

Точное описание запросов и ответов — в файле doc/api/openapi.yaml репозитория плагина. Это спецификация OpenAPI: из неё генерируется клиент консоли, и она описывает каждое поле каждого ответа. Эта страница описывает устройство и правила, спецификация определяет формат.

Адрес и включение

Свойство Значение
Сервер встроенный HTTP-сервер Picodata — тот же, на котором работает её веб-интерфейс
Порт задаётся параметром instance.http_listen
Базовый путь /s3gateway/api
Включение s3r_api.control_api = 'true'; по умолчанию API выключен
Кто отвечает любой инстанс, на котором включён сервис s3r_api
Сеансы нет: два последовательных запроса могут прийти на разные инстансы, привязка соединений к инстансу балансировщику не нужна

Аутентификация

Способ тот же, что и у консоли, и определяется параметром s3r_api.iam.

Способ Что несёт запрос
провайдер OpenID Connect токен доступа в заголовке Authorization: Bearer
auth_type: "picodata" имя и пароль пользователя Picodata в виде HTTP Basic
# Провайдер OpenID Connect
curl -H "Authorization: Bearer $TOKEN" \
  https://console.example.net/s3gateway/api/v2/capacity

# auth_type: "picodata"
curl -u ivanov https://console.example.net/s3gateway/api/v2/capacity

Полномочия в обоих случаях определяют роли Picodata: s3r_superuser, s3r_tenant_admin_<идентификатор>, s3r_observer. Что даёт каждая, описано в разделе Ролевая модель тенантов.

Запрос к тенанту, роли которого у субъекта доступа нет, получает ответ «не найдено», а не «запрещено».

Проверить учётные данные можно запросом GET /v2/rights: он отвечает именем субъекта доступа и списком его ролей.

Отзыв доступа

Внимание

Токен проверяется локально по ключам провайдера, и провайдер при этом не опрашивается. Поэтому токен, отозванный только у провайдера, действует до истечения своего срока.

Чтобы прекратить действие токена сразу, суперпользователь (роль s3r_superuser) добавляет запись в список отзыва. Список хранится в самом кластере, поэтому отзыв работает и тогда, когда провайдер недоступен.

Маршрут Действие
POST /v2/revocations добавить запись
GET /v2/revocations перечислить записи
DELETE /v2/revocations/{kind}/{value} удалить запись; отклонённые ею токены снова принимаются, если их срок не истёк. Значение, содержащее знак /, в пути указать нельзя
curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"kind": "subject", "value": "00000000-0000-0000-0000-000000000001", "reason": "увольнение"}' \
  https://console.example.net/s3gateway/api/v2/revocations

Поля записи:

Поле Обязательное Значение
kind да subject или token
value да значение заявки sub или jti
issued_before нет время в секундах Unix; по умолчанию момент запроса
expires_at нет время в секундах Unix, позже issued_before, после которого запись больше не нужна; по умолчанию issued_before плюс восемь часов, срок действия cookie консоли
reason нет причина отзыва

Поле added_by записи заполняется именем вызывающего.

Что отзывает запись:

kind Что отзывается Значение value
subject всё, что выдано субъекту доступа заявка sub токена, а при auth_type: "picodata" имя пользователя Picodata
token один токен идентификатор токена, заявка jti

Правила:

  • Запись отклоняет токены и cookie консоли, выданные в момент issued_before или раньше. Выданные позже принимаются, поэтому после отзыва пользователь может войти снова.
  • Токен без заявки iat (время выдачи) отклоняется любой записью, которая к нему относится.
  • Повторный запрос с теми же kind и value заменяет запись. Одновременные запросы, которые пишут одну и ту же запись, завершаются успешно.
  • Ответ приходит, когда запись применили все работающие инстансы.

При auth_type: "picodata":

  • пароль проверяется заново в каждом запросе, поэтому временем выдачи для входа по паролю считается момент запроса;
  • запись завершает сеансы консоли, начатые до неё, и не запрещает вход по паролю. Запретить вход можно командами ALTER USER или DROP USER.

Ограничения:

  • срок жизни токенов провайдера плагину неизвестен. Если токены провайдера действуют дольше восьми часов, задайте expires_at явно;
  • запись с прошедшим expires_at сама не удаляется и продолжает отклонять токены. Ненужную запись удаляет администратор.

Формат ответа

Успех и отказ имеют одну оболочку:

{"errors": [], "result": {"...": "..."}}

При отказе errors содержит сообщения для человека на английском языке, а рядом приходит error_details — массив описаний отказа.

Примечание

Программа разбирает коды, а не текст сообщений: тексты меняются, а коды остаются.

Описание отказа

Поле Значение
code устойчивый идентификатор для программы, см. список ниже
resource то, к чему относится отказ, или null
message то же сообщение, что в errors
error код ошибки S3R, вызвавшей отказ: номер number, имя name, сообщение message и объект fields со значениями полей кода в виде строк
traceback путь ошибки начиная с места её возникновения. Для каждого шага указаны файл исходного кода file, строка line (оба null, если место неизвестно) и пояснение note. Адресов и имён инстансов в пути нет

Поля error и traceback есть только у отказа, вызванного ошибкой S3R.

Значения code:

  • Unauthenticated, Forbidden, NotFound, NameInUse, Invalid, Internal, PayloadTooLarge, RouteNotImplemented, ProviderUnavailable;
  • коды, для которых консоль предлагает следующее действие, например OwnsBuckets, BucketNotEmpty, RepairPaused, NoClientCa и S3PublicUrlUnset.

Код ProviderUnavailable означает, что провайдер идентификации не настроен или недоступен.

Поле error:

  • клиент, который переводит сообщение, подставляет в свой шаблон значения из fields;
  • для кода Picodata или Tarantool приходят только номер и тип ошибки type. Текст такой ошибки записывается в журнал инстанса и в ответ не попадает.

Пример отказа:

{
  "errors": ["the specified S3 bucket does not exist"],
  "result": null,
  "error_details": [{
    "code": "NotFound",
    "resource": "photos",
    "message": "the specified S3 bucket does not exist",
    "error": {"number": 20010, "name": "NoSuchBucket",
              "message": "the specified S3 bucket does not exist", "fields": {}},
    "traceback": [
      {"file": "crates/s3r-meta/src/namespace.rs", "line": 2140, "note": null}
    ]
  }]
}

Коды состояния HTTP

Коды состояния обычные. Два из них имеют особенности:

Код Когда приходит Содержимое
206 пакетная операция, часть элементов которой не выполнена выполненное перечислено в result. По каждому отклонённому элементу errors содержит сообщение вида элемент: сообщение, а error_details на той же позиции содержит описание отказа, в поле item которого назван элемент
400 пакетная операция, ни один элемент которой не выполнен устроен так же, как 206
409 с кодом NameInUse объект с таким именем уже есть —

Идентификатор запроса и журнал

Каждый ответ содержит заголовок x-request-id с идентификатором запроса. Под ним отказ записан в журнал инстанса.

  • Сервер возвращает идентификатор, присланный клиентом в этом заголовке, если в нём не больше 64 символов из набора A-Z, a-z, 0-9, -, _, . и :.
  • Иначе сервер назначает свой идентификатор.

Уровень записи в журнале зависит от отказа:

Отказ Уровень журнала
внутренняя ошибка (500) error, каждый раз
временный отказ (503) warn, когда начинается сбой; debug, пока сбой продолжается; info при окончании сбоя
отказ провайдера идентификации (502 или 503 с кодом ProviderUnavailable) так же: предупреждение появляется один раз, когда начинается сбой провайдера
ошибка в самом запросе (коды 4xx) только debug

Особенности работы

Свойство Поведение Что делать клиенту
Создание не идемпотентно повторный POST с тем же именем получает 409, а не повторную выдачу уже созданного. Два администратора, создающих одного тенанта, узнают об этом клиент, потерявший ответ, выполняет GET
Постраничный вывод по курсору ответ содержит курсор — непрозрачную метку последней выданной записи. Номеров страниц и общего числа записей нет следующая страница запрашивается с курсором
Секретный ключ доступа возвращается один раз ключ приходит в ответе на его выдачу или замену. Больше его не отдаёт ни один запрос: в таблице он хранится в виде, из которого исходный ключ не восстанавливается —
Одновременные изменения одного объекта не согласуются сохраняется изменение, записанное последним —

Номеров страниц нет, потому что SQL Picodata не имеет OFFSET. Выдача по курсору, кроме того, не пропускает и не повторяет записи при одновременном изменении данных.

Состав пространства

Полный перечень маршрутов — в спецификации. Таблица показывает разделы, чтобы понимать, где искать. Какой запрос соответствует какому действию администратора, показывает Справочник административных действий.

Раздел Маршруты О чём
Сеанс /v2/start, /v2/code, /v2/rights, /v2/health способ входа, обмен кода на токен, имя и права вызывающего, проверка работоспособности
Тенанты /v2/tenants, /v2/tenants/extra_rights, /v2/tenants/{id}/mtls, /v2/tenants/{id}/set_mtls, /v2/tenants/{id}/load_mtls_cert создание и удаление тенантов, их домены, клиентские сертификаты и правила CORS по умолчанию для новых бакетов
Пользователи и ключи /v2/users, /v2/credentials, /v2/credentials/{ключ} учётные записи тенанта, выдача, замена и удаление ключей доступа, блокировка
Бакеты /v2/buckets, /v2/buckets/{бакет}/settings, /versioning, /cors, /policy, /lifecycle, /compression, /quota список бакетов, передача бакета другому владельцу (PUT /v2/buckets), настройки, те же, что задаются средствами S3
Доступ и квоты /v2/acl, /v2/quotas, /v2/quotas/tenant_quota, /v2/quotas/bucket_quota права на бакеты; ограничения всех видов, а в разделах tenant_quota и bucket_quota число бакетов и объём тенанта и его пользователей
Объекты /v2/objects, /v2/objects/presign обзор содержимого бакета и подписанная ссылка на объект
Ёмкость и кластер /v2/capacity, /v2/cluster/servers, /v2/cluster/attention сколько занято и сколько осталось, состав кластера с состоянием и шагом начального формирования и регистрацией инстансов, что требует внимания
Диски /v2/disks, /v2/disks/{диск}, /v2/disks/{диск}/failed, /v2/disks/{диск}/reformat, /v2/disks/{диск}/drain список дисков, добавление, удаление, признание вышедшим из строя, переформатирование и перевод в обслуживание; изменения только для s3r_superuser
Группы размещения /v2/placement-groups, /v2/placement-groups/{группа}/reform, /v2/placement-groups/reform состав, раскладка и позиции групп; действие «Восстановить размещение»
Схемы избыточности ярусов /v2/cluster/tiers-redundancy-levels схема избыточности каждого яруса, выполнимость её размещения и, в поле refused, причина, по которой группа сейчас не создаётся
Контроль целостности /v2/repair, /v2/repair/catalog, /v2/repair/data, /v2/repair/disks, /v2/repair/groups, /v2/repair/mode запрос проверки и состояние по областям, расписание сканирования каталога, приостановка фонового контроля целостности; запрос, расписание и режим меняет только s3r_superuser
Репликация и память /v2/replication, /v2/memory репликация между площадками, расход памяти под метаданные
Отзыв доступа /v2/revocations, /v2/revocations/{вид}/{значение} список отзыва токенов и сеансов консоли; только для s3r_superuser

Кто что может:

Запросы Требуемая роль
обзорные запросы GET: /v2/capacity, /v2/cluster/*, /v2/disks, /v2/placement-groups, /v2/repair и маршруты под ним, /v2/replication доступны и наблюдателю (s3r_observer): они ничего не меняют
всё, что меняет состояние кластера s3r_superuser
операции в пределах тенанта роль администратора этого тенанта

Ввод и вывод узла

Ввод и вывод узла кластера в этот перечень не входят, хотя маршруты для этих операций предусмотрены спецификацией: add_server_to_storage, del_server_from_storage и их аналоги для S3 отвечают 501, и в ответе указана команда, которой это делается. Состав кластера меняет Picodata, а не плагин, см. Добавление и вывод узлов.

Управление контролем целостности

Утраченный фрагмент кластер перестраивает сам, и обычно вмешиваться не нужно: см. Контроль целостности. После события, которое кластер не может обнаружить сам, администратор отправляет запрос проверки, а затем читает состояние по областям. Порядок действий описан в разделах Запрос проверки и Состояние по областям.

Маршрут Роль Ответ
GET /v2/repair s3r_observer режим, последний запрос и состояние по областям
POST /v2/repair s3r_superuser 202 с запросом; 409 во время приостановки; 503 до завершения начального формирования
PUT /v2/repair/mode s3r_superuser режим, кто и когда его установил
GET /v2/repair/catalog s3r_observer расписание и последнее сканирование каталога каждого репликасета
PUT /v2/repair/catalog s3r_superuser расписание: every_hours, 0 или от 24 до 8760
GET /v2/repair/data s3r_observer группы, ожидающие ресинхронизации, и повреждённые полосы с объектами, не больше ста на тенанта
GET /v2/repair/disks s3r_observer диски, требующие внимания, и подходящее действие
GET /v2/repair/groups s3r_observer группы, требующие внимания; у несимметричной группы reform: true

Запрос проверки и чтение состояния:

# Запросить проверку
curl -u ivanov -X POST https://console.example.net/s3gateway/api/v2/repair

# Состояние запроса и областей
curl -u ivanov https://console.example.net/s3gateway/api/v2/repair

# Подробности по области данных
curl -u ivanov https://console.example.net/s3gateway/api/v2/repair/data

Приостановка фонового контроля целостности, см. Приостановка фонового контроля целостности:

curl -u ivanov -X PUT https://console.example.net/s3gateway/api/v2/repair/mode \
  -H 'content-type: application/json' -d '{"mode": "paused"}'
Значение mode Действие
paused приостанавливает фоновый контроль целостности
running возобновляет его
другое запрос отклоняется с ответом 400

Ответ и таблица s3r_cluster содержат имя того, кто переключил режим, и время переключения. По ним выясняют, почему кластер ничего не восстанавливает.

Отличия от спецификации

Описание API управления, принятое в программе испытаний, в трёх местах намеренно расходится с тем, что здесь реализовано:

  • постраничный вывод по курсору вместо номеров страниц;
  • набор кодов состояния шире табличного;
  • базовый путь /s3gateway/api.

Перечень с обоснованием этих расхождений находится в doc/dev/CONTROL-API.md.