diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 5235bcb17ce..cb3f6062e01 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -64816,6 +64816,38 @@ paths: summary: Get suppressions affecting a specific rule tags: - Security Monitoring + /api/v2/security_monitoring/configuration/suppressions/validation: + post: + description: Validate a suppression rule. + operationId: ValidateSecurityMonitoringSuppression + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/SecurityMonitoringSuppressionUpdateRequest' + 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_suppressions_write + summary: Validate a suppression rule + tags: + - Security Monitoring + x-codegen-request-body-name: body + x-permission: + operator: OR + permissions: + - security_monitoring_suppressions_write /api/v2/security_monitoring/configuration/suppressions/{suppression_id}: delete: description: Delete a specific suppression rule. diff --git a/examples/v2/security-monitoring/ValidateSecurityMonitoringSuppression.java b/examples/v2/security-monitoring/ValidateSecurityMonitoringSuppression.java new file mode 100644 index 00000000000..57905bcf2f9 --- /dev/null +++ b/examples/v2/security-monitoring/ValidateSecurityMonitoringSuppression.java @@ -0,0 +1,42 @@ +// Validate a suppression 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.SecurityMonitoringSuppressionType; +import com.datadog.api.client.v2.model.SecurityMonitoringSuppressionUpdateAttributes; +import com.datadog.api.client.v2.model.SecurityMonitoringSuppressionUpdateData; +import com.datadog.api.client.v2.model.SecurityMonitoringSuppressionUpdateRequest; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = ApiClient.getDefaultApiClient(); + SecurityMonitoringApi apiInstance = new SecurityMonitoringApi(defaultClient); + + SecurityMonitoringSuppressionUpdateRequest body = + new SecurityMonitoringSuppressionUpdateRequest() + .data( + new SecurityMonitoringSuppressionUpdateData() + .attributes( + new SecurityMonitoringSuppressionUpdateAttributes() + .dataExclusionQuery("source:cloudtrail account_id:12345") + .description( + "This rule suppresses low-severity signals in staging" + + " environments.") + .enabled(true) + .name("Custom suppression") + .ruleQuery("type:log_detection source:cloudtrail")) + .type(SecurityMonitoringSuppressionType.SUPPRESSIONS)); + + try { + apiInstance.validateSecurityMonitoringSuppression(body); + } catch (ApiException e) { + System.err.println( + "Exception when calling SecurityMonitoringApi#validateSecurityMonitoringSuppression"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/datadog/api/client/v2/api/SecurityMonitoringApi.java b/src/main/java/com/datadog/api/client/v2/api/SecurityMonitoringApi.java index 2e0f45d3853..14b80d60672 100644 --- a/src/main/java/com/datadog/api/client/v2/api/SecurityMonitoringApi.java +++ b/src/main/java/com/datadog/api/client/v2/api/SecurityMonitoringApi.java @@ -11220,4 +11220,141 @@ public CompletableFuture> validateSecurityMonitoringRuleWithHt false, null); } + + /** + * Validate a suppression rule. + * + *

