diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 5235bcb17c..cb3f6062e0 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.py b/examples/v2/security-monitoring/ValidateSecurityMonitoringSuppression.py new file mode 100644 index 0000000000..f742cf9048 --- /dev/null +++ b/examples/v2/security-monitoring/ValidateSecurityMonitoringSuppression.py @@ -0,0 +1,34 @@ +""" +Validate a suppression rule returns "OK" response +""" + +from datadog_api_client import ApiClient, Configuration +from datadog_api_client.v2.api.security_monitoring_api import SecurityMonitoringApi +from datadog_api_client.v2.model.security_monitoring_suppression_type import SecurityMonitoringSuppressionType +from datadog_api_client.v2.model.security_monitoring_suppression_update_attributes import ( + SecurityMonitoringSuppressionUpdateAttributes, +) +from datadog_api_client.v2.model.security_monitoring_suppression_update_data import ( + SecurityMonitoringSuppressionUpdateData, +) +from datadog_api_client.v2.model.security_monitoring_suppression_update_request import ( + SecurityMonitoringSuppressionUpdateRequest, +) + +body = SecurityMonitoringSuppressionUpdateRequest( + data=SecurityMonitoringSuppressionUpdateData( + attributes=SecurityMonitoringSuppressionUpdateAttributes( + 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=SecurityMonitoringSuppressionType.SUPPRESSIONS, + ), +) + +configuration = Configuration() +with ApiClient(configuration) as api_client: + api_instance = SecurityMonitoringApi(api_client) + api_instance.validate_security_monitoring_suppression(body=body) diff --git a/src/datadog_api_client/v2/api/security_monitoring_api.py b/src/datadog_api_client/v2/api/security_monitoring_api.py index 40115539f9..3a7e124064 100644 --- a/src/datadog_api_client/v2/api/security_monitoring_api.py +++ b/src/datadog_api_client/v2/api/security_monitoring_api.py @@ -1922,6 +1922,26 @@ def __init__(self, api_client=None): api_client=api_client, ) + self._validate_security_monitoring_suppression_endpoint = _Endpoint( + settings={ + "response_type": None, + "auth": ["apiKeyAuth", "appKeyAuth", "AuthZ"], + "endpoint_path": "/api/v2/security_monitoring/configuration/suppressions/validation", + "operation_id": "validate_security_monitoring_suppression", + "http_method": "POST", + "version": "v2", + }, + params_map={ + "body": { + "required": True, + "openapi_types": (SecurityMonitoringSuppressionUpdateRequest,), + "location": "body", + }, + }, + headers_map={"accept": ["*/*"], "content_type": ["application/json"]}, + api_client=api_client, + ) + def cancel_historical_job( self, job_id: str, @@ -3923,3 +3943,19 @@ def validate_security_monitoring_rule( kwargs["body"] = body return self._validate_security_monitoring_rule_endpoint.call_with_http_info(**kwargs) + + def validate_security_monitoring_suppression( + self, + body: SecurityMonitoringSuppressionUpdateRequest, + ) -> None: + """Validate a suppression rule. + + Validate a suppression rule. + + :type body: SecurityMonitoringSuppressionUpdateRequest + :rtype: None + """ + kwargs: Dict[str, Any] = {} + kwargs["body"] = body + + return self._validate_security_monitoring_suppression_endpoint.call_with_http_info(**kwargs) diff --git a/tests/v2/cassettes/test_scenarios/test_validate_a_suppression_rule_returns_bad_request_response.frozen b/tests/v2/cassettes/test_scenarios/test_validate_a_suppression_rule_returns_bad_request_response.frozen new file mode 100644 index 0000000000..ac1839d87f --- /dev/null +++ b/tests/v2/cassettes/test_scenarios/test_validate_a_suppression_rule_returns_bad_request_response.frozen @@ -0,0 +1 @@ +2025-09-01T21:36:42.334Z \ No newline at end of file diff --git a/tests/v2/cassettes/test_scenarios/test_validate_a_suppression_rule_returns_bad_request_response.yaml b/tests/v2/cassettes/test_scenarios/test_validate_a_suppression_rule_returns_bad_request_response.yaml new file mode 100644 index 0000000000..fe950b172e --- /dev/null +++ b/tests/v2/cassettes/test_scenarios/test_validate_a_suppression_rule_returns_bad_request_response.yaml @@ -0,0 +1,22 @@ +interactions: +- request: + body: '{"data":{"attributes":{"data_exclusion_query":"not enough attributes"},"type":"suppressions"}}' + headers: + accept: + - '*/*' + content-type: + - application/json + method: POST + uri: https://api.datadoghq.com/api/v2/security_monitoring/configuration/suppressions/validation + response: + body: + string: '{"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 + status: + code: 400 + message: Bad Request +version: 1 diff --git a/tests/v2/cassettes/test_scenarios/test_validate_a_suppression_rule_returns_ok_response.frozen b/tests/v2/cassettes/test_scenarios/test_validate_a_suppression_rule_returns_ok_response.frozen new file mode 100644 index 0000000000..34761a9412 --- /dev/null +++ b/tests/v2/cassettes/test_scenarios/test_validate_a_suppression_rule_returns_ok_response.frozen @@ -0,0 +1 @@ +2025-09-01T21:36:20.593Z \ No newline at end of file diff --git a/tests/v2/cassettes/test_scenarios/test_validate_a_suppression_rule_returns_ok_response.yaml b/tests/v2/cassettes/test_scenarios/test_validate_a_suppression_rule_returns_ok_response.yaml new file mode 100644 index 0000000000..d25ac7942e --- /dev/null +++ b/tests/v2/cassettes/test_scenarios/test_validate_a_suppression_rule_returns_ok_response.yaml @@ -0,0 +1,20 @@ +interactions: +- request: + body: '{"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: + accept: + - '*/*' + content-type: + - application/json + method: POST + uri: https://api.datadoghq.com/api/v2/security_monitoring/configuration/suppressions/validation + response: + body: + string: '' + headers: {} + status: + code: 204 + message: No Content +version: 1 diff --git a/tests/v2/features/security_monitoring.feature b/tests/v2/features/security_monitoring.feature index bf07efac5f..89424290ce 100644 --- a/tests/v2/features/security_monitoring.feature +++ b/tests/v2/features/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/tests/v2/features/undo.json b/tests/v2/features/undo.json index 85b612d9d9..3ae6306bca 100644 --- a/tests/v2/features/undo.json +++ b/tests/v2/features/undo.json @@ -3024,6 +3024,12 @@ "type": "safe" } }, + "ValidateSecurityMonitoringSuppression": { + "tag": "Security Monitoring", + "undo": { + "type": "idempotent" + } + }, "DeleteSecurityMonitoringSuppression": { "tag": "Security Monitoring", "undo": {