Skip to content

Commit

Permalink
Add validation endpoint for Security Monitoring Rules (#2251)
Browse files Browse the repository at this point in the history
Co-authored-by: ci.datadog-api-spec <[email protected]>
  • Loading branch information
api-clients-generation-pipeline[bot] and ci.datadog-api-spec authored Mar 28, 2024
1 parent 42625b8 commit 32eb45b
Show file tree
Hide file tree
Showing 10 changed files with 316 additions and 4 deletions.
8 changes: 4 additions & 4 deletions .apigentools-info
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
"spec_versions": {
"v1": {
"apigentools_version": "1.6.6",
"regenerated": "2024-03-26 15:17:41.018538",
"spec_repo_commit": "46383d02"
"regenerated": "2024-03-27 22:12:45.580153",
"spec_repo_commit": "85625198"
},
"v2": {
"apigentools_version": "1.6.6",
"regenerated": "2024-03-26 15:17:41.036052",
"spec_repo_commit": "46383d02"
"regenerated": "2024-03-27 22:12:45.599497",
"spec_repo_commit": "85625198"
}
}
}
28 changes: 28 additions & 0 deletions .generator/schemas/v2/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32287,6 +32287,34 @@ paths:
tags:
- Security Monitoring
x-codegen-request-body-name: body
/api/v2/security_monitoring/rules/validation:
post:
description: Validate a detection rule.
operationId: ValidateSecurityMonitoringRule
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SecurityMonitoringRuleCreatePayload'
required: true
responses:
'204':
description: OK
'400':
$ref: '#/components/responses/BadRequestResponse'
'403':
$ref: '#/components/responses/NotAuthorizedResponse'
'429':
$ref: '#/components/responses/TooManyRequestsResponse'
security:
- apiKeyAuth: []
appKeyAuth: []
- AuthZ:
- security_monitoring_rules_write
summary: Validate a detection rule
tags:
- Security Monitoring
x-codegen-request-body-name: body
/api/v2/security_monitoring/rules/{rule_id}:
delete:
description: Delete an existing rule. Default rules cannot be deleted.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Validate a detection rule returns "OK" response

import com.datadog.api.client.ApiClient;
import com.datadog.api.client.ApiException;
import com.datadog.api.client.v2.api.SecurityMonitoringApi;
import com.datadog.api.client.v2.model.SecurityMonitoringRuleCaseCreate;
import com.datadog.api.client.v2.model.SecurityMonitoringRuleCreatePayload;
import com.datadog.api.client.v2.model.SecurityMonitoringRuleDetectionMethod;
import com.datadog.api.client.v2.model.SecurityMonitoringRuleEvaluationWindow;
import com.datadog.api.client.v2.model.SecurityMonitoringRuleKeepAlive;
import com.datadog.api.client.v2.model.SecurityMonitoringRuleMaxSignalDuration;
import com.datadog.api.client.v2.model.SecurityMonitoringRuleOptions;
import com.datadog.api.client.v2.model.SecurityMonitoringRuleQueryAggregation;
import com.datadog.api.client.v2.model.SecurityMonitoringRuleSeverity;
import com.datadog.api.client.v2.model.SecurityMonitoringRuleTypeCreate;
import com.datadog.api.client.v2.model.SecurityMonitoringStandardRuleCreatePayload;
import com.datadog.api.client.v2.model.SecurityMonitoringStandardRuleQuery;
import java.util.Arrays;
import java.util.Collections;

