diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 9f43840f75..0d0a0d67f3 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -9188,6 +9188,18 @@ components: required: - type type: object + CloudAssetType: + description: The cloud asset type + enum: + - Host + - HostImage + - Image + example: Host + type: string + x-enum-varnames: + - HOST + - HOST_IMAGE + - IMAGE CloudConfigurationComplianceRuleOptions: additionalProperties: {} description: 'Options for cloud_configuration rules. @@ -41130,6 +41142,16 @@ components: - MACHINE_LEARNING_MODEL - OPERATING_SYSTEM - PLATFORM + SBOMFormat: + description: The SBOM standard + enum: + - CycloneDX + - SPDX + example: CycloneDX + type: string + x-enum-varnames: + - CYCLONEDX + - SPDX SBOMMetadata: description: Provides additional information about a BOM. properties: @@ -41395,6 +41417,86 @@ components: type: $ref: '#/components/schemas/ScalarFormulaResponseType' type: object + ScannedAssetMetadata: + description: The metadata of a scanned asset. + properties: + attributes: + $ref: '#/components/schemas/ScannedAssetMetadataAttributes' + id: + description: The ID of the scanned asset metadata. + example: Host|i-0fc7edef1ab26d7ef + type: string + required: + - id + - attributes + type: object + ScannedAssetMetadataAsset: + description: The asset of a scanned asset metadata. + properties: + name: + description: The name of the asset. + example: i-0fc7edef1ab26d7ef + type: string + type: + $ref: '#/components/schemas/CloudAssetType' + required: + - type + - name + type: object + ScannedAssetMetadataAttributes: + description: The attributes of a scanned asset metadata. + properties: + asset: + $ref: '#/components/schemas/ScannedAssetMetadataAsset' + first_success_timestamp: + description: The timestamp when the scan of the asset was performed for + the first time. + example: '2025-07-08T07:24:53Z' + type: string + last_success: + $ref: '#/components/schemas/ScannedAssetMetadataLastSuccess' + required: + - asset + - last_success + - first_success_timestamp + type: object + ScannedAssetMetadataLastSuccess: + description: Metadata for the last successful scan of an asset. + properties: + env: + description: The environment of the last success scan of the asset. + example: prod + type: string + origin: + description: The list of origins of the last success scan of the asset. + example: + - production + items: + example: production + type: string + type: array + timestamp: + description: The timestamp of the last success scan of the asset. + example: '2025-07-08T07:24:53Z' + type: string + required: + - timestamp + type: object + ScannedAssetsMetadata: + description: The expected response schema when listing scanned assets metadata. + properties: + data: + description: List of scanned assets metadata. + items: + $ref: '#/components/schemas/ScannedAssetMetadata' + type: array + links: + $ref: '#/components/schemas/Links' + meta: + $ref: '#/components/schemas/Metadata' + required: + - data + type: object Schedule: description: Top-level container for a schedule object, including both the `data` payload and any related `included` resources (such as teams, layers, or members). @@ -51590,9 +51692,29 @@ components: - attributes - relationships type: object + VulnerabilityAdvisory: + description: Advisory associated with the vulnerability. + properties: + id: + description: Vulnerability advisory ID. + example: TRIVY-CVE-2023-0615 + type: string + last_modification_date: + description: Vulnerability advisory last modification date. + example: 2024-09-19 21:23:08+00:00 + type: string + publish_date: + description: Vulnerability advisory publish date. + example: 2024-09-19 21:23:08+00:00 + type: string + required: + - id + type: object VulnerabilityAttributes: description: The JSON:API attributes of the vulnerability. properties: + advisory: + $ref: '#/components/schemas/VulnerabilityAdvisory' advisory_id: description: Vulnerability advisory ID. example: TRIVY-CVE-2023-0615 @@ -71238,194 +71360,6 @@ paths: x-unstable: '**Note**: This endpoint is in public beta. If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/).' - /api/v2/security/assets: - get: - description: 'Get a list of vulnerable assets. - - - ### Pagination - - - Please review the [Pagination section for the "List Vulnerabilities"](#pagination) - endpoint. - - - ### Filtering - - - Please review the [Filtering section for the "List Vulnerabilities"](#filtering) - endpoint. - - - ### Metadata - - - Please review the [Metadata section for the "List Vulnerabilities"](#metadata) - endpoint.' - operationId: ListVulnerableAssets - parameters: - - description: Its value must come from the `links` section of the response - of the first request. Do not manually edit it. - example: b82cef018aab81ed1d4bb4xb35xxfc065da7efa685fbcecdbd338f3015e3afabbbfa3a911b4984_721ee28a-zecb-4e45-9960-c42065b574f4 - in: query - name: page[token] - required: false - schema: - type: string - - description: The page number to be retrieved. It should be equal or greater - than `1` - example: 1 - in: query - name: page[number] - required: false - schema: - format: int64 - minimum: 1 - type: integer - - description: Filter by name. - example: datadog-agent - in: query - name: filter[name] - required: false - schema: - type: string - - description: Filter by type. - example: Host - in: query - name: filter[type] - required: false - schema: - $ref: '#/components/schemas/AssetType' - - description: Filter by the first version of the asset since it has been vulnerable. - example: v1.15.1 - in: query - name: filter[version.first] - required: false - schema: - type: string - - description: Filter by the last detected version of the asset. - example: v1.15.1 - in: query - name: filter[version.last] - required: false - schema: - type: string - - description: Filter by the repository url associated to the asset. - example: github.com/DataDog/datadog-agent.git - in: query - name: filter[repository_url] - required: false - schema: - type: string - - description: Filter whether the asset is in production or not. - example: false - in: query - name: filter[risks.in_production] - required: false - schema: - type: boolean - - description: Filter whether the asset (Service) is under attack or not. - example: false - in: query - name: filter[risks.under_attack] - required: false - schema: - type: boolean - - description: Filter whether the asset (Host) is publicly accessible or not. - example: false - in: query - name: filter[risks.is_publicly_accessible] - required: false - schema: - type: boolean - - description: Filter whether the asset (Host) has privileged access or not. - example: false - in: query - name: filter[risks.has_privileged_access] - required: false - schema: - type: boolean - - description: Filter whether the asset (Host) has access to sensitive data - or not. - example: false - in: query - name: filter[risks.has_access_to_sensitive_data] - required: false - schema: - type: boolean - - description: Filter by environment. - example: staging - in: query - name: filter[environments] - required: false - schema: - type: string - - description: Filter by teams. - example: compute - in: query - name: filter[teams] - required: false - schema: - type: string - - description: Filter by architecture. - example: arm64 - in: query - name: filter[arch] - required: false - schema: - type: string - - description: Filter by operating system name. - example: ubuntu - in: query - name: filter[operating_system.name] - required: false - schema: - type: string - - description: Filter by operating system version. - example: '24.04' - in: query - name: filter[operating_system.version] - required: false - schema: - type: string - responses: - '200': - content: - application/json: - schema: - $ref: '#/components/schemas/ListVulnerableAssetsResponse' - description: OK - '400': - content: - application/json: - schema: - $ref: '#/components/schemas/JSONAPIErrorResponse' - description: 'Bad request: The server cannot process the request due to - invalid syntax in the request.' - '403': - content: - application/json: - schema: - $ref: '#/components/schemas/JSONAPIErrorResponse' - description: 'Forbidden: Access denied' - '404': - content: - application/json: - schema: - $ref: '#/components/schemas/JSONAPIErrorResponse' - description: 'Not found: There is no request associated with the provided - token.' - '429': - $ref: '#/components/responses/TooManyRequestsResponse' - security: - - apiKeyAuth: [] - appKeyAuth: [] - summary: List vulnerable assets - tags: - - Security Monitoring - x-unstable: '**Note**: This endpoint is a private preview. - - If you are interested in accessing this API, [fill out this form](https://forms.gle/kMYC1sDr6WDUBDsx9).' /api/v2/security/cloud_workload/policy/download: get: description: 'The download endpoint generates a Workload Protection policy file @@ -71610,6 +71544,13 @@ paths: required: false schema: type: string + - description: The standard of the SBOM. + example: CycloneDX + in: query + name: ext:format + required: false + schema: + $ref: '#/components/schemas/SBOMFormat' responses: '200': content: @@ -71647,6 +71588,120 @@ paths: x-unstable: '**Note**: This endpoint is a private preview. If you are interested in accessing this API, [fill out this form](https://forms.gle/kMYC1sDr6WDUBDsx9).' + /api/v2/security/scanned-assets-metadata: + get: + description: "Get a list of security scanned assets metadata for an organization.\n\n### + Pagination\n\nFor the \"List Vulnerabilities\" endpoint, see the [Pagination + section](#pagination).\n\n### Filtering\n\nFor the \"List Vulnerabilities\" + endpoint, see the [Filtering section](#filtering).\n\n### Metadata\n\n For + the \"List Vulnerabilities\" endpoint, see the [Metadata section](#metadata).\n\n### + Related endpoints\n\nThis endpoint returns additional metadata for cloud resources + that is not available from the standard resource endpoints. To access a richer + dataset, call this endpoint together with the relevant resource endpoint(s) + and merge (join) their results using the resource identifier.\n\n**Hosts**\n\nTo + enrich host data, join the response from the [Hosts](https://docs.datadoghq.com/api/latest/hosts/) + endpoint with the response from the scanned-assets-metadata endpoint on the + following key fields:\n\n| ENDPOINT | JOIN KEY | TYPE |\n| --- | --- | --- + |\n| [/api/v1/hosts](https://docs.datadoghq.com/api/latest/hosts/) | host_list.host_name + | string |\n| /api/v2/security/scanned-assets-metadata | data.attributes.asset.name + | string |\n\n**Host Images**\n\nTo enrich host image data, join the response + from the [Hosts](https://docs.datadoghq.com/api/latest/hosts/) endpoint with + the response from the scanned-assets-metadata endpoint on the following key + fields:\n\n| ENDPOINT | JOIN KEY | TYPE |\n| --- | --- | --- |\n| [/api/v1/hosts](https://docs.datadoghq.com/api/latest/hosts/) + | host_list.tags_by_source[\"Amazon Web Services\"][\"image\"] | string |\n| + /api/v2/security/scanned-assets-metadata | data.attributes.asset.name | string + |\n\n**Container Images**\n\nTo enrich container image data, join the response + from the [Container Images](https://docs.datadoghq.com/api/latest/container-images/) + endpoint with the response from the scanned-assets-metadata endpoint on the + following key fields:\n\n| ENDPOINT | JOIN KEY | TYPE |\n| --- | --- | --- + |\n| [/api/v2/container_images](https://docs.datadoghq.com/api/latest/container-images/) + | `data.attributes.name`@`data.attributes.repo_digest` | string |\n| /api/v2/security/scanned-assets-metadata + | data.attributes.asset.name | string |" + operationId: ListScannedAssetsMetadata + parameters: + - description: Its value must come from the `links` section of the response + of the first request. Do not manually edit it. + example: b82cef018aab81ed1d4bb4xb35xxfc065da7efa685fbcecdbd338f3015e3afabbbfa3a911b4984_721ee28a-zecb-4e45-9960-c42065b574f4 + in: query + name: page[token] + required: false + schema: + type: string + - description: The page number to be retrieved. It should be equal to or greater + than 1. + example: 1 + in: query + name: page[number] + required: false + schema: + format: int64 + minimum: 1 + type: integer + - description: The type of the scanned asset. + example: Host + in: query + name: filter[asset.type] + required: false + schema: + $ref: '#/components/schemas/CloudAssetType' + - description: The name of the scanned asset. + example: i-0fc7edef1ab26d7ef + in: query + name: filter[asset.name] + required: false + schema: + type: string + - description: The origin of last success scan. + example: agent + in: query + name: filter[last_success.origin] + required: false + schema: + type: string + - description: The environment of last success scan. + example: prod + in: query + name: filter[last_success.env] + required: false + schema: + type: string + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/ScannedAssetsMetadata' + description: OK + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/JSONAPIErrorResponse' + description: 'Bad request: The server cannot process the request due to + invalid syntax in the request.' + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/JSONAPIErrorResponse' + description: 'Forbidden: Access denied' + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/JSONAPIErrorResponse' + description: 'Not found: asset not found' + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + summary: List scanned assets metadata + tags: + - Security Monitoring + x-unstable: '**Note**: This endpoint is a private preview. + + If you are interested in accessing this API, [fill out this form](https://forms.gle/kMYC1sDr6WDUBDsx9).' /api/v2/security/signals/notification_rules: get: description: Returns the list of notification rules for security signals. @@ -71837,27 +71892,34 @@ paths: consider a request to be the first request when there is no `page[token]` parameter.\n\nThe response of this first request contains the newly created token in the `links` section.\n\nThis token can then be used in the subsequent - paginated requests.\n\n#### Subsequent requests\n\nAny request containing + paginated requests.\n\n*Note: The first request may take longer to complete + than subsequent requests.*\n\n#### Subsequent requests\n\nAny request containing valid `page[token]` and `page[number]` parameters will be considered a subsequent request.\n\nIf the `token` is invalid, a `404` response will be returned.\n\nIf - the page `number` is invalid, a `400` response will be returned.\n\n### Filtering\n\nThe - request can include some filter parameters to filter the data to be retrieved. - The format of the filter parameters follows the [JSON:API format](https://jsonapi.org/format/#fetching-filtering): - `filter[$prop_name]`, where `prop_name` is the property name in the entity - being filtered by.\n\nAll filters can include multiple values, where data - will be filtered with an OR clause: `filter[title]=Title1,Title2` will filter - all vulnerabilities where title is equal to `Title1` OR `Title2`.\n\nString - filters are case sensitive.\n\nBoolean filters accept `true` or `false` as - values.\n\nNumber filters must include an operator as a second filter input: - `filter[$prop_name][$operator]`. For example, for the vulnerabilities endpoint: - `filter[cvss.base.score][lte]=8`.\n\nAvailable operators are: `eq` (==), `lt` - (<), `lte` (<=), `gt` (>) and `gte` (>=).\n\n### Metadata\n\nFollowing [JSON:API - format](https://jsonapi.org/format/#document-meta), object including non-standard - meta-information.\n\nThis endpoint includes the meta member in the response. - For more details on each of the properties included in this section, check - the endpoints response tables.\n\n```JSON\n{\n \"data\": [...],\n \"meta\": - {\n \"total\": 1500,\n \"count\": 18732,\n \"token\": \"some_token\"\n - \ },\n \"links\": {...}\n}\n```" + the page `number` is invalid, a `400` response will be returned.\n\nThe returned + `token` is valid for all requests in the pagination sequence. To send paginated + requests in parallel, reuse the same `token` and change only the `page[number]` + parameter.\n\n### Filtering\n\nThe request can include some filter parameters + to filter the data to be retrieved. The format of the filter parameters follows + the [JSON:API format](https://jsonapi.org/format/#fetching-filtering): `filter[$prop_name]`, + where `prop_name` is the property name in the entity being filtered by.\n\nAll + filters can include multiple values, where data will be filtered with an OR + clause: `filter[title]=Title1,Title2` will filter all vulnerabilities where + title is equal to `Title1` OR `Title2`.\n\nString filters are case sensitive.\n\nBoolean + filters accept `true` or `false` as values.\n\nNumber filters must include + an operator as a second filter input: `filter[$prop_name][$operator]`. For + example, for the vulnerabilities endpoint: `filter[cvss.base.score][lte]=8`.\n\nAvailable + operators are: `eq` (==), `lt` (<), `lte` (<=), `gt` (>) and `gte` (>=).\n\n### + Metadata\n\nFollowing [JSON:API format](https://jsonapi.org/format/#document-meta), + object including non-standard meta-information.\n\nThis endpoint includes + the meta member in the response. For more details on each of the properties + included in this section, check the endpoints response tables.\n\n```JSON\n{\n + \ \"data\": [...],\n \"meta\": {\n \"total\": 1500,\n \"count\": 18732,\n + \ \"token\": \"some_token\"\n },\n \"links\": {...}\n}\n```\n### Extensions\n\nRequests + may include extensions to modify the behavior of the requested endpoint. The + filter parameters follow the [JSON:API format](https://jsonapi.org/extensions/#extensions) + format: `ext:$extension_name`, where `extension_name` is the name of the modifier + that is being applied.\n\nExtensions can only include one value: `ext:modifier=value`." operationId: ListVulnerabilities parameters: - description: Its value must come from the `links` section of the response @@ -71963,9 +72025,9 @@ paths: schema: type: string - description: Filter by advisory ID. - example: TRIVY-CVE-2023-0615 + example: CVE-2023-0615 in: query - name: filter[advisory_id] + name: filter[advisory.id] required: false schema: type: string @@ -72065,7 +72127,8 @@ paths: required: false schema: type: string - - description: Filter by asset name. + - description: Filter by asset name. This field supports the usage of wildcards + (*). example: datadog-agent in: query name: filter[asset.name] @@ -72380,6 +72443,194 @@ paths: operator: OR permissions: - security_monitoring_notification_profiles_write + /api/v2/security/vulnerable-assets: + get: + description: 'Get a list of vulnerable assets. + + + ### Pagination + + + Please review the [Pagination section for the "List Vulnerabilities"](#pagination) + endpoint. + + + ### Filtering + + + Please review the [Filtering section for the "List Vulnerabilities"](#filtering) + endpoint. + + + ### Metadata + + + Please review the [Metadata section for the "List Vulnerabilities"](#metadata) + endpoint.' + operationId: ListVulnerableAssets + parameters: + - description: Its value must come from the `links` section of the response + of the first request. Do not manually edit it. + example: b82cef018aab81ed1d4bb4xb35xxfc065da7efa685fbcecdbd338f3015e3afabbbfa3a911b4984_721ee28a-zecb-4e45-9960-c42065b574f4 + in: query + name: page[token] + required: false + schema: + type: string + - description: The page number to be retrieved. It should be equal or greater + than `1` + example: 1 + in: query + name: page[number] + required: false + schema: + format: int64 + minimum: 1 + type: integer + - description: Filter by name. This field supports the usage of wildcards (*). + example: datadog-agent + in: query + name: filter[name] + required: false + schema: + type: string + - description: Filter by type. + example: Host + in: query + name: filter[type] + required: false + schema: + $ref: '#/components/schemas/AssetType' + - description: Filter by the first version of the asset since it has been vulnerable. + example: v1.15.1 + in: query + name: filter[version.first] + required: false + schema: + type: string + - description: Filter by the last detected version of the asset. + example: v1.15.1 + in: query + name: filter[version.last] + required: false + schema: + type: string + - description: Filter by the repository url associated to the asset. + example: github.com/DataDog/datadog-agent.git + in: query + name: filter[repository_url] + required: false + schema: + type: string + - description: Filter whether the asset is in production or not. + example: false + in: query + name: filter[risks.in_production] + required: false + schema: + type: boolean + - description: Filter whether the asset (Service) is under attack or not. + example: false + in: query + name: filter[risks.under_attack] + required: false + schema: + type: boolean + - description: Filter whether the asset (Host) is publicly accessible or not. + example: false + in: query + name: filter[risks.is_publicly_accessible] + required: false + schema: + type: boolean + - description: Filter whether the asset (Host) has privileged access or not. + example: false + in: query + name: filter[risks.has_privileged_access] + required: false + schema: + type: boolean + - description: Filter whether the asset (Host) has access to sensitive data + or not. + example: false + in: query + name: filter[risks.has_access_to_sensitive_data] + required: false + schema: + type: boolean + - description: Filter by environment. + example: staging + in: query + name: filter[environments] + required: false + schema: + type: string + - description: Filter by teams. + example: compute + in: query + name: filter[teams] + required: false + schema: + type: string + - description: Filter by architecture. + example: arm64 + in: query + name: filter[arch] + required: false + schema: + type: string + - description: Filter by operating system name. + example: ubuntu + in: query + name: filter[operating_system.name] + required: false + schema: + type: string + - description: Filter by operating system version. + example: '24.04' + in: query + name: filter[operating_system.version] + required: false + schema: + type: string + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/ListVulnerableAssetsResponse' + description: OK + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/JSONAPIErrorResponse' + description: 'Bad request: The server cannot process the request due to + invalid syntax in the request.' + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/JSONAPIErrorResponse' + description: 'Forbidden: Access denied' + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/JSONAPIErrorResponse' + description: 'Not found: There is no request associated with the provided + token.' + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + summary: List vulnerable assets + tags: + - Security Monitoring + x-unstable: '**Note**: This endpoint is a private preview. + + If you are interested in accessing this API, [fill out this form](https://forms.gle/kMYC1sDr6WDUBDsx9).' /api/v2/security_monitoring/cloud_workload_security/agent_rules: get: description: 'Get the list of agent rules. diff --git a/docs/datadog_api_client.v2.model.rst b/docs/datadog_api_client.v2.model.rst index 776cbd170e..69072a0e9c 100644 --- a/docs/datadog_api_client.v2.model.rst +++ b/docs/datadog_api_client.v2.model.rst @@ -3504,6 +3504,13 @@ datadog\_api\_client.v2.model.clickup\_integration\_update module :members: :show-inheritance: +datadog\_api\_client.v2.model.cloud\_asset\_type module +------------------------------------------------------- + +.. automodule:: datadog_api_client.v2.model.cloud_asset_type + :members: + :show-inheritance: + datadog\_api\_client.v2.model.cloud\_configuration\_compliance\_rule\_options module ------------------------------------------------------------------------------------ @@ -18106,6 +18113,13 @@ datadog\_api\_client.v2.model.sbom\_component\_type module :members: :show-inheritance: +datadog\_api\_client.v2.model.sbom\_format module +------------------------------------------------- + +.. automodule:: datadog_api_client.v2.model.sbom_format + :members: + :show-inheritance: + datadog\_api\_client.v2.model.sbom\_metadata module --------------------------------------------------- @@ -18232,6 +18246,41 @@ datadog\_api\_client.v2.model.scalar\_response module :members: :show-inheritance: +datadog\_api\_client.v2.model.scanned\_asset\_metadata module +------------------------------------------------------------- + +.. automodule:: datadog_api_client.v2.model.scanned_asset_metadata + :members: + :show-inheritance: + +datadog\_api\_client.v2.model.scanned\_asset\_metadata\_asset module +-------------------------------------------------------------------- + +.. automodule:: datadog_api_client.v2.model.scanned_asset_metadata_asset + :members: + :show-inheritance: + +datadog\_api\_client.v2.model.scanned\_asset\_metadata\_attributes module +------------------------------------------------------------------------- + +.. automodule:: datadog_api_client.v2.model.scanned_asset_metadata_attributes + :members: + :show-inheritance: + +datadog\_api\_client.v2.model.scanned\_asset\_metadata\_last\_success module +---------------------------------------------------------------------------- + +.. automodule:: datadog_api_client.v2.model.scanned_asset_metadata_last_success + :members: + :show-inheritance: + +datadog\_api\_client.v2.model.scanned\_assets\_metadata module +-------------------------------------------------------------- + +.. automodule:: datadog_api_client.v2.model.scanned_assets_metadata + :members: + :show-inheritance: + datadog\_api\_client.v2.model.schedule module --------------------------------------------- @@ -22768,6 +22817,13 @@ datadog\_api\_client.v2.model.vulnerability module :members: :show-inheritance: +datadog\_api\_client.v2.model.vulnerability\_advisory module +------------------------------------------------------------ + +.. automodule:: datadog_api_client.v2.model.vulnerability_advisory + :members: + :show-inheritance: + datadog\_api\_client.v2.model.vulnerability\_attributes module -------------------------------------------------------------- diff --git a/examples/v2/security-monitoring/ListScannedAssetsMetadata.py b/examples/v2/security-monitoring/ListScannedAssetsMetadata.py new file mode 100644 index 0000000000..e8c48d247d --- /dev/null +++ b/examples/v2/security-monitoring/ListScannedAssetsMetadata.py @@ -0,0 +1,14 @@ +""" +List scanned assets metadata returns "OK" response +""" + +from datadog_api_client import ApiClient, Configuration +from datadog_api_client.v2.api.security_monitoring_api import SecurityMonitoringApi + +configuration = Configuration() +configuration.unstable_operations["list_scanned_assets_metadata"] = True +with ApiClient(configuration) as api_client: + api_instance = SecurityMonitoringApi(api_client) + response = api_instance.list_scanned_assets_metadata() + + print(response) diff --git a/src/datadog_api_client/configuration.py b/src/datadog_api_client/configuration.py index dddfc62f47..508a12fde7 100644 --- a/src/datadog_api_client/configuration.py +++ b/src/datadog_api_client/configuration.py @@ -253,6 +253,7 @@ def __init__( "v2.list_assets_sbo_ms": False, "v2.list_findings": False, "v2.list_historical_jobs": False, + "v2.list_scanned_assets_metadata": False, "v2.list_security_monitoring_histsignals": False, "v2.list_vulnerabilities": False, "v2.list_vulnerable_assets": False, diff --git a/src/datadog_api_client/v2/api/security_monitoring_api.py b/src/datadog_api_client/v2/api/security_monitoring_api.py index a6b95ea593..1aef9ceb5a 100644 --- a/src/datadog_api_client/v2/api/security_monitoring_api.py +++ b/src/datadog_api_client/v2/api/security_monitoring_api.py @@ -36,11 +36,13 @@ from datadog_api_client.v2.model.bulk_mute_findings_response import BulkMuteFindingsResponse from datadog_api_client.v2.model.bulk_mute_findings_request import BulkMuteFindingsRequest from datadog_api_client.v2.model.get_finding_response import GetFindingResponse -from datadog_api_client.v2.model.list_vulnerable_assets_response import ListVulnerableAssetsResponse -from datadog_api_client.v2.model.asset_type import AssetType from datadog_api_client.v2.model.list_assets_sbo_ms_response import ListAssetsSBOMsResponse +from datadog_api_client.v2.model.asset_type import AssetType from datadog_api_client.v2.model.sbom_component_license_type import SBOMComponentLicenseType from datadog_api_client.v2.model.get_sbom_response import GetSBOMResponse +from datadog_api_client.v2.model.sbom_format import SBOMFormat +from datadog_api_client.v2.model.scanned_assets_metadata import ScannedAssetsMetadata +from datadog_api_client.v2.model.cloud_asset_type import CloudAssetType from datadog_api_client.v2.model.notification_rule_response import NotificationRuleResponse from datadog_api_client.v2.model.create_notification_rule_parameters import CreateNotificationRuleParameters from datadog_api_client.v2.model.patch_notification_rule_parameters import PatchNotificationRuleParameters @@ -50,6 +52,7 @@ from datadog_api_client.v2.model.vulnerability_status import VulnerabilityStatus from datadog_api_client.v2.model.vulnerability_tool import VulnerabilityTool from datadog_api_client.v2.model.vulnerability_ecosystem import VulnerabilityEcosystem +from datadog_api_client.v2.model.list_vulnerable_assets_response import ListVulnerableAssetsResponse from datadog_api_client.v2.model.security_filters_response import SecurityFiltersResponse from datadog_api_client.v2.model.security_filter_response import SecurityFilterResponse from datadog_api_client.v2.model.security_filter_create_request import SecurityFilterCreateRequest @@ -742,6 +745,11 @@ def __init__(self, api_client=None): "attribute": "filter[repo_digest]", "location": "query", }, + "ext_format": { + "openapi_types": (SBOMFormat,), + "attribute": "ext:format", + "location": "query", + }, }, headers_map={ "accept": ["application/json"], @@ -1238,6 +1246,56 @@ def __init__(self, api_client=None): api_client=api_client, ) + self._list_scanned_assets_metadata_endpoint = _Endpoint( + settings={ + "response_type": (ScannedAssetsMetadata,), + "auth": ["apiKeyAuth", "appKeyAuth"], + "endpoint_path": "/api/v2/security/scanned-assets-metadata", + "operation_id": "list_scanned_assets_metadata", + "http_method": "GET", + "version": "v2", + }, + params_map={ + "page_token": { + "openapi_types": (str,), + "attribute": "page[token]", + "location": "query", + }, + "page_number": { + "validation": { + "inclusive_minimum": 1, + }, + "openapi_types": (int,), + "attribute": "page[number]", + "location": "query", + }, + "filter_asset_type": { + "openapi_types": (CloudAssetType,), + "attribute": "filter[asset.type]", + "location": "query", + }, + "filter_asset_name": { + "openapi_types": (str,), + "attribute": "filter[asset.name]", + "location": "query", + }, + "filter_last_success_origin": { + "openapi_types": (str,), + "attribute": "filter[last_success.origin]", + "location": "query", + }, + "filter_last_success_env": { + "openapi_types": (str,), + "attribute": "filter[last_success.env]", + "location": "query", + }, + }, + headers_map={ + "accept": ["application/json"], + }, + api_client=api_client, + ) + self._list_security_filters_endpoint = _Endpoint( settings={ "response_type": (SecurityFiltersResponse,), @@ -1491,7 +1549,7 @@ def __init__(self, api_client=None): }, "filter_advisory_id": { "openapi_types": (str,), - "attribute": "filter[advisory_id]", + "attribute": "filter[advisory.id]", "location": "query", }, "filter_risks_exploitation_probability": { @@ -1649,7 +1707,7 @@ def __init__(self, api_client=None): settings={ "response_type": (ListVulnerableAssetsResponse,), "auth": ["apiKeyAuth", "appKeyAuth"], - "endpoint_path": "/api/v2/security/assets", + "endpoint_path": "/api/v2/security/vulnerable-assets", "operation_id": "list_vulnerable_assets", "http_method": "GET", "version": "v2", @@ -2598,6 +2656,7 @@ def get_sbom( filter_asset_name: str, *, filter_repo_digest: Union[str, UnsetType] = unset, + ext_format: Union[SBOMFormat, UnsetType] = unset, ) -> GetSBOMResponse: """Get SBOM. @@ -2609,6 +2668,8 @@ def get_sbom( :type filter_asset_name: str :param filter_repo_digest: The container image ``repo_digest`` for the SBOM request. When the requested asset type is 'Image', this filter is mandatory. :type filter_repo_digest: str, optional + :param ext_format: The standard of the SBOM. + :type ext_format: SBOMFormat, optional :rtype: GetSBOMResponse """ kwargs: Dict[str, Any] = {} @@ -2619,6 +2680,9 @@ def get_sbom( if filter_repo_digest is not unset: kwargs["filter_repo_digest"] = filter_repo_digest + if ext_format is not unset: + kwargs["ext_format"] = ext_format + return self._get_sbom_endpoint.call_with_http_info(**kwargs) def get_security_filter( @@ -3232,6 +3296,123 @@ def list_historical_jobs( return self._list_historical_jobs_endpoint.call_with_http_info(**kwargs) + def list_scanned_assets_metadata( + self, + *, + page_token: Union[str, UnsetType] = unset, + page_number: Union[int, UnsetType] = unset, + filter_asset_type: Union[CloudAssetType, UnsetType] = unset, + filter_asset_name: Union[str, UnsetType] = unset, + filter_last_success_origin: Union[str, UnsetType] = unset, + filter_last_success_env: Union[str, UnsetType] = unset, + ) -> ScannedAssetsMetadata: + """List scanned assets metadata. + + Get a list of security scanned assets metadata for an organization. + + **Pagination** + + For the "List Vulnerabilities" endpoint, see the `Pagination section <#pagination>`_. + + **Filtering** + + For the "List Vulnerabilities" endpoint, see the `Filtering section <#filtering>`_. + + **Metadata** + + For the "List Vulnerabilities" endpoint, see the `Metadata section <#metadata>`_. + + **Related endpoints** + + This endpoint returns additional metadata for cloud resources that is not available from the standard resource endpoints. To access a richer dataset, call this endpoint together with the relevant resource endpoint(s) and merge (join) their results using the resource identifier. + + **Hosts** + + To enrich host data, join the response from the `Hosts `_ endpoint with the response from the scanned-assets-metadata endpoint on the following key fields: + + .. list-table:: + :header-rows: 1 + + * - ENDPOINT + - JOIN KEY + - TYPE + * - `/api/v1/hosts `_ + - host_list.host_name + - string + * - /api/v2/security/scanned-assets-metadata + - data.attributes.asset.name + - string + + **Host Images** + + To enrich host image data, join the response from the `Hosts `_ endpoint with the response from the scanned-assets-metadata endpoint on the following key fields: + + .. list-table:: + :header-rows: 1 + + * - ENDPOINT + - JOIN KEY + - TYPE + * - `/api/v1/hosts `_ + - host_list.tags_by_source["Amazon Web Services"]["image"] + - string + * - /api/v2/security/scanned-assets-metadata + - data.attributes.asset.name + - string + + **Container Images** + + To enrich container image data, join the response from the `Container Images `_ endpoint with the response from the scanned-assets-metadata endpoint on the following key fields: + + .. list-table:: + :header-rows: 1 + + * - ENDPOINT + - JOIN KEY + - TYPE + * - `/api/v2/container_images `_ + - ``data.attributes.name`` @ ``data.attributes.repo_digest`` + - string + * - /api/v2/security/scanned-assets-metadata + - data.attributes.asset.name + - string + + + :param page_token: Its value must come from the ``links`` section of the response of the first request. Do not manually edit it. + :type page_token: str, optional + :param page_number: The page number to be retrieved. It should be equal to or greater than 1. + :type page_number: int, optional + :param filter_asset_type: The type of the scanned asset. + :type filter_asset_type: CloudAssetType, optional + :param filter_asset_name: The name of the scanned asset. + :type filter_asset_name: str, optional + :param filter_last_success_origin: The origin of last success scan. + :type filter_last_success_origin: str, optional + :param filter_last_success_env: The environment of last success scan. + :type filter_last_success_env: str, optional + :rtype: ScannedAssetsMetadata + """ + kwargs: Dict[str, Any] = {} + if page_token is not unset: + kwargs["page_token"] = page_token + + if page_number is not unset: + kwargs["page_number"] = page_number + + if filter_asset_type is not unset: + kwargs["filter_asset_type"] = filter_asset_type + + if filter_asset_name is not unset: + kwargs["filter_asset_name"] = filter_asset_name + + if filter_last_success_origin is not unset: + kwargs["filter_last_success_origin"] = filter_last_success_origin + + if filter_last_success_env is not unset: + kwargs["filter_last_success_env"] = filter_last_success_env + + return self._list_scanned_assets_metadata_endpoint.call_with_http_info(**kwargs) + def list_security_filters( self, ) -> SecurityFiltersResponse: @@ -3538,6 +3719,8 @@ def list_vulnerabilities( This token can then be used in the subsequent paginated requests. + *Note: The first request may take longer to complete than subsequent requests.* + **Subsequent requests** Any request containing valid ``page[token]`` and ``page[number]`` parameters will be considered a subsequent request. @@ -3546,6 +3729,8 @@ def list_vulnerabilities( If the page ``number`` is invalid, a ``400`` response will be returned. + The returned ``token`` is valid for all requests in the pagination sequence. To send paginated requests in parallel, reuse the same ``token`` and change only the ``page[number]`` parameter. + **Filtering** The request can include some filter parameters to filter the data to be retrieved. The format of the filter parameters follows the `JSON:API format `_ : ``filter[$prop_name]`` , where ``prop_name`` is the property name in the entity being filtered by. @@ -3578,6 +3763,12 @@ def list_vulnerabilities( "links": {...} } + **Extensions** + + Requests may include extensions to modify the behavior of the requested endpoint. The filter parameters follow the `JSON:API format `_ format: ``ext:$extension_name`` , where ``extension_name`` is the name of the modifier that is being applied. + + Extensions can only include one value: ``ext:modifier=value``. + :param page_token: Its value must come from the ``links`` section of the response of the first request. Do not manually edit it. :type page_token: str, optional :param page_number: The page number to be retrieved. It should be equal or greater than ``1`` @@ -3632,7 +3823,7 @@ def list_vulnerabilities( :type filter_repo_digests: str, optional :param filter_origin: Filter by origin. :type filter_origin: str, optional - :param filter_asset_name: Filter by asset name. + :param filter_asset_name: Filter by asset name. This field supports the usage of wildcards (*). :type filter_asset_name: str, optional :param filter_asset_type: Filter by asset type. :type filter_asset_type: AssetType, optional @@ -3834,7 +4025,7 @@ def list_vulnerable_assets( :type page_token: str, optional :param page_number: The page number to be retrieved. It should be equal or greater than ``1`` :type page_number: int, optional - :param filter_name: Filter by name. + :param filter_name: Filter by name. This field supports the usage of wildcards (*). :type filter_name: str, optional :param filter_type: Filter by type. :type filter_type: AssetType, optional diff --git a/src/datadog_api_client/v2/model/cloud_asset_type.py b/src/datadog_api_client/v2/model/cloud_asset_type.py new file mode 100644 index 0000000000..b86a537a31 --- /dev/null +++ b/src/datadog_api_client/v2/model/cloud_asset_type.py @@ -0,0 +1,41 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + + +from datadog_api_client.model_utils import ( + ModelSimple, + cached_property, +) + +from typing import ClassVar + + +class CloudAssetType(ModelSimple): + """ + The cloud asset type + + :param value: Must be one of ["Host", "HostImage", "Image"]. + :type value: str + """ + + allowed_values = { + "Host", + "HostImage", + "Image", + } + HOST: ClassVar["CloudAssetType"] + HOST_IMAGE: ClassVar["CloudAssetType"] + IMAGE: ClassVar["CloudAssetType"] + + @cached_property + def openapi_types(_): + return { + "value": (str,), + } + + +CloudAssetType.HOST = CloudAssetType("Host") +CloudAssetType.HOST_IMAGE = CloudAssetType("HostImage") +CloudAssetType.IMAGE = CloudAssetType("Image") diff --git a/src/datadog_api_client/v2/model/sbom_format.py b/src/datadog_api_client/v2/model/sbom_format.py new file mode 100644 index 0000000000..76b3452229 --- /dev/null +++ b/src/datadog_api_client/v2/model/sbom_format.py @@ -0,0 +1,38 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + + +from datadog_api_client.model_utils import ( + ModelSimple, + cached_property, +) + +from typing import ClassVar + + +class SBOMFormat(ModelSimple): + """ + The SBOM standard + + :param value: Must be one of ["CycloneDX", "SPDX"]. + :type value: str + """ + + allowed_values = { + "CycloneDX", + "SPDX", + } + CYCLONEDX: ClassVar["SBOMFormat"] + SPDX: ClassVar["SBOMFormat"] + + @cached_property + def openapi_types(_): + return { + "value": (str,), + } + + +SBOMFormat.CYCLONEDX = SBOMFormat("CycloneDX") +SBOMFormat.SPDX = SBOMFormat("SPDX") diff --git a/src/datadog_api_client/v2/model/scanned_asset_metadata.py b/src/datadog_api_client/v2/model/scanned_asset_metadata.py new file mode 100644 index 0000000000..a948f2ca9f --- /dev/null +++ b/src/datadog_api_client/v2/model/scanned_asset_metadata.py @@ -0,0 +1,46 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + +from typing import TYPE_CHECKING + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, +) + + +if TYPE_CHECKING: + from datadog_api_client.v2.model.scanned_asset_metadata_attributes import ScannedAssetMetadataAttributes + + +class ScannedAssetMetadata(ModelNormal): + @cached_property + def openapi_types(_): + from datadog_api_client.v2.model.scanned_asset_metadata_attributes import ScannedAssetMetadataAttributes + + return { + "attributes": (ScannedAssetMetadataAttributes,), + "id": (str,), + } + + attribute_map = { + "attributes": "attributes", + "id": "id", + } + + def __init__(self_, attributes: ScannedAssetMetadataAttributes, id: str, **kwargs): + """ + The metadata of a scanned asset. + + :param attributes: The attributes of a scanned asset metadata. + :type attributes: ScannedAssetMetadataAttributes + + :param id: The ID of the scanned asset metadata. + :type id: str + """ + super().__init__(kwargs) + + self_.attributes = attributes + self_.id = id diff --git a/src/datadog_api_client/v2/model/scanned_asset_metadata_asset.py b/src/datadog_api_client/v2/model/scanned_asset_metadata_asset.py new file mode 100644 index 0000000000..5453b5853d --- /dev/null +++ b/src/datadog_api_client/v2/model/scanned_asset_metadata_asset.py @@ -0,0 +1,46 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + +from typing import TYPE_CHECKING + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, +) + + +if TYPE_CHECKING: + from datadog_api_client.v2.model.cloud_asset_type import CloudAssetType + + +class ScannedAssetMetadataAsset(ModelNormal): + @cached_property + def openapi_types(_): + from datadog_api_client.v2.model.cloud_asset_type import CloudAssetType + + return { + "name": (str,), + "type": (CloudAssetType,), + } + + attribute_map = { + "name": "name", + "type": "type", + } + + def __init__(self_, name: str, type: CloudAssetType, **kwargs): + """ + The asset of a scanned asset metadata. + + :param name: The name of the asset. + :type name: str + + :param type: The cloud asset type + :type type: CloudAssetType + """ + super().__init__(kwargs) + + self_.name = name + self_.type = type diff --git a/src/datadog_api_client/v2/model/scanned_asset_metadata_attributes.py b/src/datadog_api_client/v2/model/scanned_asset_metadata_attributes.py new file mode 100644 index 0000000000..314f48c4d1 --- /dev/null +++ b/src/datadog_api_client/v2/model/scanned_asset_metadata_attributes.py @@ -0,0 +1,60 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + +from typing import TYPE_CHECKING + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, +) + + +if TYPE_CHECKING: + from datadog_api_client.v2.model.scanned_asset_metadata_asset import ScannedAssetMetadataAsset + from datadog_api_client.v2.model.scanned_asset_metadata_last_success import ScannedAssetMetadataLastSuccess + + +class ScannedAssetMetadataAttributes(ModelNormal): + @cached_property + def openapi_types(_): + from datadog_api_client.v2.model.scanned_asset_metadata_asset import ScannedAssetMetadataAsset + from datadog_api_client.v2.model.scanned_asset_metadata_last_success import ScannedAssetMetadataLastSuccess + + return { + "asset": (ScannedAssetMetadataAsset,), + "first_success_timestamp": (str,), + "last_success": (ScannedAssetMetadataLastSuccess,), + } + + attribute_map = { + "asset": "asset", + "first_success_timestamp": "first_success_timestamp", + "last_success": "last_success", + } + + def __init__( + self_, + asset: ScannedAssetMetadataAsset, + first_success_timestamp: str, + last_success: ScannedAssetMetadataLastSuccess, + **kwargs, + ): + """ + The attributes of a scanned asset metadata. + + :param asset: The asset of a scanned asset metadata. + :type asset: ScannedAssetMetadataAsset + + :param first_success_timestamp: The timestamp when the scan of the asset was performed for the first time. + :type first_success_timestamp: str + + :param last_success: Metadata for the last successful scan of an asset. + :type last_success: ScannedAssetMetadataLastSuccess + """ + super().__init__(kwargs) + + self_.asset = asset + self_.first_success_timestamp = first_success_timestamp + self_.last_success = last_success diff --git a/src/datadog_api_client/v2/model/scanned_asset_metadata_last_success.py b/src/datadog_api_client/v2/model/scanned_asset_metadata_last_success.py new file mode 100644 index 0000000000..b6e091fefe --- /dev/null +++ b/src/datadog_api_client/v2/model/scanned_asset_metadata_last_success.py @@ -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. +from __future__ import annotations + +from typing import List, Union + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, + unset, + UnsetType, +) + + +class ScannedAssetMetadataLastSuccess(ModelNormal): + @cached_property + def openapi_types(_): + return { + "env": (str,), + "origin": ([str],), + "timestamp": (str,), + } + + attribute_map = { + "env": "env", + "origin": "origin", + "timestamp": "timestamp", + } + + def __init__( + self_, timestamp: str, env: Union[str, UnsetType] = unset, origin: Union[List[str], UnsetType] = unset, **kwargs + ): + """ + Metadata for the last successful scan of an asset. + + :param env: The environment of the last success scan of the asset. + :type env: str, optional + + :param origin: The list of origins of the last success scan of the asset. + :type origin: [str], optional + + :param timestamp: The timestamp of the last success scan of the asset. + :type timestamp: str + """ + if env is not unset: + kwargs["env"] = env + if origin is not unset: + kwargs["origin"] = origin + super().__init__(kwargs) + + self_.timestamp = timestamp diff --git a/src/datadog_api_client/v2/model/scanned_assets_metadata.py b/src/datadog_api_client/v2/model/scanned_assets_metadata.py new file mode 100644 index 0000000000..a2342eb85c --- /dev/null +++ b/src/datadog_api_client/v2/model/scanned_assets_metadata.py @@ -0,0 +1,66 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + +from typing import List, Union, TYPE_CHECKING + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, + unset, + UnsetType, +) + + +if TYPE_CHECKING: + from datadog_api_client.v2.model.scanned_asset_metadata import ScannedAssetMetadata + from datadog_api_client.v2.model.links import Links + from datadog_api_client.v2.model.metadata import Metadata + + +class ScannedAssetsMetadata(ModelNormal): + @cached_property + def openapi_types(_): + from datadog_api_client.v2.model.scanned_asset_metadata import ScannedAssetMetadata + from datadog_api_client.v2.model.links import Links + from datadog_api_client.v2.model.metadata import Metadata + + return { + "data": ([ScannedAssetMetadata],), + "links": (Links,), + "meta": (Metadata,), + } + + attribute_map = { + "data": "data", + "links": "links", + "meta": "meta", + } + + def __init__( + self_, + data: List[ScannedAssetMetadata], + links: Union[Links, UnsetType] = unset, + meta: Union[Metadata, UnsetType] = unset, + **kwargs, + ): + """ + The expected response schema when listing scanned assets metadata. + + :param data: List of scanned assets metadata. + :type data: [ScannedAssetMetadata] + + :param links: The JSON:API links related to pagination. + :type links: Links, optional + + :param meta: The metadata related to this request. + :type meta: Metadata, optional + """ + if links is not unset: + kwargs["links"] = links + if meta is not unset: + kwargs["meta"] = meta + super().__init__(kwargs) + + self_.data = data diff --git a/src/datadog_api_client/v2/model/vulnerability_advisory.py b/src/datadog_api_client/v2/model/vulnerability_advisory.py new file mode 100644 index 0000000000..a4ed0a106f --- /dev/null +++ b/src/datadog_api_client/v2/model/vulnerability_advisory.py @@ -0,0 +1,56 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + +from typing import Union + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, + unset, + UnsetType, +) + + +class VulnerabilityAdvisory(ModelNormal): + @cached_property + def openapi_types(_): + return { + "id": (str,), + "last_modification_date": (str,), + "publish_date": (str,), + } + + attribute_map = { + "id": "id", + "last_modification_date": "last_modification_date", + "publish_date": "publish_date", + } + + def __init__( + self_, + id: str, + last_modification_date: Union[str, UnsetType] = unset, + publish_date: Union[str, UnsetType] = unset, + **kwargs, + ): + """ + Advisory associated with the vulnerability. + + :param id: Vulnerability advisory ID. + :type id: str + + :param last_modification_date: Vulnerability advisory last modification date. + :type last_modification_date: str, optional + + :param publish_date: Vulnerability advisory publish date. + :type publish_date: str, optional + """ + if last_modification_date is not unset: + kwargs["last_modification_date"] = last_modification_date + if publish_date is not unset: + kwargs["publish_date"] = publish_date + super().__init__(kwargs) + + self_.id = id diff --git a/src/datadog_api_client/v2/model/vulnerability_attributes.py b/src/datadog_api_client/v2/model/vulnerability_attributes.py index 2a4cf3b4de..f6ad778602 100644 --- a/src/datadog_api_client/v2/model/vulnerability_attributes.py +++ b/src/datadog_api_client/v2/model/vulnerability_attributes.py @@ -14,6 +14,7 @@ if TYPE_CHECKING: + from datadog_api_client.v2.model.vulnerability_advisory import VulnerabilityAdvisory from datadog_api_client.v2.model.code_location import CodeLocation from datadog_api_client.v2.model.vulnerability_cvss import VulnerabilityCvss from datadog_api_client.v2.model.vulnerability_dependency_locations import VulnerabilityDependencyLocations @@ -29,6 +30,7 @@ class VulnerabilityAttributes(ModelNormal): @cached_property def openapi_types(_): + from datadog_api_client.v2.model.vulnerability_advisory import VulnerabilityAdvisory from datadog_api_client.v2.model.code_location import CodeLocation from datadog_api_client.v2.model.vulnerability_cvss import VulnerabilityCvss from datadog_api_client.v2.model.vulnerability_dependency_locations import VulnerabilityDependencyLocations @@ -41,6 +43,7 @@ def openapi_types(_): from datadog_api_client.v2.model.vulnerability_type import VulnerabilityType return { + "advisory": (VulnerabilityAdvisory,), "advisory_id": (str,), "code_location": (CodeLocation,), "cve_list": ([str],), @@ -65,6 +68,7 @@ def openapi_types(_): } attribute_map = { + "advisory": "advisory", "advisory_id": "advisory_id", "code_location": "code_location", "cve_list": "cve_list", @@ -105,6 +109,7 @@ def __init__( title: str, tool: VulnerabilityTool, type: VulnerabilityType, + advisory: Union[VulnerabilityAdvisory, UnsetType] = unset, advisory_id: Union[str, UnsetType] = unset, code_location: Union[CodeLocation, UnsetType] = unset, dependency_locations: Union[VulnerabilityDependencyLocations, UnsetType] = unset, @@ -116,6 +121,9 @@ def __init__( """ The JSON:API attributes of the vulnerability. + :param advisory: Advisory associated with the vulnerability. + :type advisory: VulnerabilityAdvisory, optional + :param advisory_id: Vulnerability advisory ID. :type advisory_id: str, optional @@ -179,6 +187,8 @@ def __init__( :param type: The vulnerability type. :type type: VulnerabilityType """ + if advisory is not unset: + kwargs["advisory"] = advisory if advisory_id is not unset: kwargs["advisory_id"] = advisory_id if code_location is not unset: diff --git a/src/datadog_api_client/v2/models/__init__.py b/src/datadog_api_client/v2/models/__init__.py index 9b303a84d7..5202a364b8 100644 --- a/src/datadog_api_client/v2/models/__init__.py +++ b/src/datadog_api_client/v2/models/__init__.py @@ -662,6 +662,7 @@ from datadog_api_client.v2.model.clickup_integration import ClickupIntegration from datadog_api_client.v2.model.clickup_integration_type import ClickupIntegrationType from datadog_api_client.v2.model.clickup_integration_update import ClickupIntegrationUpdate +from datadog_api_client.v2.model.cloud_asset_type import CloudAssetType from datadog_api_client.v2.model.cloud_configuration_compliance_rule_options import ( CloudConfigurationComplianceRuleOptions, ) @@ -3577,6 +3578,7 @@ from datadog_api_client.v2.model.sbom_component_property import SBOMComponentProperty from datadog_api_client.v2.model.sbom_component_supplier import SBOMComponentSupplier from datadog_api_client.v2.model.sbom_component_type import SBOMComponentType +from datadog_api_client.v2.model.sbom_format import SBOMFormat from datadog_api_client.v2.model.sbom_metadata import SBOMMetadata from datadog_api_client.v2.model.sbom_metadata_author import SBOMMetadataAuthor from datadog_api_client.v2.model.sbom_metadata_component import SBOMMetadataComponent @@ -3602,6 +3604,11 @@ from datadog_api_client.v2.model.scalar_meta import ScalarMeta from datadog_api_client.v2.model.scalar_query import ScalarQuery from datadog_api_client.v2.model.scalar_response import ScalarResponse +from datadog_api_client.v2.model.scanned_asset_metadata import ScannedAssetMetadata +from datadog_api_client.v2.model.scanned_asset_metadata_asset import ScannedAssetMetadataAsset +from datadog_api_client.v2.model.scanned_asset_metadata_attributes import ScannedAssetMetadataAttributes +from datadog_api_client.v2.model.scanned_asset_metadata_last_success import ScannedAssetMetadataLastSuccess +from datadog_api_client.v2.model.scanned_assets_metadata import ScannedAssetsMetadata from datadog_api_client.v2.model.schedule import Schedule from datadog_api_client.v2.model.schedule_create_request import ScheduleCreateRequest from datadog_api_client.v2.model.schedule_create_request_data import ScheduleCreateRequestData @@ -4490,6 +4497,7 @@ from datadog_api_client.v2.model.virus_total_integration_update import VirusTotalIntegrationUpdate from datadog_api_client.v2.model.vulnerabilities_type import VulnerabilitiesType from datadog_api_client.v2.model.vulnerability import Vulnerability +from datadog_api_client.v2.model.vulnerability_advisory import VulnerabilityAdvisory from datadog_api_client.v2.model.vulnerability_attributes import VulnerabilityAttributes from datadog_api_client.v2.model.vulnerability_cvss import VulnerabilityCvss from datadog_api_client.v2.model.vulnerability_dependency_locations import VulnerabilityDependencyLocations @@ -5040,6 +5048,7 @@ "ClickupIntegration", "ClickupIntegrationType", "ClickupIntegrationUpdate", + "CloudAssetType", "CloudConfigurationComplianceRuleOptions", "CloudConfigurationRegoRule", "CloudConfigurationRuleCaseCreate", @@ -7127,6 +7136,7 @@ "SBOMComponentProperty", "SBOMComponentSupplier", "SBOMComponentType", + "SBOMFormat", "SBOMMetadata", "SBOMMetadataAuthor", "SBOMMetadataComponent", @@ -7152,6 +7162,11 @@ "ScalarMeta", "ScalarQuery", "ScalarResponse", + "ScannedAssetMetadata", + "ScannedAssetMetadataAsset", + "ScannedAssetMetadataAttributes", + "ScannedAssetMetadataLastSuccess", + "ScannedAssetsMetadata", "Schedule", "ScheduleCreateRequest", "ScheduleCreateRequestData", @@ -7798,6 +7813,7 @@ "VirusTotalIntegrationUpdate", "VulnerabilitiesType", "Vulnerability", + "VulnerabilityAdvisory", "VulnerabilityAttributes", "VulnerabilityCvss", "VulnerabilityDependencyLocations", diff --git a/tests/v2/cassettes/test_scenarios/test_list_scanned_assets_metadata_returns_not_found_asset_not_found_response.frozen b/tests/v2/cassettes/test_scenarios/test_list_scanned_assets_metadata_returns_not_found_asset_not_found_response.frozen new file mode 100644 index 0000000000..69589f1391 --- /dev/null +++ b/tests/v2/cassettes/test_scenarios/test_list_scanned_assets_metadata_returns_not_found_asset_not_found_response.frozen @@ -0,0 +1 @@ +2025-10-15T08:41:14.545Z \ No newline at end of file diff --git a/tests/v2/cassettes/test_scenarios/test_list_scanned_assets_metadata_returns_not_found_asset_not_found_response.yaml b/tests/v2/cassettes/test_scenarios/test_list_scanned_assets_metadata_returns_not_found_asset_not_found_response.yaml new file mode 100644 index 0000000000..ab91f89046 --- /dev/null +++ b/tests/v2/cassettes/test_scenarios/test_list_scanned_assets_metadata_returns_not_found_asset_not_found_response.yaml @@ -0,0 +1,18 @@ +interactions: +- request: + body: null + headers: + accept: + - application/json + method: GET + uri: https://api.datadoghq.com/api/v2/security/scanned-assets-metadata?page%5Btoken%5D=unknown&page%5Bnumber%5D=1 + response: + body: + string: '{"errors":[{"status":"404","title":"Unexpected internal error"}]}' + headers: + content-type: + - application/vnd.api+json + status: + code: 404 + message: Not Found +version: 1 diff --git a/tests/v2/cassettes/test_scenarios/test_list_scanned_assets_metadata_returns_ok_response.frozen b/tests/v2/cassettes/test_scenarios/test_list_scanned_assets_metadata_returns_ok_response.frozen new file mode 100644 index 0000000000..98659e7188 --- /dev/null +++ b/tests/v2/cassettes/test_scenarios/test_list_scanned_assets_metadata_returns_ok_response.frozen @@ -0,0 +1 @@ +2025-10-15T08:42:14.735Z \ No newline at end of file diff --git a/tests/v2/cassettes/test_scenarios/test_list_scanned_assets_metadata_returns_ok_response.yaml b/tests/v2/cassettes/test_scenarios/test_list_scanned_assets_metadata_returns_ok_response.yaml new file mode 100644 index 0000000000..0cf343d356 --- /dev/null +++ b/tests/v2/cassettes/test_scenarios/test_list_scanned_assets_metadata_returns_ok_response.yaml @@ -0,0 +1,18 @@ +interactions: +- request: + body: null + headers: + accept: + - application/json + method: GET + uri: https://api.datadoghq.com/api/v2/security/scanned-assets-metadata + response: + body: + string: '{"data":[]}' + headers: + content-type: + - application/vnd.api+json + status: + code: 200 + message: OK +version: 1 diff --git a/tests/v2/cassettes/test_scenarios/test_list_vulnerable_assets_returns_not_found_there_is_no_request_associated_with_the_provided_token_response.frozen b/tests/v2/cassettes/test_scenarios/test_list_vulnerable_assets_returns_not_found_there_is_no_request_associated_with_the_provided_token_response.frozen index 7b1371734c..f78ea7dd7b 100644 --- a/tests/v2/cassettes/test_scenarios/test_list_vulnerable_assets_returns_not_found_there_is_no_request_associated_with_the_provided_token_response.frozen +++ b/tests/v2/cassettes/test_scenarios/test_list_vulnerable_assets_returns_not_found_there_is_no_request_associated_with_the_provided_token_response.frozen @@ -1 +1 @@ -2025-01-31T12:04:52.159Z \ No newline at end of file +2025-10-14T13:43:32.350Z \ No newline at end of file diff --git a/tests/v2/cassettes/test_scenarios/test_list_vulnerable_assets_returns_not_found_there_is_no_request_associated_with_the_provided_token_response.yaml b/tests/v2/cassettes/test_scenarios/test_list_vulnerable_assets_returns_not_found_there_is_no_request_associated_with_the_provided_token_response.yaml index d19a47a7c9..01de923270 100644 --- a/tests/v2/cassettes/test_scenarios/test_list_vulnerable_assets_returns_not_found_there_is_no_request_associated_with_the_provided_token_response.yaml +++ b/tests/v2/cassettes/test_scenarios/test_list_vulnerable_assets_returns_not_found_there_is_no_request_associated_with_the_provided_token_response.yaml @@ -5,11 +5,10 @@ interactions: accept: - application/json method: GET - uri: https://api.datadoghq.com/api/v2/security/assets?page%5Btoken%5D=unknown&page%5Bnumber%5D=1 + uri: https://api.datadoghq.com/api/v2/security/vulnerable-assets?page%5Btoken%5D=unknown&page%5Bnumber%5D=1 response: body: - string: '{"errors":[{"title":"Generic Error","detail":"rpc error: code = Internal - desc = no cached result set found for queryID: unknown"}]}' + string: '{"errors":[{"status":"404","title":"Unexpected internal error"}]}' headers: content-type: - application/vnd.api+json diff --git a/tests/v2/cassettes/test_scenarios/test_list_vulnerable_assets_returns_ok_response.frozen b/tests/v2/cassettes/test_scenarios/test_list_vulnerable_assets_returns_ok_response.frozen index 2131f54a8a..ecb5cae4f9 100644 --- a/tests/v2/cassettes/test_scenarios/test_list_vulnerable_assets_returns_ok_response.frozen +++ b/tests/v2/cassettes/test_scenarios/test_list_vulnerable_assets_returns_ok_response.frozen @@ -1 +1 @@ -2025-01-31T12:05:04.773Z \ No newline at end of file +2025-10-14T13:43:52.800Z \ No newline at end of file diff --git a/tests/v2/cassettes/test_scenarios/test_list_vulnerable_assets_returns_ok_response.yaml b/tests/v2/cassettes/test_scenarios/test_list_vulnerable_assets_returns_ok_response.yaml index fe78206920..ea14abc28b 100644 --- a/tests/v2/cassettes/test_scenarios/test_list_vulnerable_assets_returns_ok_response.yaml +++ b/tests/v2/cassettes/test_scenarios/test_list_vulnerable_assets_returns_ok_response.yaml @@ -5,7 +5,7 @@ interactions: accept: - application/json method: GET - uri: https://api.datadoghq.com/api/v2/security/assets?filter%5Btype%5D=Host&filter%5Brepository_url%5D=github.com%2Fdatadog%2Fdd-go&filter%5Brisks.in_production%5D=true + uri: https://api.datadoghq.com/api/v2/security/vulnerable-assets?filter%5Btype%5D=Host&filter%5Brepository_url%5D=github.com%2Fdatadog%2Fdd-go&filter%5Brisks.in_production%5D=true response: body: string: '{"data":[]}' diff --git a/tests/v2/features/security_monitoring.feature b/tests/v2/features/security_monitoring.feature index c83348e689..8e5e22baad 100644 --- a/tests/v2/features/security_monitoring.feature +++ b/tests/v2/features/security_monitoring.feature @@ -1065,6 +1065,29 @@ Feature: Security Monitoring When the request is sent Then the response status is 200 OK + @skip @team:DataDog/asm-vm + Scenario: List scanned assets metadata returns "Bad request: The server cannot process the request due to invalid syntax in the request." response + Given operation "ListScannedAssetsMetadata" enabled + And new "ListScannedAssetsMetadata" request + When the request is sent + Then the response status is 400 Bad request: The server cannot process the request due to invalid syntax in the request. + + @team:DataDog/asm-vm + Scenario: List scanned assets metadata returns "Not found: asset not found" response + Given operation "ListScannedAssetsMetadata" enabled + And new "ListScannedAssetsMetadata" request + And request contains "page[token]" parameter with value "unknown" + And request contains "page[number]" parameter with value 1 + When the request is sent + Then the response status is 404 Not found: asset not found + + @team:DataDog/asm-vm + Scenario: List scanned assets metadata returns "OK" response + Given operation "ListScannedAssetsMetadata" enabled + And new "ListScannedAssetsMetadata" request + When the request is sent + Then the response status is 200 OK + @generated @skip @team:DataDog/asm-vm Scenario: List vulnerabilities returns "Bad request: The server cannot process the request due to invalid syntax in the request." response Given operation "ListVulnerabilities" enabled diff --git a/tests/v2/features/undo.json b/tests/v2/features/undo.json index 76bc60f80e..6e05ad8acd 100644 --- a/tests/v2/features/undo.json +++ b/tests/v2/features/undo.json @@ -3223,12 +3223,6 @@ "type": "idempotent" } }, - "ListVulnerableAssets": { - "tag": "Security Monitoring", - "undo": { - "type": "safe" - } - }, "DownloadCloudWorkloadPolicyFile": { "tag": "CSM Threats", "undo": { @@ -3247,6 +3241,12 @@ "type": "safe" } }, + "ListScannedAssetsMetadata": { + "tag": "Security Monitoring", + "undo": { + "type": "safe" + } + }, "GetSignalNotificationRules": { "tag": "Security Monitoring", "undo": { @@ -3327,6 +3327,12 @@ "type": "idempotent" } }, + "ListVulnerableAssets": { + "tag": "Security Monitoring", + "undo": { + "type": "safe" + } + }, "ListCloudWorkloadSecurityAgentRules": { "tag": "CSM Threats", "undo": {