datadog_api_client/datadogV2/api/
api_organizations.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/// UploadIdPMetadataOptionalParams is a struct for passing parameters to the method [`OrganizationsAPI::upload_idp_metadata`]
14#[non_exhaustive]
15#[derive(Clone, Default, Debug)]
16pub struct UploadIdPMetadataOptionalParams {
17    /// The IdP metadata XML file
18    pub idp_file: Option<Vec<u8>>,
19}
20
21impl UploadIdPMetadataOptionalParams {
22    /// The IdP metadata XML file
23    pub fn idp_file(mut self, value: Vec<u8>) -> Self {
24        self.idp_file = Some(value);
25        self
26    }
27}
28
29/// GetOrgConfigError is a struct for typed errors of method [`OrganizationsAPI::get_org_config`]
30#[derive(Debug, Clone, Serialize, Deserialize)]
31#[serde(untagged)]
32pub enum GetOrgConfigError {
33    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
34    UnknownValue(serde_json::Value),
35}
36
37/// ListOrgConfigsError is a struct for typed errors of method [`OrganizationsAPI::list_org_configs`]
38#[derive(Debug, Clone, Serialize, Deserialize)]
39#[serde(untagged)]
40pub enum ListOrgConfigsError {
41    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
42    UnknownValue(serde_json::Value),
43}
44
45/// UpdateOrgConfigError is a struct for typed errors of method [`OrganizationsAPI::update_org_config`]
46#[derive(Debug, Clone, Serialize, Deserialize)]
47#[serde(untagged)]
48pub enum UpdateOrgConfigError {
49    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
50    UnknownValue(serde_json::Value),
51}
52
53/// UploadIdPMetadataError is a struct for typed errors of method [`OrganizationsAPI::upload_idp_metadata`]
54#[derive(Debug, Clone, Serialize, Deserialize)]
55#[serde(untagged)]
56pub enum UploadIdPMetadataError {
57    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
58    UnknownValue(serde_json::Value),
59}
60
61/// Create, edit, and manage your organizations. Read more about [multi-org accounts](<https://docs.datadoghq.com/account_management/multi_organization>).
62#[derive(Debug, Clone)]
63pub struct OrganizationsAPI {
64    config: datadog::Configuration,
65    client: reqwest_middleware::ClientWithMiddleware,
66}
67
68impl Default for OrganizationsAPI {
69    fn default() -> Self {
70        Self::with_config(datadog::Configuration::default())
71    }
72}
73
74impl OrganizationsAPI {
75    pub fn new() -> Self {
76        Self::default()
77    }
78    pub fn with_config(config: datadog::Configuration) -> Self {
79        let mut reqwest_client_builder = reqwest::Client::builder();
80
81        if let Some(proxy_url) = &config.proxy_url {
82            let proxy = reqwest::Proxy::all(proxy_url).expect("Failed to parse proxy URL");
83            reqwest_client_builder = reqwest_client_builder.proxy(proxy);
84        }
85
86        let mut middleware_client_builder =
87            reqwest_middleware::ClientBuilder::new(reqwest_client_builder.build().unwrap());
88
89        if config.enable_retry {
90            struct RetryableStatus;
91            impl reqwest_retry::RetryableStrategy for RetryableStatus {
92                fn handle(
93                    &self,
94                    res: &Result<reqwest::Response, reqwest_middleware::Error>,
95                ) -> Option<reqwest_retry::Retryable> {
96                    match res {
97                        Ok(success) => reqwest_retry::default_on_request_success(success),
98                        Err(_) => None,
99                    }
100                }
101            }
102            let backoff_policy = reqwest_retry::policies::ExponentialBackoff::builder()
103                .build_with_max_retries(config.max_retries);
104
105            let retry_middleware =
106                reqwest_retry::RetryTransientMiddleware::new_with_policy_and_strategy(
107                    backoff_policy,
108                    RetryableStatus,
109                );
110
111            middleware_client_builder = middleware_client_builder.with(retry_middleware);
112        }
113
114        let client = middleware_client_builder.build();
115
116        Self { config, client }
117    }
118
119    pub fn with_client_and_config(
120        config: datadog::Configuration,
121        client: reqwest_middleware::ClientWithMiddleware,
122    ) -> Self {
123        Self { config, client }
124    }
125
126    /// Return the name, description, and value of a specific Org Config.
127    pub async fn get_org_config(
128        &self,
129        org_config_name: String,
130    ) -> Result<crate::datadogV2::model::OrgConfigGetResponse, datadog::Error<GetOrgConfigError>>
131    {
132        match self.get_org_config_with_http_info(org_config_name).await {
133            Ok(response_content) => {
134                if let Some(e) = response_content.entity {
135                    Ok(e)
136                } else {
137                    Err(datadog::Error::Serde(serde::de::Error::custom(
138                        "response content was None",
139                    )))
140                }
141            }
142            Err(err) => Err(err),
143        }
144    }
145
146    /// Return the name, description, and value of a specific Org Config.
147    pub async fn get_org_config_with_http_info(
148        &self,
149        org_config_name: String,
150    ) -> Result<
151        datadog::ResponseContent<crate::datadogV2::model::OrgConfigGetResponse>,
152        datadog::Error<GetOrgConfigError>,
153    > {
154        let local_configuration = &self.config;
155        let operation_id = "v2.get_org_config";
156
157        let local_client = &self.client;
158
159        let local_uri_str = format!(
160            "{}/api/v2/org_configs/{org_config_name}",
161            local_configuration.get_operation_host(operation_id),
162            org_config_name = datadog::urlencode(org_config_name)
163        );
164        let mut local_req_builder =
165            local_client.request(reqwest::Method::GET, local_uri_str.as_str());
166
167        // build headers
168        let mut headers = HeaderMap::new();
169        headers.insert("Accept", HeaderValue::from_static("application/json"));
170
171        // build user agent
172        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
173            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
174            Err(e) => {
175                log::warn!("Failed to parse user agent header: {e}, falling back to default");
176                headers.insert(
177                    reqwest::header::USER_AGENT,
178                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
179                )
180            }
181        };
182
183        // build auth
184        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
185            headers.insert(
186                "DD-API-KEY",
187                HeaderValue::from_str(local_key.key.as_str())
188                    .expect("failed to parse DD-API-KEY header"),
189            );
190        };
191        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
192            headers.insert(
193                "DD-APPLICATION-KEY",
194                HeaderValue::from_str(local_key.key.as_str())
195                    .expect("failed to parse DD-APPLICATION-KEY header"),
196            );
197        };
198
199        local_req_builder = local_req_builder.headers(headers);
200        let local_req = local_req_builder.build()?;
201        log::debug!("request content: {:?}", local_req.body());
202        let local_resp = local_client.execute(local_req).await?;
203
204        let local_status = local_resp.status();
205        let local_content = local_resp.text().await?;
206        log::debug!("response content: {}", local_content);
207
208        if !local_status.is_client_error() && !local_status.is_server_error() {
209            match serde_json::from_str::<crate::datadogV2::model::OrgConfigGetResponse>(
210                &local_content,
211            ) {
212                Ok(e) => {
213                    return Ok(datadog::ResponseContent {
214                        status: local_status,
215                        content: local_content,
216                        entity: Some(e),
217                    })
218                }
219                Err(e) => return Err(datadog::Error::Serde(e)),
220            };
221        } else {
222            let local_entity: Option<GetOrgConfigError> = serde_json::from_str(&local_content).ok();
223            let local_error = datadog::ResponseContent {
224                status: local_status,
225                content: local_content,
226                entity: local_entity,
227            };
228            Err(datadog::Error::ResponseError(local_error))
229        }
230    }
231
232    /// Returns all Org Configs (name, description, and value).
233    pub async fn list_org_configs(
234        &self,
235    ) -> Result<crate::datadogV2::model::OrgConfigListResponse, datadog::Error<ListOrgConfigsError>>
236    {
237        match self.list_org_configs_with_http_info().await {
238            Ok(response_content) => {
239                if let Some(e) = response_content.entity {
240                    Ok(e)
241                } else {
242                    Err(datadog::Error::Serde(serde::de::Error::custom(
243                        "response content was None",
244                    )))
245                }
246            }
247            Err(err) => Err(err),
248        }
249    }
250
251    /// Returns all Org Configs (name, description, and value).
252    pub async fn list_org_configs_with_http_info(
253        &self,
254    ) -> Result<
255        datadog::ResponseContent<crate::datadogV2::model::OrgConfigListResponse>,
256        datadog::Error<ListOrgConfigsError>,
257    > {
258        let local_configuration = &self.config;
259        let operation_id = "v2.list_org_configs";
260
261        let local_client = &self.client;
262
263        let local_uri_str = format!(
264            "{}/api/v2/org_configs",
265            local_configuration.get_operation_host(operation_id)
266        );
267        let mut local_req_builder =
268            local_client.request(reqwest::Method::GET, local_uri_str.as_str());
269
270        // build headers
271        let mut headers = HeaderMap::new();
272        headers.insert("Accept", HeaderValue::from_static("application/json"));
273
274        // build user agent
275        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
276            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
277            Err(e) => {
278                log::warn!("Failed to parse user agent header: {e}, falling back to default");
279                headers.insert(
280                    reqwest::header::USER_AGENT,
281                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
282                )
283            }
284        };
285
286        // build auth
287        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
288            headers.insert(
289                "DD-API-KEY",
290                HeaderValue::from_str(local_key.key.as_str())
291                    .expect("failed to parse DD-API-KEY header"),
292            );
293        };
294        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
295            headers.insert(
296                "DD-APPLICATION-KEY",
297                HeaderValue::from_str(local_key.key.as_str())
298                    .expect("failed to parse DD-APPLICATION-KEY header"),
299            );
300        };
301
302        local_req_builder = local_req_builder.headers(headers);
303        let local_req = local_req_builder.build()?;
304        log::debug!("request content: {:?}", local_req.body());
305        let local_resp = local_client.execute(local_req).await?;
306
307        let local_status = local_resp.status();
308        let local_content = local_resp.text().await?;
309        log::debug!("response content: {}", local_content);
310
311        if !local_status.is_client_error() && !local_status.is_server_error() {
312            match serde_json::from_str::<crate::datadogV2::model::OrgConfigListResponse>(
313                &local_content,
314            ) {
315                Ok(e) => {
316                    return Ok(datadog::ResponseContent {
317                        status: local_status,
318                        content: local_content,
319                        entity: Some(e),
320                    })
321                }
322                Err(e) => return Err(datadog::Error::Serde(e)),
323            };
324        } else {
325            let local_entity: Option<ListOrgConfigsError> =
326                serde_json::from_str(&local_content).ok();
327            let local_error = datadog::ResponseContent {
328                status: local_status,
329                content: local_content,
330                entity: local_entity,
331            };
332            Err(datadog::Error::ResponseError(local_error))
333        }
334    }
335
336    /// Update the value of a specific Org Config.
337    pub async fn update_org_config(
338        &self,
339        org_config_name: String,
340        body: crate::datadogV2::model::OrgConfigWriteRequest,
341    ) -> Result<crate::datadogV2::model::OrgConfigGetResponse, datadog::Error<UpdateOrgConfigError>>
342    {
343        match self
344            .update_org_config_with_http_info(org_config_name, body)
345            .await
346        {
347            Ok(response_content) => {
348                if let Some(e) = response_content.entity {
349                    Ok(e)
350                } else {
351                    Err(datadog::Error::Serde(serde::de::Error::custom(
352                        "response content was None",
353                    )))
354                }
355            }
356            Err(err) => Err(err),
357        }
358    }
359
360    /// Update the value of a specific Org Config.
361    pub async fn update_org_config_with_http_info(
362        &self,
363        org_config_name: String,
364        body: crate::datadogV2::model::OrgConfigWriteRequest,
365    ) -> Result<
366        datadog::ResponseContent<crate::datadogV2::model::OrgConfigGetResponse>,
367        datadog::Error<UpdateOrgConfigError>,
368    > {
369        let local_configuration = &self.config;
370        let operation_id = "v2.update_org_config";
371
372        let local_client = &self.client;
373
374        let local_uri_str = format!(
375            "{}/api/v2/org_configs/{org_config_name}",
376            local_configuration.get_operation_host(operation_id),
377            org_config_name = datadog::urlencode(org_config_name)
378        );
379        let mut local_req_builder =
380            local_client.request(reqwest::Method::PATCH, local_uri_str.as_str());
381
382        // build headers
383        let mut headers = HeaderMap::new();
384        headers.insert("Content-Type", HeaderValue::from_static("application/json"));
385        headers.insert("Accept", HeaderValue::from_static("application/json"));
386
387        // build user agent
388        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
389            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
390            Err(e) => {
391                log::warn!("Failed to parse user agent header: {e}, falling back to default");
392                headers.insert(
393                    reqwest::header::USER_AGENT,
394                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
395                )
396            }
397        };
398
399        // build auth
400        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
401            headers.insert(
402                "DD-API-KEY",
403                HeaderValue::from_str(local_key.key.as_str())
404                    .expect("failed to parse DD-API-KEY header"),
405            );
406        };
407        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
408            headers.insert(
409                "DD-APPLICATION-KEY",
410                HeaderValue::from_str(local_key.key.as_str())
411                    .expect("failed to parse DD-APPLICATION-KEY header"),
412            );
413        };
414
415        // build body parameters
416        let output = Vec::new();
417        let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter);
418        if body.serialize(&mut ser).is_ok() {
419            if let Some(content_encoding) = headers.get("Content-Encoding") {
420                match content_encoding.to_str().unwrap_or_default() {
421                    "gzip" => {
422                        let mut enc = GzEncoder::new(Vec::new(), Compression::default());
423                        let _ = enc.write_all(ser.into_inner().as_slice());
424                        match enc.finish() {
425                            Ok(buf) => {
426                                local_req_builder = local_req_builder.body(buf);
427                            }
428                            Err(e) => return Err(datadog::Error::Io(e)),
429                        }
430                    }
431                    "deflate" => {
432                        let mut enc = ZlibEncoder::new(Vec::new(), Compression::default());
433                        let _ = enc.write_all(ser.into_inner().as_slice());
434                        match enc.finish() {
435                            Ok(buf) => {
436                                local_req_builder = local_req_builder.body(buf);
437                            }
438                            Err(e) => return Err(datadog::Error::Io(e)),
439                        }
440                    }
441                    "zstd1" => {
442                        let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap();
443                        let _ = enc.write_all(ser.into_inner().as_slice());
444                        match enc.finish() {
445                            Ok(buf) => {
446                                local_req_builder = local_req_builder.body(buf);
447                            }
448                            Err(e) => return Err(datadog::Error::Io(e)),
449                        }
450                    }
451                    _ => {
452                        local_req_builder = local_req_builder.body(ser.into_inner());
453                    }
454                }
455            } else {
456                local_req_builder = local_req_builder.body(ser.into_inner());
457            }
458        }
459
460        local_req_builder = local_req_builder.headers(headers);
461        let local_req = local_req_builder.build()?;
462        log::debug!("request content: {:?}", local_req.body());
463        let local_resp = local_client.execute(local_req).await?;
464
465        let local_status = local_resp.status();
466        let local_content = local_resp.text().await?;
467        log::debug!("response content: {}", local_content);
468
469        if !local_status.is_client_error() && !local_status.is_server_error() {
470            match serde_json::from_str::<crate::datadogV2::model::OrgConfigGetResponse>(
471                &local_content,
472            ) {
473                Ok(e) => {
474                    return Ok(datadog::ResponseContent {
475                        status: local_status,
476                        content: local_content,
477                        entity: Some(e),
478                    })
479                }
480                Err(e) => return Err(datadog::Error::Serde(e)),
481            };
482        } else {
483            let local_entity: Option<UpdateOrgConfigError> =
484                serde_json::from_str(&local_content).ok();
485            let local_error = datadog::ResponseContent {
486                status: local_status,
487                content: local_content,
488                entity: local_entity,
489            };
490            Err(datadog::Error::ResponseError(local_error))
491        }
492    }
493
494    /// Endpoint for uploading IdP metadata for SAML setup.
495    ///
496    /// Use this endpoint to upload or replace IdP metadata for SAML login configuration.
497    pub async fn upload_idp_metadata(
498        &self,
499        params: UploadIdPMetadataOptionalParams,
500    ) -> Result<(), datadog::Error<UploadIdPMetadataError>> {
501        match self.upload_idp_metadata_with_http_info(params).await {
502            Ok(_) => Ok(()),
503            Err(err) => Err(err),
504        }
505    }
506
507    /// Endpoint for uploading IdP metadata for SAML setup.
508    ///
509    /// Use this endpoint to upload or replace IdP metadata for SAML login configuration.
510    pub async fn upload_idp_metadata_with_http_info(
511        &self,
512        params: UploadIdPMetadataOptionalParams,
513    ) -> Result<datadog::ResponseContent<()>, datadog::Error<UploadIdPMetadataError>> {
514        let local_configuration = &self.config;
515        let operation_id = "v2.upload_idp_metadata";
516
517        // unbox and build optional parameters
518        let idp_file = params.idp_file;
519
520        let local_client = &self.client;
521
522        let local_uri_str = format!(
523            "{}/api/v2/saml_configurations/idp_metadata",
524            local_configuration.get_operation_host(operation_id)
525        );
526        let mut local_req_builder =
527            local_client.request(reqwest::Method::POST, local_uri_str.as_str());
528
529        // build headers
530        let mut headers = HeaderMap::new();
531        headers.insert(
532            "Content-Type",
533            HeaderValue::from_static("multipart/form-data"),
534        );
535        headers.insert("Accept", HeaderValue::from_static("*/*"));
536
537        // build user agent
538        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
539            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
540            Err(e) => {
541                log::warn!("Failed to parse user agent header: {e}, falling back to default");
542                headers.insert(
543                    reqwest::header::USER_AGENT,
544                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
545                )
546            }
547        };
548
549        // build auth
550        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
551            headers.insert(
552                "DD-API-KEY",
553                HeaderValue::from_str(local_key.key.as_str())
554                    .expect("failed to parse DD-API-KEY header"),
555            );
556        };
557        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
558            headers.insert(
559                "DD-APPLICATION-KEY",
560                HeaderValue::from_str(local_key.key.as_str())
561                    .expect("failed to parse DD-APPLICATION-KEY header"),
562            );
563        };
564
565        // build form parameters
566        if let Some(idp_file) = idp_file {
567            let mut local_form = form_data_builder::FormData::new(Vec::new());
568            let cursor = std::io::Cursor::new(idp_file);
569            if let Err(e) = local_form.write_file(
570                "idp_file",
571                cursor,
572                Some("idp_file".as_ref()),
573                "application/octet-stream",
574            ) {
575                return Err(crate::datadog::Error::Io(e));
576            };
577            headers.insert(
578                "Content-Type",
579                local_form.content_type_header().parse().unwrap(),
580            );
581            let form_result = local_form.finish();
582            match form_result {
583                Ok(form) => local_req_builder = local_req_builder.body(form),
584                Err(e) => return Err(crate::datadog::Error::Io(e)),
585            };
586        };
587
588        local_req_builder = local_req_builder.headers(headers);
589        let local_req = local_req_builder.build()?;
590        log::debug!("request content: {:?}", local_req.body());
591        let local_resp = local_client.execute(local_req).await?;
592
593        let local_status = local_resp.status();
594        let local_content = local_resp.text().await?;
595        log::debug!("response content: {}", local_content);
596
597        if !local_status.is_client_error() && !local_status.is_server_error() {
598            Ok(datadog::ResponseContent {
599                status: local_status,
600                content: local_content,
601                entity: None,
602            })
603        } else {
604            let local_entity: Option<UploadIdPMetadataError> =
605                serde_json::from_str(&local_content).ok();
606            let local_error = datadog::ResponseContent {
607                status: local_status,
608                content: local_content,
609                entity: local_entity,
610            };
611            Err(datadog::Error::ResponseError(local_error))
612        }
613    }
614}