public class Example {
public static void main(String[] args) {
ApiClient defaultClient = ApiClient.getDefaultApiClient();
SecurityMonitoringApi apiInstance = new SecurityMonitoringApi(defaultClient);

SecurityMonitoringRuleCreatePayload body =
new SecurityMonitoringRuleCreatePayload(
new SecurityMonitoringStandardRuleCreatePayload()
.cases(
Collections.singletonList(
new SecurityMonitoringRuleCaseCreate()
.name("")
.status(SecurityMonitoringRuleSeverity.INFO)
.condition("a > 0")))
.hasExtendedTitle(true)
.isEnabled(true)
.message("My security monitoring rule")
.name("My security monitoring rule")
.options(
new SecurityMonitoringRuleOptions()
.evaluationWindow(SecurityMonitoringRuleEvaluationWindow.THIRTY_MINUTES)
.keepAlive(SecurityMonitoringRuleKeepAlive.THIRTY_MINUTES)
.maxSignalDuration(SecurityMonitoringRuleMaxSignalDuration.THIRTY_MINUTES)
.detectionMethod(SecurityMonitoringRuleDetectionMethod.THRESHOLD))
.queries(
Collections.singletonList(
new SecurityMonitoringStandardRuleQuery()
.query("source:source_here")
.groupByFields(Collections.singletonList("@userIdentity.assumed_role"))
.aggregation(SecurityMonitoringRuleQueryAggregation.COUNT)
.name("")))
.tags(Arrays.asList("env:prod", "team:security"))
.type(SecurityMonitoringRuleTypeCreate.LOG_DETECTION));

try {
apiInstance.validateSecurityMonitoringRule(body);
} catch (ApiException e) {
System.err.println(
"Exception when calling SecurityMonitoringApi#validateSecurityMonitoringRule");
System.err.println("Status code: " + e.getCode());
System.err.println("Reason: " + e.getResponseBody());
System.err.println("Response headers: " + e.getResponseHeaders());
e.printStackTrace();
}
}
}
133 changes: 133 additions & 0 deletions src/main/java/com/datadog/api/client/v2/api/SecurityMonitoringApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -4344,4 +4344,137 @@ public SecurityMonitoringSuppressionResponse updateSecurityMonitoringSuppression
false,
new GenericType<SecurityMonitoringSuppressionResponse>() {});
}

/**
* Validate a detection rule.
*
* <p>See {@link #validateSecurityMonitoringRuleWithHttpInfo}.
*
* @param body (required)
* @throws ApiException if fails to make API call
*/
public void validateSecurityMonitoringRule(SecurityMonitoringRuleCreatePayload body)
throws ApiException {
validateSecurityMonitoringRuleWithHttpInfo(body);
}

/**
* Validate a detection rule.
*
* <p>See {@link #validateSecurityMonitoringRuleWithHttpInfoAsync}.
*
* @param body (required)
* @return CompletableFuture
*/
public CompletableFuture<Void> validateSecurityMonitoringRuleAsync(
SecurityMonitoringRuleCreatePayload body) {
return validateSecurityMonitoringRuleWithHttpInfoAsync(body)
.thenApply(
response -> {
return response.getData();
});
}

/**
* Validate a detection rule.
*
* @param body (required)
* @return ApiResponse&lt;Void&gt;
* @throws ApiException if fails to make API call
* @http.response.details
* <table border="1">
* <caption>Response details</caption>
* <tr><td> Status Code </td><td> Description </td><td> Response Headers </td></tr>
* <tr><td> 204 </td><td> OK </td><td> - </td></tr>
* <tr><td> 400 </td><td> Bad Request </td><td> - </td></tr>
* <tr><td> 403 </td><td> Not Authorized </td><td> - </td></tr>
* <tr><td> 429 </td><td> Too many requests </td><td> - </td></tr>
* </table>
*/
public ApiResponse<Void> validateSecurityMonitoringRuleWithHttpInfo(
SecurityMonitoringRuleCreatePayload body) throws ApiException {
Object localVarPostBody = body;

// verify the required parameter 'body' is set
if (body == null) {
throw new ApiException(
400, "Missing the required parameter 'body' when calling validateSecurityMonitoringRule");
}
// create path and map variables
String localVarPath = "/api/v2/security_monitoring/rules/validation";

Map<String, String> localVarHeaderParams = new HashMap<String, String>();

Invocation.Builder builder =
apiClient.createBuilder(
"v2.SecurityMonitoringApi.validateSecurityMonitoringRule",
localVarPath,
new ArrayList<Pair>(),
localVarHeaderParams,
new HashMap<String, String>(),
new String[] {"*/*"},
new String[] {"AuthZ", "apiKeyAuth", "appKeyAuth"});
return apiClient.invokeAPI(
"POST",
builder,
localVarHeaderParams,
new String[] {"application/json"},
localVarPostBody,
new HashMap<String, Object>(),
false,
null);
}