See {@link #validateSecurityMonitoringSuppressionWithHttpInfo}. + * + * @param body (required) + * @throws ApiException if fails to make API call + */ + public void validateSecurityMonitoringSuppression(SecurityMonitoringSuppressionUpdateRequest body) + throws ApiException { + validateSecurityMonitoringSuppressionWithHttpInfo(body); + } + + /** + * Validate a suppression rule. + * + *

See {@link #validateSecurityMonitoringSuppressionWithHttpInfoAsync}. + * + * @param body (required) + * @return CompletableFuture + */ + public CompletableFuture validateSecurityMonitoringSuppressionAsync( + SecurityMonitoringSuppressionUpdateRequest body) { + return validateSecurityMonitoringSuppressionWithHttpInfoAsync(body) + .thenApply( + response -> { + return response.getData(); + }); + } + + /** + * Validate a suppression rule. + * + * @param body (required) + * @return ApiResponse<Void> + * @throws ApiException if fails to make API call + * @http.response.details + * + * + * + * + * + * + * + *
Response details
Status Code Description Response Headers
204 OK -
400 Bad Request -
403 Not Authorized -
429 Too many requests -
+ */ + public ApiResponse validateSecurityMonitoringSuppressionWithHttpInfo( + SecurityMonitoringSuppressionUpdateRequest 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" + + " validateSecurityMonitoringSuppression"); + } + // create path and map variables + String localVarPath = "/api/v2/security_monitoring/configuration/suppressions/validation"; + + Map localVarHeaderParams = new HashMap(); + + Invocation.Builder builder = + apiClient.createBuilder( + "v2.SecurityMonitoringApi.validateSecurityMonitoringSuppression", + localVarPath, + new ArrayList(), + localVarHeaderParams, + new HashMap(), + new String[] {"*/*"}, + new String[] {"apiKeyAuth", "appKeyAuth", "AuthZ"}); + return apiClient.invokeAPI( + "POST", + builder, + localVarHeaderParams, + new String[] {"application/json"}, + localVarPostBody, + new HashMap(), + false, + null); + } + + /** + * Validate a suppression rule. + * + *

See {@link #validateSecurityMonitoringSuppressionWithHttpInfo}. + * + * @param body (required) + * @return CompletableFuture<ApiResponse<Void>> + */ + public CompletableFuture> + validateSecurityMonitoringSuppressionWithHttpInfoAsync( + SecurityMonitoringSuppressionUpdateRequest body) { + Object localVarPostBody = body; + + // verify the required parameter 'body' is set + if (body == null) { + CompletableFuture> result = new CompletableFuture<>(); + result.completeExceptionally( + new ApiException( + 400, + "Missing the required parameter 'body' when calling" + + " validateSecurityMonitoringSuppression")); + return result; + } + // create path and map variables + String localVarPath = "/api/v2/security_monitoring/configuration/suppressions/validation"; + + Map localVarHeaderParams = new HashMap(); + + Invocation.Builder builder; + try { + builder = + apiClient.createBuilder( + "v2.SecurityMonitoringApi.validateSecurityMonitoringSuppression", + localVarPath, + new ArrayList(), + localVarHeaderParams, + new HashMap(), + new String[] {"*/*"}, + new String[] {"apiKeyAuth", "appKeyAuth", "AuthZ"}); + } catch (ApiException ex) { + CompletableFuture> result = new CompletableFuture<>(); + result.completeExceptionally(ex); + return result; + } + return apiClient.invokeAPIAsync( + "POST", + builder, + localVarHeaderParams, + new String[] {"application/json"}, + localVarPostBody, + new HashMap(), + false, + null); + } } diff --git a/src/test/resources/cassettes/features/v2/Validate_a_suppression_rule_returns_Bad_Request_response.freeze b/src/test/resources/cassettes/features/v2/Validate_a_suppression_rule_returns_Bad_Request_response.freeze new file mode 100644 index 00000000000..ac1839d87fc --- /dev/null +++ b/src/test/resources/cassettes/features/v2/Validate_a_suppression_rule_returns_Bad_Request_response.freeze @@ -0,0 +1 @@ +2025-09-01T21:36:42.334Z \ No newline at end of file diff --git a/src/test/resources/cassettes/features/v2/Validate_a_suppression_rule_returns_Bad_Request_response.json b/src/test/resources/cassettes/features/v2/Validate_a_suppression_rule_returns_Bad_Request_response.json new file mode 100644 index 00000000000..43f2cc65606 --- /dev/null +++ b/src/test/resources/cassettes/features/v2/Validate_a_suppression_rule_returns_Bad_Request_response.json @@ -0,0 +1,32 @@ +[ + { + "httpRequest": { + "body": { + "type": "JSON", + "json": "{\"data\":{\"attributes\":{\"data_exclusion_query\":\"not enough attributes\"},\"type\":\"suppressions\"}}" + }, + "headers": {}, + "method": "POST", + "path": "/api/v2/security_monitoring/configuration/suppressions/validation", + "keepAlive": false, + "secure": true + }, + "httpResponse": { + "body": "{\"errors\":[\"input_validation_error(Field 'data.attributes.rule_query' is invalid: field 'rule_query' is required)\",\"input_validation_error(Field 'data.attributes.name' is invalid: name cannot be empty)\"]}", + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "statusCode": 400, + "reasonPhrase": "Bad Request" + }, + "times": { + "remainingTimes": 1 + }, + "timeToLive": { + "unlimited": true + }, + "id": "703e6a45-408a-1cf4-017d-6f3d7e7b26c9" + } +] \ No newline at end of file diff --git a/src/test/resources/cassettes/features/v2/Validate_a_suppression_rule_returns_OK_response.freeze b/src/test/resources/cassettes/features/v2/Validate_a_suppression_rule_returns_OK_response.freeze new file mode 100644 index 00000000000..34761a94128 --- /dev/null +++ b/src/test/resources/cassettes/features/v2/Validate_a_suppression_rule_returns_OK_response.freeze @@ -0,0 +1 @@ +2025-09-01T21:36:20.593Z \ No newline at end of file diff --git a/src/test/resources/cassettes/features/v2/Validate_a_suppression_rule_returns_OK_response.json b/src/test/resources/cassettes/features/v2/Validate_a_suppression_rule_returns_OK_response.json new file mode 100644 index 00000000000..cdb517eab30 --- /dev/null +++ b/src/test/resources/cassettes/features/v2/Validate_a_suppression_rule_returns_OK_response.json @@ -0,0 +1,27 @@ +[ + { + "httpRequest": { + "body": { + "type": "JSON", + "json": "{\"data\":{\"attributes\":{\"data_exclusion_query\":\"source:cloudtrail account_id:12345\",\"description\":\"This rule suppresses low-severity signals in staging environments.\",\"enabled\":true,\"name\":\"Custom suppression\",\"rule_query\":\"type:log_detection source:cloudtrail\"},\"type\":\"suppressions\"}}" + }, + "headers": {}, + "method": "POST", + "path": "/api/v2/security_monitoring/configuration/suppressions/validation", + "keepAlive": false, + "secure": true + }, + "httpResponse": { + "headers": {}, + "statusCode": 204, + "reasonPhrase": "No Content" + }, + "times": { + "remainingTimes": 1 + }, + "timeToLive": { + "unlimited": true + }, + "id": "7fdeeb56-d69b-7809-c8f4-8bdeffca83e0" + } +] \ No newline at end of file diff --git a/src/test/resources/com/datadog/api/client/v2/api/security_monitoring.feature b/src/test/resources/com/datadog/api/client/v2/api/security_monitoring.feature index bf07efac5ff..89424290ce1 100644 --- a/src/test/resources/com/datadog/api/client/v2/api/security_monitoring.feature +++ b/src/test/resources/com/datadog/api/client/v2/api/security_monitoring.feature @@ -1389,3 +1389,17 @@ Feature: Security Monitoring 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 + + @team:DataDog/k9-cloud-security-platform + Scenario: Validate a suppression rule returns "Bad Request" response + Given new "ValidateSecurityMonitoringSuppression" request + And body with value {"data": {"attributes": {"data_exclusion_query": "not enough attributes"}, "type": "suppressions"}} + When the request is sent + Then the response status is 400 Bad Request + + @team:DataDog/k9-cloud-security-platform + Scenario: Validate a suppression rule returns "OK" response + Given new "ValidateSecurityMonitoringSuppression" request + And body with value {"data": {"attributes": {"data_exclusion_query": "source:cloudtrail account_id:12345", "description": "This rule suppresses low-severity signals in staging environments.", "enabled": true, "name": "Custom suppression", "rule_query": "type:log_detection source:cloudtrail"}, "type": "suppressions"}} + When the request is sent + Then the response status is 204 OK diff --git a/src/test/resources/com/datadog/api/client/v2/api/undo.json b/src/test/resources/com/datadog/api/client/v2/api/undo.json index 85b612d9d9c..3ae6306bca4 100644 --- a/src/test/resources/com/datadog/api/client/v2/api/undo.json +++ b/src/test/resources/com/datadog/api/client/v2/api/undo.json @@ -3024,6 +3024,12 @@ "type": "safe" } }, + "ValidateSecurityMonitoringSuppression": { + "tag": "Security Monitoring", + "undo": { + "type": "idempotent" + } + }, "DeleteSecurityMonitoringSuppression": { "tag": "Security Monitoring", "undo": {