Skip to content

Commit 11ec058

Browse files
api-clients-generation-pipeline[bot]ci.datadog-api-spec
andauthored
Added new optional field definition to include more detail in findings for '/api/v2/posture_management/findings' (#663)
Co-authored-by: ci.datadog-api-spec <[email protected]>
1 parent a50313c commit 11ec058

File tree

9 files changed

+208
-11
lines changed

9 files changed

+208
-11
lines changed

.apigentools-info

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
"spec_versions": {
55
"v1": {
66
"apigentools_version": "1.6.6",
7-
"regenerated": "2025-06-05 08:11:20.110994",
8-
"spec_repo_commit": "0e7259ca"
7+
"regenerated": "2025-06-05 09:49:39.264892",
8+
"spec_repo_commit": "faa72400"
99
},
1010
"v2": {
1111
"apigentools_version": "1.6.6",
12-
"regenerated": "2025-06-05 08:11:20.126935",
13-
"spec_repo_commit": "0e7259ca"
12+
"regenerated": "2025-06-05 09:49:39.280328",
13+
"spec_repo_commit": "faa72400"
1414
}
1515
}
1616
}

.generator/schemas/v2/openapi.yaml

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15279,10 +15279,16 @@ components:
1527915279
FindingAttributes:
1528015280
description: The JSON:API attributes of the finding.
1528115281
properties:
15282+
datadog_link:
15283+
$ref: '#/components/schemas/FindingDatadogLink'
15284+
description:
15285+
$ref: '#/components/schemas/FindingDescription'
1528215286
evaluation:
1528315287
$ref: '#/components/schemas/FindingEvaluation'
1528415288
evaluation_changed_at:
1528515289
$ref: '#/components/schemas/FindingEvaluationChangedAt'
15290+
external_id:
15291+
$ref: '#/components/schemas/FindingExternalId'
1528615292
mute:
1528715293
$ref: '#/components/schemas/FindingMute'
1528815294
resource:
@@ -15300,6 +15306,22 @@ components:
1530015306
vulnerability_type:
1530115307
$ref: '#/components/schemas/FindingVulnerabilityType'
1530215308
type: object
15309+
FindingDatadogLink:
15310+
description: The Datadog relative link for this finding.
15311+
example: /security/compliance?panels=cpfinding%7Cevent%7CruleId%3Adef-000-u5t%7CresourceId%3Ae8c9ab7c52ebd7bf2fdb4db641082d7d%7CtabId%3Aoverview
15312+
type: string
15313+
FindingDescription:
15314+
description: The description and remediation steps for this finding.
15315+
example: '## Remediation
15316+
15317+
15318+
1. In the console, go to **Storage Account**.
15319+
15320+
2. For each Storage Account, navigate to **Data Protection**.
15321+
15322+
3. Select **Set soft delete enabled** and enter the number of days to retain
15323+
soft deleted data.'
15324+
type: string
1530315325
FindingEvaluation:
1530415326
description: The evaluation of the finding.
1530515327
enum:
@@ -15317,6 +15339,10 @@ components:
1531715339
format: int64
1531815340
minimum: 1
1531915341
type: integer
15342+
FindingExternalId:
15343+
description: The cloud-based ID for the resource related to the finding.
15344+
example: arn:aws:s3:::my-example-bucket
15345+
type: string
1532015346
FindingID:
1532115347
description: The unique ID for this finding.
1532215348
example: ZGVmLTAwcC1pZXJ-aS0wZjhjNjMyZDNmMzRlZTgzNw==
@@ -53082,13 +53108,19 @@ paths:
5308253108
the equal sign: `filter[evaluation_changed_at]=>=1678809373257`.\n\nQuery
5308353109
parameters must be only among the documented ones and with values of correct
5308453110
types. Duplicated query parameters (e.g. `filter[status]=low&filter[status]=info`)
53085-
are not allowed.\n\n### Response\n\nThe response includes an array of finding
53086-
objects, pagination metadata, and a count of items that match the query.\n\nEach
53087-
finding object contains the following:\n\n- The finding ID that can be used
53088-
in a `GetFinding` request to retrieve the full finding details.\n- Core attributes,
53089-
including status, evaluation, high-level resource details, muted state, and
53090-
rule details.\n- `evaluation_changed_at` and `resource_discovery_date` time
53091-
stamps.\n- An array of associated tags.\n"
53111+
are not allowed.\n\n### Additional extension fields\n\nAdditional extension
53112+
fields are available for some findings.\n\nThe data is available when you
53113+
include the query parameter `?detailed_findings=true` in the request.\n\nThe
53114+
following fields are available for findings:\n- `external_id`: The resource
53115+
external ID related to the finding.\n- `description`: The description and
53116+
remediation steps for the finding.\n- `datadog_link`: The Datadog relative
53117+
link for the finding.\n\n### Response\n\nThe response includes an array of
53118+
finding objects, pagination metadata, and a count of items that match the
53119+
query.\n\nEach finding object contains the following:\n\n- The finding ID
53120+
that can be used in a `GetFinding` request to retrieve the full finding details.\n-
53121+
Core attributes, including status, evaluation, high-level resource details,
53122+
muted state, and rule details.\n- `evaluation_changed_at` and `resource_discovery_date`
53123+
time stamps.\n- An array of associated tags.\n"
5309253124
operationId: ListFindings
5309353125
parameters:
5309453126
- description: Limit the number of findings returned. Must be <= 1000.
@@ -53191,6 +53223,14 @@ paths:
5319153223
items:
5319253224
$ref: '#/components/schemas/FindingVulnerabilityType'
5319353225
type: array
53226+
- description: Return additional fields for some findings.
53227+
example:
53228+
- true
53229+
in: query
53230+
name: detailed_findings
53231+
required: false
53232+
schema:
53233+
type: boolean
5319453234
responses:
5319553235
'200':
5319653236
content:
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// List findings returns "OK" response with details
2+
use datadog_api_client::datadog;
3+
use datadog_api_client::datadogV2::api_security_monitoring::ListFindingsOptionalParams;
4+
use datadog_api_client::datadogV2::api_security_monitoring::SecurityMonitoringAPI;
5+
6+
#[tokio::main]
7+
async fn main() {
8+
let mut configuration = datadog::Configuration::new();
9+
configuration.set_unstable_operation_enabled("v2.ListFindings", true);
10+
let api = SecurityMonitoringAPI::with_config(configuration);
11+
let resp = api
12+
.list_findings(ListFindingsOptionalParams::default().detailed_findings(true))
13+
.await;
14+
if let Ok(value) = resp {
15+
println!("{:#?}", value);
16+
} else {
17+
println!("{:#?}", resp.unwrap_err());
18+
}
19+
}

