Skip to content

Commit 5efce7d

Browse files
api-clients-generation-pipeline[bot]ci.datadog-api-spec
andauthored
Adds async Scorecard outcomes batch update endpoint (#844)
Co-authored-by: ci.datadog-api-spec <[email protected]>
1 parent a256551 commit 5efce7d

27 files changed

+1364
-5
lines changed

.generated-info

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"spec_repo_commit": "62a19e4",
3-
"generated": "2025-08-27 15:06:21.847"
2+
"spec_repo_commit": "6d9663b",
3+
"generated": "2025-08-27 16:43:08.416"
44
}

.generator/schemas/v2/openapi.yaml

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14485,6 +14485,10 @@ components:
1448514485
description: Entity definition in raw JSON or YAML representation.
1448614486
example: "apiVersion: v3\nkind: service\nmetadata:\n name: myservice\n"
1448714487
type: string
14488+
EntityReference:
14489+
description: The unique reference for an IDP entity.
14490+
example: service:my-service
14491+
type: string
1448814492
EntityRelationships:
1448914493
description: Entity relationships.
1449014494
properties:
@@ -34444,6 +34448,8 @@ components:
3444434448
description: If enabled, the rule is calculated as part of the score.
3444534449
example: true
3444634450
type: boolean
34451+
level:
34452+
$ref: '#/components/schemas/RuleLevel'
3444734453
modified_at:
3444834454
description: Time of the last rule outcome modification.
3444934455
format: date-time
@@ -34464,6 +34470,13 @@ components:
3446434470
description: The unique ID for a scorecard rule.
3446534471
example: q8MQxk8TCqrHnWkx
3446634472
type: string
34473+
RuleLevel:
34474+
description: The maturity level of the rule (1, 2, or 3).
34475+
example: 2
34476+
format: int32
34477+
maximum: 3
34478+
minimum: 1
34479+
type: integer
3446734480
RuleName:
3446834481
description: Name of the notification rule.
3446934482
example: Rule 1
@@ -43835,6 +43848,57 @@ components:
4383543848
id:
4383643849
$ref: '#/components/schemas/ApiID'
4383743850
type: object
43851+
UpdateOutcomesAsyncAttributes:
43852+
description: The JSON:API attributes for a batched set of scorecard outcomes.
43853+
properties:
43854+
results:
43855+
description: Set of scorecard outcomes to update asynchronously.
43856+
items:
43857+
$ref: '#/components/schemas/UpdateOutcomesAsyncRequestItem'
43858+
type: array
43859+
type: object
43860+
UpdateOutcomesAsyncRequest:
43861+
description: Scorecard outcomes batch request.
43862+
properties:
43863+
data:
43864+
$ref: '#/components/schemas/UpdateOutcomesAsyncRequestData'
43865+
type: object
43866+
UpdateOutcomesAsyncRequestData:
43867+
description: Scorecard outcomes batch request data.
43868+
properties:
43869+
attributes:
43870+
$ref: '#/components/schemas/UpdateOutcomesAsyncAttributes'
43871+
type:
43872+
$ref: '#/components/schemas/UpdateOutcomesAsyncType'
43873+
type: object
43874+
UpdateOutcomesAsyncRequestItem:
43875+
description: Scorecard outcome for a single entity and rule.
43876+
properties:
43877+
entity_reference:
43878+
$ref: '#/components/schemas/EntityReference'
43879+
remarks:
43880+
description: Any remarks regarding the scorecard rule's evaluation. Supports
43881+
HTML hyperlinks.
43882+
example: 'See: <a href="https://app.datadoghq.com/services">Services</a>'
43883+
type: string
43884+
rule_id:
43885+
$ref: '#/components/schemas/RuleId'
43886+
state:
43887+
$ref: '#/components/schemas/State'
43888+
required:
43889+
- rule_id
43890+
- entity_reference
43891+
- state
43892+
type: object
43893+
UpdateOutcomesAsyncType:
43894+
default: batched-outcome
43895+
description: The JSON:API type for scorecard outcomes.
43896+
enum:
43897+
- batched-outcome
43898+
example: batched-outcome
43899+
type: string
43900+
x-enum-varnames:
43901+
- BATCHED_OUTCOME
4383843902
UpdateResourceEvaluationFiltersRequest:
4383943903
description: Request object to update a resource filter.
4384043904
properties:
@@ -61882,6 +61946,39 @@ paths:
6188261946
resultsPath: data
6188361947
x-unstable: '**Note**: This endpoint is in public beta.
6188461948

