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.