Skip to content

Commit affdecb

Browse files
api-clients-generation-pipeline[bot]ci.datadog-api-spec
and
ci.datadog-api-spec
authored
Add actions and groupSignalsBy field in detection rules API (#508)
Co-authored-by: ci.datadog-api-spec <[email protected]>
1 parent eebd580 commit affdecb

18 files changed

+691
-4
lines changed

.apigentools-info

+4-4
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-02-10 19:09:28.614674",
8-
"spec_repo_commit": "824f78a1"
7+
"regenerated": "2025-02-11 09:59:44.838748",
8+
"spec_repo_commit": "b980d49f"
99
},
1010
"v2": {
1111
"apigentools_version": "1.6.6",
12-
"regenerated": "2025-02-10 19:09:28.634477",
13-
"spec_repo_commit": "824f78a1"
12+
"regenerated": "2025-02-11 09:59:44.853754",
13+
"spec_repo_commit": "b980d49f"
1414
}
1515
}
1616
}

.generator/schemas/v2/openapi.yaml

+92
Original file line numberDiff line numberDiff line change
@@ -15657,6 +15657,15 @@ components:
1565715657
example: 1729843470000
1565815658
format: int64
1565915659
type: integer
15660+
groupSignalsBy:
15661+
description: Additional grouping to perform on top of the existing groups
15662+
in the query section. Must be a subset of the existing groups.
15663+
example:
15664+
- service
15665+
items:
15666+
description: Field to group by.
15667+
type: string
15668+
type: array
1566015669
index:
1566115670
description: Index used to load the data.
1566215671
example: cloud_siem
@@ -24242,6 +24251,11 @@ components:
2424224251
SecurityMonitoringRuleCase:
2424324252
description: Case when signal is generated.
2424424253
properties:
24254+
actions:
24255+
description: Action to perform for each rule case.
24256+
items:
24257+
$ref: '#/components/schemas/SecurityMonitoringRuleCaseAction'
24258+
type: array
2424524259
condition:
2424624260
description: 'A rule case contains logical operations (`>`,`>=`, `&&`, `||`)
2424724261
to determine if a signal should be generated
@@ -24260,9 +24274,42 @@ components:
2426024274
status:
2426124275
$ref: '#/components/schemas/SecurityMonitoringRuleSeverity'
2426224276
type: object
24277+
SecurityMonitoringRuleCaseAction:
24278+
description: Action to perform when a signal is triggered. Only available for
24279+
Application Security rule type.
24280+
properties:
24281+
options:
24282+
$ref: '#/components/schemas/SecurityMonitoringRuleCaseActionOptions'
24283+
type:
24284+
$ref: '#/components/schemas/SecurityMonitoringRuleCaseActionType'
24285+
type: object
24286+
SecurityMonitoringRuleCaseActionOptions:
24287+
description: Options for the rule action
24288+
properties:
24289+
duration:
24290+
description: Duration of the action in seconds. 0 indicates no expiration.
24291+
example: 0
24292+
format: int64
24293+
minimum: 0
24294+
type: integer
24295+
type: object
24296+
SecurityMonitoringRuleCaseActionType:
24297+
description: The action type.
24298+
enum:
24299+
- block_ip
24300+
- block_user
24301+
type: string
24302+
x-enum-varnames:
24303+
- BLOCK_IP
24304+
- BLOCK_USER
2426324305
SecurityMonitoringRuleCaseCreate:
2426424306
description: Case when signal is generated.
2426524307
properties:
24308+
actions:
24309+
description: Action to perform for each rule case.
24310+
items:
24311+
$ref: '#/components/schemas/SecurityMonitoringRuleCaseAction'
24312+
type: array
2426624313
condition:
2426724314
description: 'A case contains logical operations (`>`,`>=`, `&&`, `||`)
2426824315
to determine if a signal should be generated
@@ -24724,6 +24771,15 @@ components:
2472424771
items:
2472524772
$ref: '#/components/schemas/SecurityMonitoringFilter'
2472624773
type: array
24774+
groupSignalsBy:
24775+
description: Additional grouping to perform on top of the existing groups
24776+
in the query section. Must be a subset of the existing groups.
24777+
example:
24778+
- service
24779+
items:
24780+
description: Field to group by.
24781+
type: string
24782+
type: array
2472724783
hasExtendedTitle:
2472824784
description: Whether the notifications include the triggering group-by values
2472924785
in their title.
@@ -25429,6 +25485,15 @@ components:
2542925485
items:
2543025486
$ref: '#/components/schemas/SecurityMonitoringFilter'
2543125487
type: array
25488+
groupSignalsBy:
25489+
description: Additional grouping to perform on top of the existing groups
25490+
in the query section. Must be a subset of the existing groups.
25491+
example:
25492+
- service
25493+
items:
25494+
description: Field to group by.
25495+
type: string
25496+
type: array
2543225497
hasExtendedTitle:
2543325498
description: Whether the notifications include the triggering group-by values
2543425499
in their title.
@@ -25501,6 +25566,15 @@ components:
2550125566
items:
2550225567
$ref: '#/components/schemas/SecurityMonitoringFilter'
2550325568
type: array
25569+
groupSignalsBy:
25570+
description: Additional grouping to perform on top of the existing groups
25571+
in the query section. Must be a subset of the existing groups.
25572+
example:
25573+
- service
25574+
items:
25575+
description: Field to group by.
25576+
type: string
25577+
type: array
2550425578
hasExtendedTitle:
2550525579
description: Whether the notifications include the triggering group-by values
2550625580
in their title.
@@ -25642,6 +25716,15 @@ components:
2564225716
items:
2564325717
$ref: '#/components/schemas/SecurityMonitoringFilter'
2564425718
type: array
25719+
groupSignalsBy:
25720+
description: Additional grouping to perform on top of the existing groups
25721+
in the query section. Must be a subset of the existing groups.
25722+
example:
25723+
- service
25724+
items:
25725+
description: Field to group by.
25726+
type: string
25727+
type: array
2564525728
hasExtendedTitle:
2564625729
description: Whether the notifications include the triggering group-by values
2564725730
in their title.
@@ -25719,6 +25802,15 @@ components:
2571925802
items:
2572025803
$ref: '#/components/schemas/SecurityMonitoringFilter'
2572125804
type: array
25805+
groupSignalsBy:
25806+
description: Additional grouping to perform on top of the existing groups
25807+
in the query section. Must be a subset of the existing groups.
25808+
example:
25809+
- service
25810+
items:
25811+
description: Field to group by.
25812+
type: string
25813+
type: array
2572225814
hasExtendedTitle:
2572325815
description: Whether the notifications include the triggering group-by values
2572425816
in their title.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Create a detection rule with type 'application_security 'returns "OK" response
2+
use datadog_api_client::datadog;
3+
use datadog_api_client::datadogV2::api_security_monitoring::SecurityMonitoringAPI;
4+
use datadog_api_client::datadogV2::model::SecurityMonitoringRuleCaseAction;
5+
use datadog_api_client::datadogV2::model::SecurityMonitoringRuleCaseActionOptions;
6+
use datadog_api_client::datadogV2::model::SecurityMonitoringRuleCaseActionType;
7+
use datadog_api_client::datadogV2::model::SecurityMonitoringRuleCaseCreate;
8+
use datadog_api_client::datadogV2::model::SecurityMonitoringRuleCreatePayload;
9+
use datadog_api_client::datadogV2::model::SecurityMonitoringRuleDetectionMethod;
10+
use datadog_api_client::datadogV2::model::SecurityMonitoringRuleEvaluationWindow;
11+
use datadog_api_client::datadogV2::model::SecurityMonitoringRuleKeepAlive;
12+
use datadog_api_client::datadogV2::model::SecurityMonitoringRuleMaxSignalDuration;
13+
use datadog_api_client::datadogV2::model::SecurityMonitoringRuleOptions;
14+
use datadog_api_client::datadogV2::model::SecurityMonitoringRuleQueryAggregation;
15+
use datadog_api_client::datadogV2::model::SecurityMonitoringRuleSeverity;
16+
use datadog_api_client::datadogV2::model::SecurityMonitoringRuleTypeCreate;
17+
use datadog_api_client::datadogV2::model::SecurityMonitoringStandardRuleCreatePayload;
18+
use datadog_api_client::datadogV2::model::SecurityMonitoringStandardRuleQuery;
19+
20+
#[tokio::main]
21+
async fn main() {
22+
let body =
23+
SecurityMonitoringRuleCreatePayload::SecurityMonitoringStandardRuleCreatePayload(Box::new(
24+
SecurityMonitoringStandardRuleCreatePayload::new(
25+
vec![
26+
SecurityMonitoringRuleCaseCreate::new(SecurityMonitoringRuleSeverity::INFO)
27+
.actions(vec![SecurityMonitoringRuleCaseAction::new()
28+
.options(SecurityMonitoringRuleCaseActionOptions::new().duration(900))
29+
.type_(SecurityMonitoringRuleCaseActionType::BLOCK_IP)])
30+
.condition("a > 100000".to_string())
31+
.name("".to_string())
32+
.notifications(vec![]),
33+
],
34+
true,
35+
"Test rule".to_string(),
36+
"Example-Security-Monitoring_appsec_rule".to_string(),
37+
SecurityMonitoringRuleOptions::new()
38+
.detection_method(SecurityMonitoringRuleDetectionMethod::THRESHOLD)
39+
.evaluation_window(SecurityMonitoringRuleEvaluationWindow::FIFTEEN_MINUTES)
40+
.keep_alive(SecurityMonitoringRuleKeepAlive::ONE_HOUR)
41+
.max_signal_duration(SecurityMonitoringRuleMaxSignalDuration::ONE_DAY),
42+
vec![SecurityMonitoringStandardRuleQuery::new()
43+
.aggregation(SecurityMonitoringRuleQueryAggregation::COUNT)
44+
.distinct_fields(vec![])
45+
.group_by_fields(vec!["service".to_string(), "@http.client_ip".to_string()])
46+
.query(
47+
"@appsec.security_activity:business_logic.users.login.failure".to_string(),
48+
)],
49+
)
50+
.filters(vec![])
51+
.group_signals_by(vec!["service".to_string()])
52+
.tags(vec![])
53+
.type_(SecurityMonitoringRuleTypeCreate::APPLICATION_SECURITY),
54+
));
55+
let configuration = datadog::Configuration::new();
56+
let api = SecurityMonitoringAPI::with_config(configuration);
57+
let resp = api.create_security_monitoring_rule(body).await;
58+
if let Ok(value) = resp {
59+
println!("{:#?}", value);
60+
} else {
61+
println!("{:#?}", resp.unwrap_err());
62+
}
63+
}

