REST API документация
SpaceVM предоставляет JSON REST интерфейс, к которому можно обращаться напрямую.
Ресурсо-ориентированный подход
В API используется ресурсо-ориентированный подход. Ниже описаны принципы, которые действуют для всех API SpaceVM:
- В качестве ресурсов в API выступают виртуальные машины, диски, образы и т. д. Каждый ресурс имеет уникальный идентификатор. Идентификаторы генерируются на стороне сервиса и представляют собой строку, состоящую из символов латинского алфавита и цифр. Идентификаторы необходимо передавать в запросах к API при обращении к ресурсам.
В REST для каждого ресурса определен свой уникальный URL, который формируется по схеме:
http(s)://<адрес контроллера>/<категория ресурса>/<идентификатор ресурса>
Пример запроса узла
GET http://<адрес контроллера>/api/nodes/cdf10fc6-57f8-436c-a031-78ba3ba1ae40
Как видно из примера, URL ресурсов идентифицируется связкой "категория ресурса и идентификатор ресурса".
Набор методов REST
GET
Пример запроса узлов
GET http(s)://<адрес контроллера>/api/nodes/
PUT
Пример изменения статуса сервиса ballooning узла
PUT http(s)://<адрес контроллера>/api/nodes/94450c3e-b452-46b0-af4a-f688c726f054/ballooning/
{
"ballooning": true
}
POST
Пример выключения ВМ
POST http(s)://<адрес контроллера>/api/domains/f348f0d8-e26a-4063-8019-6929b51ca57d/shutdown/
{
"force": true
}
Пример запросов через curl к API
Сначала необходимо получить ключ интеграции.
Get new VM id
VM_ID=$(curl -s -f -S -H "Content-Type: application/json" \
-H "Authorization: jwt ${TOKEN}" \
http://${VEIL_ADDRESS}/api/domains/?name=${VM_NAME} | jq -r .results[].id)
Clone VM from template
TASK_ID=$(curl -s -f -S -H "Content-Type: application/json" \
-H "Authorization: jwt ${TOKEN}" \
-d "{\\"node\\":\\"${VEIL_NODE_ID}\\", \\"verbose_name\\":\\"${VM_NAME}\\", \\"datapool\\":\\"${VEIL_DATAPOOL_ID}\\"}" \
http://${VEIL_ADDRESS}/api/domains/${TEMPLATE_ID}/clone/?async=1 | jq -r ._task.id)
Waiting for VM creation
until [ "$TASK_STATUS" == "SUCCESS" ]
do
sleep 10
TASK_STATUS=$(curl -s -f -S -H "Content-Type: application/json" \
-H "Authorization: jwt ${TOKEN}" \
http://${VEIL_ADDRESS}/api/tasks/${TASK_ID}/ | jq -r .status)
TASK_PROGRESS=$(curl -s -f -S -H "Content-Type: application/json" \
-H "Authorization: jwt ${TOKEN}" \
http://${VEIL_ADDRESS}/api/tasks/${TASK_ID}/ | jq -r .progress)
echo "Task status is: $TASK_STATUS, progress: $TASK_PROGRESS %"
done
Convert template to VM
curl -s -f -S -XPUT -H "Content-Type: application/json" \
-H "Authorization: jwt ${TOKEN}" \
-d "{\\"template\\":\\"false\\"}" \
http://${VEIL_ADDRESS}/api/domains/${VM_ID}/template/
Add authorized key
curl -s -f -S -XPOST -H "Content-Type: application/json" \
-H "Authorization: jwt ${TOKEN}" \
-d "{\\"create_user\\":false, \\"ssh_user\\":\\"${VM_USERNAME}\\", \\"ssh_key\\":\\"${PUBLIC_KEY}\\"}" \
http://${VEIL_ADDRESS}/api/domains/${VM_ID}/ssh-inject/
Start VM
curl -s -f -S -XPOST -H "Content-Type: application/json" \
-H "Authorization: jwt ${TOKEN}" \
http://${VEIL_ADDRESS}/api/domains/${VM_ID}/start/
Get VM ip address
VM_IP=$(curl -s -f -S -H "Content-Type: application/json" \
-H "Authorization: jwt ${TOKEN}" \
http://${VEIL_ADDRESS}/api/domains/?name=${VM_NAME} | jq -r .results[].guest_utils.ipv4[0])
Backup VM
TASK_ID=$(curl -s -f -S -XPOST -H "Content-Type: application/json" \
-H "Authorization: jwt ${TOKEN}" \
-d "{\\"domain\\":\\"$VM_ID\\", \\"datapool\\":\\"${VEIL_DATAPOOL_ID}\\", \\"compress\\":true, \\"limit_days\\":1}" \
http://${VEIL_ADDRESS}/api/domains/backup/?async=1 | jq -r ._task.id)
Remove VM
curl -s -f -S -H "Content-Type: application/json" \
-H "Authorization: jwt ${TOKEN}" \
-d "{\\"full\\":\\"true\\"}" \
http://${VEIL_ADDRESS}/api/domains/${VM_ID}/remove/
Пагинация
Некоторые методы API поддерживают пагинацию. Пагинация — это свойство, при котором сервер возвращает не все результаты сразу, а частями, по страницам. В основном пагинация используется для метода получения списков сущностей.
Чтобы получить нужную страницу с результатами, в запросе следует передать параметры:
-
limit - количество результатов на странице. Доступные значения: от 0 до 100. Значение по умолчанию: 100.
-
offset - сдвиг результатов относительно 0. Доступные значения: от 0 до общего количества элементов.
Пример запроса 100 событий со сдвигом 200
GET http(s)://<адрес контроллера>/api/events/?limit=100&offset=200
Обработка ошибок
Если операция завершилась успешно, сервер возвращает клиенту статус OK. Если в ходе выполнения операции возникла ошибка, сервер возвращает сообщение с описанием ошибки.
Список возможных ошибок
HTTP-код | Описание ошибки |
---|---|
400 | Клиент некорректно указал параметры запроса. |
401 | Нет прав или ошибка аутентификации. |
403 | Нет прав или ошибка аутентификации. |
404 | Запрашиваемый ресурс не найден. |
405 | Метод не разрешен |
500 | Ошибка сервера при обработке запроса. |
503 | Недоступность SMTP сервера. |
Описание отчетов об ошибках
Структура отчетов всех ошибок представляет собой JSON с двумя фиксированными (code, msg_key) и одним динамическим ключами.
code - используется для автоматической обработки ошибок и представляет собой номер или 'invalid', если не задан.
msg_key - содержит имя динамического ключа ошибки. Используется для прямого доступа к сообщению ошибки.
Динамические ключи указывают на тип ошибки и содержат читаемое сообщение от системы. На основе динамических ключей ошибки делятся на три категории:
-
различные общие ошибки, возникающие во время работы системы (detail);
-
ошибки данных, введенных пользователем в форму, но не относящиеся к определенным полям (non_field_errors);
-
ошибки данных, введенных пользователем в поля форм (ключом является имя поля).
Сообщения ошибок первой категории (1) отображаются в верхнем правом углу главного окна интерфейса. Пример структуры (ключ detail):
{
"errors": [
{
"detail": "Запрашиваемое количество процессоров (2) для виртуальной машины должно быть меньше или равно максимальному количеству процессоров (1).",
"code": "invalid"
"msg_key": "detail",
}
]
}
Сообщения ошибок второй категории (2) отображаются в нижней части окна формы, в котором были введены неверные данные.
Пример структуры (ключ non_field_errors):
{
"errors": [
{
"non_field_errors": "Тип пула данных Базовый локальный пул данных узла 192.168.20.120 (fb283687-555e-411b-aa74-a5edd1930c48) должен быть одним из следующих: lvm, thin_lvm, shared_lvm."
"code": "invalid"
"msg_key": "non_field_errors"
}
]
}
Сообщения ошибок третьей категории (3) отображаются непосредственно под полем, в котором были введены неверные данные.
Пример (ключ username):
{
"errors": [
{
"username": "Это поле обязательно.",
"code": "required",
"msg_key": "username"
}
]
}
Работа с операциями
Все операции, изменяющие состояние ресурса, имеют асинхронную сигнатуру (добавляется ?async=1
в конце запроса).
При вызове таких операций сервер возвращает объект data_with_entity или объект data_without_entity.
Используйте эти объекты, чтобы отслеживать статус операций.
Многие операции поддерживают механизм идемпотентности. Это означает, что при многократном вызове одной и той же операции сервер выполнит эту операцию один раз. Ниже в разделе Идемпотентность показано, как работает механизм идемпотентности, а также приведены примеры его использования.
Объекты ответы от задач data_with_entity и data_without_entity
Каждая операция, которая запускает задачу (просмотр осуществляется в журнале задач), приводит к созданию объекта Задачи. Этот объект содержит информацию об операции: статус, идентификатор, время вызова и т. д.
data_with_entity - словарь с ключом _task, где значением является объект задачи, и ключом _entity, где значением является объект сущности.
data_without_entity - словарь с ключом _task и значением объекта задачи.
Идемпотентность
Space VM поддерживает механизм идемпотентности. Идемпотентная операция — это операция, которая при многократном вызове возвращает один и тот же результат.
По умолчанию некоторые операции в API не являются идемпотентными. Например, операции,
которые изменяют состояние ресурсов. Для обеспечения их идемпотентности в теле запросов
необходимо передавать ключ idempotency_key
. В теле следует указать uuid-строку —
ее необходимо сформировать самостоятельно. У каждой операции должен быть свой uuid.
Примечание
Обратите внимание, что следует использовать UUID версии 4.
Когда сервис получит запрос с ключом idempotency_key
в теле, он проверит,
была ли ранее создана задача с таким uuid. Если операция была создана,
сервер вернет объект data_with_entity или data_without_entity с текущим статусом этой операции.
Если операции с таким uuid не найдено, сервис начнет ее выполнение.
На примерах ниже показано, как использовать механизм идемпотентности при работе с API SpaceVM.
Пример запуска ВМ
Например, вы отправили запрос на запуск виртуальной машины:
POST http(s)://<адрес контроллера>/api/domains/f348f0d8-e26a-4063-8019-6929b51ca57d/start/
{
"force": true,
"idempotency_key": "c1700de3-b8cb-4d8a-9990-e4ebf052e9aa"
}
Если снова отправить этот запрос c тем же idempotency_key
, сервер не будет
выполнять повторный запуск машины. Вместо этого сервер вернет объект ВМ.
Пример гонки
Данный пример демонстрирует ситуацию, в которой возникает состояние гонки.
Пусть с одного клиента был отправлен запрос на остановку запущенной виртуальной машины.
Ключ idempotency_key
при этом не указан.
Предположим, что при отправке запроса произошел сбой в соединении, и клиент не получил ответ от сервера. Виртуальная машина была остановлена, но так как ответ не был получен, клиент не будет знать статуса операции.
В это время другой клиент заново запускает эту виртуальную машину (например, через Web-интерфейс).
Но когда у первого клиента появится доступ к интернету, он повторно отправит запрос на остановку машины.
Так как ключ idempotency_key
не используется, виртуальная машина, которая необходима
второму клиенту, будет остановлена.
Если бы в запросах на остановку машины первый клиент передавал idempotency_key
, то при
повторной отправке запроса виртуальная машина не была бы остановлена.
Swagger
Swagger.yaml доступен по url http://{controller or node ip}/api/schema/
.
Swagger-ui доступен по url http://{controller or node ip}/api/schema/swagger-ui/
.
Swagger-redoc доступен по url http://{controller or node ip}/api/schema/redoc/
.