Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
358 changes: 358 additions & 0 deletions .generator/schemas/v2/openapi.yaml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""
Get a rule proposal returns "OK" response
"""

from os import environ
from datadog_api_client import ApiClient, Configuration
from datadog_api_client.v2.api.security_monitoring_api import SecurityMonitoringApi

# there is a valid "rule_proposal" in the system
RULE_PROPOSAL_DATA_ID = environ["RULE_PROPOSAL_DATA_ID"]

configuration = Configuration()
configuration.access_token = environ["DD_BEARER_TOKEN"]
configuration.unstable_operations["get_security_monitoring_rule_proposal"] = True
with ApiClient(configuration) as api_client:
api_instance = SecurityMonitoringApi(api_client)
response = api_instance.get_security_monitoring_rule_proposal(
proposal_id=RULE_PROPOSAL_DATA_ID,
)

print(response)
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""
Start a rule proposal returns "Accepted" response
"""

from os import environ
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_rule_proposal_input_type import (
SecurityMonitoringRuleProposalInputType,
)
from datadog_api_client.v2.model.security_monitoring_rule_proposal_start_request import (
SecurityMonitoringRuleProposalStartRequest,
)
from datadog_api_client.v2.model.security_monitoring_rule_proposal_start_request_attributes import (
SecurityMonitoringRuleProposalStartRequestAttributes,
)
from datadog_api_client.v2.model.security_monitoring_rule_proposal_start_request_data import (
SecurityMonitoringRuleProposalStartRequestData,
)
from datadog_api_client.v2.model.security_monitoring_rule_proposal_type import SecurityMonitoringRuleProposalType

body = SecurityMonitoringRuleProposalStartRequest(
data=SecurityMonitoringRuleProposalStartRequestData(
type=SecurityMonitoringRuleProposalType.RULE_PROPOSALS,
attributes=SecurityMonitoringRuleProposalStartRequestAttributes(
input_type=SecurityMonitoringRuleProposalInputType.NATURAL_LANGUAGE,
input="Detect repeated failed Okta logins followed by a successful login from the same IP.",
),
),
)

configuration = Configuration()
configuration.access_token = environ["DD_BEARER_TOKEN"]
configuration.unstable_operations["start_security_monitoring_rule_proposal"] = True
with ApiClient(configuration) as api_client:
api_instance = SecurityMonitoringApi(api_client)
response = api_instance.start_security_monitoring_rule_proposal(body=body)