61949+
If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/).'
61950+
post:
61951+
description: Updates multiple scorecard rule outcomes in a single batched request.
61952+
operationId: UpdateScorecardOutcomesAsync
61953+
requestBody:
61954+
content:
61955+
application/json:
61956+
schema:
61957+
$ref: '#/components/schemas/UpdateOutcomesAsyncRequest'
61958+
description: Set of scorecard outcomes.
61959+
required: true
61960+
responses:
61961+
'202':
61962+
description: Accepted
61963+
'400':
61964+
$ref: '#/components/responses/BadRequestResponse'
61965+
'403':
61966+
$ref: '#/components/responses/ForbiddenResponse'
61967+
'409':
61968+
$ref: '#/components/responses/ConflictResponse'
61969+
'429':
61970+
$ref: '#/components/responses/TooManyRequestsResponse'
61971+
security:
61972+
- apiKeyAuth: []
61973+
appKeyAuth: []
61974+
- AuthZ:
61975+
- apm_service_catalog_write
61976+
summary: Update Scorecard outcomes asynchronously
61977+
tags:
61978+
- Service Scorecards
61979+
x-codegen-request-body-name: body
61980+
x-unstable: '**Note**: This endpoint is in public beta.
61981+
6188561982
If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/).'
6188661983
/api/v2/scorecard/outcomes/batch:
6188761984
post:
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Update Scorecard outcomes asynchronously returns "Accepted" response
2+
use datadog_api_client::datadog;
3+
use datadog_api_client::datadogV2::api_service_scorecards::ServiceScorecardsAPI;
4+
use datadog_api_client::datadogV2::model::State;
5+
use datadog_api_client::datadogV2::model::UpdateOutcomesAsyncAttributes;
6+
use datadog_api_client::datadogV2::model::UpdateOutcomesAsyncRequest;
7+
use datadog_api_client::datadogV2::model::UpdateOutcomesAsyncRequestData;
8+
use datadog_api_client::datadogV2::model::UpdateOutcomesAsyncRequestItem;
9+
use datadog_api_client::datadogV2::model::UpdateOutcomesAsyncType;
10+
11+
#[tokio::main]
12+
async fn main() {
13+
// there is a valid "create_scorecard_rule" in the system
14+
let create_scorecard_rule_data_id = std::env::var("CREATE_SCORECARD_RULE_DATA_ID").unwrap();
15+
let body = UpdateOutcomesAsyncRequest::new().data(
16+
UpdateOutcomesAsyncRequestData::new()
17+
.attributes(UpdateOutcomesAsyncAttributes::new().results(vec![
18+
UpdateOutcomesAsyncRequestItem::new(
19+
"service:my-service".to_string(),
20+
create_scorecard_rule_data_id.clone(),
21+
State::PASS,
22+
)
23+
.remarks(
24+
r#"See: <a href="https://app.datadoghq.com/services">Services</a>"#
25+
.to_string(),
26+
),
27+
]))
28+
.type_(UpdateOutcomesAsyncType::BATCHED_OUTCOME),
29+
);
30+
let mut configuration = datadog::Configuration::new();
31+
configuration.set_unstable_operation_enabled("v2.UpdateScorecardOutcomesAsync", true);
32+
let api = ServiceScorecardsAPI::with_config(configuration);
33+
let resp = api.update_scorecard_outcomes_async(body).await;
34+
if let Ok(value) = resp {
35+
println!("{:#?}", value);
36+
} else {
37+
println!("{:#?}", resp.unwrap_err());
38+
}
39+
}

