datadog_api_client/datadogV2/api/
api_observability_pipelines.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 log::warn;
10use reqwest::header::{HeaderMap, HeaderValue};
11use serde::{Deserialize, Serialize};
12use std::io::Write;
13
14/// ListPipelinesOptionalParams is a struct for passing parameters to the method [`ObservabilityPipelinesAPI::list_pipelines`]
15#[non_exhaustive]
16#[derive(Clone, Default, Debug)]
17pub struct ListPipelinesOptionalParams {
18    /// Size for a given page. The maximum allowed value is 100.
19    pub page_size: Option<i64>,
20    /// Specific page number to return.
21    pub page_number: Option<i64>,
22}
23
24impl ListPipelinesOptionalParams {
25    /// Size for a given page. The maximum allowed value is 100.
26    pub fn page_size(mut self, value: i64) -> Self {
27        self.page_size = Some(value);
28        self
29    }
30    /// Specific page number to return.
31    pub fn page_number(mut self, value: i64) -> Self {
32        self.page_number = Some(value);
33        self
34    }
35}
36
37/// CreatePipelineError is a struct for typed errors of method [`ObservabilityPipelinesAPI::create_pipeline`]
38#[derive(Debug, Clone, Serialize, Deserialize)]
39#[serde(untagged)]
40pub enum CreatePipelineError {
41    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
42    UnknownValue(serde_json::Value),
43}
44
45/// DeletePipelineError is a struct for typed errors of method [`ObservabilityPipelinesAPI::delete_pipeline`]
46#[derive(Debug, Clone, Serialize, Deserialize)]
47#[serde(untagged)]
48pub enum DeletePipelineError {
49    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
50    UnknownValue(serde_json::Value),
51}
52
53/// GetPipelineError is a struct for typed errors of method [`ObservabilityPipelinesAPI::get_pipeline`]
54#[derive(Debug, Clone, Serialize, Deserialize)]
55#[serde(untagged)]
56pub enum GetPipelineError {
57    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
58    UnknownValue(serde_json::Value),
59}
60
61/// ListPipelinesError is a struct for typed errors of method [`ObservabilityPipelinesAPI::list_pipelines`]
62#[derive(Debug, Clone, Serialize, Deserialize)]
63#[serde(untagged)]
64pub enum ListPipelinesError {
65    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
66    UnknownValue(serde_json::Value),
67}
68
69/// UpdatePipelineError is a struct for typed errors of method [`ObservabilityPipelinesAPI::update_pipeline`]
70#[derive(Debug, Clone, Serialize, Deserialize)]
71#[serde(untagged)]
72pub enum UpdatePipelineError {
73    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
74    UnknownValue(serde_json::Value),
75}
76
77/// ValidatePipelineError is a struct for typed errors of method [`ObservabilityPipelinesAPI::validate_pipeline`]
78#[derive(Debug, Clone, Serialize, Deserialize)]
79#[serde(untagged)]
80pub enum ValidatePipelineError {
81    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
82    UnknownValue(serde_json::Value),
83}
84
85/// Observability Pipelines allows you to collect and process logs within your own infrastructure, and then route them to downstream integrations.
86#[derive(Debug, Clone)]
87pub struct ObservabilityPipelinesAPI {
88    config: datadog::Configuration,
89    client: reqwest_middleware::ClientWithMiddleware,
90}
91
92impl Default for ObservabilityPipelinesAPI {
93    fn default() -> Self {
94        Self::with_config(datadog::Configuration::default())
95    }
96}
97
98impl ObservabilityPipelinesAPI {
99    pub fn new() -> Self {
100        Self::default()
101    }
102    pub fn with_config(config: datadog::Configuration) -> Self {
103        let mut reqwest_client_builder = reqwest::Client::builder();
104
105        if let Some(proxy_url) = &config.proxy_url {
106            let proxy = reqwest::Proxy::all(proxy_url).expect("Failed to parse proxy URL");
107            reqwest_client_builder = reqwest_client_builder.proxy(proxy);
108        }
109
110        let mut middleware_client_builder =
111            reqwest_middleware::ClientBuilder::new(reqwest_client_builder.build().unwrap());
112
113        if config.enable_retry {
114            struct RetryableStatus;
115            impl reqwest_retry::RetryableStrategy for RetryableStatus {
116                fn handle(
117                    &self,
118                    res: &Result<reqwest::Response, reqwest_middleware::Error>,
119                ) -> Option<reqwest_retry::Retryable> {
120                    match res {
121                        Ok(success) => reqwest_retry::default_on_request_success(success),
122                        Err(_) => None,
123                    }
124                }
125            }
126            let backoff_policy = reqwest_retry::policies::ExponentialBackoff::builder()
127                .build_with_max_retries(config.max_retries);
128
129            let retry_middleware =
130                reqwest_retry::RetryTransientMiddleware::new_with_policy_and_strategy(
131                    backoff_policy,
132                    RetryableStatus,
133                );
134
135            middleware_client_builder = middleware_client_builder.with(retry_middleware);
136        }
137
138        let client = middleware_client_builder.build();
139
140        Self { config, client }
141    }
142
143    pub fn with_client_and_config(
144        config: datadog::Configuration,
145        client: reqwest_middleware::ClientWithMiddleware,
146    ) -> Self {
147        Self { config, client }
148    }
149
150    /// Create a new pipeline.
151    pub async fn create_pipeline(
152        &self,
153        body: crate::datadogV2::model::ObservabilityPipelineSpec,
154    ) -> Result<crate::datadogV2::model::ObservabilityPipeline, datadog::Error<CreatePipelineError>>
155    {
156        match self.create_pipeline_with_http_info(body).await {
157            Ok(response_content) => {
158                if let Some(e) = response_content.entity {
159                    Ok(e)
160                } else {
161                    Err(datadog::Error::Serde(serde::de::Error::custom(
162                        "response content was None",
163                    )))
164                }
165            }
166            Err(err) => Err(err),
167        }
168    }
169
170    /// Create a new pipeline.
171    pub async fn create_pipeline_with_http_info(
172        &self,
173        body: crate::datadogV2::model::ObservabilityPipelineSpec,
174    ) -> Result<
175        datadog::ResponseContent<crate::datadogV2::model::ObservabilityPipeline>,
176        datadog::Error<CreatePipelineError>,
177    > {
178        let local_configuration = &self.config;
179        let operation_id = "v2.create_pipeline";
180        if local_configuration.is_unstable_operation_enabled(operation_id) {
181            warn!("Using unstable operation {operation_id}");
182        } else {
183            let local_error = datadog::UnstableOperationDisabledError {
184                msg: "Operation 'v2.create_pipeline' is not enabled".to_string(),
185            };
186            return Err(datadog::Error::UnstableOperationDisabledError(local_error));
187        }
188
189        let local_client = &self.client;
190
191        let local_uri_str = format!(
192            "{}/api/v2/remote_config/products/obs_pipelines/pipelines",
193            local_configuration.get_operation_host(operation_id)
194        );
195        let mut local_req_builder =
196            local_client.request(reqwest::Method::POST, local_uri_str.as_str());
197
198        // build headers
199        let mut headers = HeaderMap::new();
200        headers.insert("Content-Type", HeaderValue::from_static("application/json"));
201        headers.insert("Accept", HeaderValue::from_static("application/json"));
202
203        // build user agent
204        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
205            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
206            Err(e) => {
207                log::warn!("Failed to parse user agent header: {e}, falling back to default");
208                headers.insert(
209                    reqwest::header::USER_AGENT,
210                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
211                )
212            }
213        };
214
215        // build auth
216        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
217            headers.insert(
218                "DD-API-KEY",
219                HeaderValue::from_str(local_key.key.as_str())
220                    .expect("failed to parse DD-API-KEY header"),
221            );
222        };
223        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
224            headers.insert(
225                "DD-APPLICATION-KEY",
226                HeaderValue::from_str(local_key.key.as_str())
227                    .expect("failed to parse DD-APPLICATION-KEY header"),
228            );
229        };
230
231        // build body parameters
232        let output = Vec::new();
233        let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter);
234        if body.serialize(&mut ser).is_ok() {
235            if let Some(content_encoding) = headers.get("Content-Encoding") {
236                match content_encoding.to_str().unwrap_or_default() {
237                    "gzip" => {
238                        let mut enc = GzEncoder::new(Vec::new(), Compression::default());
239                        let _ = enc.write_all(ser.into_inner().as_slice());
240                        match enc.finish() {
241                            Ok(buf) => {
242                                local_req_builder = local_req_builder.body(buf);
243                            }
244                            Err(e) => return Err(datadog::Error::Io(e)),
245                        }
246                    }
247                    "deflate" => {
248                        let mut enc = ZlibEncoder::new(Vec::new(), Compression::default());
249                        let _ = enc.write_all(ser.into_inner().as_slice());
250                        match enc.finish() {
251                            Ok(buf) => {
252                                local_req_builder = local_req_builder.body(buf);
253                            }
254                            Err(e) => return Err(datadog::Error::Io(e)),
255                        }
256                    }
257                    "zstd1" => {
258                        let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap();
259                        let _ = enc.write_all(ser.into_inner().as_slice());
260                        match enc.finish() {
261                            Ok(buf) => {
262                                local_req_builder = local_req_builder.body(buf);
263                            }
264                            Err(e) => return Err(datadog::Error::Io(e)),
265                        }
266                    }
267                    _ => {
268                        local_req_builder = local_req_builder.body(ser.into_inner());
269                    }
270                }
271            } else {
272                local_req_builder = local_req_builder.body(ser.into_inner());
273            }
274        }
275
276        local_req_builder = local_req_builder.headers(headers);
277        let local_req = local_req_builder.build()?;
278        log::debug!("request content: {:?}", local_req.body());
279        let local_resp = local_client.execute(local_req).await?;
280
281        let local_status = local_resp.status();
282        let local_content = local_resp.text().await?;
283        log::debug!("response content: {}", local_content);
284
285        if !local_status.is_client_error() && !local_status.is_server_error() {
286            match serde_json::from_str::<crate::datadogV2::model::ObservabilityPipeline>(
287                &local_content,
288            ) {
289                Ok(e) => {
290                    return Ok(datadog::ResponseContent {
291                        status: local_status,
292                        content: local_content,
293                        entity: Some(e),
294                    })
295                }
296                Err(e) => return Err(datadog::Error::Serde(e)),
297            };
298        } else {
299            let local_entity: Option<CreatePipelineError> =
300                serde_json::from_str(&local_content).ok();
301            let local_error = datadog::ResponseContent {
302                status: local_status,
303                content: local_content,
304                entity: local_entity,
305            };
306            Err(datadog::Error::ResponseError(local_error))
307        }
308    }
309
310    /// Delete a pipeline.
311    pub async fn delete_pipeline(
312        &self,
313        pipeline_id: String,
314    ) -> Result<(), datadog::Error<DeletePipelineError>> {
315        match self.delete_pipeline_with_http_info(pipeline_id).await {
316            Ok(_) => Ok(()),
317            Err(err) => Err(err),
318        }
319    }
320
321    /// Delete a pipeline.
322    pub async fn delete_pipeline_with_http_info(
323        &self,
324        pipeline_id: String,
325    ) -> Result<datadog::ResponseContent<()>, datadog::Error<DeletePipelineError>> {
326        let local_configuration = &self.config;
327        let operation_id = "v2.delete_pipeline";
328        if local_configuration.is_unstable_operation_enabled(operation_id) {
329            warn!("Using unstable operation {operation_id}");
330        } else {
331            let local_error = datadog::UnstableOperationDisabledError {
332                msg: "Operation 'v2.delete_pipeline' is not enabled".to_string(),
333            };
334            return Err(datadog::Error::UnstableOperationDisabledError(local_error));
335        }
336
337        let local_client = &self.client;
338
339        let local_uri_str = format!(
340            "{}/api/v2/remote_config/products/obs_pipelines/pipelines/{pipeline_id}",
341            local_configuration.get_operation_host(operation_id),
342            pipeline_id = datadog::urlencode(pipeline_id)
343        );
344        let mut local_req_builder =
345            local_client.request(reqwest::Method::DELETE, local_uri_str.as_str());
346
347        // build headers
348        let mut headers = HeaderMap::new();
349        headers.insert("Accept", HeaderValue::from_static("*/*"));
350
351        // build user agent
352        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
353            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
354            Err(e) => {
355                log::warn!("Failed to parse user agent header: {e}, falling back to default");
356                headers.insert(
357                    reqwest::header::USER_AGENT,
358                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
359                )
360            }
361        };
362
363        // build auth
364        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
365            headers.insert(
366                "DD-API-KEY",
367                HeaderValue::from_str(local_key.key.as_str())
368                    .expect("failed to parse DD-API-KEY header"),
369            );
370        };
371        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
372            headers.insert(
373                "DD-APPLICATION-KEY",
374                HeaderValue::from_str(local_key.key.as_str())
375                    .expect("failed to parse DD-APPLICATION-KEY header"),
376            );
377        };
378
379        local_req_builder = local_req_builder.headers(headers);
380        let local_req = local_req_builder.build()?;
381        log::debug!("request content: {:?}", local_req.body());
382        let local_resp = local_client.execute(local_req).await?;
383
384        let local_status = local_resp.status();
385        let local_content = local_resp.text().await?;
386        log::debug!("response content: {}", local_content);
387
388        if !local_status.is_client_error() && !local_status.is_server_error() {
389            Ok(datadog::ResponseContent {
390                status: local_status,
391                content: local_content,
392                entity: None,
393            })
394        } else {
395            let local_entity: Option<DeletePipelineError> =
396                serde_json::from_str(&local_content).ok();
397            let local_error = datadog::ResponseContent {
398                status: local_status,
399                content: local_content,
400                entity: local_entity,
401            };
402            Err(datadog::Error::ResponseError(local_error))
403        }
404    }
405
406    /// Get a specific pipeline by its ID.
407    pub async fn get_pipeline(
408        &self,
409        pipeline_id: String,
410    ) -> Result<crate::datadogV2::model::ObservabilityPipeline, datadog::Error<GetPipelineError>>
411    {
412        match self.get_pipeline_with_http_info(pipeline_id).await {
413            Ok(response_content) => {
414                if let Some(e) = response_content.entity {
415                    Ok(e)
416                } else {
417                    Err(datadog::Error::Serde(serde::de::Error::custom(
418                        "response content was None",
419                    )))
420                }
421            }
422            Err(err) => Err(err),
423        }
424    }
425
426    /// Get a specific pipeline by its ID.
427    pub async fn get_pipeline_with_http_info(
428        &self,
429        pipeline_id: String,
430    ) -> Result<
431        datadog::ResponseContent<crate::datadogV2::model::ObservabilityPipeline>,
432        datadog::Error<GetPipelineError>,
433    > {
434        let local_configuration = &self.config;
435        let operation_id = "v2.get_pipeline";
436        if local_configuration.is_unstable_operation_enabled(operation_id) {
437            warn!("Using unstable operation {operation_id}");
438        } else {
439            let local_error = datadog::UnstableOperationDisabledError {
440                msg: "Operation 'v2.get_pipeline' is not enabled".to_string(),
441            };
442            return Err(datadog::Error::UnstableOperationDisabledError(local_error));
443        }
444
445        let local_client = &self.client;
446
447        let local_uri_str = format!(
448            "{}/api/v2/remote_config/products/obs_pipelines/pipelines/{pipeline_id}",
449            local_configuration.get_operation_host(operation_id),
450            pipeline_id = datadog::urlencode(pipeline_id)
451        );
452        let mut local_req_builder =
453            local_client.request(reqwest::Method::GET, local_uri_str.as_str());
454
455        // build headers
456        let mut headers = HeaderMap::new();
457        headers.insert("Accept", HeaderValue::from_static("application/json"));
458
459        // build user agent
460        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
461            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
462            Err(e) => {
463                log::warn!("Failed to parse user agent header: {e}, falling back to default");
464                headers.insert(
465                    reqwest::header::USER_AGENT,
466                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
467                )
468            }
469        };
470
471        // build auth
472        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
473            headers.insert(
474                "DD-API-KEY",
475                HeaderValue::from_str(local_key.key.as_str())
476                    .expect("failed to parse DD-API-KEY header"),
477            );
478        };
479        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
480            headers.insert(
481                "DD-APPLICATION-KEY",
482                HeaderValue::from_str(local_key.key.as_str())
483                    .expect("failed to parse DD-APPLICATION-KEY header"),
484            );
485        };
486
487        local_req_builder = local_req_builder.headers(headers);
488        let local_req = local_req_builder.build()?;
489        log::debug!("request content: {:?}", local_req.body());
490        let local_resp = local_client.execute(local_req).await?;
491
492        let local_status = local_resp.status();
493        let local_content = local_resp.text().await?;
494        log::debug!("response content: {}", local_content);
495
496        if !local_status.is_client_error() && !local_status.is_server_error() {
497            match serde_json::from_str::<crate::datadogV2::model::ObservabilityPipeline>(
498                &local_content,
499            ) {
500                Ok(e) => {
501                    return Ok(datadog::ResponseContent {
502                        status: local_status,
503                        content: local_content,
504                        entity: Some(e),
505                    })
506                }
507                Err(e) => return Err(datadog::Error::Serde(e)),
508            };
509        } else {
510            let local_entity: Option<GetPipelineError> = serde_json::from_str(&local_content).ok();
511            let local_error = datadog::ResponseContent {
512                status: local_status,
513                content: local_content,
514                entity: local_entity,
515            };
516            Err(datadog::Error::ResponseError(local_error))
517        }
518    }
519
520    /// Retrieve a list of pipelines.
521    pub async fn list_pipelines(
522        &self,
523        params: ListPipelinesOptionalParams,
524    ) -> Result<crate::datadogV2::model::ListPipelinesResponse, datadog::Error<ListPipelinesError>>
525    {
526        match self.list_pipelines_with_http_info(params).await {
527            Ok(response_content) => {
528                if let Some(e) = response_content.entity {
529                    Ok(e)
530                } else {
531                    Err(datadog::Error::Serde(serde::de::Error::custom(
532                        "response content was None",
533                    )))
534                }
535            }
536            Err(err) => Err(err),
537        }
538    }
539
540    /// Retrieve a list of pipelines.
541    pub async fn list_pipelines_with_http_info(
542        &self,
543        params: ListPipelinesOptionalParams,
544    ) -> Result<
545        datadog::ResponseContent<crate::datadogV2::model::ListPipelinesResponse>,
546        datadog::Error<ListPipelinesError>,
547    > {
548        let local_configuration = &self.config;
549        let operation_id = "v2.list_pipelines";
550        if local_configuration.is_unstable_operation_enabled(operation_id) {
551            warn!("Using unstable operation {operation_id}");
552        } else {
553            let local_error = datadog::UnstableOperationDisabledError {
554                msg: "Operation 'v2.list_pipelines' is not enabled".to_string(),
555            };
556            return Err(datadog::Error::UnstableOperationDisabledError(local_error));
557        }
558
559        // unbox and build optional parameters
560        let page_size = params.page_size;
561        let page_number = params.page_number;
562
563        let local_client = &self.client;
564
565        let local_uri_str = format!(
566            "{}/api/v2/remote_config/products/obs_pipelines/pipelines",
567            local_configuration.get_operation_host(operation_id)
568        );
569        let mut local_req_builder =
570            local_client.request(reqwest::Method::GET, local_uri_str.as_str());
571
572        if let Some(ref local_query_param) = page_size {
573            local_req_builder =
574                local_req_builder.query(&[("page[size]", &local_query_param.to_string())]);
575        };
576        if let Some(ref local_query_param) = page_number {
577            local_req_builder =
578                local_req_builder.query(&[("page[number]", &local_query_param.to_string())]);
579        };
580
581        // build headers
582        let mut headers = HeaderMap::new();
583        headers.insert("Accept", HeaderValue::from_static("application/json"));
584
585        // build user agent
586        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
587            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
588            Err(e) => {
589                log::warn!("Failed to parse user agent header: {e}, falling back to default");
590                headers.insert(
591                    reqwest::header::USER_AGENT,
592                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
593                )
594            }
595        };
596
597        // build auth
598        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
599            headers.insert(
600                "DD-API-KEY",
601                HeaderValue::from_str(local_key.key.as_str())
602                    .expect("failed to parse DD-API-KEY header"),
603            );
604        };
605        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
606            headers.insert(
607                "DD-APPLICATION-KEY",
608                HeaderValue::from_str(local_key.key.as_str())
609                    .expect("failed to parse DD-APPLICATION-KEY header"),
610            );
611        };
612
613        local_req_builder = local_req_builder.headers(headers);
614        let local_req = local_req_builder.build()?;
615        log::debug!("request content: {:?}", local_req.body());
616        let local_resp = local_client.execute(local_req).await?;
617
618        let local_status = local_resp.status();
619        let local_content = local_resp.text().await?;
620        log::debug!("response content: {}", local_content);
621
622        if !local_status.is_client_error() && !local_status.is_server_error() {
623            match serde_json::from_str::<crate::datadogV2::model::ListPipelinesResponse>(
624                &local_content,
625            ) {
626                Ok(e) => {
627                    return Ok(datadog::ResponseContent {
628                        status: local_status,
629                        content: local_content,
630                        entity: Some(e),
631                    })
632                }
633                Err(e) => return Err(datadog::Error::Serde(e)),
634            };
635        } else {
636            let local_entity: Option<ListPipelinesError> =
637                serde_json::from_str(&local_content).ok();
638            let local_error = datadog::ResponseContent {
639                status: local_status,
640                content: local_content,
641                entity: local_entity,
642            };
643            Err(datadog::Error::ResponseError(local_error))
644        }
645    }
646
647    /// Update a pipeline.
648    pub async fn update_pipeline(
649        &self,
650        pipeline_id: String,
651        body: crate::datadogV2::model::ObservabilityPipeline,
652    ) -> Result<crate::datadogV2::model::ObservabilityPipeline, datadog::Error<UpdatePipelineError>>
653    {
654        match self.update_pipeline_with_http_info(pipeline_id, body).await {
655            Ok(response_content) => {
656                if let Some(e) = response_content.entity {
657                    Ok(e)
658                } else {
659                    Err(datadog::Error::Serde(serde::de::Error::custom(
660                        "response content was None",
661                    )))
662                }
663            }
664            Err(err) => Err(err),
665        }
666    }
667
668    /// Update a pipeline.
669    pub async fn update_pipeline_with_http_info(
670        &self,
671        pipeline_id: String,
672        body: crate::datadogV2::model::ObservabilityPipeline,
673    ) -> Result<
674        datadog::ResponseContent<crate::datadogV2::model::ObservabilityPipeline>,
675        datadog::Error<UpdatePipelineError>,
676    > {
677        let local_configuration = &self.config;
678        let operation_id = "v2.update_pipeline";
679        if local_configuration.is_unstable_operation_enabled(operation_id) {
680            warn!("Using unstable operation {operation_id}");
681        } else {
682            let local_error = datadog::UnstableOperationDisabledError {
683                msg: "Operation 'v2.update_pipeline' is not enabled".to_string(),
684            };
685            return Err(datadog::Error::UnstableOperationDisabledError(local_error));
686        }
687
688        let local_client = &self.client;
689
690        let local_uri_str = format!(
691            "{}/api/v2/remote_config/products/obs_pipelines/pipelines/{pipeline_id}",
692            local_configuration.get_operation_host(operation_id),
693            pipeline_id = datadog::urlencode(pipeline_id)
694        );
695        let mut local_req_builder =
696            local_client.request(reqwest::Method::PUT, local_uri_str.as_str());
697
698        // build headers
699        let mut headers = HeaderMap::new();
700        headers.insert("Content-Type", HeaderValue::from_static("application/json"));
701        headers.insert("Accept", HeaderValue::from_static("application/json"));
702
703        // build user agent
704        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
705            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
706            Err(e) => {
707                log::warn!("Failed to parse user agent header: {e}, falling back to default");
708                headers.insert(
709                    reqwest::header::USER_AGENT,
710                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
711                )
712            }
713        };
714
715        // build auth
716        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
717            headers.insert(
718                "DD-API-KEY",
719                HeaderValue::from_str(local_key.key.as_str())
720                    .expect("failed to parse DD-API-KEY header"),
721            );
722        };
723        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
724            headers.insert(
725                "DD-APPLICATION-KEY",
726                HeaderValue::from_str(local_key.key.as_str())
727                    .expect("failed to parse DD-APPLICATION-KEY header"),
728            );
729        };
730
731        // build body parameters
732        let output = Vec::new();
733        let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter);
734        if body.serialize(&mut ser).is_ok() {
735            if let Some(content_encoding) = headers.get("Content-Encoding") {
736                match content_encoding.to_str().unwrap_or_default() {
737                    "gzip" => {
738                        let mut enc = GzEncoder::new(Vec::new(), Compression::default());
739                        let _ = enc.write_all(ser.into_inner().as_slice());
740                        match enc.finish() {
741                            Ok(buf) => {
742                                local_req_builder = local_req_builder.body(buf);
743                            }
744                            Err(e) => return Err(datadog::Error::Io(e)),
745                        }
746                    }
747                    "deflate" => {
748                        let mut enc = ZlibEncoder::new(Vec::new(), Compression::default());
749                        let _ = enc.write_all(ser.into_inner().as_slice());
750                        match enc.finish() {
751                            Ok(buf) => {
752                                local_req_builder = local_req_builder.body(buf);
753                            }
754                            Err(e) => return Err(datadog::Error::Io(e)),
755                        }
756                    }
757                    "zstd1" => {
758                        let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap();
759                        let _ = enc.write_all(ser.into_inner().as_slice());
760                        match enc.finish() {
761                            Ok(buf) => {
762                                local_req_builder = local_req_builder.body(buf);
763                            }
764                            Err(e) => return Err(datadog::Error::Io(e)),
765                        }
766                    }
767                    _ => {
768                        local_req_builder = local_req_builder.body(ser.into_inner());
769                    }
770                }
771            } else {
772                local_req_builder = local_req_builder.body(ser.into_inner());
773            }
774        }
775
776        local_req_builder = local_req_builder.headers(headers);
777        let local_req = local_req_builder.build()?;
778        log::debug!("request content: {:?}", local_req.body());
779        let local_resp = local_client.execute(local_req).await?;
780
781        let local_status = local_resp.status();
782        let local_content = local_resp.text().await?;
783        log::debug!("response content: {}", local_content);
784
785        if !local_status.is_client_error() && !local_status.is_server_error() {
786            match serde_json::from_str::<crate::datadogV2::model::ObservabilityPipeline>(
787                &local_content,
788            ) {
789                Ok(e) => {
790                    return Ok(datadog::ResponseContent {
791                        status: local_status,
792                        content: local_content,
793                        entity: Some(e),
794                    })
795                }
796                Err(e) => return Err(datadog::Error::Serde(e)),
797            };
798        } else {
799            let local_entity: Option<UpdatePipelineError> =
800                serde_json::from_str(&local_content).ok();
801            let local_error = datadog::ResponseContent {
802                status: local_status,
803                content: local_content,
804                entity: local_entity,
805            };
806            Err(datadog::Error::ResponseError(local_error))
807        }
808    }
809
810    /// Validates a pipeline configuration without creating or updating any resources.
811    /// Returns a list of validation errors, if any.
812    ///
813    pub async fn validate_pipeline(
814        &self,
815        body: crate::datadogV2::model::ObservabilityPipelineSpec,
816    ) -> Result<crate::datadogV2::model::ValidationResponse, datadog::Error<ValidatePipelineError>>
817    {
818        match self.validate_pipeline_with_http_info(body).await {
819            Ok(response_content) => {
820                if let Some(e) = response_content.entity {
821                    Ok(e)
822                } else {
823                    Err(datadog::Error::Serde(serde::de::Error::custom(
824                        "response content was None",
825                    )))
826                }
827            }
828            Err(err) => Err(err),
829        }
830    }
831
832    /// Validates a pipeline configuration without creating or updating any resources.
833    /// Returns a list of validation errors, if any.
834    ///
835    pub async fn validate_pipeline_with_http_info(
836        &self,
837        body: crate::datadogV2::model::ObservabilityPipelineSpec,
838    ) -> Result<
839        datadog::ResponseContent<crate::datadogV2::model::ValidationResponse>,
840        datadog::Error<ValidatePipelineError>,
841    > {
842        let local_configuration = &self.config;
843        let operation_id = "v2.validate_pipeline";
844        if local_configuration.is_unstable_operation_enabled(operation_id) {
845            warn!("Using unstable operation {operation_id}");
846        } else {
847            let local_error = datadog::UnstableOperationDisabledError {
848                msg: "Operation 'v2.validate_pipeline' is not enabled".to_string(),
849            };
850            return Err(datadog::Error::UnstableOperationDisabledError(local_error));
851        }
852
853        let local_client = &self.client;
854
855        let local_uri_str = format!(
856            "{}/api/v2/remote_config/products/obs_pipelines/pipelines/validate",
857            local_configuration.get_operation_host(operation_id)
858        );
859        let mut local_req_builder =
860            local_client.request(reqwest::Method::POST, local_uri_str.as_str());
861
862        // build headers
863        let mut headers = HeaderMap::new();
864        headers.insert("Content-Type", HeaderValue::from_static("application/json"));
865        headers.insert("Accept", HeaderValue::from_static("application/json"));
866
867        // build user agent
868        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
869            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
870            Err(e) => {
871                log::warn!("Failed to parse user agent header: {e}, falling back to default");
872                headers.insert(
873                    reqwest::header::USER_AGENT,
874                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
875                )
876            }
877        };
878
879        // build auth
880        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
881            headers.insert(
882                "DD-API-KEY",
883                HeaderValue::from_str(local_key.key.as_str())
884                    .expect("failed to parse DD-API-KEY header"),
885            );
886        };
887        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
888            headers.insert(
889                "DD-APPLICATION-KEY",
890                HeaderValue::from_str(local_key.key.as_str())
891                    .expect("failed to parse DD-APPLICATION-KEY header"),
892            );
893        };
894
895        // build body parameters
896        let output = Vec::new();
897        let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter);
898        if body.serialize(&mut ser).is_ok() {
899            if let Some(content_encoding) = headers.get("Content-Encoding") {
900                match content_encoding.to_str().unwrap_or_default() {
901                    "gzip" => {
902                        let mut enc = GzEncoder::new(Vec::new(), Compression::default());
903                        let _ = enc.write_all(ser.into_inner().as_slice());
904                        match enc.finish() {
905                            Ok(buf) => {
906                                local_req_builder = local_req_builder.body(buf);
907                            }
908                            Err(e) => return Err(datadog::Error::Io(e)),
909                        }
910                    }
911                    "deflate" => {
912                        let mut enc = ZlibEncoder::new(Vec::new(), Compression::default());
913                        let _ = enc.write_all(ser.into_inner().as_slice());
914                        match enc.finish() {
915                            Ok(buf) => {
916                                local_req_builder = local_req_builder.body(buf);
917                            }
918                            Err(e) => return Err(datadog::Error::Io(e)),
919                        }
920                    }
921                    "zstd1" => {
922                        let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap();
923                        let _ = enc.write_all(ser.into_inner().as_slice());
924                        match enc.finish() {
925                            Ok(buf) => {
926                                local_req_builder = local_req_builder.body(buf);
927                            }
928                            Err(e) => return Err(datadog::Error::Io(e)),
929                        }
930                    }
931                    _ => {
932                        local_req_builder = local_req_builder.body(ser.into_inner());
933                    }
934                }
935            } else {
936                local_req_builder = local_req_builder.body(ser.into_inner());
937            }
938        }
939
940        local_req_builder = local_req_builder.headers(headers);
941        let local_req = local_req_builder.build()?;
942        log::debug!("request content: {:?}", local_req.body());
943        let local_resp = local_client.execute(local_req).await?;
944
945        let local_status = local_resp.status();
946        let local_content = local_resp.text().await?;
947        log::debug!("response content: {}", local_content);
948
949        if !local_status.is_client_error() && !local_status.is_server_error() {
950            match serde_json::from_str::<crate::datadogV2::model::ValidationResponse>(
951                &local_content,
952            ) {
953                Ok(e) => {
954                    return Ok(datadog::ResponseContent {
955                        status: local_status,
956                        content: local_content,
957                        entity: Some(e),
958                    })
959                }
960                Err(e) => return Err(datadog::Error::Serde(e)),
961            };
962        } else {
963            let local_entity: Option<ValidatePipelineError> =
964                serde_json::from_str(&local_content).ok();
965            let local_error = datadog::ResponseContent {
966                status: local_status,
967                content: local_content,
968                entity: local_entity,
969            };
970            Err(datadog::Error::ResponseError(local_error))
971        }
972    }
973}