/**
* Validate a detection rule.
*
* <p>See {@link #validateSecurityMonitoringRuleWithHttpInfo}.
*
* @param body (required)
* @return CompletableFuture&lt;ApiResponse&lt;Void&gt;&gt;
*/
public CompletableFuture<ApiResponse<Void>> validateSecurityMonitoringRuleWithHttpInfoAsync(
SecurityMonitoringRuleCreatePayload body) {
Object localVarPostBody = body;

// verify the required parameter 'body' is set
if (body == null) {
CompletableFuture<ApiResponse<Void>> result = new CompletableFuture<>();
result.completeExceptionally(
new ApiException(
400,
"Missing the required parameter 'body' when calling validateSecurityMonitoringRule"));
return result;
}
// create path and map variables
String localVarPath = "/api/v2/security_monitoring/rules/validation";

Map<String, String> localVarHeaderParams = new HashMap<String, String>();

Invocation.Builder builder;
try {
builder =
apiClient.createBuilder(
"v2.SecurityMonitoringApi.validateSecurityMonitoringRule",
localVarPath,
new ArrayList<Pair>(),
localVarHeaderParams,
new HashMap<String, String>(),
new String[] {"*/*"},
new String[] {"AuthZ", "apiKeyAuth", "appKeyAuth"});
} catch (ApiException ex) {
CompletableFuture<ApiResponse<Void>> result = new CompletableFuture<>();
result.completeExceptionally(ex);
return result;
}
return apiClient.invokeAPIAsync(
"POST",
builder,
localVarHeaderParams,
new String[] {"application/json"},
localVarPostBody,
new HashMap<String, Object>(),
false,
null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2024-03-27T16:23:09.814Z
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[
{
"httpRequest": {
"body": {
"type": "JSON",
"json": "{\"cases\":[{\"condition\":\"a > 0\",\"name\":\"\",\"notifications\":[],\"status\":\"info\"}],\"hasExtendedTitle\":true,\"isEnabled\":true,\"message\":\"My security monitoring rule\",\"name\":\"My security monitoring rule\",\"options\":{\"detectionMethod\":\"threshold\",\"evaluationWindow\":1800,\"keepAlive\":999999,\"maxSignalDuration\":1800},\"queries\":[{\"aggregation\":\"count\",\"distinctFields\":[],\"groupByFields\":[\"@userIdentity.assumed_role\"],\"name\":\"\",\"query\":\"source:source_here\"}],\"tags\":[\"env:prod\",\"team:security\"],\"type\":\"log_detection\"}"
},
"headers": {},
"method": "POST",
"path": "/api/v2/security_monitoring/rules/validation",
"keepAlive": false,
"secure": true
},
"httpResponse": {
"body": "{\"error\":{\"code\":\"InvalidArgument\",\"message\":\"Invalid rule configuration\",\"details\":[{\"code\":\"InvalidArgument\",\"message\":\"Max signal duration must be greater than or equal to keep alive\",\"target\":\"maxSignalDuration\"},{\"code\":\"InvalidArgument\",\"message\":\"Keep alive is not in allowed durations: 0, 1, 5, 10, 15, 30, 60, 120, 180, 360 (in minutes)\",\"target\":\"keepAlive\"}]}}\n",
"headers": {
"Content-Type": [
"application/json"
]
},
"statusCode": 400,
"reasonPhrase": "Bad Request"
},
"times": {
"remainingTimes": 1
},
"timeToLive": {
"unlimited": true
},
"id": "195f214f-cab0-861b-1336-ce2aa07b9cf5"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2024-03-27T16:23:10.157Z
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[
{
"httpRequest": {
"body": {
"type": "JSON",
"json": "{\"cases\":[{\"condition\":\"a > 0\",\"name\":\"\",\"notifications\":[],\"status\":\"info\"}],\"hasExtendedTitle\":true,\"isEnabled\":true,\"message\":\"My security monitoring rule\",\"name\":\"My security monitoring rule\",\"options\":{\"detectionMethod\":\"threshold\",\"evaluationWindow\":1800,\"keepAlive\":1800,\"maxSignalDuration\":1800},\"queries\":[{\"aggregation\":\"count\",\"distinctFields\":[],\"groupByFields\":[\"@userIdentity.assumed_role\"],\"name\":\"\",\"query\":\"source:source_here\"}],\"tags\":[\"env:prod\",\"team:security\"],\"type\":\"log_detection\"}"
},
"headers": {},
"method": "POST",
"path": "/api/v2/security_monitoring/rules/validation",
"keepAlive": false,
"secure": true
},
"httpResponse": {
"headers": {
"Content-Type": [
"text/html; charset=utf-8"
]
},
"statusCode": 204,
"reasonPhrase": "No Content"
},
"times": {
"remainingTimes": 1
},
"timeToLive": {
"unlimited": true
},
"id": "eff24aa1-fc7c-d68e-5815-6e52bbac0e73"
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -606,3 +606,17 @@ Feature: Security Monitoring
Then the response status is 200 OK
And the response "name" is equal to "{{ unique }}-Updated"
And the response "id" has the same value as "security_rule.id"

@skip-go @skip-java @skip-python @skip-ruby @skip-rust @skip-typescript @skip-validation @team:DataDog/k9-cloud-security-platform
Scenario: Validate a detection rule returns "Bad Request" response
Given new "ValidateSecurityMonitoringRule" request
And body with value {"cases":[{"name":"","status":"info","notifications":[],"condition":"a > 0"}],"hasExtendedTitle":true,"isEnabled":true,"message":"My security monitoring rule","name":"My security monitoring rule","options":{"evaluationWindow":1800,"keepAlive":999999,"maxSignalDuration":1800,"detectionMethod":"threshold"},"queries":[{"query":"source:source_here","groupByFields":["@userIdentity.assumed_role"],"distinctFields":[],"aggregation":"count","name":""}],"tags":["env:prod","team:security"],"type":"log_detection"}
When the request is sent
Then the response status is 400 Bad Request

@team:DataDog/k9-cloud-security-platform
Scenario: Validate a detection rule returns "OK" response
Given new "ValidateSecurityMonitoringRule" request
And body with value {"cases":[{"name":"","status":"info","notifications":[],"condition":"a > 0"}],"hasExtendedTitle":true,"isEnabled":true,"message":"My security monitoring rule","name":"My security monitoring rule","options":{"evaluationWindow":1800,"keepAlive":1800,"maxSignalDuration":1800,"detectionMethod":"threshold"},"queries":[{"query":"source:source_here","groupByFields":["@userIdentity.assumed_role"],"distinctFields":[],"aggregation":"count","name":""}],"tags":["env:prod","team:security"],"type":"log_detection"}
When the request is sent
Then the response status is 204 OK
6 changes: 6 additions & 0 deletions src/test/resources/com/datadog/api/client/v2/api/undo.json
Original file line number Diff line number Diff line change
Expand Up @@ -1751,6 +1751,12 @@
"type": "unsafe"
}
},
"ValidateSecurityMonitoringRule": {
"tag": "Security Monitoring",
"undo": {
"type": "idempotent"
}
},
"DeleteSecurityMonitoringRule": {
"tag": "Security Monitoring",
"undo": {
Expand Down

0 comments on commit 32eb45b

Please sign in to comment.