src/datadogV2/api/api_security_monitoring.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ pub struct ListFindingsOptionalParams {
128128
pub filter_status: Option<crate::datadogV2::model::FindingStatus>,
129129
/// Return findings that match the selected vulnerability types (repeatable).
130130
pub filter_vulnerability_type: Option<Vec<crate::datadogV2::model::FindingVulnerabilityType>>,
131+
/// Return additional fields for some findings.
132+
pub detailed_findings: Option<bool>,
131133
}
132134

133135
impl ListFindingsOptionalParams {
@@ -199,6 +201,11 @@ impl ListFindingsOptionalParams {
199201
self.filter_vulnerability_type = Some(value);
200202
self
201203
}
204+
/// Return additional fields for some findings.
205+
pub fn detailed_findings(mut self, value: bool) -> Self {
206+
self.detailed_findings = Some(value);
207+
self
208+
}
202209
}
203210

204211
/// ListHistoricalJobsOptionalParams is a struct for passing parameters to the method [`SecurityMonitoringAPI::list_historical_jobs`]
@@ -5540,6 +5547,17 @@ impl SecurityMonitoringAPI {
55405547
///
55415548
/// Query parameters must be only among the documented ones and with values of correct types. Duplicated query parameters (e.g. `filter[status]=low&filter[status]=info`) are not allowed.
55425549
///
5550+
/// ### Additional extension fields
5551+
///
5552+
/// Additional extension fields are available for some findings.
5553+
///
5554+
/// The data is available when you include the query parameter `?detailed_findings=true` in the request.
5555+
///
5556+
/// The following fields are available for findings:
5557+
/// - `external_id`: The resource external ID related to the finding.
5558+
/// - `description`: The description and remediation steps for the finding.
5559+
/// - `datadog_link`: The Datadog relative link for the finding.
5560+
///
55435561
/// ### Response
55445562
///
55455563
/// The response includes an array of finding objects, pagination metadata, and a count of items that match the query.
@@ -5625,6 +5643,17 @@ impl SecurityMonitoringAPI {
56255643
///
56265644
/// Query parameters must be only among the documented ones and with values of correct types. Duplicated query parameters (e.g. `filter[status]=low&filter[status]=info`) are not allowed.
56275645
///
5646+
/// ### Additional extension fields
5647+
///
5648+
/// Additional extension fields are available for some findings.
5649+
///
5650+
/// The data is available when you include the query parameter `?detailed_findings=true` in the request.
5651+
///
5652+
/// The following fields are available for findings:
5653+
/// - `external_id`: The resource external ID related to the finding.
5654+
/// - `description`: The description and remediation steps for the finding.
5655+
/// - `datadog_link`: The Datadog relative link for the finding.
5656+
///
56285657
/// ### Response
56295658
///
56305659
/// The response includes an array of finding objects, pagination metadata, and a count of items that match the query.
@@ -5668,6 +5697,7 @@ impl SecurityMonitoringAPI {
56685697
let filter_evaluation = params.filter_evaluation;
56695698
let filter_status = params.filter_status;
56705699
let filter_vulnerability_type = params.filter_vulnerability_type;
5700+
let detailed_findings = params.detailed_findings;
56715701

56725702
let local_client = &self.client;
56735703

@@ -5736,6 +5766,10 @@ impl SecurityMonitoringAPI {
57365766
local_req_builder.query(&[("filter[vulnerability_type]", &param.to_string())]);
57375767
}
57385768
};
5769+
if let Some(ref local_query_param) = detailed_findings {
5770+
local_req_builder =
5771+
local_req_builder.query(&[("detailed_findings", &local_query_param.to_string())]);
5772+
};
57395773

57405774
// build headers
57415775
let mut headers = HeaderMap::new();

src/datadogV2/model/model_finding_attributes.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,21 @@ use std::fmt::{self, Formatter};
1111
#[skip_serializing_none]
1212
#[derive(Clone, Debug, PartialEq, Serialize)]
1313
pub struct FindingAttributes {
14+
/// The Datadog relative link for this finding.
15+
#[serde(rename = "datadog_link")]
16+
pub datadog_link: Option<String>,
17+
/// The description and remediation steps for this finding.
18+
#[serde(rename = "description")]
19+
pub description: Option<String>,
1420
/// The evaluation of the finding.
1521
#[serde(rename = "evaluation")]
1622
pub evaluation: Option<crate::datadogV2::model::FindingEvaluation>,
1723
/// The date on which the evaluation for this finding changed (Unix ms).
1824
#[serde(rename = "evaluation_changed_at")]
1925
pub evaluation_changed_at: Option<i64>,
26+
/// The cloud-based ID for the resource related to the finding.
27+
#[serde(rename = "external_id")]
28+
pub external_id: Option<String>,
2029
/// Information about the mute status of this finding.
2130
#[serde(rename = "mute")]
2231
pub mute: Option<crate::datadogV2::model::FindingMute>,
@@ -51,8 +60,11 @@ pub struct FindingAttributes {
5160
impl FindingAttributes {
5261
pub fn new() -> FindingAttributes {
5362
FindingAttributes {
63+
datadog_link: None,
64+
description: None,
5465
evaluation: None,
5566
evaluation_changed_at: None,
67+
external_id: None,
5668
mute: None,
5769
resource: None,
5870
resource_discovery_date: None,
@@ -66,6 +78,16 @@ impl FindingAttributes {
6678
}
6779
}
6880

81+
pub fn datadog_link(mut self, value: String) -> Self {
82+
self.datadog_link = Some(value);
83+
self
84+
}
85+
86+
pub fn description(mut self, value: String) -> Self {
87+
self.description = Some(value);
88+
self
89+
}
90+
6991
pub fn evaluation(mut self, value: crate::datadogV2::model::FindingEvaluation) -> Self {
7092
self.evaluation = Some(value);
7193
self
@@ -76,6 +98,11 @@ impl FindingAttributes {
7698
self
7799
}
78100

101+
pub fn external_id(mut self, value: String) -> Self {
102+
self.external_id = Some(value);
103+
self
104+
}
105+
79106
pub fn mute(mut self, value: crate::datadogV2::model::FindingMute) -> Self {
80107
self.mute = Some(value);
81108
self
@@ -151,8 +178,11 @@ impl<'de> Deserialize<'de> for FindingAttributes {
151178
where
152179
M: MapAccess<'a>,
153180
{
181+
let mut datadog_link: Option<String> = None;
182+
let mut description: Option<String> = None;
154183
let mut evaluation: Option<crate::datadogV2::model::FindingEvaluation> = None;
155184
let mut evaluation_changed_at: Option<i64> = None;
185+
let mut external_id: Option<String> = None;
156186
let mut mute: Option<crate::datadogV2::model::FindingMute> = None;
157187
let mut resource: Option<String> = None;
158188
let mut resource_discovery_date: Option<i64> = None;
@@ -171,6 +201,20 @@ impl<'de> Deserialize<'de> for FindingAttributes {
171201

172202
while let Some((k, v)) = map.next_entry::<String, serde_json::Value>()? {
173203
match k.as_str() {
204+
"datadog_link" => {
205+
if v.is_null() {
206+
continue;
207+
}
208+
datadog_link =
209+
Some(serde_json::from_value(v).map_err(M::Error::custom)?);
210+
}
211+
"description" => {
212+
if v.is_null() {
213+
continue;
214+
}
215+
description =
216+
Some(serde_json::from_value(v).map_err(M::Error::custom)?);
217+
}
174218
"evaluation" => {
175219
if v.is_null() {
176220
continue;
@@ -194,6 +238,13 @@ impl<'de> Deserialize<'de> for FindingAttributes {
194238
evaluation_changed_at =
195239
Some(serde_json::from_value(v).map_err(M::Error::custom)?);
196240
}
241+
"external_id" => {
242+
if v.is_null() {
243+
continue;
244+
}
245+
external_id =
246+
Some(serde_json::from_value(v).map_err(M::Error::custom)?);
247+
}
197248
"mute" => {
198249
if v.is_null() {
199250
continue;
@@ -272,8 +323,11 @@ impl<'de> Deserialize<'de> for FindingAttributes {
272323
}
273324

274325
let content = FindingAttributes {
326+
datadog_link,
327+
description,
275328
evaluation,
276329
evaluation_changed_at,
330+
external_id,
277331
mute,
278332
resource,
279333
resource_discovery_date,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2025-05-20T12:11:24.321Z
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"http_interactions": [
3+
{
4+
"request": {
5+
"body": "",
6+
"headers": {
7+
"Accept": [
8+
"application/json"
9+
]
10+
},
11+
"method": "get",
12+
"uri": "https://api.datadoghq.com/api/v2/posture_management/findings?detailed_findings=true"
13+
},
14+
"response": {
15+
"body": {
16+
"string": "{\"data\":[],\"meta\":{\"page\":{\"total_filtered_count\":0},\"snapshot_timestamp\":1747743085077}}",
17+
"encoding": null
18+
},
19+
"headers": {
20+
"Content-Type": [
21+
"application/vnd.api+json"
22+
]
23+
},
24+
"status": {
25+
"code": 200,
26+
"message": "OK"
27+
}
28+
},
29+
"recorded_at": "Tue, 20 May 2025 12:11:24 GMT"
30+
}
31+
],
32+
"recorded_with": "VCR 6.0.0"
33+
}

tests/scenarios/features/v2/security_monitoring.feature

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,14 @@ Feature: Security Monitoring
840840
Then the response status is 200 OK
841841
And the response "data[0].type" is equal to "finding"
842842

843+
@team:DataDog/cloud-security-posture-management
844+
Scenario: List findings returns "OK" response with details
845+
Given operation "ListFindings" enabled
846+
And new "ListFindings" request
847+
And request contains "detailed_findings" parameter with value true
848+
When the request is sent
849+
Then the response status is 200 OK
850+
843851
@generated @skip @team:DataDog/cloud-security-posture-management @with-pagination
844852
Scenario: List findings returns "OK" response with pagination
845853
Given operation "ListFindings" enabled

0 commit comments

Comments
 (0)