datadog_api_client/datadogV2/api/
api_ip_allowlist.rs

1// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License.
2// This product includes software developed at Datadog (https://www.datadoghq.com/).
3// Copyright 2019-Present Datadog, Inc.
4use crate::datadog;
5use flate2::{
6    write::{GzEncoder, ZlibEncoder},
7    Compression,
8};
9use reqwest::header::{HeaderMap, HeaderValue};
10use serde::{Deserialize, Serialize};
11use std::io::Write;
12
13/// GetIPAllowlistError is a struct for typed errors of method [`IPAllowlistAPI::get_ip_allowlist`]
14#[derive(Debug, Clone, Serialize, Deserialize)]
15#[serde(untagged)]
16pub enum GetIPAllowlistError {
17    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
18    UnknownValue(serde_json::Value),
19}
20
21/// UpdateIPAllowlistError is a struct for typed errors of method [`IPAllowlistAPI::update_ip_allowlist`]
22#[derive(Debug, Clone, Serialize, Deserialize)]
23#[serde(untagged)]
24pub enum UpdateIPAllowlistError {
25    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
26    UnknownValue(serde_json::Value),
27}
28
29/// The IP allowlist API is used to manage the IP addresses that
30/// can access the Datadog API and web UI. It does not block
31/// access to intake APIs or public dashboards.
32///
33/// This is an enterprise-only feature. Request access by
34/// contacting Datadog support, or see the [IP Allowlist page](<https://docs.datadoghq.com/account_management/org_settings/ip_allowlist/>) for more information.
35#[derive(Debug, Clone)]
36pub struct IPAllowlistAPI {
37    config: datadog::Configuration,
38    client: reqwest_middleware::ClientWithMiddleware,
39}
40
41impl Default for IPAllowlistAPI {
42    fn default() -> Self {
43        Self::with_config(datadog::Configuration::default())
44    }
45}
46
47impl IPAllowlistAPI {
48    pub fn new() -> Self {
49        Self::default()
50    }
51    pub fn with_config(config: datadog::Configuration) -> Self {
52        let mut reqwest_client_builder = reqwest::Client::builder();
53
54        if let Some(proxy_url) = &config.proxy_url {
55            let proxy = reqwest::Proxy::all(proxy_url).expect("Failed to parse proxy URL");
56            reqwest_client_builder = reqwest_client_builder.proxy(proxy);
57        }
58
59        let mut middleware_client_builder =
60            reqwest_middleware::ClientBuilder::new(reqwest_client_builder.build().unwrap());
61
62        if config.enable_retry {
63            struct RetryableStatus;
64            impl reqwest_retry::RetryableStrategy for RetryableStatus {
65                fn handle(
66                    &self,
67                    res: &Result<reqwest::Response, reqwest_middleware::Error>,
68                ) -> Option<reqwest_retry::Retryable> {
69                    match res {
70                        Ok(success) => reqwest_retry::default_on_request_success(success),
71                        Err(_) => None,
72                    }
73                }
74            }
75            let backoff_policy = reqwest_retry::policies::ExponentialBackoff::builder()
76                .build_with_max_retries(config.max_retries);
77
78            let retry_middleware =
79                reqwest_retry::RetryTransientMiddleware::new_with_policy_and_strategy(
80                    backoff_policy,
81                    RetryableStatus,
82                );
83
84            middleware_client_builder = middleware_client_builder.with(retry_middleware);
85        }
86
87        let client = middleware_client_builder.build();
88
89        Self { config, client }
90    }
91
92    pub fn with_client_and_config(
93        config: datadog::Configuration,
94        client: reqwest_middleware::ClientWithMiddleware,
95    ) -> Self {
96        Self { config, client }
97    }
98
99    /// Returns the IP allowlist and its enabled or disabled state.
100    pub async fn get_ip_allowlist(
101        &self,
102    ) -> Result<crate::datadogV2::model::IPAllowlistResponse, datadog::Error<GetIPAllowlistError>>
103    {
104        match self.get_ip_allowlist_with_http_info().await {
105            Ok(response_content) => {
106                if let Some(e) = response_content.entity {
107                    Ok(e)
108                } else {
109                    Err(datadog::Error::Serde(serde::de::Error::custom(
110                        "response content was None",
111                    )))
112                }
113            }
114            Err(err) => Err(err),
115        }
116    }
117
118    /// Returns the IP allowlist and its enabled or disabled state.
119    pub async fn get_ip_allowlist_with_http_info(
120        &self,
121    ) -> Result<
122        datadog::ResponseContent<crate::datadogV2::model::IPAllowlistResponse>,
123        datadog::Error<GetIPAllowlistError>,
124    > {
125        let local_configuration = &self.config;
126        let operation_id = "v2.get_ip_allowlist";
127
128        let local_client = &self.client;
129
130        let local_uri_str = format!(
131            "{}/api/v2/ip_allowlist",
132            local_configuration.get_operation_host(operation_id)
133        );
134        let mut local_req_builder =
135            local_client.request(reqwest::Method::GET, local_uri_str.as_str());
136
137        // build headers
138        let mut headers = HeaderMap::new();
139        headers.insert("Accept", HeaderValue::from_static("application/json"));
140
141        // build user agent
142        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
143            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
144            Err(e) => {
145                log::warn!("Failed to parse user agent header: {e}, falling back to default");
146                headers.insert(
147                    reqwest::header::USER_AGENT,
148                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
149                )
150            }
151        };
152
153        // build auth
154        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
155            headers.insert(
156                "DD-API-KEY",
157                HeaderValue::from_str(local_key.key.as_str())
158                    .expect("failed to parse DD-API-KEY header"),
159            );
160        };
161        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
162            headers.insert(
163                "DD-APPLICATION-KEY",
164                HeaderValue::from_str(local_key.key.as_str())
165                    .expect("failed to parse DD-APPLICATION-KEY header"),
166            );
167        };
168
169        local_req_builder = local_req_builder.headers(headers);
170        let local_req = local_req_builder.build()?;
171        log::debug!("request content: {:?}", local_req.body());
172        let local_resp = local_client.execute(local_req).await?;
173
174        let local_status = local_resp.status();
175        let local_content = local_resp.text().await?;
176        log::debug!("response content: {}", local_content);
177
178        if !local_status.is_client_error() && !local_status.is_server_error() {
179            match serde_json::from_str::<crate::datadogV2::model::IPAllowlistResponse>(
180                &local_content,
181            ) {
182                Ok(e) => {
183                    return Ok(datadog::ResponseContent {
184                        status: local_status,
185                        content: local_content,
186                        entity: Some(e),
187                    })
188                }
189                Err(e) => return Err(datadog::Error::Serde(e)),
190            };
191        } else {
192            let local_entity: Option<GetIPAllowlistError> =
193                serde_json::from_str(&local_content).ok();
194            let local_error = datadog::ResponseContent {
195                status: local_status,
196                content: local_content,
197                entity: local_entity,
198            };
199            Err(datadog::Error::ResponseError(local_error))
200        }
201    }
202
203    /// Edit the entries in the IP allowlist, and enable or disable it.
204    pub async fn update_ip_allowlist(
205        &self,
206        body: crate::datadogV2::model::IPAllowlistUpdateRequest,
207    ) -> Result<crate::datadogV2::model::IPAllowlistResponse, datadog::Error<UpdateIPAllowlistError>>
208    {
209        match self.update_ip_allowlist_with_http_info(body).await {
210            Ok(response_content) => {
211                if let Some(e) = response_content.entity {
212                    Ok(e)
213                } else {
214                    Err(datadog::Error::Serde(serde::de::Error::custom(
215                        "response content was None",
216                    )))
217                }
218            }
219            Err(err) => Err(err),
220        }
221    }
222
223    /// Edit the entries in the IP allowlist, and enable or disable it.
224    pub async fn update_ip_allowlist_with_http_info(
225        &self,
226        body: crate::datadogV2::model::IPAllowlistUpdateRequest,
227    ) -> Result<
228        datadog::ResponseContent<crate::datadogV2::model::IPAllowlistResponse>,
229        datadog::Error<UpdateIPAllowlistError>,
230    > {
231        let local_configuration = &self.config;
232        let operation_id = "v2.update_ip_allowlist";
233
234        let local_client = &self.client;
235
236        let local_uri_str = format!(
237            "{}/api/v2/ip_allowlist",
238            local_configuration.get_operation_host(operation_id)
239        );
240        let mut local_req_builder =
241            local_client.request(reqwest::Method::PATCH, local_uri_str.as_str());
242
243        // build headers
244        let mut headers = HeaderMap::new();
245        headers.insert("Content-Type", HeaderValue::from_static("application/json"));
246        headers.insert("Accept", HeaderValue::from_static("application/json"));
247
248        // build user agent
249        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
250            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
251            Err(e) => {
252                log::warn!("Failed to parse user agent header: {e}, falling back to default");
253                headers.insert(
254                    reqwest::header::USER_AGENT,
255                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
256                )
257            }
258        };
259
260        // build auth
261        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
262            headers.insert(
263                "DD-API-KEY",
264                HeaderValue::from_str(local_key.key.as_str())
265                    .expect("failed to parse DD-API-KEY header"),
266            );
267        };
268        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
269            headers.insert(
270                "DD-APPLICATION-KEY",
271                HeaderValue::from_str(local_key.key.as_str())
272                    .expect("failed to parse DD-APPLICATION-KEY header"),
273            );
274        };
275
276        // build body parameters
277        let output = Vec::new();
278        let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter);
279        if body.serialize(&mut ser).is_ok() {
280            if let Some(content_encoding) = headers.get("Content-Encoding") {
281                match content_encoding.to_str().unwrap_or_default() {
282                    "gzip" => {
283                        let mut enc = GzEncoder::new(Vec::new(), Compression::default());
284                        let _ = enc.write_all(ser.into_inner().as_slice());
285                        match enc.finish() {
286                            Ok(buf) => {
287                                local_req_builder = local_req_builder.body(buf);
288                            }
289                            Err(e) => return Err(datadog::Error::Io(e)),
290                        }
291                    }
292                    "deflate" => {
293                        let mut enc = ZlibEncoder::new(Vec::new(), Compression::default());
294                        let _ = enc.write_all(ser.into_inner().as_slice());
295                        match enc.finish() {
296                            Ok(buf) => {
297                                local_req_builder = local_req_builder.body(buf);
298                            }
299                            Err(e) => return Err(datadog::Error::Io(e)),
300                        }
301                    }
302                    "zstd1" => {
303                        let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap();
304                        let _ = enc.write_all(ser.into_inner().as_slice());
305                        match enc.finish() {
306                            Ok(buf) => {
307                                local_req_builder = local_req_builder.body(buf);
308                            }
309                            Err(e) => return Err(datadog::Error::Io(e)),
310                        }
311                    }
312                    _ => {
313                        local_req_builder = local_req_builder.body(ser.into_inner());
314                    }
315                }
316            } else {
317                local_req_builder = local_req_builder.body(ser.into_inner());
318            }
319        }
320
321        local_req_builder = local_req_builder.headers(headers);
322        let local_req = local_req_builder.build()?;
323        log::debug!("request content: {:?}", local_req.body());
324        let local_resp = local_client.execute(local_req).await?;
325
326        let local_status = local_resp.status();
327        let local_content = local_resp.text().await?;
328        log::debug!("response content: {}", local_content);
329
330        if !local_status.is_client_error() && !local_status.is_server_error() {
331            match serde_json::from_str::<crate::datadogV2::model::IPAllowlistResponse>(
332                &local_content,
333            ) {
334                Ok(e) => {
335                    return Ok(datadog::ResponseContent {
336                        status: local_status,
337                        content: local_content,
338                        entity: Some(e),
339                    })
340                }
341                Err(e) => return Err(datadog::Error::Serde(e)),
342            };
343        } else {
344            let local_entity: Option<UpdateIPAllowlistError> =
345                serde_json::from_str(&local_content).ok();
346            let local_error = datadog::ResponseContent {
347                status: local_status,
348                content: local_content,
349                entity: local_entity,
350            };
351            Err(datadog::Error::ResponseError(local_error))
352        }
353    }
354}