src/datadogV2/model/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -3034,6 +3034,12 @@ pub mod model_security_monitoring_standard_rule_response;
30343034
pub use self::model_security_monitoring_standard_rule_response::SecurityMonitoringStandardRuleResponse;
30353035
pub mod model_security_monitoring_rule_case;
30363036
pub use self::model_security_monitoring_rule_case::SecurityMonitoringRuleCase;
3037+
pub mod model_security_monitoring_rule_case_action;
3038+
pub use self::model_security_monitoring_rule_case_action::SecurityMonitoringRuleCaseAction;
3039+
pub mod model_security_monitoring_rule_case_action_options;
3040+
pub use self::model_security_monitoring_rule_case_action_options::SecurityMonitoringRuleCaseActionOptions;
3041+
pub mod model_security_monitoring_rule_case_action_type;
3042+
pub use self::model_security_monitoring_rule_case_action_type::SecurityMonitoringRuleCaseActionType;
30373043
pub mod model_security_monitoring_rule_severity;
30383044
pub use self::model_security_monitoring_rule_severity::SecurityMonitoringRuleSeverity;
30393045
pub mod model_cloud_configuration_rule_compliance_signal_options;

src/datadogV2/model/model_job_definition.rs

+18
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ pub struct JobDefinition {
2020
/// Starting time of data analyzed by the job.
2121
#[serde(rename = "from")]
2222
pub from: i64,
23+
/// Additional grouping to perform on top of the existing groups in the query section. Must be a subset of the existing groups.
24+
#[serde(rename = "groupSignalsBy")]
25+
pub group_signals_by: Option<Vec<String>>,
2326
/// Index used to load the data.
2427
#[serde(rename = "index")]
2528
pub index: String,
@@ -72,6 +75,7 @@ impl JobDefinition {
7275
calculated_fields: None,
7376
cases,
7477
from,
78+
group_signals_by: None,
7579
index,
7680
message,
7781
name,
@@ -95,6 +99,11 @@ impl JobDefinition {
9599
self
96100
}
97101

102+
pub fn group_signals_by(mut self, value: Vec<String>) -> Self {
103+
self.group_signals_by = Some(value);
104+
self
105+
}
106+
98107
pub fn options(mut self, value: crate::datadogV2::model::HistoricalJobOptions) -> Self {
99108
self.options = Some(value);
100109
self
@@ -158,6 +167,7 @@ impl<'de> Deserialize<'de> for JobDefinition {
158167
Vec<crate::datadogV2::model::SecurityMonitoringRuleCaseCreate>,
159168
> = None;
160169
let mut from: Option<i64> = None;
170+
let mut group_signals_by: Option<Vec<String>> = None;
161171
let mut index: Option<String> = None;
162172
let mut message: Option<String> = None;
163173
let mut name: Option<String> = None;
@@ -193,6 +203,13 @@ impl<'de> Deserialize<'de> for JobDefinition {
193203
"from" => {
194204
from = Some(serde_json::from_value(v).map_err(M::Error::custom)?);
195205
}
206+
"groupSignalsBy" => {
207+
if v.is_null() {
208+
continue;
209+
}
210+
group_signals_by =
211+
Some(serde_json::from_value(v).map_err(M::Error::custom)?);
212+
}
196213
"index" => {
197214
index = Some(serde_json::from_value(v).map_err(M::Error::custom)?);
198215
}
@@ -259,6 +276,7 @@ impl<'de> Deserialize<'de> for JobDefinition {
259276
calculated_fields,
260277
cases,
261278
from,
279+
group_signals_by,
262280
index,
263281
message,
264282
name,

src/datadogV2/model/model_security_monitoring_rule_case.rs

+22
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ use std::fmt::{self, Formatter};
1111
#[skip_serializing_none]
1212
#[derive(Clone, Debug, PartialEq, Serialize)]
1313
pub struct SecurityMonitoringRuleCase {
14+
/// Action to perform for each rule case.
15+
#[serde(rename = "actions")]
16+
pub actions: Option<Vec<crate::datadogV2::model::SecurityMonitoringRuleCaseAction>>,
1417
/// A rule case contains logical operations (`>`,`>=`, `&&`, `||`) to determine if a signal should be generated
1518
/// based on the event counts in the previously defined queries.
1619
#[serde(rename = "condition")]
@@ -34,6 +37,7 @@ pub struct SecurityMonitoringRuleCase {
3437
impl SecurityMonitoringRuleCase {
3538
pub fn new() -> SecurityMonitoringRuleCase {
3639
SecurityMonitoringRuleCase {
40+
actions: None,
3741
condition: None,
3842
name: None,
3943
notifications: None,
@@ -43,6 +47,14 @@ impl SecurityMonitoringRuleCase {
4347
}
4448
}
4549

50+
pub fn actions(
51+
mut self,
52+
value: Vec<crate::datadogV2::model::SecurityMonitoringRuleCaseAction>,
53+
) -> Self {
54+
self.actions = Some(value);
55+
self
56+
}
57+
4658
pub fn condition(mut self, value: String) -> Self {
4759
self.condition = Some(value);
4860
self
@@ -98,6 +110,9 @@ impl<'de> Deserialize<'de> for SecurityMonitoringRuleCase {
98110
where
99111
M: MapAccess<'a>,
100112
{
113+
let mut actions: Option<
114+
Vec<crate::datadogV2::model::SecurityMonitoringRuleCaseAction>,
115+
> = None;
101116
let mut condition: Option<String> = None;
102117
let mut name: Option<String> = None;
103118
let mut notifications: Option<Vec<String>> = None;
@@ -111,6 +126,12 @@ impl<'de> Deserialize<'de> for SecurityMonitoringRuleCase {
111126

112127
while let Some((k, v)) = map.next_entry::<String, serde_json::Value>()? {
113128
match k.as_str() {
129+
"actions" => {
130+
if v.is_null() {
131+
continue;
132+
}
133+
actions = Some(serde_json::from_value(v).map_err(M::Error::custom)?);
134+
}
114135
"condition" => {
115136
if v.is_null() {
116137
continue;
@@ -153,6 +174,7 @@ impl<'de> Deserialize<'de> for SecurityMonitoringRuleCase {
153174
}
154175

155176
let content = SecurityMonitoringRuleCase {
177+
actions,
156178
condition,
157179
name,
158180
notifications,

0 commit comments

Comments
 (0)