Skip to main content

timeweb_rs/apis/
s3_api.rs

1/*
2 * Документация публичного API
3 *
4 * # Введение API Timeweb Cloud позволяет вам управлять ресурсами в облаке программным способом с использованием обычных HTTP-запросов.  Множество функций, которые доступны в панели управления Timeweb Cloud, также доступны через API, что позволяет вам автоматизировать ваши собственные сценарии.  В этой документации сперва будет описан общий дизайн и принципы работы API, а после этого конкретные конечные точки. Также будут приведены примеры запросов к ним.   ## Запросы Запросы должны выполняться по протоколу `HTTPS`, чтобы гарантировать шифрование транзакций. Поддерживаются следующие методы запроса: |Метод|Применение| |--- |--- | |GET|Извлекает данные о коллекциях и отдельных ресурсах.| |POST|Для коллекций создает новый ресурс этого типа. Также используется для выполнения действий с конкретным ресурсом.| |PUT|Обновляет существующий ресурс.| |PATCH|Некоторые ресурсы поддерживают частичное обновление, то есть обновление только части атрибутов ресурса, в этом случае вместо метода PUT будет использован PATCH.| |DELETE|Удаляет ресурс.|  Методы `POST`, `PUT` и `PATCH` могут включать объект в тело запроса с типом содержимого `application/json`.  ### Параметры в запросах Некоторые коллекции поддерживают пагинацию, поиск или сортировку в запросах. В параметрах запроса требуется передать: - `limit` — обозначает количество записей, которое необходимо вернуть  - `offset` — указывает на смещение, относительно начала списка  - `search` — позволяет указать набор символов для поиска  - `sort` — можно задать правило сортировки коллекции  ## Ответы Запросы вернут один из следующих кодов состояния ответа HTTP:  |Статус|Описание| |--- |--- | |200 OK|Действие с ресурсом было выполнено успешно.| |201 Created|Ресурс был успешно создан. При этом ресурс может быть как уже готовым к использованию, так и находиться в процессе запуска.| |204 No Content|Действие с ресурсом было выполнено успешно, и ответ не содержит дополнительной информации в теле.| |400 Bad Request|Был отправлен неверный запрос, например, в нем отсутствуют обязательные параметры и т. д. Тело ответа будет содержать дополнительную информацию об ошибке.| |401 Unauthorized|Ошибка аутентификации.| |403 Forbidden|Аутентификация прошла успешно, но недостаточно прав для выполнения действия.| |404 Not Found|Запрашиваемый ресурс не найден.| |409 Conflict|Запрос конфликтует с текущим состоянием.| |423 Locked|Ресурс из запроса заблокирован от применения к нему указанного метода.| |429 Too Many Requests|Был достигнут лимит по количеству запросов в единицу времени.| |500 Internal Server Error|При выполнении запроса произошла какая-то внутренняя ошибка. Чтобы решить эту проблему, лучше всего создать тикет в панели управления.|  ### Структура успешного ответа Все конечные точки будут возвращать данные в формате `JSON`. Ответы на `GET`-запросы будут иметь на верхнем уровне следующую структуру атрибутов:  |Название поля|Тип|Описание| |--- |--- |--- | |[entity_name]|object, object[], string[], number[], boolean|Динамическое поле, которое будет меняться в зависимости от запрашиваемого ресурса и будет содержать все атрибуты, необходимые для описания этого ресурса. Например, при запросе списка баз данных будет возвращаться поле `dbs`, а при запросе конкретного облачного сервера `server`. Для некоторых конечных точек в ответе может возвращаться сразу несколько ресурсов.| |meta|object|Опционально. Объект, который содержит вспомогательную информацию о ресурсе. Чаще всего будет встречаться при запросе коллекций и содержать поле `total`, которое будет указывать на количество элементов в коллекции.| |response_id|string|Опционально. В большинстве случаев в ответе будет содержаться ID ответа в формате UUIDv4, который однозначно указывает на ваш запрос внутри нашей системы. Если вам потребуется задать вопрос нашей поддержке, приложите к вопросу этот ID— так мы сможем найти ответ на него намного быстрее. Также вы можете использовать этот ID, чтобы убедиться, что это новый ответ на запрос и результат не был получен из кэша.|  Пример запроса на получение списка SSH-ключей: ```     HTTP/2.0 200 OK     {       \"ssh_keys\":[           {             \"body\":\"ssh-rsa AAAAB3NzaC1sdfghjkOAsBwWhs= example@device.local\",             \"created_at\":\"2021-09-15T19:52:27Z\",             \"expired_at\":null,             \"id\":5297,             \"is_default\":false,             \"name\":\"example@device.local\",             \"used_at\":null,             \"used_by\":[]           }       ],       \"meta\":{           \"total\":1       },       \"response_id\":\"94608d15-8672-4eed-8ab6-28bd6fa3cdf7\"     } ```  ### Структура ответа с ошибкой |Название поля|Тип|Описание| |--- |--- |--- | |status_code|number|Короткий числовой идентификатор ошибки.| |error_code|string|Короткий текстовый идентификатор ошибки, который уточняет числовой идентификатор и удобен для программной обработки. Самый простой пример — это код `not_found` для ошибки 404.| |message|string, string[]|Опционально. В большинстве случаев в ответе будет содержаться человекочитаемое подробное описание ошибки или ошибок, которые помогут понять, что нужно исправить.| |response_id|string|Опционально. В большинстве случае в ответе будет содержаться ID ответа в формате UUIDv4, который однозначно указывает на ваш запрос внутри нашей системы. Если вам потребуется задать вопрос нашей поддержке, приложите к вопросу этот ID — так мы сможем найти ответ на него намного быстрее.|  Пример: ```     HTTP/2.0 403 Forbidden     {       \"status_code\": 403,       \"error_code\":  \"forbidden\",       \"message\":     \"You do not have access for the attempted action\",       \"response_id\": \"94608d15-8672-4eed-8ab6-28bd6fa3cdf7\"     } ```  ## Статусы ресурсов Важно учесть, что при создании большинства ресурсов внутри платформы вам будет сразу возвращен ответ от сервера со статусом `200 OK` или `201 Created` и ID созданного ресурса в теле ответа, но при этом этот ресурс может быть ещё в *состоянии запуска*.  Для того чтобы понять, в каком состоянии сейчас находится ваш ресурс, мы добавили поле `status` в ответ на получение информации о ресурсе.  Список статусов будет отличаться в зависимости от типа ресурса. Увидеть поддерживаемый список статусов вы сможете в описании каждого конкретного ресурса.     ## Ограничение скорости запросов (Rate Limiting) Чтобы обеспечить стабильность для всех пользователей, Timeweb Cloud защищает API от всплесков входящего трафика, анализируя количество запросов c каждого аккаунта к каждой конечной точке.  Если ваше приложение отправляет более 20 запросов в секунду на одну конечную точку, то для этого запроса API может вернуть код состояния HTTP `429 Too Many Requests`.   ## Аутентификация Доступ к API осуществляется с помощью JWT-токена. Токенами можно управлять внутри панели управления Timeweb Cloud в разделе *API и Terraform*.  Токен необходимо передавать в заголовке каждого запроса в формате: ```   Authorization: Bearer $TIMEWEB_CLOUD_TOKEN ```  ## Формат примеров API Примеры в этой документации описаны с помощью `curl`, HTTP-клиента командной строки. На компьютерах `Linux` и `macOS` обычно по умолчанию установлен `curl`, и он доступен для загрузки на всех популярных платформах, включая `Windows`.  Каждый пример разделен на несколько строк символом `\\`, который совместим с `bash`. Типичный пример выглядит так: ```   curl -X PATCH      -H \"Content-Type: application/json\"      -H \"Authorization: Bearer $TIMEWEB_CLOUD_TOKEN\"      -d '{\"name\":\"Cute Corvus\",\"comment\":\"Development Server\"}'      \"https://api.timeweb.cloud/api/v1/dedicated/1051\" ``` - Параметр `-X` задает метод запроса. Для согласованности метод будет указан во всех примерах, даже если он явно не требуется для методов `GET`. - Строки `-H` задают требуемые HTTP-заголовки. - Примеры, для которых требуется объект JSON в теле запроса, передают требуемые данные через параметр `-d`.  Чтобы использовать приведенные примеры, не подставляя каждый раз в них свой токен, вы можете добавить токен один раз в переменные окружения в вашей консоли. Например, на `Linux` это можно сделать с помощью команды:  ``` TIMEWEB_CLOUD_TOKEN=\"token\" ```  После этого токен будет автоматически подставляться в ваши запросы.  Обратите внимание, что все значения в этой документации являются примерами. Не полагайтесь на IDы операционных систем, тарифов и т.д., используемые в примерах. Используйте соответствующую конечную точку для получения значений перед созданием ресурсов.   ## Версионирование API построено согласно принципам [семантического версионирования](https://semver.org/lang/ru). Это значит, что мы гарантируем обратную совместимость всех изменений в пределах одной мажорной версии.  Мажорная версия каждой конечной точки обозначается в пути запроса, например, запрос `/api/v1/servers` указывает, что этот метод имеет версию 1.
5 *
6 * The version of the OpenAPI document: 1.0.0
7 * Contact: info@timeweb.cloud
8 * Generated by: https://openapi-generator.tech
9 */
10
11use reqwest;
12use serde::{Deserialize, Serialize, de::Error as _};
13
14use super::{ContentType, Error, configuration};
15use crate::{apis::ResponseContent, models};
16
17/// struct for typed errors of method [`add_storage_subdomain_certificate`]
18#[derive(Debug, Clone, Serialize, Deserialize)]
19#[serde(untagged)]
20pub enum AddStorageSubdomainCertificateError {
21    Status400(models::GetFinances400Response),
22    Status401(models::GetFinances401Response),
23    Status403(models::GetAccountStatus403Response),
24    Status404(models::GetImage404Response),
25    Status429(models::GetFinances429Response),
26    Status500(models::GetFinances500Response),
27    UnknownValue(serde_json::Value)
28}
29
30/// struct for typed errors of method [`add_storage_subdomains`]
31#[derive(Debug, Clone, Serialize, Deserialize)]
32#[serde(untagged)]
33pub enum AddStorageSubdomainsError {
34    Status400(models::GetFinances400Response),
35    Status401(models::GetFinances401Response),
36    Status403(models::GetAccountStatus403Response),
37    Status404(models::GetImage404Response),
38    Status429(models::GetFinances429Response),
39    Status500(models::GetFinances500Response),
40    UnknownValue(serde_json::Value)
41}
42
43/// struct for typed errors of method [`create_storage`]
44#[derive(Debug, Clone, Serialize, Deserialize)]
45#[serde(untagged)]
46pub enum CreateStorageError {
47    Status400(models::GetFinances400Response),
48    Status401(models::GetFinances401Response),
49    Status403(models::GetAccountStatus403Response),
50    Status404(models::GetImage404Response),
51    Status429(models::GetFinances429Response),
52    Status500(models::GetFinances500Response),
53    UnknownValue(serde_json::Value)
54}
55
56/// struct for typed errors of method [`delete_storage`]
57#[derive(Debug, Clone, Serialize, Deserialize)]
58#[serde(untagged)]
59pub enum DeleteStorageError {
60    Status400(models::GetFinances400Response),
61    Status401(models::GetFinances401Response),
62    Status403(models::GetAccountStatus403Response),
63    Status404(models::GetImage404Response),
64    Status429(models::GetFinances429Response),
65    Status500(models::GetFinances500Response),
66    UnknownValue(serde_json::Value)
67}
68
69/// struct for typed errors of method [`delete_storage_subdomains`]
70#[derive(Debug, Clone, Serialize, Deserialize)]
71#[serde(untagged)]
72pub enum DeleteStorageSubdomainsError {
73    Status400(models::GetFinances400Response),
74    Status401(models::GetFinances401Response),
75    Status403(models::GetAccountStatus403Response),
76    Status404(models::GetImage404Response),
77    Status429(models::GetFinances429Response),
78    Status500(models::GetFinances500Response),
79    UnknownValue(serde_json::Value)
80}
81
82/// struct for typed errors of method [`get_storage`]
83#[derive(Debug, Clone, Serialize, Deserialize)]
84#[serde(untagged)]
85pub enum GetStorageError {
86    Status400(models::GetFinances400Response),
87    Status401(models::GetFinances401Response),
88    Status403(models::GetAccountStatus403Response),
89    Status404(models::GetImage404Response),
90    Status429(models::GetFinances429Response),
91    Status500(models::GetFinances500Response),
92    UnknownValue(serde_json::Value)
93}
94
95/// struct for typed errors of method [`get_storage_subdomains`]
96#[derive(Debug, Clone, Serialize, Deserialize)]
97#[serde(untagged)]
98pub enum GetStorageSubdomainsError {
99    Status400(models::GetFinances400Response),
100    Status401(models::GetFinances401Response),
101    Status403(models::GetAccountStatus403Response),
102    Status404(models::GetImage404Response),
103    Status429(models::GetFinances429Response),
104    Status500(models::GetFinances500Response),
105    UnknownValue(serde_json::Value)
106}
107
108/// struct for typed errors of method [`get_storage_transfer_status`]
109#[derive(Debug, Clone, Serialize, Deserialize)]
110#[serde(untagged)]
111pub enum GetStorageTransferStatusError {
112    Status400(models::GetFinances400Response),
113    Status401(models::GetFinances401Response),
114    Status403(models::GetAccountStatus403Response),
115    Status404(models::GetImage404Response),
116    Status429(models::GetFinances429Response),
117    Status500(models::GetFinances500Response),
118    UnknownValue(serde_json::Value)
119}
120
121/// struct for typed errors of method [`get_storage_users`]
122#[derive(Debug, Clone, Serialize, Deserialize)]
123#[serde(untagged)]
124pub enum GetStorageUsersError {
125    Status400(models::GetFinances400Response),
126    Status401(models::GetFinances401Response),
127    Status403(models::GetAccountStatus403Response),
128    Status404(models::GetImage404Response),
129    Status429(models::GetFinances429Response),
130    Status500(models::GetFinances500Response),
131    UnknownValue(serde_json::Value)
132}
133
134/// struct for typed errors of method [`get_storages`]
135#[derive(Debug, Clone, Serialize, Deserialize)]
136#[serde(untagged)]
137pub enum GetStoragesError {
138    Status400(models::GetFinances400Response),
139    Status401(models::GetFinances401Response),
140    Status403(models::GetAccountStatus403Response),
141    Status404(models::GetImage404Response),
142    Status429(models::GetFinances429Response),
143    Status500(models::GetFinances500Response),
144    UnknownValue(serde_json::Value)
145}
146
147/// struct for typed errors of method [`get_storages_presets`]
148#[derive(Debug, Clone, Serialize, Deserialize)]
149#[serde(untagged)]
150pub enum GetStoragesPresetsError {
151    Status400(models::GetFinances400Response),
152    Status401(models::GetFinances401Response),
153    Status403(models::GetAccountStatus403Response),
154    Status404(models::GetImage404Response),
155    Status429(models::GetFinances429Response),
156    Status500(models::GetFinances500Response),
157    UnknownValue(serde_json::Value)
158}
159
160/// struct for typed errors of method [`transfer_storage`]
161#[derive(Debug, Clone, Serialize, Deserialize)]
162#[serde(untagged)]
163pub enum TransferStorageError {
164    Status400(models::GetFinances400Response),
165    Status401(models::GetFinances401Response),
166    Status403(models::GetAccountStatus403Response),
167    Status404(models::GetImage404Response),
168    Status429(models::GetFinances429Response),
169    Status500(models::GetFinances500Response),
170    UnknownValue(serde_json::Value)
171}
172
173/// struct for typed errors of method [`update_storage`]
174#[derive(Debug, Clone, Serialize, Deserialize)]
175#[serde(untagged)]
176pub enum UpdateStorageError {
177    Status400(models::GetFinances400Response),
178    Status401(models::GetFinances401Response),
179    Status403(models::GetAccountStatus403Response),
180    Status404(models::GetImage404Response),
181    Status429(models::GetFinances429Response),
182    Status500(models::GetFinances500Response),
183    UnknownValue(serde_json::Value)
184}
185
186/// struct for typed errors of method [`update_storage_user`]
187#[derive(Debug, Clone, Serialize, Deserialize)]
188#[serde(untagged)]
189pub enum UpdateStorageUserError {
190    Status400(models::GetFinances400Response),
191    Status401(models::GetFinances401Response),
192    Status403(models::GetAccountStatus403Response),
193    Status404(models::GetImage404Response),
194    Status429(models::GetFinances429Response),
195    Status500(models::GetFinances500Response),
196    UnknownValue(serde_json::Value)
197}
198
199/// Чтобы добавить сертификат для поддомена хранилища, отправьте POST-запрос на
200/// `/api/v1/storages/certificates/generate`.
201pub async fn add_storage_subdomain_certificate(
202    configuration: &configuration::Configuration,
203    add_storage_subdomain_certificate_request: models::AddStorageSubdomainCertificateRequest
204) -> Result<(), Error<AddStorageSubdomainCertificateError>> {
205    // add a prefix to parameters to efficiently prevent name collisions
206    let p_body_add_storage_subdomain_certificate_request =
207        add_storage_subdomain_certificate_request;
208
209    let uri_str = format!(
210        "{}/api/v1/storages/certificates/generate",
211        configuration.base_path
212    );
213    let mut req_builder = configuration
214        .client
215        .request(reqwest::Method::POST, &uri_str);
216
217    if let Some(ref user_agent) = configuration.user_agent {
218        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
219    }
220    if let Some(ref token) = configuration.bearer_access_token {
221        req_builder = req_builder.bearer_auth(token.to_owned());
222    };
223    req_builder = req_builder.json(&p_body_add_storage_subdomain_certificate_request);
224
225    let req = req_builder.build()?;
226    let resp = configuration.client.execute(req).await?;
227
228    let status = resp.status();
229
230    if !status.is_client_error() && !status.is_server_error() {
231        Ok(())
232    } else {
233        let content = resp.text().await?;
234        let entity: Option<AddStorageSubdomainCertificateError> =
235            serde_json::from_str(&content).ok();
236        Err(Error::ResponseError(ResponseContent {
237            status,
238            content,
239            entity
240        }))
241    }
242}
243
244/// Чтобы добавить поддомены для хранилища, отправьте POST-запрос на
245/// `/api/v1/storages/buckets/{bucket_id}/subdomains`.
246pub async fn add_storage_subdomains(
247    configuration: &configuration::Configuration,
248    bucket_id: i32,
249    add_storage_subdomains_request: models::AddStorageSubdomainsRequest
250) -> Result<models::AddStorageSubdomains200Response, Error<AddStorageSubdomainsError>> {
251    // add a prefix to parameters to efficiently prevent name collisions
252    let p_path_bucket_id = bucket_id;
253    let p_body_add_storage_subdomains_request = add_storage_subdomains_request;
254
255    let uri_str = format!(
256        "{}/api/v1/storages/buckets/{bucket_id}/subdomains",
257        configuration.base_path,
258        bucket_id = p_path_bucket_id
259    );
260    let mut req_builder = configuration
261        .client
262        .request(reqwest::Method::POST, &uri_str);
263
264    if let Some(ref user_agent) = configuration.user_agent {
265        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
266    }
267    if let Some(ref token) = configuration.bearer_access_token {
268        req_builder = req_builder.bearer_auth(token.to_owned());
269    };
270    req_builder = req_builder.json(&p_body_add_storage_subdomains_request);
271
272    let req = req_builder.build()?;
273    let resp = configuration.client.execute(req).await?;
274
275    let status = resp.status();
276    let content_type = resp
277        .headers()
278        .get("content-type")
279        .and_then(|v| v.to_str().ok())
280        .unwrap_or("application/octet-stream");
281    let content_type = super::ContentType::from(content_type);
282
283    if !status.is_client_error() && !status.is_server_error() {
284        let content = resp.text().await?;
285        match content_type {
286            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
287            ContentType::Text => {
288                return Err(Error::from(serde_json::Error::custom(
289                    "Received `text/plain` content type response that cannot be converted to `models::AddStorageSubdomains200Response`"
290                )));
291            }
292            ContentType::Unsupported(unknown_type) => {
293                return Err(Error::from(serde_json::Error::custom(format!(
294                    "Received `{unknown_type}` content type response that cannot be converted to `models::AddStorageSubdomains200Response`"
295                ))));
296            }
297        }
298    } else {
299        let content = resp.text().await?;
300        let entity: Option<AddStorageSubdomainsError> = serde_json::from_str(&content).ok();
301        Err(Error::ResponseError(ResponseContent {
302            status,
303            content,
304            entity
305        }))
306    }
307}
308
309/// Чтобы создать хранилище, отправьте POST-запрос на
310/// `/api/v1/storages/buckets`.
311pub async fn create_storage(
312    configuration: &configuration::Configuration,
313    create_storage_request: models::CreateStorageRequest
314) -> Result<models::CreateStorage201Response, Error<CreateStorageError>> {
315    // add a prefix to parameters to efficiently prevent name collisions
316    let p_body_create_storage_request = create_storage_request;
317
318    let uri_str = format!("{}/api/v1/storages/buckets", configuration.base_path);
319    let mut req_builder = configuration
320        .client
321        .request(reqwest::Method::POST, &uri_str);
322
323    if let Some(ref user_agent) = configuration.user_agent {
324        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
325    }
326    if let Some(ref token) = configuration.bearer_access_token {
327        req_builder = req_builder.bearer_auth(token.to_owned());
328    };
329    req_builder = req_builder.json(&p_body_create_storage_request);
330
331    let req = req_builder.build()?;
332    let resp = configuration.client.execute(req).await?;
333
334    let status = resp.status();
335    let content_type = resp
336        .headers()
337        .get("content-type")
338        .and_then(|v| v.to_str().ok())
339        .unwrap_or("application/octet-stream");
340    let content_type = super::ContentType::from(content_type);
341
342    if !status.is_client_error() && !status.is_server_error() {
343        let content = resp.text().await?;
344        match content_type {
345            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
346            ContentType::Text => {
347                return Err(Error::from(serde_json::Error::custom(
348                    "Received `text/plain` content type response that cannot be converted to `models::CreateStorage201Response`"
349                )));
350            }
351            ContentType::Unsupported(unknown_type) => {
352                return Err(Error::from(serde_json::Error::custom(format!(
353                    "Received `{unknown_type}` content type response that cannot be converted to `models::CreateStorage201Response`"
354                ))));
355            }
356        }
357    } else {
358        let content = resp.text().await?;
359        let entity: Option<CreateStorageError> = serde_json::from_str(&content).ok();
360        Err(Error::ResponseError(ResponseContent {
361            status,
362            content,
363            entity
364        }))
365    }
366}
367
368/// Чтобы удалить хранилище, отправьте DELETE-запрос на
369/// `/api/v1/storages/buckets/{bucket_id}`.
370pub async fn delete_storage(
371    configuration: &configuration::Configuration,
372    bucket_id: i32,
373    hash: Option<&str>,
374    code: Option<&str>
375) -> Result<models::DeleteStorage200Response, Error<DeleteStorageError>> {
376    // add a prefix to parameters to efficiently prevent name collisions
377    let p_path_bucket_id = bucket_id;
378    let p_query_hash = hash;
379    let p_query_code = code;
380
381    let uri_str = format!(
382        "{}/api/v1/storages/buckets/{bucket_id}",
383        configuration.base_path,
384        bucket_id = p_path_bucket_id
385    );
386    let mut req_builder = configuration
387        .client
388        .request(reqwest::Method::DELETE, &uri_str);
389
390    if let Some(ref param_value) = p_query_hash {
391        req_builder = req_builder.query(&[("hash", &param_value.to_string())]);
392    }
393    if let Some(ref param_value) = p_query_code {
394        req_builder = req_builder.query(&[("code", &param_value.to_string())]);
395    }
396    if let Some(ref user_agent) = configuration.user_agent {
397        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
398    }
399    if let Some(ref token) = configuration.bearer_access_token {
400        req_builder = req_builder.bearer_auth(token.to_owned());
401    };
402
403    let req = req_builder.build()?;
404    let resp = configuration.client.execute(req).await?;
405
406    let status = resp.status();
407    let content_type = resp
408        .headers()
409        .get("content-type")
410        .and_then(|v| v.to_str().ok())
411        .unwrap_or("application/octet-stream");
412    let content_type = super::ContentType::from(content_type);
413
414    if !status.is_client_error() && !status.is_server_error() {
415        let content = resp.text().await?;
416        match content_type {
417            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
418            ContentType::Text => {
419                return Err(Error::from(serde_json::Error::custom(
420                    "Received `text/plain` content type response that cannot be converted to `models::DeleteStorage200Response`"
421                )));
422            }
423            ContentType::Unsupported(unknown_type) => {
424                return Err(Error::from(serde_json::Error::custom(format!(
425                    "Received `{unknown_type}` content type response that cannot be converted to `models::DeleteStorage200Response`"
426                ))));
427            }
428        }
429    } else {
430        let content = resp.text().await?;
431        let entity: Option<DeleteStorageError> = serde_json::from_str(&content).ok();
432        Err(Error::ResponseError(ResponseContent {
433            status,
434            content,
435            entity
436        }))
437    }
438}
439
440/// Чтобы удалить поддомены хранилища, отправьте DELETE-запрос на
441/// `/api/v1/storages/buckets/{bucket_id}/subdomains`.
442pub async fn delete_storage_subdomains(
443    configuration: &configuration::Configuration,
444    bucket_id: i32,
445    add_storage_subdomains_request: models::AddStorageSubdomainsRequest
446) -> Result<models::AddStorageSubdomains200Response, Error<DeleteStorageSubdomainsError>> {
447    // add a prefix to parameters to efficiently prevent name collisions
448    let p_path_bucket_id = bucket_id;
449    let p_body_add_storage_subdomains_request = add_storage_subdomains_request;
450
451    let uri_str = format!(
452        "{}/api/v1/storages/buckets/{bucket_id}/subdomains",
453        configuration.base_path,
454        bucket_id = p_path_bucket_id
455    );
456    let mut req_builder = configuration
457        .client
458        .request(reqwest::Method::DELETE, &uri_str);
459
460    if let Some(ref user_agent) = configuration.user_agent {
461        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
462    }
463    if let Some(ref token) = configuration.bearer_access_token {
464        req_builder = req_builder.bearer_auth(token.to_owned());
465    };
466    req_builder = req_builder.json(&p_body_add_storage_subdomains_request);
467
468    let req = req_builder.build()?;
469    let resp = configuration.client.execute(req).await?;
470
471    let status = resp.status();
472    let content_type = resp
473        .headers()
474        .get("content-type")
475        .and_then(|v| v.to_str().ok())
476        .unwrap_or("application/octet-stream");
477    let content_type = super::ContentType::from(content_type);
478
479    if !status.is_client_error() && !status.is_server_error() {
480        let content = resp.text().await?;
481        match content_type {
482            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
483            ContentType::Text => {
484                return Err(Error::from(serde_json::Error::custom(
485                    "Received `text/plain` content type response that cannot be converted to `models::AddStorageSubdomains200Response`"
486                )));
487            }
488            ContentType::Unsupported(unknown_type) => {
489                return Err(Error::from(serde_json::Error::custom(format!(
490                    "Received `{unknown_type}` content type response that cannot be converted to `models::AddStorageSubdomains200Response`"
491                ))));
492            }
493        }
494    } else {
495        let content = resp.text().await?;
496        let entity: Option<DeleteStorageSubdomainsError> = serde_json::from_str(&content).ok();
497        Err(Error::ResponseError(ResponseContent {
498            status,
499            content,
500            entity
501        }))
502    }
503}
504
505/// Чтобы получить хранилище по ID, отправьте GET-запрос на
506/// `/api/v1/storages/buckets/{bucket_id}`.
507pub async fn get_storage(
508    configuration: &configuration::Configuration,
509    bucket_id: i32
510) -> Result<models::CreateStorage201Response, Error<GetStorageError>> {
511    // add a prefix to parameters to efficiently prevent name collisions
512    let p_path_bucket_id = bucket_id;
513
514    let uri_str = format!(
515        "{}/api/v1/storages/buckets/{bucket_id}",
516        configuration.base_path,
517        bucket_id = p_path_bucket_id
518    );
519    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
520
521    if let Some(ref user_agent) = configuration.user_agent {
522        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
523    }
524    if let Some(ref token) = configuration.bearer_access_token {
525        req_builder = req_builder.bearer_auth(token.to_owned());
526    };
527
528    let req = req_builder.build()?;
529    let resp = configuration.client.execute(req).await?;
530
531    let status = resp.status();
532    let content_type = resp
533        .headers()
534        .get("content-type")
535        .and_then(|v| v.to_str().ok())
536        .unwrap_or("application/octet-stream");
537    let content_type = super::ContentType::from(content_type);
538
539    if !status.is_client_error() && !status.is_server_error() {
540        let content = resp.text().await?;
541        match content_type {
542            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
543            ContentType::Text => {
544                return Err(Error::from(serde_json::Error::custom(
545                    "Received `text/plain` content type response that cannot be converted to `models::CreateStorage201Response`"
546                )));
547            }
548            ContentType::Unsupported(unknown_type) => {
549                return Err(Error::from(serde_json::Error::custom(format!(
550                    "Received `{unknown_type}` content type response that cannot be converted to `models::CreateStorage201Response`"
551                ))));
552            }
553        }
554    } else {
555        let content = resp.text().await?;
556        let entity: Option<GetStorageError> = serde_json::from_str(&content).ok();
557        Err(Error::ResponseError(ResponseContent {
558            status,
559            content,
560            entity
561        }))
562    }
563}
564
565/// Чтобы получить список поддоменов хранилища, отправьте GET-запрос на
566/// `/api/v1/storages/buckets/{bucket_id}/subdomains`.
567pub async fn get_storage_subdomains(
568    configuration: &configuration::Configuration,
569    bucket_id: i32
570) -> Result<models::GetStorageSubdomains200Response, Error<GetStorageSubdomainsError>> {
571    // add a prefix to parameters to efficiently prevent name collisions
572    let p_path_bucket_id = bucket_id;
573
574    let uri_str = format!(
575        "{}/api/v1/storages/buckets/{bucket_id}/subdomains",
576        configuration.base_path,
577        bucket_id = p_path_bucket_id
578    );
579    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
580
581    if let Some(ref user_agent) = configuration.user_agent {
582        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
583    }
584    if let Some(ref token) = configuration.bearer_access_token {
585        req_builder = req_builder.bearer_auth(token.to_owned());
586    };
587
588    let req = req_builder.build()?;
589    let resp = configuration.client.execute(req).await?;
590
591    let status = resp.status();
592    let content_type = resp
593        .headers()
594        .get("content-type")
595        .and_then(|v| v.to_str().ok())
596        .unwrap_or("application/octet-stream");
597    let content_type = super::ContentType::from(content_type);
598
599    if !status.is_client_error() && !status.is_server_error() {
600        let content = resp.text().await?;
601        match content_type {
602            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
603            ContentType::Text => {
604                return Err(Error::from(serde_json::Error::custom(
605                    "Received `text/plain` content type response that cannot be converted to `models::GetStorageSubdomains200Response`"
606                )));
607            }
608            ContentType::Unsupported(unknown_type) => {
609                return Err(Error::from(serde_json::Error::custom(format!(
610                    "Received `{unknown_type}` content type response that cannot be converted to `models::GetStorageSubdomains200Response`"
611                ))));
612            }
613        }
614    } else {
615        let content = resp.text().await?;
616        let entity: Option<GetStorageSubdomainsError> = serde_json::from_str(&content).ok();
617        Err(Error::ResponseError(ResponseContent {
618            status,
619            content,
620            entity
621        }))
622    }
623}
624
625/// Чтобы получить статус переноса хранилища от стороннего S3 в Timeweb Cloud,
626/// отправьте GET-запрос на
627/// `/api/v1/storages/buckets/{bucket_id}/transfer-status`.
628pub async fn get_storage_transfer_status(
629    configuration: &configuration::Configuration,
630    bucket_id: i32
631) -> Result<models::GetStorageTransferStatus200Response, Error<GetStorageTransferStatusError>> {
632    // add a prefix to parameters to efficiently prevent name collisions
633    let p_path_bucket_id = bucket_id;
634
635    let uri_str = format!(
636        "{}/api/v1/storages/buckets/{bucket_id}/transfer-status",
637        configuration.base_path,
638        bucket_id = p_path_bucket_id
639    );
640    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
641
642    if let Some(ref user_agent) = configuration.user_agent {
643        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
644    }
645    if let Some(ref token) = configuration.bearer_access_token {
646        req_builder = req_builder.bearer_auth(token.to_owned());
647    };
648
649    let req = req_builder.build()?;
650    let resp = configuration.client.execute(req).await?;
651
652    let status = resp.status();
653    let content_type = resp
654        .headers()
655        .get("content-type")
656        .and_then(|v| v.to_str().ok())
657        .unwrap_or("application/octet-stream");
658    let content_type = super::ContentType::from(content_type);
659
660    if !status.is_client_error() && !status.is_server_error() {
661        let content = resp.text().await?;
662        match content_type {
663            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
664            ContentType::Text => {
665                return Err(Error::from(serde_json::Error::custom(
666                    "Received `text/plain` content type response that cannot be converted to `models::GetStorageTransferStatus200Response`"
667                )));
668            }
669            ContentType::Unsupported(unknown_type) => {
670                return Err(Error::from(serde_json::Error::custom(format!(
671                    "Received `{unknown_type}` content type response that cannot be converted to `models::GetStorageTransferStatus200Response`"
672                ))));
673            }
674        }
675    } else {
676        let content = resp.text().await?;
677        let entity: Option<GetStorageTransferStatusError> = serde_json::from_str(&content).ok();
678        Err(Error::ResponseError(ResponseContent {
679            status,
680            content,
681            entity
682        }))
683    }
684}
685
686/// Чтобы получить список пользователей хранилищ аккаунта, отправьте GET-запрос
687/// на `/api/v1/storages/users`.
688pub async fn get_storage_users(
689    configuration: &configuration::Configuration
690) -> Result<models::GetStorageUsers200Response, Error<GetStorageUsersError>> {
691    let uri_str = format!("{}/api/v1/storages/users", configuration.base_path);
692    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
693
694    if let Some(ref user_agent) = configuration.user_agent {
695        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
696    }
697    if let Some(ref token) = configuration.bearer_access_token {
698        req_builder = req_builder.bearer_auth(token.to_owned());
699    };
700
701    let req = req_builder.build()?;
702    let resp = configuration.client.execute(req).await?;
703
704    let status = resp.status();
705    let content_type = resp
706        .headers()
707        .get("content-type")
708        .and_then(|v| v.to_str().ok())
709        .unwrap_or("application/octet-stream");
710    let content_type = super::ContentType::from(content_type);
711
712    if !status.is_client_error() && !status.is_server_error() {
713        let content = resp.text().await?;
714        match content_type {
715            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
716            ContentType::Text => {
717                return Err(Error::from(serde_json::Error::custom(
718                    "Received `text/plain` content type response that cannot be converted to `models::GetStorageUsers200Response`"
719                )));
720            }
721            ContentType::Unsupported(unknown_type) => {
722                return Err(Error::from(serde_json::Error::custom(format!(
723                    "Received `{unknown_type}` content type response that cannot be converted to `models::GetStorageUsers200Response`"
724                ))));
725            }
726        }
727    } else {
728        let content = resp.text().await?;
729        let entity: Option<GetStorageUsersError> = serde_json::from_str(&content).ok();
730        Err(Error::ResponseError(ResponseContent {
731            status,
732            content,
733            entity
734        }))
735    }
736}
737
738/// Чтобы получить список хранилищ аккаунта, отправьте GET-запрос на
739/// `/api/v1/storages/buckets`.
740pub async fn get_storages(
741    configuration: &configuration::Configuration
742) -> Result<models::GetProjectStorages200Response, Error<GetStoragesError>> {
743    let uri_str = format!("{}/api/v1/storages/buckets", configuration.base_path);
744    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
745
746    if let Some(ref user_agent) = configuration.user_agent {
747        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
748    }
749    if let Some(ref token) = configuration.bearer_access_token {
750        req_builder = req_builder.bearer_auth(token.to_owned());
751    };
752
753    let req = req_builder.build()?;
754    let resp = configuration.client.execute(req).await?;
755
756    let status = resp.status();
757    let content_type = resp
758        .headers()
759        .get("content-type")
760        .and_then(|v| v.to_str().ok())
761        .unwrap_or("application/octet-stream");
762    let content_type = super::ContentType::from(content_type);
763
764    if !status.is_client_error() && !status.is_server_error() {
765        let content = resp.text().await?;
766        match content_type {
767            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
768            ContentType::Text => {
769                return Err(Error::from(serde_json::Error::custom(
770                    "Received `text/plain` content type response that cannot be converted to `models::GetProjectStorages200Response`"
771                )));
772            }
773            ContentType::Unsupported(unknown_type) => {
774                return Err(Error::from(serde_json::Error::custom(format!(
775                    "Received `{unknown_type}` content type response that cannot be converted to `models::GetProjectStorages200Response`"
776                ))));
777            }
778        }
779    } else {
780        let content = resp.text().await?;
781        let entity: Option<GetStoragesError> = serde_json::from_str(&content).ok();
782        Err(Error::ResponseError(ResponseContent {
783            status,
784            content,
785            entity
786        }))
787    }
788}
789
790/// Чтобы получить список тарифов для хранилищ, отправьте GET-запрос на
791/// `/api/v1/presets/storages`.   Тело ответа будет представлять собой объект
792/// JSON с ключом `storages_presets`.
793pub async fn get_storages_presets(
794    configuration: &configuration::Configuration
795) -> Result<models::GetStoragesPresets200Response, Error<GetStoragesPresetsError>> {
796    let uri_str = format!("{}/api/v1/presets/storages", configuration.base_path);
797    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
798
799    if let Some(ref user_agent) = configuration.user_agent {
800        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
801    }
802    if let Some(ref token) = configuration.bearer_access_token {
803        req_builder = req_builder.bearer_auth(token.to_owned());
804    };
805
806    let req = req_builder.build()?;
807    let resp = configuration.client.execute(req).await?;
808
809    let status = resp.status();
810    let content_type = resp
811        .headers()
812        .get("content-type")
813        .and_then(|v| v.to_str().ok())
814        .unwrap_or("application/octet-stream");
815    let content_type = super::ContentType::from(content_type);
816
817    if !status.is_client_error() && !status.is_server_error() {
818        let content = resp.text().await?;
819        match content_type {
820            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
821            ContentType::Text => {
822                return Err(Error::from(serde_json::Error::custom(
823                    "Received `text/plain` content type response that cannot be converted to `models::GetStoragesPresets200Response`"
824                )));
825            }
826            ContentType::Unsupported(unknown_type) => {
827                return Err(Error::from(serde_json::Error::custom(format!(
828                    "Received `{unknown_type}` content type response that cannot be converted to `models::GetStoragesPresets200Response`"
829                ))));
830            }
831        }
832    } else {
833        let content = resp.text().await?;
834        let entity: Option<GetStoragesPresetsError> = serde_json::from_str(&content).ok();
835        Err(Error::ResponseError(ResponseContent {
836            status,
837            content,
838            entity
839        }))
840    }
841}
842
843/// Чтобы перенести хранилище от стороннего провайдера S3 в Timeweb Cloud,
844/// отправьте POST-запрос на `/api/v1/storages/transfer`.
845pub async fn transfer_storage(
846    configuration: &configuration::Configuration,
847    transfer_storage_request: models::TransferStorageRequest
848) -> Result<(), Error<TransferStorageError>> {
849    // add a prefix to parameters to efficiently prevent name collisions
850    let p_body_transfer_storage_request = transfer_storage_request;
851
852    let uri_str = format!("{}/api/v1/storages/transfer", configuration.base_path);
853    let mut req_builder = configuration
854        .client
855        .request(reqwest::Method::POST, &uri_str);
856
857    if let Some(ref user_agent) = configuration.user_agent {
858        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
859    }
860    if let Some(ref token) = configuration.bearer_access_token {
861        req_builder = req_builder.bearer_auth(token.to_owned());
862    };
863    req_builder = req_builder.json(&p_body_transfer_storage_request);
864
865    let req = req_builder.build()?;
866    let resp = configuration.client.execute(req).await?;
867
868    let status = resp.status();
869
870    if !status.is_client_error() && !status.is_server_error() {
871        Ok(())
872    } else {
873        let content = resp.text().await?;
874        let entity: Option<TransferStorageError> = serde_json::from_str(&content).ok();
875        Err(Error::ResponseError(ResponseContent {
876            status,
877            content,
878            entity
879        }))
880    }
881}
882
883/// Чтобы изменить хранилище, отправьте PATCH-запрос на
884/// `/api/v1/storages/buckets/{bucket_id}`.
885pub async fn update_storage(
886    configuration: &configuration::Configuration,
887    bucket_id: i32,
888    update_storage_request: models::UpdateStorageRequest
889) -> Result<models::CreateStorage201Response, Error<UpdateStorageError>> {
890    // add a prefix to parameters to efficiently prevent name collisions
891    let p_path_bucket_id = bucket_id;
892    let p_body_update_storage_request = update_storage_request;
893
894    let uri_str = format!(
895        "{}/api/v1/storages/buckets/{bucket_id}",
896        configuration.base_path,
897        bucket_id = p_path_bucket_id
898    );
899    let mut req_builder = configuration
900        .client
901        .request(reqwest::Method::PATCH, &uri_str);
902
903    if let Some(ref user_agent) = configuration.user_agent {
904        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
905    }
906    if let Some(ref token) = configuration.bearer_access_token {
907        req_builder = req_builder.bearer_auth(token.to_owned());
908    };
909    req_builder = req_builder.json(&p_body_update_storage_request);
910
911    let req = req_builder.build()?;
912    let resp = configuration.client.execute(req).await?;
913
914    let status = resp.status();
915    let content_type = resp
916        .headers()
917        .get("content-type")
918        .and_then(|v| v.to_str().ok())
919        .unwrap_or("application/octet-stream");
920    let content_type = super::ContentType::from(content_type);
921
922    if !status.is_client_error() && !status.is_server_error() {
923        let content = resp.text().await?;
924        match content_type {
925            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
926            ContentType::Text => {
927                return Err(Error::from(serde_json::Error::custom(
928                    "Received `text/plain` content type response that cannot be converted to `models::CreateStorage201Response`"
929                )));
930            }
931            ContentType::Unsupported(unknown_type) => {
932                return Err(Error::from(serde_json::Error::custom(format!(
933                    "Received `{unknown_type}` content type response that cannot be converted to `models::CreateStorage201Response`"
934                ))));
935            }
936        }
937    } else {
938        let content = resp.text().await?;
939        let entity: Option<UpdateStorageError> = serde_json::from_str(&content).ok();
940        Err(Error::ResponseError(ResponseContent {
941            status,
942            content,
943            entity
944        }))
945    }
946}
947
948/// Чтобы изменить пароль пользователя-администратора хранилища, отправьте
949/// POST-запрос на `/api/v1/storages/users/{user_id}`.
950pub async fn update_storage_user(
951    configuration: &configuration::Configuration,
952    user_id: i32,
953    update_storage_user_request: models::UpdateStorageUserRequest
954) -> Result<models::UpdateStorageUser200Response, Error<UpdateStorageUserError>> {
955    // add a prefix to parameters to efficiently prevent name collisions
956    let p_path_user_id = user_id;
957    let p_body_update_storage_user_request = update_storage_user_request;
958
959    let uri_str = format!(
960        "{}/api/v1/storages/users/{user_id}",
961        configuration.base_path,
962        user_id = p_path_user_id
963    );
964    let mut req_builder = configuration
965        .client
966        .request(reqwest::Method::PATCH, &uri_str);
967
968    if let Some(ref user_agent) = configuration.user_agent {
969        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
970    }
971    if let Some(ref token) = configuration.bearer_access_token {
972        req_builder = req_builder.bearer_auth(token.to_owned());
973    };
974    req_builder = req_builder.json(&p_body_update_storage_user_request);
975
976    let req = req_builder.build()?;
977    let resp = configuration.client.execute(req).await?;
978
979    let status = resp.status();
980    let content_type = resp
981        .headers()
982        .get("content-type")
983        .and_then(|v| v.to_str().ok())
984        .unwrap_or("application/octet-stream");
985    let content_type = super::ContentType::from(content_type);
986
987    if !status.is_client_error() && !status.is_server_error() {
988        let content = resp.text().await?;
989        match content_type {
990            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
991            ContentType::Text => {
992                return Err(Error::from(serde_json::Error::custom(
993                    "Received `text/plain` content type response that cannot be converted to `models::UpdateStorageUser200Response`"
994                )));
995            }
996            ContentType::Unsupported(unknown_type) => {
997                return Err(Error::from(serde_json::Error::custom(format!(
998                    "Received `{unknown_type}` content type response that cannot be converted to `models::UpdateStorageUser200Response`"
999                ))));
1000            }
1001        }
1002    } else {
1003        let content = resp.text().await?;
1004        let entity: Option<UpdateStorageUserError> = serde_json::from_str(&content).ok();
1005        Err(Error::ResponseError(ResponseContent {
1006            status,
1007            content,
1008            entity
1009        }))
1010    }
1011}