diff --git a/.apigentools-info b/.apigentools-info index e5635d577..bb4f561fd 100644 --- a/.apigentools-info +++ b/.apigentools-info @@ -4,13 +4,13 @@ "spec_versions": { "v1": { "apigentools_version": "1.6.6", - "regenerated": "2025-05-19 17:45:10.256242", - "spec_repo_commit": "77e5efb9" + "regenerated": "2025-05-20 07:21:25.102606", + "spec_repo_commit": "fec20f97" }, "v2": { "apigentools_version": "1.6.6", - "regenerated": "2025-05-19 17:45:10.273841", - "spec_repo_commit": "77e5efb9" + "regenerated": "2025-05-20 07:21:25.118736", + "spec_repo_commit": "fec20f97" } } } \ No newline at end of file diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 631fc6d1b..79fc922a6 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -689,6 +689,21 @@ components: required: true schema: type: string + ResourceFilterAccountID: + description: Filter resource filters by cloud provider account ID. This parameter + is only valid when provider is specified. + in: query + name: account_id + required: false + schema: + type: string + ResourceFilterProvider: + description: Filter resource filters by cloud provider (e.g. aws, gcp, azure). + in: query + name: cloud_provider + required: false + schema: + type: string ResourceID: description: 'Identifier, formatted as `type:id`. Supported types: `connection`, `dashboard`, `integration-account`, `integration-service`, `integration-webhook`, @@ -807,6 +822,13 @@ components: required: true schema: type: string + SkipCache: + description: Skip cache for resource filters. + in: query + name: skip_cache + required: false + schema: + type: boolean SpansMetricIDParameter: description: The name of the span-based metric. in: path @@ -15715,6 +15737,26 @@ components: $ref: '#/components/schemas/GetInterfacesData' type: array type: object + GetResourceEvaluationFiltersResponse: + description: The definition of `GetResourceEvaluationFiltersResponse` object. + properties: + data: + $ref: '#/components/schemas/GetResourceEvaluationFiltersResponseData' + required: + - data + type: object + GetResourceEvaluationFiltersResponseData: + description: The definition of `GetResourceFilterResponseData` object. + properties: + attributes: + $ref: '#/components/schemas/ResourceFilterAttributes' + id: + description: The `data` `id`. + example: csm_resource_filter + type: string + type: + $ref: '#/components/schemas/ResourceFilterRequestType' + type: object GetRuleVersionHistoryData: description: Data for the rule version history. properties: @@ -29270,6 +29312,46 @@ components: required: - data type: object + ResourceFilterAttributes: + description: Attributes of a resource filter. + example: + aws: + '123456789': + - environment:production + - team:devops + azure: + sub-001: + - app:frontend + gcp: + project-abc: + - region:us-central1 + properties: + cloud_provider: + additionalProperties: + additionalProperties: + items: + description: Tag filter in format "key:value" + example: environment:production + type: string + type: array + type: object + description: A map of cloud provider names (e.g., "aws", "gcp", "azure") + to a map of account/resource IDs and their associated tag filters. + type: object + uuid: + description: The UUID of the resource filter. + type: string + required: + - cloud_provider + type: object + ResourceFilterRequestType: + description: Constant string to identify the request type. + enum: + - csm_resource_filter + example: csm_resource_filter + type: string + x-enum-varnames: + - CSM_RESOURCE_FILTER ResponseMetaAttributes: description: Object describing meta attributes of response. properties: @@ -32253,9 +32335,11 @@ components: example: true type: boolean SecurityMonitoringRuleKeepAlive: - description: "Once a signal is generated, the signal will remain \u201Copen\u201D - if a case is matched at least once within\nthis keep alive window. For third - party detection method, this field is not used." + description: 'Once a signal is generated, the signal will remain "open" if a + case is matched at least once within + + this keep alive window. For third party detection method, this field is not + used.' enum: - 0 - 60 @@ -32285,9 +32369,10 @@ components: - TWELVE_HOURS - ONE_DAY SecurityMonitoringRuleMaxSignalDuration: - description: "A signal will \u201Cclose\u201D regardless of the query being - matched once the time exceeds the maximum duration.\nThis time is calculated - from the first seen timestamp." + description: 'A signal will "close" regardless of the query being matched once + the time exceeds the maximum duration. + + This time is calculated from the first seen timestamp.' enum: - 0 - 60 @@ -38688,6 +38773,52 @@ components: id: $ref: '#/components/schemas/ApiID' type: object + UpdateResourceEvaluationFiltersRequest: + description: Request object to update a resource filter. + properties: + data: + $ref: '#/components/schemas/UpdateResourceEvaluationFiltersRequestData' + required: + - data + type: object + UpdateResourceEvaluationFiltersRequestData: + description: The definition of `UpdateResourceFilterRequestData` object. + properties: + attributes: + $ref: '#/components/schemas/ResourceFilterAttributes' + id: + description: The `UpdateResourceEvaluationFiltersRequestData` `id`. + example: csm_resource_filter + type: string + type: + $ref: '#/components/schemas/ResourceFilterRequestType' + required: + - attributes + - type + type: object + UpdateResourceEvaluationFiltersResponse: + description: The definition of `UpdateResourceEvaluationFiltersResponse` object. + properties: + data: + $ref: '#/components/schemas/UpdateResourceEvaluationFiltersResponseData' + required: + - data + type: object + UpdateResourceEvaluationFiltersResponseData: + description: The definition of `UpdateResourceFilterResponseData` object. + properties: + attributes: + $ref: '#/components/schemas/ResourceFilterAttributes' + id: + description: The `data` `id`. + example: csm_resource_filter + type: string + type: + $ref: '#/components/schemas/ResourceFilterRequestType' + required: + - attributes + - type + type: object UpdateRuleRequest: description: Request to update a scorecard rule. properties: @@ -43624,6 +43755,74 @@ paths: permissions: - security_monitoring_rules_read - security_monitoring_rules_write + /api/v2/cloud_security_management/resource_filters: + get: + description: List resource filters. + operationId: GetResourceEvaluationFilters + parameters: + - $ref: '#/components/parameters/ResourceFilterProvider' + - $ref: '#/components/parameters/ResourceFilterAccountID' + - $ref: '#/components/parameters/SkipCache' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/GetResourceEvaluationFiltersResponse' + description: OK + '400': + $ref: '#/components/responses/BadRequestResponse' + '403': + $ref: '#/components/responses/NotAuthorizedResponse' + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - security_monitoring_filters_read + summary: List resource filters + tags: + - Security Monitoring + x-permission: + operator: OR + permissions: + - security_monitoring_filters_read + put: + description: Update resource filters. + operationId: UpdateResourceEvaluationFilters + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateResourceEvaluationFiltersRequest' + required: true + responses: + '201': + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateResourceEvaluationFiltersResponse' + description: OK + '400': + $ref: '#/components/responses/BadRequestResponse' + '403': + $ref: '#/components/responses/NotAuthorizedResponse' + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - security_monitoring_filters_write + summary: Update resource filters + tags: + - Security Monitoring + x-codegen-request-body-name: body + x-permission: + operator: OR + permissions: + - security_monitoring_filters_write /api/v2/container_images: get: description: Get all Container Images for your organization. diff --git a/examples/v2_security-monitoring_GetResourceEvaluationFilters.rs b/examples/v2_security-monitoring_GetResourceEvaluationFilters.rs new file mode 100644 index 000000000..d7e02b7e8 --- /dev/null +++ b/examples/v2_security-monitoring_GetResourceEvaluationFilters.rs @@ -0,0 +1,22 @@ +// List resource filters returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_security_monitoring::GetResourceEvaluationFiltersOptionalParams; +use datadog_api_client::datadogV2::api_security_monitoring::SecurityMonitoringAPI; + +#[tokio::main] +async fn main() { + let configuration = datadog::Configuration::new(); + let api = SecurityMonitoringAPI::with_config(configuration); + let resp = api + .get_resource_evaluation_filters( + GetResourceEvaluationFiltersOptionalParams::default() + .cloud_provider("aws".to_string()) + .account_id("123456789".to_string()), + ) + .await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_security-monitoring_UpdateResourceEvaluationFilters.rs b/examples/v2_security-monitoring_UpdateResourceEvaluationFilters.rs new file mode 100644 index 000000000..dda561f72 --- /dev/null +++ b/examples/v2_security-monitoring_UpdateResourceEvaluationFilters.rs @@ -0,0 +1,30 @@ +// Update resource filters returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_security_monitoring::SecurityMonitoringAPI; +use datadog_api_client::datadogV2::model::ResourceFilterAttributes; +use datadog_api_client::datadogV2::model::ResourceFilterRequestType; +use datadog_api_client::datadogV2::model::UpdateResourceEvaluationFiltersRequest; +use datadog_api_client::datadogV2::model::UpdateResourceEvaluationFiltersRequestData; +use std::collections::BTreeMap; + +#[tokio::main] +async fn main() { + let body = UpdateResourceEvaluationFiltersRequest::new( + UpdateResourceEvaluationFiltersRequestData::new( + ResourceFilterAttributes::new(BTreeMap::from([( + "aws".to_string(), + BTreeMap::from([("aws_account_id".to_string(), vec!["tag1:v1".to_string()])]), + )])), + ResourceFilterRequestType::CSM_RESOURCE_FILTER, + ) + .id("csm_resource_filter".to_string()), + ); + let configuration = datadog::Configuration::new(); + let api = SecurityMonitoringAPI::with_config(configuration); + let resp = api.update_resource_evaluation_filters(body).await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/src/datadogV2/api/api_security_monitoring.rs b/src/datadogV2/api/api_security_monitoring.rs index a19c78ea9..591801dfb 100644 --- a/src/datadogV2/api/api_security_monitoring.rs +++ b/src/datadogV2/api/api_security_monitoring.rs @@ -29,6 +29,36 @@ impl GetFindingOptionalParams { } } +/// GetResourceEvaluationFiltersOptionalParams is a struct for passing parameters to the method [`SecurityMonitoringAPI::get_resource_evaluation_filters`] +#[non_exhaustive] +#[derive(Clone, Default, Debug)] +pub struct GetResourceEvaluationFiltersOptionalParams { + /// Filter resource filters by cloud provider (e.g. aws, gcp, azure). + pub cloud_provider: Option, + /// Filter resource filters by cloud provider account ID. This parameter is only valid when provider is specified. + pub account_id: Option, + /// Skip cache for resource filters. + pub skip_cache: Option, +} + +impl GetResourceEvaluationFiltersOptionalParams { + /// Filter resource filters by cloud provider (e.g. aws, gcp, azure). + pub fn cloud_provider(mut self, value: String) -> Self { + self.cloud_provider = Some(value); + self + } + /// Filter resource filters by cloud provider account ID. This parameter is only valid when provider is specified. + pub fn account_id(mut self, value: String) -> Self { + self.account_id = Some(value); + self + } + /// Skip cache for resource filters. + pub fn skip_cache(mut self, value: bool) -> Self { + self.skip_cache = Some(value); + self + } +} + /// GetRuleVersionHistoryOptionalParams is a struct for passing parameters to the method [`SecurityMonitoringAPI::get_rule_version_history`] #[non_exhaustive] #[derive(Clone, Default, Debug)] @@ -905,6 +935,14 @@ pub enum GetHistoricalJobError { UnknownValue(serde_json::Value), } +/// GetResourceEvaluationFiltersError is a struct for typed errors of method [`SecurityMonitoringAPI::get_resource_evaluation_filters`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum GetResourceEvaluationFiltersError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// GetRuleVersionHistoryError is a struct for typed errors of method [`SecurityMonitoringAPI::get_rule_version_history`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -1118,6 +1156,14 @@ pub enum UpdateCustomFrameworkError { UnknownValue(serde_json::Value), } +/// UpdateResourceEvaluationFiltersError is a struct for typed errors of method [`SecurityMonitoringAPI::update_resource_evaluation_filters`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum UpdateResourceEvaluationFiltersError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// UpdateSecurityFilterError is a struct for typed errors of method [`SecurityMonitoringAPI::update_security_filter`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -4186,6 +4232,136 @@ impl SecurityMonitoringAPI { } } + /// List resource filters. + pub async fn get_resource_evaluation_filters( + &self, + params: GetResourceEvaluationFiltersOptionalParams, + ) -> Result< + crate::datadogV2::model::GetResourceEvaluationFiltersResponse, + datadog::Error, + > { + match self + .get_resource_evaluation_filters_with_http_info(params) + .await + { + Ok(response_content) => { + if let Some(e) = response_content.entity { + Ok(e) + } else { + Err(datadog::Error::Serde(serde::de::Error::custom( + "response content was None", + ))) + } + } + Err(err) => Err(err), + } + } + + /// List resource filters. + pub async fn get_resource_evaluation_filters_with_http_info( + &self, + params: GetResourceEvaluationFiltersOptionalParams, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.get_resource_evaluation_filters"; + + // unbox and build optional parameters + let cloud_provider = params.cloud_provider; + let account_id = params.account_id; + let skip_cache = params.skip_cache; + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/cloud_security_management/resource_filters", + local_configuration.get_operation_host(operation_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::GET, local_uri_str.as_str()); + + if let Some(ref local_query_param) = cloud_provider { + local_req_builder = + local_req_builder.query(&[("cloud_provider", &local_query_param.to_string())]); + }; + if let Some(ref local_query_param) = account_id { + local_req_builder = + local_req_builder.query(&[("account_id", &local_query_param.to_string())]); + }; + if let Some(ref local_query_param) = skip_cache { + local_req_builder = + local_req_builder.query(&[("skip_cache", &local_query_param.to_string())]); + }; + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Accept", HeaderValue::from_static("application/json")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + match serde_json::from_str::< + crate::datadogV2::model::GetResourceEvaluationFiltersResponse, + >(&local_content) + { + Ok(e) => { + return Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: Some(e), + }) + } + Err(e) => return Err(datadog::Error::Serde(e)), + }; + } else { + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + /// Get a rule's version history. pub async fn get_rule_version_history( &self, @@ -8385,6 +8561,164 @@ impl SecurityMonitoringAPI { } } + /// Update resource filters. + pub async fn update_resource_evaluation_filters( + &self, + body: crate::datadogV2::model::UpdateResourceEvaluationFiltersRequest, + ) -> Result< + crate::datadogV2::model::UpdateResourceEvaluationFiltersResponse, + datadog::Error, + > { + match self + .update_resource_evaluation_filters_with_http_info(body) + .await + { + Ok(response_content) => { + if let Some(e) = response_content.entity { + Ok(e) + } else { + Err(datadog::Error::Serde(serde::de::Error::custom( + "response content was None", + ))) + } + } + Err(err) => Err(err), + } + } + + /// Update resource filters. + pub async fn update_resource_evaluation_filters_with_http_info( + &self, + body: crate::datadogV2::model::UpdateResourceEvaluationFiltersRequest, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.update_resource_evaluation_filters"; + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/cloud_security_management/resource_filters", + local_configuration.get_operation_host(operation_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::PUT, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Content-Type", HeaderValue::from_static("application/json")); + headers.insert("Accept", HeaderValue::from_static("application/json")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + // build body parameters + let output = Vec::new(); + let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter); + if body.serialize(&mut ser).is_ok() { + if let Some(content_encoding) = headers.get("Content-Encoding") { + match content_encoding.to_str().unwrap_or_default() { + "gzip" => { + let mut enc = GzEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "deflate" => { + let mut enc = ZlibEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "zstd1" => { + let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap(); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + _ => { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + } else { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + match serde_json::from_str::< + crate::datadogV2::model::UpdateResourceEvaluationFiltersResponse, + >(&local_content) + { + Ok(e) => { + return Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: Some(e), + }) + } + Err(e) => return Err(datadog::Error::Serde(e)), + }; + } else { + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + /// Update a specific security filter. /// Returns the security filter object when the request is successful. pub async fn update_security_filter( diff --git a/src/datadogV2/model/mod.rs b/src/datadogV2/model/mod.rs index e8f4de43f..6413b3c09 100644 --- a/src/datadogV2/model/mod.rs +++ b/src/datadogV2/model/mod.rs @@ -1012,6 +1012,22 @@ pub mod model_update_custom_framework_request; pub use self::model_update_custom_framework_request::UpdateCustomFrameworkRequest; pub mod model_update_custom_framework_response; pub use self::model_update_custom_framework_response::UpdateCustomFrameworkResponse; +pub mod model_get_resource_evaluation_filters_response; +pub use self::model_get_resource_evaluation_filters_response::GetResourceEvaluationFiltersResponse; +pub mod model_get_resource_evaluation_filters_response_data; +pub use self::model_get_resource_evaluation_filters_response_data::GetResourceEvaluationFiltersResponseData; +pub mod model_resource_filter_attributes; +pub use self::model_resource_filter_attributes::ResourceFilterAttributes; +pub mod model_resource_filter_request_type; +pub use self::model_resource_filter_request_type::ResourceFilterRequestType; +pub mod model_update_resource_evaluation_filters_request; +pub use self::model_update_resource_evaluation_filters_request::UpdateResourceEvaluationFiltersRequest; +pub mod model_update_resource_evaluation_filters_request_data; +pub use self::model_update_resource_evaluation_filters_request_data::UpdateResourceEvaluationFiltersRequestData; +pub mod model_update_resource_evaluation_filters_response; +pub use self::model_update_resource_evaluation_filters_response::UpdateResourceEvaluationFiltersResponse; +pub mod model_update_resource_evaluation_filters_response_data; +pub use self::model_update_resource_evaluation_filters_response_data::UpdateResourceEvaluationFiltersResponseData; pub mod model_container_images_response; pub use self::model_container_images_response::ContainerImagesResponse; pub mod model_container_image; diff --git a/src/datadogV2/model/model_get_resource_evaluation_filters_response.rs b/src/datadogV2/model/model_get_resource_evaluation_filters_response.rs new file mode 100644 index 000000000..c33f2ff16 --- /dev/null +++ b/src/datadogV2/model/model_get_resource_evaluation_filters_response.rs @@ -0,0 +1,96 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// The definition of `GetResourceEvaluationFiltersResponse` object. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct GetResourceEvaluationFiltersResponse { + /// The definition of `GetResourceFilterResponseData` object. + #[serde(rename = "data")] + pub data: crate::datadogV2::model::GetResourceEvaluationFiltersResponseData, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl GetResourceEvaluationFiltersResponse { + pub fn new( + data: crate::datadogV2::model::GetResourceEvaluationFiltersResponseData, + ) -> GetResourceEvaluationFiltersResponse { + GetResourceEvaluationFiltersResponse { + data, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for GetResourceEvaluationFiltersResponse { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct GetResourceEvaluationFiltersResponseVisitor; + impl<'a> Visitor<'a> for GetResourceEvaluationFiltersResponseVisitor { + type Value = GetResourceEvaluationFiltersResponse; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option< + crate::datadogV2::model::GetResourceEvaluationFiltersResponseData, + > = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let data = data.ok_or_else(|| M::Error::missing_field("data"))?; + + let content = GetResourceEvaluationFiltersResponse { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(GetResourceEvaluationFiltersResponseVisitor) + } +} diff --git a/src/datadogV2/model/model_get_resource_evaluation_filters_response_data.rs b/src/datadogV2/model/model_get_resource_evaluation_filters_response_data.rs new file mode 100644 index 000000000..e089f607d --- /dev/null +++ b/src/datadogV2/model/model_get_resource_evaluation_filters_response_data.rs @@ -0,0 +1,148 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// The definition of `GetResourceFilterResponseData` object. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct GetResourceEvaluationFiltersResponseData { + /// Attributes of a resource filter. + #[serde(rename = "attributes")] + pub attributes: Option, + /// The `data` `id`. + #[serde(rename = "id")] + pub id: Option, + /// Constant string to identify the request type. + #[serde(rename = "type")] + pub type_: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl GetResourceEvaluationFiltersResponseData { + pub fn new() -> GetResourceEvaluationFiltersResponseData { + GetResourceEvaluationFiltersResponseData { + attributes: None, + id: None, + type_: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn attributes(mut self, value: crate::datadogV2::model::ResourceFilterAttributes) -> Self { + self.attributes = Some(value); + self + } + + pub fn id(mut self, value: String) -> Self { + self.id = Some(value); + self + } + + pub fn type_(mut self, value: crate::datadogV2::model::ResourceFilterRequestType) -> Self { + self.type_ = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for GetResourceEvaluationFiltersResponseData { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for GetResourceEvaluationFiltersResponseData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct GetResourceEvaluationFiltersResponseDataVisitor; + impl<'a> Visitor<'a> for GetResourceEvaluationFiltersResponseDataVisitor { + type Value = GetResourceEvaluationFiltersResponseData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut attributes: Option = + None; + let mut id: Option = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "attributes" => { + if v.is_null() { + continue; + } + attributes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "id" => { + if v.is_null() { + continue; + } + id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + if v.is_null() { + continue; + } + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::ResourceFilterRequestType::UnparsedObject(_type_) => { + _unparsed = true; + }, + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = GetResourceEvaluationFiltersResponseData { + attributes, + id, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(GetResourceEvaluationFiltersResponseDataVisitor) + } +} diff --git a/src/datadogV2/model/model_historical_job_options.rs b/src/datadogV2/model/model_historical_job_options.rs index 2f1fa24e1..ab2862b00 100644 --- a/src/datadogV2/model/model_historical_job_options.rs +++ b/src/datadogV2/model/model_historical_job_options.rs @@ -22,11 +22,11 @@ pub struct HistoricalJobOptions { #[serde(rename = "impossibleTravelOptions")] pub impossible_travel_options: Option, - /// Once a signal is generated, the signal will remain “open” if a case is matched at least once within + /// Once a signal is generated, the signal will remain "open" if a case is matched at least once within /// this keep alive window. For third party detection method, this field is not used. #[serde(rename = "keepAlive")] pub keep_alive: Option, - /// A signal will “close” regardless of the query being matched once the time exceeds the maximum duration. + /// A signal will "close" regardless of the query being matched once the time exceeds the maximum duration. /// This time is calculated from the first seen timestamp. #[serde(rename = "maxSignalDuration")] pub max_signal_duration: diff --git a/src/datadogV2/model/model_resource_filter_attributes.rs b/src/datadogV2/model/model_resource_filter_attributes.rs new file mode 100644 index 000000000..9c207fd9b --- /dev/null +++ b/src/datadogV2/model/model_resource_filter_attributes.rs @@ -0,0 +1,122 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Attributes of a resource filter. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct ResourceFilterAttributes { + /// A map of cloud provider names (e.g., "aws", "gcp", "azure") to a map of account/resource IDs and their associated tag filters. + #[serde(rename = "cloud_provider")] + pub cloud_provider: + std::collections::BTreeMap>>, + /// The UUID of the resource filter. + #[serde(rename = "uuid")] + pub uuid: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl ResourceFilterAttributes { + pub fn new( + cloud_provider: std::collections::BTreeMap< + String, + std::collections::BTreeMap>, + >, + ) -> ResourceFilterAttributes { + ResourceFilterAttributes { + cloud_provider, + uuid: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn uuid(mut self, value: String) -> Self { + self.uuid = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for ResourceFilterAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct ResourceFilterAttributesVisitor; + impl<'a> Visitor<'a> for ResourceFilterAttributesVisitor { + type Value = ResourceFilterAttributes; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut cloud_provider: Option< + std::collections::BTreeMap< + String, + std::collections::BTreeMap>, + >, + > = None; + let mut uuid: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "cloud_provider" => { + cloud_provider = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "uuid" => { + if v.is_null() { + continue; + } + uuid = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let cloud_provider = + cloud_provider.ok_or_else(|| M::Error::missing_field("cloud_provider"))?; + + let content = ResourceFilterAttributes { + cloud_provider, + uuid, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(ResourceFilterAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_resource_filter_request_type.rs b/src/datadogV2/model/model_resource_filter_request_type.rs new file mode 100644 index 000000000..56175ee4f --- /dev/null +++ b/src/datadogV2/model/model_resource_filter_request_type.rs @@ -0,0 +1,48 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. + +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +#[non_exhaustive] +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum ResourceFilterRequestType { + CSM_RESOURCE_FILTER, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for ResourceFilterRequestType { + fn to_string(&self) -> String { + match self { + Self::CSM_RESOURCE_FILTER => String::from("csm_resource_filter"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for ResourceFilterRequestType { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Self::UnparsedObject(v) => v.serialize(serializer), + _ => serializer.serialize_str(self.to_string().as_str()), + } + } +} + +impl<'de> Deserialize<'de> for ResourceFilterRequestType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "csm_resource_filter" => Self::CSM_RESOURCE_FILTER, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/src/datadogV2/model/model_security_monitoring_rule_options.rs b/src/datadogV2/model/model_security_monitoring_rule_options.rs index dc1184e0d..dc7c79980 100644 --- a/src/datadogV2/model/model_security_monitoring_rule_options.rs +++ b/src/datadogV2/model/model_security_monitoring_rule_options.rs @@ -37,11 +37,11 @@ pub struct SecurityMonitoringRuleOptions { #[serde(rename = "impossibleTravelOptions")] pub impossible_travel_options: Option, - /// Once a signal is generated, the signal will remain “open” if a case is matched at least once within + /// Once a signal is generated, the signal will remain "open" if a case is matched at least once within /// this keep alive window. For third party detection method, this field is not used. #[serde(rename = "keepAlive")] pub keep_alive: Option, - /// A signal will “close” regardless of the query being matched once the time exceeds the maximum duration. + /// A signal will "close" regardless of the query being matched once the time exceeds the maximum duration. /// This time is calculated from the first seen timestamp. #[serde(rename = "maxSignalDuration")] pub max_signal_duration: diff --git a/src/datadogV2/model/model_update_resource_evaluation_filters_request.rs b/src/datadogV2/model/model_update_resource_evaluation_filters_request.rs new file mode 100644 index 000000000..95a0d21b6 --- /dev/null +++ b/src/datadogV2/model/model_update_resource_evaluation_filters_request.rs @@ -0,0 +1,96 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Request object to update a resource filter. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct UpdateResourceEvaluationFiltersRequest { + /// The definition of `UpdateResourceFilterRequestData` object. + #[serde(rename = "data")] + pub data: crate::datadogV2::model::UpdateResourceEvaluationFiltersRequestData, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl UpdateResourceEvaluationFiltersRequest { + pub fn new( + data: crate::datadogV2::model::UpdateResourceEvaluationFiltersRequestData, + ) -> UpdateResourceEvaluationFiltersRequest { + UpdateResourceEvaluationFiltersRequest { + data, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for UpdateResourceEvaluationFiltersRequest { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct UpdateResourceEvaluationFiltersRequestVisitor; + impl<'a> Visitor<'a> for UpdateResourceEvaluationFiltersRequestVisitor { + type Value = UpdateResourceEvaluationFiltersRequest; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option< + crate::datadogV2::model::UpdateResourceEvaluationFiltersRequestData, + > = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let data = data.ok_or_else(|| M::Error::missing_field("data"))?; + + let content = UpdateResourceEvaluationFiltersRequest { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(UpdateResourceEvaluationFiltersRequestVisitor) + } +} diff --git a/src/datadogV2/model/model_update_resource_evaluation_filters_request_data.rs b/src/datadogV2/model/model_update_resource_evaluation_filters_request_data.rs new file mode 100644 index 000000000..cbd9c220c --- /dev/null +++ b/src/datadogV2/model/model_update_resource_evaluation_filters_request_data.rs @@ -0,0 +1,131 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// The definition of `UpdateResourceFilterRequestData` object. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct UpdateResourceEvaluationFiltersRequestData { + /// Attributes of a resource filter. + #[serde(rename = "attributes")] + pub attributes: crate::datadogV2::model::ResourceFilterAttributes, + /// The `UpdateResourceEvaluationFiltersRequestData` `id`. + #[serde(rename = "id")] + pub id: Option, + /// Constant string to identify the request type. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::ResourceFilterRequestType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl UpdateResourceEvaluationFiltersRequestData { + pub fn new( + attributes: crate::datadogV2::model::ResourceFilterAttributes, + type_: crate::datadogV2::model::ResourceFilterRequestType, + ) -> UpdateResourceEvaluationFiltersRequestData { + UpdateResourceEvaluationFiltersRequestData { + attributes, + id: None, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn id(mut self, value: String) -> Self { + self.id = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for UpdateResourceEvaluationFiltersRequestData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct UpdateResourceEvaluationFiltersRequestDataVisitor; + impl<'a> Visitor<'a> for UpdateResourceEvaluationFiltersRequestDataVisitor { + type Value = UpdateResourceEvaluationFiltersRequestData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut attributes: Option = + None; + let mut id: Option = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "attributes" => { + attributes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "id" => { + if v.is_null() { + continue; + } + id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::ResourceFilterRequestType::UnparsedObject(_type_) => { + _unparsed = true; + }, + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let attributes = attributes.ok_or_else(|| M::Error::missing_field("attributes"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = UpdateResourceEvaluationFiltersRequestData { + attributes, + id, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(UpdateResourceEvaluationFiltersRequestDataVisitor) + } +} diff --git a/src/datadogV2/model/model_update_resource_evaluation_filters_response.rs b/src/datadogV2/model/model_update_resource_evaluation_filters_response.rs new file mode 100644 index 000000000..d58ba10c5 --- /dev/null +++ b/src/datadogV2/model/model_update_resource_evaluation_filters_response.rs @@ -0,0 +1,96 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// The definition of `UpdateResourceEvaluationFiltersResponse` object. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct UpdateResourceEvaluationFiltersResponse { + /// The definition of `UpdateResourceFilterResponseData` object. + #[serde(rename = "data")] + pub data: crate::datadogV2::model::UpdateResourceEvaluationFiltersResponseData, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl UpdateResourceEvaluationFiltersResponse { + pub fn new( + data: crate::datadogV2::model::UpdateResourceEvaluationFiltersResponseData, + ) -> UpdateResourceEvaluationFiltersResponse { + UpdateResourceEvaluationFiltersResponse { + data, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for UpdateResourceEvaluationFiltersResponse { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct UpdateResourceEvaluationFiltersResponseVisitor; + impl<'a> Visitor<'a> for UpdateResourceEvaluationFiltersResponseVisitor { + type Value = UpdateResourceEvaluationFiltersResponse; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option< + crate::datadogV2::model::UpdateResourceEvaluationFiltersResponseData, + > = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let data = data.ok_or_else(|| M::Error::missing_field("data"))?; + + let content = UpdateResourceEvaluationFiltersResponse { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(UpdateResourceEvaluationFiltersResponseVisitor) + } +} diff --git a/src/datadogV2/model/model_update_resource_evaluation_filters_response_data.rs b/src/datadogV2/model/model_update_resource_evaluation_filters_response_data.rs new file mode 100644 index 000000000..e80102701 --- /dev/null +++ b/src/datadogV2/model/model_update_resource_evaluation_filters_response_data.rs @@ -0,0 +1,131 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// The definition of `UpdateResourceFilterResponseData` object. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct UpdateResourceEvaluationFiltersResponseData { + /// Attributes of a resource filter. + #[serde(rename = "attributes")] + pub attributes: crate::datadogV2::model::ResourceFilterAttributes, + /// The `data` `id`. + #[serde(rename = "id")] + pub id: Option, + /// Constant string to identify the request type. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::ResourceFilterRequestType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl UpdateResourceEvaluationFiltersResponseData { + pub fn new( + attributes: crate::datadogV2::model::ResourceFilterAttributes, + type_: crate::datadogV2::model::ResourceFilterRequestType, + ) -> UpdateResourceEvaluationFiltersResponseData { + UpdateResourceEvaluationFiltersResponseData { + attributes, + id: None, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn id(mut self, value: String) -> Self { + self.id = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for UpdateResourceEvaluationFiltersResponseData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct UpdateResourceEvaluationFiltersResponseDataVisitor; + impl<'a> Visitor<'a> for UpdateResourceEvaluationFiltersResponseDataVisitor { + type Value = UpdateResourceEvaluationFiltersResponseData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut attributes: Option = + None; + let mut id: Option = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "attributes" => { + attributes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "id" => { + if v.is_null() { + continue; + } + id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::ResourceFilterRequestType::UnparsedObject(_type_) => { + _unparsed = true; + }, + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let attributes = attributes.ok_or_else(|| M::Error::missing_field("attributes"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = UpdateResourceEvaluationFiltersResponseData { + attributes, + id, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(UpdateResourceEvaluationFiltersResponseDataVisitor) + } +} diff --git a/tests/scenarios/cassettes/v2/security_monitoring/List-resource-filters-returns-Bad-Request-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/List-resource-filters-returns-Bad-Request-response.frozen new file mode 100644 index 000000000..1bcb49531 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/List-resource-filters-returns-Bad-Request-response.frozen @@ -0,0 +1 @@ +2025-05-06T08:24:43.362Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/List-resource-filters-returns-Bad-Request-response.json b/tests/scenarios/cassettes/v2/security_monitoring/List-resource-filters-returns-Bad-Request-response.json new file mode 100644 index 000000000..1c611f93d --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/List-resource-filters-returns-Bad-Request-response.json @@ -0,0 +1,33 @@ +{ + "http_interactions": [ + { + "request": { + "body": "", + "headers": { + "Accept": [ + "application/json" + ] + }, + "method": "get", + "uri": "https://api.datadoghq.com/api/v2/cloud_security_management/resource_filters?account_id=123456789" + }, + "response": { + "body": { + "string": "{\"errors\":[{\"status\":\"400\",\"title\":\"Bad Request\",\"detail\":\"Field 'account_id' is invalid: account_id provided without specifying the cloud provider\"}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 400, + "message": "Bad Request" + } + }, + "recorded_at": "Tue, 06 May 2025 08:24:43 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/List-resource-filters-returns-OK-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/List-resource-filters-returns-OK-response.frozen new file mode 100644 index 000000000..e99096d47 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/List-resource-filters-returns-OK-response.frozen @@ -0,0 +1 @@ +2025-05-06T10:03:18.837Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/List-resource-filters-returns-OK-response.json b/tests/scenarios/cassettes/v2/security_monitoring/List-resource-filters-returns-OK-response.json new file mode 100644 index 000000000..470b2dce2 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/List-resource-filters-returns-OK-response.json @@ -0,0 +1,33 @@ +{ + "http_interactions": [ + { + "request": { + "body": "", + "headers": { + "Accept": [ + "application/json" + ] + }, + "method": "get", + "uri": "https://api.datadoghq.com/api/v2/cloud_security_management/resource_filters?cloud_provider=aws&account_id=123456789" + }, + "response": { + "body": { + "string": "{\"data\":{\"id\":\"436195a0-5491-42a8-ac40-e0c0b61879bd\",\"type\":\"csm_resource_filter\",\"attributes\":{\"cloud_provider\":{}}}}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 200, + "message": "OK" + } + }, + "recorded_at": "Tue, 06 May 2025 10:03:18 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Update-resource-filters-returns-Bad-Request-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Update-resource-filters-returns-Bad-Request-response.frozen new file mode 100644 index 000000000..43e0b15fe --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Update-resource-filters-returns-Bad-Request-response.frozen @@ -0,0 +1 @@ +2025-05-15T09:52:48.266Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Update-resource-filters-returns-Bad-Request-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Update-resource-filters-returns-Bad-Request-response.json new file mode 100644 index 000000000..4486a59e1 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Update-resource-filters-returns-Bad-Request-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":{\"attributes\":{\"cloud_provider\":{\"invalid\":{\"aws_account_id\":[\"tag1:v1\"]}}},\"id\":\"csm_resource_filter\",\"type\":\"csm_resource_filter\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "put", + "uri": "https://api.datadoghq.com/api/v2/cloud_security_management/resource_filters" + }, + "response": { + "body": { + "string": "{\"errors\":[{\"status\":\"400\",\"title\":\"Bad Request\",\"detail\":\"Invalid cloud provider invalid\"}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 400, + "message": "Bad Request" + } + }, + "recorded_at": "Thu, 15 May 2025 09:52:48 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Update-resource-filters-returns-OK-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Update-resource-filters-returns-OK-response.frozen new file mode 100644 index 000000000..f30bda1aa --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Update-resource-filters-returns-OK-response.frozen @@ -0,0 +1 @@ +2025-05-15T09:52:49.297Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Update-resource-filters-returns-OK-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Update-resource-filters-returns-OK-response.json new file mode 100644 index 000000000..d27ec2c72 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Update-resource-filters-returns-OK-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":{\"attributes\":{\"cloud_provider\":{\"aws\":{\"aws_account_id\":[\"tag1:v1\"]}}},\"id\":\"csm_resource_filter\",\"type\":\"csm_resource_filter\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "put", + "uri": "https://api.datadoghq.com/api/v2/cloud_security_management/resource_filters" + }, + "response": { + "body": { + "string": "{\"data\":{\"id\":\"csm_resource_filter\",\"type\":\"csm_resource_filter\",\"attributes\":{\"cloud_provider\":{\"aws\":{\"aws_account_id\":[\"tag1:v1\"]}},\"uuid\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 201, + "message": "Created" + } + }, + "recorded_at": "Thu, 15 May 2025 09:52:49 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/features/v2/security_monitoring.feature b/tests/scenarios/features/v2/security_monitoring.feature index 0d71c0b6e..57200a366 100644 --- a/tests/scenarios/features/v2/security_monitoring.feature +++ b/tests/scenarios/features/v2/security_monitoring.feature @@ -872,6 +872,21 @@ Feature: Security Monitoring When the request is sent Then the response status is 200 OK + @team:DataDog/k9-cloud-security-platform + Scenario: List resource filters returns "Bad Request" response + Given new "GetResourceEvaluationFilters" request + And request contains "account_id" parameter with value "123456789" + When the request is sent + Then the response status is 400 Bad Request + + @team:DataDog/k9-cloud-security-platform + Scenario: List resource filters returns "OK" response + Given new "GetResourceEvaluationFilters" request + And request contains "cloud_provider" parameter with value "aws" + And request contains "account_id" parameter with value "123456789" + When the request is sent + Then the response status is 200 OK + @generated @skip @team:DataDog/k9-cloud-security-platform Scenario: List rules returns "Bad Request" response Given new "ListSecurityMonitoringRules" request @@ -1260,6 +1275,20 @@ Feature: Security Monitoring And the response "name" is equal to "{{ unique }}-Updated" And the response "id" has the same value as "security_rule.id" + @team:DataDog/k9-cloud-security-platform + Scenario: Update resource filters returns "Bad Request" response + Given new "UpdateResourceEvaluationFilters" request + And body with value {"data": {"attributes": {"cloud_provider": {"invalid": {"aws_account_id": ["tag1:v1"]}}}, "id": "csm_resource_filter", "type": "csm_resource_filter"}} + When the request is sent + Then the response status is 400 Bad Request + + @team:DataDog/k9-cloud-security-platform + Scenario: Update resource filters returns "OK" response + Given new "UpdateResourceEvaluationFilters" request + And body with value {"data": {"attributes": {"cloud_provider": {"aws": {"aws_account_id": ["tag1:v1"]}}}, "id": "csm_resource_filter", "type": "csm_resource_filter"}} + When the request is sent + Then the response status is 201 OK + @skip-go @skip-java @skip-python @skip-ruby @skip-rust @skip-typescript @skip-validation @team:DataDog/k9-cloud-security-platform Scenario: Validate a detection rule returns "Bad Request" response Given new "ValidateSecurityMonitoringRule" request diff --git a/tests/scenarios/features/v2/undo.json b/tests/scenarios/features/v2/undo.json index b9ea72c1d..6f0ee3848 100644 --- a/tests/scenarios/features/v2/undo.json +++ b/tests/scenarios/features/v2/undo.json @@ -548,6 +548,18 @@ "type": "idempotent" } }, + "GetResourceEvaluationFilters": { + "tag": "Security Monitoring", + "undo": { + "type": "safe" + } + }, + "UpdateResourceEvaluationFilters": { + "tag": "Security Monitoring", + "undo": { + "type": "idempotent" + } + }, "ListContainerImages": { "tag": "Container Images", "undo": { diff --git a/tests/scenarios/function_mappings.rs b/tests/scenarios/function_mappings.rs index 12d53fc49..8fa946fce 100644 --- a/tests/scenarios/function_mappings.rs +++ b/tests/scenarios/function_mappings.rs @@ -2025,6 +2025,14 @@ pub fn collect_function_calls(world: &mut DatadogWorld) { "v2.UpdateCustomFramework".into(), test_v2_update_custom_framework, ); + world.function_mappings.insert( + "v2.GetResourceEvaluationFilters".into(), + test_v2_get_resource_evaluation_filters, + ); + world.function_mappings.insert( + "v2.UpdateResourceEvaluationFilters".into(), + test_v2_update_resource_evaluation_filters, + ); world .function_mappings .insert("v2.ListFindings".into(), test_v2_list_findings); @@ -13815,6 +13823,75 @@ fn test_v2_update_custom_framework(world: &mut DatadogWorld, _parameters: &HashM world.response.code = response.status.as_u16(); } +fn test_v2_get_resource_evaluation_filters( + world: &mut DatadogWorld, + _parameters: &HashMap, +) { + let api = world + .api_instances + .v2_api_security_monitoring + .as_ref() + .expect("api instance not found"); + let cloud_provider = _parameters + .get("cloud_provider") + .and_then(|param| Some(serde_json::from_value(param.clone()).unwrap())); + let account_id = _parameters + .get("account_id") + .and_then(|param| Some(serde_json::from_value(param.clone()).unwrap())); + let skip_cache = _parameters + .get("skip_cache") + .and_then(|param| Some(serde_json::from_value(param.clone()).unwrap())); + let mut params = + datadogV2::api_security_monitoring::GetResourceEvaluationFiltersOptionalParams::default(); + params.cloud_provider = cloud_provider; + params.account_id = account_id; + params.skip_cache = skip_cache; + let response = match block_on(api.get_resource_evaluation_filters_with_http_info(params)) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + +fn test_v2_update_resource_evaluation_filters( + world: &mut DatadogWorld, + _parameters: &HashMap, +) { + let api = world + .api_instances + .v2_api_security_monitoring + .as_ref() + .expect("api instance not found"); + let body = serde_json::from_value(_parameters.get("body").unwrap().clone()).unwrap(); + let response = match block_on(api.update_resource_evaluation_filters_with_http_info(body)) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + fn test_v2_list_findings(world: &mut DatadogWorld, _parameters: &HashMap) { let api = world .api_instances