Skip to main content

timeweb_rs/apis/
firewall_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_resource_to_group`]
18#[derive(Debug, Clone, Serialize, Deserialize)]
19#[serde(untagged)]
20pub enum AddResourceToGroupError {
21    Status400(models::GetFinances400Response),
22    Status401(models::GetFinances401Response),
23    Status429(models::GetFinances429Response),
24    Status500(models::GetFinances500Response),
25    UnknownValue(serde_json::Value)
26}
27
28/// struct for typed errors of method [`create_group`]
29#[derive(Debug, Clone, Serialize, Deserialize)]
30#[serde(untagged)]
31pub enum CreateGroupError {
32    Status400(models::GetFinances400Response),
33    Status401(models::GetFinances401Response),
34    Status429(models::GetFinances429Response),
35    Status500(models::GetFinances500Response),
36    UnknownValue(serde_json::Value)
37}
38
39/// struct for typed errors of method [`create_group_rule`]
40#[derive(Debug, Clone, Serialize, Deserialize)]
41#[serde(untagged)]
42pub enum CreateGroupRuleError {
43    Status400(models::GetFinances400Response),
44    Status401(models::GetFinances401Response),
45    Status429(models::GetFinances429Response),
46    Status500(models::GetFinances500Response),
47    UnknownValue(serde_json::Value)
48}
49
50/// struct for typed errors of method [`delete_group`]
51#[derive(Debug, Clone, Serialize, Deserialize)]
52#[serde(untagged)]
53pub enum DeleteGroupError {
54    Status400(models::GetFinances400Response),
55    Status401(models::GetFinances401Response),
56    Status404(models::GetImage404Response),
57    Status429(models::GetFinances429Response),
58    Status500(models::GetFinances500Response),
59    UnknownValue(serde_json::Value)
60}
61
62/// struct for typed errors of method [`delete_group_rule`]
63#[derive(Debug, Clone, Serialize, Deserialize)]
64#[serde(untagged)]
65pub enum DeleteGroupRuleError {
66    Status400(models::GetFinances400Response),
67    Status401(models::GetFinances401Response),
68    Status404(models::GetImage404Response),
69    Status429(models::GetFinances429Response),
70    Status500(models::GetFinances500Response),
71    UnknownValue(serde_json::Value)
72}
73
74/// struct for typed errors of method [`delete_resource_from_group`]
75#[derive(Debug, Clone, Serialize, Deserialize)]
76#[serde(untagged)]
77pub enum DeleteResourceFromGroupError {
78    Status400(models::GetFinances400Response),
79    Status401(models::GetFinances401Response),
80    Status404(models::GetImage404Response),
81    Status429(models::GetFinances429Response),
82    Status500(models::GetFinances500Response),
83    UnknownValue(serde_json::Value)
84}
85
86/// struct for typed errors of method [`get_group`]
87#[derive(Debug, Clone, Serialize, Deserialize)]
88#[serde(untagged)]
89pub enum GetGroupError {
90    Status400(models::GetFinances400Response),
91    Status401(models::GetFinances401Response),
92    Status404(models::GetImage404Response),
93    Status429(models::GetFinances429Response),
94    Status500(models::GetFinances500Response),
95    UnknownValue(serde_json::Value)
96}
97
98/// struct for typed errors of method [`get_group_resources`]
99#[derive(Debug, Clone, Serialize, Deserialize)]
100#[serde(untagged)]
101pub enum GetGroupResourcesError {
102    Status400(models::GetFinances400Response),
103    Status401(models::GetFinances401Response),
104    Status429(models::GetFinances429Response),
105    Status500(models::GetFinances500Response),
106    UnknownValue(serde_json::Value)
107}
108
109/// struct for typed errors of method [`get_group_rule`]
110#[derive(Debug, Clone, Serialize, Deserialize)]
111#[serde(untagged)]
112pub enum GetGroupRuleError {
113    Status400(models::GetFinances400Response),
114    Status401(models::GetFinances401Response),
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_group_rules`]
122#[derive(Debug, Clone, Serialize, Deserialize)]
123#[serde(untagged)]
124pub enum GetGroupRulesError {
125    Status400(models::GetFinances400Response),
126    Status401(models::GetFinances401Response),
127    Status429(models::GetFinances429Response),
128    Status500(models::GetFinances500Response),
129    UnknownValue(serde_json::Value)
130}
131
132/// struct for typed errors of method [`get_groups`]
133#[derive(Debug, Clone, Serialize, Deserialize)]
134#[serde(untagged)]
135pub enum GetGroupsError {
136    Status400(models::GetFinances400Response),
137    Status401(models::GetFinances401Response),
138    Status429(models::GetFinances429Response),
139    Status500(models::GetFinances500Response),
140    UnknownValue(serde_json::Value)
141}
142
143/// struct for typed errors of method [`get_rules_for_resource`]
144#[derive(Debug, Clone, Serialize, Deserialize)]
145#[serde(untagged)]
146pub enum GetRulesForResourceError {
147    Status400(models::GetFinances400Response),
148    Status401(models::GetFinances401Response),
149    Status429(models::GetFinances429Response),
150    Status500(models::GetFinances500Response),
151    UnknownValue(serde_json::Value)
152}
153
154/// struct for typed errors of method [`update_group`]
155#[derive(Debug, Clone, Serialize, Deserialize)]
156#[serde(untagged)]
157pub enum UpdateGroupError {
158    Status400(models::GetFinances400Response),
159    Status401(models::GetFinances401Response),
160    Status404(models::GetImage404Response),
161    Status429(models::GetFinances429Response),
162    Status500(models::GetFinances500Response),
163    UnknownValue(serde_json::Value)
164}
165
166/// struct for typed errors of method [`update_group_rule`]
167#[derive(Debug, Clone, Serialize, Deserialize)]
168#[serde(untagged)]
169pub enum UpdateGroupRuleError {
170    Status400(models::GetFinances400Response),
171    Status401(models::GetFinances401Response),
172    Status404(models::GetImage404Response),
173    Status429(models::GetFinances429Response),
174    Status500(models::GetFinances500Response),
175    UnknownValue(serde_json::Value)
176}
177
178/// Чтобы слинковать ресурс с группой правил, отправьте POST запрос на
179/// `/api/v1/firewall/groups/{group_id}/resources/{resource_id}`
180pub async fn add_resource_to_group(
181    configuration: &configuration::Configuration,
182    group_id: &str,
183    resource_id: &str,
184    resource_type: Option<&str>
185) -> Result<models::AddResourceToGroup201Response, Error<AddResourceToGroupError>> {
186    // add a prefix to parameters to efficiently prevent name collisions
187    let p_path_group_id = group_id;
188    let p_path_resource_id = resource_id;
189    let p_query_resource_type = resource_type;
190
191    let uri_str = format!(
192        "{}/api/v1/firewall/groups/{group_id}/resources/{resource_id}",
193        configuration.base_path,
194        group_id = crate::apis::urlencode(p_path_group_id),
195        resource_id = crate::apis::urlencode(p_path_resource_id)
196    );
197    let mut req_builder = configuration
198        .client
199        .request(reqwest::Method::POST, &uri_str);
200
201    if let Some(ref param_value) = p_query_resource_type {
202        req_builder = req_builder.query(&[("resource_type", &param_value.to_string())]);
203    }
204    if let Some(ref user_agent) = configuration.user_agent {
205        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
206    }
207    if let Some(ref token) = configuration.bearer_access_token {
208        req_builder = req_builder.bearer_auth(token.to_owned());
209    };
210
211    let req = req_builder.build()?;
212    let resp = configuration.client.execute(req).await?;
213
214    let status = resp.status();
215    let content_type = resp
216        .headers()
217        .get("content-type")
218        .and_then(|v| v.to_str().ok())
219        .unwrap_or("application/octet-stream");
220    let content_type = super::ContentType::from(content_type);
221
222    if !status.is_client_error() && !status.is_server_error() {
223        let content = resp.text().await?;
224        match content_type {
225            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
226            ContentType::Text => {
227                return Err(Error::from(serde_json::Error::custom(
228                    "Received `text/plain` content type response that cannot be converted to `models::AddResourceToGroup201Response`"
229                )));
230            }
231            ContentType::Unsupported(unknown_type) => {
232                return Err(Error::from(serde_json::Error::custom(format!(
233                    "Received `{unknown_type}` content type response that cannot be converted to `models::AddResourceToGroup201Response`"
234                ))));
235            }
236        }
237    } else {
238        let content = resp.text().await?;
239        let entity: Option<AddResourceToGroupError> = serde_json::from_str(&content).ok();
240        Err(Error::ResponseError(ResponseContent {
241            status,
242            content,
243            entity
244        }))
245    }
246}
247
248/// Чтобы создать группу правил, отправьте POST запрос на
249/// `/api/v1/firewall/groups`
250pub async fn create_group(
251    configuration: &configuration::Configuration,
252    firewall_group_in_api: models::FirewallGroupInApi,
253    policy: Option<&str>
254) -> Result<models::CreateGroup201Response, Error<CreateGroupError>> {
255    // add a prefix to parameters to efficiently prevent name collisions
256    let p_body_firewall_group_in_api = firewall_group_in_api;
257    let p_query_policy = policy;
258
259    let uri_str = format!("{}/api/v1/firewall/groups", configuration.base_path);
260    let mut req_builder = configuration
261        .client
262        .request(reqwest::Method::POST, &uri_str);
263
264    if let Some(ref param_value) = p_query_policy {
265        req_builder = req_builder.query(&[("policy", &param_value.to_string())]);
266    }
267    if let Some(ref user_agent) = configuration.user_agent {
268        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
269    }
270    if let Some(ref token) = configuration.bearer_access_token {
271        req_builder = req_builder.bearer_auth(token.to_owned());
272    };
273    req_builder = req_builder.json(&p_body_firewall_group_in_api);
274
275    let req = req_builder.build()?;
276    let resp = configuration.client.execute(req).await?;
277
278    let status = resp.status();
279    let content_type = resp
280        .headers()
281        .get("content-type")
282        .and_then(|v| v.to_str().ok())
283        .unwrap_or("application/octet-stream");
284    let content_type = super::ContentType::from(content_type);
285
286    if !status.is_client_error() && !status.is_server_error() {
287        let content = resp.text().await?;
288        match content_type {
289            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
290            ContentType::Text => {
291                return Err(Error::from(serde_json::Error::custom(
292                    "Received `text/plain` content type response that cannot be converted to `models::CreateGroup201Response`"
293                )));
294            }
295            ContentType::Unsupported(unknown_type) => {
296                return Err(Error::from(serde_json::Error::custom(format!(
297                    "Received `{unknown_type}` content type response that cannot be converted to `models::CreateGroup201Response`"
298                ))));
299            }
300        }
301    } else {
302        let content = resp.text().await?;
303        let entity: Option<CreateGroupError> = serde_json::from_str(&content).ok();
304        Err(Error::ResponseError(ResponseContent {
305            status,
306            content,
307            entity
308        }))
309    }
310}
311
312/// Чтобы создать правило в группе, отправьте POST запрос на
313/// `/api/v1/firewall/groups/{group_id}/rules`
314pub async fn create_group_rule(
315    configuration: &configuration::Configuration,
316    group_id: &str,
317    firewall_rule_in_api: models::FirewallRuleInApi
318) -> Result<models::CreateGroupRule201Response, Error<CreateGroupRuleError>> {
319    // add a prefix to parameters to efficiently prevent name collisions
320    let p_path_group_id = group_id;
321    let p_body_firewall_rule_in_api = firewall_rule_in_api;
322
323    let uri_str = format!(
324        "{}/api/v1/firewall/groups/{group_id}/rules",
325        configuration.base_path,
326        group_id = crate::apis::urlencode(p_path_group_id)
327    );
328    let mut req_builder = configuration
329        .client
330        .request(reqwest::Method::POST, &uri_str);
331
332    if let Some(ref user_agent) = configuration.user_agent {
333        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
334    }
335    if let Some(ref token) = configuration.bearer_access_token {
336        req_builder = req_builder.bearer_auth(token.to_owned());
337    };
338    req_builder = req_builder.json(&p_body_firewall_rule_in_api);
339
340    let req = req_builder.build()?;
341    let resp = configuration.client.execute(req).await?;
342
343    let status = resp.status();
344    let content_type = resp
345        .headers()
346        .get("content-type")
347        .and_then(|v| v.to_str().ok())
348        .unwrap_or("application/octet-stream");
349    let content_type = super::ContentType::from(content_type);
350
351    if !status.is_client_error() && !status.is_server_error() {
352        let content = resp.text().await?;
353        match content_type {
354            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
355            ContentType::Text => {
356                return Err(Error::from(serde_json::Error::custom(
357                    "Received `text/plain` content type response that cannot be converted to `models::CreateGroupRule201Response`"
358                )));
359            }
360            ContentType::Unsupported(unknown_type) => {
361                return Err(Error::from(serde_json::Error::custom(format!(
362                    "Received `{unknown_type}` content type response that cannot be converted to `models::CreateGroupRule201Response`"
363                ))));
364            }
365        }
366    } else {
367        let content = resp.text().await?;
368        let entity: Option<CreateGroupRuleError> = serde_json::from_str(&content).ok();
369        Err(Error::ResponseError(ResponseContent {
370            status,
371            content,
372            entity
373        }))
374    }
375}
376
377/// Чтобы удалить группу правил, отправьте DELETE запрос на
378/// `/api/v1/firewall/groups/{group_id}`
379pub async fn delete_group(
380    configuration: &configuration::Configuration,
381    group_id: &str
382) -> Result<(), Error<DeleteGroupError>> {
383    // add a prefix to parameters to efficiently prevent name collisions
384    let p_path_group_id = group_id;
385
386    let uri_str = format!(
387        "{}/api/v1/firewall/groups/{group_id}",
388        configuration.base_path,
389        group_id = crate::apis::urlencode(p_path_group_id)
390    );
391    let mut req_builder = configuration
392        .client
393        .request(reqwest::Method::DELETE, &uri_str);
394
395    if let Some(ref user_agent) = configuration.user_agent {
396        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
397    }
398    if let Some(ref token) = configuration.bearer_access_token {
399        req_builder = req_builder.bearer_auth(token.to_owned());
400    };
401
402    let req = req_builder.build()?;
403    let resp = configuration.client.execute(req).await?;
404
405    let status = resp.status();
406
407    if !status.is_client_error() && !status.is_server_error() {
408        Ok(())
409    } else {
410        let content = resp.text().await?;
411        let entity: Option<DeleteGroupError> = serde_json::from_str(&content).ok();
412        Err(Error::ResponseError(ResponseContent {
413            status,
414            content,
415            entity
416        }))
417    }
418}
419
420/// Чтобы удалить правило, отправьте DELETE запрос на
421/// `/api/v1/firewall/groups/{group_id}/rules/{rule_id}`
422pub async fn delete_group_rule(
423    configuration: &configuration::Configuration,
424    group_id: &str,
425    rule_id: &str
426) -> Result<(), Error<DeleteGroupRuleError>> {
427    // add a prefix to parameters to efficiently prevent name collisions
428    let p_path_group_id = group_id;
429    let p_path_rule_id = rule_id;
430
431    let uri_str = format!(
432        "{}/api/v1/firewall/groups/{group_id}/rules/{rule_id}",
433        configuration.base_path,
434        group_id = crate::apis::urlencode(p_path_group_id),
435        rule_id = crate::apis::urlencode(p_path_rule_id)
436    );
437    let mut req_builder = configuration
438        .client
439        .request(reqwest::Method::DELETE, &uri_str);
440
441    if let Some(ref user_agent) = configuration.user_agent {
442        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
443    }
444    if let Some(ref token) = configuration.bearer_access_token {
445        req_builder = req_builder.bearer_auth(token.to_owned());
446    };
447
448    let req = req_builder.build()?;
449    let resp = configuration.client.execute(req).await?;
450
451    let status = resp.status();
452
453    if !status.is_client_error() && !status.is_server_error() {
454        Ok(())
455    } else {
456        let content = resp.text().await?;
457        let entity: Option<DeleteGroupRuleError> = serde_json::from_str(&content).ok();
458        Err(Error::ResponseError(ResponseContent {
459            status,
460            content,
461            entity
462        }))
463    }
464}
465
466/// Чтобы отлинковать ресурс от группы правил, отправьте DELETE запрос на
467/// `/api/v1/firewall/groups/{group_id}/resources/{resource_id}`
468pub async fn delete_resource_from_group(
469    configuration: &configuration::Configuration,
470    group_id: &str,
471    resource_id: &str,
472    resource_type: Option<&str>
473) -> Result<(), Error<DeleteResourceFromGroupError>> {
474    // add a prefix to parameters to efficiently prevent name collisions
475    let p_path_group_id = group_id;
476    let p_path_resource_id = resource_id;
477    let p_query_resource_type = resource_type;
478
479    let uri_str = format!(
480        "{}/api/v1/firewall/groups/{group_id}/resources/{resource_id}",
481        configuration.base_path,
482        group_id = crate::apis::urlencode(p_path_group_id),
483        resource_id = crate::apis::urlencode(p_path_resource_id)
484    );
485    let mut req_builder = configuration
486        .client
487        .request(reqwest::Method::DELETE, &uri_str);
488
489    if let Some(ref param_value) = p_query_resource_type {
490        req_builder = req_builder.query(&[("resource_type", &param_value.to_string())]);
491    }
492    if let Some(ref user_agent) = configuration.user_agent {
493        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
494    }
495    if let Some(ref token) = configuration.bearer_access_token {
496        req_builder = req_builder.bearer_auth(token.to_owned());
497    };
498
499    let req = req_builder.build()?;
500    let resp = configuration.client.execute(req).await?;
501
502    let status = resp.status();
503
504    if !status.is_client_error() && !status.is_server_error() {
505        Ok(())
506    } else {
507        let content = resp.text().await?;
508        let entity: Option<DeleteResourceFromGroupError> = serde_json::from_str(&content).ok();
509        Err(Error::ResponseError(ResponseContent {
510            status,
511            content,
512            entity
513        }))
514    }
515}
516
517/// Чтобы получить информацию о группе правил, отправьте GET запрос на
518/// `/api/v1/firewall/groups/{group_id}`
519pub async fn get_group(
520    configuration: &configuration::Configuration,
521    group_id: &str
522) -> Result<models::CreateGroup201Response, Error<GetGroupError>> {
523    // add a prefix to parameters to efficiently prevent name collisions
524    let p_path_group_id = group_id;
525
526    let uri_str = format!(
527        "{}/api/v1/firewall/groups/{group_id}",
528        configuration.base_path,
529        group_id = crate::apis::urlencode(p_path_group_id)
530    );
531    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
532
533    if let Some(ref user_agent) = configuration.user_agent {
534        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
535    }
536    if let Some(ref token) = configuration.bearer_access_token {
537        req_builder = req_builder.bearer_auth(token.to_owned());
538    };
539
540    let req = req_builder.build()?;
541    let resp = configuration.client.execute(req).await?;
542
543    let status = resp.status();
544    let content_type = resp
545        .headers()
546        .get("content-type")
547        .and_then(|v| v.to_str().ok())
548        .unwrap_or("application/octet-stream");
549    let content_type = super::ContentType::from(content_type);
550
551    if !status.is_client_error() && !status.is_server_error() {
552        let content = resp.text().await?;
553        match content_type {
554            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
555            ContentType::Text => {
556                return Err(Error::from(serde_json::Error::custom(
557                    "Received `text/plain` content type response that cannot be converted to `models::CreateGroup201Response`"
558                )));
559            }
560            ContentType::Unsupported(unknown_type) => {
561                return Err(Error::from(serde_json::Error::custom(format!(
562                    "Received `{unknown_type}` content type response that cannot be converted to `models::CreateGroup201Response`"
563                ))));
564            }
565        }
566    } else {
567        let content = resp.text().await?;
568        let entity: Option<GetGroupError> = serde_json::from_str(&content).ok();
569        Err(Error::ResponseError(ResponseContent {
570            status,
571            content,
572            entity
573        }))
574    }
575}
576
577/// Чтобы получить слинкованных ресурсов для группы правил, отправьте GET запрос
578/// на `/api/v1/firewall/groups/{group_id}/resources`
579pub async fn get_group_resources(
580    configuration: &configuration::Configuration,
581    group_id: &str,
582    limit: Option<i32>,
583    offset: Option<i32>
584) -> Result<models::GetGroupResources200Response, Error<GetGroupResourcesError>> {
585    // add a prefix to parameters to efficiently prevent name collisions
586    let p_path_group_id = group_id;
587    let p_query_limit = limit;
588    let p_query_offset = offset;
589
590    let uri_str = format!(
591        "{}/api/v1/firewall/groups/{group_id}/resources",
592        configuration.base_path,
593        group_id = crate::apis::urlencode(p_path_group_id)
594    );
595    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
596
597    if let Some(ref param_value) = p_query_limit {
598        req_builder = req_builder.query(&[("limit", &param_value.to_string())]);
599    }
600    if let Some(ref param_value) = p_query_offset {
601        req_builder = req_builder.query(&[("offset", &param_value.to_string())]);
602    }
603    if let Some(ref user_agent) = configuration.user_agent {
604        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
605    }
606    if let Some(ref token) = configuration.bearer_access_token {
607        req_builder = req_builder.bearer_auth(token.to_owned());
608    };
609
610    let req = req_builder.build()?;
611    let resp = configuration.client.execute(req).await?;
612
613    let status = resp.status();
614    let content_type = resp
615        .headers()
616        .get("content-type")
617        .and_then(|v| v.to_str().ok())
618        .unwrap_or("application/octet-stream");
619    let content_type = super::ContentType::from(content_type);
620
621    if !status.is_client_error() && !status.is_server_error() {
622        let content = resp.text().await?;
623        match content_type {
624            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
625            ContentType::Text => {
626                return Err(Error::from(serde_json::Error::custom(
627                    "Received `text/plain` content type response that cannot be converted to `models::GetGroupResources200Response`"
628                )));
629            }
630            ContentType::Unsupported(unknown_type) => {
631                return Err(Error::from(serde_json::Error::custom(format!(
632                    "Received `{unknown_type}` content type response that cannot be converted to `models::GetGroupResources200Response`"
633                ))));
634            }
635        }
636    } else {
637        let content = resp.text().await?;
638        let entity: Option<GetGroupResourcesError> = serde_json::from_str(&content).ok();
639        Err(Error::ResponseError(ResponseContent {
640            status,
641            content,
642            entity
643        }))
644    }
645}
646
647/// Чтобы получить инфомрацию о правиле, отправьте GET запрос на
648/// `/api/v1/firewall/groups/{group_id}/rules/{rule_id}`
649pub async fn get_group_rule(
650    configuration: &configuration::Configuration,
651    rule_id: &str,
652    group_id: &str
653) -> Result<models::CreateGroupRule201Response, Error<GetGroupRuleError>> {
654    // add a prefix to parameters to efficiently prevent name collisions
655    let p_path_rule_id = rule_id;
656    let p_path_group_id = group_id;
657
658    let uri_str = format!(
659        "{}/api/v1/firewall/groups/{group_id}/rules/{rule_id}",
660        configuration.base_path,
661        rule_id = crate::apis::urlencode(p_path_rule_id),
662        group_id = crate::apis::urlencode(p_path_group_id)
663    );
664    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
665
666    if let Some(ref user_agent) = configuration.user_agent {
667        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
668    }
669    if let Some(ref token) = configuration.bearer_access_token {
670        req_builder = req_builder.bearer_auth(token.to_owned());
671    };
672
673    let req = req_builder.build()?;
674    let resp = configuration.client.execute(req).await?;
675
676    let status = resp.status();
677    let content_type = resp
678        .headers()
679        .get("content-type")
680        .and_then(|v| v.to_str().ok())
681        .unwrap_or("application/octet-stream");
682    let content_type = super::ContentType::from(content_type);
683
684    if !status.is_client_error() && !status.is_server_error() {
685        let content = resp.text().await?;
686        match content_type {
687            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
688            ContentType::Text => {
689                return Err(Error::from(serde_json::Error::custom(
690                    "Received `text/plain` content type response that cannot be converted to `models::CreateGroupRule201Response`"
691                )));
692            }
693            ContentType::Unsupported(unknown_type) => {
694                return Err(Error::from(serde_json::Error::custom(format!(
695                    "Received `{unknown_type}` content type response that cannot be converted to `models::CreateGroupRule201Response`"
696                ))));
697            }
698        }
699    } else {
700        let content = resp.text().await?;
701        let entity: Option<GetGroupRuleError> = serde_json::from_str(&content).ok();
702        Err(Error::ResponseError(ResponseContent {
703            status,
704            content,
705            entity
706        }))
707    }
708}
709
710/// Чтобы получить список правил в группе, отправьте GET запрос на
711/// `/api/v1/firewall/groups/{group_id}/rules`
712pub async fn get_group_rules(
713    configuration: &configuration::Configuration,
714    group_id: &str,
715    limit: Option<i32>,
716    offset: Option<i32>
717) -> Result<models::GetGroupRules200Response, Error<GetGroupRulesError>> {
718    // add a prefix to parameters to efficiently prevent name collisions
719    let p_path_group_id = group_id;
720    let p_query_limit = limit;
721    let p_query_offset = offset;
722
723    let uri_str = format!(
724        "{}/api/v1/firewall/groups/{group_id}/rules",
725        configuration.base_path,
726        group_id = crate::apis::urlencode(p_path_group_id)
727    );
728    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
729
730    if let Some(ref param_value) = p_query_limit {
731        req_builder = req_builder.query(&[("limit", &param_value.to_string())]);
732    }
733    if let Some(ref param_value) = p_query_offset {
734        req_builder = req_builder.query(&[("offset", &param_value.to_string())]);
735    }
736    if let Some(ref user_agent) = configuration.user_agent {
737        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
738    }
739    if let Some(ref token) = configuration.bearer_access_token {
740        req_builder = req_builder.bearer_auth(token.to_owned());
741    };
742
743    let req = req_builder.build()?;
744    let resp = configuration.client.execute(req).await?;
745
746    let status = resp.status();
747    let content_type = resp
748        .headers()
749        .get("content-type")
750        .and_then(|v| v.to_str().ok())
751        .unwrap_or("application/octet-stream");
752    let content_type = super::ContentType::from(content_type);
753
754    if !status.is_client_error() && !status.is_server_error() {
755        let content = resp.text().await?;
756        match content_type {
757            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
758            ContentType::Text => {
759                return Err(Error::from(serde_json::Error::custom(
760                    "Received `text/plain` content type response that cannot be converted to `models::GetGroupRules200Response`"
761                )));
762            }
763            ContentType::Unsupported(unknown_type) => {
764                return Err(Error::from(serde_json::Error::custom(format!(
765                    "Received `{unknown_type}` content type response that cannot be converted to `models::GetGroupRules200Response`"
766                ))));
767            }
768        }
769    } else {
770        let content = resp.text().await?;
771        let entity: Option<GetGroupRulesError> = serde_json::from_str(&content).ok();
772        Err(Error::ResponseError(ResponseContent {
773            status,
774            content,
775            entity
776        }))
777    }
778}
779
780/// Чтобы получить групп правил для аккаунта, отправьте GET запрос на
781/// `/api/v1/firewall/groups`
782pub async fn get_groups(
783    configuration: &configuration::Configuration,
784    limit: Option<i32>,
785    offset: Option<i32>
786) -> Result<models::GetGroups200Response, Error<GetGroupsError>> {
787    // add a prefix to parameters to efficiently prevent name collisions
788    let p_query_limit = limit;
789    let p_query_offset = offset;
790
791    let uri_str = format!("{}/api/v1/firewall/groups", configuration.base_path);
792    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
793
794    if let Some(ref param_value) = p_query_limit {
795        req_builder = req_builder.query(&[("limit", &param_value.to_string())]);
796    }
797    if let Some(ref param_value) = p_query_offset {
798        req_builder = req_builder.query(&[("offset", &param_value.to_string())]);
799    }
800    if let Some(ref user_agent) = configuration.user_agent {
801        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
802    }
803    if let Some(ref token) = configuration.bearer_access_token {
804        req_builder = req_builder.bearer_auth(token.to_owned());
805    };
806
807    let req = req_builder.build()?;
808    let resp = configuration.client.execute(req).await?;
809
810    let status = resp.status();
811    let content_type = resp
812        .headers()
813        .get("content-type")
814        .and_then(|v| v.to_str().ok())
815        .unwrap_or("application/octet-stream");
816    let content_type = super::ContentType::from(content_type);
817
818    if !status.is_client_error() && !status.is_server_error() {
819        let content = resp.text().await?;
820        match content_type {
821            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
822            ContentType::Text => {
823                return Err(Error::from(serde_json::Error::custom(
824                    "Received `text/plain` content type response that cannot be converted to `models::GetGroups200Response`"
825                )));
826            }
827            ContentType::Unsupported(unknown_type) => {
828                return Err(Error::from(serde_json::Error::custom(format!(
829                    "Received `{unknown_type}` content type response that cannot be converted to `models::GetGroups200Response`"
830                ))));
831            }
832        }
833    } else {
834        let content = resp.text().await?;
835        let entity: Option<GetGroupsError> = serde_json::from_str(&content).ok();
836        Err(Error::ResponseError(ResponseContent {
837            status,
838            content,
839            entity
840        }))
841    }
842}
843
844/// Чтобы получить список групп правил, с которыми слинкован ресурс, отправьте
845/// GET запрос на `/api/v1/firewall/service/{resource_type}/{resource_id}`
846pub async fn get_rules_for_resource(
847    configuration: &configuration::Configuration,
848    resource_id: &str,
849    resource_type: models::ResourceType,
850    limit: Option<i32>,
851    offset: Option<i32>
852) -> Result<models::GetGroups200Response, Error<GetRulesForResourceError>> {
853    // add a prefix to parameters to efficiently prevent name collisions
854    let p_path_resource_id = resource_id;
855    let p_path_resource_type = resource_type;
856    let p_query_limit = limit;
857    let p_query_offset = offset;
858
859    let uri_str = format!(
860        "{}/api/v1/firewall/service/{resource_type}/{resource_id}",
861        configuration.base_path,
862        resource_id = crate::apis::urlencode(p_path_resource_id),
863        resource_type = p_path_resource_type.to_string()
864    );
865    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
866
867    if let Some(ref param_value) = p_query_limit {
868        req_builder = req_builder.query(&[("limit", &param_value.to_string())]);
869    }
870    if let Some(ref param_value) = p_query_offset {
871        req_builder = req_builder.query(&[("offset", &param_value.to_string())]);
872    }
873    if let Some(ref user_agent) = configuration.user_agent {
874        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
875    }
876    if let Some(ref token) = configuration.bearer_access_token {
877        req_builder = req_builder.bearer_auth(token.to_owned());
878    };
879
880    let req = req_builder.build()?;
881    let resp = configuration.client.execute(req).await?;
882
883    let status = resp.status();
884    let content_type = resp
885        .headers()
886        .get("content-type")
887        .and_then(|v| v.to_str().ok())
888        .unwrap_or("application/octet-stream");
889    let content_type = super::ContentType::from(content_type);
890
891    if !status.is_client_error() && !status.is_server_error() {
892        let content = resp.text().await?;
893        match content_type {
894            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
895            ContentType::Text => {
896                return Err(Error::from(serde_json::Error::custom(
897                    "Received `text/plain` content type response that cannot be converted to `models::GetGroups200Response`"
898                )));
899            }
900            ContentType::Unsupported(unknown_type) => {
901                return Err(Error::from(serde_json::Error::custom(format!(
902                    "Received `{unknown_type}` content type response that cannot be converted to `models::GetGroups200Response`"
903                ))));
904            }
905        }
906    } else {
907        let content = resp.text().await?;
908        let entity: Option<GetRulesForResourceError> = serde_json::from_str(&content).ok();
909        Err(Error::ResponseError(ResponseContent {
910            status,
911            content,
912            entity
913        }))
914    }
915}
916
917/// Чтобы изменить группу правил, отправьте PATCH запрос на
918/// `/api/v1/firewall/groups/{group_id}`
919pub async fn update_group(
920    configuration: &configuration::Configuration,
921    group_id: &str,
922    firewall_group_in_api: models::FirewallGroupInApi
923) -> Result<models::CreateGroup201Response, Error<UpdateGroupError>> {
924    // add a prefix to parameters to efficiently prevent name collisions
925    let p_path_group_id = group_id;
926    let p_body_firewall_group_in_api = firewall_group_in_api;
927
928    let uri_str = format!(
929        "{}/api/v1/firewall/groups/{group_id}",
930        configuration.base_path,
931        group_id = crate::apis::urlencode(p_path_group_id)
932    );
933    let mut req_builder = configuration
934        .client
935        .request(reqwest::Method::PATCH, &uri_str);
936
937    if let Some(ref user_agent) = configuration.user_agent {
938        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
939    }
940    if let Some(ref token) = configuration.bearer_access_token {
941        req_builder = req_builder.bearer_auth(token.to_owned());
942    };
943    req_builder = req_builder.json(&p_body_firewall_group_in_api);
944
945    let req = req_builder.build()?;
946    let resp = configuration.client.execute(req).await?;
947
948    let status = resp.status();
949    let content_type = resp
950        .headers()
951        .get("content-type")
952        .and_then(|v| v.to_str().ok())
953        .unwrap_or("application/octet-stream");
954    let content_type = super::ContentType::from(content_type);
955
956    if !status.is_client_error() && !status.is_server_error() {
957        let content = resp.text().await?;
958        match content_type {
959            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
960            ContentType::Text => {
961                return Err(Error::from(serde_json::Error::custom(
962                    "Received `text/plain` content type response that cannot be converted to `models::CreateGroup201Response`"
963                )));
964            }
965            ContentType::Unsupported(unknown_type) => {
966                return Err(Error::from(serde_json::Error::custom(format!(
967                    "Received `{unknown_type}` content type response that cannot be converted to `models::CreateGroup201Response`"
968                ))));
969            }
970        }
971    } else {
972        let content = resp.text().await?;
973        let entity: Option<UpdateGroupError> = serde_json::from_str(&content).ok();
974        Err(Error::ResponseError(ResponseContent {
975            status,
976            content,
977            entity
978        }))
979    }
980}
981
982/// Чтобы изменить правило, отправьте PATCH запрос на
983/// `/api/v1/firewall/groups/{group_id}/rules/{rule_id}`
984pub async fn update_group_rule(
985    configuration: &configuration::Configuration,
986    group_id: &str,
987    rule_id: &str,
988    firewall_rule_in_api: models::FirewallRuleInApi
989) -> Result<models::CreateGroupRule201Response, Error<UpdateGroupRuleError>> {
990    // add a prefix to parameters to efficiently prevent name collisions
991    let p_path_group_id = group_id;
992    let p_path_rule_id = rule_id;
993    let p_body_firewall_rule_in_api = firewall_rule_in_api;
994
995    let uri_str = format!(
996        "{}/api/v1/firewall/groups/{group_id}/rules/{rule_id}",
997        configuration.base_path,
998        group_id = crate::apis::urlencode(p_path_group_id),
999        rule_id = crate::apis::urlencode(p_path_rule_id)
1000    );
1001    let mut req_builder = configuration
1002        .client
1003        .request(reqwest::Method::PATCH, &uri_str);
1004
1005    if let Some(ref user_agent) = configuration.user_agent {
1006        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
1007    }
1008    if let Some(ref token) = configuration.bearer_access_token {
1009        req_builder = req_builder.bearer_auth(token.to_owned());
1010    };
1011    req_builder = req_builder.json(&p_body_firewall_rule_in_api);
1012
1013    let req = req_builder.build()?;
1014    let resp = configuration.client.execute(req).await?;
1015
1016    let status = resp.status();
1017    let content_type = resp
1018        .headers()
1019        .get("content-type")
1020        .and_then(|v| v.to_str().ok())
1021        .unwrap_or("application/octet-stream");
1022    let content_type = super::ContentType::from(content_type);
1023
1024    if !status.is_client_error() && !status.is_server_error() {
1025        let content = resp.text().await?;
1026        match content_type {
1027            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
1028            ContentType::Text => {
1029                return Err(Error::from(serde_json::Error::custom(
1030                    "Received `text/plain` content type response that cannot be converted to `models::CreateGroupRule201Response`"
1031                )));
1032            }
1033            ContentType::Unsupported(unknown_type) => {
1034                return Err(Error::from(serde_json::Error::custom(format!(
1035                    "Received `{unknown_type}` content type response that cannot be converted to `models::CreateGroupRule201Response`"
1036                ))));
1037            }
1038        }
1039    } else {
1040        let content = resp.text().await?;
1041        let entity: Option<UpdateGroupRuleError> = serde_json::from_str(&content).ok();
1042        Err(Error::ResponseError(ResponseContent {
1043            status,
1044            content,
1045            entity
1046        }))
1047    }
1048}