src/datadog/configuration.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ impl Default for Configuration {
201201
("v2.delete_scorecard_rule".to_owned(), false),
202202
("v2.list_scorecard_outcomes".to_owned(), false),
203203
("v2.list_scorecard_rules".to_owned(), false),
204+
("v2.update_scorecard_outcomes_async".to_owned(), false),
204205
("v2.update_scorecard_rule".to_owned(), false),
205206
("v2.create_incident_service".to_owned(), false),
206207
("v2.delete_incident_service".to_owned(), false),

src/datadogV2/api/api_service_scorecards.rs

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,14 @@ pub enum ListScorecardRulesError {
211211
UnknownValue(serde_json::Value),
212212
}
213213

214+
/// UpdateScorecardOutcomesAsyncError is a struct for typed errors of method [`ServiceScorecardsAPI::update_scorecard_outcomes_async`]
215+
#[derive(Debug, Clone, Serialize, Deserialize)]
216+
#[serde(untagged)]
217+
pub enum UpdateScorecardOutcomesAsyncError {
218+
APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
219+
UnknownValue(serde_json::Value),
220+
}
221+
214222
/// UpdateScorecardRuleError is a struct for typed errors of method [`ServiceScorecardsAPI::update_scorecard_rule`]
215223
#[derive(Debug, Clone, Serialize, Deserialize)]
216224
#[serde(untagged)]
@@ -1117,6 +1125,151 @@ impl ServiceScorecardsAPI {
11171125
}
11181126
}
11191127

