Skip to main content

timeweb_rs/apis/
vpc_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 [`create_vpc`]
18#[derive(Debug, Clone, Serialize, Deserialize)]
19#[serde(untagged)]
20pub enum CreateVpcError {
21    Status400(models::GetFinances400Response),
22    Status401(models::GetFinances401Response),
23    Status403(models::GetAccountStatus403Response),
24    Status409(models::CreateDatabaseBackup409Response),
25    Status429(models::GetFinances429Response),
26    Status500(models::GetFinances500Response),
27    UnknownValue(serde_json::Value)
28}
29
30/// struct for typed errors of method [`delete_vpc`]
31#[derive(Debug, Clone, Serialize, Deserialize)]
32#[serde(untagged)]
33pub enum DeleteVpcError {
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 [`get_vpc`]
44#[derive(Debug, Clone, Serialize, Deserialize)]
45#[serde(untagged)]
46pub enum GetVpcError {
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 [`get_vpc_ports`]
57#[derive(Debug, Clone, Serialize, Deserialize)]
58#[serde(untagged)]
59pub enum GetVpcPortsError {
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 [`get_vpc_services`]
70#[derive(Debug, Clone, Serialize, Deserialize)]
71#[serde(untagged)]
72pub enum GetVpcServicesError {
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_vpcs`]
83#[derive(Debug, Clone, Serialize, Deserialize)]
84#[serde(untagged)]
85pub enum GetVpcsError {
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 [`update_vpcs`]
96#[derive(Debug, Clone, Serialize, Deserialize)]
97#[serde(untagged)]
98pub enum UpdateVpcsError {
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/// Чтобы создать создать VPC, отправьте POST-запрос в `/api/v2/vpcs`, задав
109/// необходимые атрибуты.
110pub async fn create_vpc(
111    configuration: &configuration::Configuration,
112    create_vpc: models::CreateVpc
113) -> Result<models::CreateVpc201Response, Error<CreateVpcError>> {
114    // add a prefix to parameters to efficiently prevent name collisions
115    let p_body_create_vpc = create_vpc;
116
117    let uri_str = format!("{}/api/v2/vpcs", configuration.base_path);
118    let mut req_builder = configuration
119        .client
120        .request(reqwest::Method::POST, &uri_str);
121
122    if let Some(ref user_agent) = configuration.user_agent {
123        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
124    }
125    if let Some(ref token) = configuration.bearer_access_token {
126        req_builder = req_builder.bearer_auth(token.to_owned());
127    };
128    req_builder = req_builder.json(&p_body_create_vpc);
129
130    let req = req_builder.build()?;
131    let resp = configuration.client.execute(req).await?;
132
133    let status = resp.status();
134    let content_type = resp
135        .headers()
136        .get("content-type")
137        .and_then(|v| v.to_str().ok())
138        .unwrap_or("application/octet-stream");
139    let content_type = super::ContentType::from(content_type);
140
141    if !status.is_client_error() && !status.is_server_error() {
142        let content = resp.text().await?;
143        match content_type {
144            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
145            ContentType::Text => {
146                return Err(Error::from(serde_json::Error::custom(
147                    "Received `text/plain` content type response that cannot be converted to `models::CreateVpc201Response`"
148                )));
149            }
150            ContentType::Unsupported(unknown_type) => {
151                return Err(Error::from(serde_json::Error::custom(format!(
152                    "Received `{unknown_type}` content type response that cannot be converted to `models::CreateVpc201Response`"
153                ))));
154            }
155        }
156    } else {
157        let content = resp.text().await?;
158        let entity: Option<CreateVpcError> = serde_json::from_str(&content).ok();
159        Err(Error::ResponseError(ResponseContent {
160            status,
161            content,
162            entity
163        }))
164    }
165}
166
167/// Чтобы удалить VPC, отправьте DELETE-запрос на `/api/v1/vpcs/{vpc_id}`
168pub async fn delete_vpc(
169    configuration: &configuration::Configuration,
170    vpc_id: &str
171) -> Result<(), Error<DeleteVpcError>> {
172    // add a prefix to parameters to efficiently prevent name collisions
173    let p_path_vpc_id = vpc_id;
174
175    let uri_str = format!(
176        "{}/api/v1/vpcs/{vpc_id}",
177        configuration.base_path,
178        vpc_id = crate::apis::urlencode(p_path_vpc_id)
179    );
180    let mut req_builder = configuration
181        .client
182        .request(reqwest::Method::DELETE, &uri_str);
183
184    if let Some(ref user_agent) = configuration.user_agent {
185        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
186    }
187    if let Some(ref token) = configuration.bearer_access_token {
188        req_builder = req_builder.bearer_auth(token.to_owned());
189    };
190
191    let req = req_builder.build()?;
192    let resp = configuration.client.execute(req).await?;
193
194    let status = resp.status();
195
196    if !status.is_client_error() && !status.is_server_error() {
197        Ok(())
198    } else {
199        let content = resp.text().await?;
200        let entity: Option<DeleteVpcError> = serde_json::from_str(&content).ok();
201        Err(Error::ResponseError(ResponseContent {
202            status,
203            content,
204            entity
205        }))
206    }
207}
208
209/// Чтобы отобразить информацию об отдельном VPC, отправьте запрос GET на
210/// `api/v2/vpcs/{vpc_id}`.
211pub async fn get_vpc(
212    configuration: &configuration::Configuration,
213    vpc_id: &str
214) -> Result<models::CreateVpc201Response, Error<GetVpcError>> {
215    // add a prefix to parameters to efficiently prevent name collisions
216    let p_path_vpc_id = vpc_id;
217
218    let uri_str = format!(
219        "{}/api/v2/vpcs/{vpc_id}",
220        configuration.base_path,
221        vpc_id = crate::apis::urlencode(p_path_vpc_id)
222    );
223    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
224
225    if let Some(ref user_agent) = configuration.user_agent {
226        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
227    }
228    if let Some(ref token) = configuration.bearer_access_token {
229        req_builder = req_builder.bearer_auth(token.to_owned());
230    };
231
232    let req = req_builder.build()?;
233    let resp = configuration.client.execute(req).await?;
234
235    let status = resp.status();
236    let content_type = resp
237        .headers()
238        .get("content-type")
239        .and_then(|v| v.to_str().ok())
240        .unwrap_or("application/octet-stream");
241    let content_type = super::ContentType::from(content_type);
242
243    if !status.is_client_error() && !status.is_server_error() {
244        let content = resp.text().await?;
245        match content_type {
246            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
247            ContentType::Text => {
248                return Err(Error::from(serde_json::Error::custom(
249                    "Received `text/plain` content type response that cannot be converted to `models::CreateVpc201Response`"
250                )));
251            }
252            ContentType::Unsupported(unknown_type) => {
253                return Err(Error::from(serde_json::Error::custom(format!(
254                    "Received `{unknown_type}` content type response that cannot be converted to `models::CreateVpc201Response`"
255                ))));
256            }
257        }
258    } else {
259        let content = resp.text().await?;
260        let entity: Option<GetVpcError> = serde_json::from_str(&content).ok();
261        Err(Error::ResponseError(ResponseContent {
262            status,
263            content,
264            entity
265        }))
266    }
267}
268
269/// Чтобы получить список портов для VPC, отправьте GET-запрос на
270/// `/api/v1/vpcs/{vpc_id}/ports`.
271pub async fn get_vpc_ports(
272    configuration: &configuration::Configuration,
273    vpc_id: &str
274) -> Result<models::GetVpcPorts200Response, Error<GetVpcPortsError>> {
275    // add a prefix to parameters to efficiently prevent name collisions
276    let p_path_vpc_id = vpc_id;
277
278    let uri_str = format!(
279        "{}/api/v1/vpcs/{vpc_id}/ports",
280        configuration.base_path,
281        vpc_id = crate::apis::urlencode(p_path_vpc_id)
282    );
283    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
284
285    if let Some(ref user_agent) = configuration.user_agent {
286        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
287    }
288    if let Some(ref token) = configuration.bearer_access_token {
289        req_builder = req_builder.bearer_auth(token.to_owned());
290    };
291
292    let req = req_builder.build()?;
293    let resp = configuration.client.execute(req).await?;
294
295    let status = resp.status();
296    let content_type = resp
297        .headers()
298        .get("content-type")
299        .and_then(|v| v.to_str().ok())
300        .unwrap_or("application/octet-stream");
301    let content_type = super::ContentType::from(content_type);
302
303    if !status.is_client_error() && !status.is_server_error() {
304        let content = resp.text().await?;
305        match content_type {
306            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
307            ContentType::Text => {
308                return Err(Error::from(serde_json::Error::custom(
309                    "Received `text/plain` content type response that cannot be converted to `models::GetVpcPorts200Response`"
310                )));
311            }
312            ContentType::Unsupported(unknown_type) => {
313                return Err(Error::from(serde_json::Error::custom(format!(
314                    "Received `{unknown_type}` content type response that cannot be converted to `models::GetVpcPorts200Response`"
315                ))));
316            }
317        }
318    } else {
319        let content = resp.text().await?;
320        let entity: Option<GetVpcPortsError> = serde_json::from_str(&content).ok();
321        Err(Error::ResponseError(ResponseContent {
322            status,
323            content,
324            entity
325        }))
326    }
327}
328
329/// Чтобы получить список сервисов, отправьте GET-запрос на
330/// `/api/v2/vpcs/{vpc_id}/services`.
331pub async fn get_vpc_services(
332    configuration: &configuration::Configuration,
333    vpc_id: &str
334) -> Result<models::GetVpcServices200Response, Error<GetVpcServicesError>> {
335    // add a prefix to parameters to efficiently prevent name collisions
336    let p_path_vpc_id = vpc_id;
337
338    let uri_str = format!(
339        "{}/api/v2/vpcs/{vpc_id}/services",
340        configuration.base_path,
341        vpc_id = crate::apis::urlencode(p_path_vpc_id)
342    );
343    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
344
345    if let Some(ref user_agent) = configuration.user_agent {
346        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
347    }
348    if let Some(ref token) = configuration.bearer_access_token {
349        req_builder = req_builder.bearer_auth(token.to_owned());
350    };
351
352    let req = req_builder.build()?;
353    let resp = configuration.client.execute(req).await?;
354
355    let status = resp.status();
356    let content_type = resp
357        .headers()
358        .get("content-type")
359        .and_then(|v| v.to_str().ok())
360        .unwrap_or("application/octet-stream");
361    let content_type = super::ContentType::from(content_type);
362
363    if !status.is_client_error() && !status.is_server_error() {
364        let content = resp.text().await?;
365        match content_type {
366            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
367            ContentType::Text => {
368                return Err(Error::from(serde_json::Error::custom(
369                    "Received `text/plain` content type response that cannot be converted to `models::GetVpcServices200Response`"
370                )));
371            }
372            ContentType::Unsupported(unknown_type) => {
373                return Err(Error::from(serde_json::Error::custom(format!(
374                    "Received `{unknown_type}` content type response that cannot be converted to `models::GetVpcServices200Response`"
375                ))));
376            }
377        }
378    } else {
379        let content = resp.text().await?;
380        let entity: Option<GetVpcServicesError> = serde_json::from_str(&content).ok();
381        Err(Error::ResponseError(ResponseContent {
382            status,
383            content,
384            entity
385        }))
386    }
387}
388
389/// Чтобы получить список VPCs, отправьте GET-запрос на `/api/v2/vpcs`.
390pub async fn get_vpcs(
391    configuration: &configuration::Configuration
392) -> Result<models::GetVpcs200Response, Error<GetVpcsError>> {
393    let uri_str = format!("{}/api/v2/vpcs", configuration.base_path);
394    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
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::GetVpcs200Response`"
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::GetVpcs200Response`"
426                ))));
427            }
428        }
429    } else {
430        let content = resp.text().await?;
431        let entity: Option<GetVpcsError> = serde_json::from_str(&content).ok();
432        Err(Error::ResponseError(ResponseContent {
433            status,
434            content,
435            entity
436        }))
437    }
438}
439
440/// Чтобы изменить VPC, отправьте PATCH-запрос на `/api/v2/vpcs/{vpc_id}`
441pub async fn update_vpcs(
442    configuration: &configuration::Configuration,
443    vpc_id: &str,
444    update_vpc: models::UpdateVpc
445) -> Result<models::CreateVpc201Response, Error<UpdateVpcsError>> {
446    // add a prefix to parameters to efficiently prevent name collisions
447    let p_path_vpc_id = vpc_id;
448    let p_body_update_vpc = update_vpc;
449
450    let uri_str = format!(
451        "{}/api/v2/vpcs/{vpc_id}",
452        configuration.base_path,
453        vpc_id = crate::apis::urlencode(p_path_vpc_id)
454    );
455    let mut req_builder = configuration
456        .client
457        .request(reqwest::Method::PATCH, &uri_str);
458
459    if let Some(ref user_agent) = configuration.user_agent {
460        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
461    }
462    if let Some(ref token) = configuration.bearer_access_token {
463        req_builder = req_builder.bearer_auth(token.to_owned());
464    };
465    req_builder = req_builder.json(&p_body_update_vpc);
466
467    let req = req_builder.build()?;
468    let resp = configuration.client.execute(req).await?;
469
470    let status = resp.status();
471    let content_type = resp
472        .headers()
473        .get("content-type")
474        .and_then(|v| v.to_str().ok())
475        .unwrap_or("application/octet-stream");
476    let content_type = super::ContentType::from(content_type);
477
478    if !status.is_client_error() && !status.is_server_error() {
479        let content = resp.text().await?;
480        match content_type {
481            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
482            ContentType::Text => {
483                return Err(Error::from(serde_json::Error::custom(
484                    "Received `text/plain` content type response that cannot be converted to `models::CreateVpc201Response`"
485                )));
486            }
487            ContentType::Unsupported(unknown_type) => {
488                return Err(Error::from(serde_json::Error::custom(format!(
489                    "Received `{unknown_type}` content type response that cannot be converted to `models::CreateVpc201Response`"
490                ))));
491            }
492        }
493    } else {
494        let content = resp.text().await?;
495        let entity: Option<UpdateVpcsError> = serde_json::from_str(&content).ok();
496        Err(Error::ResponseError(ResponseContent {
497            status,
498            content,
499            entity
500        }))
501    }
502}