From ca82852d1411cc9060271858740a69922a28e6e8 Mon Sep 17 00:00:00 2001 From: "ci.datadog-api-spec" Date: Mon, 8 Jun 2026 15:08:37 +0000 Subject: [PATCH] Regenerate client from commit e6354d0 of spec repo --- .generator/schemas/v2/openapi.yaml | 223 ++++++++++++++ ...ecurity-monitoring_CreateIoCTriageState.rs | 23 ++ ...ity-monitoring_GetIndicatorOfCompromise.rs | 4 +- src/datadog/configuration.rs | 1 + src/datadogV2/api/api_security_monitoring.rs | 272 +++++++++++++++++- src/datadogV2/model/mod.rs | 14 + src/datadogV2/model/model_io_c_indicator.rs | 52 ++++ .../model/model_io_c_indicator_detailed.rs | 70 +++++ .../model/model_io_c_triage_event.rs | 140 +++++++++ .../model/model_io_c_triage_write_request.rs | 92 ++++++ ...el_io_c_triage_write_request_attributes.rs | 104 +++++++ .../model_io_c_triage_write_request_data.rs | 107 +++++++ .../model/model_io_c_triage_write_response.rs | 105 +++++++ ...l_io_c_triage_write_response_attributes.rs | 174 +++++++++++ .../model_io_c_triage_write_response_data.rs | 144 ++++++++++ ...-state-returns-Bad-Request-response.frozen | 1 + ...ge-state-returns-Bad-Request-response.json | 39 +++ ...iage-state-returns-Created-response.frozen | 1 + ...triage-state-returns-Created-response.json | 39 +++ ...r-of-compromise-returns-OK-response.frozen | 2 +- ...tor-of-compromise-returns-OK-response.json | 6 +- ...s-of-compromise-returns-OK-response.frozen | 2 +- ...ors-of-compromise-returns-OK-response.json | 4 +- .../features/v2/security_monitoring.feature | 19 +- tests/scenarios/features/v2/undo.json | 6 + tests/scenarios/function_mappings.rs | 65 ++++- 26 files changed, 1698 insertions(+), 11 deletions(-) create mode 100644 examples/v2_security-monitoring_CreateIoCTriageState.rs create mode 100644 src/datadogV2/model/model_io_c_triage_event.rs create mode 100644 src/datadogV2/model/model_io_c_triage_write_request.rs create mode 100644 src/datadogV2/model/model_io_c_triage_write_request_attributes.rs create mode 100644 src/datadogV2/model/model_io_c_triage_write_request_data.rs create mode 100644 src/datadogV2/model/model_io_c_triage_write_response.rs create mode 100644 src/datadogV2/model/model_io_c_triage_write_response_attributes.rs create mode 100644 src/datadogV2/model/model_io_c_triage_write_response_data.rs create mode 100644 tests/scenarios/cassettes/v2/security_monitoring/Create-or-update-an-indicator-triage-state-returns-Bad-Request-response.frozen create mode 100644 tests/scenarios/cassettes/v2/security_monitoring/Create-or-update-an-indicator-triage-state-returns-Bad-Request-response.json create mode 100644 tests/scenarios/cassettes/v2/security_monitoring/Create-or-update-an-indicator-triage-state-returns-Created-response.frozen create mode 100644 tests/scenarios/cassettes/v2/security_monitoring/Create-or-update-an-indicator-triage-state-returns-Created-response.json diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 2d470c8f2f..2d1f24f090 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -44181,6 +44181,16 @@ components: items: type: string type: array + triage_state: + description: "Current triage state of the indicator: not_reviewed or reviewed." + type: string + triaged_at: + description: Timestamp when the indicator was last triaged. + format: date-time + type: string + triaged_by: + description: UUID of the user who last triaged the indicator. + type: string type: object IoCIndicatorDetailed: description: An indicator of compromise with extended context from your environment. @@ -44299,6 +44309,21 @@ components: items: type: string type: array + triage_history: + description: Full triage history timeline. Returned only when `include_triage_history` is true. + items: + $ref: "#/components/schemas/IoCTriageEvent" + type: array + triage_state: + description: "Current triage state of the indicator: not_reviewed or reviewed." + type: string + triaged_at: + description: Timestamp when the indicator was last triaged. + format: date-time + type: string + triaged_by: + description: UUID of the user who last triaged the indicator. + type: string users: additionalProperties: description: List of user identifiers in this category. @@ -44337,6 +44362,97 @@ components: description: Name of the threat intelligence source. type: string type: object + IoCTriageEvent: + description: A single entry in an indicator's triage history timeline. + properties: + triage_state: + description: "Triage state set by this action: not_reviewed or reviewed." + type: string + triaged_at: + description: Timestamp when this triage action occurred. + format: date-time + type: string + triaged_by: + description: UUID of the user who performed this triage action. + type: string + type: object + IoCTriageWriteRequest: + description: Request body for creating or updating an indicator triage state. + properties: + data: + $ref: "#/components/schemas/IoCTriageWriteRequestData" + required: + - data + type: object + IoCTriageWriteRequestAttributes: + description: Attributes for setting an indicator's triage state. + properties: + indicator: + description: The indicator value to triage (for example, an IP address or domain). + example: "192.0.2.1" + type: string + triage_state: + description: "The triage state to set: not_reviewed or reviewed." + example: reviewed + type: string + required: + - indicator + - triage_state + type: object + IoCTriageWriteRequestData: + description: Data object for the triage write request. + properties: + attributes: + $ref: "#/components/schemas/IoCTriageWriteRequestAttributes" + type: + default: ioc_triage_state + description: Triage state resource type. + example: ioc_triage_state + type: string + required: + - type + - attributes + type: object + IoCTriageWriteResponse: + description: Response for the create indicator triage state endpoint. + properties: + data: + $ref: "#/components/schemas/IoCTriageWriteResponseData" + type: object + IoCTriageWriteResponseAttributes: + description: Attributes of a created or updated triage state. + properties: + created_at: + description: Timestamp when the triage record was created. + format: date-time + type: string + indicator: + description: The indicator value that was triaged. + type: string + triage_state: + description: "The triage state that was set: not_reviewed or reviewed." + type: string + triaged_at: + description: Timestamp when the triage state was set. + format: date-time + type: string + triaged_by: + description: UUID of the user who set the triage state. + type: string + type: object + IoCTriageWriteResponseData: + description: Data object of the triage write response. + properties: + attributes: + $ref: "#/components/schemas/IoCTriageWriteResponseAttributes" + id: + description: Unique identifier for the triage state record. + type: string + type: + default: ioc_triage_state + description: Triage state resource type. + type: string + type: object Issue: description: The issue matching the request. properties: @@ -159560,6 +159676,25 @@ paths: schema: default: desc type: string + - description: When true, return only OCSF field-based matches. When false, return regex/message-based matches. + in: query + name: ocsf + required: false + schema: + default: true + type: boolean + - description: Filter indicators whose triage state was updated by a specific user UUID. + in: query + name: worked_by + required: false + schema: + type: string + - description: "Filter by triage state: not_reviewed or reviewed." + in: query + name: triage_state + required: false + schema: + type: string responses: "200": content: @@ -159611,6 +159746,38 @@ paths: required: true schema: type: string + - description: When true, return only OCSF field-based matches. When false, return regex/message-based matches. + in: query + name: ocsf + required: false + schema: + default: true + type: boolean + - description: Include full triage history for the indicator. + in: query + name: include_triage_history + required: false + schema: + default: false + type: boolean + - description: Maximum number of triage history events returned. Only applied when `include_triage_history` is true. + in: query + name: triage_history_limit + required: false + schema: + default: 50 + format: int32 + maximum: 1000 + minimum: 1 + type: integer + - description: Pagination offset into the triage history. Only applied when `include_triage_history` is true. + in: query + name: triage_history_offset + required: false + schema: + default: 0 + format: int32 + type: integer responses: "200": content: @@ -159648,6 +159815,62 @@ paths: x-unstable: |- **Note**: This endpoint is in beta and may be subject to changes. Please check the documentation regularly for updates. + /api/v2/security/siem/ioc-explorer/triage: + post: + description: |- + Set the triage state of an indicator of compromise (IoC). This creates or + updates the triage state for the indicator in your organization. + operationId: CreateIoCTriageState + requestBody: + content: + "application/json": + examples: + default: + value: + data: + attributes: + indicator: "192.0.2.1" + triage_state: reviewed + type: ioc_triage_state + schema: + $ref: "#/components/schemas/IoCTriageWriteRequest" + description: The triage state to set for the indicator. + required: true + responses: + "201": + content: + "application/json": + examples: + default: + value: + data: + attributes: + created_at: "2026-06-04T12:00:00Z" + indicator: "192.0.2.1" + triage_state: reviewed + triaged_at: "2026-06-04T12:00:00Z" + triaged_by: 11111111-2222-3333-4444-555555555555 + id: abc-123 + type: ioc_triage_state + schema: + $ref: "#/components/schemas/IoCTriageWriteResponse" + description: Created + "400": + $ref: "#/components/responses/BadRequestResponse" + "403": + $ref: "#/components/responses/NotAuthorizedResponse" + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - security_monitoring_signals_write + summary: Create or update an indicator triage state + tags: ["Security Monitoring"] + x-unstable: |- + **Note**: This endpoint is in beta and may be subject to changes. + Please check the documentation regularly for updates. /api/v2/security/signals/notification_rules: get: description: Returns the list of notification rules for security signals. diff --git a/examples/v2_security-monitoring_CreateIoCTriageState.rs b/examples/v2_security-monitoring_CreateIoCTriageState.rs new file mode 100644 index 0000000000..92ec0a133e --- /dev/null +++ b/examples/v2_security-monitoring_CreateIoCTriageState.rs @@ -0,0 +1,23 @@ +// Create or update an indicator triage state returns "Created" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_security_monitoring::SecurityMonitoringAPI; +use datadog_api_client::datadogV2::model::IoCTriageWriteRequest; +use datadog_api_client::datadogV2::model::IoCTriageWriteRequestAttributes; +use datadog_api_client::datadogV2::model::IoCTriageWriteRequestData; + +#[tokio::main] +async fn main() { + let body = IoCTriageWriteRequest::new(IoCTriageWriteRequestData::new( + IoCTriageWriteRequestAttributes::new("192.0.2.1".to_string(), "reviewed".to_string()), + "ioc_triage_state".to_string(), + )); + let mut configuration = datadog::Configuration::new(); + configuration.set_unstable_operation_enabled("v2.CreateIoCTriageState", true); + let api = SecurityMonitoringAPI::with_config(configuration); + let resp = api.create_io_c_triage_state(body).await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_security-monitoring_GetIndicatorOfCompromise.rs b/examples/v2_security-monitoring_GetIndicatorOfCompromise.rs index 20d246a76b..be24d2ba4c 100644 --- a/examples/v2_security-monitoring_GetIndicatorOfCompromise.rs +++ b/examples/v2_security-monitoring_GetIndicatorOfCompromise.rs @@ -1,5 +1,6 @@ // Get an indicator of compromise returns "OK" response use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_security_monitoring::GetIndicatorOfCompromiseOptionalParams; use datadog_api_client::datadogV2::api_security_monitoring::SecurityMonitoringAPI; #[tokio::main] @@ -9,7 +10,8 @@ async fn main() { let api = SecurityMonitoringAPI::with_config(configuration); let resp = api .get_indicator_of_compromise( - "masscan/1.3 (https://github.com/robertdavidgraham/masscan)".to_string(), + "192.0.2.1".to_string(), + GetIndicatorOfCompromiseOptionalParams::default().include_triage_history(true), ) .await; if let Ok(value) = resp { diff --git a/src/datadog/configuration.rs b/src/datadog/configuration.rs index 77317e5213..c4e517b011 100644 --- a/src/datadog/configuration.rs +++ b/src/datadog/configuration.rs @@ -296,6 +296,7 @@ impl Default for Configuration { "v2.convert_security_monitoring_terraform_resource".to_owned(), false, ), + ("v2.create_io_c_triage_state".to_owned(), false), ( "v2.create_sample_log_generation_subscription".to_owned(), false, diff --git a/src/datadogV2/api/api_security_monitoring.rs b/src/datadogV2/api/api_security_monitoring.rs index 7602a068d8..3d49b87e5b 100644 --- a/src/datadogV2/api/api_security_monitoring.rs +++ b/src/datadogV2/api/api_security_monitoring.rs @@ -88,6 +88,43 @@ impl GetFindingOptionalParams { } } +/// GetIndicatorOfCompromiseOptionalParams is a struct for passing parameters to the method [`SecurityMonitoringAPI::get_indicator_of_compromise`] +#[non_exhaustive] +#[derive(Clone, Default, Debug)] +pub struct GetIndicatorOfCompromiseOptionalParams { + /// When true, return only OCSF field-based matches. When false, return regex/message-based matches. + pub ocsf: Option, + /// Include full triage history for the indicator. + pub include_triage_history: Option, + /// Maximum number of triage history events returned. Only applied when `include_triage_history` is true. + pub triage_history_limit: Option, + /// Pagination offset into the triage history. Only applied when `include_triage_history` is true. + pub triage_history_offset: Option, +} + +impl GetIndicatorOfCompromiseOptionalParams { + /// When true, return only OCSF field-based matches. When false, return regex/message-based matches. + pub fn ocsf(mut self, value: bool) -> Self { + self.ocsf = Some(value); + self + } + /// Include full triage history for the indicator. + pub fn include_triage_history(mut self, value: bool) -> Self { + self.include_triage_history = Some(value); + self + } + /// Maximum number of triage history events returned. Only applied when `include_triage_history` is true. + pub fn triage_history_limit(mut self, value: i32) -> Self { + self.triage_history_limit = Some(value); + self + } + /// Pagination offset into the triage history. Only applied when `include_triage_history` is true. + pub fn triage_history_offset(mut self, value: i32) -> Self { + self.triage_history_offset = Some(value); + self + } +} + /// GetResourceEvaluationFiltersOptionalParams is a struct for passing parameters to the method [`SecurityMonitoringAPI::get_resource_evaluation_filters`] #[non_exhaustive] #[derive(Clone, Default, Debug)] @@ -536,6 +573,12 @@ pub struct ListIndicatorsOfCompromiseOptionalParams { pub sort_column: Option, /// Sort order: asc or desc. pub sort_order: Option, + /// When true, return only OCSF field-based matches. When false, return regex/message-based matches. + pub ocsf: Option, + /// Filter indicators whose triage state was updated by a specific user UUID. + pub worked_by: Option, + /// Filter by triage state: not_reviewed or reviewed. + pub triage_state: Option, } impl ListIndicatorsOfCompromiseOptionalParams { @@ -564,6 +607,21 @@ impl ListIndicatorsOfCompromiseOptionalParams { self.sort_order = Some(value); self } + /// When true, return only OCSF field-based matches. When false, return regex/message-based matches. + pub fn ocsf(mut self, value: bool) -> Self { + self.ocsf = Some(value); + self + } + /// Filter indicators whose triage state was updated by a specific user UUID. + pub fn worked_by(mut self, value: String) -> Self { + self.worked_by = Some(value); + self + } + /// Filter by triage state: not_reviewed or reviewed. + pub fn triage_state(mut self, value: String) -> Self { + self.triage_state = Some(value); + self + } } /// ListSampleLogGenerationSubscriptionsOptionalParams is a struct for passing parameters to the method [`SecurityMonitoringAPI::list_sample_log_generation_subscriptions`] @@ -1581,6 +1639,14 @@ pub enum CreateCustomFrameworkError { UnknownValue(serde_json::Value), } +/// CreateIoCTriageStateError is a struct for typed errors of method [`SecurityMonitoringAPI::create_io_c_triage_state`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum CreateIoCTriageStateError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// CreateJiraIssuesError is a struct for typed errors of method [`SecurityMonitoringAPI::create_jira_issues`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -5636,6 +5702,171 @@ impl SecurityMonitoringAPI { } } + /// Set the triage state of an indicator of compromise (IoC). This creates or + /// updates the triage state for the indicator in your organization. + pub async fn create_io_c_triage_state( + &self, + body: crate::datadogV2::model::IoCTriageWriteRequest, + ) -> Result< + crate::datadogV2::model::IoCTriageWriteResponse, + datadog::Error, + > { + match self.create_io_c_triage_state_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), + } + } + + /// Set the triage state of an indicator of compromise (IoC). This creates or + /// updates the triage state for the indicator in your organization. + pub async fn create_io_c_triage_state_with_http_info( + &self, + body: crate::datadogV2::model::IoCTriageWriteRequest, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.create_io_c_triage_state"; + if local_configuration.is_unstable_operation_enabled(operation_id) { + warn!("Using unstable operation {operation_id}"); + } else { + let local_error = datadog::UnstableOperationDisabledError { + msg: "Operation 'v2.create_io_c_triage_state' is not enabled".to_string(), + }; + return Err(datadog::Error::UnstableOperationDisabledError(local_error)); + } + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/security/siem/ioc-explorer/triage", + local_configuration.get_operation_host(operation_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::POST, 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)), + } + } + #[cfg(feature = "zstd")] + "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::( + &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)) + } + } + /// Create Jira issues for security findings. /// This operation creates a case in Datadog and a Jira issue linked to that case for bidirectional sync between Datadog and Jira. To configure the Jira integration, see [Bidirectional ticket syncing with Jira](). You can create up to 50 Jira issues per request and associate up to 50 security findings per Jira issue. Security findings that are already attached to another Jira issue will be detached from their previous Jira issue and attached to the newly created Jira issue. pub async fn create_jira_issues( @@ -10633,12 +10864,13 @@ impl SecurityMonitoringAPI { pub async fn get_indicator_of_compromise( &self, indicator: String, + params: GetIndicatorOfCompromiseOptionalParams, ) -> Result< crate::datadogV2::model::GetIoCIndicatorResponse, datadog::Error, > { match self - .get_indicator_of_compromise_with_http_info(indicator) + .get_indicator_of_compromise_with_http_info(indicator, params) .await { Ok(response_content) => { @@ -10658,6 +10890,7 @@ impl SecurityMonitoringAPI { pub async fn get_indicator_of_compromise_with_http_info( &self, indicator: String, + params: GetIndicatorOfCompromiseOptionalParams, ) -> Result< datadog::ResponseContent, datadog::Error, @@ -10673,6 +10906,12 @@ impl SecurityMonitoringAPI { return Err(datadog::Error::UnstableOperationDisabledError(local_error)); } + // unbox and build optional parameters + let ocsf = params.ocsf; + let include_triage_history = params.include_triage_history; + let triage_history_limit = params.triage_history_limit; + let triage_history_offset = params.triage_history_offset; + let local_client = &self.client; let local_uri_str = format!( @@ -10683,6 +10922,22 @@ impl SecurityMonitoringAPI { local_client.request(reqwest::Method::GET, local_uri_str.as_str()); local_req_builder = local_req_builder.query(&[("indicator", &indicator.to_string())]); + if let Some(ref local_query_param) = ocsf { + local_req_builder = + local_req_builder.query(&[("ocsf", &local_query_param.to_string())]); + }; + if let Some(ref local_query_param) = include_triage_history { + local_req_builder = local_req_builder + .query(&[("include_triage_history", &local_query_param.to_string())]); + }; + if let Some(ref local_query_param) = triage_history_limit { + local_req_builder = local_req_builder + .query(&[("triage_history_limit", &local_query_param.to_string())]); + }; + if let Some(ref local_query_param) = triage_history_offset { + local_req_builder = local_req_builder + .query(&[("triage_history_offset", &local_query_param.to_string())]); + }; // build headers let mut headers = HeaderMap::new(); @@ -14968,6 +15223,9 @@ impl SecurityMonitoringAPI { let query = params.query; let sort_column = params.sort_column; let sort_order = params.sort_order; + let ocsf = params.ocsf; + let worked_by = params.worked_by; + let triage_state = params.triage_state; let local_client = &self.client; @@ -14998,6 +15256,18 @@ impl SecurityMonitoringAPI { local_req_builder = local_req_builder.query(&[("sort[order]", &local_query_param.to_string())]); }; + if let Some(ref local_query_param) = ocsf { + local_req_builder = + local_req_builder.query(&[("ocsf", &local_query_param.to_string())]); + }; + if let Some(ref local_query_param) = worked_by { + local_req_builder = + local_req_builder.query(&[("worked_by", &local_query_param.to_string())]); + }; + if let Some(ref local_query_param) = triage_state { + local_req_builder = + local_req_builder.query(&[("triage_state", &local_query_param.to_string())]); + }; // build headers let mut headers = HeaderMap::new(); diff --git a/src/datadogV2/model/mod.rs b/src/datadogV2/model/mod.rs index dc9baf5f5c..824966e270 100644 --- a/src/datadogV2/model/mod.rs +++ b/src/datadogV2/model/mod.rs @@ -9526,6 +9526,20 @@ pub mod model_io_c_indicator_detailed; pub use self::model_io_c_indicator_detailed::IoCIndicatorDetailed; pub mod model_io_c_signal_severity_count; pub use self::model_io_c_signal_severity_count::IoCSignalSeverityCount; +pub mod model_io_c_triage_event; +pub use self::model_io_c_triage_event::IoCTriageEvent; +pub mod model_io_c_triage_write_request; +pub use self::model_io_c_triage_write_request::IoCTriageWriteRequest; +pub mod model_io_c_triage_write_request_data; +pub use self::model_io_c_triage_write_request_data::IoCTriageWriteRequestData; +pub mod model_io_c_triage_write_request_attributes; +pub use self::model_io_c_triage_write_request_attributes::IoCTriageWriteRequestAttributes; +pub mod model_io_c_triage_write_response; +pub use self::model_io_c_triage_write_response::IoCTriageWriteResponse; +pub mod model_io_c_triage_write_response_data; +pub use self::model_io_c_triage_write_response_data::IoCTriageWriteResponseData; +pub mod model_io_c_triage_write_response_attributes; +pub use self::model_io_c_triage_write_response_attributes::IoCTriageWriteResponseAttributes; pub mod model_create_notification_rule_parameters; pub use self::model_create_notification_rule_parameters::CreateNotificationRuleParameters; pub mod model_create_notification_rule_parameters_data; diff --git a/src/datadogV2/model/model_io_c_indicator.rs b/src/datadogV2/model/model_io_c_indicator.rs index 83ded28bdc..a1c14cbe78 100644 --- a/src/datadogV2/model/model_io_c_indicator.rs +++ b/src/datadogV2/model/model_io_c_indicator.rs @@ -86,6 +86,15 @@ pub struct IoCIndicator { /// Tags associated with the indicator. #[serde(rename = "tags")] pub tags: Option>, + /// Current triage state of the indicator: not_reviewed or reviewed. + #[serde(rename = "triage_state")] + pub triage_state: Option, + /// Timestamp when the indicator was last triaged. + #[serde(rename = "triaged_at")] + pub triaged_at: Option>, + /// UUID of the user who last triaged the indicator. + #[serde(rename = "triaged_by")] + pub triaged_by: Option, #[serde(flatten)] pub additional_properties: std::collections::BTreeMap, #[serde(skip)] @@ -117,6 +126,9 @@ impl IoCIndicator { signal_tier: None, suspicious_sources: None, tags: None, + triage_state: None, + triaged_at: None, + triaged_by: None, additional_properties: std::collections::BTreeMap::new(), _unparsed: false, } @@ -236,6 +248,21 @@ impl IoCIndicator { self } + pub fn triage_state(mut self, value: String) -> Self { + self.triage_state = Some(value); + self + } + + pub fn triaged_at(mut self, value: chrono::DateTime) -> Self { + self.triaged_at = Some(value); + self + } + + pub fn triaged_by(mut self, value: String) -> Self { + self.triaged_by = Some(value); + self + } + pub fn additional_properties( mut self, value: std::collections::BTreeMap, @@ -293,6 +320,9 @@ impl<'de> Deserialize<'de> for IoCIndicator { Option>, > = None; let mut tags: Option> = None; + let mut triage_state: Option = None; + let mut triaged_at: Option> = None; + let mut triaged_by: Option = None; let mut additional_properties: std::collections::BTreeMap< String, serde_json::Value, @@ -477,6 +507,25 @@ impl<'de> Deserialize<'de> for IoCIndicator { } tags = Some(serde_json::from_value(v).map_err(M::Error::custom)?); } + "triage_state" => { + if v.is_null() { + continue; + } + triage_state = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "triaged_at" => { + if v.is_null() { + continue; + } + triaged_at = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "triaged_by" => { + if v.is_null() { + continue; + } + triaged_by = 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); @@ -507,6 +556,9 @@ impl<'de> Deserialize<'de> for IoCIndicator { signal_tier, suspicious_sources, tags, + triage_state, + triaged_at, + triaged_by, additional_properties, _unparsed, }; diff --git a/src/datadogV2/model/model_io_c_indicator_detailed.rs b/src/datadogV2/model/model_io_c_indicator_detailed.rs index 026e114ccc..dfd900e8b0 100644 --- a/src/datadogV2/model/model_io_c_indicator_detailed.rs +++ b/src/datadogV2/model/model_io_c_indicator_detailed.rs @@ -113,6 +113,18 @@ pub struct IoCIndicatorDetailed { /// Tags associated with the indicator. #[serde(rename = "tags")] pub tags: Option>, + /// Full triage history timeline. Returned only when `include_triage_history` is true. + #[serde(rename = "triage_history")] + pub triage_history: Option>, + /// Current triage state of the indicator: not_reviewed or reviewed. + #[serde(rename = "triage_state")] + pub triage_state: Option, + /// Timestamp when the indicator was last triaged. + #[serde(rename = "triaged_at")] + pub triaged_at: Option>, + /// UUID of the user who last triaged the indicator. + #[serde(rename = "triaged_by")] + pub triaged_by: Option, /// Users associated with this indicator, grouped by category. #[serde(rename = "users")] pub users: Option>>, @@ -156,6 +168,10 @@ impl IoCIndicatorDetailed { signal_tier: None, suspicious_sources: None, tags: None, + triage_history: None, + triage_state: None, + triaged_at: None, + triaged_by: None, users: None, additional_properties: std::collections::BTreeMap::new(), _unparsed: false, @@ -327,6 +343,26 @@ impl IoCIndicatorDetailed { self } + pub fn triage_history(mut self, value: Vec) -> Self { + self.triage_history = Some(value); + self + } + + pub fn triage_state(mut self, value: String) -> Self { + self.triage_state = Some(value); + self + } + + pub fn triaged_at(mut self, value: chrono::DateTime) -> Self { + self.triaged_at = Some(value); + self + } + + pub fn triaged_by(mut self, value: String) -> Self { + self.triaged_by = Some(value); + self + } + pub fn users(mut self, value: std::collections::BTreeMap>) -> Self { self.users = Some(value); self @@ -402,6 +438,10 @@ impl<'de> Deserialize<'de> for IoCIndicatorDetailed { Option>, > = None; let mut tags: Option> = None; + let mut triage_history: Option> = None; + let mut triage_state: Option = None; + let mut triaged_at: Option> = None; + let mut triaged_by: Option = None; let mut users: Option>> = None; let mut additional_properties: std::collections::BTreeMap< String, @@ -647,6 +687,32 @@ impl<'de> Deserialize<'de> for IoCIndicatorDetailed { } tags = Some(serde_json::from_value(v).map_err(M::Error::custom)?); } + "triage_history" => { + if v.is_null() { + continue; + } + triage_history = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "triage_state" => { + if v.is_null() { + continue; + } + triage_state = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "triaged_at" => { + if v.is_null() { + continue; + } + triaged_at = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "triaged_by" => { + if v.is_null() { + continue; + } + triaged_by = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } "users" => { if v.is_null() { continue; @@ -692,6 +758,10 @@ impl<'de> Deserialize<'de> for IoCIndicatorDetailed { signal_tier, suspicious_sources, tags, + triage_history, + triage_state, + triaged_at, + triaged_by, users, additional_properties, _unparsed, diff --git a/src/datadogV2/model/model_io_c_triage_event.rs b/src/datadogV2/model/model_io_c_triage_event.rs new file mode 100644 index 0000000000..543df58817 --- /dev/null +++ b/src/datadogV2/model/model_io_c_triage_event.rs @@ -0,0 +1,140 @@ +// 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}; + +/// A single entry in an indicator's triage history timeline. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct IoCTriageEvent { + /// Triage state set by this action: not_reviewed or reviewed. + #[serde(rename = "triage_state")] + pub triage_state: Option, + /// Timestamp when this triage action occurred. + #[serde(rename = "triaged_at")] + pub triaged_at: Option>, + /// UUID of the user who performed this triage action. + #[serde(rename = "triaged_by")] + pub triaged_by: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl IoCTriageEvent { + pub fn new() -> IoCTriageEvent { + IoCTriageEvent { + triage_state: None, + triaged_at: None, + triaged_by: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn triage_state(mut self, value: String) -> Self { + self.triage_state = Some(value); + self + } + + pub fn triaged_at(mut self, value: chrono::DateTime) -> Self { + self.triaged_at = Some(value); + self + } + + pub fn triaged_by(mut self, value: String) -> Self { + self.triaged_by = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for IoCTriageEvent { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for IoCTriageEvent { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct IoCTriageEventVisitor; + impl<'a> Visitor<'a> for IoCTriageEventVisitor { + type Value = IoCTriageEvent; + + 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 triage_state: Option = None; + let mut triaged_at: Option> = None; + let mut triaged_by: 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() { + "triage_state" => { + if v.is_null() { + continue; + } + triage_state = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "triaged_at" => { + if v.is_null() { + continue; + } + triaged_at = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "triaged_by" => { + if v.is_null() { + continue; + } + triaged_by = 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 content = IoCTriageEvent { + triage_state, + triaged_at, + triaged_by, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(IoCTriageEventVisitor) + } +} diff --git a/src/datadogV2/model/model_io_c_triage_write_request.rs b/src/datadogV2/model/model_io_c_triage_write_request.rs new file mode 100644 index 0000000000..05d3807abf --- /dev/null +++ b/src/datadogV2/model/model_io_c_triage_write_request.rs @@ -0,0 +1,92 @@ +// 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 body for creating or updating an indicator triage state. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct IoCTriageWriteRequest { + /// Data object for the triage write request. + #[serde(rename = "data")] + pub data: crate::datadogV2::model::IoCTriageWriteRequestData, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl IoCTriageWriteRequest { + pub fn new(data: crate::datadogV2::model::IoCTriageWriteRequestData) -> IoCTriageWriteRequest { + IoCTriageWriteRequest { + 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 IoCTriageWriteRequest { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct IoCTriageWriteRequestVisitor; + impl<'a> Visitor<'a> for IoCTriageWriteRequestVisitor { + type Value = IoCTriageWriteRequest; + + 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 = 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 = IoCTriageWriteRequest { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(IoCTriageWriteRequestVisitor) + } +} diff --git a/src/datadogV2/model/model_io_c_triage_write_request_attributes.rs b/src/datadogV2/model/model_io_c_triage_write_request_attributes.rs new file mode 100644 index 0000000000..0d6c9fe448 --- /dev/null +++ b/src/datadogV2/model/model_io_c_triage_write_request_attributes.rs @@ -0,0 +1,104 @@ +// 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 for setting an indicator's triage state. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct IoCTriageWriteRequestAttributes { + /// The indicator value to triage (for example, an IP address or domain). + #[serde(rename = "indicator")] + pub indicator: String, + /// The triage state to set: not_reviewed or reviewed. + #[serde(rename = "triage_state")] + pub triage_state: String, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl IoCTriageWriteRequestAttributes { + pub fn new(indicator: String, triage_state: String) -> IoCTriageWriteRequestAttributes { + IoCTriageWriteRequestAttributes { + indicator, + triage_state, + 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 IoCTriageWriteRequestAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct IoCTriageWriteRequestAttributesVisitor; + impl<'a> Visitor<'a> for IoCTriageWriteRequestAttributesVisitor { + type Value = IoCTriageWriteRequestAttributes; + + 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 indicator: Option = None; + let mut triage_state: 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() { + "indicator" => { + indicator = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "triage_state" => { + triage_state = + 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 indicator = indicator.ok_or_else(|| M::Error::missing_field("indicator"))?; + let triage_state = + triage_state.ok_or_else(|| M::Error::missing_field("triage_state"))?; + + let content = IoCTriageWriteRequestAttributes { + indicator, + triage_state, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(IoCTriageWriteRequestAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_io_c_triage_write_request_data.rs b/src/datadogV2/model/model_io_c_triage_write_request_data.rs new file mode 100644 index 0000000000..6629367d86 --- /dev/null +++ b/src/datadogV2/model/model_io_c_triage_write_request_data.rs @@ -0,0 +1,107 @@ +// 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}; + +/// Data object for the triage write request. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct IoCTriageWriteRequestData { + /// Attributes for setting an indicator's triage state. + #[serde(rename = "attributes")] + pub attributes: crate::datadogV2::model::IoCTriageWriteRequestAttributes, + /// Triage state resource type. + #[serde(rename = "type")] + pub type_: String, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl IoCTriageWriteRequestData { + pub fn new( + attributes: crate::datadogV2::model::IoCTriageWriteRequestAttributes, + type_: String, + ) -> IoCTriageWriteRequestData { + IoCTriageWriteRequestData { + attributes, + type_, + 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 IoCTriageWriteRequestData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct IoCTriageWriteRequestDataVisitor; + impl<'a> Visitor<'a> for IoCTriageWriteRequestDataVisitor { + type Value = IoCTriageWriteRequestData; + + 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< + crate::datadogV2::model::IoCTriageWriteRequestAttributes, + > = 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)?); + } + "type" => { + type_ = 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 attributes = attributes.ok_or_else(|| M::Error::missing_field("attributes"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = IoCTriageWriteRequestData { + attributes, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(IoCTriageWriteRequestDataVisitor) + } +} diff --git a/src/datadogV2/model/model_io_c_triage_write_response.rs b/src/datadogV2/model/model_io_c_triage_write_response.rs new file mode 100644 index 0000000000..4f20bd6d42 --- /dev/null +++ b/src/datadogV2/model/model_io_c_triage_write_response.rs @@ -0,0 +1,105 @@ +// 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}; + +/// Response for the create indicator triage state endpoint. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct IoCTriageWriteResponse { + /// Data object of the triage write response. + #[serde(rename = "data")] + pub data: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl IoCTriageWriteResponse { + pub fn new() -> IoCTriageWriteResponse { + IoCTriageWriteResponse { + data: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn data(mut self, value: crate::datadogV2::model::IoCTriageWriteResponseData) -> Self { + self.data = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for IoCTriageWriteResponse { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for IoCTriageWriteResponse { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct IoCTriageWriteResponseVisitor; + impl<'a> Visitor<'a> for IoCTriageWriteResponseVisitor { + type Value = IoCTriageWriteResponse; + + 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 = 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" => { + if v.is_null() { + continue; + } + 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 content = IoCTriageWriteResponse { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(IoCTriageWriteResponseVisitor) + } +} diff --git a/src/datadogV2/model/model_io_c_triage_write_response_attributes.rs b/src/datadogV2/model/model_io_c_triage_write_response_attributes.rs new file mode 100644 index 0000000000..c84696e69a --- /dev/null +++ b/src/datadogV2/model/model_io_c_triage_write_response_attributes.rs @@ -0,0 +1,174 @@ +// 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 created or updated triage state. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct IoCTriageWriteResponseAttributes { + /// Timestamp when the triage record was created. + #[serde(rename = "created_at")] + pub created_at: Option>, + /// The indicator value that was triaged. + #[serde(rename = "indicator")] + pub indicator: Option, + /// The triage state that was set: not_reviewed or reviewed. + #[serde(rename = "triage_state")] + pub triage_state: Option, + /// Timestamp when the triage state was set. + #[serde(rename = "triaged_at")] + pub triaged_at: Option>, + /// UUID of the user who set the triage state. + #[serde(rename = "triaged_by")] + pub triaged_by: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl IoCTriageWriteResponseAttributes { + pub fn new() -> IoCTriageWriteResponseAttributes { + IoCTriageWriteResponseAttributes { + created_at: None, + indicator: None, + triage_state: None, + triaged_at: None, + triaged_by: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn created_at(mut self, value: chrono::DateTime) -> Self { + self.created_at = Some(value); + self + } + + pub fn indicator(mut self, value: String) -> Self { + self.indicator = Some(value); + self + } + + pub fn triage_state(mut self, value: String) -> Self { + self.triage_state = Some(value); + self + } + + pub fn triaged_at(mut self, value: chrono::DateTime) -> Self { + self.triaged_at = Some(value); + self + } + + pub fn triaged_by(mut self, value: String) -> Self { + self.triaged_by = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for IoCTriageWriteResponseAttributes { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for IoCTriageWriteResponseAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct IoCTriageWriteResponseAttributesVisitor; + impl<'a> Visitor<'a> for IoCTriageWriteResponseAttributesVisitor { + type Value = IoCTriageWriteResponseAttributes; + + 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 created_at: Option> = None; + let mut indicator: Option = None; + let mut triage_state: Option = None; + let mut triaged_at: Option> = None; + let mut triaged_by: 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() { + "created_at" => { + if v.is_null() { + continue; + } + created_at = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "indicator" => { + if v.is_null() { + continue; + } + indicator = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "triage_state" => { + if v.is_null() { + continue; + } + triage_state = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "triaged_at" => { + if v.is_null() { + continue; + } + triaged_at = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "triaged_by" => { + if v.is_null() { + continue; + } + triaged_by = 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 content = IoCTriageWriteResponseAttributes { + created_at, + indicator, + triage_state, + triaged_at, + triaged_by, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(IoCTriageWriteResponseAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_io_c_triage_write_response_data.rs b/src/datadogV2/model/model_io_c_triage_write_response_data.rs new file mode 100644 index 0000000000..e986ab24be --- /dev/null +++ b/src/datadogV2/model/model_io_c_triage_write_response_data.rs @@ -0,0 +1,144 @@ +// 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}; + +/// Data object of the triage write response. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct IoCTriageWriteResponseData { + /// Attributes of a created or updated triage state. + #[serde(rename = "attributes")] + pub attributes: Option, + /// Unique identifier for the triage state record. + #[serde(rename = "id")] + pub id: Option, + /// Triage state resource type. + #[serde(rename = "type")] + pub type_: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl IoCTriageWriteResponseData { + pub fn new() -> IoCTriageWriteResponseData { + IoCTriageWriteResponseData { + attributes: None, + id: None, + type_: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn attributes( + mut self, + value: crate::datadogV2::model::IoCTriageWriteResponseAttributes, + ) -> 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: String) -> 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 IoCTriageWriteResponseData { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for IoCTriageWriteResponseData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct IoCTriageWriteResponseDataVisitor; + impl<'a> Visitor<'a> for IoCTriageWriteResponseDataVisitor { + type Value = IoCTriageWriteResponseData; + + 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< + crate::datadogV2::model::IoCTriageWriteResponseAttributes, + > = 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 Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = IoCTriageWriteResponseData { + attributes, + id, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(IoCTriageWriteResponseDataVisitor) + } +} diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-or-update-an-indicator-triage-state-returns-Bad-Request-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Create-or-update-an-indicator-triage-state-returns-Bad-Request-response.frozen new file mode 100644 index 0000000000..d6a26ed39d --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-or-update-an-indicator-triage-state-returns-Bad-Request-response.frozen @@ -0,0 +1 @@ +2026-06-05T12:20:47.940Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-or-update-an-indicator-triage-state-returns-Bad-Request-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Create-or-update-an-indicator-triage-state-returns-Bad-Request-response.json new file mode 100644 index 0000000000..0fec2d91c1 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-or-update-an-indicator-triage-state-returns-Bad-Request-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":{\"attributes\":{\"indicator\":\"192.0.2.1\",\"triage_state\":\"invalid_state\"},\"type\":\"ioc_triage_state\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "post", + "uri": "https://api.datadoghq.com/api/v2/security/siem/ioc-explorer/triage" + }, + "response": { + "body": { + "string": "{\"errors\":[{\"title\":\"Generic Error\",\"detail\":\"invalid triage_state\"}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 400, + "message": "Bad Request" + } + }, + "recorded_at": "Fri, 05 Jun 2026 12:20:47 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-or-update-an-indicator-triage-state-returns-Created-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Create-or-update-an-indicator-triage-state-returns-Created-response.frozen new file mode 100644 index 0000000000..0ac630dda1 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-or-update-an-indicator-triage-state-returns-Created-response.frozen @@ -0,0 +1 @@ +2026-06-05T12:22:26.137Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-or-update-an-indicator-triage-state-returns-Created-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Create-or-update-an-indicator-triage-state-returns-Created-response.json new file mode 100644 index 0000000000..d343d0c1e2 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-or-update-an-indicator-triage-state-returns-Created-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":{\"attributes\":{\"indicator\":\"192.0.2.1\",\"triage_state\":\"reviewed\"},\"type\":\"ioc_triage_state\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "post", + "uri": "https://api.datadoghq.com/api/v2/security/siem/ioc-explorer/triage" + }, + "response": { + "body": { + "string": "{\"data\":{\"id\":\"2e6eff68-4ffa-4cab-b9bb-d9ce1ef3b42a\",\"type\":\"ioc_triage_state\",\"attributes\":{\"created_at\":\"2026-06-05T12:22:26.488248Z\",\"indicator\":\"192.0.2.1\",\"triage_state\":\"reviewed\",\"triaged_at\":\"2026-06-05T12:22:26.488248Z\",\"triaged_by\":\"dc6535c4-0b70-47aa-9c6a-9b0fc0be3f19\"}}}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 201, + "message": "Created" + } + }, + "recorded_at": "Fri, 05 Jun 2026 12:22:26 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Get-an-indicator-of-compromise-returns-OK-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Get-an-indicator-of-compromise-returns-OK-response.frozen index fc8ed109ad..3dc6b0aa0a 100644 --- a/tests/scenarios/cassettes/v2/security_monitoring/Get-an-indicator-of-compromise-returns-OK-response.frozen +++ b/tests/scenarios/cassettes/v2/security_monitoring/Get-an-indicator-of-compromise-returns-OK-response.frozen @@ -1 +1 @@ -2026-04-14T18:22:29.733Z \ No newline at end of file +2026-06-05T12:58:33.985Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Get-an-indicator-of-compromise-returns-OK-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Get-an-indicator-of-compromise-returns-OK-response.json index dfd29aae1b..ad70506ec1 100644 --- a/tests/scenarios/cassettes/v2/security_monitoring/Get-an-indicator-of-compromise-returns-OK-response.json +++ b/tests/scenarios/cassettes/v2/security_monitoring/Get-an-indicator-of-compromise-returns-OK-response.json @@ -9,11 +9,11 @@ ] }, "method": "get", - "uri": "https://api.datadoghq.com/api/v2/security/siem/ioc-explorer/indicator?indicator=masscan%2F1.3%20%28https%3A%2F%2Fgithub.com%2Frobertdavidgraham%2Fmasscan%29" + "uri": "https://api.datadoghq.com/api/v2/security/siem/ioc-explorer/indicator?indicator=192.0.2.1&include_triage_history=true" }, "response": { "body": { - "string": "{\"data\":{\"id\":\"65a31893-cc59-4125-9424-44f7ba083e53\",\"type\":\"get_indicator_response\",\"attributes\":{\"data\":{\"id\":\"masscan/1.3 (https://github.com/robertdavidgraham/masscan)\",\"indicator\":\"masscan/1.3 (https://github.com/robertdavidgraham/masscan)\",\"indicator_type\":\"User Agent\",\"score\":4,\"as_type\":\"hosting\",\"malicious_sources\":null,\"suspicious_sources\":[{\"name\":\"Datadog Threat Research\"}],\"benign_sources\":null,\"categories\":[\"scanner\"],\"tags\":[],\"signal_matches\":0,\"log_matches\":45,\"first_seen\":\"2025-01-08T23:24:45Z\",\"last_seen\":\"2026-04-10T14:36:20Z\",\"signal_tier\":0,\"max_trust_score\":\"RAISE_SCORE\",\"m_sources\":\"NO_EFFECT\",\"m_persistence\":\"RAISE_SCORE\",\"m_signal\":\"NO_EFFECT\",\"m_as_type\":\"NO_EFFECT\",\"log_sources\":[],\"services\":[],\"signal_severity\":[],\"users\":{},\"critical_assets\":[],\"hosts\":[],\"as_number\":\"\",\"as_organization\":\"\",\"as_cidr_block\":\"\"}}}}", + "string": "{\"data\":{\"id\":\"b38eb8e1-61c8-470f-be58-f41531a7c134\",\"type\":\"get_indicator_response\",\"attributes\":{\"data\":{\"id\":\"192.0.2.1\",\"indicator\":\"192.0.2.1\",\"indicator_type\":\"IP Address\",\"score\":4,\"as_type\":\"hosting\",\"malicious_sources\":null,\"suspicious_sources\":[{\"name\":\"SOURCE1\"}],\"benign_sources\":null,\"categories\":[\"hosting_proxy\"],\"tags\":[],\"signal_matches\":1,\"log_matches\":7,\"signal_tier\":0,\"max_trust_score\":\"RAISE_SCORE\",\"m_sources\":\"NO_EFFECT\",\"m_persistence\":\"NO_EFFECT\",\"m_signal\":\"NO_EFFECT\",\"m_as_type\":\"NO_EFFECT\",\"triage_state\":\"reviewed\",\"triaged_at\":\"2026-06-03T18:55:42.108938Z\",\"triaged_by\":\"00000000-0000-0000-0000-000000000000\",\"log_sources\":[],\"services\":[],\"signal_severity\":[{\"severity\":\"info\",\"count\":1}],\"users\":{},\"critical_assets\":[],\"hosts\":[],\"additional_data\":{},\"triage_history\":[{\"triaged_at\":\"2026-06-03T18:55:42.108938Z\",\"triaged_by\":\"00000000-0000-0000-0000-000000000000\",\"triage_state\":\"reviewed\"},{\"triaged_at\":\"2026-06-03T13:32:14.735424Z\",\"triaged_by\":\"00000000-0000-0000-0000-000000000000\",\"triage_state\":\"reviewed\"}]}}}}", "encoding": null }, "headers": { @@ -26,7 +26,7 @@ "message": "OK" } }, - "recorded_at": "Tue, 14 Apr 2026 18:22:29 GMT" + "recorded_at": "Fri, 05 Jun 2026 12:58:33 GMT" } ], "recorded_with": "VCR 6.0.0" diff --git a/tests/scenarios/cassettes/v2/security_monitoring/List-indicators-of-compromise-returns-OK-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/List-indicators-of-compromise-returns-OK-response.frozen index 5814ac627e..b1bf7726a1 100644 --- a/tests/scenarios/cassettes/v2/security_monitoring/List-indicators-of-compromise-returns-OK-response.frozen +++ b/tests/scenarios/cassettes/v2/security_monitoring/List-indicators-of-compromise-returns-OK-response.frozen @@ -1 +1 @@ -2026-04-14T18:22:48.392Z \ No newline at end of file +2026-06-05T12:32:21.136Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/List-indicators-of-compromise-returns-OK-response.json b/tests/scenarios/cassettes/v2/security_monitoring/List-indicators-of-compromise-returns-OK-response.json index e6704bf9d1..6790ddd8bb 100644 --- a/tests/scenarios/cassettes/v2/security_monitoring/List-indicators-of-compromise-returns-OK-response.json +++ b/tests/scenarios/cassettes/v2/security_monitoring/List-indicators-of-compromise-returns-OK-response.json @@ -13,7 +13,7 @@ }, "response": { "body": { - "string": "{\"data\":{\"id\":\"a4e3b616-e180-4b47-a379-43da9c5b300e\",\"type\":\"ioc_explorer_response\",\"attributes\":{\"data\":[{\"id\":\"43.228.157.121\",\"indicator\":\"43.228.157.121\",\"indicator_type\":\"IP Address\",\"score\":8,\"as_type\":\"hosting\",\"malicious_sources\":[{\"name\":\"threatfox\"}],\"suspicious_sources\":[{\"name\":\"tor\"},{\"name\":\"SPUR\"}],\"benign_sources\":null,\"categories\":[\"malware\",\"tor\",\"hosting_proxy\"],\"tags\":[],\"signal_matches\":0,\"log_matches\":14,\"signal_tier\":0,\"max_trust_score\":\"RAISE_SCORE\",\"m_sources\":\"RAISE_SCORE\",\"m_persistence\":\"NO_EFFECT\",\"m_signal\":\"NO_EFFECT\",\"m_as_type\":\"NO_EFFECT\",\"as_geo\":{\"city\":\"Frankfurt am Main\",\"country_code\":\"DE\",\"country_name\":\"Germany\"}}],\"metadata\":{\"count\":25091},\"paging\":{\"offset\":1}}}}", + "string": "{\"data\":{\"id\":\"22b62903-4053-42ed-9448-c750da2ecd81\",\"type\":\"ioc_explorer_response\",\"attributes\":{\"data\":[{\"id\":\"192.0.2.1\",\"indicator\":\"192.0.2.1\",\"indicator_type\":\"IP Address\",\"score\":4,\"as_type\":\"hosting\",\"malicious_sources\":null,\"suspicious_sources\":[{\"name\":\"SOURCE1\"}],\"benign_sources\":null,\"categories\":[\"hosting_proxy\"],\"tags\":[],\"signal_matches\":1,\"log_matches\":7,\"signal_tier\":0,\"max_trust_score\":\"RAISE_SCORE\",\"m_sources\":\"NO_EFFECT\",\"m_persistence\":\"NO_EFFECT\",\"m_signal\":\"NO_EFFECT\",\"m_as_type\":\"NO_EFFECT\",\"triage_state\":\"reviewed\",\"triaged_at\":\"2026-06-03T18:55:42.108938Z\",\"triaged_by\":\"00000000-0000-0000-0000-000000000000\"}],\"metadata\":{\"count\":585},\"paging\":{\"offset\":1}}}}", "encoding": null }, "headers": { @@ -26,7 +26,7 @@ "message": "OK" } }, - "recorded_at": "Tue, 14 Apr 2026 18:22:48 GMT" + "recorded_at": "Fri, 05 Jun 2026 12:32:21 GMT" } ], "recorded_with": "VCR 6.0.0" diff --git a/tests/scenarios/features/v2/security_monitoring.feature b/tests/scenarios/features/v2/security_monitoring.feature index bae8918780..7e4a21f8c6 100644 --- a/tests/scenarios/features/v2/security_monitoring.feature +++ b/tests/scenarios/features/v2/security_monitoring.feature @@ -954,6 +954,22 @@ Feature: Security Monitoring When the request is sent Then the response status is 404 Not Found + @replay-only @skip-terraform-config @team:DataDog/k9-cloud-siem + Scenario: Create or update an indicator triage state returns "Bad Request" response + Given operation "CreateIoCTriageState" enabled + And new "CreateIoCTriageState" request + And body with value {"data": {"attributes": {"indicator": "192.0.2.1", "triage_state": "invalid_state"}, "type": "ioc_triage_state"}} + When the request is sent + Then the response status is 400 Bad Request + + @replay-only @skip-terraform-config @team:DataDog/k9-cloud-siem + Scenario: Create or update an indicator triage state returns "Created" response + Given operation "CreateIoCTriageState" enabled + And new "CreateIoCTriageState" request + And body with value {"data": {"attributes": {"indicator": "192.0.2.1", "triage_state": "reviewed"}, "type": "ioc_triage_state"}} + When the request is sent + Then the response status is 201 Created + @generated @skip @team:DataDog/k9-cloud-siem Scenario: Deactivate content pack returns "Accepted" response Given operation "DeactivateContentPack" enabled @@ -1730,7 +1746,8 @@ Feature: Security Monitoring Scenario: Get an indicator of compromise returns "OK" response Given operation "GetIndicatorOfCompromise" enabled And new "GetIndicatorOfCompromise" request - And request contains "indicator" parameter with value "masscan/1.3 (https://github.com/robertdavidgraham/masscan)" + And request contains "indicator" parameter with value "192.0.2.1" + And request contains "include_triage_history" parameter with value true When the request is sent Then the response status is 200 OK diff --git a/tests/scenarios/features/v2/undo.json b/tests/scenarios/features/v2/undo.json index 9101d0155c..e5e1b9ed26 100644 --- a/tests/scenarios/features/v2/undo.json +++ b/tests/scenarios/features/v2/undo.json @@ -6706,6 +6706,12 @@ "type": "safe" } }, + "CreateIoCTriageState": { + "tag": "Security Monitoring", + "undo": { + "type": "safe" + } + }, "GetSignalNotificationRules": { "tag": "Security Monitoring", "undo": { diff --git a/tests/scenarios/function_mappings.rs b/tests/scenarios/function_mappings.rs index 1b05e31666..df529b7cab 100644 --- a/tests/scenarios/function_mappings.rs +++ b/tests/scenarios/function_mappings.rs @@ -3409,6 +3409,10 @@ pub fn collect_function_calls(world: &mut DatadogWorld) { "v2.GetIndicatorOfCompromise".into(), test_v2_get_indicator_of_compromise, ); + world.function_mappings.insert( + "v2.CreateIoCTriageState".into(), + test_v2_create_io_c_triage_state, + ); world.function_mappings.insert( "v2.GetSignalNotificationRules".into(), test_v2_get_signal_notification_rules, @@ -25161,6 +25165,15 @@ fn test_v2_list_indicators_of_compromise( let sort_order = _parameters .get("sort[order]") .and_then(|param| Some(serde_json::from_value(param.clone()).unwrap())); + let ocsf = _parameters + .get("ocsf") + .and_then(|param| Some(serde_json::from_value(param.clone()).unwrap())); + let worked_by = _parameters + .get("worked_by") + .and_then(|param| Some(serde_json::from_value(param.clone()).unwrap())); + let triage_state = _parameters + .get("triage_state") + .and_then(|param| Some(serde_json::from_value(param.clone()).unwrap())); let mut params = datadogV2::api_security_monitoring::ListIndicatorsOfCompromiseOptionalParams::default(); params.limit = limit; @@ -25168,6 +25181,9 @@ fn test_v2_list_indicators_of_compromise( params.query = query; params.sort_column = sort_column; params.sort_order = sort_order; + params.ocsf = ocsf; + params.worked_by = worked_by; + params.triage_state = triage_state; let response = match block_on(api.list_indicators_of_compromise_with_http_info(params)) { Ok(response) => response, Err(error) => { @@ -25196,7 +25212,54 @@ fn test_v2_get_indicator_of_compromise( .as_ref() .expect("api instance not found"); let indicator = serde_json::from_value(_parameters.get("indicator").unwrap().clone()).unwrap(); - let response = match block_on(api.get_indicator_of_compromise_with_http_info(indicator)) { + let ocsf = _parameters + .get("ocsf") + .and_then(|param| Some(serde_json::from_value(param.clone()).unwrap())); + let include_triage_history = _parameters + .get("include_triage_history") + .and_then(|param| Some(serde_json::from_value(param.clone()).unwrap())); + let triage_history_limit = _parameters + .get("triage_history_limit") + .and_then(|param| Some(serde_json::from_value(param.clone()).unwrap())); + let triage_history_offset = _parameters + .get("triage_history_offset") + .and_then(|param| Some(serde_json::from_value(param.clone()).unwrap())); + let mut params = + datadogV2::api_security_monitoring::GetIndicatorOfCompromiseOptionalParams::default(); + params.ocsf = ocsf; + params.include_triage_history = include_triage_history; + params.triage_history_limit = triage_history_limit; + params.triage_history_offset = triage_history_offset; + let response = match block_on(api.get_indicator_of_compromise_with_http_info(indicator, 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_create_io_c_triage_state( + 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.create_io_c_triage_state_with_http_info(body)) { Ok(response) => response, Err(error) => { return match error {