diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 6bc8997cf..05ce562f5 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -5270,6 +5270,79 @@ components: example: _latest type: string type: object + AttachCaseRequest: + description: Request for attaching security findings to a case. + properties: + data: + $ref: '#/components/schemas/AttachCaseRequestData' + type: object + AttachCaseRequestData: + description: Data of the case to attach security findings to. + properties: + id: + description: The unique identifier of the case. + example: c1234567-89ab-cdef-0123-456789abcdef + type: string + relationships: + $ref: '#/components/schemas/AttachCaseRequestDataRelationships' + type: + $ref: '#/components/schemas/CaseDataType' + required: + - type + - id + type: object + AttachCaseRequestDataRelationships: + description: Relationships of the case to attach security findings to. + properties: + findings: + $ref: '#/components/schemas/Findings' + description: Security findings to attach to the case. + required: + - findings + type: object + AttachJiraIssueRequest: + description: Request for attaching security findings to a Jira issue. + properties: + data: + $ref: '#/components/schemas/AttachJiraIssueRequestData' + type: object + AttachJiraIssueRequestData: + description: Data of the Jira issue to attach security findings to. + properties: + attributes: + $ref: '#/components/schemas/AttachJiraIssueRequestDataAttributes' + id: + description: The unique identifier of the Jira issue attachment request. + example: j1234567-89ab-cdef-0123-456789abcdef + type: string + relationships: + $ref: '#/components/schemas/AttachJiraIssueRequestDataRelationships' + type: + $ref: '#/components/schemas/JiraIssuesDataType' + required: + - type + type: object + AttachJiraIssueRequestDataAttributes: + description: Attributes of the Jira issue to attach security findings to. + properties: + jira_issue_url: + description: The URL of the Jira issue to attach security findings to. + example: https://domain.atlassian.net/browse/PROJ-123 + type: string + required: + - jira_issue_url + type: object + AttachJiraIssueRequestDataRelationships: + description: Relationships of the Jira issue to attach security findings to. + properties: + findings: + $ref: '#/components/schemas/Findings' + project: + $ref: '#/components/schemas/CaseManagementProject' + required: + - findings + - project + type: object AuditLogsEvent: description: Object description of an Audit Logs event after it is processed and stored by Datadog. @@ -8942,6 +9015,15 @@ components: required: - data type: object + CaseDataType: + default: cases + description: Cases resource type. + enum: + - cases + example: cases + type: string + x-enum-varnames: + - CASES CaseEmpty: description: Case empty request data properties: @@ -8958,6 +9040,53 @@ components: required: - data type: object + CaseInsightsItems: + description: An insight of the case. + properties: + ref: + description: The reference of the insight. + example: /security/appsec/vm/library/vulnerability/dfa027f7c037b2f77159adc027fecb56?detection=static + type: string + resource_id: + description: The unique identifier of the resource. For example, the unique + identifier of a security finding. + example: ZGVmLTAwcC1pZXJ-aS0wZjhjNjMyZDNmMzRlZTgzNw== + type: string + type: + description: The type of the resource. For example, the type of a security + finding is "SECURITY_FINDING". + example: SECURITY_FINDING + type: string + type: object + CaseManagementProject: + description: Case management project. + properties: + data: + $ref: '#/components/schemas/CaseManagementProjectData' + required: + - data + type: object + CaseManagementProjectData: + properties: + id: + description: The unique identifier of the case management project. + example: aeadc05e-98a8-11ec-ac2c-da7ad0900001 + type: string + type: + $ref: '#/components/schemas/CaseManagementProjectDataType' + required: + - type + - id + type: object + CaseManagementProjectDataType: + default: projects + description: Projects resource type. + enum: + - projects + example: projects + type: string + x-enum-varnames: + - PROJECTS CaseObjectAttributes: additionalProperties: items: @@ -12602,6 +12731,68 @@ components: required: - type type: object + CreateCaseRequestArray: + description: List of requests to create cases for security findings. + properties: + data: + items: + $ref: '#/components/schemas/CreateCaseRequestData' + type: array + required: + - data + type: object + CreateCaseRequestData: + description: Data of the case to create. + properties: + attributes: + $ref: '#/components/schemas/CreateCaseRequestDataAttributes' + id: + description: The unique identifier of the case. + example: c1234567-89ab-cdef-0123-456789abcdef + type: string + relationships: + $ref: '#/components/schemas/CreateCaseRequestDataRelationships' + type: + $ref: '#/components/schemas/CaseDataType' + required: + - type + type: object + CreateCaseRequestDataAttributes: + description: Attributes of the case to create. + properties: + assignee_id: + description: The unique identifier of the user assigned to the case. + example: f315bdaf-9ee7-4808-a9c1-99c15bf0f4d0 + type: string + description: + description: The description of the case. If not provided, the description + will be automatically generated. + example: A description of the case. + type: string + priority: + $ref: '#/components/schemas/CasePriority' + description: The priority of the case. If not provided, the priority will + be automatically set to "NOT_DEFINED". + example: P4 + title: + description: The title of the case. If not provided, the title will be automatically + generated. + example: A title for the case. + type: string + type: object + CreateCaseRequestDataRelationships: + description: Relationships of the case to create. + properties: + findings: + $ref: '#/components/schemas/Findings' + description: Security findings of the case to create. + project: + $ref: '#/components/schemas/CaseManagementProject' + description: Project of the case to create. + required: + - findings + - project + type: object CreateConnectionRequest: example: data: @@ -12873,6 +13064,89 @@ components: required: - data type: object + CreateJiraIssueRequestArray: + description: List of requests to create Jira issues for security findings. + properties: + data: + items: + $ref: '#/components/schemas/CreateJiraIssueRequestData' + type: array + included: + items: + $ref: '#/components/schemas/CreateJiraIssueRequestArrayIncluded' + type: array + required: + - data + type: object + CreateJiraIssueRequestArrayIncluded: + description: 'Attributes and relationships of the case linked to the Jira issue. + Should contain all of the following: case, project, and security findings.' + oneOf: + - $ref: '#/components/schemas/CreateCaseRequestData' + - $ref: '#/components/schemas/CaseManagementProjectData' + - $ref: '#/components/schemas/FindingData' + CreateJiraIssueRequestData: + description: Data of the Jira issue to create. + properties: + attributes: + $ref: '#/components/schemas/CreateJiraIssueRequestDataAttributes' + id: + description: The unique identifier of the Jira issue creation request. + example: j1234567-89ab-cdef-0123-456789abcdef + type: string + relationships: + $ref: '#/components/schemas/CreateJiraIssueRequestDataRelationships' + type: + $ref: '#/components/schemas/JiraIssuesDataType' + required: + - type + type: object + CreateJiraIssueRequestDataAttributes: + description: Attributes of the Jira issue to create. + properties: + fields: + $ref: '#/components/schemas/CreateJiraIssueRequestDataAttributesFields' + type: object + CreateJiraIssueRequestDataAttributesFields: + description: Custom fields of the Jira issue to create. For the list of available + fields, see [Jira documentation](https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issues/#api-rest-api-2-issue-createmeta-projectidorkey-issuetypes-issuetypeid-get). + properties: + fields: + example: + customfield_10001: Value 1 + customfield_10002: + - Value 2 + - Value 3 + type: object + type: object + CreateJiraIssueRequestDataRelationships: + description: Relationships of the Jira issue to create. + properties: + case: + $ref: '#/components/schemas/CreateJiraIssueRequestDataRelationshipsCase' + required: + - case + type: object + CreateJiraIssueRequestDataRelationshipsCase: + description: Case linked to the Jira issue. + properties: + data: + $ref: '#/components/schemas/CreateJiraIssueRequestDataRelationshipsCaseData' + required: + - data + type: object + CreateJiraIssueRequestDataRelationshipsCaseData: + description: Case linked to the Jira issue. + properties: + id: + example: c1234567-89ab-cdef-0123-456789abcdef + type: string + type: + $ref: '#/components/schemas/CaseDataType' + required: + - type + - id + type: object CreateNotificationRuleParameters: description: Body of the notification rule create request. properties: @@ -16862,6 +17136,35 @@ components: oneOf: - $ref: '#/components/schemas/DeploymentRuleOptionsFaultyDeploymentDetection' - $ref: '#/components/schemas/DeploymentRuleOptionsMonitor' + DetachCaseRequest: + description: Request for detaching security findings from their case. + properties: + data: + $ref: '#/components/schemas/DetachCaseRequestData' + type: object + DetachCaseRequestData: + description: Data for detaching security findings from their case. + properties: + id: + description: The unique identifier of the detachment request. + example: f8b9e3b1-24ec-4413-8be5-1b12b98533c6 + type: string + relationships: + $ref: '#/components/schemas/DetachCaseRequestDataRelationships' + type: + $ref: '#/components/schemas/CaseDataType' + required: + - type + type: object + DetachCaseRequestDataRelationships: + description: Relationships detaching security findings from their case. + properties: + findings: + $ref: '#/components/schemas/Findings' + description: Security findings to detach from their case. + required: + - findings + type: object DetailedFinding: description: A single finding with with message and resource configuration. properties: @@ -20712,6 +21015,153 @@ components: vulnerability_type: $ref: '#/components/schemas/FindingVulnerabilityType' type: object + FindingCaseResponse: + description: Case response. + properties: + data: + $ref: '#/components/schemas/FindingCaseResponseData' + type: object + FindingCaseResponseArray: + description: List of case responses. + properties: + data: + items: + $ref: '#/components/schemas/FindingCaseResponseData' + type: array + required: + - data + type: object + FindingCaseResponseData: + description: Data of the case. + properties: + attributes: + $ref: '#/components/schemas/FindingCaseResponseDataAttributes' + id: + description: The unique identifier of the case. + example: c1234567-89ab-cdef-0123-456789abcdef + type: string + relationships: + $ref: '#/components/schemas/FindingCaseResponseDataRelationships' + type: + $ref: '#/components/schemas/CaseDataType' + required: + - type + type: object + FindingCaseResponseDataAttributes: + description: Attributes of the case. + properties: + archived_at: + description: Timestamp of when the case was archived. + example: '2025-01-01T00:00:00.000Z' + format: date-time + type: string + assigned_to: + $ref: '#/components/schemas/RelationshipToUser' + description: User assigned to the case. + attributes: + additionalProperties: + items: + type: string + type: array + type: object + closed_at: + description: Timestamp of when the case was closed. + example: '2025-01-01T00:00:00.000Z' + format: date-time + type: string + created_at: + description: Timestamp of when the case was created. + example: '2025-01-01T00:00:00.000Z' + format: date-time + type: string + creation_source: + description: Source of the case creation. + example: CS_SECURITY_FINDING + type: string + description: + description: Description of the case. + example: A description of the case. + type: string + due_date: + description: Due date of the case. + example: '2025-01-01' + type: string + insights: + description: Insights of the case. + items: + $ref: '#/components/schemas/CaseInsightsItems' + type: array + jira_issue: + $ref: '#/components/schemas/FindingJiraIssue' + description: Jira issue associated with the case. + key: + description: Key of the case. + example: PROJ-123 + type: string + modified_at: + description: Timestamp of when the case was last modified. + example: '2025-01-01T00:00:00.000Z' + format: date-time + type: string + priority: + description: Priority of the case. + example: P4 + type: string + status: + description: Status of the case. + example: OPEN + type: string + status_group: + description: Status group of the case. + example: SG_OPEN + type: string + status_name: + description: Status name of the case. + example: Open + type: string + title: + description: Title of the case. + example: A title for the case. + type: string + type: + description: Type of the case. For security cases, this is always "SECURITY". + example: SECURITY + type: string + type: object + FindingCaseResponseDataRelationships: + description: Relationships of the case. + properties: + created_by: + $ref: '#/components/schemas/RelationshipToUser' + description: User who created the case. + modified_by: + $ref: '#/components/schemas/RelationshipToUser' + description: User who last modified the case. + project: + $ref: '#/components/schemas/CaseManagementProject' + description: Project in which the case was created. + type: object + FindingData: + properties: + id: + description: The unique identifier of the security finding. + example: ZGVmLTAwcC1pZXJ-aS0wZjhjNjMyZDNmMzRlZTgzNw== + type: string + type: + $ref: '#/components/schemas/FindingDataType' + required: + - type + - id + type: object + FindingDataType: + default: findings + description: Security findings resource type. + enum: + - findings + example: findings + type: string + x-enum-varnames: + - FINDINGS FindingDatadogLink: description: The Datadog relative link for this finding. example: /security/compliance?panels=cpfinding%7Cevent%7CruleId%3Adef-000-u5t%7CresourceId%3Ae8c9ab7c52ebd7bf2fdb4db641082d7d%7CtabId%3Aoverview @@ -20753,6 +21203,42 @@ components: description: The unique ID for this finding. example: ZGVmLTAwcC1pZXJ-aS0wZjhjNjMyZDNmMzRlZTgzNw== type: string + FindingJiraIssue: + description: Jira issue associated with the case. + properties: + error_message: + description: The error message if the Jira issue creation failed. + example: '{"errorMessages":["An error occured."],"errors":{}}' + type: string + result: + $ref: '#/components/schemas/FindingJiraIssueResult' + status: + description: The status of the Jira issue creation. Can be "COMPLETED" if + the Jira issue was created successfully, or "FAILED" if the Jira issue + creation failed. + example: COMPLETED + type: string + type: object + FindingJiraIssueResult: + description: Result of the Jira issue creation. + properties: + account_id: + description: The account ID of the Jira issue. + example: 463a8631-680e-455c-bfd3-3ed04d326eb7 + type: string + issue_id: + description: The unique identifier of the Jira issue. + example: '2871276' + type: string + issue_key: + description: The key of the Jira issue. + example: PROJ-123 + type: string + issue_url: + description: The URL of the Jira issue. + example: https://domain.atlassian.net/browse/PROJ-123 + type: string + type: object FindingMute: additionalProperties: false description: Information about the mute status of this finding. @@ -20878,6 +21364,14 @@ components: - ATTACK_PATH - IDENTITY_RISK - API_SECURITY + Findings: + description: A list of security findings. + properties: + data: + items: + $ref: '#/components/schemas/FindingData' + type: array + type: object FlakyTest: description: A flaky test object. properties: @@ -28295,6 +28789,15 @@ components: description: Jira project key type: string type: object + JiraIssuesDataType: + default: jira_issues + description: Jira issues resource type. + enum: + - jira_issues + example: jira_issues + type: string + x-enum-varnames: + - JIRA_ISSUES JobCreateResponse: description: Run a threat hunting job response. properties: @@ -74543,10 +75046,16 @@ paths: security: - apiKeyAuth: [] appKeyAuth: [] + - AuthZ: [] summary: Mute or unmute a batch of findings tags: - Security Monitoring x-codegen-request-body-name: body + x-permission: + operator: OR + permissions: + - security_monitoring_findings_write + - appsec_vm_write x-unstable: '**Note**: This endpoint is in public beta. If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/).' @@ -78230,6 +78739,208 @@ paths: operator: OR permissions: - security_monitoring_cws_agent_rules_read + /api/v2/security/findings/cases: + delete: + description: Detach security findings from their case. This operation dissociates + security findings from their associated cases without deleting the cases themselves. + You can detach security findings from multiple different cases in a single + request, with a limit of 50 security findings per request. Security findings + that are not currently attached to any case will be ignored. + operationId: DetachCase + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/DetachCaseRequest' + required: true + responses: + '204': + description: No Content + '400': + $ref: '#/components/responses/BadRequestResponse' + '404': + $ref: '#/components/responses/NotFoundResponse' + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: [] + summary: Detach security findings from their case + tags: + - Security Monitoring + x-codegen-request-body-name: body + x-permission: + operator: OR + permissions: + - security_monitoring_findings_write + - appsec_vm_write + post: + description: Create cases for security findings. You can create up to 50 cases + per request and associate up to 50 security findings per case. Security findings + that are already attached to another case will be detached from their previous + case and attached to the newly created case. + operationId: CreateCases + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateCaseRequestArray' + required: true + responses: + '201': + content: + application/json: + schema: + $ref: '#/components/schemas/FindingCaseResponseArray' + description: Created + '400': + $ref: '#/components/responses/BadRequestResponse' + '404': + $ref: '#/components/responses/NotFoundResponse' + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: [] + summary: Create cases for security findings + tags: + - Security Monitoring + x-codegen-request-body-name: body + x-permission: + operator: OR + permissions: + - security_monitoring_findings_write + - appsec_vm_write + /api/v2/security/findings/cases/{case_id}: + patch: + description: Attach security findings to a case. You can attach up to 50 security + findings per case. Security findings that are already attached to another + case will be detached from their previous case and attached to the specified + case. + operationId: AttachCase + parameters: + - description: The unique identifier of the case to attach security findings + to + in: path + name: case_id + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/AttachCaseRequest' + required: true + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/FindingCaseResponse' + description: OK + '400': + $ref: '#/components/responses/BadRequestResponse' + '404': + $ref: '#/components/responses/NotFoundResponse' + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: [] + summary: Attach security findings to a case + tags: + - Security Monitoring + x-codegen-request-body-name: body + x-permission: + operator: OR + permissions: + - security_monitoring_findings_write + - appsec_vm_write + /api/v2/security/findings/jira_issues: + patch: + description: Attach security findings to a Jira issue by providing the Jira + issue URL. You can attach up to 50 security findings per Jira issue. If the + Jira issue is not linked to any case, this operation will create a case for + the security findings and link the Jira issue to the newly created case. Security + findings that are already attached to another Jira issue will be detached + from their previous Jira issue and attached to the specified Jira issue. + operationId: AttachJiraIssue + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/AttachJiraIssueRequest' + required: true + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/FindingCaseResponse' + description: OK + '400': + $ref: '#/components/responses/BadRequestResponse' + '404': + $ref: '#/components/responses/NotFoundResponse' + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: [] + summary: Attach security findings to a Jira issue + tags: + - Security Monitoring + x-codegen-request-body-name: body + x-permission: + operator: OR + permissions: + - security_monitoring_findings_write + - appsec_vm_write + post: + description: Create Jira issues for security findings. This operation creates + a case in Datadog and a Jira issue linked to that case for bidirectional sync + between Datadog and Jira. You can create up to 50 Jira issues per request + and associate up to 50 security findings per Jira issue. Security findings + that are already attached to another Jira issue will be detached from their + previous Jira issue and attached to the newly created Jira issue. + operationId: CreateJiraIssues + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateJiraIssueRequestArray' + required: true + responses: + '201': + content: + application/json: + schema: + $ref: '#/components/schemas/FindingCaseResponseArray' + description: Created + '400': + $ref: '#/components/responses/BadRequestResponse' + '404': + $ref: '#/components/responses/NotFoundResponse' + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: [] + summary: Create Jira issues for security findings + tags: + - Security Monitoring + x-codegen-request-body-name: body + x-permission: + operator: OR + permissions: + - security_monitoring_findings_write + - appsec_vm_write /api/v2/security/sboms: get: description: 'Get a list of assets SBOMs for an organization. diff --git a/examples/v2_security-monitoring_AttachCase.rs b/examples/v2_security-monitoring_AttachCase.rs new file mode 100644 index 000000000..f8616d53c --- /dev/null +++ b/examples/v2_security-monitoring_AttachCase.rs @@ -0,0 +1,48 @@ +// Attach security findings to a case returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_security_monitoring::SecurityMonitoringAPI; +use datadog_api_client::datadogV2::model::AttachCaseRequest; +use datadog_api_client::datadogV2::model::AttachCaseRequestData; +use datadog_api_client::datadogV2::model::AttachCaseRequestDataRelationships; +use datadog_api_client::datadogV2::model::CaseDataType; +use datadog_api_client::datadogV2::model::FindingData; +use datadog_api_client::datadogV2::model::FindingDataType; +use datadog_api_client::datadogV2::model::Findings; + +#[tokio::main] +async fn main() { + let body = + AttachCaseRequest + ::new().data( + AttachCaseRequestData::new( + "7d16945b-baf8-411e-ab2a-20fe43af1ea3".to_string(), + CaseDataType::CASES, + ).relationships( + AttachCaseRequestDataRelationships::new( + Findings + ::new().data( + vec![ + FindingData::new( + "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=".to_string(), + FindingDataType::FINDINGS, + ), + FindingData::new( + "MmUzMzZkODQ2YTI3NDU0OTk4NDk3NzhkOTY5YjU2Zjh-YWJjZGI1ODI4OTYzNWM3ZmUwZTBlOWRkYTRiMGUyOGQ=".to_string(), + FindingDataType::FINDINGS, + ) + ], + ), + ), + ), + ); + let configuration = datadog::Configuration::new(); + let api = SecurityMonitoringAPI::with_config(configuration); + let resp = api + .attach_case("7d16945b-baf8-411e-ab2a-20fe43af1ea3".to_string(), body) + .await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_security-monitoring_AttachCase_897782765.rs b/examples/v2_security-monitoring_AttachCase_897782765.rs new file mode 100644 index 000000000..ddd2ef154 --- /dev/null +++ b/examples/v2_security-monitoring_AttachCase_897782765.rs @@ -0,0 +1,44 @@ +// Attach security finding to a case returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_security_monitoring::SecurityMonitoringAPI; +use datadog_api_client::datadogV2::model::AttachCaseRequest; +use datadog_api_client::datadogV2::model::AttachCaseRequestData; +use datadog_api_client::datadogV2::model::AttachCaseRequestDataRelationships; +use datadog_api_client::datadogV2::model::CaseDataType; +use datadog_api_client::datadogV2::model::FindingData; +use datadog_api_client::datadogV2::model::FindingDataType; +use datadog_api_client::datadogV2::model::Findings; + +#[tokio::main] +async fn main() { + let body = + AttachCaseRequest + ::new().data( + AttachCaseRequestData::new( + "7d16945b-baf8-411e-ab2a-20fe43af1ea3".to_string(), + CaseDataType::CASES, + ).relationships( + AttachCaseRequestDataRelationships::new( + Findings + ::new().data( + vec![ + FindingData::new( + "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=".to_string(), + FindingDataType::FINDINGS, + ) + ], + ), + ), + ), + ); + let configuration = datadog::Configuration::new(); + let api = SecurityMonitoringAPI::with_config(configuration); + let resp = api + .attach_case("7d16945b-baf8-411e-ab2a-20fe43af1ea3".to_string(), body) + .await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_security-monitoring_AttachJiraIssue.rs b/examples/v2_security-monitoring_AttachJiraIssue.rs new file mode 100644 index 000000000..de5b178b9 --- /dev/null +++ b/examples/v2_security-monitoring_AttachJiraIssue.rs @@ -0,0 +1,59 @@ +// Attach security findings to a Jira issue returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_security_monitoring::SecurityMonitoringAPI; +use datadog_api_client::datadogV2::model::AttachJiraIssueRequest; +use datadog_api_client::datadogV2::model::AttachJiraIssueRequestData; +use datadog_api_client::datadogV2::model::AttachJiraIssueRequestDataAttributes; +use datadog_api_client::datadogV2::model::AttachJiraIssueRequestDataRelationships; +use datadog_api_client::datadogV2::model::CaseManagementProject; +use datadog_api_client::datadogV2::model::CaseManagementProjectData; +use datadog_api_client::datadogV2::model::CaseManagementProjectDataType; +use datadog_api_client::datadogV2::model::FindingData; +use datadog_api_client::datadogV2::model::FindingDataType; +use datadog_api_client::datadogV2::model::Findings; +use datadog_api_client::datadogV2::model::JiraIssuesDataType; + +#[tokio::main] +async fn main() { + let body = + AttachJiraIssueRequest + ::new().data( + AttachJiraIssueRequestData::new(JiraIssuesDataType::JIRA_ISSUES) + .attributes( + AttachJiraIssueRequestDataAttributes::new( + "https://datadoghq-sandbox-538.atlassian.net/browse/CSMSEC-105476".to_string(), + ), + ) + .relationships( + AttachJiraIssueRequestDataRelationships::new( + Findings + ::new().data( + vec![ + FindingData::new( + "OTQ3NjJkMmYwMTIzMzMxNTc1Y2Q4MTA5NWU0NTBmMDl-ZjE3NjMxZWVkYzBjZGI1NDY2NWY2OGQxZDk4MDY4MmI=".to_string(), + FindingDataType::FINDINGS, + ), + FindingData::new( + "MTNjN2ZmYWMzMDIxYmU1ZDFiZDRjNWUwN2I1NzVmY2F-YTA3MzllMTUzNWM3NmEyZjdiNzEzOWM5YmViZTMzOGM=".to_string(), + FindingDataType::FINDINGS, + ) + ], + ), + CaseManagementProject::new( + CaseManagementProjectData::new( + "959a6f71-bac8-4027-b1d3-2264f569296f".to_string(), + CaseManagementProjectDataType::PROJECTS, + ), + ), + ), + ), + ); + let configuration = datadog::Configuration::new(); + let api = SecurityMonitoringAPI::with_config(configuration); + let resp = api.attach_jira_issue(body).await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_security-monitoring_AttachJiraIssue_3042842144.rs b/examples/v2_security-monitoring_AttachJiraIssue_3042842144.rs new file mode 100644 index 000000000..4124f5b15 --- /dev/null +++ b/examples/v2_security-monitoring_AttachJiraIssue_3042842144.rs @@ -0,0 +1,55 @@ +// Attach security finding to a Jira issue returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_security_monitoring::SecurityMonitoringAPI; +use datadog_api_client::datadogV2::model::AttachJiraIssueRequest; +use datadog_api_client::datadogV2::model::AttachJiraIssueRequestData; +use datadog_api_client::datadogV2::model::AttachJiraIssueRequestDataAttributes; +use datadog_api_client::datadogV2::model::AttachJiraIssueRequestDataRelationships; +use datadog_api_client::datadogV2::model::CaseManagementProject; +use datadog_api_client::datadogV2::model::CaseManagementProjectData; +use datadog_api_client::datadogV2::model::CaseManagementProjectDataType; +use datadog_api_client::datadogV2::model::FindingData; +use datadog_api_client::datadogV2::model::FindingDataType; +use datadog_api_client::datadogV2::model::Findings; +use datadog_api_client::datadogV2::model::JiraIssuesDataType; + +#[tokio::main] +async fn main() { + let body = + AttachJiraIssueRequest + ::new().data( + AttachJiraIssueRequestData::new(JiraIssuesDataType::JIRA_ISSUES) + .attributes( + AttachJiraIssueRequestDataAttributes::new( + "https://datadoghq-sandbox-538.atlassian.net/browse/CSMSEC-105476".to_string(), + ), + ) + .relationships( + AttachJiraIssueRequestDataRelationships::new( + Findings + ::new().data( + vec![ + FindingData::new( + "OTQ3NjJkMmYwMTIzMzMxNTc1Y2Q4MTA5NWU0NTBmMDl-ZjE3NjMxZWVkYzBjZGI1NDY2NWY2OGQxZDk4MDY4MmI=".to_string(), + FindingDataType::FINDINGS, + ) + ], + ), + CaseManagementProject::new( + CaseManagementProjectData::new( + "959a6f71-bac8-4027-b1d3-2264f569296f".to_string(), + CaseManagementProjectDataType::PROJECTS, + ), + ), + ), + ), + ); + let configuration = datadog::Configuration::new(); + let api = SecurityMonitoringAPI::with_config(configuration); + let resp = api.attach_jira_issue(body).await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_security-monitoring_CreateCases.rs b/examples/v2_security-monitoring_CreateCases.rs new file mode 100644 index 000000000..5fa38fb1c --- /dev/null +++ b/examples/v2_security-monitoring_CreateCases.rs @@ -0,0 +1,81 @@ +// Create cases for security findings returns "Created" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_security_monitoring::SecurityMonitoringAPI; +use datadog_api_client::datadogV2::model::CaseDataType; +use datadog_api_client::datadogV2::model::CaseManagementProject; +use datadog_api_client::datadogV2::model::CaseManagementProjectData; +use datadog_api_client::datadogV2::model::CaseManagementProjectDataType; +use datadog_api_client::datadogV2::model::CreateCaseRequestArray; +use datadog_api_client::datadogV2::model::CreateCaseRequestData; +use datadog_api_client::datadogV2::model::CreateCaseRequestDataAttributes; +use datadog_api_client::datadogV2::model::CreateCaseRequestDataRelationships; +use datadog_api_client::datadogV2::model::FindingData; +use datadog_api_client::datadogV2::model::FindingDataType; +use datadog_api_client::datadogV2::model::Findings; + +#[tokio::main] +async fn main() { + let body = + CreateCaseRequestArray::new( + vec![ + CreateCaseRequestData::new(CaseDataType::CASES) + .attributes( + CreateCaseRequestDataAttributes::new() + .description("A description".to_string()) + .title("A title".to_string()), + ) + .relationships( + CreateCaseRequestDataRelationships::new( + Findings + ::new().data( + vec![ + FindingData::new( + "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=".to_string(), + FindingDataType::FINDINGS, + ) + ], + ), + CaseManagementProject::new( + CaseManagementProjectData::new( + "959a6f71-bac8-4027-b1d3-2264f569296f".to_string(), + CaseManagementProjectDataType::PROJECTS, + ), + ), + ), + ), + CreateCaseRequestData::new(CaseDataType::CASES) + .attributes( + CreateCaseRequestDataAttributes::new() + .description("A description".to_string()) + .title("A title".to_string()), + ) + .relationships( + CreateCaseRequestDataRelationships::new( + Findings + ::new().data( + vec![ + FindingData::new( + "MzZkNTMxODNmOGZlZmJiYzIyMDg4NzhmM2QyMDExZjB-ZmY5NzUwNDQzYTE0MGIyNDM1MTg4YjkxZDNmMDU4OGU=".to_string(), + FindingDataType::FINDINGS, + ) + ], + ), + CaseManagementProject::new( + CaseManagementProjectData::new( + "959a6f71-bac8-4027-b1d3-2264f569296f".to_string(), + CaseManagementProjectDataType::PROJECTS, + ), + ), + ), + ) + ], + ); + let configuration = datadog::Configuration::new(); + let api = SecurityMonitoringAPI::with_config(configuration); + let resp = api.create_cases(body).await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_security-monitoring_CreateCases_2385516013.rs b/examples/v2_security-monitoring_CreateCases_2385516013.rs new file mode 100644 index 000000000..584f0115b --- /dev/null +++ b/examples/v2_security-monitoring_CreateCases_2385516013.rs @@ -0,0 +1,56 @@ +// Create case for security finding returns "Created" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_security_monitoring::SecurityMonitoringAPI; +use datadog_api_client::datadogV2::model::CaseDataType; +use datadog_api_client::datadogV2::model::CaseManagementProject; +use datadog_api_client::datadogV2::model::CaseManagementProjectData; +use datadog_api_client::datadogV2::model::CaseManagementProjectDataType; +use datadog_api_client::datadogV2::model::CreateCaseRequestArray; +use datadog_api_client::datadogV2::model::CreateCaseRequestData; +use datadog_api_client::datadogV2::model::CreateCaseRequestDataAttributes; +use datadog_api_client::datadogV2::model::CreateCaseRequestDataRelationships; +use datadog_api_client::datadogV2::model::FindingData; +use datadog_api_client::datadogV2::model::FindingDataType; +use datadog_api_client::datadogV2::model::Findings; + +#[tokio::main] +async fn main() { + let body = + CreateCaseRequestArray::new( + vec![ + CreateCaseRequestData::new(CaseDataType::CASES) + .attributes( + CreateCaseRequestDataAttributes::new() + .description("A description".to_string()) + .title("A title".to_string()), + ) + .relationships( + CreateCaseRequestDataRelationships::new( + Findings + ::new().data( + vec![ + FindingData::new( + "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=".to_string(), + FindingDataType::FINDINGS, + ) + ], + ), + CaseManagementProject::new( + CaseManagementProjectData::new( + "959a6f71-bac8-4027-b1d3-2264f569296f".to_string(), + CaseManagementProjectDataType::PROJECTS, + ), + ), + ), + ) + ], + ); + let configuration = datadog::Configuration::new(); + let api = SecurityMonitoringAPI::with_config(configuration); + let resp = api.create_cases(body).await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_security-monitoring_CreateCases_2798851680.rs b/examples/v2_security-monitoring_CreateCases_2798851680.rs new file mode 100644 index 000000000..5288580a1 --- /dev/null +++ b/examples/v2_security-monitoring_CreateCases_2798851680.rs @@ -0,0 +1,60 @@ +// Create case for security findings returns "Created" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_security_monitoring::SecurityMonitoringAPI; +use datadog_api_client::datadogV2::model::CaseDataType; +use datadog_api_client::datadogV2::model::CaseManagementProject; +use datadog_api_client::datadogV2::model::CaseManagementProjectData; +use datadog_api_client::datadogV2::model::CaseManagementProjectDataType; +use datadog_api_client::datadogV2::model::CreateCaseRequestArray; +use datadog_api_client::datadogV2::model::CreateCaseRequestData; +use datadog_api_client::datadogV2::model::CreateCaseRequestDataAttributes; +use datadog_api_client::datadogV2::model::CreateCaseRequestDataRelationships; +use datadog_api_client::datadogV2::model::FindingData; +use datadog_api_client::datadogV2::model::FindingDataType; +use datadog_api_client::datadogV2::model::Findings; + +#[tokio::main] +async fn main() { + let body = + CreateCaseRequestArray::new( + vec![ + CreateCaseRequestData::new(CaseDataType::CASES) + .attributes( + CreateCaseRequestDataAttributes::new() + .description("A description".to_string()) + .title("A title".to_string()), + ) + .relationships( + CreateCaseRequestDataRelationships::new( + Findings + ::new().data( + vec![ + FindingData::new( + "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=".to_string(), + FindingDataType::FINDINGS, + ), + FindingData::new( + "MzZkNTMxODNmOGZlZmJiYzIyMDg4NzhmM2QyMDExZjB-ZmY5NzUwNDQzYTE0MGIyNDM1MTg4YjkxZDNmMDU4OGU=".to_string(), + FindingDataType::FINDINGS, + ) + ], + ), + CaseManagementProject::new( + CaseManagementProjectData::new( + "959a6f71-bac8-4027-b1d3-2264f569296f".to_string(), + CaseManagementProjectDataType::PROJECTS, + ), + ), + ), + ) + ], + ); + let configuration = datadog::Configuration::new(); + let api = SecurityMonitoringAPI::with_config(configuration); + let resp = api.create_cases(body).await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_security-monitoring_CreateJiraIssues.rs b/examples/v2_security-monitoring_CreateJiraIssues.rs new file mode 100644 index 000000000..1807f137b --- /dev/null +++ b/examples/v2_security-monitoring_CreateJiraIssues.rs @@ -0,0 +1,149 @@ +// Create Jira issues for security findings returns "Created" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_security_monitoring::SecurityMonitoringAPI; +use datadog_api_client::datadogV2::model::CaseDataType; +use datadog_api_client::datadogV2::model::CaseManagementProject; +use datadog_api_client::datadogV2::model::CaseManagementProjectData; +use datadog_api_client::datadogV2::model::CaseManagementProjectDataType; +use datadog_api_client::datadogV2::model::CreateCaseRequestData; +use datadog_api_client::datadogV2::model::CreateCaseRequestDataAttributes; +use datadog_api_client::datadogV2::model::CreateCaseRequestDataRelationships; +use datadog_api_client::datadogV2::model::CreateJiraIssueRequestArray; +use datadog_api_client::datadogV2::model::CreateJiraIssueRequestArrayIncluded; +use datadog_api_client::datadogV2::model::CreateJiraIssueRequestData; +use datadog_api_client::datadogV2::model::CreateJiraIssueRequestDataAttributes; +use datadog_api_client::datadogV2::model::CreateJiraIssueRequestDataRelationships; +use datadog_api_client::datadogV2::model::CreateJiraIssueRequestDataRelationshipsCase; +use datadog_api_client::datadogV2::model::CreateJiraIssueRequestDataRelationshipsCaseData; +use datadog_api_client::datadogV2::model::FindingData; +use datadog_api_client::datadogV2::model::FindingDataType; +use datadog_api_client::datadogV2::model::Findings; +use datadog_api_client::datadogV2::model::JiraIssuesDataType; + +#[tokio::main] +async fn main() { + let body = + CreateJiraIssueRequestArray::new( + vec![ + CreateJiraIssueRequestData::new(JiraIssuesDataType::JIRA_ISSUES) + .attributes(CreateJiraIssueRequestDataAttributes::new()) + .relationships( + CreateJiraIssueRequestDataRelationships::new( + CreateJiraIssueRequestDataRelationshipsCase::new( + CreateJiraIssueRequestDataRelationshipsCaseData::new( + "53e242c6-a7d6-46ad-9680-b8d14753f716".to_string(), + CaseDataType::CASES, + ), + ), + ), + ), + CreateJiraIssueRequestData::new(JiraIssuesDataType::JIRA_ISSUES) + .attributes(CreateJiraIssueRequestDataAttributes::new()) + .relationships( + CreateJiraIssueRequestDataRelationships::new( + CreateJiraIssueRequestDataRelationshipsCase::new( + CreateJiraIssueRequestDataRelationshipsCaseData::new( + "195772b2-1f53-41d2-b81e-48c8e6c21d33".to_string(), + CaseDataType::CASES, + ), + ), + ), + ) + ], + ).included( + vec![ + CreateJiraIssueRequestArrayIncluded::CreateCaseRequestData( + Box::new( + CreateCaseRequestData::new(CaseDataType::CASES) + .attributes( + CreateCaseRequestDataAttributes::new() + .description("A description".to_string()) + .title("A title".to_string()), + ) + .id("53e242c6-a7d6-46ad-9680-b8d14753f716".to_string()) + .relationships( + CreateCaseRequestDataRelationships::new( + Findings + ::new().data( + vec![ + FindingData::new( + "OTQ3NjJkMmYwMTIzMzMxNTc1Y2Q4MTA5NWU0NTBmMDl-ZjE3NjMxZWVkYzBjZGI1NDY2NWY2OGQxZDk4MDY4MmI=".to_string(), + FindingDataType::FINDINGS, + ) + ], + ), + CaseManagementProject::new( + CaseManagementProjectData::new( + "959a6f71-bac8-4027-b1d3-2264f569296f".to_string(), + CaseManagementProjectDataType::PROJECTS, + ), + ), + ), + ), + ), + ), + CreateJiraIssueRequestArrayIncluded::CreateCaseRequestData( + Box::new( + CreateCaseRequestData::new(CaseDataType::CASES) + .attributes( + CreateCaseRequestDataAttributes::new() + .description("A description".to_string()) + .title("A title".to_string()), + ) + .id("195772b2-1f53-41d2-b81e-48c8e6c21d33".to_string()) + .relationships( + CreateCaseRequestDataRelationships::new( + Findings + ::new().data( + vec![ + FindingData::new( + "MTNjN2ZmYWMzMDIxYmU1ZDFiZDRjNWUwN2I1NzVmY2F-YTA3MzllMTUzNWM3NmEyZjdiNzEzOWM5YmViZTMzOGM=".to_string(), + FindingDataType::FINDINGS, + ) + ], + ), + CaseManagementProject::new( + CaseManagementProjectData::new( + "959a6f71-bac8-4027-b1d3-2264f569296f".to_string(), + CaseManagementProjectDataType::PROJECTS, + ), + ), + ), + ), + ), + ), + CreateJiraIssueRequestArrayIncluded::CaseManagementProjectData( + Box::new( + CaseManagementProjectData::new( + "959a6f71-bac8-4027-b1d3-2264f569296f".to_string(), + CaseManagementProjectDataType::PROJECTS, + ), + ), + ), + CreateJiraIssueRequestArrayIncluded::FindingData( + Box::new( + FindingData::new( + "OTQ3NjJkMmYwMTIzMzMxNTc1Y2Q4MTA5NWU0NTBmMDl-ZjE3NjMxZWVkYzBjZGI1NDY2NWY2OGQxZDk4MDY4MmI=".to_string(), + FindingDataType::FINDINGS, + ), + ), + ), + CreateJiraIssueRequestArrayIncluded::FindingData( + Box::new( + FindingData::new( + "MTNjN2ZmYWMzMDIxYmU1ZDFiZDRjNWUwN2I1NzVmY2F-YTA3MzllMTUzNWM3NmEyZjdiNzEzOWM5YmViZTMzOGM=".to_string(), + FindingDataType::FINDINGS, + ), + ), + ) + ], + ); + let configuration = datadog::Configuration::new(); + let api = SecurityMonitoringAPI::with_config(configuration); + let resp = api.create_jira_issues(body).await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_security-monitoring_CreateJiraIssues_379590688.rs b/examples/v2_security-monitoring_CreateJiraIssues_379590688.rs new file mode 100644 index 000000000..3593142b2 --- /dev/null +++ b/examples/v2_security-monitoring_CreateJiraIssues_379590688.rs @@ -0,0 +1,99 @@ +// Create Jira issue for security finding returns "Created" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_security_monitoring::SecurityMonitoringAPI; +use datadog_api_client::datadogV2::model::CaseDataType; +use datadog_api_client::datadogV2::model::CaseManagementProject; +use datadog_api_client::datadogV2::model::CaseManagementProjectData; +use datadog_api_client::datadogV2::model::CaseManagementProjectDataType; +use datadog_api_client::datadogV2::model::CreateCaseRequestData; +use datadog_api_client::datadogV2::model::CreateCaseRequestDataAttributes; +use datadog_api_client::datadogV2::model::CreateCaseRequestDataRelationships; +use datadog_api_client::datadogV2::model::CreateJiraIssueRequestArray; +use datadog_api_client::datadogV2::model::CreateJiraIssueRequestArrayIncluded; +use datadog_api_client::datadogV2::model::CreateJiraIssueRequestData; +use datadog_api_client::datadogV2::model::CreateJiraIssueRequestDataAttributes; +use datadog_api_client::datadogV2::model::CreateJiraIssueRequestDataRelationships; +use datadog_api_client::datadogV2::model::CreateJiraIssueRequestDataRelationshipsCase; +use datadog_api_client::datadogV2::model::CreateJiraIssueRequestDataRelationshipsCaseData; +use datadog_api_client::datadogV2::model::FindingData; +use datadog_api_client::datadogV2::model::FindingDataType; +use datadog_api_client::datadogV2::model::Findings; +use datadog_api_client::datadogV2::model::JiraIssuesDataType; + +#[tokio::main] +async fn main() { + let body = + CreateJiraIssueRequestArray::new( + vec![ + CreateJiraIssueRequestData::new(JiraIssuesDataType::JIRA_ISSUES) + .attributes(CreateJiraIssueRequestDataAttributes::new()) + .relationships( + CreateJiraIssueRequestDataRelationships::new( + CreateJiraIssueRequestDataRelationshipsCase::new( + CreateJiraIssueRequestDataRelationshipsCaseData::new( + "6a773295-8729-4034-aada-53b64cbe02e7".to_string(), + CaseDataType::CASES, + ), + ), + ), + ) + ], + ).included( + vec![ + CreateJiraIssueRequestArrayIncluded::CreateCaseRequestData( + Box::new( + CreateCaseRequestData::new(CaseDataType::CASES) + .attributes( + CreateCaseRequestDataAttributes::new() + .description("A description".to_string()) + .title("A title".to_string()), + ) + .id("6a773295-8729-4034-aada-53b64cbe02e7".to_string()) + .relationships( + CreateCaseRequestDataRelationships::new( + Findings + ::new().data( + vec![ + FindingData::new( + "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=".to_string(), + FindingDataType::FINDINGS, + ) + ], + ), + CaseManagementProject::new( + CaseManagementProjectData::new( + "959a6f71-bac8-4027-b1d3-2264f569296f".to_string(), + CaseManagementProjectDataType::PROJECTS, + ), + ), + ), + ), + ), + ), + CreateJiraIssueRequestArrayIncluded::CaseManagementProjectData( + Box::new( + CaseManagementProjectData::new( + "959a6f71-bac8-4027-b1d3-2264f569296f".to_string(), + CaseManagementProjectDataType::PROJECTS, + ), + ), + ), + CreateJiraIssueRequestArrayIncluded::FindingData( + Box::new( + FindingData::new( + "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=".to_string(), + FindingDataType::FINDINGS, + ), + ), + ) + ], + ); + let configuration = datadog::Configuration::new(); + let api = SecurityMonitoringAPI::with_config(configuration); + let resp = api.create_jira_issues(body).await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_security-monitoring_CreateJiraIssues_829823123.rs b/examples/v2_security-monitoring_CreateJiraIssues_829823123.rs new file mode 100644 index 000000000..4084ca219 --- /dev/null +++ b/examples/v2_security-monitoring_CreateJiraIssues_829823123.rs @@ -0,0 +1,111 @@ +// Create Jira issue for security findings returns "Created" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_security_monitoring::SecurityMonitoringAPI; +use datadog_api_client::datadogV2::model::CaseDataType; +use datadog_api_client::datadogV2::model::CaseManagementProject; +use datadog_api_client::datadogV2::model::CaseManagementProjectData; +use datadog_api_client::datadogV2::model::CaseManagementProjectDataType; +use datadog_api_client::datadogV2::model::CreateCaseRequestData; +use datadog_api_client::datadogV2::model::CreateCaseRequestDataAttributes; +use datadog_api_client::datadogV2::model::CreateCaseRequestDataRelationships; +use datadog_api_client::datadogV2::model::CreateJiraIssueRequestArray; +use datadog_api_client::datadogV2::model::CreateJiraIssueRequestArrayIncluded; +use datadog_api_client::datadogV2::model::CreateJiraIssueRequestData; +use datadog_api_client::datadogV2::model::CreateJiraIssueRequestDataAttributes; +use datadog_api_client::datadogV2::model::CreateJiraIssueRequestDataRelationships; +use datadog_api_client::datadogV2::model::CreateJiraIssueRequestDataRelationshipsCase; +use datadog_api_client::datadogV2::model::CreateJiraIssueRequestDataRelationshipsCaseData; +use datadog_api_client::datadogV2::model::FindingData; +use datadog_api_client::datadogV2::model::FindingDataType; +use datadog_api_client::datadogV2::model::Findings; +use datadog_api_client::datadogV2::model::JiraIssuesDataType; + +#[tokio::main] +async fn main() { + let body = + CreateJiraIssueRequestArray::new( + vec![ + CreateJiraIssueRequestData::new(JiraIssuesDataType::JIRA_ISSUES) + .attributes(CreateJiraIssueRequestDataAttributes::new()) + .relationships( + CreateJiraIssueRequestDataRelationships::new( + CreateJiraIssueRequestDataRelationshipsCase::new( + CreateJiraIssueRequestDataRelationshipsCaseData::new( + "e469ceda-957a-4557-a607-9ff25032e9ca".to_string(), + CaseDataType::CASES, + ), + ), + ), + ) + ], + ).included( + vec![ + CreateJiraIssueRequestArrayIncluded::CreateCaseRequestData( + Box::new( + CreateCaseRequestData::new(CaseDataType::CASES) + .attributes( + CreateCaseRequestDataAttributes::new() + .description("A description".to_string()) + .title("A title".to_string()), + ) + .id("e469ceda-957a-4557-a607-9ff25032e9ca".to_string()) + .relationships( + CreateCaseRequestDataRelationships::new( + Findings + ::new().data( + vec![ + FindingData::new( + "MzUxMDI4OWYyYWEyODRhYjQ0Zjg2YjY2ZTFmNjRjYzd-NDU2OWQyNTk1MjM5OGI2NzJjMTVhYjhiODY1ZDcwZWY=".to_string(), + FindingDataType::FINDINGS, + ), + FindingData::new( + "ZjE2ZGI5YjdmYTQyYzhhMDQ3Nzc3YjM1NGQ2Y2NmZTd-NDU2OWQyNTk1MjM5OGI2NzJjMTVhYjhiODY1ZDcwZWY=".to_string(), + FindingDataType::FINDINGS, + ) + ], + ), + CaseManagementProject::new( + CaseManagementProjectData::new( + "959a6f71-bac8-4027-b1d3-2264f569296f".to_string(), + CaseManagementProjectDataType::PROJECTS, + ), + ), + ), + ), + ), + ), + CreateJiraIssueRequestArrayIncluded::CaseManagementProjectData( + Box::new( + CaseManagementProjectData::new( + "959a6f71-bac8-4027-b1d3-2264f569296f".to_string(), + CaseManagementProjectDataType::PROJECTS, + ), + ), + ), + CreateJiraIssueRequestArrayIncluded::FindingData( + Box::new( + FindingData::new( + "MzUxMDI4OWYyYWEyODRhYjQ0Zjg2YjY2ZTFmNjRjYzd-NDU2OWQyNTk1MjM5OGI2NzJjMTVhYjhiODY1ZDcwZWY=".to_string(), + FindingDataType::FINDINGS, + ), + ), + ), + CreateJiraIssueRequestArrayIncluded::FindingData( + Box::new( + FindingData::new( + "ZjE2ZGI5YjdmYTQyYzhhMDQ3Nzc3YjM1NGQ2Y2NmZTd-NDU2OWQyNTk1MjM5OGI2NzJjMTVhYjhiODY1ZDcwZWY=".to_string(), + FindingDataType::FINDINGS, + ), + ), + ) + ], + ); + let configuration = datadog::Configuration::new(); + let api = SecurityMonitoringAPI::with_config(configuration); + let resp = api.create_jira_issues(body).await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_security-monitoring_DetachCase.rs b/examples/v2_security-monitoring_DetachCase.rs new file mode 100644 index 000000000..0f9c53beb --- /dev/null +++ b/examples/v2_security-monitoring_DetachCase.rs @@ -0,0 +1,41 @@ +// Detach security findings from their case returns "No Content" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_security_monitoring::SecurityMonitoringAPI; +use datadog_api_client::datadogV2::model::CaseDataType; +use datadog_api_client::datadogV2::model::DetachCaseRequest; +use datadog_api_client::datadogV2::model::DetachCaseRequestData; +use datadog_api_client::datadogV2::model::DetachCaseRequestDataRelationships; +use datadog_api_client::datadogV2::model::FindingData; +use datadog_api_client::datadogV2::model::FindingDataType; +use datadog_api_client::datadogV2::model::Findings; + +#[tokio::main] +async fn main() { + let body = + DetachCaseRequest + ::new().data( + DetachCaseRequestData::new( + CaseDataType::CASES, + ).relationships( + DetachCaseRequestDataRelationships::new( + Findings + ::new().data( + vec![ + FindingData::new( + "YzM2MTFjYzcyNmY0Zjg4MTAxZmRlNjQ1MWU1ZGQwYzR-YzI5NzE5Y2Y4MzU4ZjliNzhkNjYxNTY0ODIzZDQ2YTM=".to_string(), + FindingDataType::FINDINGS, + ) + ], + ), + ), + ), + ); + let configuration = datadog::Configuration::new(); + let api = SecurityMonitoringAPI::with_config(configuration); + let resp = api.detach_case(body).await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/src/datadogV2/api/api_security_monitoring.rs b/src/datadogV2/api/api_security_monitoring.rs index 3a44bb32f..21a8d06b4 100644 --- a/src/datadogV2/api/api_security_monitoring.rs +++ b/src/datadogV2/api/api_security_monitoring.rs @@ -1047,6 +1047,22 @@ impl SearchSecurityMonitoringSignalsOptionalParams { } } +/// AttachCaseError is a struct for typed errors of method [`SecurityMonitoringAPI::attach_case`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum AttachCaseError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + +/// AttachJiraIssueError is a struct for typed errors of method [`SecurityMonitoringAPI::attach_jira_issue`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum AttachJiraIssueError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// CancelThreatHuntingJobError is a struct for typed errors of method [`SecurityMonitoringAPI::cancel_threat_hunting_job`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -1079,6 +1095,14 @@ pub enum ConvertSecurityMonitoringRuleFromJSONToTerraformError { UnknownValue(serde_json::Value), } +/// CreateCasesError is a struct for typed errors of method [`SecurityMonitoringAPI::create_cases`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum CreateCasesError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// CreateCustomFrameworkError is a struct for typed errors of method [`SecurityMonitoringAPI::create_custom_framework`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -1087,6 +1111,14 @@ pub enum CreateCustomFrameworkError { UnknownValue(serde_json::Value), } +/// CreateJiraIssuesError is a struct for typed errors of method [`SecurityMonitoringAPI::create_jira_issues`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum CreateJiraIssuesError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// CreateSecurityFilterError is a struct for typed errors of method [`SecurityMonitoringAPI::create_security_filter`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -1183,6 +1215,14 @@ pub enum DeleteVulnerabilityNotificationRuleError { UnknownValue(serde_json::Value), } +/// DetachCaseError is a struct for typed errors of method [`SecurityMonitoringAPI::detach_case`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum DetachCaseError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// EditSecurityMonitoringSignalAssigneeError is a struct for typed errors of method [`SecurityMonitoringAPI::edit_security_monitoring_signal_assignee`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -1647,46 +1687,52 @@ impl SecurityMonitoringAPI { Self { config, client } } - /// Cancel a threat hunting job. - pub async fn cancel_threat_hunting_job( + /// Attach security findings to a case. You can attach up to 50 security findings per case. Security findings that are already attached to another case will be detached from their previous case and attached to the specified case. + pub async fn attach_case( &self, - job_id: String, - ) -> Result<(), datadog::Error> { - match self.cancel_threat_hunting_job_with_http_info(job_id).await { - Ok(_) => Ok(()), + case_id: String, + body: crate::datadogV2::model::AttachCaseRequest, + ) -> Result> { + match self.attach_case_with_http_info(case_id, body).await { + Ok(response_content) => { + if let Some(e) = response_content.entity { + Ok(e) + } else { + Err(datadog::Error::Serde(serde::de::Error::custom( + "response content was None", + ))) + } + } Err(err) => Err(err), } } - /// Cancel a threat hunting job. - pub async fn cancel_threat_hunting_job_with_http_info( + /// Attach security findings to a case. You can attach up to 50 security findings per case. Security findings that are already attached to another case will be detached from their previous case and attached to the specified case. + pub async fn attach_case_with_http_info( &self, - job_id: String, - ) -> Result, datadog::Error> { + case_id: String, + body: crate::datadogV2::model::AttachCaseRequest, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { let local_configuration = &self.config; - let operation_id = "v2.cancel_threat_hunting_job"; - if local_configuration.is_unstable_operation_enabled(operation_id) { - warn!("Using unstable operation {operation_id}"); - } else { - let local_error = datadog::UnstableOperationDisabledError { - msg: "Operation 'v2.cancel_threat_hunting_job' is not enabled".to_string(), - }; - return Err(datadog::Error::UnstableOperationDisabledError(local_error)); - } + let operation_id = "v2.attach_case"; let local_client = &self.client; let local_uri_str = format!( - "{}/api/v2/siem-threat-hunting/jobs/{job_id}/cancel", + "{}/api/v2/security/findings/cases/{case_id}", local_configuration.get_operation_host(operation_id), - job_id = datadog::urlencode(job_id) + case_id = datadog::urlencode(case_id) ); let mut local_req_builder = local_client.request(reqwest::Method::PATCH, local_uri_str.as_str()); // build headers let mut headers = HeaderMap::new(); - headers.insert("Accept", HeaderValue::from_static("*/*")); + headers.insert("Content-Type", HeaderValue::from_static("application/json")); + headers.insert("Accept", HeaderValue::from_static("application/json")); // build user agent match HeaderValue::from_str(local_configuration.user_agent.as_str()) { @@ -1716,6 +1762,51 @@ impl SecurityMonitoringAPI { ); }; + // build body parameters + let output = Vec::new(); + let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter); + if body.serialize(&mut ser).is_ok() { + if let Some(content_encoding) = headers.get("Content-Encoding") { + match content_encoding.to_str().unwrap_or_default() { + "gzip" => { + let mut enc = GzEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "deflate" => { + let mut enc = ZlibEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "zstd1" => { + let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap(); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + _ => { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + } else { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + local_req_builder = local_req_builder.headers(headers); let local_req = local_req_builder.build()?; log::debug!("request content: {:?}", local_req.body()); @@ -1726,14 +1817,20 @@ impl SecurityMonitoringAPI { log::debug!("response content: {}", local_content); if !local_status.is_client_error() && !local_status.is_server_error() { - Ok(datadog::ResponseContent { - status: local_status, - content: local_content, - entity: None, - }) + match serde_json::from_str::( + &local_content, + ) { + Ok(e) => { + return Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: Some(e), + }) + } + Err(e) => return Err(datadog::Error::Serde(e)), + }; } else { - let local_entity: Option = - serde_json::from_str(&local_content).ok(); + let local_entity: Option = serde_json::from_str(&local_content).ok(); let local_error = datadog::ResponseContent { status: local_status, content: local_content, @@ -1743,24 +1840,13 @@ impl SecurityMonitoringAPI { } } - /// Convert an existing rule from JSON to Terraform for Datadog provider - /// resource `datadog_security_monitoring_rule`. You can do so for the following rule types: - /// - App and API Protection - /// - Cloud SIEM (log detection and signal correlation) - /// - Workload Protection - /// - /// You can convert Cloud Security configuration rules using Terraform's [Datadog Cloud Configuration Rule resource](). - pub async fn convert_existing_security_monitoring_rule( + /// Attach security findings to a Jira issue by providing the Jira issue URL. You can attach up to 50 security findings per Jira issue. If the Jira issue is not linked to any case, this operation will create a case for the security findings and link the Jira issue to the newly created case. Security findings that are already attached to another Jira issue will be detached from their previous Jira issue and attached to the specified Jira issue. + pub async fn attach_jira_issue( &self, - rule_id: String, - ) -> Result< - crate::datadogV2::model::SecurityMonitoringRuleConvertResponse, - datadog::Error, - > { - match self - .convert_existing_security_monitoring_rule_with_http_info(rule_id) - .await - { + body: crate::datadogV2::model::AttachJiraIssueRequest, + ) -> Result> + { + match self.attach_jira_issue_with_http_info(body).await { Ok(response_content) => { if let Some(e) = response_content.entity { Ok(e) @@ -1774,35 +1860,29 @@ impl SecurityMonitoringAPI { } } - /// Convert an existing rule from JSON to Terraform for Datadog provider - /// resource `datadog_security_monitoring_rule`. You can do so for the following rule types: - /// - App and API Protection - /// - Cloud SIEM (log detection and signal correlation) - /// - Workload Protection - /// - /// You can convert Cloud Security configuration rules using Terraform's [Datadog Cloud Configuration Rule resource](). - pub async fn convert_existing_security_monitoring_rule_with_http_info( + /// Attach security findings to a Jira issue by providing the Jira issue URL. You can attach up to 50 security findings per Jira issue. If the Jira issue is not linked to any case, this operation will create a case for the security findings and link the Jira issue to the newly created case. Security findings that are already attached to another Jira issue will be detached from their previous Jira issue and attached to the specified Jira issue. + pub async fn attach_jira_issue_with_http_info( &self, - rule_id: String, + body: crate::datadogV2::model::AttachJiraIssueRequest, ) -> Result< - datadog::ResponseContent, - datadog::Error, + datadog::ResponseContent, + datadog::Error, > { let local_configuration = &self.config; - let operation_id = "v2.convert_existing_security_monitoring_rule"; + let operation_id = "v2.attach_jira_issue"; let local_client = &self.client; let local_uri_str = format!( - "{}/api/v2/security_monitoring/rules/{rule_id}/convert", - local_configuration.get_operation_host(operation_id), - rule_id = datadog::urlencode(rule_id) + "{}/api/v2/security/findings/jira_issues", + local_configuration.get_operation_host(operation_id) ); let mut local_req_builder = - local_client.request(reqwest::Method::GET, local_uri_str.as_str()); + local_client.request(reqwest::Method::PATCH, local_uri_str.as_str()); // build headers let mut headers = HeaderMap::new(); + headers.insert("Content-Type", HeaderValue::from_static("application/json")); headers.insert("Accept", HeaderValue::from_static("application/json")); // build user agent @@ -1833,6 +1913,582 @@ impl SecurityMonitoringAPI { ); }; + // build body parameters + let output = Vec::new(); + let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter); + if body.serialize(&mut ser).is_ok() { + if let Some(content_encoding) = headers.get("Content-Encoding") { + match content_encoding.to_str().unwrap_or_default() { + "gzip" => { + let mut enc = GzEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "deflate" => { + let mut enc = ZlibEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "zstd1" => { + let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap(); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + _ => { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + } else { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + match serde_json::from_str::( + &local_content, + ) { + Ok(e) => { + return Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: Some(e), + }) + } + Err(e) => return Err(datadog::Error::Serde(e)), + }; + } else { + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + + /// Cancel a threat hunting job. + pub async fn cancel_threat_hunting_job( + &self, + job_id: String, + ) -> Result<(), datadog::Error> { + match self.cancel_threat_hunting_job_with_http_info(job_id).await { + Ok(_) => Ok(()), + Err(err) => Err(err), + } + } + + /// Cancel a threat hunting job. + pub async fn cancel_threat_hunting_job_with_http_info( + &self, + job_id: String, + ) -> Result, datadog::Error> { + let local_configuration = &self.config; + let operation_id = "v2.cancel_threat_hunting_job"; + if local_configuration.is_unstable_operation_enabled(operation_id) { + warn!("Using unstable operation {operation_id}"); + } else { + let local_error = datadog::UnstableOperationDisabledError { + msg: "Operation 'v2.cancel_threat_hunting_job' is not enabled".to_string(), + }; + return Err(datadog::Error::UnstableOperationDisabledError(local_error)); + } + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/siem-threat-hunting/jobs/{job_id}/cancel", + local_configuration.get_operation_host(operation_id), + job_id = datadog::urlencode(job_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::PATCH, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Accept", HeaderValue::from_static("*/*")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: None, + }) + } else { + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + + /// Convert an existing rule from JSON to Terraform for Datadog provider + /// resource `datadog_security_monitoring_rule`. You can do so for the following rule types: + /// - App and API Protection + /// - Cloud SIEM (log detection and signal correlation) + /// - Workload Protection + /// + /// You can convert Cloud Security configuration rules using Terraform's [Datadog Cloud Configuration Rule resource](). + pub async fn convert_existing_security_monitoring_rule( + &self, + rule_id: String, + ) -> Result< + crate::datadogV2::model::SecurityMonitoringRuleConvertResponse, + datadog::Error, + > { + match self + .convert_existing_security_monitoring_rule_with_http_info(rule_id) + .await + { + Ok(response_content) => { + if let Some(e) = response_content.entity { + Ok(e) + } else { + Err(datadog::Error::Serde(serde::de::Error::custom( + "response content was None", + ))) + } + } + Err(err) => Err(err), + } + } + + /// Convert an existing rule from JSON to Terraform for Datadog provider + /// resource `datadog_security_monitoring_rule`. You can do so for the following rule types: + /// - App and API Protection + /// - Cloud SIEM (log detection and signal correlation) + /// - Workload Protection + /// + /// You can convert Cloud Security configuration rules using Terraform's [Datadog Cloud Configuration Rule resource](). + pub async fn convert_existing_security_monitoring_rule_with_http_info( + &self, + rule_id: String, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.convert_existing_security_monitoring_rule"; + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/security_monitoring/rules/{rule_id}/convert", + local_configuration.get_operation_host(operation_id), + rule_id = datadog::urlencode(rule_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::GET, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Accept", HeaderValue::from_static("application/json")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + match serde_json::from_str::< + crate::datadogV2::model::SecurityMonitoringRuleConvertResponse, + >(&local_content) + { + Ok(e) => { + return Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: Some(e), + }) + } + Err(e) => return Err(datadog::Error::Serde(e)), + }; + } else { + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + + /// Convert a job result to a signal. + pub async fn convert_job_result_to_signal( + &self, + body: crate::datadogV2::model::ConvertJobResultsToSignalsRequest, + ) -> Result<(), datadog::Error> { + match self.convert_job_result_to_signal_with_http_info(body).await { + Ok(_) => Ok(()), + Err(err) => Err(err), + } + } + + /// Convert a job result to a signal. + pub async fn convert_job_result_to_signal_with_http_info( + &self, + body: crate::datadogV2::model::ConvertJobResultsToSignalsRequest, + ) -> Result, datadog::Error> { + let local_configuration = &self.config; + let operation_id = "v2.convert_job_result_to_signal"; + if local_configuration.is_unstable_operation_enabled(operation_id) { + warn!("Using unstable operation {operation_id}"); + } else { + let local_error = datadog::UnstableOperationDisabledError { + msg: "Operation 'v2.convert_job_result_to_signal' is not enabled".to_string(), + }; + return Err(datadog::Error::UnstableOperationDisabledError(local_error)); + } + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/siem-threat-hunting/jobs/signal_convert", + local_configuration.get_operation_host(operation_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::POST, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Content-Type", HeaderValue::from_static("application/json")); + headers.insert("Accept", HeaderValue::from_static("*/*")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + // build body parameters + let output = Vec::new(); + let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter); + if body.serialize(&mut ser).is_ok() { + if let Some(content_encoding) = headers.get("Content-Encoding") { + match content_encoding.to_str().unwrap_or_default() { + "gzip" => { + let mut enc = GzEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "deflate" => { + let mut enc = ZlibEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "zstd1" => { + let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap(); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + _ => { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + } else { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: None, + }) + } else { + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + + /// Convert a rule that doesn't (yet) exist from JSON to Terraform for Datadog provider + /// resource `datadog_security_monitoring_rule`. You can do so for the following rule types: + /// - App and API Protection + /// - Cloud SIEM (log detection and signal correlation) + /// - Workload Protection + /// + /// You can convert Cloud Security configuration rules using Terraform's [Datadog Cloud Configuration Rule resource](). + pub async fn convert_security_monitoring_rule_from_json_to_terraform( + &self, + body: crate::datadogV2::model::SecurityMonitoringRuleConvertPayload, + ) -> Result< + crate::datadogV2::model::SecurityMonitoringRuleConvertResponse, + datadog::Error, + > { + match self + .convert_security_monitoring_rule_from_json_to_terraform_with_http_info(body) + .await + { + Ok(response_content) => { + if let Some(e) = response_content.entity { + Ok(e) + } else { + Err(datadog::Error::Serde(serde::de::Error::custom( + "response content was None", + ))) + } + } + Err(err) => Err(err), + } + } + + /// Convert a rule that doesn't (yet) exist from JSON to Terraform for Datadog provider + /// resource `datadog_security_monitoring_rule`. You can do so for the following rule types: + /// - App and API Protection + /// - Cloud SIEM (log detection and signal correlation) + /// - Workload Protection + /// + /// You can convert Cloud Security configuration rules using Terraform's [Datadog Cloud Configuration Rule resource](). + pub async fn convert_security_monitoring_rule_from_json_to_terraform_with_http_info( + &self, + body: crate::datadogV2::model::SecurityMonitoringRuleConvertPayload, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.convert_security_monitoring_rule_from_json_to_terraform"; + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/security_monitoring/rules/convert", + local_configuration.get_operation_host(operation_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::POST, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Content-Type", HeaderValue::from_static("application/json")); + headers.insert("Accept", HeaderValue::from_static("application/json")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + // build body parameters + let output = Vec::new(); + let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter); + if body.serialize(&mut ser).is_ok() { + if let Some(content_encoding) = headers.get("Content-Encoding") { + match content_encoding.to_str().unwrap_or_default() { + "gzip" => { + let mut enc = GzEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "deflate" => { + let mut enc = ZlibEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "zstd1" => { + let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap(); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + _ => { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + } else { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + local_req_builder = local_req_builder.headers(headers); let local_req = local_req_builder.build()?; log::debug!("request content: {:?}", local_req.body()); @@ -1857,7 +2513,7 @@ impl SecurityMonitoringAPI { Err(e) => return Err(datadog::Error::Serde(e)), }; } else { - let local_entity: Option = + let local_entity: Option = serde_json::from_str(&local_content).ok(); let local_error = datadog::ResponseContent { status: local_status, @@ -1868,37 +2524,41 @@ impl SecurityMonitoringAPI { } } - /// Convert a job result to a signal. - pub async fn convert_job_result_to_signal( + /// Create cases for security findings. You can create up to 50 cases per request and associate up to 50 security findings per case. Security findings that are already attached to another case will be detached from their previous case and attached to the newly created case. + pub async fn create_cases( &self, - body: crate::datadogV2::model::ConvertJobResultsToSignalsRequest, - ) -> Result<(), datadog::Error> { - match self.convert_job_result_to_signal_with_http_info(body).await { - Ok(_) => Ok(()), + body: crate::datadogV2::model::CreateCaseRequestArray, + ) -> Result> + { + match self.create_cases_with_http_info(body).await { + Ok(response_content) => { + if let Some(e) = response_content.entity { + Ok(e) + } else { + Err(datadog::Error::Serde(serde::de::Error::custom( + "response content was None", + ))) + } + } Err(err) => Err(err), } } - /// Convert a job result to a signal. - pub async fn convert_job_result_to_signal_with_http_info( + /// Create cases for security findings. You can create up to 50 cases per request and associate up to 50 security findings per case. Security findings that are already attached to another case will be detached from their previous case and attached to the newly created case. + pub async fn create_cases_with_http_info( &self, - body: crate::datadogV2::model::ConvertJobResultsToSignalsRequest, - ) -> Result, datadog::Error> { + body: crate::datadogV2::model::CreateCaseRequestArray, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { let local_configuration = &self.config; - let operation_id = "v2.convert_job_result_to_signal"; - if local_configuration.is_unstable_operation_enabled(operation_id) { - warn!("Using unstable operation {operation_id}"); - } else { - let local_error = datadog::UnstableOperationDisabledError { - msg: "Operation 'v2.convert_job_result_to_signal' is not enabled".to_string(), - }; - return Err(datadog::Error::UnstableOperationDisabledError(local_error)); - } + let operation_id = "v2.create_cases"; let local_client = &self.client; let local_uri_str = format!( - "{}/api/v2/siem-threat-hunting/jobs/signal_convert", + "{}/api/v2/security/findings/cases", local_configuration.get_operation_host(operation_id) ); let mut local_req_builder = @@ -1907,7 +2567,7 @@ impl SecurityMonitoringAPI { // build headers let mut headers = HeaderMap::new(); headers.insert("Content-Type", HeaderValue::from_static("application/json")); - headers.insert("Accept", HeaderValue::from_static("*/*")); + headers.insert("Accept", HeaderValue::from_static("application/json")); // build user agent match HeaderValue::from_str(local_configuration.user_agent.as_str()) { @@ -1992,14 +2652,20 @@ impl SecurityMonitoringAPI { log::debug!("response content: {}", local_content); if !local_status.is_client_error() && !local_status.is_server_error() { - Ok(datadog::ResponseContent { - status: local_status, - content: local_content, - entity: None, - }) + match serde_json::from_str::( + &local_content, + ) { + Ok(e) => { + return Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: Some(e), + }) + } + Err(e) => return Err(datadog::Error::Serde(e)), + }; } else { - let local_entity: Option = - serde_json::from_str(&local_content).ok(); + let local_entity: Option = serde_json::from_str(&local_content).ok(); let local_error = datadog::ResponseContent { status: local_status, content: local_content, @@ -2009,24 +2675,15 @@ impl SecurityMonitoringAPI { } } - /// Convert a rule that doesn't (yet) exist from JSON to Terraform for Datadog provider - /// resource `datadog_security_monitoring_rule`. You can do so for the following rule types: - /// - App and API Protection - /// - Cloud SIEM (log detection and signal correlation) - /// - Workload Protection - /// - /// You can convert Cloud Security configuration rules using Terraform's [Datadog Cloud Configuration Rule resource](). - pub async fn convert_security_monitoring_rule_from_json_to_terraform( + /// Create a custom framework. + pub async fn create_custom_framework( &self, - body: crate::datadogV2::model::SecurityMonitoringRuleConvertPayload, + body: crate::datadogV2::model::CreateCustomFrameworkRequest, ) -> Result< - crate::datadogV2::model::SecurityMonitoringRuleConvertResponse, - datadog::Error, + crate::datadogV2::model::CreateCustomFrameworkResponse, + datadog::Error, > { - match self - .convert_security_monitoring_rule_from_json_to_terraform_with_http_info(body) - .await - { + match self.create_custom_framework_with_http_info(body).await { Ok(response_content) => { if let Some(e) = response_content.entity { Ok(e) @@ -2040,27 +2697,21 @@ impl SecurityMonitoringAPI { } } - /// Convert a rule that doesn't (yet) exist from JSON to Terraform for Datadog provider - /// resource `datadog_security_monitoring_rule`. You can do so for the following rule types: - /// - App and API Protection - /// - Cloud SIEM (log detection and signal correlation) - /// - Workload Protection - /// - /// You can convert Cloud Security configuration rules using Terraform's [Datadog Cloud Configuration Rule resource](). - pub async fn convert_security_monitoring_rule_from_json_to_terraform_with_http_info( + /// Create a custom framework. + pub async fn create_custom_framework_with_http_info( &self, - body: crate::datadogV2::model::SecurityMonitoringRuleConvertPayload, + body: crate::datadogV2::model::CreateCustomFrameworkRequest, ) -> Result< - datadog::ResponseContent, - datadog::Error, + datadog::ResponseContent, + datadog::Error, > { let local_configuration = &self.config; - let operation_id = "v2.convert_security_monitoring_rule_from_json_to_terraform"; + let operation_id = "v2.create_custom_framework"; let local_client = &self.client; let local_uri_str = format!( - "{}/api/v2/security_monitoring/rules/convert", + "{}/api/v2/cloud_security_management/custom_frameworks", local_configuration.get_operation_host(operation_id) ); let mut local_req_builder = @@ -2154,10 +2805,9 @@ impl SecurityMonitoringAPI { log::debug!("response content: {}", local_content); if !local_status.is_client_error() && !local_status.is_server_error() { - match serde_json::from_str::< - crate::datadogV2::model::SecurityMonitoringRuleConvertResponse, - >(&local_content) - { + match serde_json::from_str::( + &local_content, + ) { Ok(e) => { return Ok(datadog::ResponseContent { status: local_status, @@ -2168,7 +2818,7 @@ impl SecurityMonitoringAPI { Err(e) => return Err(datadog::Error::Serde(e)), }; } else { - let local_entity: Option = + let local_entity: Option = serde_json::from_str(&local_content).ok(); let local_error = datadog::ResponseContent { status: local_status, @@ -2179,15 +2829,15 @@ impl SecurityMonitoringAPI { } } - /// Create a custom framework. - pub async fn create_custom_framework( + /// Create Jira issues for security findings. This operation creates a case in Datadog and a Jira issue linked to that case for bidirectional sync between Datadog and Jira. You can create up to 50 Jira issues per request and associate up to 50 security findings per Jira issue. Security findings that are already attached to another Jira issue will be detached from their previous Jira issue and attached to the newly created Jira issue. + pub async fn create_jira_issues( &self, - body: crate::datadogV2::model::CreateCustomFrameworkRequest, + body: crate::datadogV2::model::CreateJiraIssueRequestArray, ) -> Result< - crate::datadogV2::model::CreateCustomFrameworkResponse, - datadog::Error, + crate::datadogV2::model::FindingCaseResponseArray, + datadog::Error, > { - match self.create_custom_framework_with_http_info(body).await { + match self.create_jira_issues_with_http_info(body).await { Ok(response_content) => { if let Some(e) = response_content.entity { Ok(e) @@ -2201,21 +2851,21 @@ impl SecurityMonitoringAPI { } } - /// Create a custom framework. - pub async fn create_custom_framework_with_http_info( + /// Create Jira issues for security findings. This operation creates a case in Datadog and a Jira issue linked to that case for bidirectional sync between Datadog and Jira. You can create up to 50 Jira issues per request and associate up to 50 security findings per Jira issue. Security findings that are already attached to another Jira issue will be detached from their previous Jira issue and attached to the newly created Jira issue. + pub async fn create_jira_issues_with_http_info( &self, - body: crate::datadogV2::model::CreateCustomFrameworkRequest, + body: crate::datadogV2::model::CreateJiraIssueRequestArray, ) -> Result< - datadog::ResponseContent, - datadog::Error, + datadog::ResponseContent, + datadog::Error, > { let local_configuration = &self.config; - let operation_id = "v2.create_custom_framework"; + let operation_id = "v2.create_jira_issues"; let local_client = &self.client; let local_uri_str = format!( - "{}/api/v2/cloud_security_management/custom_frameworks", + "{}/api/v2/security/findings/jira_issues", local_configuration.get_operation_host(operation_id) ); let mut local_req_builder = @@ -2309,7 +2959,7 @@ impl SecurityMonitoringAPI { log::debug!("response content: {}", local_content); if !local_status.is_client_error() && !local_status.is_server_error() { - match serde_json::from_str::( + match serde_json::from_str::( &local_content, ) { Ok(e) => { @@ -2322,7 +2972,7 @@ impl SecurityMonitoringAPI { Err(e) => return Err(datadog::Error::Serde(e)), }; } else { - let local_entity: Option = + let local_entity: Option = serde_json::from_str(&local_content).ok(); let local_error = datadog::ResponseContent { status: local_status, @@ -3796,6 +4446,138 @@ impl SecurityMonitoringAPI { } } + /// Detach security findings from their case. This operation dissociates security findings from their associated cases without deleting the cases themselves. You can detach security findings from multiple different cases in a single request, with a limit of 50 security findings per request. Security findings that are not currently attached to any case will be ignored. + pub async fn detach_case( + &self, + body: crate::datadogV2::model::DetachCaseRequest, + ) -> Result<(), datadog::Error> { + match self.detach_case_with_http_info(body).await { + Ok(_) => Ok(()), + Err(err) => Err(err), + } + } + + /// Detach security findings from their case. This operation dissociates security findings from their associated cases without deleting the cases themselves. You can detach security findings from multiple different cases in a single request, with a limit of 50 security findings per request. Security findings that are not currently attached to any case will be ignored. + pub async fn detach_case_with_http_info( + &self, + body: crate::datadogV2::model::DetachCaseRequest, + ) -> Result, datadog::Error> { + let local_configuration = &self.config; + let operation_id = "v2.detach_case"; + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/security/findings/cases", + local_configuration.get_operation_host(operation_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::DELETE, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Content-Type", HeaderValue::from_static("application/json")); + headers.insert("Accept", HeaderValue::from_static("*/*")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + // build body parameters + let output = Vec::new(); + let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter); + if body.serialize(&mut ser).is_ok() { + if let Some(content_encoding) = headers.get("Content-Encoding") { + match content_encoding.to_str().unwrap_or_default() { + "gzip" => { + let mut enc = GzEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "deflate" => { + let mut enc = ZlibEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "zstd1" => { + let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap(); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + _ => { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + } else { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: None, + }) + } else { + let local_entity: Option = serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + /// Modify the triage assignee of a security signal. pub async fn edit_security_monitoring_signal_assignee( &self, diff --git a/src/datadogV2/model/mod.rs b/src/datadogV2/model/mod.rs index a95f0e302..af304d956 100644 --- a/src/datadogV2/model/mod.rs +++ b/src/datadogV2/model/mod.rs @@ -5616,6 +5616,82 @@ pub mod model_update_rule_response; pub use self::model_update_rule_response::UpdateRuleResponse; pub mod model_update_rule_response_data; pub use self::model_update_rule_response_data::UpdateRuleResponseData; +pub mod model_detach_case_request; +pub use self::model_detach_case_request::DetachCaseRequest; +pub mod model_detach_case_request_data; +pub use self::model_detach_case_request_data::DetachCaseRequestData; +pub mod model_detach_case_request_data_relationships; +pub use self::model_detach_case_request_data_relationships::DetachCaseRequestDataRelationships; +pub mod model_findings; +pub use self::model_findings::Findings; +pub mod model_finding_data; +pub use self::model_finding_data::FindingData; +pub mod model_finding_data_type; +pub use self::model_finding_data_type::FindingDataType; +pub mod model_case_data_type; +pub use self::model_case_data_type::CaseDataType; +pub mod model_create_case_request_array; +pub use self::model_create_case_request_array::CreateCaseRequestArray; +pub mod model_create_case_request_data; +pub use self::model_create_case_request_data::CreateCaseRequestData; +pub mod model_create_case_request_data_attributes; +pub use self::model_create_case_request_data_attributes::CreateCaseRequestDataAttributes; +pub mod model_create_case_request_data_relationships; +pub use self::model_create_case_request_data_relationships::CreateCaseRequestDataRelationships; +pub mod model_case_management_project; +pub use self::model_case_management_project::CaseManagementProject; +pub mod model_case_management_project_data; +pub use self::model_case_management_project_data::CaseManagementProjectData; +pub mod model_case_management_project_data_type; +pub use self::model_case_management_project_data_type::CaseManagementProjectDataType; +pub mod model_finding_case_response_array; +pub use self::model_finding_case_response_array::FindingCaseResponseArray; +pub mod model_finding_case_response_data; +pub use self::model_finding_case_response_data::FindingCaseResponseData; +pub mod model_finding_case_response_data_attributes; +pub use self::model_finding_case_response_data_attributes::FindingCaseResponseDataAttributes; +pub mod model_case_insights_items; +pub use self::model_case_insights_items::CaseInsightsItems; +pub mod model_finding_jira_issue; +pub use self::model_finding_jira_issue::FindingJiraIssue; +pub mod model_finding_jira_issue_result; +pub use self::model_finding_jira_issue_result::FindingJiraIssueResult; +pub mod model_finding_case_response_data_relationships; +pub use self::model_finding_case_response_data_relationships::FindingCaseResponseDataRelationships; +pub mod model_attach_case_request; +pub use self::model_attach_case_request::AttachCaseRequest; +pub mod model_attach_case_request_data; +pub use self::model_attach_case_request_data::AttachCaseRequestData; +pub mod model_attach_case_request_data_relationships; +pub use self::model_attach_case_request_data_relationships::AttachCaseRequestDataRelationships; +pub mod model_finding_case_response; +pub use self::model_finding_case_response::FindingCaseResponse; +pub mod model_attach_jira_issue_request; +pub use self::model_attach_jira_issue_request::AttachJiraIssueRequest; +pub mod model_attach_jira_issue_request_data; +pub use self::model_attach_jira_issue_request_data::AttachJiraIssueRequestData; +pub mod model_attach_jira_issue_request_data_attributes; +pub use self::model_attach_jira_issue_request_data_attributes::AttachJiraIssueRequestDataAttributes; +pub mod model_attach_jira_issue_request_data_relationships; +pub use self::model_attach_jira_issue_request_data_relationships::AttachJiraIssueRequestDataRelationships; +pub mod model_jira_issues_data_type; +pub use self::model_jira_issues_data_type::JiraIssuesDataType; +pub mod model_create_jira_issue_request_array; +pub use self::model_create_jira_issue_request_array::CreateJiraIssueRequestArray; +pub mod model_create_jira_issue_request_data; +pub use self::model_create_jira_issue_request_data::CreateJiraIssueRequestData; +pub mod model_create_jira_issue_request_data_attributes; +pub use self::model_create_jira_issue_request_data_attributes::CreateJiraIssueRequestDataAttributes; +pub mod model_create_jira_issue_request_data_attributes_fields; +pub use self::model_create_jira_issue_request_data_attributes_fields::CreateJiraIssueRequestDataAttributesFields; +pub mod model_create_jira_issue_request_data_relationships; +pub use self::model_create_jira_issue_request_data_relationships::CreateJiraIssueRequestDataRelationships; +pub mod model_create_jira_issue_request_data_relationships_case; +pub use self::model_create_jira_issue_request_data_relationships_case::CreateJiraIssueRequestDataRelationshipsCase; +pub mod model_create_jira_issue_request_data_relationships_case_data; +pub use self::model_create_jira_issue_request_data_relationships_case_data::CreateJiraIssueRequestDataRelationshipsCaseData; +pub mod model_create_jira_issue_request_array_included; +pub use self::model_create_jira_issue_request_array_included::CreateJiraIssueRequestArrayIncluded; pub mod model_asset_type; pub use self::model_asset_type::AssetType; pub mod model_sbom_component_license_type; diff --git a/src/datadogV2/model/model_attach_case_request.rs b/src/datadogV2/model/model_attach_case_request.rs new file mode 100644 index 000000000..e646a706e --- /dev/null +++ b/src/datadogV2/model/model_attach_case_request.rs @@ -0,0 +1,105 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Request for attaching security findings to a case. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct AttachCaseRequest { + /// Data of the case to attach security findings to. + #[serde(rename = "data")] + pub data: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl AttachCaseRequest { + pub fn new() -> AttachCaseRequest { + AttachCaseRequest { + data: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn data(mut self, value: crate::datadogV2::model::AttachCaseRequestData) -> Self { + self.data = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for AttachCaseRequest { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for AttachCaseRequest { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct AttachCaseRequestVisitor; + impl<'a> Visitor<'a> for AttachCaseRequestVisitor { + type Value = AttachCaseRequest; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + if v.is_null() { + continue; + } + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = AttachCaseRequest { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(AttachCaseRequestVisitor) + } +} diff --git a/src/datadogV2/model/model_attach_case_request_data.rs b/src/datadogV2/model/model_attach_case_request_data.rs new file mode 100644 index 000000000..ad318c62e --- /dev/null +++ b/src/datadogV2/model/model_attach_case_request_data.rs @@ -0,0 +1,135 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Data of the case to attach security findings to. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct AttachCaseRequestData { + /// The unique identifier of the case. + #[serde(rename = "id")] + pub id: String, + /// Relationships of the case to attach security findings to. + #[serde(rename = "relationships")] + pub relationships: Option, + /// Cases resource type. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::CaseDataType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl AttachCaseRequestData { + pub fn new(id: String, type_: crate::datadogV2::model::CaseDataType) -> AttachCaseRequestData { + AttachCaseRequestData { + id, + relationships: None, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn relationships( + mut self, + value: crate::datadogV2::model::AttachCaseRequestDataRelationships, + ) -> Self { + self.relationships = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for AttachCaseRequestData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct AttachCaseRequestDataVisitor; + impl<'a> Visitor<'a> for AttachCaseRequestDataVisitor { + type Value = AttachCaseRequestData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut id: Option = None; + let mut relationships: Option< + crate::datadogV2::model::AttachCaseRequestDataRelationships, + > = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "id" => { + id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "relationships" => { + if v.is_null() { + continue; + } + relationships = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::CaseDataType::UnparsedObject( + _type_, + ) => { + _unparsed = true; + } + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let id = id.ok_or_else(|| M::Error::missing_field("id"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = AttachCaseRequestData { + id, + relationships, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(AttachCaseRequestDataVisitor) + } +} diff --git a/src/datadogV2/model/model_attach_case_request_data_relationships.rs b/src/datadogV2/model/model_attach_case_request_data_relationships.rs new file mode 100644 index 000000000..c6e437990 --- /dev/null +++ b/src/datadogV2/model/model_attach_case_request_data_relationships.rs @@ -0,0 +1,92 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Relationships of the case to attach security findings to. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct AttachCaseRequestDataRelationships { + /// A list of security findings. + #[serde(rename = "findings")] + pub findings: crate::datadogV2::model::Findings, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl AttachCaseRequestDataRelationships { + pub fn new(findings: crate::datadogV2::model::Findings) -> AttachCaseRequestDataRelationships { + AttachCaseRequestDataRelationships { + findings, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for AttachCaseRequestDataRelationships { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct AttachCaseRequestDataRelationshipsVisitor; + impl<'a> Visitor<'a> for AttachCaseRequestDataRelationshipsVisitor { + type Value = AttachCaseRequestDataRelationships; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut findings: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "findings" => { + findings = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let findings = findings.ok_or_else(|| M::Error::missing_field("findings"))?; + + let content = AttachCaseRequestDataRelationships { + findings, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(AttachCaseRequestDataRelationshipsVisitor) + } +} diff --git a/src/datadogV2/model/model_attach_jira_issue_request.rs b/src/datadogV2/model/model_attach_jira_issue_request.rs new file mode 100644 index 000000000..247d9c514 --- /dev/null +++ b/src/datadogV2/model/model_attach_jira_issue_request.rs @@ -0,0 +1,105 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Request for attaching security findings to a Jira issue. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct AttachJiraIssueRequest { + /// Data of the Jira issue to attach security findings to. + #[serde(rename = "data")] + pub data: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl AttachJiraIssueRequest { + pub fn new() -> AttachJiraIssueRequest { + AttachJiraIssueRequest { + data: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn data(mut self, value: crate::datadogV2::model::AttachJiraIssueRequestData) -> Self { + self.data = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for AttachJiraIssueRequest { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for AttachJiraIssueRequest { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct AttachJiraIssueRequestVisitor; + impl<'a> Visitor<'a> for AttachJiraIssueRequestVisitor { + type Value = AttachJiraIssueRequest; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + if v.is_null() { + continue; + } + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = AttachJiraIssueRequest { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(AttachJiraIssueRequestVisitor) + } +} diff --git a/src/datadogV2/model/model_attach_jira_issue_request_data.rs b/src/datadogV2/model/model_attach_jira_issue_request_data.rs new file mode 100644 index 000000000..d00231ab4 --- /dev/null +++ b/src/datadogV2/model/model_attach_jira_issue_request_data.rs @@ -0,0 +1,164 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Data of the Jira issue to attach security findings to. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct AttachJiraIssueRequestData { + /// Attributes of the Jira issue to attach security findings to. + #[serde(rename = "attributes")] + pub attributes: Option, + /// The unique identifier of the Jira issue attachment request. + #[serde(rename = "id")] + pub id: Option, + /// Relationships of the Jira issue to attach security findings to. + #[serde(rename = "relationships")] + pub relationships: Option, + /// Jira issues resource type. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::JiraIssuesDataType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl AttachJiraIssueRequestData { + pub fn new(type_: crate::datadogV2::model::JiraIssuesDataType) -> AttachJiraIssueRequestData { + AttachJiraIssueRequestData { + attributes: None, + id: None, + relationships: None, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn attributes( + mut self, + value: crate::datadogV2::model::AttachJiraIssueRequestDataAttributes, + ) -> Self { + self.attributes = Some(value); + self + } + + pub fn id(mut self, value: String) -> Self { + self.id = Some(value); + self + } + + pub fn relationships( + mut self, + value: crate::datadogV2::model::AttachJiraIssueRequestDataRelationships, + ) -> Self { + self.relationships = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for AttachJiraIssueRequestData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct AttachJiraIssueRequestDataVisitor; + impl<'a> Visitor<'a> for AttachJiraIssueRequestDataVisitor { + type Value = AttachJiraIssueRequestData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut attributes: Option< + crate::datadogV2::model::AttachJiraIssueRequestDataAttributes, + > = None; + let mut id: Option = None; + let mut relationships: Option< + crate::datadogV2::model::AttachJiraIssueRequestDataRelationships, + > = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "attributes" => { + if v.is_null() { + continue; + } + attributes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "id" => { + if v.is_null() { + continue; + } + id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "relationships" => { + if v.is_null() { + continue; + } + relationships = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::JiraIssuesDataType::UnparsedObject( + _type_, + ) => { + _unparsed = true; + } + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = AttachJiraIssueRequestData { + attributes, + id, + relationships, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(AttachJiraIssueRequestDataVisitor) + } +} diff --git a/src/datadogV2/model/model_attach_jira_issue_request_data_attributes.rs b/src/datadogV2/model/model_attach_jira_issue_request_data_attributes.rs new file mode 100644 index 000000000..ec5b23fba --- /dev/null +++ b/src/datadogV2/model/model_attach_jira_issue_request_data_attributes.rs @@ -0,0 +1,94 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Attributes of the Jira issue to attach security findings to. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct AttachJiraIssueRequestDataAttributes { + /// The URL of the Jira issue to attach security findings to. + #[serde(rename = "jira_issue_url")] + pub jira_issue_url: String, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl AttachJiraIssueRequestDataAttributes { + pub fn new(jira_issue_url: String) -> AttachJiraIssueRequestDataAttributes { + AttachJiraIssueRequestDataAttributes { + jira_issue_url, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for AttachJiraIssueRequestDataAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct AttachJiraIssueRequestDataAttributesVisitor; + impl<'a> Visitor<'a> for AttachJiraIssueRequestDataAttributesVisitor { + type Value = AttachJiraIssueRequestDataAttributes; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut jira_issue_url: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "jira_issue_url" => { + jira_issue_url = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let jira_issue_url = + jira_issue_url.ok_or_else(|| M::Error::missing_field("jira_issue_url"))?; + + let content = AttachJiraIssueRequestDataAttributes { + jira_issue_url, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(AttachJiraIssueRequestDataAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_attach_jira_issue_request_data_relationships.rs b/src/datadogV2/model/model_attach_jira_issue_request_data_relationships.rs new file mode 100644 index 000000000..991f4ab5a --- /dev/null +++ b/src/datadogV2/model/model_attach_jira_issue_request_data_relationships.rs @@ -0,0 +1,105 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Relationships of the Jira issue to attach security findings to. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct AttachJiraIssueRequestDataRelationships { + /// A list of security findings. + #[serde(rename = "findings")] + pub findings: crate::datadogV2::model::Findings, + /// Case management project. + #[serde(rename = "project")] + pub project: crate::datadogV2::model::CaseManagementProject, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl AttachJiraIssueRequestDataRelationships { + pub fn new( + findings: crate::datadogV2::model::Findings, + project: crate::datadogV2::model::CaseManagementProject, + ) -> AttachJiraIssueRequestDataRelationships { + AttachJiraIssueRequestDataRelationships { + findings, + project, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for AttachJiraIssueRequestDataRelationships { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct AttachJiraIssueRequestDataRelationshipsVisitor; + impl<'a> Visitor<'a> for AttachJiraIssueRequestDataRelationshipsVisitor { + type Value = AttachJiraIssueRequestDataRelationships; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut findings: Option = None; + let mut project: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "findings" => { + findings = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "project" => { + project = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let findings = findings.ok_or_else(|| M::Error::missing_field("findings"))?; + let project = project.ok_or_else(|| M::Error::missing_field("project"))?; + + let content = AttachJiraIssueRequestDataRelationships { + findings, + project, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(AttachJiraIssueRequestDataRelationshipsVisitor) + } +} diff --git a/src/datadogV2/model/model_case_data_type.rs b/src/datadogV2/model/model_case_data_type.rs new file mode 100644 index 000000000..837f01619 --- /dev/null +++ b/src/datadogV2/model/model_case_data_type.rs @@ -0,0 +1,48 @@ +// 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. + +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +#[non_exhaustive] +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum CaseDataType { + CASES, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for CaseDataType { + fn to_string(&self) -> String { + match self { + Self::CASES => String::from("cases"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for CaseDataType { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Self::UnparsedObject(v) => v.serialize(serializer), + _ => serializer.serialize_str(self.to_string().as_str()), + } + } +} + +impl<'de> Deserialize<'de> for CaseDataType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "cases" => Self::CASES, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/src/datadogV2/model/model_case_insights_items.rs b/src/datadogV2/model/model_case_insights_items.rs new file mode 100644 index 000000000..0b68011ab --- /dev/null +++ b/src/datadogV2/model/model_case_insights_items.rs @@ -0,0 +1,140 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// An insight of the case. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct CaseInsightsItems { + /// The reference of the insight. + #[serde(rename = "ref")] + pub ref_: Option, + /// The unique identifier of the resource. For example, the unique identifier of a security finding. + #[serde(rename = "resource_id")] + pub resource_id: Option, + /// The type of the resource. For example, the type of a security finding is "SECURITY_FINDING". + #[serde(rename = "type")] + pub type_: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl CaseInsightsItems { + pub fn new() -> CaseInsightsItems { + CaseInsightsItems { + ref_: None, + resource_id: None, + type_: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn ref_(mut self, value: String) -> Self { + self.ref_ = Some(value); + self + } + + pub fn resource_id(mut self, value: String) -> Self { + self.resource_id = Some(value); + self + } + + pub fn type_(mut self, value: String) -> Self { + self.type_ = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for CaseInsightsItems { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for CaseInsightsItems { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct CaseInsightsItemsVisitor; + impl<'a> Visitor<'a> for CaseInsightsItemsVisitor { + type Value = CaseInsightsItems; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut ref_: Option = None; + let mut resource_id: Option = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "ref" => { + if v.is_null() { + continue; + } + ref_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "resource_id" => { + if v.is_null() { + continue; + } + resource_id = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + if v.is_null() { + continue; + } + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = CaseInsightsItems { + ref_, + resource_id, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(CaseInsightsItemsVisitor) + } +} diff --git a/src/datadogV2/model/model_case_management_project.rs b/src/datadogV2/model/model_case_management_project.rs new file mode 100644 index 000000000..eab8f2f87 --- /dev/null +++ b/src/datadogV2/model/model_case_management_project.rs @@ -0,0 +1,91 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Case management project. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct CaseManagementProject { + #[serde(rename = "data")] + pub data: crate::datadogV2::model::CaseManagementProjectData, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl CaseManagementProject { + pub fn new(data: crate::datadogV2::model::CaseManagementProjectData) -> CaseManagementProject { + CaseManagementProject { + data, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for CaseManagementProject { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct CaseManagementProjectVisitor; + impl<'a> Visitor<'a> for CaseManagementProjectVisitor { + type Value = CaseManagementProject; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let data = data.ok_or_else(|| M::Error::missing_field("data"))?; + + let content = CaseManagementProject { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(CaseManagementProjectVisitor) + } +} diff --git a/src/datadogV2/model/model_case_management_project_data.rs b/src/datadogV2/model/model_case_management_project_data.rs new file mode 100644 index 000000000..49aa7a5fc --- /dev/null +++ b/src/datadogV2/model/model_case_management_project_data.rs @@ -0,0 +1,113 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct CaseManagementProjectData { + /// The unique identifier of the case management project. + #[serde(rename = "id")] + pub id: String, + /// Projects resource type. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::CaseManagementProjectDataType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl CaseManagementProjectData { + pub fn new( + id: String, + type_: crate::datadogV2::model::CaseManagementProjectDataType, + ) -> CaseManagementProjectData { + CaseManagementProjectData { + id, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for CaseManagementProjectData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct CaseManagementProjectDataVisitor; + impl<'a> Visitor<'a> for CaseManagementProjectDataVisitor { + type Value = CaseManagementProjectData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut id: Option = None; + let mut type_: Option = + None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "id" => { + id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::CaseManagementProjectDataType::UnparsedObject(_type_) => { + _unparsed = true; + }, + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let id = id.ok_or_else(|| M::Error::missing_field("id"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = CaseManagementProjectData { + id, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(CaseManagementProjectDataVisitor) + } +} diff --git a/src/datadogV2/model/model_case_management_project_data_type.rs b/src/datadogV2/model/model_case_management_project_data_type.rs new file mode 100644 index 000000000..8c7844af7 --- /dev/null +++ b/src/datadogV2/model/model_case_management_project_data_type.rs @@ -0,0 +1,48 @@ +// 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. + +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +#[non_exhaustive] +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum CaseManagementProjectDataType { + PROJECTS, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for CaseManagementProjectDataType { + fn to_string(&self) -> String { + match self { + Self::PROJECTS => String::from("projects"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for CaseManagementProjectDataType { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Self::UnparsedObject(v) => v.serialize(serializer), + _ => serializer.serialize_str(self.to_string().as_str()), + } + } +} + +impl<'de> Deserialize<'de> for CaseManagementProjectDataType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "projects" => Self::PROJECTS, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/src/datadogV2/model/model_create_case_request_array.rs b/src/datadogV2/model/model_create_case_request_array.rs new file mode 100644 index 000000000..35a9fd9c7 --- /dev/null +++ b/src/datadogV2/model/model_create_case_request_array.rs @@ -0,0 +1,93 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// List of requests to create cases for security findings. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct CreateCaseRequestArray { + #[serde(rename = "data")] + pub data: Vec, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl CreateCaseRequestArray { + pub fn new( + data: Vec, + ) -> CreateCaseRequestArray { + CreateCaseRequestArray { + data, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for CreateCaseRequestArray { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct CreateCaseRequestArrayVisitor; + impl<'a> Visitor<'a> for CreateCaseRequestArrayVisitor { + type Value = CreateCaseRequestArray; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option> = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let data = data.ok_or_else(|| M::Error::missing_field("data"))?; + + let content = CreateCaseRequestArray { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(CreateCaseRequestArrayVisitor) + } +} diff --git a/src/datadogV2/model/model_create_case_request_data.rs b/src/datadogV2/model/model_create_case_request_data.rs new file mode 100644 index 000000000..84b6d65c4 --- /dev/null +++ b/src/datadogV2/model/model_create_case_request_data.rs @@ -0,0 +1,164 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Data of the case to create. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct CreateCaseRequestData { + /// Attributes of the case to create. + #[serde(rename = "attributes")] + pub attributes: Option, + /// The unique identifier of the case. + #[serde(rename = "id")] + pub id: Option, + /// Relationships of the case to create. + #[serde(rename = "relationships")] + pub relationships: Option, + /// Cases resource type. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::CaseDataType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl CreateCaseRequestData { + pub fn new(type_: crate::datadogV2::model::CaseDataType) -> CreateCaseRequestData { + CreateCaseRequestData { + attributes: None, + id: None, + relationships: None, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn attributes( + mut self, + value: crate::datadogV2::model::CreateCaseRequestDataAttributes, + ) -> Self { + self.attributes = Some(value); + self + } + + pub fn id(mut self, value: String) -> Self { + self.id = Some(value); + self + } + + pub fn relationships( + mut self, + value: crate::datadogV2::model::CreateCaseRequestDataRelationships, + ) -> Self { + self.relationships = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for CreateCaseRequestData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct CreateCaseRequestDataVisitor; + impl<'a> Visitor<'a> for CreateCaseRequestDataVisitor { + type Value = CreateCaseRequestData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut attributes: Option< + crate::datadogV2::model::CreateCaseRequestDataAttributes, + > = None; + let mut id: Option = None; + let mut relationships: Option< + crate::datadogV2::model::CreateCaseRequestDataRelationships, + > = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "attributes" => { + if v.is_null() { + continue; + } + attributes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "id" => { + if v.is_null() { + continue; + } + id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "relationships" => { + if v.is_null() { + continue; + } + relationships = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::CaseDataType::UnparsedObject( + _type_, + ) => { + _unparsed = true; + } + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = CreateCaseRequestData { + attributes, + id, + relationships, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(CreateCaseRequestDataVisitor) + } +} diff --git a/src/datadogV2/model/model_create_case_request_data_attributes.rs b/src/datadogV2/model/model_create_case_request_data_attributes.rs new file mode 100644 index 000000000..767e38200 --- /dev/null +++ b/src/datadogV2/model/model_create_case_request_data_attributes.rs @@ -0,0 +1,168 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Attributes of the case to create. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct CreateCaseRequestDataAttributes { + /// The unique identifier of the user assigned to the case. + #[serde(rename = "assignee_id")] + pub assignee_id: Option, + /// The description of the case. If not provided, the description will be automatically generated. + #[serde(rename = "description")] + pub description: Option, + /// Case priority + #[serde(rename = "priority")] + pub priority: Option, + /// The title of the case. If not provided, the title will be automatically generated. + #[serde(rename = "title")] + pub title: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl CreateCaseRequestDataAttributes { + pub fn new() -> CreateCaseRequestDataAttributes { + CreateCaseRequestDataAttributes { + assignee_id: None, + description: None, + priority: None, + title: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn assignee_id(mut self, value: String) -> Self { + self.assignee_id = Some(value); + self + } + + pub fn description(mut self, value: String) -> Self { + self.description = Some(value); + self + } + + pub fn priority(mut self, value: crate::datadogV2::model::CasePriority) -> Self { + self.priority = Some(value); + self + } + + pub fn title(mut self, value: String) -> Self { + self.title = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for CreateCaseRequestDataAttributes { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for CreateCaseRequestDataAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct CreateCaseRequestDataAttributesVisitor; + impl<'a> Visitor<'a> for CreateCaseRequestDataAttributesVisitor { + type Value = CreateCaseRequestDataAttributes; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut assignee_id: Option = None; + let mut description: Option = None; + let mut priority: Option = None; + let mut title: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "assignee_id" => { + if v.is_null() { + continue; + } + assignee_id = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "description" => { + if v.is_null() { + continue; + } + description = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "priority" => { + if v.is_null() { + continue; + } + priority = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _priority) = priority { + match _priority { + crate::datadogV2::model::CasePriority::UnparsedObject( + _priority, + ) => { + _unparsed = true; + } + _ => {} + } + } + } + "title" => { + if v.is_null() { + continue; + } + title = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = CreateCaseRequestDataAttributes { + assignee_id, + description, + priority, + title, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(CreateCaseRequestDataAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_create_case_request_data_relationships.rs b/src/datadogV2/model/model_create_case_request_data_relationships.rs new file mode 100644 index 000000000..805f81f14 --- /dev/null +++ b/src/datadogV2/model/model_create_case_request_data_relationships.rs @@ -0,0 +1,105 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Relationships of the case to create. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct CreateCaseRequestDataRelationships { + /// A list of security findings. + #[serde(rename = "findings")] + pub findings: crate::datadogV2::model::Findings, + /// Case management project. + #[serde(rename = "project")] + pub project: crate::datadogV2::model::CaseManagementProject, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl CreateCaseRequestDataRelationships { + pub fn new( + findings: crate::datadogV2::model::Findings, + project: crate::datadogV2::model::CaseManagementProject, + ) -> CreateCaseRequestDataRelationships { + CreateCaseRequestDataRelationships { + findings, + project, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for CreateCaseRequestDataRelationships { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct CreateCaseRequestDataRelationshipsVisitor; + impl<'a> Visitor<'a> for CreateCaseRequestDataRelationshipsVisitor { + type Value = CreateCaseRequestDataRelationships; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut findings: Option = None; + let mut project: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "findings" => { + findings = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "project" => { + project = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let findings = findings.ok_or_else(|| M::Error::missing_field("findings"))?; + let project = project.ok_or_else(|| M::Error::missing_field("project"))?; + + let content = CreateCaseRequestDataRelationships { + findings, + project, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(CreateCaseRequestDataRelationshipsVisitor) + } +} diff --git a/src/datadogV2/model/model_create_jira_issue_request_array.rs b/src/datadogV2/model/model_create_jira_issue_request_array.rs new file mode 100644 index 000000000..47a73120a --- /dev/null +++ b/src/datadogV2/model/model_create_jira_issue_request_array.rs @@ -0,0 +1,115 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// List of requests to create Jira issues for security findings. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct CreateJiraIssueRequestArray { + #[serde(rename = "data")] + pub data: Vec, + #[serde(rename = "included")] + pub included: Option>, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl CreateJiraIssueRequestArray { + pub fn new( + data: Vec, + ) -> CreateJiraIssueRequestArray { + CreateJiraIssueRequestArray { + data, + included: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn included( + mut self, + value: Vec, + ) -> Self { + self.included = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for CreateJiraIssueRequestArray { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct CreateJiraIssueRequestArrayVisitor; + impl<'a> Visitor<'a> for CreateJiraIssueRequestArrayVisitor { + type Value = CreateJiraIssueRequestArray; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option> = + None; + let mut included: Option< + Vec, + > = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "included" => { + if v.is_null() { + continue; + } + included = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let data = data.ok_or_else(|| M::Error::missing_field("data"))?; + + let content = CreateJiraIssueRequestArray { + data, + included, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(CreateJiraIssueRequestArrayVisitor) + } +} diff --git a/src/datadogV2/model/model_create_jira_issue_request_array_included.rs b/src/datadogV2/model/model_create_jira_issue_request_array_included.rs new file mode 100644 index 000000000..53dcbd9ca --- /dev/null +++ b/src/datadogV2/model/model_create_jira_issue_request_array_included.rs @@ -0,0 +1,52 @@ +// 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. +use serde::{Deserialize, Deserializer, Serialize}; + +/// Attributes and relationships of the case linked to the Jira issue. Should contain all of the following: case, project, and security findings. +#[non_exhaustive] +#[derive(Clone, Debug, PartialEq, Serialize)] +#[serde(untagged)] +pub enum CreateJiraIssueRequestArrayIncluded { + CreateCaseRequestData(Box), + CaseManagementProjectData(Box), + FindingData(Box), + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl<'de> Deserialize<'de> for CreateJiraIssueRequestArrayIncluded { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let value: serde_json::Value = Deserialize::deserialize(deserializer)?; + if let Ok(_v) = serde_json::from_value::>( + value.clone(), + ) { + if !_v._unparsed { + return Ok(CreateJiraIssueRequestArrayIncluded::CreateCaseRequestData( + _v, + )); + } + } + if let Ok(_v) = serde_json::from_value::< + Box, + >(value.clone()) + { + if !_v._unparsed { + return Ok(CreateJiraIssueRequestArrayIncluded::CaseManagementProjectData(_v)); + } + } + if let Ok(_v) = + serde_json::from_value::>(value.clone()) + { + if !_v._unparsed { + return Ok(CreateJiraIssueRequestArrayIncluded::FindingData(_v)); + } + } + + return Ok(CreateJiraIssueRequestArrayIncluded::UnparsedObject( + crate::datadog::UnparsedObject { value }, + )); + } +} diff --git a/src/datadogV2/model/model_create_jira_issue_request_data.rs b/src/datadogV2/model/model_create_jira_issue_request_data.rs new file mode 100644 index 000000000..ea9ec2a64 --- /dev/null +++ b/src/datadogV2/model/model_create_jira_issue_request_data.rs @@ -0,0 +1,164 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Data of the Jira issue to create. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct CreateJiraIssueRequestData { + /// Attributes of the Jira issue to create. + #[serde(rename = "attributes")] + pub attributes: Option, + /// The unique identifier of the Jira issue creation request. + #[serde(rename = "id")] + pub id: Option, + /// Relationships of the Jira issue to create. + #[serde(rename = "relationships")] + pub relationships: Option, + /// Jira issues resource type. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::JiraIssuesDataType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl CreateJiraIssueRequestData { + pub fn new(type_: crate::datadogV2::model::JiraIssuesDataType) -> CreateJiraIssueRequestData { + CreateJiraIssueRequestData { + attributes: None, + id: None, + relationships: None, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn attributes( + mut self, + value: crate::datadogV2::model::CreateJiraIssueRequestDataAttributes, + ) -> Self { + self.attributes = Some(value); + self + } + + pub fn id(mut self, value: String) -> Self { + self.id = Some(value); + self + } + + pub fn relationships( + mut self, + value: crate::datadogV2::model::CreateJiraIssueRequestDataRelationships, + ) -> Self { + self.relationships = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for CreateJiraIssueRequestData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct CreateJiraIssueRequestDataVisitor; + impl<'a> Visitor<'a> for CreateJiraIssueRequestDataVisitor { + type Value = CreateJiraIssueRequestData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut attributes: Option< + crate::datadogV2::model::CreateJiraIssueRequestDataAttributes, + > = None; + let mut id: Option = None; + let mut relationships: Option< + crate::datadogV2::model::CreateJiraIssueRequestDataRelationships, + > = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "attributes" => { + if v.is_null() { + continue; + } + attributes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "id" => { + if v.is_null() { + continue; + } + id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "relationships" => { + if v.is_null() { + continue; + } + relationships = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::JiraIssuesDataType::UnparsedObject( + _type_, + ) => { + _unparsed = true; + } + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = CreateJiraIssueRequestData { + attributes, + id, + relationships, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(CreateJiraIssueRequestDataVisitor) + } +} diff --git a/src/datadogV2/model/model_create_jira_issue_request_data_attributes.rs b/src/datadogV2/model/model_create_jira_issue_request_data_attributes.rs new file mode 100644 index 000000000..cc4c3687a --- /dev/null +++ b/src/datadogV2/model/model_create_jira_issue_request_data_attributes.rs @@ -0,0 +1,110 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Attributes of the Jira issue to create. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct CreateJiraIssueRequestDataAttributes { + /// Custom fields of the Jira issue to create. For the list of available fields, see [Jira documentation](). + #[serde(rename = "fields")] + pub fields: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl CreateJiraIssueRequestDataAttributes { + pub fn new() -> CreateJiraIssueRequestDataAttributes { + CreateJiraIssueRequestDataAttributes { + fields: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn fields( + mut self, + value: crate::datadogV2::model::CreateJiraIssueRequestDataAttributesFields, + ) -> Self { + self.fields = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for CreateJiraIssueRequestDataAttributes { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for CreateJiraIssueRequestDataAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct CreateJiraIssueRequestDataAttributesVisitor; + impl<'a> Visitor<'a> for CreateJiraIssueRequestDataAttributesVisitor { + type Value = CreateJiraIssueRequestDataAttributes; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut fields: Option< + crate::datadogV2::model::CreateJiraIssueRequestDataAttributesFields, + > = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "fields" => { + if v.is_null() { + continue; + } + fields = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = CreateJiraIssueRequestDataAttributes { + fields, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(CreateJiraIssueRequestDataAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_create_jira_issue_request_data_attributes_fields.rs b/src/datadogV2/model/model_create_jira_issue_request_data_attributes_fields.rs new file mode 100644 index 000000000..1c2040e91 --- /dev/null +++ b/src/datadogV2/model/model_create_jira_issue_request_data_attributes_fields.rs @@ -0,0 +1,105 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Custom fields of the Jira issue to create. For the list of available fields, see [Jira documentation](). +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct CreateJiraIssueRequestDataAttributesFields { + #[serde(rename = "fields")] + pub fields: Option>, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl CreateJiraIssueRequestDataAttributesFields { + pub fn new() -> CreateJiraIssueRequestDataAttributesFields { + CreateJiraIssueRequestDataAttributesFields { + fields: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn fields(mut self, value: std::collections::BTreeMap) -> Self { + self.fields = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for CreateJiraIssueRequestDataAttributesFields { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for CreateJiraIssueRequestDataAttributesFields { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct CreateJiraIssueRequestDataAttributesFieldsVisitor; + impl<'a> Visitor<'a> for CreateJiraIssueRequestDataAttributesFieldsVisitor { + type Value = CreateJiraIssueRequestDataAttributesFields; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut fields: Option> = + None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "fields" => { + if v.is_null() { + continue; + } + fields = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = CreateJiraIssueRequestDataAttributesFields { + fields, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(CreateJiraIssueRequestDataAttributesFieldsVisitor) + } +} diff --git a/src/datadogV2/model/model_create_jira_issue_request_data_relationships.rs b/src/datadogV2/model/model_create_jira_issue_request_data_relationships.rs new file mode 100644 index 000000000..97985000b --- /dev/null +++ b/src/datadogV2/model/model_create_jira_issue_request_data_relationships.rs @@ -0,0 +1,96 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Relationships of the Jira issue to create. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct CreateJiraIssueRequestDataRelationships { + /// Case linked to the Jira issue. + #[serde(rename = "case")] + pub case: crate::datadogV2::model::CreateJiraIssueRequestDataRelationshipsCase, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl CreateJiraIssueRequestDataRelationships { + pub fn new( + case: crate::datadogV2::model::CreateJiraIssueRequestDataRelationshipsCase, + ) -> CreateJiraIssueRequestDataRelationships { + CreateJiraIssueRequestDataRelationships { + case, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for CreateJiraIssueRequestDataRelationships { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct CreateJiraIssueRequestDataRelationshipsVisitor; + impl<'a> Visitor<'a> for CreateJiraIssueRequestDataRelationshipsVisitor { + type Value = CreateJiraIssueRequestDataRelationships; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut case: Option< + crate::datadogV2::model::CreateJiraIssueRequestDataRelationshipsCase, + > = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "case" => { + case = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let case = case.ok_or_else(|| M::Error::missing_field("case"))?; + + let content = CreateJiraIssueRequestDataRelationships { + case, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(CreateJiraIssueRequestDataRelationshipsVisitor) + } +} diff --git a/src/datadogV2/model/model_create_jira_issue_request_data_relationships_case.rs b/src/datadogV2/model/model_create_jira_issue_request_data_relationships_case.rs new file mode 100644 index 000000000..156bdaba7 --- /dev/null +++ b/src/datadogV2/model/model_create_jira_issue_request_data_relationships_case.rs @@ -0,0 +1,96 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Case linked to the Jira issue. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct CreateJiraIssueRequestDataRelationshipsCase { + /// Case linked to the Jira issue. + #[serde(rename = "data")] + pub data: crate::datadogV2::model::CreateJiraIssueRequestDataRelationshipsCaseData, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl CreateJiraIssueRequestDataRelationshipsCase { + pub fn new( + data: crate::datadogV2::model::CreateJiraIssueRequestDataRelationshipsCaseData, + ) -> CreateJiraIssueRequestDataRelationshipsCase { + CreateJiraIssueRequestDataRelationshipsCase { + data, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for CreateJiraIssueRequestDataRelationshipsCase { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct CreateJiraIssueRequestDataRelationshipsCaseVisitor; + impl<'a> Visitor<'a> for CreateJiraIssueRequestDataRelationshipsCaseVisitor { + type Value = CreateJiraIssueRequestDataRelationshipsCase; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option< + crate::datadogV2::model::CreateJiraIssueRequestDataRelationshipsCaseData, + > = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let data = data.ok_or_else(|| M::Error::missing_field("data"))?; + + let content = CreateJiraIssueRequestDataRelationshipsCase { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(CreateJiraIssueRequestDataRelationshipsCaseVisitor) + } +} diff --git a/src/datadogV2/model/model_create_jira_issue_request_data_relationships_case_data.rs b/src/datadogV2/model/model_create_jira_issue_request_data_relationships_case_data.rs new file mode 100644 index 000000000..f6e45576c --- /dev/null +++ b/src/datadogV2/model/model_create_jira_issue_request_data_relationships_case_data.rs @@ -0,0 +1,114 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Case linked to the Jira issue. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct CreateJiraIssueRequestDataRelationshipsCaseData { + #[serde(rename = "id")] + pub id: String, + /// Cases resource type. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::CaseDataType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl CreateJiraIssueRequestDataRelationshipsCaseData { + pub fn new( + id: String, + type_: crate::datadogV2::model::CaseDataType, + ) -> CreateJiraIssueRequestDataRelationshipsCaseData { + CreateJiraIssueRequestDataRelationshipsCaseData { + id, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for CreateJiraIssueRequestDataRelationshipsCaseData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct CreateJiraIssueRequestDataRelationshipsCaseDataVisitor; + impl<'a> Visitor<'a> for CreateJiraIssueRequestDataRelationshipsCaseDataVisitor { + type Value = CreateJiraIssueRequestDataRelationshipsCaseData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut id: Option = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "id" => { + id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::CaseDataType::UnparsedObject( + _type_, + ) => { + _unparsed = true; + } + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let id = id.ok_or_else(|| M::Error::missing_field("id"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = CreateJiraIssueRequestDataRelationshipsCaseData { + id, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(CreateJiraIssueRequestDataRelationshipsCaseDataVisitor) + } +} diff --git a/src/datadogV2/model/model_detach_case_request.rs b/src/datadogV2/model/model_detach_case_request.rs new file mode 100644 index 000000000..a7f9f3376 --- /dev/null +++ b/src/datadogV2/model/model_detach_case_request.rs @@ -0,0 +1,105 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Request for detaching security findings from their case. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct DetachCaseRequest { + /// Data for detaching security findings from their case. + #[serde(rename = "data")] + pub data: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl DetachCaseRequest { + pub fn new() -> DetachCaseRequest { + DetachCaseRequest { + data: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn data(mut self, value: crate::datadogV2::model::DetachCaseRequestData) -> Self { + self.data = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for DetachCaseRequest { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for DetachCaseRequest { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct DetachCaseRequestVisitor; + impl<'a> Visitor<'a> for DetachCaseRequestVisitor { + type Value = DetachCaseRequest; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + if v.is_null() { + continue; + } + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = DetachCaseRequest { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(DetachCaseRequestVisitor) + } +} diff --git a/src/datadogV2/model/model_detach_case_request_data.rs b/src/datadogV2/model/model_detach_case_request_data.rs new file mode 100644 index 000000000..c4f99d3ea --- /dev/null +++ b/src/datadogV2/model/model_detach_case_request_data.rs @@ -0,0 +1,142 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Data for detaching security findings from their case. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct DetachCaseRequestData { + /// The unique identifier of the detachment request. + #[serde(rename = "id")] + pub id: Option, + /// Relationships detaching security findings from their case. + #[serde(rename = "relationships")] + pub relationships: Option, + /// Cases resource type. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::CaseDataType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl DetachCaseRequestData { + pub fn new(type_: crate::datadogV2::model::CaseDataType) -> DetachCaseRequestData { + DetachCaseRequestData { + id: None, + relationships: None, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn id(mut self, value: String) -> Self { + self.id = Some(value); + self + } + + pub fn relationships( + mut self, + value: crate::datadogV2::model::DetachCaseRequestDataRelationships, + ) -> Self { + self.relationships = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for DetachCaseRequestData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct DetachCaseRequestDataVisitor; + impl<'a> Visitor<'a> for DetachCaseRequestDataVisitor { + type Value = DetachCaseRequestData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut id: Option = None; + let mut relationships: Option< + crate::datadogV2::model::DetachCaseRequestDataRelationships, + > = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "id" => { + if v.is_null() { + continue; + } + id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "relationships" => { + if v.is_null() { + continue; + } + relationships = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::CaseDataType::UnparsedObject( + _type_, + ) => { + _unparsed = true; + } + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = DetachCaseRequestData { + id, + relationships, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(DetachCaseRequestDataVisitor) + } +} diff --git a/src/datadogV2/model/model_detach_case_request_data_relationships.rs b/src/datadogV2/model/model_detach_case_request_data_relationships.rs new file mode 100644 index 000000000..a2a678110 --- /dev/null +++ b/src/datadogV2/model/model_detach_case_request_data_relationships.rs @@ -0,0 +1,92 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Relationships detaching security findings from their case. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct DetachCaseRequestDataRelationships { + /// A list of security findings. + #[serde(rename = "findings")] + pub findings: crate::datadogV2::model::Findings, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl DetachCaseRequestDataRelationships { + pub fn new(findings: crate::datadogV2::model::Findings) -> DetachCaseRequestDataRelationships { + DetachCaseRequestDataRelationships { + findings, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for DetachCaseRequestDataRelationships { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct DetachCaseRequestDataRelationshipsVisitor; + impl<'a> Visitor<'a> for DetachCaseRequestDataRelationshipsVisitor { + type Value = DetachCaseRequestDataRelationships; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut findings: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "findings" => { + findings = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let findings = findings.ok_or_else(|| M::Error::missing_field("findings"))?; + + let content = DetachCaseRequestDataRelationships { + findings, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(DetachCaseRequestDataRelationshipsVisitor) + } +} diff --git a/src/datadogV2/model/model_finding_case_response.rs b/src/datadogV2/model/model_finding_case_response.rs new file mode 100644 index 000000000..5eb0b7635 --- /dev/null +++ b/src/datadogV2/model/model_finding_case_response.rs @@ -0,0 +1,105 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Case response. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FindingCaseResponse { + /// Data of the case. + #[serde(rename = "data")] + pub data: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FindingCaseResponse { + pub fn new() -> FindingCaseResponse { + FindingCaseResponse { + data: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn data(mut self, value: crate::datadogV2::model::FindingCaseResponseData) -> Self { + self.data = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for FindingCaseResponse { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for FindingCaseResponse { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FindingCaseResponseVisitor; + impl<'a> Visitor<'a> for FindingCaseResponseVisitor { + type Value = FindingCaseResponse; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + if v.is_null() { + continue; + } + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = FindingCaseResponse { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FindingCaseResponseVisitor) + } +} diff --git a/src/datadogV2/model/model_finding_case_response_array.rs b/src/datadogV2/model/model_finding_case_response_array.rs new file mode 100644 index 000000000..87ad1c4d0 --- /dev/null +++ b/src/datadogV2/model/model_finding_case_response_array.rs @@ -0,0 +1,93 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// List of case responses. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FindingCaseResponseArray { + #[serde(rename = "data")] + pub data: Vec, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FindingCaseResponseArray { + pub fn new( + data: Vec, + ) -> FindingCaseResponseArray { + FindingCaseResponseArray { + data, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for FindingCaseResponseArray { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FindingCaseResponseArrayVisitor; + impl<'a> Visitor<'a> for FindingCaseResponseArrayVisitor { + type Value = FindingCaseResponseArray; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option> = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let data = data.ok_or_else(|| M::Error::missing_field("data"))?; + + let content = FindingCaseResponseArray { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FindingCaseResponseArrayVisitor) + } +} diff --git a/src/datadogV2/model/model_finding_case_response_data.rs b/src/datadogV2/model/model_finding_case_response_data.rs new file mode 100644 index 000000000..d01fa0295 --- /dev/null +++ b/src/datadogV2/model/model_finding_case_response_data.rs @@ -0,0 +1,164 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Data of the case. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FindingCaseResponseData { + /// Attributes of the case. + #[serde(rename = "attributes")] + pub attributes: Option, + /// The unique identifier of the case. + #[serde(rename = "id")] + pub id: Option, + /// Relationships of the case. + #[serde(rename = "relationships")] + pub relationships: Option, + /// Cases resource type. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::CaseDataType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FindingCaseResponseData { + pub fn new(type_: crate::datadogV2::model::CaseDataType) -> FindingCaseResponseData { + FindingCaseResponseData { + attributes: None, + id: None, + relationships: None, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn attributes( + mut self, + value: crate::datadogV2::model::FindingCaseResponseDataAttributes, + ) -> Self { + self.attributes = Some(value); + self + } + + pub fn id(mut self, value: String) -> Self { + self.id = Some(value); + self + } + + pub fn relationships( + mut self, + value: crate::datadogV2::model::FindingCaseResponseDataRelationships, + ) -> Self { + self.relationships = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for FindingCaseResponseData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FindingCaseResponseDataVisitor; + impl<'a> Visitor<'a> for FindingCaseResponseDataVisitor { + type Value = FindingCaseResponseData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut attributes: Option< + crate::datadogV2::model::FindingCaseResponseDataAttributes, + > = None; + let mut id: Option = None; + let mut relationships: Option< + crate::datadogV2::model::FindingCaseResponseDataRelationships, + > = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "attributes" => { + if v.is_null() { + continue; + } + attributes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "id" => { + if v.is_null() { + continue; + } + id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "relationships" => { + if v.is_null() { + continue; + } + relationships = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::CaseDataType::UnparsedObject( + _type_, + ) => { + _unparsed = true; + } + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = FindingCaseResponseData { + attributes, + id, + relationships, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FindingCaseResponseDataVisitor) + } +} diff --git a/src/datadogV2/model/model_finding_case_response_data_attributes.rs b/src/datadogV2/model/model_finding_case_response_data_attributes.rs new file mode 100644 index 000000000..8cb80b480 --- /dev/null +++ b/src/datadogV2/model/model_finding_case_response_data_attributes.rs @@ -0,0 +1,400 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Attributes of the case. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FindingCaseResponseDataAttributes { + /// Timestamp of when the case was archived. + #[serde(rename = "archived_at")] + pub archived_at: Option>, + /// Relationship to user. + #[serde(rename = "assigned_to")] + pub assigned_to: Option, + #[serde(rename = "attributes")] + pub attributes: Option>>, + /// Timestamp of when the case was closed. + #[serde(rename = "closed_at")] + pub closed_at: Option>, + /// Timestamp of when the case was created. + #[serde(rename = "created_at")] + pub created_at: Option>, + /// Source of the case creation. + #[serde(rename = "creation_source")] + pub creation_source: Option, + /// Description of the case. + #[serde(rename = "description")] + pub description: Option, + /// Due date of the case. + #[serde(rename = "due_date")] + pub due_date: Option, + /// Insights of the case. + #[serde(rename = "insights")] + pub insights: Option>, + /// Jira issue associated with the case. + #[serde(rename = "jira_issue")] + pub jira_issue: Option, + /// Key of the case. + #[serde(rename = "key")] + pub key: Option, + /// Timestamp of when the case was last modified. + #[serde(rename = "modified_at")] + pub modified_at: Option>, + /// Priority of the case. + #[serde(rename = "priority")] + pub priority: Option, + /// Status of the case. + #[serde(rename = "status")] + pub status: Option, + /// Status group of the case. + #[serde(rename = "status_group")] + pub status_group: Option, + /// Status name of the case. + #[serde(rename = "status_name")] + pub status_name: Option, + /// Title of the case. + #[serde(rename = "title")] + pub title: Option, + /// Type of the case. For security cases, this is always "SECURITY". + #[serde(rename = "type")] + pub type_: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FindingCaseResponseDataAttributes { + pub fn new() -> FindingCaseResponseDataAttributes { + FindingCaseResponseDataAttributes { + archived_at: None, + assigned_to: None, + attributes: None, + closed_at: None, + created_at: None, + creation_source: None, + description: None, + due_date: None, + insights: None, + jira_issue: None, + key: None, + modified_at: None, + priority: None, + status: None, + status_group: None, + status_name: None, + title: None, + type_: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn archived_at(mut self, value: chrono::DateTime) -> Self { + self.archived_at = Some(value); + self + } + + pub fn assigned_to(mut self, value: crate::datadogV2::model::RelationshipToUser) -> Self { + self.assigned_to = Some(value); + self + } + + pub fn attributes(mut self, value: std::collections::BTreeMap>) -> Self { + self.attributes = Some(value); + self + } + + pub fn closed_at(mut self, value: chrono::DateTime) -> Self { + self.closed_at = Some(value); + self + } + + pub fn created_at(mut self, value: chrono::DateTime) -> Self { + self.created_at = Some(value); + self + } + + pub fn creation_source(mut self, value: String) -> Self { + self.creation_source = Some(value); + self + } + + pub fn description(mut self, value: String) -> Self { + self.description = Some(value); + self + } + + pub fn due_date(mut self, value: String) -> Self { + self.due_date = Some(value); + self + } + + pub fn insights(mut self, value: Vec) -> Self { + self.insights = Some(value); + self + } + + pub fn jira_issue(mut self, value: crate::datadogV2::model::FindingJiraIssue) -> Self { + self.jira_issue = Some(value); + self + } + + pub fn key(mut self, value: String) -> Self { + self.key = Some(value); + self + } + + pub fn modified_at(mut self, value: chrono::DateTime) -> Self { + self.modified_at = Some(value); + self + } + + pub fn priority(mut self, value: String) -> Self { + self.priority = Some(value); + self + } + + pub fn status(mut self, value: String) -> Self { + self.status = Some(value); + self + } + + pub fn status_group(mut self, value: String) -> Self { + self.status_group = Some(value); + self + } + + pub fn status_name(mut self, value: String) -> Self { + self.status_name = Some(value); + self + } + + pub fn title(mut self, value: String) -> Self { + self.title = Some(value); + self + } + + pub fn type_(mut self, value: String) -> Self { + self.type_ = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for FindingCaseResponseDataAttributes { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for FindingCaseResponseDataAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FindingCaseResponseDataAttributesVisitor; + impl<'a> Visitor<'a> for FindingCaseResponseDataAttributesVisitor { + type Value = FindingCaseResponseDataAttributes; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut archived_at: Option> = None; + let mut assigned_to: Option = None; + let mut attributes: Option>> = None; + let mut closed_at: Option> = None; + let mut created_at: Option> = None; + let mut creation_source: Option = None; + let mut description: Option = None; + let mut due_date: Option = None; + let mut insights: Option> = None; + let mut jira_issue: Option = None; + let mut key: Option = None; + let mut modified_at: Option> = None; + let mut priority: Option = None; + let mut status: Option = None; + let mut status_group: Option = None; + let mut status_name: Option = None; + let mut title: Option = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "archived_at" => { + if v.is_null() { + continue; + } + archived_at = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "assigned_to" => { + if v.is_null() { + continue; + } + assigned_to = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "attributes" => { + if v.is_null() { + continue; + } + attributes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "closed_at" => { + if v.is_null() { + continue; + } + closed_at = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "created_at" => { + if v.is_null() { + continue; + } + created_at = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "creation_source" => { + if v.is_null() { + continue; + } + creation_source = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "description" => { + if v.is_null() { + continue; + } + description = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "due_date" => { + if v.is_null() { + continue; + } + due_date = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "insights" => { + if v.is_null() { + continue; + } + insights = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "jira_issue" => { + if v.is_null() { + continue; + } + jira_issue = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "key" => { + if v.is_null() { + continue; + } + key = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "modified_at" => { + if v.is_null() { + continue; + } + modified_at = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "priority" => { + if v.is_null() { + continue; + } + priority = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "status" => { + if v.is_null() { + continue; + } + status = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "status_group" => { + if v.is_null() { + continue; + } + status_group = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "status_name" => { + if v.is_null() { + continue; + } + status_name = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "title" => { + if v.is_null() { + continue; + } + title = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + if v.is_null() { + continue; + } + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = FindingCaseResponseDataAttributes { + archived_at, + assigned_to, + attributes, + closed_at, + created_at, + creation_source, + description, + due_date, + insights, + jira_issue, + key, + modified_at, + priority, + status, + status_group, + status_name, + title, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FindingCaseResponseDataAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_finding_case_response_data_relationships.rs b/src/datadogV2/model/model_finding_case_response_data_relationships.rs new file mode 100644 index 000000000..5a16d7696 --- /dev/null +++ b/src/datadogV2/model/model_finding_case_response_data_relationships.rs @@ -0,0 +1,140 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Relationships of the case. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FindingCaseResponseDataRelationships { + /// Relationship to user. + #[serde(rename = "created_by")] + pub created_by: Option, + /// Relationship to user. + #[serde(rename = "modified_by")] + pub modified_by: Option, + /// Case management project. + #[serde(rename = "project")] + pub project: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FindingCaseResponseDataRelationships { + pub fn new() -> FindingCaseResponseDataRelationships { + FindingCaseResponseDataRelationships { + created_by: None, + modified_by: None, + project: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn created_by(mut self, value: crate::datadogV2::model::RelationshipToUser) -> Self { + self.created_by = Some(value); + self + } + + pub fn modified_by(mut self, value: crate::datadogV2::model::RelationshipToUser) -> Self { + self.modified_by = Some(value); + self + } + + pub fn project(mut self, value: crate::datadogV2::model::CaseManagementProject) -> Self { + self.project = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for FindingCaseResponseDataRelationships { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for FindingCaseResponseDataRelationships { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FindingCaseResponseDataRelationshipsVisitor; + impl<'a> Visitor<'a> for FindingCaseResponseDataRelationshipsVisitor { + type Value = FindingCaseResponseDataRelationships; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut created_by: Option = None; + let mut modified_by: Option = None; + let mut project: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "created_by" => { + if v.is_null() { + continue; + } + created_by = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "modified_by" => { + if v.is_null() { + continue; + } + modified_by = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "project" => { + if v.is_null() { + continue; + } + project = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = FindingCaseResponseDataRelationships { + created_by, + modified_by, + project, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FindingCaseResponseDataRelationshipsVisitor) + } +} diff --git a/src/datadogV2/model/model_finding_data.rs b/src/datadogV2/model/model_finding_data.rs new file mode 100644 index 000000000..30ea3e2dd --- /dev/null +++ b/src/datadogV2/model/model_finding_data.rs @@ -0,0 +1,111 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FindingData { + /// The unique identifier of the security finding. + #[serde(rename = "id")] + pub id: String, + /// Security findings resource type. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::FindingDataType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FindingData { + pub fn new(id: String, type_: crate::datadogV2::model::FindingDataType) -> FindingData { + FindingData { + id, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for FindingData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FindingDataVisitor; + impl<'a> Visitor<'a> for FindingDataVisitor { + type Value = FindingData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut id: Option = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "id" => { + id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::FindingDataType::UnparsedObject( + _type_, + ) => { + _unparsed = true; + } + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let id = id.ok_or_else(|| M::Error::missing_field("id"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = FindingData { + id, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FindingDataVisitor) + } +} diff --git a/src/datadogV2/model/model_finding_data_type.rs b/src/datadogV2/model/model_finding_data_type.rs new file mode 100644 index 000000000..e7a7431e7 --- /dev/null +++ b/src/datadogV2/model/model_finding_data_type.rs @@ -0,0 +1,48 @@ +// 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. + +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +#[non_exhaustive] +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum FindingDataType { + FINDINGS, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for FindingDataType { + fn to_string(&self) -> String { + match self { + Self::FINDINGS => String::from("findings"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for FindingDataType { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Self::UnparsedObject(v) => v.serialize(serializer), + _ => serializer.serialize_str(self.to_string().as_str()), + } + } +} + +impl<'de> Deserialize<'de> for FindingDataType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "findings" => Self::FINDINGS, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/src/datadogV2/model/model_finding_jira_issue.rs b/src/datadogV2/model/model_finding_jira_issue.rs new file mode 100644 index 000000000..5a5bce695 --- /dev/null +++ b/src/datadogV2/model/model_finding_jira_issue.rs @@ -0,0 +1,140 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Jira issue associated with the case. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FindingJiraIssue { + /// The error message if the Jira issue creation failed. + #[serde(rename = "error_message")] + pub error_message: Option, + /// Result of the Jira issue creation. + #[serde(rename = "result")] + pub result: Option, + /// The status of the Jira issue creation. Can be "COMPLETED" if the Jira issue was created successfully, or "FAILED" if the Jira issue creation failed. + #[serde(rename = "status")] + pub status: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FindingJiraIssue { + pub fn new() -> FindingJiraIssue { + FindingJiraIssue { + error_message: None, + result: None, + status: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn error_message(mut self, value: String) -> Self { + self.error_message = Some(value); + self + } + + pub fn result(mut self, value: crate::datadogV2::model::FindingJiraIssueResult) -> Self { + self.result = Some(value); + self + } + + pub fn status(mut self, value: String) -> Self { + self.status = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for FindingJiraIssue { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for FindingJiraIssue { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FindingJiraIssueVisitor; + impl<'a> Visitor<'a> for FindingJiraIssueVisitor { + type Value = FindingJiraIssue; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut error_message: Option = None; + let mut result: Option = None; + let mut status: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "error_message" => { + if v.is_null() { + continue; + } + error_message = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "result" => { + if v.is_null() { + continue; + } + result = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "status" => { + if v.is_null() { + continue; + } + status = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = FindingJiraIssue { + error_message, + result, + status, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FindingJiraIssueVisitor) + } +} diff --git a/src/datadogV2/model/model_finding_jira_issue_result.rs b/src/datadogV2/model/model_finding_jira_issue_result.rs new file mode 100644 index 000000000..6ac5f0a88 --- /dev/null +++ b/src/datadogV2/model/model_finding_jira_issue_result.rs @@ -0,0 +1,156 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Result of the Jira issue creation. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FindingJiraIssueResult { + /// The account ID of the Jira issue. + #[serde(rename = "account_id")] + pub account_id: Option, + /// The unique identifier of the Jira issue. + #[serde(rename = "issue_id")] + pub issue_id: Option, + /// The key of the Jira issue. + #[serde(rename = "issue_key")] + pub issue_key: Option, + /// The URL of the Jira issue. + #[serde(rename = "issue_url")] + pub issue_url: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FindingJiraIssueResult { + pub fn new() -> FindingJiraIssueResult { + FindingJiraIssueResult { + account_id: None, + issue_id: None, + issue_key: None, + issue_url: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn account_id(mut self, value: String) -> Self { + self.account_id = Some(value); + self + } + + pub fn issue_id(mut self, value: String) -> Self { + self.issue_id = Some(value); + self + } + + pub fn issue_key(mut self, value: String) -> Self { + self.issue_key = Some(value); + self + } + + pub fn issue_url(mut self, value: String) -> Self { + self.issue_url = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for FindingJiraIssueResult { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for FindingJiraIssueResult { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FindingJiraIssueResultVisitor; + impl<'a> Visitor<'a> for FindingJiraIssueResultVisitor { + type Value = FindingJiraIssueResult; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut account_id: Option = None; + let mut issue_id: Option = None; + let mut issue_key: Option = None; + let mut issue_url: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "account_id" => { + if v.is_null() { + continue; + } + account_id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "issue_id" => { + if v.is_null() { + continue; + } + issue_id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "issue_key" => { + if v.is_null() { + continue; + } + issue_key = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "issue_url" => { + if v.is_null() { + continue; + } + issue_url = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = FindingJiraIssueResult { + account_id, + issue_id, + issue_key, + issue_url, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FindingJiraIssueResultVisitor) + } +} diff --git a/src/datadogV2/model/model_findings.rs b/src/datadogV2/model/model_findings.rs new file mode 100644 index 000000000..6e8a88281 --- /dev/null +++ b/src/datadogV2/model/model_findings.rs @@ -0,0 +1,104 @@ +// 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. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// A list of security findings. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct Findings { + #[serde(rename = "data")] + pub data: Option>, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl Findings { + pub fn new() -> Findings { + Findings { + data: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn data(mut self, value: Vec) -> Self { + self.data = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for Findings { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for Findings { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FindingsVisitor; + impl<'a> Visitor<'a> for FindingsVisitor { + type Value = Findings; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option> = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + if v.is_null() { + continue; + } + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = Findings { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FindingsVisitor) + } +} diff --git a/src/datadogV2/model/model_jira_issues_data_type.rs b/src/datadogV2/model/model_jira_issues_data_type.rs new file mode 100644 index 000000000..a376de409 --- /dev/null +++ b/src/datadogV2/model/model_jira_issues_data_type.rs @@ -0,0 +1,48 @@ +// 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. + +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +#[non_exhaustive] +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum JiraIssuesDataType { + JIRA_ISSUES, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for JiraIssuesDataType { + fn to_string(&self) -> String { + match self { + Self::JIRA_ISSUES => String::from("jira_issues"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for JiraIssuesDataType { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Self::UnparsedObject(v) => v.serialize(serializer), + _ => serializer.serialize_str(self.to_string().as_str()), + } + } +} + +impl<'de> Deserialize<'de> for JiraIssuesDataType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "jira_issues" => Self::JIRA_ISSUES, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/tests/scenarios/cassettes/v2/deployment_gates/Create-deployment-rule-returns-Bad-Request-response.frozen b/tests/scenarios/cassettes/v2/deployment_gates/Create-deployment-rule-returns-Bad-Request-response.frozen index d0f2e850f..818d31b6d 100644 --- a/tests/scenarios/cassettes/v2/deployment_gates/Create-deployment-rule-returns-Bad-Request-response.frozen +++ b/tests/scenarios/cassettes/v2/deployment_gates/Create-deployment-rule-returns-Bad-Request-response.frozen @@ -1 +1 @@ -2025-11-28T10:48:39.297Z \ No newline at end of file +2025-12-02T17:11:57.622Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/deployment_gates/Create-deployment-rule-returns-Bad-Request-response.json b/tests/scenarios/cassettes/v2/deployment_gates/Create-deployment-rule-returns-Bad-Request-response.json index a45a32a9b..2b69a2f7f 100644 --- a/tests/scenarios/cassettes/v2/deployment_gates/Create-deployment-rule-returns-Bad-Request-response.json +++ b/tests/scenarios/cassettes/v2/deployment_gates/Create-deployment-rule-returns-Bad-Request-response.json @@ -3,7 +3,7 @@ { "request": { "body": { - "string": "{\"data\":{\"attributes\":{\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testcreatedeploymentrulereturnsbadrequestresponse1764326919\",\"service\":\"my-service\"},\"type\":\"deployment_gate\"}}", + "string": "{\"data\":{\"attributes\":{\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\"},\"type\":\"deployment_gate\"}}", "encoding": null }, "headers": { @@ -19,7 +19,7 @@ }, "response": { "body": { - "string": "{\"data\":{\"id\":\"64de7180-ffd3-417b-beb6-c6ea469b5b5f\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-11-28T10:48:39.863066Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testcreatedeploymentrulereturnsbadrequestresponse1764326919\",\"service\":\"my-service\",\"updated_at\":\"2025-11-28T10:48:39.863066Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", + "string": "{\"data\":{\"id\":\"daadd697-95f4-4608-b6cc-8e6337d692ab\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-12-02T17:11:58.225449Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\",\"updated_at\":\"2025-12-02T17:11:58.225449Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", "encoding": null }, "headers": { @@ -32,7 +32,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:39 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:11:57 GMT" }, { "request": { @@ -49,7 +49,7 @@ ] }, "method": "post", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/64de7180-ffd3-417b-beb6-c6ea469b5b5f/rules" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/daadd697-95f4-4608-b6cc-8e6337d692ab/rules" }, "response": { "body": { @@ -66,7 +66,7 @@ "message": "Bad Request" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:39 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:11:57 GMT" }, { "request": { @@ -77,7 +77,7 @@ ] }, "method": "delete", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/64de7180-ffd3-417b-beb6-c6ea469b5b5f" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/daadd697-95f4-4608-b6cc-8e6337d692ab" }, "response": { "body": { @@ -90,7 +90,7 @@ "message": "No Content" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:39 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:11:57 GMT" } ], "recorded_with": "VCR 6.0.0" diff --git a/tests/scenarios/cassettes/v2/deployment_gates/Create-deployment-rule-returns-OK-response.frozen b/tests/scenarios/cassettes/v2/deployment_gates/Create-deployment-rule-returns-OK-response.frozen index a342e74d9..f7669bb4b 100644 --- a/tests/scenarios/cassettes/v2/deployment_gates/Create-deployment-rule-returns-OK-response.frozen +++ b/tests/scenarios/cassettes/v2/deployment_gates/Create-deployment-rule-returns-OK-response.frozen @@ -1 +1 @@ -2025-11-28T10:48:40.199Z \ No newline at end of file +2025-12-02T17:11:58.561Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/deployment_gates/Create-deployment-rule-returns-OK-response.json b/tests/scenarios/cassettes/v2/deployment_gates/Create-deployment-rule-returns-OK-response.json index 9ad24fa64..262d09da8 100644 --- a/tests/scenarios/cassettes/v2/deployment_gates/Create-deployment-rule-returns-OK-response.json +++ b/tests/scenarios/cassettes/v2/deployment_gates/Create-deployment-rule-returns-OK-response.json @@ -3,7 +3,7 @@ { "request": { "body": { - "string": "{\"data\":{\"attributes\":{\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testcreatedeploymentrulereturnsokresponse1764326920\",\"service\":\"my-service\"},\"type\":\"deployment_gate\"}}", + "string": "{\"data\":{\"attributes\":{\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\"},\"type\":\"deployment_gate\"}}", "encoding": null }, "headers": { @@ -19,7 +19,7 @@ }, "response": { "body": { - "string": "{\"data\":{\"id\":\"2abe97e8-438e-410e-9630-185bd3634d4d\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-11-28T10:48:40.314903Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testcreatedeploymentrulereturnsokresponse1764326920\",\"service\":\"my-service\",\"updated_at\":\"2025-11-28T10:48:40.314903Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", + "string": "{\"data\":{\"id\":\"b998ebca-01ad-4db8-96e6-a2beb54f497a\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-12-02T17:11:58.67035Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\",\"updated_at\":\"2025-12-02T17:11:58.67035Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", "encoding": null }, "headers": { @@ -32,7 +32,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:40 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:11:58 GMT" }, { "request": { @@ -49,11 +49,11 @@ ] }, "method": "post", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/2abe97e8-438e-410e-9630-185bd3634d4d/rules" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/b998ebca-01ad-4db8-96e6-a2beb54f497a/rules" }, "response": { "body": { - "string": "{\"data\":{\"id\":\"3370e167-8ad1-4cce-8efe-4688ff6d862e\",\"type\":\"deployment_rule\",\"attributes\":{\"created_at\":\"2025-11-28T10:48:40.464432Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"gate_id\":\"2abe97e8-438e-410e-9630-185bd3634d4d\",\"name\":\"My deployment rule\",\"options\":{},\"type\":\"faulty_deployment_detection\",\"updated_at\":\"2025-11-28T10:48:40.464432Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", + "string": "{\"data\":{\"id\":\"3feb569f-bb55-47cb-990f-7bc0c4c076f4\",\"type\":\"deployment_rule\",\"attributes\":{\"created_at\":\"2025-12-02T17:11:58.877828Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"gate_id\":\"b998ebca-01ad-4db8-96e6-a2beb54f497a\",\"name\":\"My deployment rule\",\"options\":{},\"type\":\"faulty_deployment_detection\",\"updated_at\":\"2025-12-02T17:11:58.877828Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", "encoding": null }, "headers": { @@ -66,7 +66,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:40 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:11:58 GMT" }, { "request": { @@ -77,7 +77,7 @@ ] }, "method": "delete", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/2abe97e8-438e-410e-9630-185bd3634d4d/rules/3370e167-8ad1-4cce-8efe-4688ff6d862e" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/b998ebca-01ad-4db8-96e6-a2beb54f497a/rules/3feb569f-bb55-47cb-990f-7bc0c4c076f4" }, "response": { "body": { @@ -90,7 +90,7 @@ "message": "No Content" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:40 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:11:58 GMT" }, { "request": { @@ -101,7 +101,7 @@ ] }, "method": "delete", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/2abe97e8-438e-410e-9630-185bd3634d4d" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/b998ebca-01ad-4db8-96e6-a2beb54f497a" }, "response": { "body": { @@ -114,7 +114,7 @@ "message": "No Content" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:40 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:11:58 GMT" } ], "recorded_with": "VCR 6.0.0" diff --git a/tests/scenarios/cassettes/v2/deployment_gates/Delete-deployment-gate-returns-No-Content-response.frozen b/tests/scenarios/cassettes/v2/deployment_gates/Delete-deployment-gate-returns-No-Content-response.frozen index c903e462f..6727b321f 100644 --- a/tests/scenarios/cassettes/v2/deployment_gates/Delete-deployment-gate-returns-No-Content-response.frozen +++ b/tests/scenarios/cassettes/v2/deployment_gates/Delete-deployment-gate-returns-No-Content-response.frozen @@ -1 +1 @@ -2025-11-28T10:48:40.779Z \ No newline at end of file +2025-12-02T17:11:59.228Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/deployment_gates/Delete-deployment-gate-returns-No-Content-response.json b/tests/scenarios/cassettes/v2/deployment_gates/Delete-deployment-gate-returns-No-Content-response.json index 3f76ab32e..d37f4601c 100644 --- a/tests/scenarios/cassettes/v2/deployment_gates/Delete-deployment-gate-returns-No-Content-response.json +++ b/tests/scenarios/cassettes/v2/deployment_gates/Delete-deployment-gate-returns-No-Content-response.json @@ -3,7 +3,7 @@ { "request": { "body": { - "string": "{\"data\":{\"attributes\":{\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testdeletedeploymentgatereturnsnocontentresponse1764326920\",\"service\":\"my-service\"},\"type\":\"deployment_gate\"}}", + "string": "{\"data\":{\"attributes\":{\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\"},\"type\":\"deployment_gate\"}}", "encoding": null }, "headers": { @@ -19,7 +19,7 @@ }, "response": { "body": { - "string": "{\"data\":{\"id\":\"86e38caf-0d2a-4e72-93ac-9850957d2c6b\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-11-28T10:48:40.909837Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testdeletedeploymentgatereturnsnocontentresponse1764326920\",\"service\":\"my-service\",\"updated_at\":\"2025-11-28T10:48:40.909837Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", + "string": "{\"data\":{\"id\":\"0d6b54a5-70ad-4e9a-9ee4-f7d99f25a3d5\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-12-02T17:11:59.349857Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\",\"updated_at\":\"2025-12-02T17:11:59.349857Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", "encoding": null }, "headers": { @@ -32,7 +32,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:40 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:11:59 GMT" }, { "request": { @@ -43,7 +43,7 @@ ] }, "method": "delete", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/86e38caf-0d2a-4e72-93ac-9850957d2c6b" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/0d6b54a5-70ad-4e9a-9ee4-f7d99f25a3d5" }, "response": { "body": { @@ -56,7 +56,7 @@ "message": "No Content" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:40 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:11:59 GMT" }, { "request": { @@ -67,7 +67,7 @@ ] }, "method": "delete", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/86e38caf-0d2a-4e72-93ac-9850957d2c6b" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/0d6b54a5-70ad-4e9a-9ee4-f7d99f25a3d5" }, "response": { "body": { @@ -84,7 +84,7 @@ "message": "Not Found" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:40 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:11:59 GMT" } ], "recorded_with": "VCR 6.0.0" diff --git a/tests/scenarios/cassettes/v2/deployment_gates/Delete-deployment-rule-returns-No-Content-response.frozen b/tests/scenarios/cassettes/v2/deployment_gates/Delete-deployment-rule-returns-No-Content-response.frozen index e0d912f1f..5d67a9ba4 100644 --- a/tests/scenarios/cassettes/v2/deployment_gates/Delete-deployment-rule-returns-No-Content-response.frozen +++ b/tests/scenarios/cassettes/v2/deployment_gates/Delete-deployment-rule-returns-No-Content-response.frozen @@ -1 +1 @@ -2025-11-28T10:48:41.219Z \ No newline at end of file +2025-12-02T17:11:59.690Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/deployment_gates/Delete-deployment-rule-returns-No-Content-response.json b/tests/scenarios/cassettes/v2/deployment_gates/Delete-deployment-rule-returns-No-Content-response.json index 810b4a122..f0e3a0bc2 100644 --- a/tests/scenarios/cassettes/v2/deployment_gates/Delete-deployment-rule-returns-No-Content-response.json +++ b/tests/scenarios/cassettes/v2/deployment_gates/Delete-deployment-rule-returns-No-Content-response.json @@ -3,7 +3,7 @@ { "request": { "body": { - "string": "{\"data\":{\"attributes\":{\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testdeletedeploymentrulereturnsnocontentresponse1764326921\",\"service\":\"my-service\"},\"type\":\"deployment_gate\"}}", + "string": "{\"data\":{\"attributes\":{\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\"},\"type\":\"deployment_gate\"}}", "encoding": null }, "headers": { @@ -19,7 +19,7 @@ }, "response": { "body": { - "string": "{\"data\":{\"id\":\"32ff7c01-1f90-4ae4-bef0-b759f1ad280f\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-11-28T10:48:41.325741Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testdeletedeploymentrulereturnsnocontentresponse1764326921\",\"service\":\"my-service\",\"updated_at\":\"2025-11-28T10:48:41.325741Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", + "string": "{\"data\":{\"id\":\"051490b0-1383-4dd4-b719-fb17ab089898\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-12-02T17:11:59.799293Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\",\"updated_at\":\"2025-12-02T17:11:59.799293Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", "encoding": null }, "headers": { @@ -32,7 +32,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:41 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:11:59 GMT" }, { "request": { @@ -49,11 +49,11 @@ ] }, "method": "post", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/32ff7c01-1f90-4ae4-bef0-b759f1ad280f/rules" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/051490b0-1383-4dd4-b719-fb17ab089898/rules" }, "response": { "body": { - "string": "{\"data\":{\"id\":\"8229075f-8014-432c-9597-ba549ae5cd83\",\"type\":\"deployment_rule\",\"attributes\":{\"created_at\":\"2025-11-28T10:48:41.470358Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"gate_id\":\"32ff7c01-1f90-4ae4-bef0-b759f1ad280f\",\"name\":\"My deployment rule\",\"options\":{},\"type\":\"faulty_deployment_detection\",\"updated_at\":\"2025-11-28T10:48:41.470358Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", + "string": "{\"data\":{\"id\":\"29fb1e0d-d3f4-4f3a-a4de-1bd65cf57c16\",\"type\":\"deployment_rule\",\"attributes\":{\"created_at\":\"2025-12-02T17:11:59.98839Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"gate_id\":\"051490b0-1383-4dd4-b719-fb17ab089898\",\"name\":\"My deployment rule\",\"options\":{},\"type\":\"faulty_deployment_detection\",\"updated_at\":\"2025-12-02T17:11:59.98839Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", "encoding": null }, "headers": { @@ -66,7 +66,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:41 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:11:59 GMT" }, { "request": { @@ -77,7 +77,7 @@ ] }, "method": "delete", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/32ff7c01-1f90-4ae4-bef0-b759f1ad280f/rules/8229075f-8014-432c-9597-ba549ae5cd83" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/051490b0-1383-4dd4-b719-fb17ab089898/rules/29fb1e0d-d3f4-4f3a-a4de-1bd65cf57c16" }, "response": { "body": { @@ -90,7 +90,7 @@ "message": "No Content" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:41 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:11:59 GMT" }, { "request": { @@ -101,7 +101,7 @@ ] }, "method": "delete", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/32ff7c01-1f90-4ae4-bef0-b759f1ad280f/rules/8229075f-8014-432c-9597-ba549ae5cd83" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/051490b0-1383-4dd4-b719-fb17ab089898/rules/29fb1e0d-d3f4-4f3a-a4de-1bd65cf57c16" }, "response": { "body": { @@ -118,7 +118,7 @@ "message": "Not Found" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:41 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:11:59 GMT" }, { "request": { @@ -129,7 +129,7 @@ ] }, "method": "delete", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/32ff7c01-1f90-4ae4-bef0-b759f1ad280f" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/051490b0-1383-4dd4-b719-fb17ab089898" }, "response": { "body": { @@ -142,7 +142,7 @@ "message": "No Content" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:41 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:11:59 GMT" } ], "recorded_with": "VCR 6.0.0" diff --git a/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-gate-returns-OK-response.frozen b/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-gate-returns-OK-response.frozen index 13cea2df2..a00e4ba26 100644 --- a/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-gate-returns-OK-response.frozen +++ b/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-gate-returns-OK-response.frozen @@ -1 +1 @@ -2025-11-28T10:48:41.902Z \ No newline at end of file +2025-12-02T17:12:00.422Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-gate-returns-OK-response.json b/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-gate-returns-OK-response.json index 29c745751..d7b97ac4a 100644 --- a/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-gate-returns-OK-response.json +++ b/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-gate-returns-OK-response.json @@ -3,7 +3,7 @@ { "request": { "body": { - "string": "{\"data\":{\"attributes\":{\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testgetdeploymentgatereturnsokresponse1764326921\",\"service\":\"my-service\"},\"type\":\"deployment_gate\"}}", + "string": "{\"data\":{\"attributes\":{\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\"},\"type\":\"deployment_gate\"}}", "encoding": null }, "headers": { @@ -19,7 +19,7 @@ }, "response": { "body": { - "string": "{\"data\":{\"id\":\"6fc0d64b-aa76-49f9-804b-5ba224951b53\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-11-28T10:48:42.011911Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testgetdeploymentgatereturnsokresponse1764326921\",\"service\":\"my-service\",\"updated_at\":\"2025-11-28T10:48:42.011911Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", + "string": "{\"data\":{\"id\":\"a71a41f7-e7b9-4c51-8af0-397c8e99aaf9\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-12-02T17:12:00.52354Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\",\"updated_at\":\"2025-12-02T17:12:00.52354Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", "encoding": null }, "headers": { @@ -32,7 +32,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:41 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:00 GMT" }, { "request": { @@ -43,11 +43,11 @@ ] }, "method": "get", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/6fc0d64b-aa76-49f9-804b-5ba224951b53" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/a71a41f7-e7b9-4c51-8af0-397c8e99aaf9" }, "response": { "body": { - "string": "{\"data\":{\"id\":\"6fc0d64b-aa76-49f9-804b-5ba224951b53\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-11-28T10:48:42.011911Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testgetdeploymentgatereturnsokresponse1764326921\",\"service\":\"my-service\",\"updated_at\":\"2025-11-28T10:48:42.011911Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", + "string": "{\"data\":{\"id\":\"a71a41f7-e7b9-4c51-8af0-397c8e99aaf9\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-12-02T17:12:00.52354Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\",\"updated_at\":\"2025-12-02T17:12:00.52354Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", "encoding": null }, "headers": { @@ -60,7 +60,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:41 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:00 GMT" }, { "request": { @@ -71,7 +71,7 @@ ] }, "method": "delete", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/6fc0d64b-aa76-49f9-804b-5ba224951b53" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/a71a41f7-e7b9-4c51-8af0-397c8e99aaf9" }, "response": { "body": { @@ -84,7 +84,7 @@ "message": "No Content" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:41 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:00 GMT" } ], "recorded_with": "VCR 6.0.0" diff --git a/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-rule-returns-Bad-Request-response.frozen b/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-rule-returns-Bad-Request-response.frozen index 3ae04f6f7..e00dc1eb2 100644 --- a/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-rule-returns-Bad-Request-response.frozen +++ b/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-rule-returns-Bad-Request-response.frozen @@ -1 +1 @@ -2025-11-28T10:48:42.334Z \ No newline at end of file +2025-12-02T17:12:00.864Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-rule-returns-Bad-Request-response.json b/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-rule-returns-Bad-Request-response.json index 2afc09b2e..72afe25f6 100644 --- a/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-rule-returns-Bad-Request-response.json +++ b/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-rule-returns-Bad-Request-response.json @@ -3,7 +3,7 @@ { "request": { "body": { - "string": "{\"data\":{\"attributes\":{\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testgetdeploymentrulereturnsbadrequestresponse1764326922\",\"service\":\"my-service\"},\"type\":\"deployment_gate\"}}", + "string": "{\"data\":{\"attributes\":{\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\"},\"type\":\"deployment_gate\"}}", "encoding": null }, "headers": { @@ -19,7 +19,7 @@ }, "response": { "body": { - "string": "{\"data\":{\"id\":\"10bfb87d-3e15-4889-895c-28fd41d71837\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-11-28T10:48:42.440107Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testgetdeploymentrulereturnsbadrequestresponse1764326922\",\"service\":\"my-service\",\"updated_at\":\"2025-11-28T10:48:42.440107Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", + "string": "{\"data\":{\"id\":\"241e9292-911a-4eea-90e0-83b5f27a468c\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-12-02T17:12:00.969748Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\",\"updated_at\":\"2025-12-02T17:12:00.969748Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", "encoding": null }, "headers": { @@ -32,7 +32,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:42 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:00 GMT" }, { "request": { @@ -49,11 +49,11 @@ ] }, "method": "post", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/10bfb87d-3e15-4889-895c-28fd41d71837/rules" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/241e9292-911a-4eea-90e0-83b5f27a468c/rules" }, "response": { "body": { - "string": "{\"data\":{\"id\":\"e8c6d6c6-c529-4c30-92f9-8d965a68b120\",\"type\":\"deployment_rule\",\"attributes\":{\"created_at\":\"2025-11-28T10:48:42.588675Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"gate_id\":\"10bfb87d-3e15-4889-895c-28fd41d71837\",\"name\":\"My deployment rule\",\"options\":{},\"type\":\"faulty_deployment_detection\",\"updated_at\":\"2025-11-28T10:48:42.588675Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", + "string": "{\"data\":{\"id\":\"48d335e3-7744-4aef-af75-7c6d0bb9e24e\",\"type\":\"deployment_rule\",\"attributes\":{\"created_at\":\"2025-12-02T17:12:01.161979Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"gate_id\":\"241e9292-911a-4eea-90e0-83b5f27a468c\",\"name\":\"My deployment rule\",\"options\":{},\"type\":\"faulty_deployment_detection\",\"updated_at\":\"2025-12-02T17:12:01.161979Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", "encoding": null }, "headers": { @@ -66,7 +66,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:42 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:00 GMT" }, { "request": { @@ -94,7 +94,7 @@ "message": "Bad Request" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:42 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:00 GMT" }, { "request": { @@ -105,7 +105,7 @@ ] }, "method": "delete", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/10bfb87d-3e15-4889-895c-28fd41d71837/rules/e8c6d6c6-c529-4c30-92f9-8d965a68b120" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/241e9292-911a-4eea-90e0-83b5f27a468c/rules/48d335e3-7744-4aef-af75-7c6d0bb9e24e" }, "response": { "body": { @@ -118,7 +118,7 @@ "message": "No Content" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:42 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:00 GMT" }, { "request": { @@ -129,7 +129,7 @@ ] }, "method": "delete", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/10bfb87d-3e15-4889-895c-28fd41d71837" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/241e9292-911a-4eea-90e0-83b5f27a468c" }, "response": { "body": { @@ -142,7 +142,7 @@ "message": "No Content" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:42 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:00 GMT" } ], "recorded_with": "VCR 6.0.0" diff --git a/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-rule-returns-OK-response.frozen b/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-rule-returns-OK-response.frozen index dff9a2ed2..d03936e1d 100644 --- a/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-rule-returns-OK-response.frozen +++ b/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-rule-returns-OK-response.frozen @@ -1 +1 @@ -2025-11-28T10:48:42.991Z \ No newline at end of file +2025-12-02T17:12:01.624Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-rule-returns-OK-response.json b/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-rule-returns-OK-response.json index 09ac6f3b0..dcf07b295 100644 --- a/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-rule-returns-OK-response.json +++ b/tests/scenarios/cassettes/v2/deployment_gates/Get-deployment-rule-returns-OK-response.json @@ -3,7 +3,7 @@ { "request": { "body": { - "string": "{\"data\":{\"attributes\":{\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testgetdeploymentrulereturnsokresponse1764326922\",\"service\":\"my-service\"},\"type\":\"deployment_gate\"}}", + "string": "{\"data\":{\"attributes\":{\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\"},\"type\":\"deployment_gate\"}}", "encoding": null }, "headers": { @@ -19,7 +19,7 @@ }, "response": { "body": { - "string": "{\"data\":{\"id\":\"701d9655-8d81-43d0-9954-cf24b4959b60\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-11-28T10:48:43.092215Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testgetdeploymentrulereturnsokresponse1764326922\",\"service\":\"my-service\",\"updated_at\":\"2025-11-28T10:48:43.092215Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", + "string": "{\"data\":{\"id\":\"defa04e5-9bb2-4a40-b854-1c2378ffcc58\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-12-02T17:12:01.70723Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\",\"updated_at\":\"2025-12-02T17:12:01.70723Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", "encoding": null }, "headers": { @@ -32,7 +32,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:42 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:01 GMT" }, { "request": { @@ -49,11 +49,11 @@ ] }, "method": "post", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/701d9655-8d81-43d0-9954-cf24b4959b60/rules" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/defa04e5-9bb2-4a40-b854-1c2378ffcc58/rules" }, "response": { "body": { - "string": "{\"data\":{\"id\":\"c96cd32f-5c92-4bc7-9483-85a824b394a7\",\"type\":\"deployment_rule\",\"attributes\":{\"created_at\":\"2025-11-28T10:48:43.237862Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"gate_id\":\"701d9655-8d81-43d0-9954-cf24b4959b60\",\"name\":\"My deployment rule\",\"options\":{},\"type\":\"faulty_deployment_detection\",\"updated_at\":\"2025-11-28T10:48:43.237862Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", + "string": "{\"data\":{\"id\":\"c1009845-b7a4-4701-846b-df160891ab3d\",\"type\":\"deployment_rule\",\"attributes\":{\"created_at\":\"2025-12-02T17:12:01.871247Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"gate_id\":\"defa04e5-9bb2-4a40-b854-1c2378ffcc58\",\"name\":\"My deployment rule\",\"options\":{},\"type\":\"faulty_deployment_detection\",\"updated_at\":\"2025-12-02T17:12:01.871247Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", "encoding": null }, "headers": { @@ -66,7 +66,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:42 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:01 GMT" }, { "request": { @@ -77,11 +77,11 @@ ] }, "method": "get", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/701d9655-8d81-43d0-9954-cf24b4959b60/rules/c96cd32f-5c92-4bc7-9483-85a824b394a7" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/defa04e5-9bb2-4a40-b854-1c2378ffcc58/rules/c1009845-b7a4-4701-846b-df160891ab3d" }, "response": { "body": { - "string": "{\"data\":{\"id\":\"c96cd32f-5c92-4bc7-9483-85a824b394a7\",\"type\":\"deployment_rule\",\"attributes\":{\"created_at\":\"2025-11-28T10:48:43.237862Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"gate_id\":\"701d9655-8d81-43d0-9954-cf24b4959b60\",\"name\":\"My deployment rule\",\"options\":{},\"type\":\"faulty_deployment_detection\",\"updated_at\":\"2025-11-28T10:48:43.237862Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", + "string": "{\"data\":{\"id\":\"c1009845-b7a4-4701-846b-df160891ab3d\",\"type\":\"deployment_rule\",\"attributes\":{\"created_at\":\"2025-12-02T17:12:01.871247Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"gate_id\":\"defa04e5-9bb2-4a40-b854-1c2378ffcc58\",\"name\":\"My deployment rule\",\"options\":{},\"type\":\"faulty_deployment_detection\",\"updated_at\":\"2025-12-02T17:12:01.871247Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", "encoding": null }, "headers": { @@ -94,7 +94,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:42 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:01 GMT" }, { "request": { @@ -105,7 +105,7 @@ ] }, "method": "delete", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/701d9655-8d81-43d0-9954-cf24b4959b60/rules/c96cd32f-5c92-4bc7-9483-85a824b394a7" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/defa04e5-9bb2-4a40-b854-1c2378ffcc58/rules/c1009845-b7a4-4701-846b-df160891ab3d" }, "response": { "body": { @@ -118,7 +118,7 @@ "message": "No Content" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:42 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:01 GMT" }, { "request": { @@ -129,7 +129,7 @@ ] }, "method": "delete", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/701d9655-8d81-43d0-9954-cf24b4959b60" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/defa04e5-9bb2-4a40-b854-1c2378ffcc58" }, "response": { "body": { @@ -142,7 +142,7 @@ "message": "No Content" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:42 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:01 GMT" } ], "recorded_with": "VCR 6.0.0" diff --git a/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-gate-returns-OK-response.frozen b/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-gate-returns-OK-response.frozen index 72fa1316f..363a2cef5 100644 --- a/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-gate-returns-OK-response.frozen +++ b/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-gate-returns-OK-response.frozen @@ -1 +1 @@ -2025-11-28T10:48:43.738Z \ No newline at end of file +2025-12-02T17:12:02.280Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-gate-returns-OK-response.json b/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-gate-returns-OK-response.json index bd19c1f17..27bdc2e5e 100644 --- a/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-gate-returns-OK-response.json +++ b/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-gate-returns-OK-response.json @@ -3,7 +3,7 @@ { "request": { "body": { - "string": "{\"data\":{\"attributes\":{\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testupdatedeploymentgatereturnsokresponse1764326923\",\"service\":\"my-service\"},\"type\":\"deployment_gate\"}}", + "string": "{\"data\":{\"attributes\":{\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\"},\"type\":\"deployment_gate\"}}", "encoding": null }, "headers": { @@ -19,7 +19,7 @@ }, "response": { "body": { - "string": "{\"data\":{\"id\":\"6080b4ee-0fa6-4370-aafa-adb5b71c2fab\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-11-28T10:48:43.844073Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testupdatedeploymentgatereturnsokresponse1764326923\",\"service\":\"my-service\",\"updated_at\":\"2025-11-28T10:48:43.844073Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", + "string": "{\"data\":{\"id\":\"010e234b-b358-463e-a44d-6fbe29ec3f6b\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-12-02T17:12:02.374479Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\",\"updated_at\":\"2025-12-02T17:12:02.374479Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", "encoding": null }, "headers": { @@ -32,7 +32,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:43 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:02 GMT" }, { "request": { @@ -49,11 +49,11 @@ ] }, "method": "put", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/6080b4ee-0fa6-4370-aafa-adb5b71c2fab" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/010e234b-b358-463e-a44d-6fbe29ec3f6b" }, "response": { "body": { - "string": "{\"data\":{\"id\":\"6080b4ee-0fa6-4370-aafa-adb5b71c2fab\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-11-28T10:48:43.844073Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testupdatedeploymentgatereturnsokresponse1764326923\",\"service\":\"my-service\",\"updated_at\":\"2025-11-28T10:48:44.028502Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", + "string": "{\"data\":{\"id\":\"010e234b-b358-463e-a44d-6fbe29ec3f6b\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-12-02T17:12:02.374479Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\",\"updated_at\":\"2025-12-02T17:12:02.534024Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", "encoding": null }, "headers": { @@ -66,7 +66,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:43 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:02 GMT" }, { "request": { @@ -77,7 +77,7 @@ ] }, "method": "delete", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/6080b4ee-0fa6-4370-aafa-adb5b71c2fab" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/010e234b-b358-463e-a44d-6fbe29ec3f6b" }, "response": { "body": { @@ -90,7 +90,7 @@ "message": "No Content" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:43 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:02 GMT" } ], "recorded_with": "VCR 6.0.0" diff --git a/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-rule-returns-Bad-Request-response.frozen b/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-rule-returns-Bad-Request-response.frozen index e708a507a..742e9ca60 100644 --- a/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-rule-returns-Bad-Request-response.frozen +++ b/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-rule-returns-Bad-Request-response.frozen @@ -1 +1 @@ -2025-11-28T10:48:44.227Z \ No newline at end of file +2025-12-02T17:12:02.719Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-rule-returns-Bad-Request-response.json b/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-rule-returns-Bad-Request-response.json index be3f8748b..026af610a 100644 --- a/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-rule-returns-Bad-Request-response.json +++ b/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-rule-returns-Bad-Request-response.json @@ -3,7 +3,7 @@ { "request": { "body": { - "string": "{\"data\":{\"attributes\":{\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testupdatedeploymentrulereturnsbadrequestresponse1764326924\",\"service\":\"my-service\"},\"type\":\"deployment_gate\"}}", + "string": "{\"data\":{\"attributes\":{\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\"},\"type\":\"deployment_gate\"}}", "encoding": null }, "headers": { @@ -19,7 +19,7 @@ }, "response": { "body": { - "string": "{\"data\":{\"id\":\"f7fc03e3-86d9-4731-9baf-9b3a2f9239c3\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-11-28T10:48:44.325367Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testupdatedeploymentrulereturnsbadrequestresponse1764326924\",\"service\":\"my-service\",\"updated_at\":\"2025-11-28T10:48:44.325367Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", + "string": "{\"data\":{\"id\":\"ef2fa0b3-0f6a-49a4-9043-1d8130cb7361\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-12-02T17:12:02.81563Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\",\"updated_at\":\"2025-12-02T17:12:02.81563Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", "encoding": null }, "headers": { @@ -32,7 +32,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:44 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:02 GMT" }, { "request": { @@ -49,11 +49,11 @@ ] }, "method": "post", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/f7fc03e3-86d9-4731-9baf-9b3a2f9239c3/rules" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/ef2fa0b3-0f6a-49a4-9043-1d8130cb7361/rules" }, "response": { "body": { - "string": "{\"data\":{\"id\":\"63e71fe3-f002-4e46-bc24-772c7a743e95\",\"type\":\"deployment_rule\",\"attributes\":{\"created_at\":\"2025-11-28T10:48:44.453112Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"gate_id\":\"f7fc03e3-86d9-4731-9baf-9b3a2f9239c3\",\"name\":\"My deployment rule\",\"options\":{},\"type\":\"faulty_deployment_detection\",\"updated_at\":\"2025-11-28T10:48:44.453112Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", + "string": "{\"data\":{\"id\":\"c89bf1d3-5e6a-43b1-9009-cfaaaddf8518\",\"type\":\"deployment_rule\",\"attributes\":{\"created_at\":\"2025-12-02T17:12:02.99992Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"gate_id\":\"ef2fa0b3-0f6a-49a4-9043-1d8130cb7361\",\"name\":\"My deployment rule\",\"options\":{},\"type\":\"faulty_deployment_detection\",\"updated_at\":\"2025-12-02T17:12:02.99992Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", "encoding": null }, "headers": { @@ -66,7 +66,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:44 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:02 GMT" }, { "request": { @@ -100,7 +100,7 @@ "message": "Bad Request" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:44 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:02 GMT" }, { "request": { @@ -111,7 +111,7 @@ ] }, "method": "delete", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/f7fc03e3-86d9-4731-9baf-9b3a2f9239c3/rules/63e71fe3-f002-4e46-bc24-772c7a743e95" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/ef2fa0b3-0f6a-49a4-9043-1d8130cb7361/rules/c89bf1d3-5e6a-43b1-9009-cfaaaddf8518" }, "response": { "body": { @@ -124,7 +124,7 @@ "message": "No Content" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:44 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:02 GMT" }, { "request": { @@ -135,7 +135,7 @@ ] }, "method": "delete", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/f7fc03e3-86d9-4731-9baf-9b3a2f9239c3" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/ef2fa0b3-0f6a-49a4-9043-1d8130cb7361" }, "response": { "body": { @@ -148,7 +148,7 @@ "message": "No Content" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:44 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:02 GMT" } ], "recorded_with": "VCR 6.0.0" diff --git a/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-rule-returns-OK-response.frozen b/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-rule-returns-OK-response.frozen index 75b8801eb..e8ff3a3f0 100644 --- a/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-rule-returns-OK-response.frozen +++ b/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-rule-returns-OK-response.frozen @@ -1 +1 @@ -2025-11-28T10:48:44.855Z \ No newline at end of file +2025-12-02T17:12:03.436Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-rule-returns-OK-response.json b/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-rule-returns-OK-response.json index daa73b7a2..1a37997ff 100644 --- a/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-rule-returns-OK-response.json +++ b/tests/scenarios/cassettes/v2/deployment_gates/Update-deployment-rule-returns-OK-response.json @@ -3,7 +3,7 @@ { "request": { "body": { - "string": "{\"data\":{\"attributes\":{\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testupdatedeploymentrulereturnsokresponse1764326924\",\"service\":\"my-service\"},\"type\":\"deployment_gate\"}}", + "string": "{\"data\":{\"attributes\":{\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\"},\"type\":\"deployment_gate\"}}", "encoding": null }, "headers": { @@ -19,7 +19,7 @@ }, "response": { "body": { - "string": "{\"data\":{\"id\":\"b9fe1de0-ba29-4f86-abbb-09ec15047772\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-11-28T10:48:44.953026Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate-testupdatedeploymentrulereturnsokresponse1764326924\",\"service\":\"my-service\",\"updated_at\":\"2025-11-28T10:48:44.953026Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", + "string": "{\"data\":{\"id\":\"bfdae182-ee23-493c-a90b-05441a76ad73\",\"type\":\"deployment_gate\",\"attributes\":{\"created_at\":\"2025-12-02T17:12:03.529101Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"env\":\"production\",\"identifier\":\"my-gate\",\"service\":\"my-service\",\"updated_at\":\"2025-12-02T17:12:03.529101Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", "encoding": null }, "headers": { @@ -32,7 +32,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:44 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:03 GMT" }, { "request": { @@ -49,11 +49,11 @@ ] }, "method": "post", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/b9fe1de0-ba29-4f86-abbb-09ec15047772/rules" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/bfdae182-ee23-493c-a90b-05441a76ad73/rules" }, "response": { "body": { - "string": "{\"data\":{\"id\":\"04207b55-28e1-46e6-9aa1-ed45dd022e3e\",\"type\":\"deployment_rule\",\"attributes\":{\"created_at\":\"2025-11-28T10:48:45.086885Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"gate_id\":\"b9fe1de0-ba29-4f86-abbb-09ec15047772\",\"name\":\"My deployment rule\",\"options\":{},\"type\":\"faulty_deployment_detection\",\"updated_at\":\"2025-11-28T10:48:45.086885Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", + "string": "{\"data\":{\"id\":\"93ed5e98-aeb8-4096-a035-0907f327019e\",\"type\":\"deployment_rule\",\"attributes\":{\"created_at\":\"2025-12-02T17:12:03.68857Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"gate_id\":\"bfdae182-ee23-493c-a90b-05441a76ad73\",\"name\":\"My deployment rule\",\"options\":{},\"type\":\"faulty_deployment_detection\",\"updated_at\":\"2025-12-02T17:12:03.68857Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", "encoding": null }, "headers": { @@ -66,7 +66,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:44 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:03 GMT" }, { "request": { @@ -83,11 +83,11 @@ ] }, "method": "put", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/b9fe1de0-ba29-4f86-abbb-09ec15047772/rules/04207b55-28e1-46e6-9aa1-ed45dd022e3e" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/bfdae182-ee23-493c-a90b-05441a76ad73/rules/93ed5e98-aeb8-4096-a035-0907f327019e" }, "response": { "body": { - "string": "{\"data\":{\"id\":\"04207b55-28e1-46e6-9aa1-ed45dd022e3e\",\"type\":\"deployment_rule\",\"attributes\":{\"created_at\":\"2025-11-28T10:48:45.086885Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"gate_id\":\"b9fe1de0-ba29-4f86-abbb-09ec15047772\",\"name\":\"Updated deployment rule\",\"options\":{},\"type\":\"faulty_deployment_detection\",\"updated_at\":\"2025-11-28T10:48:45.232653Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", + "string": "{\"data\":{\"id\":\"93ed5e98-aeb8-4096-a035-0907f327019e\",\"type\":\"deployment_rule\",\"attributes\":{\"created_at\":\"2025-12-02T17:12:03.68857Z\",\"created_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"},\"dry_run\":false,\"gate_id\":\"bfdae182-ee23-493c-a90b-05441a76ad73\",\"name\":\"Updated deployment rule\",\"options\":{},\"type\":\"faulty_deployment_detection\",\"updated_at\":\"2025-12-02T17:12:03.882016Z\",\"updated_by\":{\"id\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\"}}}}", "encoding": null }, "headers": { @@ -100,7 +100,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:44 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:03 GMT" }, { "request": { @@ -111,7 +111,7 @@ ] }, "method": "delete", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/b9fe1de0-ba29-4f86-abbb-09ec15047772/rules/04207b55-28e1-46e6-9aa1-ed45dd022e3e" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/bfdae182-ee23-493c-a90b-05441a76ad73/rules/93ed5e98-aeb8-4096-a035-0907f327019e" }, "response": { "body": { @@ -124,7 +124,7 @@ "message": "No Content" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:44 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:03 GMT" }, { "request": { @@ -135,7 +135,7 @@ ] }, "method": "delete", - "uri": "https://api.datadoghq.com/api/v2/deployment_gates/b9fe1de0-ba29-4f86-abbb-09ec15047772" + "uri": "https://api.datadoghq.com/api/v2/deployment_gates/bfdae182-ee23-493c-a90b-05441a76ad73" }, "response": { "body": { @@ -148,7 +148,7 @@ "message": "No Content" } }, - "recorded_at": "Fri, 28 Nov 2025 10:48:44 GMT" + "recorded_at": "Tue, 02 Dec 2025 17:12:03 GMT" } ], "recorded_with": "VCR 6.0.0" diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-finding-to-a-Jira-issue-returns-OK-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-finding-to-a-Jira-issue-returns-OK-response.frozen new file mode 100644 index 000000000..e21d532e4 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-finding-to-a-Jira-issue-returns-OK-response.frozen @@ -0,0 +1 @@ +2025-11-20T15:49:48.969Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-finding-to-a-Jira-issue-returns-OK-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-finding-to-a-Jira-issue-returns-OK-response.json new file mode 100644 index 000000000..81e85f287 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-finding-to-a-Jira-issue-returns-OK-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":{\"attributes\":{\"jira_issue_url\":\"https://datadoghq-sandbox-538.atlassian.net/browse/CSMSEC-105476\"},\"relationships\":{\"findings\":{\"data\":[{\"id\":\"OTQ3NjJkMmYwMTIzMzMxNTc1Y2Q4MTA5NWU0NTBmMDl-ZjE3NjMxZWVkYzBjZGI1NDY2NWY2OGQxZDk4MDY4MmI=\",\"type\":\"findings\"}]},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}},\"type\":\"jira_issues\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "patch", + "uri": "https://api.datadoghq.com/api/v2/security/findings/jira_issues" + }, + "response": { + "body": { + "string": "{\"data\":{\"id\":\"9efb1118-ed9c-4b02-b13b-f3acf8415f7c\",\"type\":\"cases\",\"attributes\":{\"created_at\":\"2025-11-20T15:22:44.644286Z\",\"creation_source\":\"CS_SECURITY_FINDING\",\"description\":\"A description\",\"insights\":[{\"type\":\"SECURITY_FINDING\",\"ref\":\"/security/appsec/vm/library/vulnerability/94762d2f0123331575cd81095e450f09?detection=static\",\"resource_id\":\"OTQ3NjJkMmYwMTIzMzMxNTc1Y2Q4MTA5NWU0NTBmMDl-ZjE3NjMxZWVkYzBjZGI1NDY2NWY2OGQxZDk4MDY4MmI=\"}],\"jira_issue\":{\"status\":\"COMPLETED\",\"result\":{\"issue_id\":\"2404808\",\"issue_key\":\"CSMSEC-105476\",\"issue_url\":\"https://datadoghq-sandbox-538.atlassian.net/browse/CSMSEC-105476\",\"account_id\":\"fdcffa62-24ab-4914-a195-a22bdc607030\"}},\"key\":\"CSMINV-463\",\"modified_at\":\"2025-11-20T15:49:53.272293Z\",\"priority\":\"NOT_DEFINED\",\"status\":\"OPEN\",\"status_group\":\"SG_OPEN\",\"status_name\":\"Open\",\"title\":\"A title\",\"type\":\"SECURITY\"},\"relationships\":{\"created_by\":{\"data\":{\"id\":\"dc09afab-6ae7-11ef-92b1-828dac1b0195\",\"type\":\"users\"}},\"modified_by\":{\"data\":{\"id\":\"dc09afab-6ae7-11ef-92b1-828dac1b0195\",\"type\":\"users\"}},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}}}}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 200, + "message": "OK" + } + }, + "recorded_at": "Thu, 20 Nov 2025 15:49:48 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-finding-to-a-case-returns-OK-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-finding-to-a-case-returns-OK-response.frozen new file mode 100644 index 000000000..24c38af62 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-finding-to-a-case-returns-OK-response.frozen @@ -0,0 +1 @@ +2025-11-19T16:20:46.726Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-finding-to-a-case-returns-OK-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-finding-to-a-case-returns-OK-response.json new file mode 100644 index 000000000..7cf7423a6 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-finding-to-a-case-returns-OK-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":{\"id\":\"7d16945b-baf8-411e-ab2a-20fe43af1ea3\",\"relationships\":{\"findings\":{\"data\":[{\"id\":\"ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=\",\"type\":\"findings\"}]}},\"type\":\"cases\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "patch", + "uri": "https://api.datadoghq.com/api/v2/security/findings/cases/7d16945b-baf8-411e-ab2a-20fe43af1ea3" + }, + "response": { + "body": { + "string": "{\"data\":{\"id\":\"7d16945b-baf8-411e-ab2a-20fe43af1ea3\",\"type\":\"cases\",\"attributes\":{\"created_at\":\"2025-11-19T13:54:23.634063Z\",\"creation_source\":\"CS_SECURITY_FINDING\",\"description\":\"A description\",\"insights\":[{\"type\":\"SECURITY_FINDING\",\"ref\":\"/security/appsec/vm/library/vulnerability/dfa027f7c037b2f77159adc027fecb56?detection=static\",\"resource_id\":\"ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=\"}],\"key\":\"CSMINV-459\",\"modified_at\":\"2025-11-19T16:20:51.754979Z\",\"priority\":\"NOT_DEFINED\",\"status\":\"OPEN\",\"status_group\":\"SG_OPEN\",\"status_name\":\"Open\",\"title\":\"A title\",\"type\":\"SECURITY\"},\"relationships\":{\"created_by\":{\"data\":{\"id\":\"dc09afab-6ae7-11ef-92b1-828dac1b0195\",\"type\":\"users\"}},\"modified_by\":{\"data\":{\"id\":\"dc09afab-6ae7-11ef-92b1-828dac1b0195\",\"type\":\"users\"}},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}}}}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 200, + "message": "OK" + } + }, + "recorded_at": "Wed, 19 Nov 2025 16:20:46 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-Jira-issue-returns-Bad-Request-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-Jira-issue-returns-Bad-Request-response.frozen new file mode 100644 index 000000000..7b6703448 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-Jira-issue-returns-Bad-Request-response.frozen @@ -0,0 +1 @@ +2025-11-20T15:53:19.037Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-Jira-issue-returns-Bad-Request-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-Jira-issue-returns-Bad-Request-response.json new file mode 100644 index 000000000..da5c03a61 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-Jira-issue-returns-Bad-Request-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":{\"attributes\":{\"jira_issue_url\":\"https://datadoghq-sandbox-538.atlassian.net/browse/CSMSEC-105476\"},\"relationships\":{\"findings\":{\"data\":[]},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}},\"type\":\"jira_issues\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "patch", + "uri": "https://api.datadoghq.com/api/v2/security/findings/jira_issues" + }, + "response": { + "body": { + "string": "{\"errors\":[{\"status\":\"400\",\"title\":\"Bad Request\",\"detail\":\"no finding provided\"}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 400, + "message": "Bad Request" + } + }, + "recorded_at": "Thu, 20 Nov 2025 15:53:19 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-Jira-issue-returns-Not-Found-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-Jira-issue-returns-Not-Found-response.frozen new file mode 100644 index 000000000..4495f3bf0 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-Jira-issue-returns-Not-Found-response.frozen @@ -0,0 +1 @@ +2025-11-20T15:59:56.064Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-Jira-issue-returns-Not-Found-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-Jira-issue-returns-Not-Found-response.json new file mode 100644 index 000000000..35bfff268 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-Jira-issue-returns-Not-Found-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":{\"attributes\":{\"jira_issue_url\":\"https://datadoghq-sandbox-538.atlassian.net/browse/CSMSEC-105476\"},\"relationships\":{\"findings\":{\"data\":[{\"id\":\"wrong-finding-id\",\"type\":\"findings\"}]},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}},\"type\":\"jira_issues\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "patch", + "uri": "https://api.datadoghq.com/api/v2/security/findings/jira_issues" + }, + "response": { + "body": { + "string": "{\"errors\":[{\"status\":\"404\",\"title\":\"Not Found\",\"detail\":\"finding not found\"}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 404, + "message": "Not Found" + } + }, + "recorded_at": "Thu, 20 Nov 2025 15:59:56 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-Jira-issue-returns-OK-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-Jira-issue-returns-OK-response.frozen new file mode 100644 index 000000000..8a74e023f --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-Jira-issue-returns-OK-response.frozen @@ -0,0 +1 @@ +2025-11-20T15:52:21.664Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-Jira-issue-returns-OK-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-Jira-issue-returns-OK-response.json new file mode 100644 index 000000000..9786ff838 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-Jira-issue-returns-OK-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":{\"attributes\":{\"jira_issue_url\":\"https://datadoghq-sandbox-538.atlassian.net/browse/CSMSEC-105476\"},\"relationships\":{\"findings\":{\"data\":[{\"id\":\"OTQ3NjJkMmYwMTIzMzMxNTc1Y2Q4MTA5NWU0NTBmMDl-ZjE3NjMxZWVkYzBjZGI1NDY2NWY2OGQxZDk4MDY4MmI=\",\"type\":\"findings\"},{\"id\":\"MTNjN2ZmYWMzMDIxYmU1ZDFiZDRjNWUwN2I1NzVmY2F-YTA3MzllMTUzNWM3NmEyZjdiNzEzOWM5YmViZTMzOGM=\",\"type\":\"findings\"}]},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}},\"type\":\"jira_issues\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "patch", + "uri": "https://api.datadoghq.com/api/v2/security/findings/jira_issues" + }, + "response": { + "body": { + "string": "{\"data\":{\"id\":\"9efb1118-ed9c-4b02-b13b-f3acf8415f7c\",\"type\":\"cases\",\"attributes\":{\"created_at\":\"2025-11-20T15:22:44.644286Z\",\"creation_source\":\"CS_SECURITY_FINDING\",\"description\":\"A description\",\"insights\":[{\"type\":\"SECURITY_FINDING\",\"ref\":\"/security/appsec/vm/library/vulnerability/94762d2f0123331575cd81095e450f09?detection=static\",\"resource_id\":\"OTQ3NjJkMmYwMTIzMzMxNTc1Y2Q4MTA5NWU0NTBmMDl-ZjE3NjMxZWVkYzBjZGI1NDY2NWY2OGQxZDk4MDY4MmI=\"},{\"type\":\"SECURITY_FINDING\",\"ref\":\"/security/appsec/vm/library/vulnerability/13c7ffac3021be5d1bd4c5e07b575fca?detection=static\",\"resource_id\":\"MTNjN2ZmYWMzMDIxYmU1ZDFiZDRjNWUwN2I1NzVmY2F-YTA3MzllMTUzNWM3NmEyZjdiNzEzOWM5YmViZTMzOGM=\"}],\"jira_issue\":{\"status\":\"COMPLETED\",\"result\":{\"issue_id\":\"2404808\",\"issue_key\":\"CSMSEC-105476\",\"issue_url\":\"https://datadoghq-sandbox-538.atlassian.net/browse/CSMSEC-105476\",\"account_id\":\"fdcffa62-24ab-4914-a195-a22bdc607030\"}},\"key\":\"CSMINV-463\",\"modified_at\":\"2025-11-20T15:52:25.368628Z\",\"priority\":\"NOT_DEFINED\",\"status\":\"OPEN\",\"status_group\":\"SG_OPEN\",\"status_name\":\"Open\",\"title\":\"A title\",\"type\":\"SECURITY\"},\"relationships\":{\"created_by\":{\"data\":{\"id\":\"dc09afab-6ae7-11ef-92b1-828dac1b0195\",\"type\":\"users\"}},\"modified_by\":{\"data\":{\"id\":\"dc09afab-6ae7-11ef-92b1-828dac1b0195\",\"type\":\"users\"}},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}}}}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 200, + "message": "OK" + } + }, + "recorded_at": "Thu, 20 Nov 2025 15:52:21 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-case-returns-Bad-Request-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-case-returns-Bad-Request-response.frozen new file mode 100644 index 000000000..1adeacaf4 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-case-returns-Bad-Request-response.frozen @@ -0,0 +1 @@ +2025-11-19T16:16:38.781Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-case-returns-Bad-Request-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-case-returns-Bad-Request-response.json new file mode 100644 index 000000000..8d05d3778 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-case-returns-Bad-Request-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":{\"id\":\"7d16945b-baf8-411e-ab2a-20fe43af1ea3\",\"relationships\":{\"findings\":{\"data\":[]}},\"type\":\"cases\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "patch", + "uri": "https://api.datadoghq.com/api/v2/security/findings/cases/7d16945b-baf8-411e-ab2a-20fe43af1ea3" + }, + "response": { + "body": { + "string": "{\"errors\":[{\"status\":\"400\",\"title\":\"Bad Request\",\"detail\":\"no finding provided\"}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 400, + "message": "Bad Request" + } + }, + "recorded_at": "Wed, 19 Nov 2025 16:16:38 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-case-returns-Not-Found-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-case-returns-Not-Found-response.frozen new file mode 100644 index 000000000..ed7d98397 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-case-returns-Not-Found-response.frozen @@ -0,0 +1 @@ +2025-11-19T16:17:49.938Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-case-returns-Not-Found-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-case-returns-Not-Found-response.json new file mode 100644 index 000000000..70beed0d8 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-case-returns-Not-Found-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":{\"id\":\"wrong-case-id\",\"relationships\":{\"findings\":{\"data\":[{\"id\":\"ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=\",\"type\":\"findings\"}]}},\"type\":\"cases\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "patch", + "uri": "https://api.datadoghq.com/api/v2/security/findings/cases/wrong-case-id" + }, + "response": { + "body": { + "string": "{\"errors\":[{\"status\":\"404\",\"title\":\"Not Found\",\"detail\":\"failed to get case: case not found\"}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 404, + "message": "Not Found" + } + }, + "recorded_at": "Wed, 19 Nov 2025 16:17:49 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-case-returns-OK-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-case-returns-OK-response.frozen new file mode 100644 index 000000000..376033b3d --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-case-returns-OK-response.frozen @@ -0,0 +1 @@ +2025-11-19T16:23:42.957Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-case-returns-OK-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-case-returns-OK-response.json new file mode 100644 index 000000000..9101e40a1 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Attach-security-findings-to-a-case-returns-OK-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":{\"id\":\"7d16945b-baf8-411e-ab2a-20fe43af1ea3\",\"relationships\":{\"findings\":{\"data\":[{\"id\":\"ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=\",\"type\":\"findings\"},{\"id\":\"MmUzMzZkODQ2YTI3NDU0OTk4NDk3NzhkOTY5YjU2Zjh-YWJjZGI1ODI4OTYzNWM3ZmUwZTBlOWRkYTRiMGUyOGQ=\",\"type\":\"findings\"}]}},\"type\":\"cases\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "patch", + "uri": "https://api.datadoghq.com/api/v2/security/findings/cases/7d16945b-baf8-411e-ab2a-20fe43af1ea3" + }, + "response": { + "body": { + "string": "{\"data\":{\"id\":\"7d16945b-baf8-411e-ab2a-20fe43af1ea3\",\"type\":\"cases\",\"attributes\":{\"created_at\":\"2025-11-19T13:54:23.634063Z\",\"creation_source\":\"CS_SECURITY_FINDING\",\"description\":\"A description\",\"insights\":[{\"type\":\"SECURITY_FINDING\",\"ref\":\"/security/appsec/vm/library/vulnerability/dfa027f7c037b2f77159adc027fecb56?detection=static\",\"resource_id\":\"ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=\"},{\"type\":\"SECURITY_FINDING\",\"ref\":\"/security/appsec/vm/library/vulnerability/36d53183f8fefbbc2208878f3d2011f0?detection=static\",\"resource_id\":\"MzZkNTMxODNmOGZlZmJiYzIyMDg4NzhmM2QyMDExZjB-ZmY5NzUwNDQzYTE0MGIyNDM1MTg4YjkxZDNmMDU4OGU=\"},{\"type\":\"SECURITY_FINDING\",\"ref\":\"/security/appsec/vm/library/vulnerability/2e336d846a2745499849778d969b56f8?detection=static\",\"resource_id\":\"MmUzMzZkODQ2YTI3NDU0OTk4NDk3NzhkOTY5YjU2Zjh-YWJjZGI1ODI4OTYzNWM3ZmUwZTBlOWRkYTRiMGUyOGQ=\"}],\"key\":\"CSMINV-459\",\"modified_at\":\"2025-11-19T16:23:22.109092Z\",\"priority\":\"NOT_DEFINED\",\"status\":\"OPEN\",\"status_group\":\"SG_OPEN\",\"status_name\":\"Open\",\"title\":\"A title\",\"type\":\"SECURITY\"},\"relationships\":{\"created_by\":{\"data\":{\"id\":\"dc09afab-6ae7-11ef-92b1-828dac1b0195\",\"type\":\"users\"}},\"modified_by\":{\"data\":{\"id\":\"dc09afab-6ae7-11ef-92b1-828dac1b0195\",\"type\":\"users\"}},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}}}}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 200, + "message": "OK" + } + }, + "recorded_at": "Wed, 19 Nov 2025 16:23:42 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issue-for-security-finding-returns-Created-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issue-for-security-finding-returns-Created-response.frozen new file mode 100644 index 000000000..6c188712b --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issue-for-security-finding-returns-Created-response.frozen @@ -0,0 +1 @@ +2025-11-19T17:01:11.179Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issue-for-security-finding-returns-Created-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issue-for-security-finding-returns-Created-response.json new file mode 100644 index 000000000..b2436d247 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issue-for-security-finding-returns-Created-response.json @@ -0,0 +1,69 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":[{\"attributes\":{},\"relationships\":{\"case\":{\"data\":{\"id\":\"6a773295-8729-4034-aada-53b64cbe02e7\",\"type\":\"cases\"}}},\"type\":\"jira_issues\"}],\"included\":[{\"attributes\":{\"description\":\"A description\",\"title\":\"A title\"},\"id\":\"6a773295-8729-4034-aada-53b64cbe02e7\",\"relationships\":{\"findings\":{\"data\":[{\"id\":\"ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=\",\"type\":\"findings\"}]},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}},\"type\":\"cases\"},{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"},{\"id\":\"ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=\",\"type\":\"findings\"}]}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "post", + "uri": "https://api.datadoghq.com/api/v2/security/findings/jira_issues" + }, + "response": { + "body": { + "string": "{\"data\":[{\"id\":\"6a773295-8729-4034-aada-53b64cbe02e7\",\"type\":\"cases\",\"attributes\":{\"created_at\":\"2025-11-19T17:01:15.21452Z\",\"creation_source\":\"CS_SECURITY_FINDING\",\"description\":\"A description\",\"insights\":[{\"type\":\"SECURITY_FINDING\",\"ref\":\"/security/appsec/vm/library/vulnerability/dfa027f7c037b2f77159adc027fecb56?detection=static\",\"resource_id\":\"ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=\"}],\"jira_issue\":{\"status\":\"COMPLETED\",\"result\":{\"issue_id\":\"2402037\",\"issue_key\":\"CSMSEC-105473\",\"issue_url\":\"https://datadoghq-sandbox-538.atlassian.net/browse/CSMSEC-105473\",\"account_id\":\"fdcffa62-24ab-4914-a195-a22bdc607030\"}},\"key\":\"CSMINV-461\",\"modified_at\":\"2025-11-19T17:01:16.621974Z\",\"priority\":\"NOT_DEFINED\",\"status\":\"OPEN\",\"status_group\":\"SG_OPEN\",\"status_name\":\"Open\",\"title\":\"A title\",\"type\":\"SECURITY\"},\"relationships\":{\"created_by\":{\"data\":{\"id\":\"dc09afab-6ae7-11ef-92b1-828dac1b0195\",\"type\":\"users\"}},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}}}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 201, + "message": "Created" + } + }, + "recorded_at": "Wed, 19 Nov 2025 17:01:11 GMT" + }, + { + "request": { + "body": { + "string": "{\"data\":{\"id\":\"6a773295-8729-4034-aada-53b64cbe02e7\",\"relationships\":{\"findings\":{\"data\":[{\"id\":\"ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=\",\"type\":\"findings\"}]}},\"type\":\"cases\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "*/*" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "delete", + "uri": "https://api.datadoghq.com/api/v2/security/findings/cases" + }, + "response": { + "body": { + "string": "", + "encoding": null + }, + "headers": {}, + "status": { + "code": 204, + "message": "No Content" + } + }, + "recorded_at": "Wed, 19 Nov 2025 17:01:11 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issue-for-security-findings-returns-Created-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issue-for-security-findings-returns-Created-response.frozen new file mode 100644 index 000000000..8bb7a59bf --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issue-for-security-findings-returns-Created-response.frozen @@ -0,0 +1 @@ +2025-11-21T14:49:30.001Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issue-for-security-findings-returns-Created-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issue-for-security-findings-returns-Created-response.json new file mode 100644 index 000000000..96474535d --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issue-for-security-findings-returns-Created-response.json @@ -0,0 +1,69 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":[{\"attributes\":{},\"relationships\":{\"case\":{\"data\":{\"id\":\"e469ceda-957a-4557-a607-9ff25032e9ca\",\"type\":\"cases\"}}},\"type\":\"jira_issues\"}],\"included\":[{\"attributes\":{\"description\":\"A description\",\"title\":\"A title\"},\"id\":\"e469ceda-957a-4557-a607-9ff25032e9ca\",\"relationships\":{\"findings\":{\"data\":[{\"id\":\"MzUxMDI4OWYyYWEyODRhYjQ0Zjg2YjY2ZTFmNjRjYzd-NDU2OWQyNTk1MjM5OGI2NzJjMTVhYjhiODY1ZDcwZWY=\",\"type\":\"findings\"},{\"id\":\"ZjE2ZGI5YjdmYTQyYzhhMDQ3Nzc3YjM1NGQ2Y2NmZTd-NDU2OWQyNTk1MjM5OGI2NzJjMTVhYjhiODY1ZDcwZWY=\",\"type\":\"findings\"}]},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}},\"type\":\"cases\"},{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"},{\"id\":\"MzUxMDI4OWYyYWEyODRhYjQ0Zjg2YjY2ZTFmNjRjYzd-NDU2OWQyNTk1MjM5OGI2NzJjMTVhYjhiODY1ZDcwZWY=\",\"type\":\"findings\"},{\"id\":\"ZjE2ZGI5YjdmYTQyYzhhMDQ3Nzc3YjM1NGQ2Y2NmZTd-NDU2OWQyNTk1MjM5OGI2NzJjMTVhYjhiODY1ZDcwZWY=\",\"type\":\"findings\"}]}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "post", + "uri": "https://api.datadoghq.com/api/v2/security/findings/jira_issues" + }, + "response": { + "body": { + "string": "{\"data\":[{\"id\":\"e469ceda-957a-4557-a607-9ff25032e9ca\",\"type\":\"cases\",\"attributes\":{\"created_at\":\"2025-11-21T14:49:32.034826Z\",\"creation_source\":\"CS_SECURITY_FINDING\",\"description\":\"A description\",\"insights\":[{\"type\":\"SECURITY_FINDING\",\"ref\":\"/security/appsec/vm/library/vulnerability/f16db9b7fa42c8a047777b354d6ccfe7?detection=static\",\"resource_id\":\"ZjE2ZGI5YjdmYTQyYzhhMDQ3Nzc3YjM1NGQ2Y2NmZTd-NDU2OWQyNTk1MjM5OGI2NzJjMTVhYjhiODY1ZDcwZWY=\"},{\"type\":\"SECURITY_FINDING\",\"ref\":\"/security/appsec/vm/library/vulnerability/3510289f2aa284ab44f86b66e1f64cc7?detection=static\",\"resource_id\":\"MzUxMDI4OWYyYWEyODRhYjQ0Zjg2YjY2ZTFmNjRjYzd-NDU2OWQyNTk1MjM5OGI2NzJjMTVhYjhiODY1ZDcwZWY=\"}],\"jira_issue\":{\"status\":\"COMPLETED\",\"result\":{\"issue_id\":\"2407744\",\"issue_key\":\"CSMSEC-105481\",\"issue_url\":\"https://datadoghq-sandbox-538.atlassian.net/browse/CSMSEC-105481\",\"account_id\":\"fdcffa62-24ab-4914-a195-a22bdc607030\"}},\"key\":\"CSMINV-468\",\"modified_at\":\"2025-11-21T14:49:33.306003Z\",\"priority\":\"NOT_DEFINED\",\"status\":\"OPEN\",\"status_group\":\"SG_OPEN\",\"status_name\":\"Open\",\"title\":\"A title\",\"type\":\"SECURITY\"},\"relationships\":{\"created_by\":{\"data\":{\"id\":\"dc09afab-6ae7-11ef-92b1-828dac1b0195\",\"type\":\"users\"}},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}}}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 201, + "message": "Created" + } + }, + "recorded_at": "Fri, 21 Nov 2025 14:49:30 GMT" + }, + { + "request": { + "body": { + "string": "{\"data\":{\"id\":\"e469ceda-957a-4557-a607-9ff25032e9ca\",\"relationships\":{\"findings\":{\"data\":[{\"id\":\"ZjE2ZGI5YjdmYTQyYzhhMDQ3Nzc3YjM1NGQ2Y2NmZTd-NDU2OWQyNTk1MjM5OGI2NzJjMTVhYjhiODY1ZDcwZWY=\",\"type\":\"findings\"}]}},\"type\":\"cases\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "*/*" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "delete", + "uri": "https://api.datadoghq.com/api/v2/security/findings/cases" + }, + "response": { + "body": { + "string": "", + "encoding": null + }, + "headers": {}, + "status": { + "code": 204, + "message": "No Content" + } + }, + "recorded_at": "Fri, 21 Nov 2025 14:49:30 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issues-for-security-findings-returns-Bad-Request-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issues-for-security-findings-returns-Bad-Request-response.frozen new file mode 100644 index 000000000..ff98ffb1a --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issues-for-security-findings-returns-Bad-Request-response.frozen @@ -0,0 +1 @@ +2025-11-20T12:01:47.295Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issues-for-security-findings-returns-Bad-Request-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issues-for-security-findings-returns-Bad-Request-response.json new file mode 100644 index 000000000..b6a461a85 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issues-for-security-findings-returns-Bad-Request-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":[{\"attributes\":{},\"relationships\":{\"case\":{\"data\":{\"id\":\"a7c38bab-ae98-4113-878c-c98799f914c2\",\"type\":\"cases\"}}},\"type\":\"jira_issues\"}],\"included\":[{\"id\":\"a7c38bab-ae98-4113-878c-c98799f914c2\",\"relationships\":{\"findings\":{\"data\":[]},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}},\"type\":\"cases\"},{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}]}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "post", + "uri": "https://api.datadoghq.com/api/v2/security/findings/jira_issues" + }, + "response": { + "body": { + "string": "{\"errors\":[{\"status\":\"400\",\"title\":\"Bad Request\",\"detail\":\"no finding provided\"}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 400, + "message": "Bad Request" + } + }, + "recorded_at": "Thu, 20 Nov 2025 12:01:47 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issues-for-security-findings-returns-Created-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issues-for-security-findings-returns-Created-response.frozen new file mode 100644 index 000000000..e5b6d0d76 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issues-for-security-findings-returns-Created-response.frozen @@ -0,0 +1 @@ +2025-11-20T15:32:21.828Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issues-for-security-findings-returns-Created-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issues-for-security-findings-returns-Created-response.json new file mode 100644 index 000000000..5c03e38f9 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issues-for-security-findings-returns-Created-response.json @@ -0,0 +1,69 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":[{\"attributes\":{},\"relationships\":{\"case\":{\"data\":{\"id\":\"53e242c6-a7d6-46ad-9680-b8d14753f716\",\"type\":\"cases\"}}},\"type\":\"jira_issues\"},{\"attributes\":{},\"relationships\":{\"case\":{\"data\":{\"id\":\"195772b2-1f53-41d2-b81e-48c8e6c21d33\",\"type\":\"cases\"}}},\"type\":\"jira_issues\"}],\"included\":[{\"attributes\":{\"description\":\"A description\",\"title\":\"A title\"},\"id\":\"53e242c6-a7d6-46ad-9680-b8d14753f716\",\"relationships\":{\"findings\":{\"data\":[{\"id\":\"OTQ3NjJkMmYwMTIzMzMxNTc1Y2Q4MTA5NWU0NTBmMDl-ZjE3NjMxZWVkYzBjZGI1NDY2NWY2OGQxZDk4MDY4MmI=\",\"type\":\"findings\"}]},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}},\"type\":\"cases\"},{\"attributes\":{\"description\":\"A description\",\"title\":\"A title\"},\"id\":\"195772b2-1f53-41d2-b81e-48c8e6c21d33\",\"relationships\":{\"findings\":{\"data\":[{\"id\":\"MTNjN2ZmYWMzMDIxYmU1ZDFiZDRjNWUwN2I1NzVmY2F-YTA3MzllMTUzNWM3NmEyZjdiNzEzOWM5YmViZTMzOGM=\",\"type\":\"findings\"}]},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}},\"type\":\"cases\"},{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"},{\"id\":\"OTQ3NjJkMmYwMTIzMzMxNTc1Y2Q4MTA5NWU0NTBmMDl-ZjE3NjMxZWVkYzBjZGI1NDY2NWY2OGQxZDk4MDY4MmI=\",\"type\":\"findings\"},{\"id\":\"MTNjN2ZmYWMzMDIxYmU1ZDFiZDRjNWUwN2I1NzVmY2F-YTA3MzllMTUzNWM3NmEyZjdiNzEzOWM5YmViZTMzOGM=\",\"type\":\"findings\"}]}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "post", + "uri": "https://api.datadoghq.com/api/v2/security/findings/jira_issues" + }, + "response": { + "body": { + "string": "{\"data\":[{\"id\":\"53e242c6-a7d6-46ad-9680-b8d14753f716\",\"type\":\"cases\",\"attributes\":{\"created_at\":\"2025-11-20T15:32:23.777159Z\",\"creation_source\":\"CS_SECURITY_FINDING\",\"description\":\"A description\",\"insights\":[{\"type\":\"SECURITY_FINDING\",\"ref\":\"/security/appsec/vm/library/vulnerability/94762d2f0123331575cd81095e450f09?detection=static\",\"resource_id\":\"OTQ3NjJkMmYwMTIzMzMxNTc1Y2Q4MTA5NWU0NTBmMDl-ZjE3NjMxZWVkYzBjZGI1NDY2NWY2OGQxZDk4MDY4MmI=\"}],\"jira_issue\":{\"status\":\"COMPLETED\",\"result\":{\"issue_id\":\"2404837\",\"issue_key\":\"CSMSEC-105480\",\"issue_url\":\"https://datadoghq-sandbox-538.atlassian.net/browse/CSMSEC-105480\",\"account_id\":\"fdcffa62-24ab-4914-a195-a22bdc607030\"}},\"key\":\"CSMINV-467\",\"modified_at\":\"2025-11-20T15:32:25.088199Z\",\"priority\":\"NOT_DEFINED\",\"status\":\"OPEN\",\"status_group\":\"SG_OPEN\",\"status_name\":\"Open\",\"title\":\"A title\",\"type\":\"SECURITY\"},\"relationships\":{\"created_by\":{\"data\":{\"id\":\"dc09afab-6ae7-11ef-92b1-828dac1b0195\",\"type\":\"users\"}},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}}},{\"id\":\"195772b2-1f53-41d2-b81e-48c8e6c21d33\",\"type\":\"cases\",\"attributes\":{\"created_at\":\"2025-11-20T15:32:23.776904Z\",\"creation_source\":\"CS_SECURITY_FINDING\",\"description\":\"A description\",\"insights\":[{\"type\":\"SECURITY_FINDING\",\"ref\":\"/security/appsec/vm/library/vulnerability/13c7ffac3021be5d1bd4c5e07b575fca?detection=static\",\"resource_id\":\"MTNjN2ZmYWMzMDIxYmU1ZDFiZDRjNWUwN2I1NzVmY2F-YTA3MzllMTUzNWM3NmEyZjdiNzEzOWM5YmViZTMzOGM=\"}],\"jira_issue\":{\"status\":\"COMPLETED\",\"result\":{\"issue_id\":\"2404836\",\"issue_key\":\"CSMSEC-105479\",\"issue_url\":\"https://datadoghq-sandbox-538.atlassian.net/browse/CSMSEC-105479\",\"account_id\":\"fdcffa62-24ab-4914-a195-a22bdc607030\"}},\"key\":\"CSMINV-466\",\"modified_at\":\"2025-11-20T15:32:24.96456Z\",\"priority\":\"NOT_DEFINED\",\"status\":\"OPEN\",\"status_group\":\"SG_OPEN\",\"status_name\":\"Open\",\"title\":\"A title\",\"type\":\"SECURITY\"},\"relationships\":{\"created_by\":{\"data\":{\"id\":\"dc09afab-6ae7-11ef-92b1-828dac1b0195\",\"type\":\"users\"}},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}}}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 201, + "message": "Created" + } + }, + "recorded_at": "Thu, 20 Nov 2025 15:32:21 GMT" + }, + { + "request": { + "body": { + "string": "{\"data\":{\"id\":\"53e242c6-a7d6-46ad-9680-b8d14753f716\",\"relationships\":{\"findings\":{\"data\":[{\"id\":\"OTQ3NjJkMmYwMTIzMzMxNTc1Y2Q4MTA5NWU0NTBmMDl-ZjE3NjMxZWVkYzBjZGI1NDY2NWY2OGQxZDk4MDY4MmI=\",\"type\":\"findings\"}]}},\"type\":\"cases\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "*/*" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "delete", + "uri": "https://api.datadoghq.com/api/v2/security/findings/cases" + }, + "response": { + "body": { + "string": "", + "encoding": null + }, + "headers": {}, + "status": { + "code": 204, + "message": "No Content" + } + }, + "recorded_at": "Thu, 20 Nov 2025 15:32:21 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issues-for-security-findings-returns-Not-Found-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issues-for-security-findings-returns-Not-Found-response.frozen new file mode 100644 index 000000000..f0ed0dd3f --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issues-for-security-findings-returns-Not-Found-response.frozen @@ -0,0 +1 @@ +2025-11-20T15:42:51.100Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issues-for-security-findings-returns-Not-Found-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issues-for-security-findings-returns-Not-Found-response.json new file mode 100644 index 000000000..af2410050 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-Jira-issues-for-security-findings-returns-Not-Found-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":[{\"attributes\":{},\"relationships\":{\"case\":{\"data\":{\"id\":\"6ed1d7c2-e1a3-4369-b92b-a38d3cc75cf3\",\"type\":\"cases\"}}},\"type\":\"jira_issues\"}],\"included\":[{\"attributes\":{\"description\":\"A description\",\"title\":\"A title\"},\"id\":\"6ed1d7c2-e1a3-4369-b92b-a38d3cc75cf3\",\"relationships\":{\"findings\":{\"data\":[{\"id\":\"YzM2MTFjYzcyNmY0Zjg4MTAxZmRlNjQ1MWU1ZGQwYzR-YzI5NzE5Y2Y4MzU4ZjliNzhkNjYxNTY0ODIzZDQ2YTM=\",\"type\":\"findings\"}]},\"project\":{\"data\":{\"id\":\"00000000-0000-0000-0000-000000000000\",\"type\":\"projects\"}}},\"type\":\"cases\"},{\"id\":\"00000000-0000-0000-0000-000000000000\",\"type\":\"projects\"},{\"id\":\"YzM2MTFjYzcyNmY0Zjg4MTAxZmRlNjQ1MWU1ZGQwYzR-YzI5NzE5Y2Y4MzU4ZjliNzhkNjYxNTY0ODIzZDQ2YTM=\",\"type\":\"findings\"}]}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "post", + "uri": "https://api.datadoghq.com/api/v2/security/findings/jira_issues" + }, + "response": { + "body": { + "string": "{\"errors\":[{\"status\":\"404\",\"title\":\"Not Found\",\"detail\":\"project not found\"}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 404, + "message": "Not Found" + } + }, + "recorded_at": "Thu, 20 Nov 2025 15:42:51 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-case-for-security-finding-returns-Created-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Create-case-for-security-finding-returns-Created-response.frozen new file mode 100644 index 000000000..a6ccca66a --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-case-for-security-finding-returns-Created-response.frozen @@ -0,0 +1 @@ +2025-11-19T13:45:48.321Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-case-for-security-finding-returns-Created-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Create-case-for-security-finding-returns-Created-response.json new file mode 100644 index 000000000..9483c7a95 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-case-for-security-finding-returns-Created-response.json @@ -0,0 +1,69 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":[{\"attributes\":{\"description\":\"A description\",\"title\":\"A title\"},\"relationships\":{\"findings\":{\"data\":[{\"id\":\"ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=\",\"type\":\"findings\"}]},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}},\"type\":\"cases\"}]}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "post", + "uri": "https://api.datadoghq.com/api/v2/security/findings/cases" + }, + "response": { + "body": { + "string": "{\"data\":[{\"id\":\"639c5df7-2352-4fc6-9d39-7dc8bdb8af14\",\"type\":\"cases\",\"attributes\":{\"created_at\":\"2025-11-19T13:45:50.295906Z\",\"creation_source\":\"CS_SECURITY_FINDING\",\"description\":\"A description\",\"insights\":[{\"type\":\"SECURITY_FINDING\",\"ref\":\"/security/appsec/vm/library/vulnerability/dfa027f7c037b2f77159adc027fecb56?detection=static\",\"resource_id\":\"ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=\"}],\"key\":\"CSMINV-454\",\"priority\":\"NOT_DEFINED\",\"status\":\"OPEN\",\"status_group\":\"SG_OPEN\",\"status_name\":\"Open\",\"title\":\"A title\",\"type\":\"SECURITY\"},\"relationships\":{\"created_by\":{\"data\":{\"id\":\"dc09afab-6ae7-11ef-92b1-828dac1b0195\",\"type\":\"users\"}},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}}}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 201, + "message": "Created" + } + }, + "recorded_at": "Wed, 19 Nov 2025 13:45:48 GMT" + }, + { + "request": { + "body": { + "string": "{\"data\":{\"id\":\"639c5df7-2352-4fc6-9d39-7dc8bdb8af14\",\"relationships\":{\"findings\":{\"data\":[{\"id\":\"ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=\",\"type\":\"findings\"}]}},\"type\":\"cases\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "*/*" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "delete", + "uri": "https://api.datadoghq.com/api/v2/security/findings/cases" + }, + "response": { + "body": { + "string": "", + "encoding": null + }, + "headers": {}, + "status": { + "code": 204, + "message": "No Content" + } + }, + "recorded_at": "Wed, 19 Nov 2025 13:45:48 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-case-for-security-findings-returns-Created-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Create-case-for-security-findings-returns-Created-response.frozen new file mode 100644 index 000000000..11d711428 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-case-for-security-findings-returns-Created-response.frozen @@ -0,0 +1 @@ +2025-11-19T13:46:07.661Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-case-for-security-findings-returns-Created-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Create-case-for-security-findings-returns-Created-response.json new file mode 100644 index 000000000..fef95c117 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-case-for-security-findings-returns-Created-response.json @@ -0,0 +1,69 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":[{\"attributes\":{\"description\":\"A description\",\"title\":\"A title\"},\"relationships\":{\"findings\":{\"data\":[{\"id\":\"ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=\",\"type\":\"findings\"},{\"id\":\"MzZkNTMxODNmOGZlZmJiYzIyMDg4NzhmM2QyMDExZjB-ZmY5NzUwNDQzYTE0MGIyNDM1MTg4YjkxZDNmMDU4OGU=\",\"type\":\"findings\"}]},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}},\"type\":\"cases\"}]}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "post", + "uri": "https://api.datadoghq.com/api/v2/security/findings/cases" + }, + "response": { + "body": { + "string": "{\"data\":[{\"id\":\"2c1ac0c4-e8cf-4699-8781-09077b10d2a0\",\"type\":\"cases\",\"attributes\":{\"created_at\":\"2025-11-19T13:46:09.874194Z\",\"creation_source\":\"CS_SECURITY_FINDING\",\"description\":\"A description\",\"insights\":[{\"type\":\"SECURITY_FINDING\",\"ref\":\"/security/appsec/vm/library/vulnerability/36d53183f8fefbbc2208878f3d2011f0?detection=static\",\"resource_id\":\"MzZkNTMxODNmOGZlZmJiYzIyMDg4NzhmM2QyMDExZjB-ZmY5NzUwNDQzYTE0MGIyNDM1MTg4YjkxZDNmMDU4OGU=\"},{\"type\":\"SECURITY_FINDING\",\"ref\":\"/security/appsec/vm/library/vulnerability/dfa027f7c037b2f77159adc027fecb56?detection=static\",\"resource_id\":\"ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=\"}],\"key\":\"CSMINV-455\",\"priority\":\"NOT_DEFINED\",\"status\":\"OPEN\",\"status_group\":\"SG_OPEN\",\"status_name\":\"Open\",\"title\":\"A title\",\"type\":\"SECURITY\"},\"relationships\":{\"created_by\":{\"data\":{\"id\":\"dc09afab-6ae7-11ef-92b1-828dac1b0195\",\"type\":\"users\"}},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}}}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 201, + "message": "Created" + } + }, + "recorded_at": "Wed, 19 Nov 2025 13:46:07 GMT" + }, + { + "request": { + "body": { + "string": "{\"data\":{\"id\":\"2c1ac0c4-e8cf-4699-8781-09077b10d2a0\",\"relationships\":{\"findings\":{\"data\":[{\"id\":\"MzZkNTMxODNmOGZlZmJiYzIyMDg4NzhmM2QyMDExZjB-ZmY5NzUwNDQzYTE0MGIyNDM1MTg4YjkxZDNmMDU4OGU=\",\"type\":\"findings\"}]}},\"type\":\"cases\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "*/*" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "delete", + "uri": "https://api.datadoghq.com/api/v2/security/findings/cases" + }, + "response": { + "body": { + "string": "", + "encoding": null + }, + "headers": {}, + "status": { + "code": 204, + "message": "No Content" + } + }, + "recorded_at": "Wed, 19 Nov 2025 13:46:07 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-cases-for-security-findings-returns-Bad-Request-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Create-cases-for-security-findings-returns-Bad-Request-response.frozen new file mode 100644 index 000000000..03dcf1623 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-cases-for-security-findings-returns-Bad-Request-response.frozen @@ -0,0 +1 @@ +2025-11-19T13:46:49.148Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-cases-for-security-findings-returns-Bad-Request-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Create-cases-for-security-findings-returns-Bad-Request-response.json new file mode 100644 index 000000000..e53673e38 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-cases-for-security-findings-returns-Bad-Request-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":[{\"attributes\":{},\"relationships\":{\"findings\":{\"data\":[]},\"project\":{\"data\":{\"id\":\"7f198869-c7ef-4afc-97cf-da5cdc13b5c3\",\"type\":\"projects\"}}},\"type\":\"cases\"}]}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "post", + "uri": "https://api.datadoghq.com/api/v2/security/findings/cases" + }, + "response": { + "body": { + "string": "{\"errors\":[{\"status\":\"400\",\"title\":\"Bad Request\",\"detail\":\"no finding provided\"}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 400, + "message": "Bad Request" + } + }, + "recorded_at": "Wed, 19 Nov 2025 13:46:49 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-cases-for-security-findings-returns-Created-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Create-cases-for-security-findings-returns-Created-response.frozen new file mode 100644 index 000000000..d1e05ac25 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-cases-for-security-findings-returns-Created-response.frozen @@ -0,0 +1 @@ +2025-11-19T13:54:20.603Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-cases-for-security-findings-returns-Created-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Create-cases-for-security-findings-returns-Created-response.json new file mode 100644 index 000000000..eb9e770e1 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-cases-for-security-findings-returns-Created-response.json @@ -0,0 +1,69 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":[{\"attributes\":{\"description\":\"A description\",\"title\":\"A title\"},\"relationships\":{\"findings\":{\"data\":[{\"id\":\"ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=\",\"type\":\"findings\"}]},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}},\"type\":\"cases\"},{\"attributes\":{\"description\":\"A description\",\"title\":\"A title\"},\"relationships\":{\"findings\":{\"data\":[{\"id\":\"MzZkNTMxODNmOGZlZmJiYzIyMDg4NzhmM2QyMDExZjB-ZmY5NzUwNDQzYTE0MGIyNDM1MTg4YjkxZDNmMDU4OGU=\",\"type\":\"findings\"}]},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}},\"type\":\"cases\"}]}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "post", + "uri": "https://api.datadoghq.com/api/v2/security/findings/cases" + }, + "response": { + "body": { + "string": "{\"data\":[{\"id\":\"7d16945b-baf8-411e-ab2a-20fe43af1ea3\",\"type\":\"cases\",\"attributes\":{\"created_at\":\"2025-11-19T13:54:23.634063Z\",\"creation_source\":\"CS_SECURITY_FINDING\",\"description\":\"A description\",\"insights\":[{\"type\":\"SECURITY_FINDING\",\"ref\":\"/security/appsec/vm/library/vulnerability/dfa027f7c037b2f77159adc027fecb56?detection=static\",\"resource_id\":\"ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=\"}],\"key\":\"CSMINV-459\",\"priority\":\"NOT_DEFINED\",\"status\":\"OPEN\",\"status_group\":\"SG_OPEN\",\"status_name\":\"Open\",\"title\":\"A title\",\"type\":\"SECURITY\"},\"relationships\":{\"created_by\":{\"data\":{\"id\":\"dc09afab-6ae7-11ef-92b1-828dac1b0195\",\"type\":\"users\"}},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}}},{\"id\":\"601cab78-ef04-4bdf-901a-55533afbde0b\",\"type\":\"cases\",\"attributes\":{\"created_at\":\"2025-11-19T13:54:23.634552Z\",\"creation_source\":\"CS_SECURITY_FINDING\",\"description\":\"A description\",\"insights\":[{\"type\":\"SECURITY_FINDING\",\"ref\":\"/security/appsec/vm/library/vulnerability/36d53183f8fefbbc2208878f3d2011f0?detection=static\",\"resource_id\":\"MzZkNTMxODNmOGZlZmJiYzIyMDg4NzhmM2QyMDExZjB-ZmY5NzUwNDQzYTE0MGIyNDM1MTg4YjkxZDNmMDU4OGU=\"}],\"key\":\"CSMINV-458\",\"priority\":\"NOT_DEFINED\",\"status\":\"OPEN\",\"status_group\":\"SG_OPEN\",\"status_name\":\"Open\",\"title\":\"A title\",\"type\":\"SECURITY\"},\"relationships\":{\"created_by\":{\"data\":{\"id\":\"dc09afab-6ae7-11ef-92b1-828dac1b0195\",\"type\":\"users\"}},\"project\":{\"data\":{\"id\":\"959a6f71-bac8-4027-b1d3-2264f569296f\",\"type\":\"projects\"}}}}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 201, + "message": "Created" + } + }, + "recorded_at": "Wed, 19 Nov 2025 13:54:20 GMT" + }, + { + "request": { + "body": { + "string": "{\"data\":{\"id\":\"7d16945b-baf8-411e-ab2a-20fe43af1ea3\",\"relationships\":{\"findings\":{\"data\":[{\"id\":\"ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=\",\"type\":\"findings\"}]}},\"type\":\"cases\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "*/*" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "delete", + "uri": "https://api.datadoghq.com/api/v2/security/findings/cases" + }, + "response": { + "body": { + "string": "", + "encoding": null + }, + "headers": {}, + "status": { + "code": 204, + "message": "No Content" + } + }, + "recorded_at": "Wed, 19 Nov 2025 13:54:20 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-cases-for-security-findings-returns-Not-Found-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Create-cases-for-security-findings-returns-Not-Found-response.frozen new file mode 100644 index 000000000..331897b6e --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-cases-for-security-findings-returns-Not-Found-response.frozen @@ -0,0 +1 @@ +2025-11-19T13:47:19.797Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Create-cases-for-security-findings-returns-Not-Found-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Create-cases-for-security-findings-returns-Not-Found-response.json new file mode 100644 index 000000000..453a763d3 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Create-cases-for-security-findings-returns-Not-Found-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":[{\"attributes\":{},\"relationships\":{\"findings\":{\"data\":[{\"id\":\"ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=\",\"type\":\"findings\"}]},\"project\":{\"data\":{\"id\":\"00000000-0000-0000-0000-000000000000\",\"type\":\"projects\"}}},\"type\":\"cases\"}]}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "post", + "uri": "https://api.datadoghq.com/api/v2/security/findings/cases" + }, + "response": { + "body": { + "string": "{\"errors\":[{\"status\":\"404\",\"title\":\"Not Found\",\"detail\":\"project not found\"}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 404, + "message": "Not Found" + } + }, + "recorded_at": "Wed, 19 Nov 2025 13:47:19 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Detach-security-findings-from-their-case-returns-Bad-Request-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Detach-security-findings-from-their-case-returns-Bad-Request-response.frozen new file mode 100644 index 000000000..48119112e --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Detach-security-findings-from-their-case-returns-Bad-Request-response.frozen @@ -0,0 +1 @@ +2025-11-20T16:07:27.292Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Detach-security-findings-from-their-case-returns-Bad-Request-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Detach-security-findings-from-their-case-returns-Bad-Request-response.json new file mode 100644 index 000000000..295b0578c --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Detach-security-findings-from-their-case-returns-Bad-Request-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":{\"relationships\":{\"findings\":{\"data\":[]}},\"type\":\"cases\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "*/*" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "delete", + "uri": "https://api.datadoghq.com/api/v2/security/findings/cases" + }, + "response": { + "body": { + "string": "{\"errors\":[{\"status\":\"400\",\"title\":\"Bad Request\",\"detail\":\"no finding provided\"}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 400, + "message": "Bad Request" + } + }, + "recorded_at": "Thu, 20 Nov 2025 16:07:27 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Detach-security-findings-from-their-case-returns-No-Content-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Detach-security-findings-from-their-case-returns-No-Content-response.frozen new file mode 100644 index 000000000..3e388493c --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Detach-security-findings-from-their-case-returns-No-Content-response.frozen @@ -0,0 +1 @@ +2025-11-21T13:41:10.798Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Detach-security-findings-from-their-case-returns-No-Content-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Detach-security-findings-from-their-case-returns-No-Content-response.json new file mode 100644 index 000000000..16eb8ed20 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Detach-security-findings-from-their-case-returns-No-Content-response.json @@ -0,0 +1,35 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":{\"relationships\":{\"findings\":{\"data\":[{\"id\":\"YzM2MTFjYzcyNmY0Zjg4MTAxZmRlNjQ1MWU1ZGQwYzR-YzI5NzE5Y2Y4MzU4ZjliNzhkNjYxNTY0ODIzZDQ2YTM=\",\"type\":\"findings\"}]}},\"type\":\"cases\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "*/*" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "delete", + "uri": "https://api.datadoghq.com/api/v2/security/findings/cases" + }, + "response": { + "body": { + "string": "", + "encoding": null + }, + "headers": {}, + "status": { + "code": 204, + "message": "No Content" + } + }, + "recorded_at": "Fri, 21 Nov 2025 13:41:10 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Detach-security-findings-from-their-case-returns-Not-Found-response.frozen b/tests/scenarios/cassettes/v2/security_monitoring/Detach-security-findings-from-their-case-returns-Not-Found-response.frozen new file mode 100644 index 000000000..72e1b275e --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Detach-security-findings-from-their-case-returns-Not-Found-response.frozen @@ -0,0 +1 @@ +2025-11-20T16:06:53.415Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/security_monitoring/Detach-security-findings-from-their-case-returns-Not-Found-response.json b/tests/scenarios/cassettes/v2/security_monitoring/Detach-security-findings-from-their-case-returns-Not-Found-response.json new file mode 100644 index 000000000..7033ad4a6 --- /dev/null +++ b/tests/scenarios/cassettes/v2/security_monitoring/Detach-security-findings-from-their-case-returns-Not-Found-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":{\"relationships\":{\"findings\":{\"data\":[{\"id\":\"wrong-finding-id\",\"type\":\"findings\"}]}},\"type\":\"cases\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "*/*" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "delete", + "uri": "https://api.datadoghq.com/api/v2/security/findings/cases" + }, + "response": { + "body": { + "string": "{\"errors\":[{\"status\":\"404\",\"title\":\"Not Found\",\"detail\":\"finding not found\"}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 404, + "message": "Not Found" + } + }, + "recorded_at": "Thu, 20 Nov 2025 16:06:53 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/features/v2/given.json b/tests/scenarios/features/v2/given.json index d1d4bce2f..6c6d3bf98 100644 --- a/tests/scenarios/features/v2/given.json +++ b/tests/scenarios/features/v2/given.json @@ -350,7 +350,7 @@ "parameters": [ { "name": "body", - "value": "{\n \"data\": {\n \"type\": \"deployment_gate\",\n \"attributes\": {\n \"service\": \"my-service\",\n \"env\": \"production\",\n \"identifier\": \"my-gate-{{ unique_lower_alnum }}\",\n \"dry_run\": false\n }\n }\n}" + "value": "{\n \"data\": {\n \"type\": \"deployment_gate\",\n \"attributes\": {\n \"service\": \"my-service\",\n \"env\": \"production\",\n \"identifier\": \"my-gate\",\n \"dry_run\": false\n }\n }\n}" } ], "step": "there is a valid \"deployment_gate\" in the system", diff --git a/tests/scenarios/features/v2/security_monitoring.feature b/tests/scenarios/features/v2/security_monitoring.feature index 531c84c19..5599d509a 100644 --- a/tests/scenarios/features/v2/security_monitoring.feature +++ b/tests/scenarios/features/v2/security_monitoring.feature @@ -5,9 +5,83 @@ Feature: Security Monitoring information. Background: - Given an instance of "SecurityMonitoring" API - And a valid "apiKeyAuth" key in the system + Given a valid "apiKeyAuth" key in the system And a valid "appKeyAuth" key in the system + And an instance of "SecurityMonitoring" API + + @team:DataDog/k9-investigation + Scenario: Attach security finding to a Jira issue returns "OK" response + Given new "AttachJiraIssue" request + And body with value {"data": {"attributes": {"jira_issue_url": "https://datadoghq-sandbox-538.atlassian.net/browse/CSMSEC-105476"}, "relationships": {"findings": {"data": [{"id": "OTQ3NjJkMmYwMTIzMzMxNTc1Y2Q4MTA5NWU0NTBmMDl-ZjE3NjMxZWVkYzBjZGI1NDY2NWY2OGQxZDk4MDY4MmI=", "type": "findings"}]}, "project": {"data": {"id": "959a6f71-bac8-4027-b1d3-2264f569296f", "type": "projects"}}}, "type": "jira_issues"}} + When the request is sent + Then the response status is 200 OK + And the response "data.attributes.status_group" is equal to "SG_OPEN" + And the response "data.attributes.insights" has item with field "resource_id" with value "OTQ3NjJkMmYwMTIzMzMxNTc1Y2Q4MTA5NWU0NTBmMDl-ZjE3NjMxZWVkYzBjZGI1NDY2NWY2OGQxZDk4MDY4MmI=" + And the response "data.attributes.jira_issue.result.issue_url" is equal to "https://datadoghq-sandbox-538.atlassian.net/browse/CSMSEC-105476" + + @team:DataDog/k9-investigation + Scenario: Attach security finding to a case returns "OK" response + Given new "AttachCase" request + And request contains "case_id" parameter with value "7d16945b-baf8-411e-ab2a-20fe43af1ea3" + And body with value {"data": {"id": "7d16945b-baf8-411e-ab2a-20fe43af1ea3", "relationships": {"findings": {"data": [{"id": "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=", "type": "findings"}]}}, "type": "cases"}} + When the request is sent + Then the response status is 200 OK + And the response "data.id" is equal to "7d16945b-baf8-411e-ab2a-20fe43af1ea3" + And the response "data.attributes.status_group" is equal to "SG_OPEN" + And the response "data.attributes.insights" has item with field "resource_id" with value "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=" + + @team:DataDog/k9-investigation + Scenario: Attach security findings to a Jira issue returns "Bad Request" response + Given new "AttachJiraIssue" request + And body with value {"data": {"attributes": {"jira_issue_url": "https://datadoghq-sandbox-538.atlassian.net/browse/CSMSEC-105476"}, "relationships": {"findings": {"data": []}, "project": {"data": {"id": "959a6f71-bac8-4027-b1d3-2264f569296f", "type": "projects"}}}, "type": "jira_issues"}} + When the request is sent + Then the response status is 400 Bad Request + + @team:DataDog/k9-investigation + Scenario: Attach security findings to a Jira issue returns "Not Found" response + Given new "AttachJiraIssue" request + And body with value {"data": {"attributes": {"jira_issue_url": "https://datadoghq-sandbox-538.atlassian.net/browse/CSMSEC-105476"}, "relationships": {"findings": {"data": [{"id": "wrong-finding-id", "type": "findings"}]}, "project": {"data": {"id": "959a6f71-bac8-4027-b1d3-2264f569296f", "type": "projects"}}}, "type": "jira_issues"}} + When the request is sent + Then the response status is 404 Not Found + + @team:DataDog/k9-investigation + Scenario: Attach security findings to a Jira issue returns "OK" response + Given new "AttachJiraIssue" request + And body with value {"data": {"attributes": {"jira_issue_url": "https://datadoghq-sandbox-538.atlassian.net/browse/CSMSEC-105476"}, "relationships": {"findings": {"data": [{"id": "OTQ3NjJkMmYwMTIzMzMxNTc1Y2Q4MTA5NWU0NTBmMDl-ZjE3NjMxZWVkYzBjZGI1NDY2NWY2OGQxZDk4MDY4MmI=", "type": "findings"}, {"id": "MTNjN2ZmYWMzMDIxYmU1ZDFiZDRjNWUwN2I1NzVmY2F-YTA3MzllMTUzNWM3NmEyZjdiNzEzOWM5YmViZTMzOGM=", "type": "findings"}]}, "project": {"data": {"id": "959a6f71-bac8-4027-b1d3-2264f569296f", "type": "projects"}}}, "type": "jira_issues"}} + When the request is sent + Then the response status is 200 OK + And the response "data.attributes.status_group" is equal to "SG_OPEN" + And the response "data.attributes.insights" has item with field "resource_id" with value "OTQ3NjJkMmYwMTIzMzMxNTc1Y2Q4MTA5NWU0NTBmMDl-ZjE3NjMxZWVkYzBjZGI1NDY2NWY2OGQxZDk4MDY4MmI=" + And the response "data.attributes.insights" has item with field "resource_id" with value "MTNjN2ZmYWMzMDIxYmU1ZDFiZDRjNWUwN2I1NzVmY2F-YTA3MzllMTUzNWM3NmEyZjdiNzEzOWM5YmViZTMzOGM=" + And the response "data.attributes.jira_issue.result.issue_url" is equal to "https://datadoghq-sandbox-538.atlassian.net/browse/CSMSEC-105476" + + @team:DataDog/k9-investigation + Scenario: Attach security findings to a case returns "Bad Request" response + Given new "AttachCase" request + And request contains "case_id" parameter with value "7d16945b-baf8-411e-ab2a-20fe43af1ea3" + And body with value {"data": {"id": "7d16945b-baf8-411e-ab2a-20fe43af1ea3", "relationships": {"findings": {"data": []}}, "type": "cases"}} + When the request is sent + Then the response status is 400 Bad Request + + @team:DataDog/k9-investigation + Scenario: Attach security findings to a case returns "Not Found" response + Given new "AttachCase" request + And request contains "case_id" parameter with value "wrong-case-id" + And body with value {"data": {"id": "wrong-case-id", "relationships": {"findings": {"data": [{"id": "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=", "type": "findings"}]}}, "type": "cases"}} + When the request is sent + Then the response status is 404 Not Found + + @team:DataDog/k9-investigation + Scenario: Attach security findings to a case returns "OK" response + Given new "AttachCase" request + And request contains "case_id" parameter with value "7d16945b-baf8-411e-ab2a-20fe43af1ea3" + And body with value {"data": {"id": "7d16945b-baf8-411e-ab2a-20fe43af1ea3", "relationships": {"findings": {"data": [{"id": "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=", "type": "findings"}, {"id": "MmUzMzZkODQ2YTI3NDU0OTk4NDk3NzhkOTY5YjU2Zjh-YWJjZGI1ODI4OTYzNWM3ZmUwZTBlOWRkYTRiMGUyOGQ=", "type": "findings"}]}}, "type": "cases"}} + When the request is sent + Then the response status is 200 OK + And the response "data.id" is equal to "7d16945b-baf8-411e-ab2a-20fe43af1ea3" + And the response "data.attributes.status_group" is equal to "SG_OPEN" + And the response "data.attributes.insights" has item with field "resource_id" with value "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=" + And the response "data.attributes.insights" has item with field "resource_id" with value "MmUzMzZkODQ2YTI3NDU0OTk4NDk3NzhkOTY5YjU2Zjh-YWJjZGI1ODI4OTYzNWM3ZmUwZTBlOWRkYTRiMGUyOGQ=" @team:DataDog/k9-cloud-security-platform Scenario: Cancel a historical job returns "Bad Request" response @@ -184,6 +258,78 @@ Feature: Security Monitoring Then the response status is 200 OK And the response "terraformContent" is equal to "resource \"datadog_security_monitoring_rule\" \"_{{ unique_hash }}\" {\n\tname = \"_{{ unique_hash }}\"\n\tenabled = true\n\tquery {\n\t\tquery = \"@test:true\"\n\t\tgroup_by_fields = []\n\t\thas_optional_group_by_fields = false\n\t\tdistinct_fields = []\n\t\taggregation = \"count\"\n\t\tname = \"\"\n\t\tdata_source = \"logs\"\n\t}\n\toptions {\n\t\tkeep_alive = 3600\n\t\tmax_signal_duration = 86400\n\t\tdetection_method = \"threshold\"\n\t\tevaluation_window = 900\n\t}\n\tcase {\n\t\tname = \"\"\n\t\tstatus = \"info\"\n\t\tnotifications = []\n\t\tcondition = \"a > 0\"\n\t}\n\tmessage = \"Test rule\"\n\ttags = []\n\thas_extended_title = false\n\ttype = \"log_detection\"\n}\n" + @team:DataDog/k9-investigation + Scenario: Create Jira issue for security finding returns "Created" response + Given new "CreateJiraIssues" request + And body with value {"data": [{"type": "jira_issues", "attributes": {}, "relationships": {"case": {"data": {"type": "cases", "id": "6a773295-8729-4034-aada-53b64cbe02e7"}}}}], "included": [{"type": "cases", "attributes": {"title": "A title", "description": "A description"}, "relationships": {"project": {"data": {"type": "projects", "id": "959a6f71-bac8-4027-b1d3-2264f569296f"}}, "findings": {"data": [{"type": "findings", "id": "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y="}]}}, "id": "6a773295-8729-4034-aada-53b64cbe02e7"}, {"type": "projects", "id": "959a6f71-bac8-4027-b1d3-2264f569296f"}, {"type": "findings", "id": "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y="}]} + When the request is sent + Then the response status is 201 Created + And the response "data" has length 1 + And the response "data[0]" has field "id" + And the response "data[0].attributes.title" is equal to "A title" + And the response "data[0].attributes.description" is equal to "A description" + And the response "data[0].attributes.type" is equal to "SECURITY" + And the response "data[0].attributes.insights" has length 1 + And the response "data[0].attributes.insights[0].resource_id" is equal to "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=" + And the response "data[0].attributes.insights[0].type" is equal to "SECURITY_FINDING" + And the response "data[0].attributes.jira_issue.status" is equal to "COMPLETED" + + @team:DataDog/k9-investigation + Scenario: Create Jira issue for security findings returns "Created" response + Given new "CreateJiraIssues" request + And body with value {"data": [{"type": "jira_issues", "attributes": {}, "relationships": {"case": {"data": {"type": "cases", "id": "e469ceda-957a-4557-a607-9ff25032e9ca"}}}}], "included": [{"type": "cases", "attributes": {"title": "A title", "description": "A description"}, "relationships": {"project": {"data": {"type": "projects", "id": "959a6f71-bac8-4027-b1d3-2264f569296f"}}, "findings": {"data": [{"type": "findings", "id": "MzUxMDI4OWYyYWEyODRhYjQ0Zjg2YjY2ZTFmNjRjYzd-NDU2OWQyNTk1MjM5OGI2NzJjMTVhYjhiODY1ZDcwZWY="}, {"type": "findings", "id": "ZjE2ZGI5YjdmYTQyYzhhMDQ3Nzc3YjM1NGQ2Y2NmZTd-NDU2OWQyNTk1MjM5OGI2NzJjMTVhYjhiODY1ZDcwZWY="}]}}, "id": "e469ceda-957a-4557-a607-9ff25032e9ca"}, {"type": "projects", "id": "959a6f71-bac8-4027-b1d3-2264f569296f"}, {"type": "findings", "id": "MzUxMDI4OWYyYWEyODRhYjQ0Zjg2YjY2ZTFmNjRjYzd-NDU2OWQyNTk1MjM5OGI2NzJjMTVhYjhiODY1ZDcwZWY="}, {"type": "findings", "id": "ZjE2ZGI5YjdmYTQyYzhhMDQ3Nzc3YjM1NGQ2Y2NmZTd-NDU2OWQyNTk1MjM5OGI2NzJjMTVhYjhiODY1ZDcwZWY="}]} + When the request is sent + Then the response status is 201 Created + And the response "data" has length 1 + And the response "data[0]" has field "id" + And the response "data[0].attributes.title" is equal to "A title" + And the response "data[0].attributes.description" is equal to "A description" + And the response "data[0].attributes.type" is equal to "SECURITY" + And the response "data[0].attributes.insights" has length 2 + And the response "data[0].attributes.insights[1].resource_id" is equal to "MzUxMDI4OWYyYWEyODRhYjQ0Zjg2YjY2ZTFmNjRjYzd-NDU2OWQyNTk1MjM5OGI2NzJjMTVhYjhiODY1ZDcwZWY=" + And the response "data[0].attributes.insights[1].type" is equal to "SECURITY_FINDING" + And the response "data[0].attributes.insights[0].resource_id" is equal to "ZjE2ZGI5YjdmYTQyYzhhMDQ3Nzc3YjM1NGQ2Y2NmZTd-NDU2OWQyNTk1MjM5OGI2NzJjMTVhYjhiODY1ZDcwZWY=" + And the response "data[0].attributes.insights[0].type" is equal to "SECURITY_FINDING" + And the response "data[0].attributes.jira_issue.status" is equal to "COMPLETED" + + @team:DataDog/k9-investigation + Scenario: Create Jira issues for security findings returns "Bad Request" response + Given new "CreateJiraIssues" request + And body with value {"data": [{"type": "jira_issues", "attributes": {}, "relationships": {"case": {"data": {"type": "cases", "id": "a7c38bab-ae98-4113-878c-c98799f914c2"}}}}], "included": [{"type": "cases", "relationships": {"project": {"data": {"type": "projects", "id": "959a6f71-bac8-4027-b1d3-2264f569296f"}}, "findings": {"data": []}}, "id": "a7c38bab-ae98-4113-878c-c98799f914c2"}, {"type": "projects", "id": "959a6f71-bac8-4027-b1d3-2264f569296f"}]} + When the request is sent + Then the response status is 400 Bad Request + + @team:DataDog/k9-investigation + Scenario: Create Jira issues for security findings returns "Created" response + Given new "CreateJiraIssues" request + And body with value {"data": [{"type": "jira_issues", "attributes":{}, "relationships": {"case": {"data": {"type": "cases", "id":"53e242c6-a7d6-46ad-9680-b8d14753f716"}}}}, {"type": "jira_issues", "attributes": {}, "relationships": {"case": {"data": {"type": "cases", "id": "195772b2-1f53-41d2-b81e-48c8e6c21d33"}}}}], "included":[{"type":"cases", "attributes":{"title":"A title", "description":"A description"}, "relationships":{"project":{"data":{"type":"projects", "id":"959a6f71-bac8-4027-b1d3-2264f569296f"}}, "findings": {"data": [{"type": "findings", "id": "OTQ3NjJkMmYwMTIzMzMxNTc1Y2Q4MTA5NWU0NTBmMDl-ZjE3NjMxZWVkYzBjZGI1NDY2NWY2OGQxZDk4MDY4MmI="}]}}, "id": "53e242c6-a7d6-46ad-9680-b8d14753f716"}, {"type": "cases", "attributes": {"title": "A title", "description": "A description"}, "relationships": {"project": {"data": {"type": "projects", "id": "959a6f71-bac8-4027-b1d3-2264f569296f"}}, "findings": {"data":[{"type": "findings", "id": "MTNjN2ZmYWMzMDIxYmU1ZDFiZDRjNWUwN2I1NzVmY2F-YTA3MzllMTUzNWM3NmEyZjdiNzEzOWM5YmViZTMzOGM="}]}}, "id": "195772b2-1f53-41d2-b81e-48c8e6c21d33"}, {"type": "projects", "id": "959a6f71-bac8-4027-b1d3-2264f569296f"}, {"type": "findings", "id": "OTQ3NjJkMmYwMTIzMzMxNTc1Y2Q4MTA5NWU0NTBmMDl-ZjE3NjMxZWVkYzBjZGI1NDY2NWY2OGQxZDk4MDY4MmI="}, {"type": "findings", "id": "MTNjN2ZmYWMzMDIxYmU1ZDFiZDRjNWUwN2I1NzVmY2F-YTA3MzllMTUzNWM3NmEyZjdiNzEzOWM5YmViZTMzOGM="}]} + When the request is sent + Then the response status is 201 Created + And the response "data" has length 2 + And the response "data[0]" has field "id" + And the response "data[0].attributes.title" is equal to "A title" + And the response "data[0].attributes.description" is equal to "A description" + And the response "data[0].attributes.type" is equal to "SECURITY" + And the response "data[0].attributes.insights" has length 1 + And the response "data[0].attributes.insights[0].resource_id" is equal to "OTQ3NjJkMmYwMTIzMzMxNTc1Y2Q4MTA5NWU0NTBmMDl-ZjE3NjMxZWVkYzBjZGI1NDY2NWY2OGQxZDk4MDY4MmI=" + And the response "data[0].attributes.insights[0].type" is equal to "SECURITY_FINDING" + And the response "data[0].attributes.jira_issue.status" is equal to "COMPLETED" + And the response "data[1]" has field "id" + And the response "data[1].attributes.title" is equal to "A title" + And the response "data[1].attributes.description" is equal to "A description" + And the response "data[1].attributes.type" is equal to "SECURITY" + And the response "data[1].attributes.insights" has length 1 + And the response "data[1].attributes.insights[0].resource_id" is equal to "MTNjN2ZmYWMzMDIxYmU1ZDFiZDRjNWUwN2I1NzVmY2F-YTA3MzllMTUzNWM3NmEyZjdiNzEzOWM5YmViZTMzOGM=" + And the response "data[1].attributes.insights[0].type" is equal to "SECURITY_FINDING" + And the response "data[1].attributes.jira_issue.status" is equal to "COMPLETED" + + @team:DataDog/k9-investigation + Scenario: Create Jira issues for security findings returns "Not Found" response + Given new "CreateJiraIssues" request + And body with value {"data": [{"type": "jira_issues", "attributes": {}, "relationships": {"case": {"data": {"type": "cases", "id": "6ed1d7c2-e1a3-4369-b92b-a38d3cc75cf3"}}}}], "included": [{"type": "cases", "attributes": {"title": "A title", "description": "A description"}, "relationships": {"project": {"data": {"type": "projects", "id": "00000000-0000-0000-0000-000000000000"}}, "findings": {"data": [{"type": "findings", "id": "YzM2MTFjYzcyNmY0Zjg4MTAxZmRlNjQ1MWU1ZGQwYzR-YzI5NzE5Y2Y4MzU4ZjliNzhkNjYxNTY0ODIzZDQ2YTM="}]}}, "id": "6ed1d7c2-e1a3-4369-b92b-a38d3cc75cf3"}, {"type": "projects", "id": "00000000-0000-0000-0000-000000000000"}, {"type": "findings", "id": "YzM2MTFjYzcyNmY0Zjg4MTAxZmRlNjQ1MWU1ZGQwYzR-YzI5NzE5Y2Y4MzU4ZjliNzhkNjYxNTY0ODIzZDQ2YTM="}]} + When the request is sent + Then the response status is 404 Not Found + @skip-validation @team:DataDog/k9-cloud-security-platform Scenario: Create a cloud_configuration rule returns "OK" response Given new "CreateSecurityMonitoringRule" request @@ -408,6 +554,74 @@ Feature: Security Monitoring And the response "data.attributes.rule_query" is equal to "type:log_detection source:cloudtrail" And the response "data.attributes.data_exclusion_query" is equal to "account_id:12345" + @team:DataDog/k9-investigation + Scenario: Create case for security finding returns "Created" response + Given new "CreateCases" request + And body with value {"data": [{"attributes": {"title": "A title", "description": "A description"}, "relationships": {"findings": {"data": [{"id": "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=", "type": "findings"}]}, "project": {"data": {"id": "959a6f71-bac8-4027-b1d3-2264f569296f", "type": "projects"}}}, "type": "cases"}]} + When the request is sent + Then the response status is 201 Created + And the response "data" has length 1 + And the response "data[0]" has field "id" + And the response "data[0].attributes.title" is equal to "A title" + And the response "data[0].attributes.description" is equal to "A description" + And the response "data[0].attributes.type" is equal to "SECURITY" + And the response "data[0].attributes.insights" has length 1 + And the response "data[0].attributes.insights[0].resource_id" is equal to "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=" + And the response "data[0].attributes.insights[0].type" is equal to "SECURITY_FINDING" + + @team:DataDog/k9-investigation + Scenario: Create case for security findings returns "Created" response + Given new "CreateCases" request + And body with value {"data": [{"attributes": {"title": "A title", "description": "A description"}, "relationships": {"findings": {"data": [{"id": "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=", "type": "findings"}, {"id": "MzZkNTMxODNmOGZlZmJiYzIyMDg4NzhmM2QyMDExZjB-ZmY5NzUwNDQzYTE0MGIyNDM1MTg4YjkxZDNmMDU4OGU=", "type": "findings"}]}, "project": {"data": {"id": "959a6f71-bac8-4027-b1d3-2264f569296f", "type": "projects"}}}, "type": "cases"}]} + When the request is sent + Then the response status is 201 Created + And the response "data" has length 1 + And the response "data[0]" has field "id" + And the response "data[0].attributes.title" is equal to "A title" + And the response "data[0].attributes.description" is equal to "A description" + And the response "data[0].attributes.type" is equal to "SECURITY" + And the response "data[0].attributes.insights" has length 2 + And the response "data[0].attributes.insights[1].resource_id" is equal to "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=" + And the response "data[0].attributes.insights[1].type" is equal to "SECURITY_FINDING" + And the response "data[0].attributes.insights[0].resource_id" is equal to "MzZkNTMxODNmOGZlZmJiYzIyMDg4NzhmM2QyMDExZjB-ZmY5NzUwNDQzYTE0MGIyNDM1MTg4YjkxZDNmMDU4OGU=" + And the response "data[0].attributes.insights[0].type" is equal to "SECURITY_FINDING" + + @team:DataDog/k9-investigation + Scenario: Create cases for security findings returns "Bad Request" response + Given new "CreateCases" request + And body with value {"data": [{"attributes": {}, "relationships": {"findings": {"data": []}, "project": {"data": {"id": "7f198869-c7ef-4afc-97cf-da5cdc13b5c3", "type": "projects"}}}, "type": "cases"}]} + When the request is sent + Then the response status is 400 Bad Request + + @team:DataDog/k9-investigation + Scenario: Create cases for security findings returns "Created" response + Given new "CreateCases" request + And body with value {"data": [{"attributes": {"title": "A title", "description": "A description"}, "relationships": {"findings": {"data": [{"id": "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=", "type": "findings"}]}, "project": {"data": {"id": "959a6f71-bac8-4027-b1d3-2264f569296f", "type": "projects"}}}, "type": "cases"}, {"attributes": {"title": "A title", "description": "A description"}, "relationships": {"findings": {"data": [{"id": "MzZkNTMxODNmOGZlZmJiYzIyMDg4NzhmM2QyMDExZjB-ZmY5NzUwNDQzYTE0MGIyNDM1MTg4YjkxZDNmMDU4OGU=", "type": "findings"}]}, "project": {"data": {"id": "959a6f71-bac8-4027-b1d3-2264f569296f", "type": "projects"}}}, "type": "cases"}]} + When the request is sent + Then the response status is 201 Created + And the response "data" has length 2 + And the response "data[0]" has field "id" + And the response "data[0].attributes.title" is equal to "A title" + And the response "data[0].attributes.description" is equal to "A description" + And the response "data[0].attributes.type" is equal to "SECURITY" + And the response "data[0].attributes.insights" has length 1 + And the response "data[0].attributes.insights[0].resource_id" is equal to "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=" + And the response "data[0].attributes.insights[0].type" is equal to "SECURITY_FINDING" + And the response "data[1]" has field "id" + And the response "data[1].attributes.title" is equal to "A title" + And the response "data[1].attributes.description" is equal to "A description" + And the response "data[1].attributes.type" is equal to "SECURITY" + And the response "data[1].attributes.insights" has length 1 + And the response "data[1].attributes.insights[0].resource_id" is equal to "MzZkNTMxODNmOGZlZmJiYzIyMDg4NzhmM2QyMDExZjB-ZmY5NzUwNDQzYTE0MGIyNDM1MTg4YjkxZDNmMDU4OGU=" + And the response "data[1].attributes.insights[0].type" is equal to "SECURITY_FINDING" + + @team:DataDog/k9-investigation + Scenario: Create cases for security findings returns "Not Found" response + Given new "CreateCases" request + And body with value {"data": [{"attributes": {}, "relationships": {"findings": {"data": [{"id": "ZGZhMDI3ZjdjMDM3YjJmNzcxNTlhZGMwMjdmZWNiNTZ-MTVlYTNmYWU3NjNlOTNlYTE2YjM4N2JmZmI4Yjk5N2Y=", "type": "findings"}]}, "project": {"data": {"id": "00000000-0000-0000-0000-000000000000", "type": "projects"}}}, "type": "cases"}]} + When the request is sent + Then the response status is 404 Not Found + @team:DataDog/k9-cloud-security-platform Scenario: Delete a custom framework returns "Bad Request" response Given new "DeleteCustomFramework" request @@ -546,6 +760,27 @@ Feature: Security Monitoring When the request is sent Then the response status is 204 OK + @team:DataDog/k9-investigation + Scenario: Detach security findings from their case returns "Bad Request" response + Given new "DetachCase" request + And body with value {"data": {"relationships": {"findings": {"data": []}}, "type": "cases"}} + When the request is sent + Then the response status is 400 Bad Request + + @team:DataDog/k9-investigation + Scenario: Detach security findings from their case returns "No Content" response + Given new "DetachCase" request + And body with value {"data": {"relationships": {"findings": {"data": [{"id": "YzM2MTFjYzcyNmY0Zjg4MTAxZmRlNjQ1MWU1ZGQwYzR-YzI5NzE5Y2Y4MzU4ZjliNzhkNjYxNTY0ODIzZDQ2YTM=", "type": "findings"}]}}, "type": "cases"}} + When the request is sent + Then the response status is 204 No Content + + @team:DataDog/k9-investigation + Scenario: Detach security findings from their case returns "Not Found" response + Given new "DetachCase" request + And body with value {"data": {"relationships": {"findings": {"data": [{"id": "wrong-finding-id", "type": "findings"}]}}, "type": "cases"}} + When the request is sent + Then the response status is 404 Not Found + @generated @skip @team:DataDog/asm-vm Scenario: Get SBOM returns "Bad request: The server cannot process the request due to invalid syntax in the request." response Given operation "GetSBOM" enabled diff --git a/tests/scenarios/features/v2/undo.json b/tests/scenarios/features/v2/undo.json index 7c226bf60..2e54bbe0a 100644 --- a/tests/scenarios/features/v2/undo.json +++ b/tests/scenarios/features/v2/undo.json @@ -3670,6 +3670,50 @@ "type": "safe" } }, + "DetachCase": { + "tag": "Security Monitoring", + "undo": { + "type": "idempotent" + } + }, + "CreateCases": { + "tag": "Security Monitoring", + "undo": { + "operationId": "DetachCase", + "parameters": [ + { + "name": "body", + "template": "{\n \"data\": {\n \"type\": \"cases\",\n \"id\": \"{{data[0].id}}\",\n \"relationships\": {\n \"findings\": {\n \"data\": [\n {\n \"type\": \"findings\",\n \"id\": \"{{data[0].attributes.insights[0].resource_id}}\"\n }\n ]\n }\n }\n }\n}" + } + ], + "type": "unsafe" + } + }, + "AttachCase": { + "tag": "Security Monitoring", + "undo": { + "type": "idempotent" + } + }, + "AttachJiraIssue": { + "tag": "Security Monitoring", + "undo": { + "type": "idempotent" + } + }, + "CreateJiraIssues": { + "tag": "Security Monitoring", + "undo": { + "operationId": "DetachCase", + "parameters": [ + { + "name": "body", + "template": "{\n \"data\": {\n \"type\": \"cases\",\n \"id\": \"{{data[0].id}}\",\n \"relationships\": {\n \"findings\": {\n \"data\": [\n {\n \"type\": \"findings\",\n \"id\": \"{{data[0].attributes.insights[0].resource_id}}\"\n }\n ]\n }\n }\n }\n}" + } + ], + "type": "unsafe" + } + }, "ListAssetsSBOMs": { "tag": "Security Monitoring", "undo": { diff --git a/tests/scenarios/function_mappings.rs b/tests/scenarios/function_mappings.rs index 925d69993..a1421af5e 100644 --- a/tests/scenarios/function_mappings.rs +++ b/tests/scenarios/function_mappings.rs @@ -2390,6 +2390,21 @@ pub fn collect_function_calls(world: &mut DatadogWorld) { world .function_mappings .insert("v2.GetFinding".into(), test_v2_get_finding); + world + .function_mappings + .insert("v2.DetachCase".into(), test_v2_detach_case); + world + .function_mappings + .insert("v2.CreateCases".into(), test_v2_create_cases); + world + .function_mappings + .insert("v2.AttachCase".into(), test_v2_attach_case); + world + .function_mappings + .insert("v2.AttachJiraIssue".into(), test_v2_attach_jira_issue); + world + .function_mappings + .insert("v2.CreateJiraIssues".into(), test_v2_create_jira_issues); world .function_mappings .insert("v2.ListAssetsSBOMs".into(), test_v2_list_assets_sbo_ms); @@ -16748,6 +16763,132 @@ fn test_v2_get_finding(world: &mut DatadogWorld, _parameters: &HashMap) { + let api = world + .api_instances + .v2_api_security_monitoring + .as_ref() + .expect("api instance not found"); + let body = serde_json::from_value(_parameters.get("body").unwrap().clone()).unwrap(); + let response = match block_on(api.detach_case_with_http_info(body)) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + +fn test_v2_create_cases(world: &mut DatadogWorld, _parameters: &HashMap) { + let api = world + .api_instances + .v2_api_security_monitoring + .as_ref() + .expect("api instance not found"); + let body = serde_json::from_value(_parameters.get("body").unwrap().clone()).unwrap(); + let response = match block_on(api.create_cases_with_http_info(body)) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + +fn test_v2_attach_case(world: &mut DatadogWorld, _parameters: &HashMap) { + let api = world + .api_instances + .v2_api_security_monitoring + .as_ref() + .expect("api instance not found"); + let case_id = serde_json::from_value(_parameters.get("case_id").unwrap().clone()).unwrap(); + let body = serde_json::from_value(_parameters.get("body").unwrap().clone()).unwrap(); + let response = match block_on(api.attach_case_with_http_info(case_id, body)) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + +fn test_v2_attach_jira_issue(world: &mut DatadogWorld, _parameters: &HashMap) { + let api = world + .api_instances + .v2_api_security_monitoring + .as_ref() + .expect("api instance not found"); + let body = serde_json::from_value(_parameters.get("body").unwrap().clone()).unwrap(); + let response = match block_on(api.attach_jira_issue_with_http_info(body)) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + +fn test_v2_create_jira_issues(world: &mut DatadogWorld, _parameters: &HashMap) { + let api = world + .api_instances + .v2_api_security_monitoring + .as_ref() + .expect("api instance not found"); + let body = serde_json::from_value(_parameters.get("body").unwrap().clone()).unwrap(); + let response = match block_on(api.create_jira_issues_with_http_info(body)) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + fn test_v2_list_assets_sbo_ms(world: &mut DatadogWorld, _parameters: &HashMap) { let api = world .api_instances