diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index dbd876c34d..b0a2f61cc8 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -136453,6 +136453,252 @@ components: description: Pagination type. One of `offset_limit` or `number_size`. type: string type: object + TemporaryGrantRequestAttributes: + description: Request history and the linked grant state. List and detail reads include grant_state for approved requests. Decision responses record the decision. Read the request for current grant state. + properties: + created_at: + description: When the request was submitted. + example: "2028-02-16T00:00:00Z" + format: date-time + type: string + decided_at: + description: When the decision or cancellation was recorded. + example: "2028-02-16T00:00:00Z" + format: date-time + type: string + decided_by_user_id: + description: UUID of the reviewer, or of the requester if the request was canceled. + example: 12345678-1234-1234-1234-123456789012 + format: uuid + type: string + entity_key: + description: The requester identity resolved by the server. + example: user_handle:jane@example.com + type: string + expires_at: + description: Immutable exclusive expiry, normalized to UTC microsecond precision. + example: "2028-02-16T00:00:00Z" + format: date-time + type: string + grant_state: + $ref: "#/components/schemas/TemporaryGrantRequestGrantState" + justification: + description: Reason for requesting temporary credits. Trimmed and limited to 4096 UTF-8 bytes. + example: Credits needed to finish the incident investigation. + maxLength: 4096 + minLength: 1 + type: string + quota_namespace: + description: The quota namespace. Only AI credits are supported. + example: ai_credits + type: string + requested_by_user_id: + description: UUID of the authenticated requester. + example: 12345678-1234-1234-1234-123456789012 + format: uuid + type: string + status: + $ref: "#/components/schemas/TemporaryGrantRequestStatus" + total: + description: Target monthly AI credit limit in positive whole credits, not additional credits. Fractional credits are not accepted. + example: 200 + format: int64 + maximum: 9223372036854 + minimum: 1 + type: integer + required: + - quota_namespace + - entity_key + - requested_by_user_id + - total + - justification + - expires_at + - status + - created_at + type: object + TemporaryGrantRequestCreateAttributes: + additionalProperties: false + description: Immutable terms and justification for a temporary grant request. + properties: + expires_at: + description: Exclusive expiry. Must be a future timestamp with a timezone. Date-only values are rejected. If omitted or null, defaults to the next UTC month boundary. Approval accepts this deadline unchanged. + example: "2028-02-16T00:00:00Z" + format: date-time + nullable: true + type: string + justification: + description: Reason for requesting temporary credits. Trimmed and limited to 4096 UTF-8 bytes. + example: Credits needed to finish the incident investigation. + maxLength: 4096 + minLength: 1 + type: string + total: + description: Target monthly AI credit limit in positive whole credits, not additional credits. Fractional credits are not accepted. + example: 200 + format: int64 + maximum: 9223372036854 + minimum: 1 + type: integer + required: + - total + - justification + type: object + TemporaryGrantRequestCreateData: + description: The request resource to create. The server generates its ID. + properties: + attributes: + $ref: "#/components/schemas/TemporaryGrantRequestCreateAttributes" + type: + $ref: "#/components/schemas/TemporaryGrantRequestType" + required: + - type + - attributes + type: object + TemporaryGrantRequestCreateRequest: + description: Create a request for the authenticated human user. + properties: + data: + $ref: "#/components/schemas/TemporaryGrantRequestCreateData" + required: + - data + type: object + TemporaryGrantRequestData: + description: A temporary grant request resource. + properties: + attributes: + $ref: "#/components/schemas/TemporaryGrantRequestAttributes" + id: + description: Server-generated request UUID. + example: 12345678-1234-1234-1234-123456789012 + format: uuid + type: string + type: + $ref: "#/components/schemas/TemporaryGrantRequestType" + required: + - id + - type + - attributes + type: object + TemporaryGrantRequestDecision: + description: Approve the exact submitted total and expiry, or deny the request. + enum: + - approved + - denied + example: approved + type: string + x-enum-varnames: + - APPROVED + - DENIED + TemporaryGrantRequestDecisionAttributes: + additionalProperties: false + description: Binary decision. Overrides, reason fields, and unknown attributes are rejected, including null values. + properties: + decision: + $ref: "#/components/schemas/TemporaryGrantRequestDecision" + required: + - decision + type: object + TemporaryGrantRequestDecisionData: + description: A decision on a pending request. + properties: + attributes: + $ref: "#/components/schemas/TemporaryGrantRequestDecisionAttributes" + id: + description: Request UUID. Must match request_id in the path. Missing or mismatched IDs return 400 Bad Request. + example: 12345678-1234-1234-1234-123456789012 + format: uuid + type: string + type: + $ref: "#/components/schemas/TemporaryGrantRequestType" + required: + - id + - type + - attributes + type: object + TemporaryGrantRequestDecisionRequest: + description: Approve or deny a pending request. + properties: + data: + $ref: "#/components/schemas/TemporaryGrantRequestDecisionData" + required: + - data + type: object + TemporaryGrantRequestGrantState: + description: Current state of the grant associated with an approved request. Replaced means a newer grant superseded this grant. The newer grant might no longer be active. This field is absent for requests that weren't approved. + enum: + - active + - expired + - revoked + - replaced + example: active + type: string + x-enum-varnames: + - ACTIVE + - EXPIRED + - REVOKED + - REPLACED + TemporaryGrantRequestListMeta: + description: Pagination metadata. + properties: + page: + $ref: "#/components/schemas/TemporaryGrantRequestPage" + required: + - page + type: object + TemporaryGrantRequestListResponse: + description: A page of temporary grant requests, ordered by UUID rather than creation time. + properties: + data: + description: Requests visible to the authenticated caller. + items: + $ref: "#/components/schemas/TemporaryGrantRequestData" + type: array + meta: + $ref: "#/components/schemas/TemporaryGrantRequestListMeta" + required: + - data + - meta + type: object + TemporaryGrantRequestPage: + description: UUID cursor pagination. A full final page can return a cursor followed by an empty page. + properties: + next_cursor: + description: Use this UUID as page[cursor] to retrieve the next page. Omitted when the page is not full. + example: 12345678-1234-1234-1234-123456789012 + format: uuid + type: string + type: object + TemporaryGrantRequestResponse: + description: A single temporary grant request. + properties: + data: + $ref: "#/components/schemas/TemporaryGrantRequestData" + required: + - data + type: object + TemporaryGrantRequestStatus: + description: The durable request decision, independent of whether its grant is still active. + enum: + - pending + - approved + - denied + - cancelled + example: pending + type: string + x-enum-varnames: + - PENDING + - APPROVED + - DENIED + - CANCELLED + TemporaryGrantRequestType: + default: temporary_grant_requests + description: The temporary grant request resource type. + enum: + - temporary_grant_requests + example: temporary_grant_requests + type: string + x-enum-varnames: + - TEMPORARY_GRANT_REQUESTS TenancyConfig: description: Response containing a single OCI tenancy integration configuration. example: @@ -252119,6 +252365,363 @@ paths: x-unstable: |- **Note**: This endpoint is in preview and is subject to change. If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). + /api/v2/usage/admin/temporary-grant-requests: + get: + description: List all request statuses within the authenticated organization. Filter by pending status for the review queue. Requires Billing Edit, including for reads. Requires an authenticated human user. Service-account credentials are unsupported. Request status remains approved after expiry, revocation, or replacement. + operationId: ListTemporaryGrantRequests + parameters: + - description: Optional status. Defaults to all statuses. + in: query + name: filter[status] + required: false + schema: + $ref: "#/components/schemas/TemporaryGrantRequestStatus" + - description: Page size, from 1 to 100. + in: query + name: page[limit] + required: false + schema: + default: 50 + format: int64 + maximum: 100 + minimum: 1 + type: integer + - description: UUID cursor from meta.page.next_cursor. + in: query + name: page[cursor] + required: false + schema: + format: uuid + type: string + - description: Filter by requester UUID within the authenticated organization. + in: query + name: filter[requested_by_user_id] + required: false + schema: + format: uuid + type: string + responses: + "200": + content: + application/json: + examples: + default: + value: + data: + - attributes: + created_at: "2028-02-16T00:00:00Z" + entity_key: user_handle:jane@example.com + expires_at: "2028-03-01T00:00:00Z" + justification: Credits needed to finish the incident investigation. + quota_namespace: ai_credits + requested_by_user_id: 12345678-1234-1234-1234-123456789012 + status: pending + total: 200 + id: 34567890-3456-3456-3456-345678901234 + type: temporary_grant_requests + meta: + page: {} + schema: + $ref: "#/components/schemas/TemporaryGrantRequestListResponse" + description: OK + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Bad Request + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Unauthorized + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Forbidden + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Not Found + "409": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Conflict + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - billing_edit + summary: List organization temporary grant requests + tags: + - Usage Metering + x-pagination: + cursorParam: page[cursor] + cursorPath: meta.page.next_cursor + limitParam: page[limit] + resultsPath: data + x-permission: + operator: OR + permissions: + - billing_edit + x-unstable: |- + **Note**: This endpoint is in preview and is subject to change. + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). + /api/v2/usage/admin/temporary-grant-requests/{request_id}: + get: + description: Read an organization request, justification, decision, and linked grant state. Requires Billing Edit. Requires an authenticated human user. Service-account credentials are unsupported. Request status remains approved after expiry, revocation, or replacement. + operationId: GetTemporaryGrantRequest + parameters: + - description: The temporary grant request UUID. + in: path + name: request_id + required: true + schema: + description: The request UUID. + example: 12345678-1234-1234-1234-123456789012 + format: uuid + type: string + responses: + "200": + content: + application/json: + examples: + default: + value: + data: + attributes: + created_at: "2028-02-16T00:00:00Z" + entity_key: user_handle:jane@example.com + expires_at: "2028-03-01T00:00:00Z" + justification: Credits needed to finish the incident investigation. + quota_namespace: ai_credits + requested_by_user_id: 12345678-1234-1234-1234-123456789012 + status: pending + total: 200 + id: 34567890-3456-3456-3456-345678901234 + type: temporary_grant_requests + schema: + $ref: "#/components/schemas/TemporaryGrantRequestResponse" + description: OK + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Bad Request + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Unauthorized + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Forbidden + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Not Found + "409": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Conflict + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - billing_edit + summary: Get an organization temporary grant request + tags: + - Usage Metering + x-permission: + operator: OR + permissions: + - billing_edit + x-unstable: |- + **Note**: This endpoint is in preview and is subject to change. + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). + /api/v2/usage/admin/temporary-grant-requests/{request_id}/decision: + post: + description: Approve or deny the submitted terms, which are immutable. Approval atomically writes the grant, audit record, and request decision. An expired request can't be approved. Requires the Billing Edit permission. Requires an authenticated human user. Service-account credentials aren't supported. Request status remains approved after the grant's expiry, revocation, or replacement. + operationId: UpdateTemporaryGrantRequest + parameters: + - description: The temporary grant request UUID. + in: path + name: request_id + required: true + schema: + description: The request UUID. + example: 12345678-1234-1234-1234-123456789012 + format: uuid + type: string + requestBody: + content: + application/json: + examples: + default: + value: + data: + attributes: + decision: approved + id: 12345678-1234-1234-1234-123456789012 + type: temporary_grant_requests + schema: + $ref: "#/components/schemas/TemporaryGrantRequestDecisionRequest" + required: true + responses: + "200": + content: + application/json: + examples: + default: + value: + data: + attributes: + created_at: "2028-02-16T00:00:00Z" + decided_at: "2028-02-16T01:00:00Z" + decided_by_user_id: 23456789-2345-2345-2345-234567890123 + entity_key: user_handle:jane@example.com + expires_at: "2028-03-01T00:00:00Z" + justification: Credits needed to finish the incident investigation. + quota_namespace: ai_credits + requested_by_user_id: 12345678-1234-1234-1234-123456789012 + status: approved + total: 200 + id: 34567890-3456-3456-3456-345678901234 + type: temporary_grant_requests + schema: + $ref: "#/components/schemas/TemporaryGrantRequestResponse" + description: OK + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Bad Request + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Unauthorized + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Forbidden + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Not Found + "409": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Conflict + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - billing_edit + summary: Decide a temporary grant request + tags: + - Usage Metering + x-permission: + operator: OR + permissions: + - billing_edit + x-unstable: |- + **Note**: This endpoint is in preview and is subject to change. + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). + /api/v2/usage/admin/temporary-grant-requests/{request_id}/grant: + delete: + description: Revoke only the grant that's still associated with this approved request. The request and audit history remain. A stale request can't revoke a replacement grant. Requires the Billing Edit permission. Requires an authenticated human user. Service-account credentials aren't supported. Request status remains approved after the grant's expiry, revocation, or replacement. + operationId: DeleteRequestedTemporaryGrant + parameters: + - description: The temporary grant request UUID. + in: path + name: request_id + required: true + schema: + description: The request UUID. + example: 12345678-1234-1234-1234-123456789012 + format: uuid + type: string + responses: + "204": + description: No Content + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Bad Request + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Unauthorized + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Forbidden + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Not Found + "409": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Conflict + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - billing_edit + summary: Revoke a requested temporary grant + tags: + - Usage Metering + x-permission: + operator: OR + permissions: + - billing_edit + x-unstable: |- + **Note**: This endpoint is in preview and is subject to change. + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). /api/v2/usage/application_security: get: deprecated: true @@ -253326,6 +253929,403 @@ paths: operator: OR permissions: - usage_read + /api/v2/usage/temporary-grant-requests: + get: + description: List the authenticated user's own requests, including decided requests. Other users' requests are never included. Requires an authenticated human user. Service-account credentials aren't supported. Request status remains approved after the grant's expiry, revocation, or replacement. + operationId: ListMyTemporaryGrantRequests + parameters: + - description: Optional status. Defaults to all statuses. + in: query + name: filter[status] + required: false + schema: + $ref: "#/components/schemas/TemporaryGrantRequestStatus" + - description: Page size, from 1 to 100. + in: query + name: page[limit] + required: false + schema: + default: 50 + format: int64 + maximum: 100 + minimum: 1 + type: integer + - description: UUID cursor from meta.page.next_cursor. + in: query + name: page[cursor] + required: false + schema: + format: uuid + type: string + responses: + "200": + content: + application/json: + examples: + default: + value: + data: + - attributes: + created_at: "2028-02-16T00:00:00Z" + entity_key: user_handle:jane@example.com + expires_at: "2028-03-01T00:00:00Z" + justification: Credits needed to finish the incident investigation. + quota_namespace: ai_credits + requested_by_user_id: 12345678-1234-1234-1234-123456789012 + status: pending + total: 200 + id: 34567890-3456-3456-3456-345678901234 + type: temporary_grant_requests + meta: + page: {} + schema: + $ref: "#/components/schemas/TemporaryGrantRequestListResponse" + description: OK + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Bad Request + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Unauthorized + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Forbidden + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Not Found + "409": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Conflict + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - assistant_access + - AuthZ: + - bits_dev_write + - AuthZ: + - bits_investigations_write + - AuthZ: + - bits_security_analyst_write + - AuthZ: + - agent_builder_run + - AuthZ: + - billing_edit + summary: List your temporary grant requests + tags: + - Usage Metering + x-pagination: + cursorParam: page[cursor] + cursorPath: meta.page.next_cursor + limitParam: page[limit] + resultsPath: data + x-permission: + operator: OR + permissions: + - assistant_access + - bits_dev_write + - bits_investigations_write + - bits_security_analyst_write + - agent_builder_run + - billing_edit + x-unstable: |- + **Note**: This endpoint is in preview and is subject to change. + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). + post: + description: Request a temporary increase to your monthly AI credit limit. Set `total` to the new monthly limit you need, in whole credits, not the number of credits to add. Include a justification and, optionally, an expiry. If you omit the expiry, the grant ends at the next UTC month boundary. A user with the Billing Edit permission approves or denies the request. Requires an authenticated human user. Service-account credentials are unsupported. + operationId: CreateTemporaryGrantRequest + requestBody: + content: + application/json: + examples: + default: + value: + data: + attributes: + expires_at: "2028-03-01T00:00:00Z" + justification: Credits needed to finish the incident investigation. + total: 200 + type: temporary_grant_requests + schema: + $ref: "#/components/schemas/TemporaryGrantRequestCreateRequest" + required: true + responses: + "201": + content: + application/json: + examples: + default: + value: + data: + attributes: + created_at: "2028-02-16T00:00:00Z" + entity_key: user_handle:jane@example.com + expires_at: "2028-03-01T00:00:00Z" + justification: Credits needed to finish the incident investigation. + quota_namespace: ai_credits + requested_by_user_id: 12345678-1234-1234-1234-123456789012 + status: pending + total: 200 + id: 34567890-3456-3456-3456-345678901234 + type: temporary_grant_requests + schema: + $ref: "#/components/schemas/TemporaryGrantRequestResponse" + description: Created + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Bad Request + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Unauthorized + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Forbidden + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Not Found + "409": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Conflict + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - assistant_access + - AuthZ: + - bits_dev_write + - AuthZ: + - bits_investigations_write + - AuthZ: + - bits_security_analyst_write + - AuthZ: + - agent_builder_run + - AuthZ: + - billing_edit + summary: Create a temporary grant request + tags: + - Usage Metering + x-permission: + operator: OR + permissions: + - assistant_access + - bits_dev_write + - bits_investigations_write + - bits_security_analyst_write + - agent_builder_run + - billing_edit + x-unstable: |- + **Note**: This endpoint is in preview and is subject to change. + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). + /api/v2/usage/temporary-grant-requests/{request_id}: + delete: + description: Cancel a pending request that you own. The request history is kept, and no grant is created or revoked. Requires an authenticated human user. Service-account credentials are unsupported. + operationId: DeleteTemporaryGrantRequest + parameters: + - description: The temporary grant request UUID. + in: path + name: request_id + required: true + schema: + description: The request UUID. + example: 12345678-1234-1234-1234-123456789012 + format: uuid + type: string + responses: + "204": + description: No Content + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Bad Request + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Unauthorized + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Forbidden + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Not Found + "409": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Conflict + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - assistant_access + - AuthZ: + - bits_dev_write + - AuthZ: + - bits_investigations_write + - AuthZ: + - bits_security_analyst_write + - AuthZ: + - agent_builder_run + - AuthZ: + - billing_edit + summary: Cancel your temporary grant request + tags: + - Usage Metering + x-permission: + operator: OR + permissions: + - assistant_access + - bits_dev_write + - bits_investigations_write + - bits_security_analyst_write + - agent_builder_run + - billing_edit + x-unstable: |- + **Note**: This endpoint is in preview and is subject to change. + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). + get: + description: Read an owned request, its decision, and its linked grant state. Requires an authenticated human user. Service-account credentials are unsupported. Request status remains approved after expiry, revocation, or replacement. + operationId: GetMyTemporaryGrantRequest + parameters: + - description: The temporary grant request UUID. + in: path + name: request_id + required: true + schema: + description: The request UUID. + example: 12345678-1234-1234-1234-123456789012 + format: uuid + type: string + responses: + "200": + content: + application/json: + examples: + default: + value: + data: + attributes: + created_at: "2028-02-16T00:00:00Z" + entity_key: user_handle:jane@example.com + expires_at: "2028-03-01T00:00:00Z" + justification: Credits needed to finish the incident investigation. + quota_namespace: ai_credits + requested_by_user_id: 12345678-1234-1234-1234-123456789012 + status: pending + total: 200 + id: 34567890-3456-3456-3456-345678901234 + type: temporary_grant_requests + schema: + $ref: "#/components/schemas/TemporaryGrantRequestResponse" + description: OK + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Bad Request + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Unauthorized + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Forbidden + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Not Found + "409": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Conflict + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - assistant_access + - AuthZ: + - bits_dev_write + - AuthZ: + - bits_investigations_write + - AuthZ: + - bits_security_analyst_write + - AuthZ: + - agent_builder_run + - AuthZ: + - billing_edit + summary: Get your temporary grant request + tags: + - Usage Metering + x-permission: + operator: OR + permissions: + - assistant_access + - bits_dev_write + - bits_investigations_write + - bits_security_analyst_write + - agent_builder_run + - billing_edit + x-unstable: |- + **Note**: This endpoint is in preview and is subject to change. + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). /api/v2/usage/usage-attribution-types: get: description: |- diff --git a/examples/v2/usage-metering/CreateTemporaryGrantRequest.py b/examples/v2/usage-metering/CreateTemporaryGrantRequest.py new file mode 100644 index 0000000000..92449e44fe --- /dev/null +++ b/examples/v2/usage-metering/CreateTemporaryGrantRequest.py @@ -0,0 +1,33 @@ +""" +Create a temporary grant request returns "Created" response +""" + +from os import environ +from datadog_api_client import ApiClient, Configuration +from datadog_api_client.v2.api.usage_metering_api import UsageMeteringApi +from datadog_api_client.v2.model.temporary_grant_request_create_attributes import TemporaryGrantRequestCreateAttributes +from datadog_api_client.v2.model.temporary_grant_request_create_data import TemporaryGrantRequestCreateData +from datadog_api_client.v2.model.temporary_grant_request_create_request import TemporaryGrantRequestCreateRequest +from datadog_api_client.v2.model.temporary_grant_request_type import TemporaryGrantRequestType +from datetime import datetime +from dateutil.tz import tzutc + +body = TemporaryGrantRequestCreateRequest( + data=TemporaryGrantRequestCreateData( + attributes=TemporaryGrantRequestCreateAttributes( + expires_at=datetime(2028, 2, 16, 0, 0, tzinfo=tzutc()), + justification="Credits needed to finish the incident investigation.", + total=200, + ), + type=TemporaryGrantRequestType.TEMPORARY_GRANT_REQUESTS, + ), +) + +configuration = Configuration() +configuration.access_token = environ["DD_BEARER_TOKEN"] +configuration.unstable_operations["create_temporary_grant_request"] = True +with ApiClient(configuration) as api_client: + api_instance = UsageMeteringApi(api_client) + response = api_instance.create_temporary_grant_request(body=body) + + print(response) diff --git a/examples/v2/usage-metering/DeleteRequestedTemporaryGrant.py b/examples/v2/usage-metering/DeleteRequestedTemporaryGrant.py new file mode 100644 index 0000000000..fd760df97b --- /dev/null +++ b/examples/v2/usage-metering/DeleteRequestedTemporaryGrant.py @@ -0,0 +1,17 @@ +""" +Revoke a requested temporary grant returns "No Content" response +""" + +from os import environ +from datadog_api_client import ApiClient, Configuration +from datadog_api_client.v2.api.usage_metering_api import UsageMeteringApi +from uuid import UUID + +configuration = Configuration() +configuration.access_token = environ["DD_BEARER_TOKEN"] +configuration.unstable_operations["delete_requested_temporary_grant"] = True +with ApiClient(configuration) as api_client: + api_instance = UsageMeteringApi(api_client) + api_instance.delete_requested_temporary_grant( + request_id=UUID("12345678-1234-1234-1234-123456789012"), + ) diff --git a/examples/v2/usage-metering/DeleteTemporaryGrantRequest.py b/examples/v2/usage-metering/DeleteTemporaryGrantRequest.py new file mode 100644 index 0000000000..40a389792f --- /dev/null +++ b/examples/v2/usage-metering/DeleteTemporaryGrantRequest.py @@ -0,0 +1,17 @@ +""" +Cancel your temporary grant request returns "No Content" response +""" + +from os import environ +from datadog_api_client import ApiClient, Configuration +from datadog_api_client.v2.api.usage_metering_api import UsageMeteringApi +from uuid import UUID + +configuration = Configuration() +configuration.access_token = environ["DD_BEARER_TOKEN"] +configuration.unstable_operations["delete_temporary_grant_request"] = True +with ApiClient(configuration) as api_client: + api_instance = UsageMeteringApi(api_client) + api_instance.delete_temporary_grant_request( + request_id=UUID("12345678-1234-1234-1234-123456789012"), + ) diff --git a/examples/v2/usage-metering/GetMyTemporaryGrantRequest.py b/examples/v2/usage-metering/GetMyTemporaryGrantRequest.py new file mode 100644 index 0000000000..80af83c1a5 --- /dev/null +++ b/examples/v2/usage-metering/GetMyTemporaryGrantRequest.py @@ -0,0 +1,21 @@ +""" +Get your temporary grant request returns "OK" response +""" + +from os import environ +from datadog_api_client import ApiClient, Configuration +from datadog_api_client.v2.api.usage_metering_api import UsageMeteringApi + +# there is a valid "temporary_grant_request" in the system +TEMPORARY_GRANT_REQUEST_DATA_ID = environ["TEMPORARY_GRANT_REQUEST_DATA_ID"] + +configuration = Configuration() +configuration.access_token = environ["DD_BEARER_TOKEN"] +configuration.unstable_operations["get_my_temporary_grant_request"] = True +with ApiClient(configuration) as api_client: + api_instance = UsageMeteringApi(api_client) + response = api_instance.get_my_temporary_grant_request( + request_id=TEMPORARY_GRANT_REQUEST_DATA_ID, + ) + + print(response) diff --git a/examples/v2/usage-metering/GetTemporaryGrantRequest.py b/examples/v2/usage-metering/GetTemporaryGrantRequest.py new file mode 100644 index 0000000000..f3c4c5b376 --- /dev/null +++ b/examples/v2/usage-metering/GetTemporaryGrantRequest.py @@ -0,0 +1,21 @@ +""" +Get an organization temporary grant request returns "OK" response +""" + +from os import environ +from datadog_api_client import ApiClient, Configuration +from datadog_api_client.v2.api.usage_metering_api import UsageMeteringApi + +# there is a valid "temporary_grant_request" in the system +TEMPORARY_GRANT_REQUEST_DATA_ID = environ["TEMPORARY_GRANT_REQUEST_DATA_ID"] + +configuration = Configuration() +configuration.access_token = environ["DD_BEARER_TOKEN"] +configuration.unstable_operations["get_temporary_grant_request"] = True +with ApiClient(configuration) as api_client: + api_instance = UsageMeteringApi(api_client) + response = api_instance.get_temporary_grant_request( + request_id=TEMPORARY_GRANT_REQUEST_DATA_ID, + ) + + print(response) diff --git a/examples/v2/usage-metering/ListMyTemporaryGrantRequests.py b/examples/v2/usage-metering/ListMyTemporaryGrantRequests.py new file mode 100644 index 0000000000..87093cb221 --- /dev/null +++ b/examples/v2/usage-metering/ListMyTemporaryGrantRequests.py @@ -0,0 +1,16 @@ +""" +List your temporary grant requests returns "OK" response +""" + +from os import environ +from datadog_api_client import ApiClient, Configuration +from datadog_api_client.v2.api.usage_metering_api import UsageMeteringApi + +configuration = Configuration() +configuration.access_token = environ["DD_BEARER_TOKEN"] +configuration.unstable_operations["list_my_temporary_grant_requests"] = True +with ApiClient(configuration) as api_client: + api_instance = UsageMeteringApi(api_client) + response = api_instance.list_my_temporary_grant_requests() + + print(response) diff --git a/examples/v2/usage-metering/ListMyTemporaryGrantRequests_3885243213.py b/examples/v2/usage-metering/ListMyTemporaryGrantRequests_3885243213.py new file mode 100644 index 0000000000..396df27ff1 --- /dev/null +++ b/examples/v2/usage-metering/ListMyTemporaryGrantRequests_3885243213.py @@ -0,0 +1,16 @@ +""" +List your temporary grant requests returns "OK" response with pagination +""" + +from os import environ +from datadog_api_client import ApiClient, Configuration +from datadog_api_client.v2.api.usage_metering_api import UsageMeteringApi + +configuration = Configuration() +configuration.access_token = environ["DD_BEARER_TOKEN"] +configuration.unstable_operations["list_my_temporary_grant_requests"] = True +with ApiClient(configuration) as api_client: + api_instance = UsageMeteringApi(api_client) + items = api_instance.list_my_temporary_grant_requests_with_pagination() + for item in items: + print(item) diff --git a/examples/v2/usage-metering/ListTemporaryGrantRequests.py b/examples/v2/usage-metering/ListTemporaryGrantRequests.py new file mode 100644 index 0000000000..65282ae079 --- /dev/null +++ b/examples/v2/usage-metering/ListTemporaryGrantRequests.py @@ -0,0 +1,16 @@ +""" +List organization temporary grant requests returns "OK" response +""" + +from os import environ +from datadog_api_client import ApiClient, Configuration +from datadog_api_client.v2.api.usage_metering_api import UsageMeteringApi + +configuration = Configuration() +configuration.access_token = environ["DD_BEARER_TOKEN"] +configuration.unstable_operations["list_temporary_grant_requests"] = True +with ApiClient(configuration) as api_client: + api_instance = UsageMeteringApi(api_client) + response = api_instance.list_temporary_grant_requests() + + print(response) diff --git a/examples/v2/usage-metering/ListTemporaryGrantRequests_3760725651.py b/examples/v2/usage-metering/ListTemporaryGrantRequests_3760725651.py new file mode 100644 index 0000000000..234f6cb6e3 --- /dev/null +++ b/examples/v2/usage-metering/ListTemporaryGrantRequests_3760725651.py @@ -0,0 +1,16 @@ +""" +List organization temporary grant requests returns "OK" response with pagination +""" + +from os import environ +from datadog_api_client import ApiClient, Configuration +from datadog_api_client.v2.api.usage_metering_api import UsageMeteringApi + +configuration = Configuration() +configuration.access_token = environ["DD_BEARER_TOKEN"] +configuration.unstable_operations["list_temporary_grant_requests"] = True +with ApiClient(configuration) as api_client: + api_instance = UsageMeteringApi(api_client) + items = api_instance.list_temporary_grant_requests_with_pagination() + for item in items: + print(item) diff --git a/examples/v2/usage-metering/UpdateTemporaryGrantRequest.py b/examples/v2/usage-metering/UpdateTemporaryGrantRequest.py new file mode 100644 index 0000000000..7b18064a0a --- /dev/null +++ b/examples/v2/usage-metering/UpdateTemporaryGrantRequest.py @@ -0,0 +1,36 @@ +""" +Decide a temporary grant request returns "OK" response +""" + +from os import environ +from datadog_api_client import ApiClient, Configuration +from datadog_api_client.v2.api.usage_metering_api import UsageMeteringApi +from datadog_api_client.v2.model.temporary_grant_request_decision import TemporaryGrantRequestDecision +from datadog_api_client.v2.model.temporary_grant_request_decision_attributes import ( + TemporaryGrantRequestDecisionAttributes, +) +from datadog_api_client.v2.model.temporary_grant_request_decision_data import TemporaryGrantRequestDecisionData +from datadog_api_client.v2.model.temporary_grant_request_decision_request import TemporaryGrantRequestDecisionRequest +from datadog_api_client.v2.model.temporary_grant_request_type import TemporaryGrantRequestType + +# there is a valid "temporary_grant_request" in the system +TEMPORARY_GRANT_REQUEST_DATA_ID = environ["TEMPORARY_GRANT_REQUEST_DATA_ID"] + +body = TemporaryGrantRequestDecisionRequest( + data=TemporaryGrantRequestDecisionData( + attributes=TemporaryGrantRequestDecisionAttributes( + decision=TemporaryGrantRequestDecision.DENIED, + ), + id=TEMPORARY_GRANT_REQUEST_DATA_ID, + type=TemporaryGrantRequestType.TEMPORARY_GRANT_REQUESTS, + ), +) + +configuration = Configuration() +configuration.access_token = environ["DD_BEARER_TOKEN"] +configuration.unstable_operations["update_temporary_grant_request"] = True +with ApiClient(configuration) as api_client: + api_instance = UsageMeteringApi(api_client) + response = api_instance.update_temporary_grant_request(request_id=TEMPORARY_GRANT_REQUEST_DATA_ID, body=body) + + print(response) diff --git a/src/datadog_api_client/configuration.py b/src/datadog_api_client/configuration.py index 29f69e0e9d..78f82fb84a 100644 --- a/src/datadog_api_client/configuration.py +++ b/src/datadog_api_client/configuration.py @@ -493,10 +493,18 @@ def __init__( "v2.search_cost_recommendations": False, "v2.update_unit_cost": False, "v2.create_quotas": False, + "v2.create_temporary_grant_request": False, "v2.delete_pending_quota": False, "v2.delete_quota": False, + "v2.delete_requested_temporary_grant": False, + "v2.delete_temporary_grant_request": False, + "v2.get_my_temporary_grant_request": False, + "v2.get_temporary_grant_request": False, + "v2.list_my_temporary_grant_requests": False, "v2.list_quotas": False, + "v2.list_temporary_grant_requests": False, "v2.update_quota": False, + "v2.update_temporary_grant_request": False, "v2.create_ownership_feedback": False, "v2.get_ownership_evidence": False, "v2.get_ownership_inference": False, diff --git a/src/datadog_api_client/v2/api/usage_metering_api.py b/src/datadog_api_client/v2/api/usage_metering_api.py index 2fc21f8f08..5f29e6ce04 100644 --- a/src/datadog_api_client/v2/api/usage_metering_api.py +++ b/src/datadog_api_client/v2/api/usage_metering_api.py @@ -15,10 +15,16 @@ get_attribute_from_path, UnsetType, unset, + UUID, ) from datadog_api_client.v2.model.active_billing_dimensions_response import ActiveBillingDimensionsResponse from datadog_api_client.v2.model.monthly_cost_attribution_response import MonthlyCostAttributionResponse from datadog_api_client.v2.model.sort_direction import SortDirection +from datadog_api_client.v2.model.temporary_grant_request_list_response import TemporaryGrantRequestListResponse +from datadog_api_client.v2.model.temporary_grant_request_status import TemporaryGrantRequestStatus +from datadog_api_client.v2.model.temporary_grant_request_data import TemporaryGrantRequestData +from datadog_api_client.v2.model.temporary_grant_request_response import TemporaryGrantRequestResponse +from datadog_api_client.v2.model.temporary_grant_request_decision_request import TemporaryGrantRequestDecisionRequest from datadog_api_client.v2.model.usage_application_security_monitoring_response import ( UsageApplicationSecurityMonitoringResponse, ) @@ -36,6 +42,7 @@ from datadog_api_client.v2.model.usage_quota_response import UsageQuotaResponse from datadog_api_client.v2.model.usage_quota_update_request import UsageQuotaUpdateRequest from datadog_api_client.v2.model.usage_summary_available_fields_response import UsageSummaryAvailableFieldsResponse +from datadog_api_client.v2.model.temporary_grant_request_create_request import TemporaryGrantRequestCreateRequest from datadog_api_client.v2.model.usage_attribution_types_response import UsageAttributionTypesResponse @@ -89,6 +96,26 @@ def __init__(self, api_client=None): api_client=api_client, ) + self._create_temporary_grant_request_endpoint = _Endpoint( + settings={ + "response_type": (TemporaryGrantRequestResponse,), + "auth": ["apiKeyAuth", "appKeyAuth", "AuthZ"], + "endpoint_path": "/api/v2/usage/temporary-grant-requests", + "operation_id": "create_temporary_grant_request", + "http_method": "POST", + "version": "v2", + }, + params_map={ + "body": { + "required": True, + "openapi_types": (TemporaryGrantRequestCreateRequest,), + "location": "body", + }, + }, + headers_map={"accept": ["application/json"], "content_type": ["application/json"]}, + api_client=api_client, + ) + self._delete_pending_quota_endpoint = _Endpoint( settings={ "response_type": None, @@ -147,6 +174,52 @@ def __init__(self, api_client=None): api_client=api_client, ) + self._delete_requested_temporary_grant_endpoint = _Endpoint( + settings={ + "response_type": None, + "auth": ["apiKeyAuth", "appKeyAuth", "AuthZ"], + "endpoint_path": "/api/v2/usage/admin/temporary-grant-requests/{request_id}/grant", + "operation_id": "delete_requested_temporary_grant", + "http_method": "DELETE", + "version": "v2", + }, + params_map={ + "request_id": { + "required": True, + "openapi_types": (UUID,), + "attribute": "request_id", + "location": "path", + }, + }, + headers_map={ + "accept": ["*/*"], + }, + api_client=api_client, + ) + + self._delete_temporary_grant_request_endpoint = _Endpoint( + settings={ + "response_type": None, + "auth": ["apiKeyAuth", "appKeyAuth", "AuthZ"], + "endpoint_path": "/api/v2/usage/temporary-grant-requests/{request_id}", + "operation_id": "delete_temporary_grant_request", + "http_method": "DELETE", + "version": "v2", + }, + params_map={ + "request_id": { + "required": True, + "openapi_types": (UUID,), + "attribute": "request_id", + "location": "path", + }, + }, + headers_map={ + "accept": ["*/*"], + }, + api_client=api_client, + ) + self._get_active_billing_dimensions_endpoint = _Endpoint( settings={ "response_type": (ActiveBillingDimensionsResponse,), @@ -435,6 +508,29 @@ def __init__(self, api_client=None): api_client=api_client, ) + self._get_my_temporary_grant_request_endpoint = _Endpoint( + settings={ + "response_type": (TemporaryGrantRequestResponse,), + "auth": ["apiKeyAuth", "appKeyAuth", "AuthZ"], + "endpoint_path": "/api/v2/usage/temporary-grant-requests/{request_id}", + "operation_id": "get_my_temporary_grant_request", + "http_method": "GET", + "version": "v2", + }, + params_map={ + "request_id": { + "required": True, + "openapi_types": (UUID,), + "attribute": "request_id", + "location": "path", + }, + }, + headers_map={ + "accept": ["application/json"], + }, + api_client=api_client, + ) + self._get_projected_cost_endpoint = _Endpoint( settings={ "response_type": (ProjectedCostResponse,), @@ -462,6 +558,29 @@ def __init__(self, api_client=None): api_client=api_client, ) + self._get_temporary_grant_request_endpoint = _Endpoint( + settings={ + "response_type": (TemporaryGrantRequestResponse,), + "auth": ["apiKeyAuth", "appKeyAuth", "AuthZ"], + "endpoint_path": "/api/v2/usage/admin/temporary-grant-requests/{request_id}", + "operation_id": "get_temporary_grant_request", + "http_method": "GET", + "version": "v2", + }, + params_map={ + "request_id": { + "required": True, + "openapi_types": (UUID,), + "attribute": "request_id", + "location": "path", + }, + }, + headers_map={ + "accept": ["application/json"], + }, + api_client=api_client, + ) + self._get_usage_application_security_monitoring_endpoint = _Endpoint( settings={ "response_type": (UsageApplicationSecurityMonitoringResponse,), @@ -578,6 +697,42 @@ def __init__(self, api_client=None): api_client=api_client, ) + self._list_my_temporary_grant_requests_endpoint = _Endpoint( + settings={ + "response_type": (TemporaryGrantRequestListResponse,), + "auth": ["apiKeyAuth", "appKeyAuth", "AuthZ"], + "endpoint_path": "/api/v2/usage/temporary-grant-requests", + "operation_id": "list_my_temporary_grant_requests", + "http_method": "GET", + "version": "v2", + }, + params_map={ + "filter_status": { + "openapi_types": (TemporaryGrantRequestStatus,), + "attribute": "filter[status]", + "location": "query", + }, + "page_limit": { + "validation": { + "inclusive_maximum": 100, + "inclusive_minimum": 1, + }, + "openapi_types": (int,), + "attribute": "page[limit]", + "location": "query", + }, + "page_cursor": { + "openapi_types": (UUID,), + "attribute": "page[cursor]", + "location": "query", + }, + }, + headers_map={ + "accept": ["application/json"], + }, + api_client=api_client, + ) + self._list_quotas_endpoint = _Endpoint( settings={ "response_type": (UsageQuotasListResponse,), @@ -620,6 +775,47 @@ def __init__(self, api_client=None): api_client=api_client, ) + self._list_temporary_grant_requests_endpoint = _Endpoint( + settings={ + "response_type": (TemporaryGrantRequestListResponse,), + "auth": ["apiKeyAuth", "appKeyAuth", "AuthZ"], + "endpoint_path": "/api/v2/usage/admin/temporary-grant-requests", + "operation_id": "list_temporary_grant_requests", + "http_method": "GET", + "version": "v2", + }, + params_map={ + "filter_status": { + "openapi_types": (TemporaryGrantRequestStatus,), + "attribute": "filter[status]", + "location": "query", + }, + "page_limit": { + "validation": { + "inclusive_maximum": 100, + "inclusive_minimum": 1, + }, + "openapi_types": (int,), + "attribute": "page[limit]", + "location": "query", + }, + "page_cursor": { + "openapi_types": (UUID,), + "attribute": "page[cursor]", + "location": "query", + }, + "filter_requested_by_user_id": { + "openapi_types": (UUID,), + "attribute": "filter[requested_by_user_id]", + "location": "query", + }, + }, + headers_map={ + "accept": ["application/json"], + }, + api_client=api_client, + ) + self._update_quota_endpoint = _Endpoint( settings={ "response_type": (UsageQuotaResponse,), @@ -652,6 +848,32 @@ def __init__(self, api_client=None): api_client=api_client, ) + self._update_temporary_grant_request_endpoint = _Endpoint( + settings={ + "response_type": (TemporaryGrantRequestResponse,), + "auth": ["apiKeyAuth", "appKeyAuth", "AuthZ"], + "endpoint_path": "/api/v2/usage/admin/temporary-grant-requests/{request_id}/decision", + "operation_id": "update_temporary_grant_request", + "http_method": "POST", + "version": "v2", + }, + params_map={ + "request_id": { + "required": True, + "openapi_types": (UUID,), + "attribute": "request_id", + "location": "path", + }, + "body": { + "required": True, + "openapi_types": (TemporaryGrantRequestDecisionRequest,), + "location": "body", + }, + }, + headers_map={"accept": ["application/json"], "content_type": ["application/json"]}, + api_client=api_client, + ) + def create_quotas( self, quota_namespace: str, @@ -685,6 +907,22 @@ def create_quotas( return self._create_quotas_endpoint.call_with_http_info(**kwargs) + def create_temporary_grant_request( + self, + body: TemporaryGrantRequestCreateRequest, + ) -> TemporaryGrantRequestResponse: + """Create a temporary grant request. + + Request a temporary increase to your monthly AI credit limit. Set ``total`` to the new monthly limit you need, in whole credits, not the number of credits to add. Include a justification and, optionally, an expiry. If you omit the expiry, the grant ends at the next UTC month boundary. A user with the Billing Edit permission approves or denies the request. Requires an authenticated human user. Service-account credentials are unsupported. + + :type body: TemporaryGrantRequestCreateRequest + :rtype: TemporaryGrantRequestResponse + """ + kwargs: Dict[str, Any] = {} + kwargs["body"] = body + + return self._create_temporary_grant_request_endpoint.call_with_http_info(**kwargs) + def delete_pending_quota( self, quota_namespace: str, @@ -729,6 +967,40 @@ def delete_quota( return self._delete_quota_endpoint.call_with_http_info(**kwargs) + def delete_requested_temporary_grant( + self, + request_id: UUID, + ) -> None: + """Revoke a requested temporary grant. + + Revoke only the grant that's still associated with this approved request. The request and audit history remain. A stale request can't revoke a replacement grant. Requires the Billing Edit permission. Requires an authenticated human user. Service-account credentials aren't supported. Request status remains approved after the grant's expiry, revocation, or replacement. + + :param request_id: The temporary grant request UUID. + :type request_id: UUID + :rtype: None + """ + kwargs: Dict[str, Any] = {} + kwargs["request_id"] = request_id + + return self._delete_requested_temporary_grant_endpoint.call_with_http_info(**kwargs) + + def delete_temporary_grant_request( + self, + request_id: UUID, + ) -> None: + """Cancel your temporary grant request. + + Cancel a pending request that you own. The request history is kept, and no grant is created or revoked. Requires an authenticated human user. Service-account credentials are unsupported. + + :param request_id: The temporary grant request UUID. + :type request_id: UUID + :rtype: None + """ + kwargs: Dict[str, Any] = {} + kwargs["request_id"] = request_id + + return self._delete_temporary_grant_request_endpoint.call_with_http_info(**kwargs) + def get_active_billing_dimensions( self, ) -> ActiveBillingDimensionsResponse: @@ -1056,6 +1328,23 @@ def get_monthly_cost_attribution( return self._get_monthly_cost_attribution_endpoint.call_with_http_info(**kwargs) + def get_my_temporary_grant_request( + self, + request_id: UUID, + ) -> TemporaryGrantRequestResponse: + """Get your temporary grant request. + + Read an owned request, its decision, and its linked grant state. Requires an authenticated human user. Service-account credentials are unsupported. Request status remains approved after expiry, revocation, or replacement. + + :param request_id: The temporary grant request UUID. + :type request_id: UUID + :rtype: TemporaryGrantRequestResponse + """ + kwargs: Dict[str, Any] = {} + kwargs["request_id"] = request_id + + return self._get_my_temporary_grant_request_endpoint.call_with_http_info(**kwargs) + def get_projected_cost( self, *, @@ -1084,6 +1373,23 @@ def get_projected_cost( return self._get_projected_cost_endpoint.call_with_http_info(**kwargs) + def get_temporary_grant_request( + self, + request_id: UUID, + ) -> TemporaryGrantRequestResponse: + """Get an organization temporary grant request. + + Read an organization request, justification, decision, and linked grant state. Requires Billing Edit. Requires an authenticated human user. Service-account credentials are unsupported. Request status remains approved after expiry, revocation, or replacement. + + :param request_id: The temporary grant request UUID. + :type request_id: UUID + :rtype: TemporaryGrantRequestResponse + """ + kwargs: Dict[str, Any] = {} + kwargs["request_id"] = request_id + + return self._get_temporary_grant_request_endpoint.call_with_http_info(**kwargs) + def get_usage_application_security_monitoring( self, start_hr: datetime, @@ -1226,6 +1532,81 @@ def get_usage_summary_available_fields( kwargs: Dict[str, Any] = {} return self._get_usage_summary_available_fields_endpoint.call_with_http_info(**kwargs) + def list_my_temporary_grant_requests( + self, + *, + filter_status: Union[TemporaryGrantRequestStatus, UnsetType] = unset, + page_limit: Union[int, UnsetType] = unset, + page_cursor: Union[UUID, UnsetType] = unset, + ) -> TemporaryGrantRequestListResponse: + """List your temporary grant requests. + + List the authenticated user's own requests, including decided requests. Other users' requests are never included. Requires an authenticated human user. Service-account credentials aren't supported. Request status remains approved after the grant's expiry, revocation, or replacement. + + :param filter_status: Optional status. Defaults to all statuses. + :type filter_status: TemporaryGrantRequestStatus, optional + :param page_limit: Page size, from 1 to 100. + :type page_limit: int, optional + :param page_cursor: UUID cursor from meta.page.next_cursor. + :type page_cursor: UUID, optional + :rtype: TemporaryGrantRequestListResponse + """ + kwargs: Dict[str, Any] = {} + if filter_status is not unset: + kwargs["filter_status"] = filter_status + + if page_limit is not unset: + kwargs["page_limit"] = page_limit + + if page_cursor is not unset: + kwargs["page_cursor"] = page_cursor + + return self._list_my_temporary_grant_requests_endpoint.call_with_http_info(**kwargs) + + def list_my_temporary_grant_requests_with_pagination( + self, + *, + filter_status: Union[TemporaryGrantRequestStatus, UnsetType] = unset, + page_limit: Union[int, UnsetType] = unset, + page_cursor: Union[UUID, UnsetType] = unset, + ) -> collections.abc.Iterable[TemporaryGrantRequestData]: + """List your temporary grant requests. + + Provide a paginated version of :meth:`list_my_temporary_grant_requests`, returning all items. + + :param filter_status: Optional status. Defaults to all statuses. + :type filter_status: TemporaryGrantRequestStatus, optional + :param page_limit: Page size, from 1 to 100. + :type page_limit: int, optional + :param page_cursor: UUID cursor from meta.page.next_cursor. + :type page_cursor: UUID, optional + + :return: A generator of paginated results. + :rtype: collections.abc.Iterable[TemporaryGrantRequestData] + """ + kwargs: Dict[str, Any] = {} + if filter_status is not unset: + kwargs["filter_status"] = filter_status + + if page_limit is not unset: + kwargs["page_limit"] = page_limit + + if page_cursor is not unset: + kwargs["page_cursor"] = page_cursor + + local_page_size = get_attribute_from_path(kwargs, "page_limit", 50) + endpoint = self._list_my_temporary_grant_requests_endpoint + set_attribute_from_path(kwargs, "page_limit", local_page_size, endpoint.params_map) + pagination = { + "limit_value": local_page_size, + "results_path": "data", + "cursor_param": "page_cursor", + "cursor_path": "meta.page.next_cursor", + "endpoint": endpoint, + "kwargs": kwargs, + } + return endpoint.call_with_http_info_paginated(pagination) + def list_quotas( self, quota_namespace: str, @@ -1313,6 +1694,93 @@ def list_quotas_with_pagination( } return endpoint.call_with_http_info_paginated(pagination) + def list_temporary_grant_requests( + self, + *, + filter_status: Union[TemporaryGrantRequestStatus, UnsetType] = unset, + page_limit: Union[int, UnsetType] = unset, + page_cursor: Union[UUID, UnsetType] = unset, + filter_requested_by_user_id: Union[UUID, UnsetType] = unset, + ) -> TemporaryGrantRequestListResponse: + """List organization temporary grant requests. + + List all request statuses within the authenticated organization. Filter by pending status for the review queue. Requires Billing Edit, including for reads. Requires an authenticated human user. Service-account credentials are unsupported. Request status remains approved after expiry, revocation, or replacement. + + :param filter_status: Optional status. Defaults to all statuses. + :type filter_status: TemporaryGrantRequestStatus, optional + :param page_limit: Page size, from 1 to 100. + :type page_limit: int, optional + :param page_cursor: UUID cursor from meta.page.next_cursor. + :type page_cursor: UUID, optional + :param filter_requested_by_user_id: Filter by requester UUID within the authenticated organization. + :type filter_requested_by_user_id: UUID, optional + :rtype: TemporaryGrantRequestListResponse + """ + kwargs: Dict[str, Any] = {} + if filter_status is not unset: + kwargs["filter_status"] = filter_status + + if page_limit is not unset: + kwargs["page_limit"] = page_limit + + if page_cursor is not unset: + kwargs["page_cursor"] = page_cursor + + if filter_requested_by_user_id is not unset: + kwargs["filter_requested_by_user_id"] = filter_requested_by_user_id + + return self._list_temporary_grant_requests_endpoint.call_with_http_info(**kwargs) + + def list_temporary_grant_requests_with_pagination( + self, + *, + filter_status: Union[TemporaryGrantRequestStatus, UnsetType] = unset, + page_limit: Union[int, UnsetType] = unset, + page_cursor: Union[UUID, UnsetType] = unset, + filter_requested_by_user_id: Union[UUID, UnsetType] = unset, + ) -> collections.abc.Iterable[TemporaryGrantRequestData]: + """List organization temporary grant requests. + + Provide a paginated version of :meth:`list_temporary_grant_requests`, returning all items. + + :param filter_status: Optional status. Defaults to all statuses. + :type filter_status: TemporaryGrantRequestStatus, optional + :param page_limit: Page size, from 1 to 100. + :type page_limit: int, optional + :param page_cursor: UUID cursor from meta.page.next_cursor. + :type page_cursor: UUID, optional + :param filter_requested_by_user_id: Filter by requester UUID within the authenticated organization. + :type filter_requested_by_user_id: UUID, optional + + :return: A generator of paginated results. + :rtype: collections.abc.Iterable[TemporaryGrantRequestData] + """ + kwargs: Dict[str, Any] = {} + if filter_status is not unset: + kwargs["filter_status"] = filter_status + + if page_limit is not unset: + kwargs["page_limit"] = page_limit + + if page_cursor is not unset: + kwargs["page_cursor"] = page_cursor + + if filter_requested_by_user_id is not unset: + kwargs["filter_requested_by_user_id"] = filter_requested_by_user_id + + local_page_size = get_attribute_from_path(kwargs, "page_limit", 50) + endpoint = self._list_temporary_grant_requests_endpoint + set_attribute_from_path(kwargs, "page_limit", local_page_size, endpoint.params_map) + pagination = { + "limit_value": local_page_size, + "results_path": "data", + "cursor_param": "page_cursor", + "cursor_path": "meta.page.next_cursor", + "endpoint": endpoint, + "kwargs": kwargs, + } + return endpoint.call_with_http_info_paginated(pagination) + def update_quota( self, quota_namespace: str, @@ -1339,3 +1807,24 @@ def update_quota( kwargs["body"] = body return self._update_quota_endpoint.call_with_http_info(**kwargs) + + def update_temporary_grant_request( + self, + request_id: UUID, + body: TemporaryGrantRequestDecisionRequest, + ) -> TemporaryGrantRequestResponse: + """Decide a temporary grant request. + + Approve or deny the submitted terms, which are immutable. Approval atomically writes the grant, audit record, and request decision. An expired request can't be approved. Requires the Billing Edit permission. Requires an authenticated human user. Service-account credentials aren't supported. Request status remains approved after the grant's expiry, revocation, or replacement. + + :param request_id: The temporary grant request UUID. + :type request_id: UUID + :type body: TemporaryGrantRequestDecisionRequest + :rtype: TemporaryGrantRequestResponse + """ + kwargs: Dict[str, Any] = {} + kwargs["request_id"] = request_id + + kwargs["body"] = body + + return self._update_temporary_grant_request_endpoint.call_with_http_info(**kwargs) diff --git a/src/datadog_api_client/v2/model/temporary_grant_request_attributes.py b/src/datadog_api_client/v2/model/temporary_grant_request_attributes.py new file mode 100644 index 0000000000..7f87084372 --- /dev/null +++ b/src/datadog_api_client/v2/model/temporary_grant_request_attributes.py @@ -0,0 +1,134 @@ +# 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, TYPE_CHECKING + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, + datetime, + unset, + UnsetType, + UUID, +) + + +if TYPE_CHECKING: + from datadog_api_client.v2.model.temporary_grant_request_grant_state import TemporaryGrantRequestGrantState + from datadog_api_client.v2.model.temporary_grant_request_status import TemporaryGrantRequestStatus + + +class TemporaryGrantRequestAttributes(ModelNormal): + validations = { + "justification": { + "max_length": 4096, + "min_length": 1, + }, + "total": { + "inclusive_maximum": 9223372036854, + "inclusive_minimum": 1, + }, + } + + @cached_property + def openapi_types(_): + from datadog_api_client.v2.model.temporary_grant_request_grant_state import TemporaryGrantRequestGrantState + from datadog_api_client.v2.model.temporary_grant_request_status import TemporaryGrantRequestStatus + + return { + "created_at": (datetime,), + "decided_at": (datetime,), + "decided_by_user_id": (UUID,), + "entity_key": (str,), + "expires_at": (datetime,), + "grant_state": (TemporaryGrantRequestGrantState,), + "justification": (str,), + "quota_namespace": (str,), + "requested_by_user_id": (UUID,), + "status": (TemporaryGrantRequestStatus,), + "total": (int,), + } + + attribute_map = { + "created_at": "created_at", + "decided_at": "decided_at", + "decided_by_user_id": "decided_by_user_id", + "entity_key": "entity_key", + "expires_at": "expires_at", + "grant_state": "grant_state", + "justification": "justification", + "quota_namespace": "quota_namespace", + "requested_by_user_id": "requested_by_user_id", + "status": "status", + "total": "total", + } + + def __init__( + self_, + created_at: datetime, + entity_key: str, + expires_at: datetime, + justification: str, + quota_namespace: str, + requested_by_user_id: UUID, + status: TemporaryGrantRequestStatus, + total: int, + decided_at: Union[datetime, UnsetType] = unset, + decided_by_user_id: Union[UUID, UnsetType] = unset, + grant_state: Union[TemporaryGrantRequestGrantState, UnsetType] = unset, + **kwargs, + ): + """ + Request history and the linked grant state. List and detail reads include grant_state for approved requests. Decision responses record the decision. Read the request for current grant state. + + :param created_at: When the request was submitted. + :type created_at: datetime + + :param decided_at: When the decision or cancellation was recorded. + :type decided_at: datetime, optional + + :param decided_by_user_id: UUID of the reviewer, or of the requester if the request was canceled. + :type decided_by_user_id: UUID, optional + + :param entity_key: The requester identity resolved by the server. + :type entity_key: str + + :param expires_at: Immutable exclusive expiry, normalized to UTC microsecond precision. + :type expires_at: datetime + + :param grant_state: Current state of the grant associated with an approved request. Replaced means a newer grant superseded this grant. The newer grant might no longer be active. This field is absent for requests that weren't approved. + :type grant_state: TemporaryGrantRequestGrantState, optional + + :param justification: Reason for requesting temporary credits. Trimmed and limited to 4096 UTF-8 bytes. + :type justification: str + + :param quota_namespace: The quota namespace. Only AI credits are supported. + :type quota_namespace: str + + :param requested_by_user_id: UUID of the authenticated requester. + :type requested_by_user_id: UUID + + :param status: The durable request decision, independent of whether its grant is still active. + :type status: TemporaryGrantRequestStatus + + :param total: Target monthly AI credit limit in positive whole credits, not additional credits. Fractional credits are not accepted. + :type total: int + """ + if decided_at is not unset: + kwargs["decided_at"] = decided_at + if decided_by_user_id is not unset: + kwargs["decided_by_user_id"] = decided_by_user_id + if grant_state is not unset: + kwargs["grant_state"] = grant_state + super().__init__(kwargs) + + self_.created_at = created_at + self_.entity_key = entity_key + self_.expires_at = expires_at + self_.justification = justification + self_.quota_namespace = quota_namespace + self_.requested_by_user_id = requested_by_user_id + self_.status = status + self_.total = total diff --git a/src/datadog_api_client/v2/model/temporary_grant_request_create_attributes.py b/src/datadog_api_client/v2/model/temporary_grant_request_create_attributes.py new file mode 100644 index 0000000000..5d89966255 --- /dev/null +++ b/src/datadog_api_client/v2/model/temporary_grant_request_create_attributes.py @@ -0,0 +1,68 @@ +# 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, + datetime, + none_type, + unset, + UnsetType, +) + + +class TemporaryGrantRequestCreateAttributes(ModelNormal): + validations = { + "justification": { + "max_length": 4096, + "min_length": 1, + }, + "total": { + "inclusive_maximum": 9223372036854, + "inclusive_minimum": 1, + }, + } + + @cached_property + def additional_properties_type(_): + return None + + @cached_property + def openapi_types(_): + return { + "expires_at": (datetime, none_type), + "justification": (str,), + "total": (int,), + } + + attribute_map = { + "expires_at": "expires_at", + "justification": "justification", + "total": "total", + } + + def __init__( + self_, justification: str, total: int, expires_at: Union[datetime, none_type, UnsetType] = unset, **kwargs + ): + """ + Immutable terms and justification for a temporary grant request. + + :param expires_at: Exclusive expiry. Must be a future timestamp with a timezone. Date-only values are rejected. If omitted or null, defaults to the next UTC month boundary. Approval accepts this deadline unchanged. + :type expires_at: datetime, none_type, optional + + :param justification: Reason for requesting temporary credits. Trimmed and limited to 4096 UTF-8 bytes. + :type justification: str + + :param total: Target monthly AI credit limit in positive whole credits, not additional credits. Fractional credits are not accepted. + :type total: int + """ + if expires_at is not unset: + kwargs["expires_at"] = expires_at + super().__init__(kwargs) + + self_.justification = justification + self_.total = total diff --git a/src/datadog_api_client/v2/model/temporary_grant_request_create_data.py b/src/datadog_api_client/v2/model/temporary_grant_request_create_data.py new file mode 100644 index 0000000000..9058db7c4c --- /dev/null +++ b/src/datadog_api_client/v2/model/temporary_grant_request_create_data.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 TYPE_CHECKING + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, +) + + +if TYPE_CHECKING: + from datadog_api_client.v2.model.temporary_grant_request_create_attributes import ( + TemporaryGrantRequestCreateAttributes, + ) + from datadog_api_client.v2.model.temporary_grant_request_type import TemporaryGrantRequestType + + +class TemporaryGrantRequestCreateData(ModelNormal): + @cached_property + def openapi_types(_): + from datadog_api_client.v2.model.temporary_grant_request_create_attributes import ( + TemporaryGrantRequestCreateAttributes, + ) + from datadog_api_client.v2.model.temporary_grant_request_type import TemporaryGrantRequestType + + return { + "attributes": (TemporaryGrantRequestCreateAttributes,), + "type": (TemporaryGrantRequestType,), + } + + attribute_map = { + "attributes": "attributes", + "type": "type", + } + + def __init__(self_, attributes: TemporaryGrantRequestCreateAttributes, type: TemporaryGrantRequestType, **kwargs): + """ + The request resource to create. The server generates its ID. + + :param attributes: Immutable terms and justification for a temporary grant request. + :type attributes: TemporaryGrantRequestCreateAttributes + + :param type: The temporary grant request resource type. + :type type: TemporaryGrantRequestType + """ + super().__init__(kwargs) + + self_.attributes = attributes + self_.type = type diff --git a/src/datadog_api_client/v2/model/temporary_grant_request_create_request.py b/src/datadog_api_client/v2/model/temporary_grant_request_create_request.py new file mode 100644 index 0000000000..b81e59fcc0 --- /dev/null +++ b/src/datadog_api_client/v2/model/temporary_grant_request_create_request.py @@ -0,0 +1,40 @@ +# 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.temporary_grant_request_create_data import TemporaryGrantRequestCreateData + + +class TemporaryGrantRequestCreateRequest(ModelNormal): + @cached_property + def openapi_types(_): + from datadog_api_client.v2.model.temporary_grant_request_create_data import TemporaryGrantRequestCreateData + + return { + "data": (TemporaryGrantRequestCreateData,), + } + + attribute_map = { + "data": "data", + } + + def __init__(self_, data: TemporaryGrantRequestCreateData, **kwargs): + """ + Create a request for the authenticated human user. + + :param data: The request resource to create. The server generates its ID. + :type data: TemporaryGrantRequestCreateData + """ + super().__init__(kwargs) + + self_.data = data diff --git a/src/datadog_api_client/v2/model/temporary_grant_request_data.py b/src/datadog_api_client/v2/model/temporary_grant_request_data.py new file mode 100644 index 0000000000..a5bdd3e5fb --- /dev/null +++ b/src/datadog_api_client/v2/model/temporary_grant_request_data.py @@ -0,0 +1,57 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + +from typing import TYPE_CHECKING + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, + UUID, +) + + +if TYPE_CHECKING: + from datadog_api_client.v2.model.temporary_grant_request_attributes import TemporaryGrantRequestAttributes + from datadog_api_client.v2.model.temporary_grant_request_type import TemporaryGrantRequestType + + +class TemporaryGrantRequestData(ModelNormal): + @cached_property + def openapi_types(_): + from datadog_api_client.v2.model.temporary_grant_request_attributes import TemporaryGrantRequestAttributes + from datadog_api_client.v2.model.temporary_grant_request_type import TemporaryGrantRequestType + + return { + "attributes": (TemporaryGrantRequestAttributes,), + "id": (UUID,), + "type": (TemporaryGrantRequestType,), + } + + attribute_map = { + "attributes": "attributes", + "id": "id", + "type": "type", + } + + def __init__( + self_, attributes: TemporaryGrantRequestAttributes, id: UUID, type: TemporaryGrantRequestType, **kwargs + ): + """ + A temporary grant request resource. + + :param attributes: Request history and the linked grant state. List and detail reads include grant_state for approved requests. Decision responses record the decision. Read the request for current grant state. + :type attributes: TemporaryGrantRequestAttributes + + :param id: Server-generated request UUID. + :type id: UUID + + :param type: The temporary grant request resource type. + :type type: TemporaryGrantRequestType + """ + super().__init__(kwargs) + + self_.attributes = attributes + self_.id = id + self_.type = type diff --git a/src/datadog_api_client/v2/model/temporary_grant_request_decision.py b/src/datadog_api_client/v2/model/temporary_grant_request_decision.py new file mode 100644 index 0000000000..b9363ec21d --- /dev/null +++ b/src/datadog_api_client/v2/model/temporary_grant_request_decision.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 TemporaryGrantRequestDecision(ModelSimple): + """ + Approve the exact submitted total and expiry, or deny the request. + + :param value: Must be one of ["approved", "denied"]. + :type value: str + """ + + allowed_values = { + "approved", + "denied", + } + APPROVED: ClassVar["TemporaryGrantRequestDecision"] + DENIED: ClassVar["TemporaryGrantRequestDecision"] + + @cached_property + def openapi_types(_): + return { + "value": (str,), + } + + +TemporaryGrantRequestDecision.APPROVED = TemporaryGrantRequestDecision("approved") +TemporaryGrantRequestDecision.DENIED = TemporaryGrantRequestDecision("denied") diff --git a/src/datadog_api_client/v2/model/temporary_grant_request_decision_attributes.py b/src/datadog_api_client/v2/model/temporary_grant_request_decision_attributes.py new file mode 100644 index 0000000000..c169e0c228 --- /dev/null +++ b/src/datadog_api_client/v2/model/temporary_grant_request_decision_attributes.py @@ -0,0 +1,44 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + +from typing import TYPE_CHECKING + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, +) + + +if TYPE_CHECKING: + from datadog_api_client.v2.model.temporary_grant_request_decision import TemporaryGrantRequestDecision + + +class TemporaryGrantRequestDecisionAttributes(ModelNormal): + @cached_property + def additional_properties_type(_): + return None + + @cached_property + def openapi_types(_): + from datadog_api_client.v2.model.temporary_grant_request_decision import TemporaryGrantRequestDecision + + return { + "decision": (TemporaryGrantRequestDecision,), + } + + attribute_map = { + "decision": "decision", + } + + def __init__(self_, decision: TemporaryGrantRequestDecision, **kwargs): + """ + Binary decision. Overrides, reason fields, and unknown attributes are rejected, including null values. + + :param decision: Approve the exact submitted total and expiry, or deny the request. + :type decision: TemporaryGrantRequestDecision + """ + super().__init__(kwargs) + + self_.decision = decision diff --git a/src/datadog_api_client/v2/model/temporary_grant_request_decision_data.py b/src/datadog_api_client/v2/model/temporary_grant_request_decision_data.py new file mode 100644 index 0000000000..719de58bc7 --- /dev/null +++ b/src/datadog_api_client/v2/model/temporary_grant_request_decision_data.py @@ -0,0 +1,61 @@ +# 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, + UUID, +) + + +if TYPE_CHECKING: + from datadog_api_client.v2.model.temporary_grant_request_decision_attributes import ( + TemporaryGrantRequestDecisionAttributes, + ) + from datadog_api_client.v2.model.temporary_grant_request_type import TemporaryGrantRequestType + + +class TemporaryGrantRequestDecisionData(ModelNormal): + @cached_property + def openapi_types(_): + from datadog_api_client.v2.model.temporary_grant_request_decision_attributes import ( + TemporaryGrantRequestDecisionAttributes, + ) + from datadog_api_client.v2.model.temporary_grant_request_type import TemporaryGrantRequestType + + return { + "attributes": (TemporaryGrantRequestDecisionAttributes,), + "id": (UUID,), + "type": (TemporaryGrantRequestType,), + } + + attribute_map = { + "attributes": "attributes", + "id": "id", + "type": "type", + } + + def __init__( + self_, attributes: TemporaryGrantRequestDecisionAttributes, id: UUID, type: TemporaryGrantRequestType, **kwargs + ): + """ + A decision on a pending request. + + :param attributes: Binary decision. Overrides, reason fields, and unknown attributes are rejected, including null values. + :type attributes: TemporaryGrantRequestDecisionAttributes + + :param id: Request UUID. Must match request_id in the path. Missing or mismatched IDs return 400 Bad Request. + :type id: UUID + + :param type: The temporary grant request resource type. + :type type: TemporaryGrantRequestType + """ + super().__init__(kwargs) + + self_.attributes = attributes + self_.id = id + self_.type = type diff --git a/src/datadog_api_client/v2/model/temporary_grant_request_decision_request.py b/src/datadog_api_client/v2/model/temporary_grant_request_decision_request.py new file mode 100644 index 0000000000..f2c81a010c --- /dev/null +++ b/src/datadog_api_client/v2/model/temporary_grant_request_decision_request.py @@ -0,0 +1,40 @@ +# 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.temporary_grant_request_decision_data import TemporaryGrantRequestDecisionData + + +class TemporaryGrantRequestDecisionRequest(ModelNormal): + @cached_property + def openapi_types(_): + from datadog_api_client.v2.model.temporary_grant_request_decision_data import TemporaryGrantRequestDecisionData + + return { + "data": (TemporaryGrantRequestDecisionData,), + } + + attribute_map = { + "data": "data", + } + + def __init__(self_, data: TemporaryGrantRequestDecisionData, **kwargs): + """ + Approve or deny a pending request. + + :param data: A decision on a pending request. + :type data: TemporaryGrantRequestDecisionData + """ + super().__init__(kwargs) + + self_.data = data diff --git a/src/datadog_api_client/v2/model/temporary_grant_request_grant_state.py b/src/datadog_api_client/v2/model/temporary_grant_request_grant_state.py new file mode 100644 index 0000000000..c0b28945aa --- /dev/null +++ b/src/datadog_api_client/v2/model/temporary_grant_request_grant_state.py @@ -0,0 +1,44 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + + +from datadog_api_client.model_utils import ( + ModelSimple, + cached_property, +) + +from typing import ClassVar + + +class TemporaryGrantRequestGrantState(ModelSimple): + """ + Current state of the grant associated with an approved request. Replaced means a newer grant superseded this grant. The newer grant might no longer be active. This field is absent for requests that weren't approved. + + :param value: Must be one of ["active", "expired", "revoked", "replaced"]. + :type value: str + """ + + allowed_values = { + "active", + "expired", + "revoked", + "replaced", + } + ACTIVE: ClassVar["TemporaryGrantRequestGrantState"] + EXPIRED: ClassVar["TemporaryGrantRequestGrantState"] + REVOKED: ClassVar["TemporaryGrantRequestGrantState"] + REPLACED: ClassVar["TemporaryGrantRequestGrantState"] + + @cached_property + def openapi_types(_): + return { + "value": (str,), + } + + +TemporaryGrantRequestGrantState.ACTIVE = TemporaryGrantRequestGrantState("active") +TemporaryGrantRequestGrantState.EXPIRED = TemporaryGrantRequestGrantState("expired") +TemporaryGrantRequestGrantState.REVOKED = TemporaryGrantRequestGrantState("revoked") +TemporaryGrantRequestGrantState.REPLACED = TemporaryGrantRequestGrantState("replaced") diff --git a/src/datadog_api_client/v2/model/temporary_grant_request_list_meta.py b/src/datadog_api_client/v2/model/temporary_grant_request_list_meta.py new file mode 100644 index 0000000000..3200ebc0c9 --- /dev/null +++ b/src/datadog_api_client/v2/model/temporary_grant_request_list_meta.py @@ -0,0 +1,40 @@ +# 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.temporary_grant_request_page import TemporaryGrantRequestPage + + +class TemporaryGrantRequestListMeta(ModelNormal): + @cached_property + def openapi_types(_): + from datadog_api_client.v2.model.temporary_grant_request_page import TemporaryGrantRequestPage + + return { + "page": (TemporaryGrantRequestPage,), + } + + attribute_map = { + "page": "page", + } + + def __init__(self_, page: TemporaryGrantRequestPage, **kwargs): + """ + Pagination metadata. + + :param page: UUID cursor pagination. A full final page can return a cursor followed by an empty page. + :type page: TemporaryGrantRequestPage + """ + super().__init__(kwargs) + + self_.page = page diff --git a/src/datadog_api_client/v2/model/temporary_grant_request_list_response.py b/src/datadog_api_client/v2/model/temporary_grant_request_list_response.py new file mode 100644 index 0000000000..4ebd97737e --- /dev/null +++ b/src/datadog_api_client/v2/model/temporary_grant_request_list_response.py @@ -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. +from __future__ import annotations + +from typing import List, TYPE_CHECKING + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, +) + + +if TYPE_CHECKING: + from datadog_api_client.v2.model.temporary_grant_request_data import TemporaryGrantRequestData + from datadog_api_client.v2.model.temporary_grant_request_list_meta import TemporaryGrantRequestListMeta + + +class TemporaryGrantRequestListResponse(ModelNormal): + @cached_property + def openapi_types(_): + from datadog_api_client.v2.model.temporary_grant_request_data import TemporaryGrantRequestData + from datadog_api_client.v2.model.temporary_grant_request_list_meta import TemporaryGrantRequestListMeta + + return { + "data": ([TemporaryGrantRequestData],), + "meta": (TemporaryGrantRequestListMeta,), + } + + attribute_map = { + "data": "data", + "meta": "meta", + } + + def __init__(self_, data: List[TemporaryGrantRequestData], meta: TemporaryGrantRequestListMeta, **kwargs): + """ + A page of temporary grant requests, ordered by UUID rather than creation time. + + :param data: Requests visible to the authenticated caller. + :type data: [TemporaryGrantRequestData] + + :param meta: Pagination metadata. + :type meta: TemporaryGrantRequestListMeta + """ + super().__init__(kwargs) + + self_.data = data + self_.meta = meta diff --git a/src/datadog_api_client/v2/model/temporary_grant_request_page.py b/src/datadog_api_client/v2/model/temporary_grant_request_page.py new file mode 100644 index 0000000000..40c732b385 --- /dev/null +++ b/src/datadog_api_client/v2/model/temporary_grant_request_page.py @@ -0,0 +1,37 @@ +# 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, + UUID, +) + + +class TemporaryGrantRequestPage(ModelNormal): + @cached_property + def openapi_types(_): + return { + "next_cursor": (UUID,), + } + + attribute_map = { + "next_cursor": "next_cursor", + } + + def __init__(self_, next_cursor: Union[UUID, UnsetType] = unset, **kwargs): + """ + UUID cursor pagination. A full final page can return a cursor followed by an empty page. + + :param next_cursor: Use this UUID as page[cursor] to retrieve the next page. Omitted when the page is not full. + :type next_cursor: UUID, optional + """ + if next_cursor is not unset: + kwargs["next_cursor"] = next_cursor + super().__init__(kwargs) diff --git a/src/datadog_api_client/v2/model/temporary_grant_request_response.py b/src/datadog_api_client/v2/model/temporary_grant_request_response.py new file mode 100644 index 0000000000..bf5b83d4a9 --- /dev/null +++ b/src/datadog_api_client/v2/model/temporary_grant_request_response.py @@ -0,0 +1,40 @@ +# 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.temporary_grant_request_data import TemporaryGrantRequestData + + +class TemporaryGrantRequestResponse(ModelNormal): + @cached_property + def openapi_types(_): + from datadog_api_client.v2.model.temporary_grant_request_data import TemporaryGrantRequestData + + return { + "data": (TemporaryGrantRequestData,), + } + + attribute_map = { + "data": "data", + } + + def __init__(self_, data: TemporaryGrantRequestData, **kwargs): + """ + A single temporary grant request. + + :param data: A temporary grant request resource. + :type data: TemporaryGrantRequestData + """ + super().__init__(kwargs) + + self_.data = data diff --git a/src/datadog_api_client/v2/model/temporary_grant_request_status.py b/src/datadog_api_client/v2/model/temporary_grant_request_status.py new file mode 100644 index 0000000000..31e6caa6cb --- /dev/null +++ b/src/datadog_api_client/v2/model/temporary_grant_request_status.py @@ -0,0 +1,44 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + + +from datadog_api_client.model_utils import ( + ModelSimple, + cached_property, +) + +from typing import ClassVar + + +class TemporaryGrantRequestStatus(ModelSimple): + """ + The durable request decision, independent of whether its grant is still active. + + :param value: Must be one of ["pending", "approved", "denied", "cancelled"]. + :type value: str + """ + + allowed_values = { + "pending", + "approved", + "denied", + "cancelled", + } + PENDING: ClassVar["TemporaryGrantRequestStatus"] + APPROVED: ClassVar["TemporaryGrantRequestStatus"] + DENIED: ClassVar["TemporaryGrantRequestStatus"] + CANCELLED: ClassVar["TemporaryGrantRequestStatus"] + + @cached_property + def openapi_types(_): + return { + "value": (str,), + } + + +TemporaryGrantRequestStatus.PENDING = TemporaryGrantRequestStatus("pending") +TemporaryGrantRequestStatus.APPROVED = TemporaryGrantRequestStatus("approved") +TemporaryGrantRequestStatus.DENIED = TemporaryGrantRequestStatus("denied") +TemporaryGrantRequestStatus.CANCELLED = TemporaryGrantRequestStatus("cancelled") diff --git a/src/datadog_api_client/v2/model/temporary_grant_request_type.py b/src/datadog_api_client/v2/model/temporary_grant_request_type.py new file mode 100644 index 0000000000..6cd31e3245 --- /dev/null +++ b/src/datadog_api_client/v2/model/temporary_grant_request_type.py @@ -0,0 +1,35 @@ +# 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 TemporaryGrantRequestType(ModelSimple): + """ + The temporary grant request resource type. + + :param value: If omitted defaults to "temporary_grant_requests". Must be one of ["temporary_grant_requests"]. + :type value: str + """ + + allowed_values = { + "temporary_grant_requests", + } + TEMPORARY_GRANT_REQUESTS: ClassVar["TemporaryGrantRequestType"] + + @cached_property + def openapi_types(_): + return { + "value": (str,), + } + + +TemporaryGrantRequestType.TEMPORARY_GRANT_REQUESTS = TemporaryGrantRequestType("temporary_grant_requests") diff --git a/src/datadog_api_client/v2/models/__init__.py b/src/datadog_api_client/v2/models/__init__.py index e2e4ba94c3..9dd64a5950 100644 --- a/src/datadog_api_client/v2/models/__init__.py +++ b/src/datadog_api_client/v2/models/__init__.py @@ -12248,6 +12248,24 @@ from datadog_api_client.v2.model.teams_response_links import TeamsResponseLinks from datadog_api_client.v2.model.teams_response_meta import TeamsResponseMeta from datadog_api_client.v2.model.teams_response_meta_pagination import TeamsResponseMetaPagination +from datadog_api_client.v2.model.temporary_grant_request_attributes import TemporaryGrantRequestAttributes +from datadog_api_client.v2.model.temporary_grant_request_create_attributes import TemporaryGrantRequestCreateAttributes +from datadog_api_client.v2.model.temporary_grant_request_create_data import TemporaryGrantRequestCreateData +from datadog_api_client.v2.model.temporary_grant_request_create_request import TemporaryGrantRequestCreateRequest +from datadog_api_client.v2.model.temporary_grant_request_data import TemporaryGrantRequestData +from datadog_api_client.v2.model.temporary_grant_request_decision import TemporaryGrantRequestDecision +from datadog_api_client.v2.model.temporary_grant_request_decision_attributes import ( + TemporaryGrantRequestDecisionAttributes, +) +from datadog_api_client.v2.model.temporary_grant_request_decision_data import TemporaryGrantRequestDecisionData +from datadog_api_client.v2.model.temporary_grant_request_decision_request import TemporaryGrantRequestDecisionRequest +from datadog_api_client.v2.model.temporary_grant_request_grant_state import TemporaryGrantRequestGrantState +from datadog_api_client.v2.model.temporary_grant_request_list_meta import TemporaryGrantRequestListMeta +from datadog_api_client.v2.model.temporary_grant_request_list_response import TemporaryGrantRequestListResponse +from datadog_api_client.v2.model.temporary_grant_request_page import TemporaryGrantRequestPage +from datadog_api_client.v2.model.temporary_grant_request_response import TemporaryGrantRequestResponse +from datadog_api_client.v2.model.temporary_grant_request_status import TemporaryGrantRequestStatus +from datadog_api_client.v2.model.temporary_grant_request_type import TemporaryGrantRequestType from datadog_api_client.v2.model.tenancy_config import TenancyConfig from datadog_api_client.v2.model.tenancy_config_data import TenancyConfigData from datadog_api_client.v2.model.tenancy_config_data_attributes import TenancyConfigDataAttributes @@ -21256,6 +21274,22 @@ "TeamsResponseLinks", "TeamsResponseMeta", "TeamsResponseMetaPagination", + "TemporaryGrantRequestAttributes", + "TemporaryGrantRequestCreateAttributes", + "TemporaryGrantRequestCreateData", + "TemporaryGrantRequestCreateRequest", + "TemporaryGrantRequestData", + "TemporaryGrantRequestDecision", + "TemporaryGrantRequestDecisionAttributes", + "TemporaryGrantRequestDecisionData", + "TemporaryGrantRequestDecisionRequest", + "TemporaryGrantRequestGrantState", + "TemporaryGrantRequestListMeta", + "TemporaryGrantRequestListResponse", + "TemporaryGrantRequestPage", + "TemporaryGrantRequestResponse", + "TemporaryGrantRequestStatus", + "TemporaryGrantRequestType", "TenancyConfig", "TenancyConfigData", "TenancyConfigDataAttributes", diff --git a/tests/generated-test/test-runner-data/manifest.json b/tests/generated-test/test-runner-data/manifest.json index 16919a3dbb..f53b535da4 100644 --- a/tests/generated-test/test-runner-data/manifest.json +++ b/tests/generated-test/test-runner-data/manifest.json @@ -12754,6 +12754,13 @@ "scenario": "Ingest STIX threat intelligence returns \"OK\" response", "version": "v2" }, + { + "feature": "Usage Metering", + "feature_file": "../../v2/features/usage_metering.feature", + "file": "v2/usage-metering/decide-a-temporary-grant-request-returns-ok-response.json", + "scenario": "Decide a temporary grant request returns \"OK\" response", + "version": "v2" + }, { "feature": "Usage Metering", "feature_file": "../../v2/features/usage_metering.feature", @@ -12775,6 +12782,13 @@ "scenario": "Get active billing dimensions for cost attribution returns \"OK\" response", "version": "v2" }, + { + "feature": "Usage Metering", + "feature_file": "../../v2/features/usage_metering.feature", + "file": "v2/usage-metering/get-an-organization-temporary-grant-request-returns-ok-response.json", + "scenario": "Get an organization temporary grant request returns \"OK\" response", + "version": "v2" + }, { "feature": "Usage Metering", "feature_file": "../../v2/features/usage_metering.feature", @@ -12817,6 +12831,13 @@ "scenario": "Get projected cost across your account returns \"OK\" response", "version": "v2" }, + { + "feature": "Usage Metering", + "feature_file": "../../v2/features/usage_metering.feature", + "file": "v2/usage-metering/get-your-temporary-grant-request-returns-ok-response.json", + "scenario": "Get your temporary grant request returns \"OK\" response", + "version": "v2" + }, { "feature": "Usage Metering", "feature_file": "../../v2/features/usage_metering.feature", diff --git a/tests/generated-test/test-runner-data/v2/usage-metering/decide-a-temporary-grant-request-returns-ok-response.json b/tests/generated-test/test-runner-data/v2/usage-metering/decide-a-temporary-grant-request-returns-ok-response.json new file mode 100644 index 0000000000..a5002c9959 --- /dev/null +++ b/tests/generated-test/test-runner-data/v2/usage-metering/decide-a-temporary-grant-request-returns-ok-response.json @@ -0,0 +1,51 @@ +{ + "api": "UsageMetering", + "expected_status": 200, + "feature": "Usage Metering", + "id": "v2/Usage Metering/Decide a temporary grant request returns \"OK\" response", + "operation_id": "UpdateTemporaryGrantRequest", + "request": { + "body": { + "schema": { + "format": null, + "ref": "TemporaryGrantRequestDecisionRequest", + "type": "object" + }, + "source": "inline", + "value": { + "data": { + "attributes": { + "decision": "denied" + }, + "id": "{{ temporary_grant_request.data.id }}", + "type": "temporary_grant_requests" + } + } + }, + "content_type": "application/json", + "method": "POST", + "pagination": false, + "parameters": [ + { + "explode": null, + "in": "path", + "name": "request_id", + "required": true, + "schema": { + "format": "uuid", + "ref": null, + "type": "string" + }, + "source": { + "path": "temporary_grant_request.data.id", + "type": "fixture" + }, + "style": null + } + ], + "path": "/api/v2/usage/admin/temporary-grant-requests/{request_id}/decision" + }, + "scenario": "Decide a temporary grant request returns \"OK\" response", + "schema_version": 1, + "version": "v2" +} diff --git a/tests/generated-test/test-runner-data/v2/usage-metering/get-an-organization-temporary-grant-request-returns-ok-response.json b/tests/generated-test/test-runner-data/v2/usage-metering/get-an-organization-temporary-grant-request-returns-ok-response.json new file mode 100644 index 0000000000..95dcebda93 --- /dev/null +++ b/tests/generated-test/test-runner-data/v2/usage-metering/get-an-organization-temporary-grant-request-returns-ok-response.json @@ -0,0 +1,35 @@ +{ + "api": "UsageMetering", + "expected_status": 200, + "feature": "Usage Metering", + "id": "v2/Usage Metering/Get an organization temporary grant request returns \"OK\" response", + "operation_id": "GetTemporaryGrantRequest", + "request": { + "body": null, + "content_type": null, + "method": "GET", + "pagination": false, + "parameters": [ + { + "explode": null, + "in": "path", + "name": "request_id", + "required": true, + "schema": { + "format": "uuid", + "ref": null, + "type": "string" + }, + "source": { + "path": "temporary_grant_request.data.id", + "type": "fixture" + }, + "style": null + } + ], + "path": "/api/v2/usage/admin/temporary-grant-requests/{request_id}" + }, + "scenario": "Get an organization temporary grant request returns \"OK\" response", + "schema_version": 1, + "version": "v2" +} diff --git a/tests/generated-test/test-runner-data/v2/usage-metering/get-your-temporary-grant-request-returns-ok-response.json b/tests/generated-test/test-runner-data/v2/usage-metering/get-your-temporary-grant-request-returns-ok-response.json new file mode 100644 index 0000000000..b59d5ef704 --- /dev/null +++ b/tests/generated-test/test-runner-data/v2/usage-metering/get-your-temporary-grant-request-returns-ok-response.json @@ -0,0 +1,35 @@ +{ + "api": "UsageMetering", + "expected_status": 200, + "feature": "Usage Metering", + "id": "v2/Usage Metering/Get your temporary grant request returns \"OK\" response", + "operation_id": "GetMyTemporaryGrantRequest", + "request": { + "body": null, + "content_type": null, + "method": "GET", + "pagination": false, + "parameters": [ + { + "explode": null, + "in": "path", + "name": "request_id", + "required": true, + "schema": { + "format": "uuid", + "ref": null, + "type": "string" + }, + "source": { + "path": "temporary_grant_request.data.id", + "type": "fixture" + }, + "style": null + } + ], + "path": "/api/v2/usage/temporary-grant-requests/{request_id}" + }, + "scenario": "Get your temporary grant request returns \"OK\" response", + "schema_version": 1, + "version": "v2" +} diff --git a/tests/generated-test/test-server-data/v2/usage-metering.json b/tests/generated-test/test-server-data/v2/usage-metering.json index 9a9927ae5c..e8634f9d06 100644 --- a/tests/generated-test/test-server-data/v2/usage-metering.json +++ b/tests/generated-test/test-server-data/v2/usage-metering.json @@ -1,6 +1,99 @@ { "feature": "Usage Metering", "recordings": [ + { + "feature": "Usage Metering", + "frozen_at": "2026-10-29T18:06:54.122Z", + "interactions": [ + { + "request": { + "body": { + "type": "json", + "value": { + "data": { + "attributes": { + "justification": "Credits needed for Test-Decide_a_temporary_grant_request_returns_OK_response-1793297214.", + "total": 200 + }, + "type": "temporary_grant_requests" + } + } + }, + "content_type": "application/json", + "method": "POST", + "path": "/api/v2/usage/temporary-grant-requests", + "query": [] + }, + "response": { + "body": { + "encoding": "text", + "value": "{\"data\":{\"id\":\"5c05597a-04d0-4b95-969e-6bad0108f4e1\",\"type\":\"temporary_grant_requests\",\"attributes\":{\"created_at\":\"2026-10-29T18:06:56.353756Z\",\"entity_key\":\"user_handle:cedric.vanrompay@datadoghq.com\",\"expires_at\":\"2026-11-01T00:00:00Z\",\"justification\":\"Credits needed for Test-Decide_a_temporary_grant_request_returns_OK_response-1793297214.\",\"quota_namespace\":\"ai_credits\",\"requested_by_user_id\":\"028000b7-d90f-4d20-b4a9-6ff4a83b7950\",\"status\":\"pending\",\"total\":200}}}" + }, + "headers": { + "content-type": "application/vnd.api+json" + }, + "reason": "Created", + "status": 201 + } + }, + { + "request": { + "body": { + "type": "json", + "value": { + "data": { + "attributes": { + "decision": "denied" + }, + "id": "5c05597a-04d0-4b95-969e-6bad0108f4e1", + "type": "temporary_grant_requests" + } + } + }, + "content_type": "application/json", + "method": "POST", + "path": "/api/v2/usage/admin/temporary-grant-requests/5c05597a-04d0-4b95-969e-6bad0108f4e1/decision", + "query": [] + }, + "response": { + "body": { + "encoding": "text", + "value": "{\"data\":{\"id\":\"5c05597a-04d0-4b95-969e-6bad0108f4e1\",\"type\":\"temporary_grant_requests\",\"attributes\":{\"created_at\":\"2026-10-29T18:06:56.353756Z\",\"decided_at\":\"2026-10-29T18:06:56.430411Z\",\"decided_by_user_id\":\"028000b7-d90f-4d20-b4a9-6ff4a83b7950\",\"entity_key\":\"user_handle:cedric.vanrompay@datadoghq.com\",\"expires_at\":\"2026-11-01T00:00:00Z\",\"justification\":\"Credits needed for Test-Decide_a_temporary_grant_request_returns_OK_response-1793297214.\",\"quota_namespace\":\"ai_credits\",\"requested_by_user_id\":\"028000b7-d90f-4d20-b4a9-6ff4a83b7950\",\"status\":\"denied\",\"total\":200}}}" + }, + "headers": { + "content-type": "application/vnd.api+json" + }, + "reason": "OK", + "status": 200 + } + }, + { + "request": { + "body": { + "type": "empty", + "value": null + }, + "content_type": "", + "method": "DELETE", + "path": "/api/v2/usage/temporary-grant-requests/5c05597a-04d0-4b95-969e-6bad0108f4e1", + "query": [] + }, + "response": { + "body": { + "encoding": "text", + "value": "{\"errors\":[{\"title\":\"Generic Error\",\"detail\":\"temporary grant request is no longer pending or has expired\"}]}" + }, + "headers": { + "content-type": "application/vnd.api+json" + }, + "reason": "Conflict", + "status": 409 + } + } + ], + "scenario": "Decide a temporary grant request returns \"OK\" response", + "version": "v2" + }, { "feature": "Usage Metering", "frozen_at": "2023-11-16T19:41:02.013Z", @@ -120,6 +213,89 @@ "scenario": "Get active billing dimensions for cost attribution returns \"OK\" response", "version": "v2" }, + { + "feature": "Usage Metering", + "frozen_at": "2026-10-29T18:06:56.505Z", + "interactions": [ + { + "request": { + "body": { + "type": "json", + "value": { + "data": { + "attributes": { + "justification": "Credits needed for Test-Get_an_organization_temporary_grant_request_returns_OK_response-1793297216.", + "total": 200 + }, + "type": "temporary_grant_requests" + } + } + }, + "content_type": "application/json", + "method": "POST", + "path": "/api/v2/usage/temporary-grant-requests", + "query": [] + }, + "response": { + "body": { + "encoding": "text", + "value": "{\"data\":{\"id\":\"5c0e85a8-8def-4a55-ba83-17b30be04b21\",\"type\":\"temporary_grant_requests\",\"attributes\":{\"created_at\":\"2026-10-29T18:06:56.559013Z\",\"entity_key\":\"user_handle:cedric.vanrompay@datadoghq.com\",\"expires_at\":\"2026-11-01T00:00:00Z\",\"justification\":\"Credits needed for Test-Get_an_organization_temporary_grant_request_returns_OK_response-1793297216.\",\"quota_namespace\":\"ai_credits\",\"requested_by_user_id\":\"028000b7-d90f-4d20-b4a9-6ff4a83b7950\",\"status\":\"pending\",\"total\":200}}}" + }, + "headers": { + "content-type": "application/vnd.api+json" + }, + "reason": "Created", + "status": 201 + } + }, + { + "request": { + "body": { + "type": "empty", + "value": null + }, + "content_type": "", + "method": "GET", + "path": "/api/v2/usage/admin/temporary-grant-requests/5c0e85a8-8def-4a55-ba83-17b30be04b21", + "query": [] + }, + "response": { + "body": { + "encoding": "text", + "value": "{\"data\":{\"id\":\"5c0e85a8-8def-4a55-ba83-17b30be04b21\",\"type\":\"temporary_grant_requests\",\"attributes\":{\"created_at\":\"2026-10-29T18:06:56.559013Z\",\"entity_key\":\"user_handle:cedric.vanrompay@datadoghq.com\",\"expires_at\":\"2026-11-01T00:00:00Z\",\"justification\":\"Credits needed for Test-Get_an_organization_temporary_grant_request_returns_OK_response-1793297216.\",\"quota_namespace\":\"ai_credits\",\"requested_by_user_id\":\"028000b7-d90f-4d20-b4a9-6ff4a83b7950\",\"status\":\"pending\",\"total\":200}}}" + }, + "headers": { + "content-type": "application/vnd.api+json" + }, + "reason": "OK", + "status": 200 + } + }, + { + "request": { + "body": { + "type": "empty", + "value": null + }, + "content_type": "", + "method": "DELETE", + "path": "/api/v2/usage/temporary-grant-requests/5c0e85a8-8def-4a55-ba83-17b30be04b21", + "query": [] + }, + "response": { + "body": { + "encoding": "text", + "value": "" + }, + "headers": {}, + "reason": "No Content", + "status": 204 + } + } + ], + "scenario": "Get an organization temporary grant request returns \"OK\" response", + "version": "v2" + }, { "feature": "Usage Metering", "frozen_at": "2026-06-02T19:26:31.725Z", @@ -698,6 +874,89 @@ "scenario": "Get projected cost across your account returns \"OK\" response", "version": "v2" }, + { + "feature": "Usage Metering", + "frozen_at": "2026-10-29T18:06:56.719Z", + "interactions": [ + { + "request": { + "body": { + "type": "json", + "value": { + "data": { + "attributes": { + "justification": "Credits needed for Test-Get_your_temporary_grant_request_returns_OK_response-1793297216.", + "total": 200 + }, + "type": "temporary_grant_requests" + } + } + }, + "content_type": "application/json", + "method": "POST", + "path": "/api/v2/usage/temporary-grant-requests", + "query": [] + }, + "response": { + "body": { + "encoding": "text", + "value": "{\"data\":{\"id\":\"7b02f423-50da-4694-a06f-fc850bed6e79\",\"type\":\"temporary_grant_requests\",\"attributes\":{\"created_at\":\"2026-10-29T18:06:56.825991Z\",\"entity_key\":\"user_handle:cedric.vanrompay@datadoghq.com\",\"expires_at\":\"2026-11-01T00:00:00Z\",\"justification\":\"Credits needed for Test-Get_your_temporary_grant_request_returns_OK_response-1793297216.\",\"quota_namespace\":\"ai_credits\",\"requested_by_user_id\":\"028000b7-d90f-4d20-b4a9-6ff4a83b7950\",\"status\":\"pending\",\"total\":200}}}" + }, + "headers": { + "content-type": "application/vnd.api+json" + }, + "reason": "Created", + "status": 201 + } + }, + { + "request": { + "body": { + "type": "empty", + "value": null + }, + "content_type": "", + "method": "GET", + "path": "/api/v2/usage/temporary-grant-requests/7b02f423-50da-4694-a06f-fc850bed6e79", + "query": [] + }, + "response": { + "body": { + "encoding": "text", + "value": "{\"data\":{\"id\":\"7b02f423-50da-4694-a06f-fc850bed6e79\",\"type\":\"temporary_grant_requests\",\"attributes\":{\"created_at\":\"2026-10-29T18:06:56.825991Z\",\"entity_key\":\"user_handle:cedric.vanrompay@datadoghq.com\",\"expires_at\":\"2026-11-01T00:00:00Z\",\"justification\":\"Credits needed for Test-Get_your_temporary_grant_request_returns_OK_response-1793297216.\",\"quota_namespace\":\"ai_credits\",\"requested_by_user_id\":\"028000b7-d90f-4d20-b4a9-6ff4a83b7950\",\"status\":\"pending\",\"total\":200}}}" + }, + "headers": { + "content-type": "application/vnd.api+json" + }, + "reason": "OK", + "status": 200 + } + }, + { + "request": { + "body": { + "type": "empty", + "value": null + }, + "content_type": "", + "method": "DELETE", + "path": "/api/v2/usage/temporary-grant-requests/7b02f423-50da-4694-a06f-fc850bed6e79", + "query": [] + }, + "response": { + "body": { + "encoding": "text", + "value": "" + }, + "headers": {}, + "reason": "No Content", + "status": 204 + } + } + ], + "scenario": "Get your temporary grant request returns \"OK\" response", + "version": "v2" + }, { "feature": "Usage Metering", "frozen_at": "2022-11-03T21:08:41.229Z", diff --git a/tests/v2/features/given.json b/tests/v2/features/given.json index 133777e08d..05c5655fc6 100644 --- a/tests/v2/features/given.json +++ b/tests/v2/features/given.json @@ -2126,6 +2126,18 @@ "tag": "Teams", "operationId": "CreateTeamNotificationRule" }, + { + "parameters": [ + { + "name": "body", + "value": "{\"data\": {\"type\": \"temporary_grant_requests\", \"attributes\": {\"total\": 200, \"justification\": \"Credits needed for {{ unique }}.\"}}}" + } + ], + "step": "there is a valid \"temporary_grant_request\" in the system", + "key": "temporary_grant_request", + "tag": "Usage Metering", + "operationId": "CreateTemporaryGrantRequest" + }, { "parameters": [ { diff --git a/tests/v2/features/undo.json b/tests/v2/features/undo.json index 45b82eb3cd..e3fceb0202 100644 --- a/tests/v2/features/undo.json +++ b/tests/v2/features/undo.json @@ -11150,6 +11150,30 @@ "type": "safe" } }, + "ListTemporaryGrantRequests": { + "tag": "Usage Metering", + "undo": { + "type": "safe" + } + }, + "GetTemporaryGrantRequest": { + "tag": "Usage Metering", + "undo": { + "type": "safe" + } + }, + "UpdateTemporaryGrantRequest": { + "tag": "Usage Metering", + "undo": { + "type": "idempotent" + } + }, + "DeleteRequestedTemporaryGrant": { + "tag": "Usage Metering", + "undo": { + "type": "idempotent" + } + }, "GetUsageApplicationSecurityMonitoring": { "tag": "Usage Metering", "undo": { @@ -11240,6 +11264,37 @@ "type": "safe" } }, + "ListMyTemporaryGrantRequests": { + "tag": "Usage Metering", + "undo": { + "type": "safe" + } + }, + "CreateTemporaryGrantRequest": { + "tag": "Usage Metering", + "undo": { + "operationId": "DeleteTemporaryGrantRequest", + "parameters": [ + { + "name": "request_id", + "source": "data.id" + } + ], + "type": "unsafe" + } + }, + "DeleteTemporaryGrantRequest": { + "tag": "Usage Metering", + "undo": { + "type": "idempotent" + } + }, + "GetMyTemporaryGrantRequest": { + "tag": "Usage Metering", + "undo": { + "type": "safe" + } + }, "GetUsageAttributionTypes": { "tag": "Usage Metering", "undo": { diff --git a/tests/v2/features/usage_metering.feature b/tests/v2/features/usage_metering.feature index 9fd783ecd6..3e420970e7 100644 --- a/tests/v2/features/usage_metering.feature +++ b/tests/v2/features/usage_metering.feature @@ -41,6 +41,70 @@ Feature: Usage Metering When the request is sent Then the response status is 404 Not Found + @generated @skip @team:ddoghq/billing-hub + Scenario: Cancel your temporary grant request returns "Bad Request" response + Given operation "DeleteTemporaryGrantRequest" enabled + And new "DeleteTemporaryGrantRequest" request + And request contains "request_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:ddoghq/billing-hub + Scenario: Cancel your temporary grant request returns "Conflict" response + Given operation "DeleteTemporaryGrantRequest" enabled + And new "DeleteTemporaryGrantRequest" request + And request contains "request_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 409 Conflict + + @generated @skip @team:ddoghq/billing-hub + Scenario: Cancel your temporary grant request returns "No Content" response + Given operation "DeleteTemporaryGrantRequest" enabled + And new "DeleteTemporaryGrantRequest" request + And request contains "request_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 204 No Content + + @generated @skip @team:ddoghq/billing-hub + Scenario: Cancel your temporary grant request returns "Not Found" response + Given operation "DeleteTemporaryGrantRequest" enabled + And new "DeleteTemporaryGrantRequest" request + And request contains "request_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 404 Not Found + + @generated @skip @team:ddoghq/billing-hub + Scenario: Create a temporary grant request returns "Bad Request" response + Given operation "CreateTemporaryGrantRequest" enabled + And new "CreateTemporaryGrantRequest" request + And body with value {"data": {"attributes": {"expires_at": "2028-02-16T00:00:00Z", "justification": "Credits needed to finish the incident investigation.", "total": 200}, "type": "temporary_grant_requests"}} + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:ddoghq/billing-hub + Scenario: Create a temporary grant request returns "Conflict" response + Given operation "CreateTemporaryGrantRequest" enabled + And new "CreateTemporaryGrantRequest" request + And body with value {"data": {"attributes": {"expires_at": "2028-02-16T00:00:00Z", "justification": "Credits needed to finish the incident investigation.", "total": 200}, "type": "temporary_grant_requests"}} + When the request is sent + Then the response status is 409 Conflict + + @generated @skip @team:ddoghq/billing-hub + Scenario: Create a temporary grant request returns "Created" response + Given operation "CreateTemporaryGrantRequest" enabled + And new "CreateTemporaryGrantRequest" request + And body with value {"data": {"attributes": {"expires_at": "2028-02-16T00:00:00Z", "justification": "Credits needed to finish the incident investigation.", "total": 200}, "type": "temporary_grant_requests"}} + When the request is sent + Then the response status is 201 Created + + @generated @skip @team:ddoghq/billing-hub + Scenario: Create a temporary grant request returns "Not Found" response + Given operation "CreateTemporaryGrantRequest" enabled + And new "CreateTemporaryGrantRequest" request + And body with value {"data": {"attributes": {"expires_at": "2028-02-16T00:00:00Z", "justification": "Credits needed to finish the incident investigation.", "total": 200}, "type": "temporary_grant_requests"}} + When the request is sent + Then the response status is 404 Not Found + @generated @skip @team:ddoghq/billing-hub Scenario: Create or update usage quotas returns "Bad Request. Returned if the request is malformed, including when an item sets `pending_usage_limit` on a scoped quota, provides `enforced` without `usage_limit`, or provides neither limit. A pending-only item for a quota that does not exist is reported in that item's `error`; when only the caller's organization is targeted, this failure returns `400`." response Given operation "CreateQuotas" enabled @@ -59,6 +123,44 @@ Feature: Usage Metering When the request is sent Then the response status is 200 OK. The response includes each item's result; see each item's `error` attribute for any that failed to write. + @generated @skip @team:ddoghq/billing-hub + Scenario: Decide a temporary grant request returns "Bad Request" response + Given operation "UpdateTemporaryGrantRequest" enabled + And new "UpdateTemporaryGrantRequest" request + And request contains "request_id" parameter from "REPLACE.ME" + And body with value {"data": {"attributes": {"decision": "approved"}, "id": "12345678-1234-1234-1234-123456789012", "type": "temporary_grant_requests"}} + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:ddoghq/billing-hub + Scenario: Decide a temporary grant request returns "Conflict" response + Given operation "UpdateTemporaryGrantRequest" enabled + And new "UpdateTemporaryGrantRequest" request + And request contains "request_id" parameter from "REPLACE.ME" + And body with value {"data": {"attributes": {"decision": "approved"}, "id": "12345678-1234-1234-1234-123456789012", "type": "temporary_grant_requests"}} + When the request is sent + Then the response status is 409 Conflict + + @generated @skip @team:ddoghq/billing-hub + Scenario: Decide a temporary grant request returns "Not Found" response + Given operation "UpdateTemporaryGrantRequest" enabled + And new "UpdateTemporaryGrantRequest" request + And request contains "request_id" parameter from "REPLACE.ME" + And body with value {"data": {"attributes": {"decision": "approved"}, "id": "12345678-1234-1234-1234-123456789012", "type": "temporary_grant_requests"}} + When the request is sent + Then the response status is 404 Not Found + + @team:ddoghq/billing-hub + Scenario: Decide a temporary grant request returns "OK" response + Given operation "UpdateTemporaryGrantRequest" enabled + And there is a valid "temporary_grant_request" in the system + And new "UpdateTemporaryGrantRequest" request + And request contains "request_id" parameter from "temporary_grant_request.data.id" + And body with value {"data": {"attributes": {"decision": "denied"}, "id": "{{ temporary_grant_request.data.id }}", "type": "temporary_grant_requests"}} + When the request is sent + Then the response status is 200 OK + And the response "data.id" has the same value as "temporary_grant_request.data.id" + @generated @skip @team:ddoghq/billing-hub Scenario: Delete a usage quota returns "No Content" response Given operation "DeleteQuota" enabled @@ -107,6 +209,40 @@ Feature: Usage Metering When the request is sent Then the response status is 200 OK + @generated @skip @team:ddoghq/billing-hub + Scenario: Get an organization temporary grant request returns "Bad Request" response + Given operation "GetTemporaryGrantRequest" enabled + And new "GetTemporaryGrantRequest" request + And request contains "request_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:ddoghq/billing-hub + Scenario: Get an organization temporary grant request returns "Conflict" response + Given operation "GetTemporaryGrantRequest" enabled + And new "GetTemporaryGrantRequest" request + And request contains "request_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 409 Conflict + + @generated @skip @team:ddoghq/billing-hub + Scenario: Get an organization temporary grant request returns "Not Found" response + Given operation "GetTemporaryGrantRequest" enabled + And new "GetTemporaryGrantRequest" request + And request contains "request_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 404 Not Found + + @team:ddoghq/billing-hub + Scenario: Get an organization temporary grant request returns "OK" response + Given operation "GetTemporaryGrantRequest" enabled + And there is a valid "temporary_grant_request" in the system + And new "GetTemporaryGrantRequest" request + And request contains "request_id" parameter from "temporary_grant_request.data.id" + When the request is sent + Then the response status is 200 OK + And the response "data.id" has the same value as "temporary_grant_request.data.id" + @team:ddoghq/billing-hub Scenario: Get available fields for usage summary returns "Bad Request" response Given new "GetUsageSummaryAvailableFields" request @@ -289,6 +425,40 @@ Feature: Usage Metering When the request is sent Then the response status is 200 OK + @generated @skip @team:ddoghq/billing-hub + Scenario: Get your temporary grant request returns "Bad Request" response + Given operation "GetMyTemporaryGrantRequest" enabled + And new "GetMyTemporaryGrantRequest" request + And request contains "request_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:ddoghq/billing-hub + Scenario: Get your temporary grant request returns "Conflict" response + Given operation "GetMyTemporaryGrantRequest" enabled + And new "GetMyTemporaryGrantRequest" request + And request contains "request_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 409 Conflict + + @generated @skip @team:ddoghq/billing-hub + Scenario: Get your temporary grant request returns "Not Found" response + Given operation "GetMyTemporaryGrantRequest" enabled + And new "GetMyTemporaryGrantRequest" request + And request contains "request_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 404 Not Found + + @team:ddoghq/billing-hub + Scenario: Get your temporary grant request returns "OK" response + Given operation "GetMyTemporaryGrantRequest" enabled + And there is a valid "temporary_grant_request" in the system + And new "GetMyTemporaryGrantRequest" request + And request contains "request_id" parameter from "temporary_grant_request.data.id" + When the request is sent + Then the response status is 200 OK + And the response "data.id" has the same value as "temporary_grant_request.data.id" + @team:ddoghq/billing-hub Scenario: GetEstimatedCostByOrg with both start_month and start_date returns "Bad Request" response Given new "GetEstimatedCostByOrg" request @@ -306,6 +476,41 @@ Feature: Usage Metering When the request is sent Then the response status is 200 OK + @generated @skip @team:ddoghq/billing-hub + Scenario: List organization temporary grant requests returns "Bad Request" response + Given operation "ListTemporaryGrantRequests" enabled + And new "ListTemporaryGrantRequests" request + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:ddoghq/billing-hub + Scenario: List organization temporary grant requests returns "Conflict" response + Given operation "ListTemporaryGrantRequests" enabled + And new "ListTemporaryGrantRequests" request + When the request is sent + Then the response status is 409 Conflict + + @generated @skip @team:ddoghq/billing-hub + Scenario: List organization temporary grant requests returns "Not Found" response + Given operation "ListTemporaryGrantRequests" enabled + And new "ListTemporaryGrantRequests" request + When the request is sent + Then the response status is 404 Not Found + + @generated @skip @team:ddoghq/billing-hub + Scenario: List organization temporary grant requests returns "OK" response + Given operation "ListTemporaryGrantRequests" enabled + And new "ListTemporaryGrantRequests" request + When the request is sent + Then the response status is 200 OK + + @generated @skip @team:ddoghq/billing-hub @with-pagination + Scenario: List organization temporary grant requests returns "OK" response with pagination + Given operation "ListTemporaryGrantRequests" enabled + And new "ListTemporaryGrantRequests" request + When the request with pagination is sent + Then the response status is 200 OK + @generated @skip @team:ddoghq/billing-hub Scenario: List usage quotas returns "Bad Request" response Given operation "ListQuotas" enabled @@ -330,6 +535,73 @@ Feature: Usage Metering When the request with pagination is sent Then the response status is 200 OK + @generated @skip @team:ddoghq/billing-hub + Scenario: List your temporary grant requests returns "Bad Request" response + Given operation "ListMyTemporaryGrantRequests" enabled + And new "ListMyTemporaryGrantRequests" request + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:ddoghq/billing-hub + Scenario: List your temporary grant requests returns "Conflict" response + Given operation "ListMyTemporaryGrantRequests" enabled + And new "ListMyTemporaryGrantRequests" request + When the request is sent + Then the response status is 409 Conflict + + @generated @skip @team:ddoghq/billing-hub + Scenario: List your temporary grant requests returns "Not Found" response + Given operation "ListMyTemporaryGrantRequests" enabled + And new "ListMyTemporaryGrantRequests" request + When the request is sent + Then the response status is 404 Not Found + + @generated @skip @team:ddoghq/billing-hub + Scenario: List your temporary grant requests returns "OK" response + Given operation "ListMyTemporaryGrantRequests" enabled + And new "ListMyTemporaryGrantRequests" request + When the request is sent + Then the response status is 200 OK + + @generated @skip @team:ddoghq/billing-hub @with-pagination + Scenario: List your temporary grant requests returns "OK" response with pagination + Given operation "ListMyTemporaryGrantRequests" enabled + And new "ListMyTemporaryGrantRequests" request + When the request with pagination is sent + Then the response status is 200 OK + + @generated @skip @team:ddoghq/billing-hub + Scenario: Revoke a requested temporary grant returns "Bad Request" response + Given operation "DeleteRequestedTemporaryGrant" enabled + And new "DeleteRequestedTemporaryGrant" request + And request contains "request_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:ddoghq/billing-hub + Scenario: Revoke a requested temporary grant returns "Conflict" response + Given operation "DeleteRequestedTemporaryGrant" enabled + And new "DeleteRequestedTemporaryGrant" request + And request contains "request_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 409 Conflict + + @generated @skip @team:ddoghq/billing-hub + Scenario: Revoke a requested temporary grant returns "No Content" response + Given operation "DeleteRequestedTemporaryGrant" enabled + And new "DeleteRequestedTemporaryGrant" request + And request contains "request_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 204 No Content + + @generated @skip @team:ddoghq/billing-hub + Scenario: Revoke a requested temporary grant returns "Not Found" response + Given operation "DeleteRequestedTemporaryGrant" enabled + And new "DeleteRequestedTemporaryGrant" request + And request contains "request_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 404 Not Found + @generated @skip @team:ddoghq/billing-hub Scenario: Update a usage quota returns "Bad Request. Returned if the request is malformed, if the `id` in the request body does not match the `id` in the request path, if none of `usage_limit`, `enforced`, or `pending_usage_limit` is provided, or if `pending_usage_limit` is set on a scoped quota." response Given operation "UpdateQuota" enabled