print(response)
2 changes: 2 additions & 0 deletions src/datadog_api_client/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ def __init__(
"v2.get_security_monitoring_histsignal": False,
"v2.get_security_monitoring_histsignals_by_job_id": False,
"v2.get_security_monitoring_integration_config": False,
"v2.get_security_monitoring_rule_proposal": False,
"v2.get_signal_entities": False,
"v2.get_single_entity_context": False,
"v2.get_static_analysis_default_rulesets": False,
Expand Down Expand Up @@ -468,6 +469,7 @@ def __init__(
"v2.run_historical_job": False,
"v2.search_security_monitoring_histsignals": False,
"v2.start_security_monitoring_batch_migration": False,
"v2.start_security_monitoring_rule_proposal": False,
"v2.update_findings_assignee": False,
"v2.update_findings_severity": False,
"v2.update_security_findings_automation_due_date_rule": False,
Expand Down
104 changes: 104 additions & 0 deletions src/datadog_api_client/v2/api/security_monitoring_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,15 @@
from datadog_api_client.v2.model.security_monitoring_rule_convert_bulk_payload import (
SecurityMonitoringRuleConvertBulkPayload,
)
from datadog_api_client.v2.model.security_monitoring_rule_proposal_start_response import (
SecurityMonitoringRuleProposalStartResponse,
)
from datadog_api_client.v2.model.security_monitoring_rule_proposal_start_request import (
SecurityMonitoringRuleProposalStartRequest,
)
from datadog_api_client.v2.model.security_monitoring_rule_proposal_response import (
SecurityMonitoringRuleProposalResponse,
)
from datadog_api_client.v2.model.security_monitoring_rule_test_response import SecurityMonitoringRuleTestResponse
from datadog_api_client.v2.model.security_monitoring_rule_test_request import SecurityMonitoringRuleTestRequest
from datadog_api_client.v2.model.security_monitoring_rule_validate_payload import SecurityMonitoringRuleValidatePayload
Expand Down Expand Up @@ -2825,6 +2834,29 @@ def __init__(self, api_client=None):
api_client=api_client,
)

self._get_security_monitoring_rule_proposal_endpoint = _Endpoint(
settings={
"response_type": (SecurityMonitoringRuleProposalResponse,),
"auth": ["apiKeyAuth", "appKeyAuth", "AuthZ"],
"endpoint_path": "/api/v2/security_monitoring/rules/proposals/{proposal_id}",
"operation_id": "get_security_monitoring_rule_proposal",
"http_method": "GET",
"version": "v2",
},
params_map={
"proposal_id": {
"required": True,
"openapi_types": (UUID,),
"attribute": "proposal_id",
"location": "path",
},
},
headers_map={
"accept": ["application/json"],
},
api_client=api_client,
)

self._get_security_monitoring_signal_endpoint = _Endpoint(
settings={
"response_type": (SecurityMonitoringSignalResponse,),
Expand Down Expand Up @@ -4914,6 +4946,26 @@ def __init__(self, api_client=None):
api_client=api_client,
)

self._start_security_monitoring_rule_proposal_endpoint = _Endpoint(
settings={
"response_type": (SecurityMonitoringRuleProposalStartResponse,),
"auth": ["apiKeyAuth", "appKeyAuth", "AuthZ"],
"endpoint_path": "/api/v2/security_monitoring/rules/proposals",
"operation_id": "start_security_monitoring_rule_proposal",
"http_method": "POST",
"version": "v2",
},
params_map={
"body": {
"required": True,
"openapi_types": (SecurityMonitoringRuleProposalStartRequest,),
"location": "body",
},
},
headers_map={"accept": ["application/json"], "content_type": ["application/json"]},
api_client=api_client,
)

self._test_existing_security_monitoring_rule_endpoint = _Endpoint(
settings={
"response_type": (SecurityMonitoringRuleTestResponse,),
Expand Down Expand Up @@ -6121,6 +6173,7 @@ def create_security_monitoring_batch_migration(
rule. To load more rules, add them with the add resources endpoint before starting the
batch migration. A batch migration can hold up to 1000 resources. The response does not
include the created resources: list the resources of the batch migration to retrieve them.
Alternatively, use the start-a-rule-proposal endpoint to get a single proposed rule.

:type body: SecurityMonitoringBatchMigrationCreateRequest
:rtype: SecurityMonitoringBatchMigrationResponse
Expand Down Expand Up @@ -7602,6 +7655,30 @@ def get_security_monitoring_rule(

return self._get_security_monitoring_rule_endpoint.call_with_http_info(**kwargs)

def get_security_monitoring_rule_proposal(
self,
proposal_id: UUID,
) -> SecurityMonitoringRuleProposalResponse:
"""Get a rule proposal.

Get the status of a rule proposal started with the start-a-rule-proposal endpoint.
While the status is ``pending`` or ``in_progress`` , the proposed rule is still being
generated. Poll this endpoint again later. If the status is ``completed`` , the response's ``rule`` field contains
the proposed Cloud SIEM detection rule. If the status is ``failed`` , the response's ``error`` field contains
the reason a rule could not be generated.

This endpoint does not create or modify any detection rules in Cloud SIEM. To create the
proposed rule, use the create-a-detection-rule endpoint.

:param proposal_id: The ID of the rule proposal, returned by the start a rule proposal endpoint.
:type proposal_id: UUID
:rtype: SecurityMonitoringRuleProposalResponse
"""
kwargs: Dict[str, Any] = {}
kwargs["proposal_id"] = proposal_id

return self._get_security_monitoring_rule_proposal_endpoint.call_with_http_info(**kwargs)

def get_security_monitoring_signal(
self,
signal_id: str,
Expand Down Expand Up @@ -10099,6 +10176,33 @@ def start_security_monitoring_batch_migration(

return self._start_security_monitoring_batch_migration_endpoint.call_with_http_info(**kwargs)

def start_security_monitoring_rule_proposal(
self,
body: SecurityMonitoringRuleProposalStartRequest,
) -> SecurityMonitoringRuleProposalStartResponse:
"""Start a rule proposal.

Start generating a proposed Cloud SIEM detection rule from a natural-language
description, or from an SPL or KQL rule. The proposal is based on your organization's
log sources, log fields, and existing detection rules. When logs from the matching
source are available, the proposed query is tested against your recent logs.

The proposed rule is generated asynchronously. This endpoint returns a proposal ``id``
with the status ``pending``. To get the proposed rule, pass this ``id`` to the get-a-rule-proposal
endpoint and poll the endpoint until the status is ``completed`` or ``failed``. A proposal
usually takes a few minutes, and up to 10 minutes.

This endpoint does not create or modify any detection rules in Cloud SIEM. To translate
many rules at once, use batch migrations instead.

:type body: SecurityMonitoringRuleProposalStartRequest
:rtype: SecurityMonitoringRuleProposalStartResponse
"""
kwargs: Dict[str, Any] = {}
kwargs["body"] = body

return self._start_security_monitoring_rule_proposal_endpoint.call_with_http_info(**kwargs)

def test_existing_security_monitoring_rule(
self,
rule_id: str,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License.
# This product includes software developed at Datadog (https://www.datadoghq.com/).
# Copyright 2019-Present Datadog, Inc.
from __future__ import annotations

from typing import Union

from datadog_api_client.model_utils import (
ModelNormal,
cached_property,
unset,
UnsetType,
)


class SecurityMonitoringRuleProposalError(ModelNormal):
@cached_property
def openapi_types(_):
return {
"kind": (str,),
"message": (str,),
"type": (str,),
}

attribute_map = {
"kind": "kind",
"message": "message",
"type": "type",
}

def __init__(
self_, kind: str, message: Union[str, UnsetType] = unset, type: Union[str, UnsetType] = unset, **kwargs
):
"""
The reason no rule could be generated. Only present when the status is ``failed``.

:param kind: The kind of failure.

* ``translation_error`` : no rule could be generated from the input. Reword the input
or add details, then start a new rule proposal.
* ``internal_error`` : the proposal failed because of an internal error. Start a new
rule proposal to try again.
:type kind: str

:param message: A human-readable explanation of why no rule could be generated, when available.
:type message: str, optional

:param type: The type of failure within its kind, such as ``NoRuleProduced``.
:type type: str, optional
"""
if message is not unset:
kwargs["message"] = message
if type is not unset:
kwargs["type"] = type
super().__init__(kwargs)

self_.kind = kind
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License.
# This product includes software developed at Datadog (https://www.datadoghq.com/).
# Copyright 2019-Present Datadog, Inc.
from __future__ import annotations


from datadog_api_client.model_utils import (
ModelSimple,
cached_property,
)

from typing import ClassVar


class SecurityMonitoringRuleProposalInputType(ModelSimple):
"""
The type of input to generate the proposed rule from: `natural_language` for a
plain-English description of the behavior to detect, `spl` for a Splunk SPL search or
saved search definition, or `kql` for a Microsoft KQL query. SPL inputs must be
self-contained, with search macros expanded.

:param value: Must be one of ["natural_language", "spl", "kql"].
:type value: str
"""

allowed_values = {
"natural_language",
"spl",
"kql",
}
NATURAL_LANGUAGE: ClassVar["SecurityMonitoringRuleProposalInputType"]
SPL: ClassVar["SecurityMonitoringRuleProposalInputType"]
KQL: ClassVar["SecurityMonitoringRuleProposalInputType"]

@cached_property
def openapi_types(_):
return {
"value": (str,),
}


SecurityMonitoringRuleProposalInputType.NATURAL_LANGUAGE = SecurityMonitoringRuleProposalInputType("natural_language")
SecurityMonitoringRuleProposalInputType.SPL = SecurityMonitoringRuleProposalInputType("spl")
SecurityMonitoringRuleProposalInputType.KQL = SecurityMonitoringRuleProposalInputType("kql")
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License.
# This product includes software developed at Datadog (https://www.datadoghq.com/).
# Copyright 2019-Present Datadog, Inc.
from __future__ import annotations

from typing import TYPE_CHECKING

from datadog_api_client.model_utils import (
ModelNormal,
cached_property,
)


if TYPE_CHECKING:
from datadog_api_client.v2.model.security_monitoring_rule_proposal_response_data import (
SecurityMonitoringRuleProposalResponseData,
)


class SecurityMonitoringRuleProposalResponse(ModelNormal):
@cached_property
def openapi_types(_):
from datadog_api_client.v2.model.security_monitoring_rule_proposal_response_data import (
SecurityMonitoringRuleProposalResponseData,
)

return {
"data": (SecurityMonitoringRuleProposalResponseData,),
}

attribute_map = {
"data": "data",
}

def __init__(self_, data: SecurityMonitoringRuleProposalResponseData, **kwargs):
"""
Response containing a rule proposal.

:param data: Data of the rule proposal.
:type data: SecurityMonitoringRuleProposalResponseData
"""
super().__init__(kwargs)

self_.data = data
Loading
Loading