Skip to main content

timeweb_rs/apis/
floating_ip_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 [`bind_floating_ip`]
18#[derive(Debug, Clone, Serialize, Deserialize)]
19#[serde(untagged)]
20pub enum BindFloatingIpError {
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 [`create_floating_ip`]
31#[derive(Debug, Clone, Serialize, Deserialize)]
32#[serde(untagged)]
33pub enum CreateFloatingIpError {
34    Status400(models::GetFinances400Response),
35    Status401(models::GetFinances401Response),
36    Status403(models::GetAccountStatus403Response),
37    Status409(models::CreateDatabaseBackup409Response),
38    Status429(models::GetFinances429Response),
39    Status500(models::GetFinances500Response),
40    UnknownValue(serde_json::Value)
41}
42
43/// struct for typed errors of method [`delete_floating_ip`]
44#[derive(Debug, Clone, Serialize, Deserialize)]
45#[serde(untagged)]
46pub enum DeleteFloatingIpError {
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_floating_ip`]
57#[derive(Debug, Clone, Serialize, Deserialize)]
58#[serde(untagged)]
59pub enum GetFloatingIpError {
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_floating_ips`]
70#[derive(Debug, Clone, Serialize, Deserialize)]
71#[serde(untagged)]
72pub enum GetFloatingIpsError {
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 [`unbind_floating_ip`]
83#[derive(Debug, Clone, Serialize, Deserialize)]
84#[serde(untagged)]
85pub enum UnbindFloatingIpError {
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_floating_ip`]
96#[derive(Debug, Clone, Serialize, Deserialize)]
97#[serde(untagged)]
98pub enum UpdateFloatingIpError {
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/// Чтобы привязать IP к сервису, отправьте POST-запрос на
109/// `/api/v1/floating-ips/{floating_ip_id}/bind`.
110pub async fn bind_floating_ip(
111    configuration: &configuration::Configuration,
112    floating_ip_id: &str,
113    bind_floating_ip: models::BindFloatingIp
114) -> Result<(), Error<BindFloatingIpError>> {
115    // add a prefix to parameters to efficiently prevent name collisions
116    let p_path_floating_ip_id = floating_ip_id;
117    let p_body_bind_floating_ip = bind_floating_ip;
118
119    let uri_str = format!(
120        "{}/api/v1/floating-ips/{floating_ip_id}/bind",
121        configuration.base_path,
122        floating_ip_id = crate::apis::urlencode(p_path_floating_ip_id)
123    );
124    let mut req_builder = configuration
125        .client
126        .request(reqwest::Method::POST, &uri_str);
127
128    if let Some(ref user_agent) = configuration.user_agent {
129        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
130    }
131    if let Some(ref token) = configuration.bearer_access_token {
132        req_builder = req_builder.bearer_auth(token.to_owned());
133    };
134    req_builder = req_builder.json(&p_body_bind_floating_ip);
135
136    let req = req_builder.build()?;
137    let resp = configuration.client.execute(req).await?;
138
139    let status = resp.status();
140
141    if !status.is_client_error() && !status.is_server_error() {
142        Ok(())
143    } else {
144        let content = resp.text().await?;
145        let entity: Option<BindFloatingIpError> = serde_json::from_str(&content).ok();
146        Err(Error::ResponseError(ResponseContent {
147            status,
148            content,
149            entity
150        }))
151    }
152}
153
154/// Чтобы создать создать плавающий IP, отправьте POST-запрос в
155/// `/api/v1/floating-ips`, задав необходимые атрибуты.
156pub async fn create_floating_ip(
157    configuration: &configuration::Configuration,
158    create_floating_ip: models::CreateFloatingIp
159) -> Result<models::CreateFloatingIp201Response, Error<CreateFloatingIpError>> {
160    // add a prefix to parameters to efficiently prevent name collisions
161    let p_body_create_floating_ip = create_floating_ip;
162
163    let uri_str = format!("{}/api/v1/floating-ips", configuration.base_path);
164    let mut req_builder = configuration
165        .client
166        .request(reqwest::Method::POST, &uri_str);
167
168    if let Some(ref user_agent) = configuration.user_agent {
169        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
170    }
171    if let Some(ref token) = configuration.bearer_access_token {
172        req_builder = req_builder.bearer_auth(token.to_owned());
173    };
174    req_builder = req_builder.json(&p_body_create_floating_ip);
175
176    let req = req_builder.build()?;
177    let resp = configuration.client.execute(req).await?;
178
179    let status = resp.status();
180    let content_type = resp
181        .headers()
182        .get("content-type")
183        .and_then(|v| v.to_str().ok())
184        .unwrap_or("application/octet-stream");
185    let content_type = super::ContentType::from(content_type);
186
187    if !status.is_client_error() && !status.is_server_error() {
188        let content = resp.text().await?;
189        match content_type {
190            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
191            ContentType::Text => {
192                return Err(Error::from(serde_json::Error::custom(
193                    "Received `text/plain` content type response that cannot be converted to `models::CreateFloatingIp201Response`"
194                )));
195            }
196            ContentType::Unsupported(unknown_type) => {
197                return Err(Error::from(serde_json::Error::custom(format!(
198                    "Received `{unknown_type}` content type response that cannot be converted to `models::CreateFloatingIp201Response`"
199                ))));
200            }
201        }
202    } else {
203        let content = resp.text().await?;
204        let entity: Option<CreateFloatingIpError> = serde_json::from_str(&content).ok();
205        Err(Error::ResponseError(ResponseContent {
206            status,
207            content,
208            entity
209        }))
210    }
211}
212
213/// Чтобы удалить плавающий IP, отправьте DELETE-запрос на
214/// `/api/v1/floating-ips/{floating_ip_id}`
215pub async fn delete_floating_ip(
216    configuration: &configuration::Configuration,
217    floating_ip_id: &str
218) -> Result<(), Error<DeleteFloatingIpError>> {
219    // add a prefix to parameters to efficiently prevent name collisions
220    let p_path_floating_ip_id = floating_ip_id;
221
222    let uri_str = format!(
223        "{}/api/v1/floating-ips/{floating_ip_id}",
224        configuration.base_path,
225        floating_ip_id = crate::apis::urlencode(p_path_floating_ip_id)
226    );
227    let mut req_builder = configuration
228        .client
229        .request(reqwest::Method::DELETE, &uri_str);
230
231    if let Some(ref user_agent) = configuration.user_agent {
232        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
233    }
234    if let Some(ref token) = configuration.bearer_access_token {
235        req_builder = req_builder.bearer_auth(token.to_owned());
236    };
237
238    let req = req_builder.build()?;
239    let resp = configuration.client.execute(req).await?;
240
241    let status = resp.status();
242
243    if !status.is_client_error() && !status.is_server_error() {
244        Ok(())
245    } else {
246        let content = resp.text().await?;
247        let entity: Option<DeleteFloatingIpError> = serde_json::from_str(&content).ok();
248        Err(Error::ResponseError(ResponseContent {
249            status,
250            content,
251            entity
252        }))
253    }
254}
255
256/// Чтобы отобразить информацию об отдельном плавающем IP, отправьте запрос GET
257/// на `api/v1/floating-ips/{floating_ip_id}`.
258pub async fn get_floating_ip(
259    configuration: &configuration::Configuration,
260    floating_ip_id: &str
261) -> Result<models::CreateFloatingIp201Response, Error<GetFloatingIpError>> {
262    // add a prefix to parameters to efficiently prevent name collisions
263    let p_path_floating_ip_id = floating_ip_id;
264
265    let uri_str = format!(
266        "{}/api/v1/floating-ips/{floating_ip_id}",
267        configuration.base_path,
268        floating_ip_id = crate::apis::urlencode(p_path_floating_ip_id)
269    );
270    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
271
272    if let Some(ref user_agent) = configuration.user_agent {
273        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
274    }
275    if let Some(ref token) = configuration.bearer_access_token {
276        req_builder = req_builder.bearer_auth(token.to_owned());
277    };
278
279    let req = req_builder.build()?;
280    let resp = configuration.client.execute(req).await?;
281
282    let status = resp.status();
283    let content_type = resp
284        .headers()
285        .get("content-type")
286        .and_then(|v| v.to_str().ok())
287        .unwrap_or("application/octet-stream");
288    let content_type = super::ContentType::from(content_type);
289
290    if !status.is_client_error() && !status.is_server_error() {
291        let content = resp.text().await?;
292        match content_type {
293            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
294            ContentType::Text => {
295                return Err(Error::from(serde_json::Error::custom(
296                    "Received `text/plain` content type response that cannot be converted to `models::CreateFloatingIp201Response`"
297                )));
298            }
299            ContentType::Unsupported(unknown_type) => {
300                return Err(Error::from(serde_json::Error::custom(format!(
301                    "Received `{unknown_type}` content type response that cannot be converted to `models::CreateFloatingIp201Response`"
302                ))));
303            }
304        }
305    } else {
306        let content = resp.text().await?;
307        let entity: Option<GetFloatingIpError> = serde_json::from_str(&content).ok();
308        Err(Error::ResponseError(ResponseContent {
309            status,
310            content,
311            entity
312        }))
313    }
314}
315
316/// Чтобы получить список плавающих IP, отправьте GET-запрос на
317/// `/api/v1/floating-ips`.
318pub async fn get_floating_ips(
319    configuration: &configuration::Configuration
320) -> Result<models::GetFloatingIps200Response, Error<GetFloatingIpsError>> {
321    let uri_str = format!("{}/api/v1/floating-ips", configuration.base_path);
322    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
323
324    if let Some(ref user_agent) = configuration.user_agent {
325        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
326    }
327    if let Some(ref token) = configuration.bearer_access_token {
328        req_builder = req_builder.bearer_auth(token.to_owned());
329    };
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::GetFloatingIps200Response`"
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::GetFloatingIps200Response`"
354                ))));
355            }
356        }
357    } else {
358        let content = resp.text().await?;
359        let entity: Option<GetFloatingIpsError> = serde_json::from_str(&content).ok();
360        Err(Error::ResponseError(ResponseContent {
361            status,
362            content,
363            entity
364        }))
365    }
366}
367
368/// Чтобы отвязать IP от сервиса, отправьте POST-запрос на
369/// `/api/v1/floating-ips/{floating_ip_id}/unbind`.
370pub async fn unbind_floating_ip(
371    configuration: &configuration::Configuration,
372    floating_ip_id: &str
373) -> Result<(), Error<UnbindFloatingIpError>> {
374    // add a prefix to parameters to efficiently prevent name collisions
375    let p_path_floating_ip_id = floating_ip_id;
376
377    let uri_str = format!(
378        "{}/api/v1/floating-ips/{floating_ip_id}/unbind",
379        configuration.base_path,
380        floating_ip_id = crate::apis::urlencode(p_path_floating_ip_id)
381    );
382    let mut req_builder = configuration
383        .client
384        .request(reqwest::Method::POST, &uri_str);
385
386    if let Some(ref user_agent) = configuration.user_agent {
387        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
388    }
389    if let Some(ref token) = configuration.bearer_access_token {
390        req_builder = req_builder.bearer_auth(token.to_owned());
391    };
392
393    let req = req_builder.build()?;
394    let resp = configuration.client.execute(req).await?;
395
396    let status = resp.status();
397
398    if !status.is_client_error() && !status.is_server_error() {
399        Ok(())
400    } else {
401        let content = resp.text().await?;
402        let entity: Option<UnbindFloatingIpError> = serde_json::from_str(&content).ok();
403        Err(Error::ResponseError(ResponseContent {
404            status,
405            content,
406            entity
407        }))
408    }
409}
410
411/// Чтобы изменить плавающий IP, отправьте PATCH-запрос на
412/// `/api/v1/floating-ips/{floating_ip_id}`
413pub async fn update_floating_ip(
414    configuration: &configuration::Configuration,
415    floating_ip_id: &str,
416    update_floating_ip: models::UpdateFloatingIp
417) -> Result<models::CreateFloatingIp201Response, Error<UpdateFloatingIpError>> {
418    // add a prefix to parameters to efficiently prevent name collisions
419    let p_path_floating_ip_id = floating_ip_id;
420    let p_body_update_floating_ip = update_floating_ip;
421
422    let uri_str = format!(
423        "{}/api/v1/floating-ips/{floating_ip_id}",
424        configuration.base_path,
425        floating_ip_id = crate::apis::urlencode(p_path_floating_ip_id)
426    );
427    let mut req_builder = configuration
428        .client
429        .request(reqwest::Method::PATCH, &uri_str);
430
431    if let Some(ref user_agent) = configuration.user_agent {
432        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
433    }
434    if let Some(ref token) = configuration.bearer_access_token {
435        req_builder = req_builder.bearer_auth(token.to_owned());
436    };
437    req_builder = req_builder.json(&p_body_update_floating_ip);
438
439    let req = req_builder.build()?;
440    let resp = configuration.client.execute(req).await?;
441
442    let status = resp.status();
443    let content_type = resp
444        .headers()
445        .get("content-type")
446        .and_then(|v| v.to_str().ok())
447        .unwrap_or("application/octet-stream");
448    let content_type = super::ContentType::from(content_type);
449
450    if !status.is_client_error() && !status.is_server_error() {
451        let content = resp.text().await?;
452        match content_type {
453            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
454            ContentType::Text => {
455                return Err(Error::from(serde_json::Error::custom(
456                    "Received `text/plain` content type response that cannot be converted to `models::CreateFloatingIp201Response`"
457                )));
458            }
459            ContentType::Unsupported(unknown_type) => {
460                return Err(Error::from(serde_json::Error::custom(format!(
461                    "Received `{unknown_type}` content type response that cannot be converted to `models::CreateFloatingIp201Response`"
462                ))));
463            }
464        }
465    } else {
466        let content = resp.text().await?;
467        let entity: Option<UpdateFloatingIpError> = serde_json::from_str(&content).ok();
468        Err(Error::ResponseError(ResponseContent {
469            status,
470            content,
471            entity
472        }))
473    }
474}