1128+
/// Updates multiple scorecard rule outcomes in a single batched request.
1129+
pub async fn update_scorecard_outcomes_async(
1130+
&self,
1131+
body: crate::datadogV2::model::UpdateOutcomesAsyncRequest,
1132+
) -> Result<(), datadog::Error<UpdateScorecardOutcomesAsyncError>> {
1133+
match self
1134+
.update_scorecard_outcomes_async_with_http_info(body)
1135+
.await
1136+
{
1137+
Ok(_) => Ok(()),
1138+
Err(err) => Err(err),
1139+
}
1140+
}
1141+
1142+
/// Updates multiple scorecard rule outcomes in a single batched request.
1143+
pub async fn update_scorecard_outcomes_async_with_http_info(
1144+
&self,
1145+
body: crate::datadogV2::model::UpdateOutcomesAsyncRequest,
1146+
) -> Result<datadog::ResponseContent<()>, datadog::Error<UpdateScorecardOutcomesAsyncError>>
1147+
{
1148+
let local_configuration = &self.config;
1149+
let operation_id = "v2.update_scorecard_outcomes_async";
1150+
if local_configuration.is_unstable_operation_enabled(operation_id) {
1151+
warn!("Using unstable operation {operation_id}");
1152+
} else {
1153+
let local_error = datadog::UnstableOperationDisabledError {
1154+
msg: "Operation 'v2.update_scorecard_outcomes_async' is not enabled".to_string(),
1155+
};
1156+
return Err(datadog::Error::UnstableOperationDisabledError(local_error));
1157+
}
1158+
1159+
let local_client = &self.client;
1160+
1161+
let local_uri_str = format!(
1162+
"{}/api/v2/scorecard/outcomes",
1163+
local_configuration.get_operation_host(operation_id)
1164+
);
1165+
let mut local_req_builder =
1166+
local_client.request(reqwest::Method::POST, local_uri_str.as_str());
1167+
1168+
// build headers
1169+
let mut headers = HeaderMap::new();
1170+
headers.insert("Content-Type", HeaderValue::from_static("application/json"));
1171+
headers.insert("Accept", HeaderValue::from_static("*/*"));
1172+
1173+
// build user agent
1174+
match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
1175+
Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
1176+
Err(e) => {
1177+
log::warn!("Failed to parse user agent header: {e}, falling back to default");
1178+
headers.insert(
1179+
reqwest::header::USER_AGENT,
1180+
HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
1181+
)
1182+
}
1183+
};
1184+
1185+
// build auth
1186+
if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
1187+
headers.insert(
1188+
"DD-API-KEY",
1189+
HeaderValue::from_str(local_key.key.as_str())
1190+
.expect("failed to parse DD-API-KEY header"),
1191+
);
1192+
};
1193+
if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
1194+
headers.insert(
1195+
"DD-APPLICATION-KEY",
1196+
HeaderValue::from_str(local_key.key.as_str())
1197+
.expect("failed to parse DD-APPLICATION-KEY header"),
1198+
);
1199+
};
1200+
1201+
// build body parameters
1202+
let output = Vec::new();
1203+
let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter);
1204+
if body.serialize(&mut ser).is_ok() {
1205+
if let Some(content_encoding) = headers.get("Content-Encoding") {
1206+
match content_encoding.to_str().unwrap_or_default() {
1207+
"gzip" => {
1208+
let mut enc = GzEncoder::new(Vec::new(), Compression::default());
1209+
let _ = enc.write_all(ser.into_inner().as_slice());
1210+
match enc.finish() {
1211+
Ok(buf) => {
1212+
local_req_builder = local_req_builder.body(buf);
1213+
}
1214+
Err(e) => return Err(datadog::Error::Io(e)),
1215+
}
1216+
}
1217+
"deflate" => {
1218+
let mut enc = ZlibEncoder::new(Vec::new(), Compression::default());
1219+
let _ = enc.write_all(ser.into_inner().as_slice());
1220+
match enc.finish() {
1221+
Ok(buf) => {
1222+
local_req_builder = local_req_builder.body(buf);
1223+
}
1224+
Err(e) => return Err(datadog::Error::Io(e)),
1225+
}
1226+
}
1227+
"zstd1" => {
1228+
let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap();
1229+
let _ = enc.write_all(ser.into_inner().as_slice());
1230+
match enc.finish() {
1231+
Ok(buf) => {
1232+
local_req_builder = local_req_builder.body(buf);
1233+
}
1234+
Err(e) => return Err(datadog::Error::Io(e)),
1235+
}
1236+
}
1237+
_ => {
1238+
local_req_builder = local_req_builder.body(ser.into_inner());
1239+
}
1240+
}
1241+
} else {
1242+
local_req_builder = local_req_builder.body(ser.into_inner());
1243+
}
1244+
}
1245+
1246+
local_req_builder = local_req_builder.headers(headers);
1247+
let local_req = local_req_builder.build()?;
1248+
log::debug!("request content: {:?}", local_req.body());
1249+
let local_resp = local_client.execute(local_req).await?;
1250+
1251+
let local_status = local_resp.status();
1252+
let local_content = local_resp.text().await?;
1253+
log::debug!("response content: {}", local_content);
1254+
1255+
if !local_status.is_client_error() && !local_status.is_server_error() {
1256+
Ok(datadog::ResponseContent {
1257+
status: local_status,
1258+
content: local_content,
1259+
entity: None,
1260+
})
1261+
} else {
1262+
let local_entity: Option<UpdateScorecardOutcomesAsyncError> =
1263+
serde_json::from_str(&local_content).ok();
1264+
let local_error = datadog::ResponseContent {
1265+
status: local_status,
1266+
content: local_content,
1267+
entity: local_entity,
1268+
};
1269+
Err(datadog::Error::ResponseError(local_error))
1270+
}
1271+
}
1272+
11201273
/// Updates an existing rule.
11211274
pub async fn update_scorecard_rule(
11221275
&self,

src/datadogV2/model/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4514,6 +4514,16 @@ pub mod model_outcomes_response_included_rule_attributes;
45144514
pub use self::model_outcomes_response_included_rule_attributes::OutcomesResponseIncludedRuleAttributes;
45154515
pub mod model_outcomes_response_links;
45164516
pub use self::model_outcomes_response_links::OutcomesResponseLinks;
4517+
pub mod model_update_outcomes_async_request;
4518+
pub use self::model_update_outcomes_async_request::UpdateOutcomesAsyncRequest;
4519+
pub mod model_update_outcomes_async_request_data;
4520+
pub use self::model_update_outcomes_async_request_data::UpdateOutcomesAsyncRequestData;
4521+
pub mod model_update_outcomes_async_attributes;
4522+
pub use self::model_update_outcomes_async_attributes::UpdateOutcomesAsyncAttributes;
4523+
pub mod model_update_outcomes_async_request_item;
4524+
pub use self::model_update_outcomes_async_request_item::UpdateOutcomesAsyncRequestItem;
4525+
pub mod model_update_outcomes_async_type;
4526+
pub use self::model_update_outcomes_async_type::UpdateOutcomesAsyncType;
45174527
pub mod model_outcomes_batch_request;
45184528
pub use self::model_outcomes_batch_request::OutcomesBatchRequest;
45194529
pub mod model_outcomes_batch_request_data;

0 commit comments

Comments
 (0)