From 3da0f1c154723e099b473e7db46551b1af43b7a9 Mon Sep 17 00:00:00 2001 From: "ci.datadog-api-spec" Date: Tue, 1 Jul 2025 19:50:57 +0000 Subject: [PATCH] Regenerate client from commit dcd0d219 of spec repo --- .apigentools-info | 8 +- .generator/schemas/v2/openapi.yaml | 368 +++++++++++- ...management_CreateCostGCPUsageCostConfig.rs | 30 + ...management_DeleteCostGCPUsageCostConfig.rs | 17 + ...-management_ListCostGCPUsageCostConfigs.rs | 15 + ...management_UpdateCostGCPUsageCostConfig.rs | 25 + .../api/api_cloud_cost_management.rs | 549 +++++++++++++++++- src/datadogV2/model/mod.rs | 26 + .../model/model_gcp_usage_cost_config.rs | 131 +++++ .../model_gcp_usage_cost_config_attributes.rs | 282 +++++++++ .../model_gcp_usage_cost_config_patch_data.rs | 116 ++++ ...del_gcp_usage_cost_config_patch_request.rs | 94 +++ ...ge_cost_config_patch_request_attributes.rs | 92 +++ ...cp_usage_cost_config_patch_request_type.rs | 50 ++ .../model_gcp_usage_cost_config_post_data.rs | 116 ++++ ...odel_gcp_usage_cost_config_post_request.rs | 94 +++ ...age_cost_config_post_request_attributes.rs | 166 ++++++ ...gcp_usage_cost_config_post_request_type.rs | 48 ++ .../model_gcp_usage_cost_config_response.rs | 105 ++++ .../model/model_gcp_usage_cost_config_type.rs | 48 ++ .../model_gcp_usage_cost_configs_response.rs | 105 ++++ ...config-returns-Bad-Request-response.frozen | 1 + ...t-config-returns-Bad-Request-response.json | 39 ++ ...age-Cost-config-returns-OK-response.frozen | 1 + ...Usage-Cost-config-returns-OK-response.json | 39 ++ ...config-returns-Bad-Request-response.frozen | 1 + ...t-config-returns-Bad-Request-response.json | 33 ++ ...-config-returns-No-Content-response.frozen | 1 + ...st-config-returns-No-Content-response.json | 33 ++ ...t-config-returns-Not-Found-response.frozen | 1 + ...ost-config-returns-Not-Found-response.json | 33 ++ ...ge-Cost-configs-returns-OK-response.frozen | 1 + ...sage-Cost-configs-returns-OK-response.json | 33 ++ ...config-returns-Bad-Request-response.frozen | 1 + ...t-config-returns-Bad-Request-response.json | 39 ++ ...t-config-returns-Not-Found-response.frozen | 1 + ...ost-config-returns-Not-Found-response.json | 39 ++ ...age-Cost-config-returns-OK-response.frozen | 1 + ...Usage-Cost-config-returns-OK-response.json | 39 ++ .../features/v2/cloud_cost_management.feature | 71 ++- tests/scenarios/features/v2/undo.json | 24 + tests/scenarios/function_mappings.rs | 133 +++++ 42 files changed, 3040 insertions(+), 9 deletions(-) create mode 100644 examples/v2_cloud-cost-management_CreateCostGCPUsageCostConfig.rs create mode 100644 examples/v2_cloud-cost-management_DeleteCostGCPUsageCostConfig.rs create mode 100644 examples/v2_cloud-cost-management_ListCostGCPUsageCostConfigs.rs create mode 100644 examples/v2_cloud-cost-management_UpdateCostGCPUsageCostConfig.rs create mode 100644 src/datadogV2/model/model_gcp_usage_cost_config.rs create mode 100644 src/datadogV2/model/model_gcp_usage_cost_config_attributes.rs create mode 100644 src/datadogV2/model/model_gcp_usage_cost_config_patch_data.rs create mode 100644 src/datadogV2/model/model_gcp_usage_cost_config_patch_request.rs create mode 100644 src/datadogV2/model/model_gcp_usage_cost_config_patch_request_attributes.rs create mode 100644 src/datadogV2/model/model_gcp_usage_cost_config_patch_request_type.rs create mode 100644 src/datadogV2/model/model_gcp_usage_cost_config_post_data.rs create mode 100644 src/datadogV2/model/model_gcp_usage_cost_config_post_request.rs create mode 100644 src/datadogV2/model/model_gcp_usage_cost_config_post_request_attributes.rs create mode 100644 src/datadogV2/model/model_gcp_usage_cost_config_post_request_type.rs create mode 100644 src/datadogV2/model/model_gcp_usage_cost_config_response.rs create mode 100644 src/datadogV2/model/model_gcp_usage_cost_config_type.rs create mode 100644 src/datadogV2/model/model_gcp_usage_cost_configs_response.rs create mode 100644 tests/scenarios/cassettes/v2/cloud_cost_management/Create-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.frozen create mode 100644 tests/scenarios/cassettes/v2/cloud_cost_management/Create-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.json create mode 100644 tests/scenarios/cassettes/v2/cloud_cost_management/Create-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-OK-response.frozen create mode 100644 tests/scenarios/cassettes/v2/cloud_cost_management/Create-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-OK-response.json create mode 100644 tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.frozen create mode 100644 tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.json create mode 100644 tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-No-Content-response.frozen create mode 100644 tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-No-Content-response.json create mode 100644 tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Not-Found-response.frozen create mode 100644 tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Not-Found-response.json create mode 100644 tests/scenarios/cassettes/v2/cloud_cost_management/List-Cloud-Cost-Management-GCP-Usage-Cost-configs-returns-OK-response.frozen create mode 100644 tests/scenarios/cassettes/v2/cloud_cost_management/List-Cloud-Cost-Management-GCP-Usage-Cost-configs-returns-OK-response.json create mode 100644 tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.frozen create mode 100644 tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.json create mode 100644 tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Not-Found-response.frozen create mode 100644 tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Not-Found-response.json create mode 100644 tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-OK-response.frozen create mode 100644 tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-OK-response.json diff --git a/.apigentools-info b/.apigentools-info index 5e9b50708..13875163a 100644 --- a/.apigentools-info +++ b/.apigentools-info @@ -4,13 +4,13 @@ "spec_versions": { "v1": { "apigentools_version": "1.6.6", - "regenerated": "2025-06-30 17:05:08.769740", - "spec_repo_commit": "d8e7ee77" + "regenerated": "2025-07-01 19:44:34.157748", + "spec_repo_commit": "dcd0d219" }, "v2": { "apigentools_version": "1.6.6", - "regenerated": "2025-06-30 17:05:08.786526", - "spec_repo_commit": "d8e7ee77" + "regenerated": "2025-07-01 19:44:34.178109", + "spec_repo_commit": "dcd0d219" } } } \ No newline at end of file diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index d5a8de2b6..da27cb1f6 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -16162,6 +16162,212 @@ components: type: string x-enum-varnames: - GCP_SERVICE_ACCOUNT + GCPUsageCostConfig: + description: GCP Usage Cost config. + properties: + attributes: + $ref: '#/components/schemas/GCPUsageCostConfigAttributes' + id: + description: The ID of the GCP Usage Cost config. + type: string + type: + $ref: '#/components/schemas/GCPUsageCostConfigType' + required: + - attributes + - type + type: object + GCPUsageCostConfigAttributes: + description: Attributes for a GCP Usage Cost config. + properties: + account_id: + description: The GCP account ID. + example: 123456_A123BC_12AB34 + type: string + bucket_name: + description: The GCP bucket name used to store the Usage Cost export. + example: dd-cost-bucket + type: string + created_at: + description: The timestamp when the GCP Usage Cost config was created. + pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{6}$ + type: string + dataset: + description: The export dataset name used for the GCP Usage Cost Report. + example: billing + type: string + error_messages: + description: The error messages for the GCP Usage Cost config. + items: + type: string + nullable: true + type: array + export_prefix: + description: The export prefix used for the GCP Usage Cost Report. + example: datadog_cloud_cost_usage_export + type: string + export_project_name: + description: The name of the GCP Usage Cost Report. + example: dd-cloud-cost-report + type: string + months: + deprecated: true + description: The number of months the report has been backfilled. + format: int32 + maximum: 36 + type: integer + project_id: + description: The `project_id` of the GCP Usage Cost report. + example: my-project-123 + type: string + service_account: + description: The unique GCP service account email. + example: dd-ccm-gcp-integration@my-environment.iam.gserviceaccount.com + type: string + status: + description: The status of the GCP Usage Cost config. + example: active + type: string + status_updated_at: + description: The timestamp when the GCP Usage Cost config status was updated. + pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{6}$ + type: string + updated_at: + description: The timestamp when the GCP Usage Cost config status was updated. + pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{6}$ + type: string + required: + - account_id + - bucket_name + - dataset + - export_prefix + - export_project_name + - service_account + - status + type: object + GCPUsageCostConfigPatchData: + description: GCP Usage Cost config patch data. + properties: + attributes: + $ref: '#/components/schemas/GCPUsageCostConfigPatchRequestAttributes' + type: + $ref: '#/components/schemas/GCPUsageCostConfigPatchRequestType' + required: + - attributes + - type + type: object + GCPUsageCostConfigPatchRequest: + description: GCP Usage Cost config patch request. + properties: + data: + $ref: '#/components/schemas/GCPUsageCostConfigPatchData' + required: + - data + type: object + GCPUsageCostConfigPatchRequestAttributes: + description: Attributes for GCP Usage Cost config patch request. + properties: + is_enabled: + description: Whether or not the Cloud Cost Management account is enabled. + example: true + type: boolean + required: + - is_enabled + type: object + GCPUsageCostConfigPatchRequestType: + default: gcp_uc_config_patch_request + description: Type of GCP Usage Cost config patch request. + enum: + - gcp_uc_config_patch_request + example: gcp_uc_config_patch_request + type: string + x-enum-varnames: + - GCP_USAGE_COST_CONFIG_PATCH_REQUEST + GCPUsageCostConfigPostData: + description: GCP Usage Cost config post data. + properties: + attributes: + $ref: '#/components/schemas/GCPUsageCostConfigPostRequestAttributes' + type: + $ref: '#/components/schemas/GCPUsageCostConfigPostRequestType' + required: + - attributes + - type + type: object + GCPUsageCostConfigPostRequest: + description: GCP Usage Cost config post request. + properties: + data: + $ref: '#/components/schemas/GCPUsageCostConfigPostData' + required: + - data + type: object + GCPUsageCostConfigPostRequestAttributes: + description: Attributes for GCP Usage Cost config post request. + properties: + billing_account_id: + description: The GCP account ID. + example: 123456_A123BC_12AB34 + type: string + bucket_name: + description: The GCP bucket name used to store the Usage Cost export. + example: dd-cost-bucket + type: string + export_dataset_name: + description: The export dataset name used for the GCP Usage Cost report. + example: billing + type: string + export_prefix: + description: The export prefix used for the GCP Usage Cost report. + example: datadog_cloud_cost_usage_export + type: string + export_project_name: + description: The name of the GCP Usage Cost report. + example: dd-cloud-cost-report + type: string + service_account: + description: The unique GCP service account email. + example: dd-ccm-gcp-integration@my-environment.iam.gserviceaccount.com + type: string + required: + - billing_account_id + - bucket_name + - export_project_name + - export_dataset_name + - service_account + type: object + GCPUsageCostConfigPostRequestType: + default: gcp_uc_config_post_request + description: Type of GCP Usage Cost config post request. + enum: + - gcp_uc_config_post_request + example: gcp_usage_cost_config_post_request + type: string + x-enum-varnames: + - GCP_USAGE_COST_CONFIG_POST_REQUEST + GCPUsageCostConfigResponse: + description: Response of GCP Usage Cost config. + properties: + data: + $ref: '#/components/schemas/GCPUsageCostConfig' + type: object + GCPUsageCostConfigType: + default: gcp_uc_config + description: Type of GCP Usage Cost config. + enum: + - gcp_uc_config + example: gcp_uc_config + type: string + x-enum-varnames: + - GCP_UC_CONFIG + GCPUsageCostConfigsResponse: + description: List of GCP Usage Cost configs. + properties: + data: + description: A GCP Usage Cost config. + items: + $ref: '#/components/schemas/GCPUsageCostConfig' + type: array + type: object GetActionConnectionResponse: description: The response for found connection properties: @@ -46254,6 +46460,164 @@ paths: summary: Get Custom Costs file tags: - Cloud Cost Management + /api/v2/cost/gcp_uc_config: + get: + description: List the GCP Usage Cost configs. + operationId: ListCostGCPUsageCostConfigs + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/GCPUsageCostConfigsResponse' + description: OK + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/APIErrorResponse' + description: Forbidden + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - cloud_cost_management_read + summary: List Cloud Cost Management GCP Usage Cost configs + tags: + - Cloud Cost Management + x-permission: + operator: OR + permissions: + - cloud_cost_management_read + post: + description: Create a Cloud Cost Management account for an GCP Usage Cost config. + operationId: CreateCostGCPUsageCostConfig + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/GCPUsageCostConfigPostRequest' + required: true + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/GCPUsageCostConfigResponse' + description: OK + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/APIErrorResponse' + description: Bad Request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/APIErrorResponse' + description: Forbidden + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - cloud_cost_management_write + summary: Create Cloud Cost Management GCP Usage Cost config + tags: + - Cloud Cost Management + x-permission: + operator: OR + permissions: + - cloud_cost_management_write + /api/v2/cost/gcp_uc_config/{cloud_account_id}: + delete: + description: Archive a Cloud Cost Management account. + operationId: DeleteCostGCPUsageCostConfig + parameters: + - $ref: '#/components/parameters/CloudAccountID' + responses: + '204': + description: No Content + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/APIErrorResponse' + description: Bad Request + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/APIErrorResponse' + description: Not Found + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - cloud_cost_management_write + summary: Delete Cloud Cost Management GCP Usage Cost config + tags: + - Cloud Cost Management + x-permission: + operator: OR + permissions: + - cloud_cost_management_write + patch: + description: Update the status of an GCP Usage Cost config (active/archived). + operationId: UpdateCostGCPUsageCostConfig + parameters: + - $ref: '#/components/parameters/CloudAccountID' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/GCPUsageCostConfigPatchRequest' + required: true + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/GCPUsageCostConfigResponse' + description: OK + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/APIErrorResponse' + description: Bad Request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/APIErrorResponse' + description: Forbidden + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/APIErrorResponse' + description: Not Found + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - cloud_cost_management_write + summary: Update Cloud Cost Management GCP Usage Cost config + tags: + - Cloud Cost Management + x-permission: + operator: OR + permissions: + - cloud_cost_management_write /api/v2/cost_by_tag/active_billing_dimensions: get: description: Get active billing dimensions for cost attribution. Cost data for @@ -64333,8 +64697,8 @@ tags: for more information. name: Case Management - description: The Cloud Cost Management API allows you to set up, edit, and delete - Cloud Cost Management accounts for AWS and Azure. You can query your cost data - by using the [Metrics endpoint](https://docs.datadoghq.com/api/latest/metrics/#query-timeseries-data-across-multiple-products) + Cloud Cost Management accounts for AWS, Azure, and GCP. You can query your cost + data by using the [Metrics endpoint](https://docs.datadoghq.com/api/latest/metrics/#query-timeseries-data-across-multiple-products) and the `cloud_cost` data source. For more information, see the [Cloud Cost Management documentation](https://docs.datadoghq.com/cloud_cost_management/). name: Cloud Cost Management diff --git a/examples/v2_cloud-cost-management_CreateCostGCPUsageCostConfig.rs b/examples/v2_cloud-cost-management_CreateCostGCPUsageCostConfig.rs new file mode 100644 index 000000000..a15e7c4c5 --- /dev/null +++ b/examples/v2_cloud-cost-management_CreateCostGCPUsageCostConfig.rs @@ -0,0 +1,30 @@ +// Create Cloud Cost Management GCP Usage Cost config returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_cloud_cost_management::CloudCostManagementAPI; +use datadog_api_client::datadogV2::model::GCPUsageCostConfigPostData; +use datadog_api_client::datadogV2::model::GCPUsageCostConfigPostRequest; +use datadog_api_client::datadogV2::model::GCPUsageCostConfigPostRequestAttributes; +use datadog_api_client::datadogV2::model::GCPUsageCostConfigPostRequestType; + +#[tokio::main] +async fn main() { + let body = GCPUsageCostConfigPostRequest::new(GCPUsageCostConfigPostData::new( + GCPUsageCostConfigPostRequestAttributes::new( + "123456_A123BC_12AB34".to_string(), + "dd-cost-bucket".to_string(), + "billing".to_string(), + "dd-cloud-cost-report".to_string(), + "dd-ccm-gcp-integration@my-environment.iam.gserviceaccount.com".to_string(), + ) + .export_prefix("datadog_cloud_cost_usage_export".to_string()), + GCPUsageCostConfigPostRequestType::GCP_USAGE_COST_CONFIG_POST_REQUEST, + )); + let configuration = datadog::Configuration::new(); + let api = CloudCostManagementAPI::with_config(configuration); + let resp = api.create_cost_gcp_usage_cost_config(body).await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_cloud-cost-management_DeleteCostGCPUsageCostConfig.rs b/examples/v2_cloud-cost-management_DeleteCostGCPUsageCostConfig.rs new file mode 100644 index 000000000..cb5de637c --- /dev/null +++ b/examples/v2_cloud-cost-management_DeleteCostGCPUsageCostConfig.rs @@ -0,0 +1,17 @@ +// Delete Cloud Cost Management GCP Usage Cost config returns "No Content" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_cloud_cost_management::CloudCostManagementAPI; + +#[tokio::main] +async fn main() { + let configuration = datadog::Configuration::new(); + let api = CloudCostManagementAPI::with_config(configuration); + let resp = api + .delete_cost_gcp_usage_cost_config("100".to_string()) + .await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_cloud-cost-management_ListCostGCPUsageCostConfigs.rs b/examples/v2_cloud-cost-management_ListCostGCPUsageCostConfigs.rs new file mode 100644 index 000000000..e7cb9cf6b --- /dev/null +++ b/examples/v2_cloud-cost-management_ListCostGCPUsageCostConfigs.rs @@ -0,0 +1,15 @@ +// List Cloud Cost Management GCP Usage Cost configs returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_cloud_cost_management::CloudCostManagementAPI; + +#[tokio::main] +async fn main() { + let configuration = datadog::Configuration::new(); + let api = CloudCostManagementAPI::with_config(configuration); + let resp = api.list_cost_gcp_usage_cost_configs().await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_cloud-cost-management_UpdateCostGCPUsageCostConfig.rs b/examples/v2_cloud-cost-management_UpdateCostGCPUsageCostConfig.rs new file mode 100644 index 000000000..14059f6e7 --- /dev/null +++ b/examples/v2_cloud-cost-management_UpdateCostGCPUsageCostConfig.rs @@ -0,0 +1,25 @@ +// Update Cloud Cost Management GCP Usage Cost config returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_cloud_cost_management::CloudCostManagementAPI; +use datadog_api_client::datadogV2::model::GCPUsageCostConfigPatchData; +use datadog_api_client::datadogV2::model::GCPUsageCostConfigPatchRequest; +use datadog_api_client::datadogV2::model::GCPUsageCostConfigPatchRequestAttributes; +use datadog_api_client::datadogV2::model::GCPUsageCostConfigPatchRequestType; + +#[tokio::main] +async fn main() { + let body = GCPUsageCostConfigPatchRequest::new(GCPUsageCostConfigPatchData::new( + GCPUsageCostConfigPatchRequestAttributes::new(true), + GCPUsageCostConfigPatchRequestType::GCP_USAGE_COST_CONFIG_PATCH_REQUEST, + )); + let configuration = datadog::Configuration::new(); + let api = CloudCostManagementAPI::with_config(configuration); + let resp = api + .update_cost_gcp_usage_cost_config("100".to_string(), body) + .await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/src/datadogV2/api/api_cloud_cost_management.rs b/src/datadogV2/api/api_cloud_cost_management.rs index 3aa12a06d..c7d888344 100644 --- a/src/datadogV2/api/api_cloud_cost_management.rs +++ b/src/datadogV2/api/api_cloud_cost_management.rs @@ -26,6 +26,14 @@ pub enum CreateCostAzureUCConfigsError { UnknownValue(serde_json::Value), } +/// CreateCostGCPUsageCostConfigError is a struct for typed errors of method [`CloudCostManagementAPI::create_cost_gcp_usage_cost_config`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum CreateCostGCPUsageCostConfigError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// DeleteBudgetError is a struct for typed errors of method [`CloudCostManagementAPI::delete_budget`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -50,6 +58,14 @@ pub enum DeleteCostAzureUCConfigError { UnknownValue(serde_json::Value), } +/// DeleteCostGCPUsageCostConfigError is a struct for typed errors of method [`CloudCostManagementAPI::delete_cost_gcp_usage_cost_config`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum DeleteCostGCPUsageCostConfigError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// DeleteCustomCostsFileError is a struct for typed errors of method [`CloudCostManagementAPI::delete_custom_costs_file`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -98,6 +114,14 @@ pub enum ListCostAzureUCConfigsError { UnknownValue(serde_json::Value), } +/// ListCostGCPUsageCostConfigsError is a struct for typed errors of method [`CloudCostManagementAPI::list_cost_gcp_usage_cost_configs`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ListCostGCPUsageCostConfigsError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// ListCustomCostsFilesError is a struct for typed errors of method [`CloudCostManagementAPI::list_custom_costs_files`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -122,6 +146,14 @@ pub enum UpdateCostAzureUCConfigsError { UnknownValue(serde_json::Value), } +/// UpdateCostGCPUsageCostConfigError is a struct for typed errors of method [`CloudCostManagementAPI::update_cost_gcp_usage_cost_config`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum UpdateCostGCPUsageCostConfigError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// UploadCustomCostsFileError is a struct for typed errors of method [`CloudCostManagementAPI::upload_custom_costs_file`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -138,7 +170,7 @@ pub enum UpsertBudgetError { UnknownValue(serde_json::Value), } -/// The Cloud Cost Management API allows you to set up, edit, and delete Cloud Cost Management accounts for AWS and Azure. You can query your cost data by using the [Metrics endpoint]() and the `cloud_cost` data source. For more information, see the [Cloud Cost Management documentation](). +/// The Cloud Cost Management API allows you to set up, edit, and delete Cloud Cost Management accounts for AWS, Azure, and GCP. You can query your cost data by using the [Metrics endpoint]() and the `cloud_cost` data source. For more information, see the [Cloud Cost Management documentation](). #[derive(Debug, Clone)] pub struct CloudCostManagementAPI { config: datadog::Configuration, @@ -511,6 +543,163 @@ impl CloudCostManagementAPI { } } + /// Create a Cloud Cost Management account for an GCP Usage Cost config. + pub async fn create_cost_gcp_usage_cost_config( + &self, + body: crate::datadogV2::model::GCPUsageCostConfigPostRequest, + ) -> Result< + crate::datadogV2::model::GCPUsageCostConfigResponse, + datadog::Error, + > { + match self + .create_cost_gcp_usage_cost_config_with_http_info(body) + .await + { + Ok(response_content) => { + if let Some(e) = response_content.entity { + Ok(e) + } else { + Err(datadog::Error::Serde(serde::de::Error::custom( + "response content was None", + ))) + } + } + Err(err) => Err(err), + } + } + + /// Create a Cloud Cost Management account for an GCP Usage Cost config. + pub async fn create_cost_gcp_usage_cost_config_with_http_info( + &self, + body: crate::datadogV2::model::GCPUsageCostConfigPostRequest, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.create_cost_gcp_usage_cost_config"; + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/cost/gcp_uc_config", + local_configuration.get_operation_host(operation_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::POST, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Content-Type", HeaderValue::from_static("application/json")); + headers.insert("Accept", HeaderValue::from_static("application/json")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + // build body parameters + let output = Vec::new(); + let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter); + if body.serialize(&mut ser).is_ok() { + if let Some(content_encoding) = headers.get("Content-Encoding") { + match content_encoding.to_str().unwrap_or_default() { + "gzip" => { + let mut enc = GzEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "deflate" => { + let mut enc = ZlibEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "zstd1" => { + let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap(); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + _ => { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + } else { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + match serde_json::from_str::( + &local_content, + ) { + Ok(e) => { + return Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: Some(e), + }) + } + Err(e) => return Err(datadog::Error::Serde(e)), + }; + } else { + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + /// Delete a budget. pub async fn delete_budget( &self, @@ -780,6 +969,98 @@ impl CloudCostManagementAPI { } } + /// Archive a Cloud Cost Management account. + pub async fn delete_cost_gcp_usage_cost_config( + &self, + cloud_account_id: String, + ) -> Result<(), datadog::Error> { + match self + .delete_cost_gcp_usage_cost_config_with_http_info(cloud_account_id) + .await + { + Ok(_) => Ok(()), + Err(err) => Err(err), + } + } + + /// Archive a Cloud Cost Management account. + pub async fn delete_cost_gcp_usage_cost_config_with_http_info( + &self, + cloud_account_id: String, + ) -> Result, datadog::Error> + { + let local_configuration = &self.config; + let operation_id = "v2.delete_cost_gcp_usage_cost_config"; + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/cost/gcp_uc_config/{cloud_account_id}", + local_configuration.get_operation_host(operation_id), + cloud_account_id = datadog::urlencode(cloud_account_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::DELETE, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Accept", HeaderValue::from_static("*/*")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: None, + }) + } else { + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + /// Delete the specified Custom Costs file. pub async fn delete_custom_costs_file( &self, @@ -1393,6 +1674,112 @@ impl CloudCostManagementAPI { } } + /// List the GCP Usage Cost configs. + pub async fn list_cost_gcp_usage_cost_configs( + &self, + ) -> Result< + crate::datadogV2::model::GCPUsageCostConfigsResponse, + datadog::Error, + > { + match self.list_cost_gcp_usage_cost_configs_with_http_info().await { + Ok(response_content) => { + if let Some(e) = response_content.entity { + Ok(e) + } else { + Err(datadog::Error::Serde(serde::de::Error::custom( + "response content was None", + ))) + } + } + Err(err) => Err(err), + } + } + + /// List the GCP Usage Cost configs. + pub async fn list_cost_gcp_usage_cost_configs_with_http_info( + &self, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.list_cost_gcp_usage_cost_configs"; + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/cost/gcp_uc_config", + local_configuration.get_operation_host(operation_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::GET, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Accept", HeaderValue::from_static("application/json")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + match serde_json::from_str::( + &local_content, + ) { + Ok(e) => { + return Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: Some(e), + }) + } + Err(e) => return Err(datadog::Error::Serde(e)), + }; + } else { + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + /// List the Custom Costs files. pub async fn list_custom_costs_files( &self, @@ -1819,6 +2206,166 @@ impl CloudCostManagementAPI { } } + /// Update the status of an GCP Usage Cost config (active/archived). + pub async fn update_cost_gcp_usage_cost_config( + &self, + cloud_account_id: String, + body: crate::datadogV2::model::GCPUsageCostConfigPatchRequest, + ) -> Result< + crate::datadogV2::model::GCPUsageCostConfigResponse, + datadog::Error, + > { + match self + .update_cost_gcp_usage_cost_config_with_http_info(cloud_account_id, body) + .await + { + Ok(response_content) => { + if let Some(e) = response_content.entity { + Ok(e) + } else { + Err(datadog::Error::Serde(serde::de::Error::custom( + "response content was None", + ))) + } + } + Err(err) => Err(err), + } + } + + /// Update the status of an GCP Usage Cost config (active/archived). + pub async fn update_cost_gcp_usage_cost_config_with_http_info( + &self, + cloud_account_id: String, + body: crate::datadogV2::model::GCPUsageCostConfigPatchRequest, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.update_cost_gcp_usage_cost_config"; + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/cost/gcp_uc_config/{cloud_account_id}", + local_configuration.get_operation_host(operation_id), + cloud_account_id = datadog::urlencode(cloud_account_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::PATCH, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Content-Type", HeaderValue::from_static("application/json")); + headers.insert("Accept", HeaderValue::from_static("application/json")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + // build body parameters + let output = Vec::new(); + let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter); + if body.serialize(&mut ser).is_ok() { + if let Some(content_encoding) = headers.get("Content-Encoding") { + match content_encoding.to_str().unwrap_or_default() { + "gzip" => { + let mut enc = GzEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "deflate" => { + let mut enc = ZlibEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "zstd1" => { + let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap(); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + _ => { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + } else { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + match serde_json::from_str::( + &local_content, + ) { + Ok(e) => { + return Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: Some(e), + }) + } + Err(e) => return Err(datadog::Error::Serde(e)), + }; + } else { + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + /// Upload a Custom Costs file. pub async fn upload_custom_costs_file( &self, diff --git a/src/datadogV2/model/mod.rs b/src/datadogV2/model/mod.rs index 05db30592..9ab4bdf50 100644 --- a/src/datadogV2/model/mod.rs +++ b/src/datadogV2/model/mod.rs @@ -1240,6 +1240,32 @@ pub mod model_custom_costs_file_metadata_with_content; pub use self::model_custom_costs_file_metadata_with_content::CustomCostsFileMetadataWithContent; pub mod model_custom_cost_get_response_meta; pub use self::model_custom_cost_get_response_meta::CustomCostGetResponseMeta; +pub mod model_gcp_usage_cost_configs_response; +pub use self::model_gcp_usage_cost_configs_response::GCPUsageCostConfigsResponse; +pub mod model_gcp_usage_cost_config; +pub use self::model_gcp_usage_cost_config::GCPUsageCostConfig; +pub mod model_gcp_usage_cost_config_attributes; +pub use self::model_gcp_usage_cost_config_attributes::GCPUsageCostConfigAttributes; +pub mod model_gcp_usage_cost_config_type; +pub use self::model_gcp_usage_cost_config_type::GCPUsageCostConfigType; +pub mod model_gcp_usage_cost_config_post_request; +pub use self::model_gcp_usage_cost_config_post_request::GCPUsageCostConfigPostRequest; +pub mod model_gcp_usage_cost_config_post_data; +pub use self::model_gcp_usage_cost_config_post_data::GCPUsageCostConfigPostData; +pub mod model_gcp_usage_cost_config_post_request_attributes; +pub use self::model_gcp_usage_cost_config_post_request_attributes::GCPUsageCostConfigPostRequestAttributes; +pub mod model_gcp_usage_cost_config_post_request_type; +pub use self::model_gcp_usage_cost_config_post_request_type::GCPUsageCostConfigPostRequestType; +pub mod model_gcp_usage_cost_config_response; +pub use self::model_gcp_usage_cost_config_response::GCPUsageCostConfigResponse; +pub mod model_gcp_usage_cost_config_patch_request; +pub use self::model_gcp_usage_cost_config_patch_request::GCPUsageCostConfigPatchRequest; +pub mod model_gcp_usage_cost_config_patch_data; +pub use self::model_gcp_usage_cost_config_patch_data::GCPUsageCostConfigPatchData; +pub mod model_gcp_usage_cost_config_patch_request_attributes; +pub use self::model_gcp_usage_cost_config_patch_request_attributes::GCPUsageCostConfigPatchRequestAttributes; +pub mod model_gcp_usage_cost_config_patch_request_type; +pub use self::model_gcp_usage_cost_config_patch_request_type::GCPUsageCostConfigPatchRequestType; pub mod model_active_billing_dimensions_response; pub use self::model_active_billing_dimensions_response::ActiveBillingDimensionsResponse; pub mod model_active_billing_dimensions_body; diff --git a/src/datadogV2/model/model_gcp_usage_cost_config.rs b/src/datadogV2/model/model_gcp_usage_cost_config.rs new file mode 100644 index 000000000..faba28a51 --- /dev/null +++ b/src/datadogV2/model/model_gcp_usage_cost_config.rs @@ -0,0 +1,131 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// GCP Usage Cost config. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct GCPUsageCostConfig { + /// Attributes for a GCP Usage Cost config. + #[serde(rename = "attributes")] + pub attributes: crate::datadogV2::model::GCPUsageCostConfigAttributes, + /// The ID of the GCP Usage Cost config. + #[serde(rename = "id")] + pub id: Option, + /// Type of GCP Usage Cost config. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::GCPUsageCostConfigType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl GCPUsageCostConfig { + pub fn new( + attributes: crate::datadogV2::model::GCPUsageCostConfigAttributes, + type_: crate::datadogV2::model::GCPUsageCostConfigType, + ) -> GCPUsageCostConfig { + GCPUsageCostConfig { + attributes, + id: None, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn id(mut self, value: String) -> Self { + self.id = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for GCPUsageCostConfig { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct GCPUsageCostConfigVisitor; + impl<'a> Visitor<'a> for GCPUsageCostConfigVisitor { + type Value = GCPUsageCostConfig; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut attributes: Option = + None; + let mut id: Option = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "attributes" => { + attributes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "id" => { + if v.is_null() { + continue; + } + id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::GCPUsageCostConfigType::UnparsedObject(_type_) => { + _unparsed = true; + }, + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let attributes = attributes.ok_or_else(|| M::Error::missing_field("attributes"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = GCPUsageCostConfig { + attributes, + id, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(GCPUsageCostConfigVisitor) + } +} diff --git a/src/datadogV2/model/model_gcp_usage_cost_config_attributes.rs b/src/datadogV2/model/model_gcp_usage_cost_config_attributes.rs new file mode 100644 index 000000000..a0bc8a0c2 --- /dev/null +++ b/src/datadogV2/model/model_gcp_usage_cost_config_attributes.rs @@ -0,0 +1,282 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Attributes for a GCP Usage Cost config. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct GCPUsageCostConfigAttributes { + /// The GCP account ID. + #[serde(rename = "account_id")] + pub account_id: String, + /// The GCP bucket name used to store the Usage Cost export. + #[serde(rename = "bucket_name")] + pub bucket_name: String, + /// The timestamp when the GCP Usage Cost config was created. + #[serde(rename = "created_at")] + pub created_at: Option, + /// The export dataset name used for the GCP Usage Cost Report. + #[serde(rename = "dataset")] + pub dataset: String, + /// The error messages for the GCP Usage Cost config. + #[serde( + rename = "error_messages", + default, + with = "::serde_with::rust::double_option" + )] + pub error_messages: Option>>, + /// The export prefix used for the GCP Usage Cost Report. + #[serde(rename = "export_prefix")] + pub export_prefix: String, + /// The name of the GCP Usage Cost Report. + #[serde(rename = "export_project_name")] + pub export_project_name: String, + /// The number of months the report has been backfilled. + #[deprecated] + #[serde(rename = "months")] + pub months: Option, + /// The `project_id` of the GCP Usage Cost report. + #[serde(rename = "project_id")] + pub project_id: Option, + /// The unique GCP service account email. + #[serde(rename = "service_account")] + pub service_account: String, + /// The status of the GCP Usage Cost config. + #[serde(rename = "status")] + pub status: String, + /// The timestamp when the GCP Usage Cost config status was updated. + #[serde(rename = "status_updated_at")] + pub status_updated_at: Option, + /// The timestamp when the GCP Usage Cost config status was updated. + #[serde(rename = "updated_at")] + pub updated_at: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl GCPUsageCostConfigAttributes { + pub fn new( + account_id: String, + bucket_name: String, + dataset: String, + export_prefix: String, + export_project_name: String, + service_account: String, + status: String, + ) -> GCPUsageCostConfigAttributes { + #[allow(deprecated)] + GCPUsageCostConfigAttributes { + account_id, + bucket_name, + created_at: None, + dataset, + error_messages: None, + export_prefix, + export_project_name, + months: None, + project_id: None, + service_account, + status, + status_updated_at: None, + updated_at: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + #[allow(deprecated)] + pub fn created_at(mut self, value: String) -> Self { + self.created_at = Some(value); + self + } + + #[allow(deprecated)] + pub fn error_messages(mut self, value: Option>) -> Self { + self.error_messages = Some(value); + self + } + + #[allow(deprecated)] + pub fn months(mut self, value: i32) -> Self { + self.months = Some(value); + self + } + + #[allow(deprecated)] + pub fn project_id(mut self, value: String) -> Self { + self.project_id = Some(value); + self + } + + #[allow(deprecated)] + pub fn status_updated_at(mut self, value: String) -> Self { + self.status_updated_at = Some(value); + self + } + + #[allow(deprecated)] + pub fn updated_at(mut self, value: String) -> Self { + self.updated_at = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for GCPUsageCostConfigAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct GCPUsageCostConfigAttributesVisitor; + impl<'a> Visitor<'a> for GCPUsageCostConfigAttributesVisitor { + type Value = GCPUsageCostConfigAttributes; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut account_id: Option = None; + let mut bucket_name: Option = None; + let mut created_at: Option = None; + let mut dataset: Option = None; + let mut error_messages: Option>> = None; + let mut export_prefix: Option = None; + let mut export_project_name: Option = None; + let mut months: Option = None; + let mut project_id: Option = None; + let mut service_account: Option = None; + let mut status: Option = None; + let mut status_updated_at: Option = None; + let mut updated_at: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "account_id" => { + account_id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "bucket_name" => { + bucket_name = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "created_at" => { + if v.is_null() { + continue; + } + created_at = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "dataset" => { + dataset = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "error_messages" => { + error_messages = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "export_prefix" => { + export_prefix = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "export_project_name" => { + export_project_name = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "months" => { + if v.is_null() { + continue; + } + months = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "project_id" => { + if v.is_null() { + continue; + } + project_id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "service_account" => { + service_account = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "status" => { + status = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "status_updated_at" => { + if v.is_null() { + continue; + } + status_updated_at = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "updated_at" => { + if v.is_null() { + continue; + } + updated_at = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let account_id = account_id.ok_or_else(|| M::Error::missing_field("account_id"))?; + let bucket_name = + bucket_name.ok_or_else(|| M::Error::missing_field("bucket_name"))?; + let dataset = dataset.ok_or_else(|| M::Error::missing_field("dataset"))?; + let export_prefix = + export_prefix.ok_or_else(|| M::Error::missing_field("export_prefix"))?; + let export_project_name = export_project_name + .ok_or_else(|| M::Error::missing_field("export_project_name"))?; + let service_account = + service_account.ok_or_else(|| M::Error::missing_field("service_account"))?; + let status = status.ok_or_else(|| M::Error::missing_field("status"))?; + + #[allow(deprecated)] + let content = GCPUsageCostConfigAttributes { + account_id, + bucket_name, + created_at, + dataset, + error_messages, + export_prefix, + export_project_name, + months, + project_id, + service_account, + status, + status_updated_at, + updated_at, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(GCPUsageCostConfigAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_gcp_usage_cost_config_patch_data.rs b/src/datadogV2/model/model_gcp_usage_cost_config_patch_data.rs new file mode 100644 index 000000000..24d21c803 --- /dev/null +++ b/src/datadogV2/model/model_gcp_usage_cost_config_patch_data.rs @@ -0,0 +1,116 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// GCP Usage Cost config patch data. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct GCPUsageCostConfigPatchData { + /// Attributes for GCP Usage Cost config patch request. + #[serde(rename = "attributes")] + pub attributes: crate::datadogV2::model::GCPUsageCostConfigPatchRequestAttributes, + /// Type of GCP Usage Cost config patch request. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::GCPUsageCostConfigPatchRequestType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl GCPUsageCostConfigPatchData { + pub fn new( + attributes: crate::datadogV2::model::GCPUsageCostConfigPatchRequestAttributes, + type_: crate::datadogV2::model::GCPUsageCostConfigPatchRequestType, + ) -> GCPUsageCostConfigPatchData { + GCPUsageCostConfigPatchData { + attributes, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for GCPUsageCostConfigPatchData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct GCPUsageCostConfigPatchDataVisitor; + impl<'a> Visitor<'a> for GCPUsageCostConfigPatchDataVisitor { + type Value = GCPUsageCostConfigPatchData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut attributes: Option< + crate::datadogV2::model::GCPUsageCostConfigPatchRequestAttributes, + > = None; + let mut type_: Option = + None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "attributes" => { + attributes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::GCPUsageCostConfigPatchRequestType::UnparsedObject(_type_) => { + _unparsed = true; + }, + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let attributes = attributes.ok_or_else(|| M::Error::missing_field("attributes"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = GCPUsageCostConfigPatchData { + attributes, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(GCPUsageCostConfigPatchDataVisitor) + } +} diff --git a/src/datadogV2/model/model_gcp_usage_cost_config_patch_request.rs b/src/datadogV2/model/model_gcp_usage_cost_config_patch_request.rs new file mode 100644 index 000000000..f7e529694 --- /dev/null +++ b/src/datadogV2/model/model_gcp_usage_cost_config_patch_request.rs @@ -0,0 +1,94 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// GCP Usage Cost config patch request. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct GCPUsageCostConfigPatchRequest { + /// GCP Usage Cost config patch data. + #[serde(rename = "data")] + pub data: crate::datadogV2::model::GCPUsageCostConfigPatchData, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl GCPUsageCostConfigPatchRequest { + pub fn new( + data: crate::datadogV2::model::GCPUsageCostConfigPatchData, + ) -> GCPUsageCostConfigPatchRequest { + GCPUsageCostConfigPatchRequest { + data, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for GCPUsageCostConfigPatchRequest { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct GCPUsageCostConfigPatchRequestVisitor; + impl<'a> Visitor<'a> for GCPUsageCostConfigPatchRequestVisitor { + type Value = GCPUsageCostConfigPatchRequest; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let data = data.ok_or_else(|| M::Error::missing_field("data"))?; + + let content = GCPUsageCostConfigPatchRequest { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(GCPUsageCostConfigPatchRequestVisitor) + } +} diff --git a/src/datadogV2/model/model_gcp_usage_cost_config_patch_request_attributes.rs b/src/datadogV2/model/model_gcp_usage_cost_config_patch_request_attributes.rs new file mode 100644 index 000000000..7ab4db211 --- /dev/null +++ b/src/datadogV2/model/model_gcp_usage_cost_config_patch_request_attributes.rs @@ -0,0 +1,92 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Attributes for GCP Usage Cost config patch request. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct GCPUsageCostConfigPatchRequestAttributes { + /// Whether or not the Cloud Cost Management account is enabled. + #[serde(rename = "is_enabled")] + pub is_enabled: bool, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl GCPUsageCostConfigPatchRequestAttributes { + pub fn new(is_enabled: bool) -> GCPUsageCostConfigPatchRequestAttributes { + GCPUsageCostConfigPatchRequestAttributes { + is_enabled, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for GCPUsageCostConfigPatchRequestAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct GCPUsageCostConfigPatchRequestAttributesVisitor; + impl<'a> Visitor<'a> for GCPUsageCostConfigPatchRequestAttributesVisitor { + type Value = GCPUsageCostConfigPatchRequestAttributes; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut is_enabled: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "is_enabled" => { + is_enabled = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let is_enabled = is_enabled.ok_or_else(|| M::Error::missing_field("is_enabled"))?; + + let content = GCPUsageCostConfigPatchRequestAttributes { + is_enabled, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(GCPUsageCostConfigPatchRequestAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_gcp_usage_cost_config_patch_request_type.rs b/src/datadogV2/model/model_gcp_usage_cost_config_patch_request_type.rs new file mode 100644 index 000000000..ef79d5438 --- /dev/null +++ b/src/datadogV2/model/model_gcp_usage_cost_config_patch_request_type.rs @@ -0,0 +1,50 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. + +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +#[non_exhaustive] +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum GCPUsageCostConfigPatchRequestType { + GCP_USAGE_COST_CONFIG_PATCH_REQUEST, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for GCPUsageCostConfigPatchRequestType { + fn to_string(&self) -> String { + match self { + Self::GCP_USAGE_COST_CONFIG_PATCH_REQUEST => { + String::from("gcp_uc_config_patch_request") + } + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for GCPUsageCostConfigPatchRequestType { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Self::UnparsedObject(v) => v.serialize(serializer), + _ => serializer.serialize_str(self.to_string().as_str()), + } + } +} + +impl<'de> Deserialize<'de> for GCPUsageCostConfigPatchRequestType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "gcp_uc_config_patch_request" => Self::GCP_USAGE_COST_CONFIG_PATCH_REQUEST, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/src/datadogV2/model/model_gcp_usage_cost_config_post_data.rs b/src/datadogV2/model/model_gcp_usage_cost_config_post_data.rs new file mode 100644 index 000000000..ec61215e3 --- /dev/null +++ b/src/datadogV2/model/model_gcp_usage_cost_config_post_data.rs @@ -0,0 +1,116 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// GCP Usage Cost config post data. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct GCPUsageCostConfigPostData { + /// Attributes for GCP Usage Cost config post request. + #[serde(rename = "attributes")] + pub attributes: crate::datadogV2::model::GCPUsageCostConfigPostRequestAttributes, + /// Type of GCP Usage Cost config post request. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::GCPUsageCostConfigPostRequestType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl GCPUsageCostConfigPostData { + pub fn new( + attributes: crate::datadogV2::model::GCPUsageCostConfigPostRequestAttributes, + type_: crate::datadogV2::model::GCPUsageCostConfigPostRequestType, + ) -> GCPUsageCostConfigPostData { + GCPUsageCostConfigPostData { + attributes, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for GCPUsageCostConfigPostData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct GCPUsageCostConfigPostDataVisitor; + impl<'a> Visitor<'a> for GCPUsageCostConfigPostDataVisitor { + type Value = GCPUsageCostConfigPostData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut attributes: Option< + crate::datadogV2::model::GCPUsageCostConfigPostRequestAttributes, + > = None; + let mut type_: Option = + None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "attributes" => { + attributes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::GCPUsageCostConfigPostRequestType::UnparsedObject(_type_) => { + _unparsed = true; + }, + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let attributes = attributes.ok_or_else(|| M::Error::missing_field("attributes"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = GCPUsageCostConfigPostData { + attributes, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(GCPUsageCostConfigPostDataVisitor) + } +} diff --git a/src/datadogV2/model/model_gcp_usage_cost_config_post_request.rs b/src/datadogV2/model/model_gcp_usage_cost_config_post_request.rs new file mode 100644 index 000000000..086fce4b8 --- /dev/null +++ b/src/datadogV2/model/model_gcp_usage_cost_config_post_request.rs @@ -0,0 +1,94 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// GCP Usage Cost config post request. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct GCPUsageCostConfigPostRequest { + /// GCP Usage Cost config post data. + #[serde(rename = "data")] + pub data: crate::datadogV2::model::GCPUsageCostConfigPostData, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl GCPUsageCostConfigPostRequest { + pub fn new( + data: crate::datadogV2::model::GCPUsageCostConfigPostData, + ) -> GCPUsageCostConfigPostRequest { + GCPUsageCostConfigPostRequest { + data, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for GCPUsageCostConfigPostRequest { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct GCPUsageCostConfigPostRequestVisitor; + impl<'a> Visitor<'a> for GCPUsageCostConfigPostRequestVisitor { + type Value = GCPUsageCostConfigPostRequest; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let data = data.ok_or_else(|| M::Error::missing_field("data"))?; + + let content = GCPUsageCostConfigPostRequest { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(GCPUsageCostConfigPostRequestVisitor) + } +} diff --git a/src/datadogV2/model/model_gcp_usage_cost_config_post_request_attributes.rs b/src/datadogV2/model/model_gcp_usage_cost_config_post_request_attributes.rs new file mode 100644 index 000000000..7302a123b --- /dev/null +++ b/src/datadogV2/model/model_gcp_usage_cost_config_post_request_attributes.rs @@ -0,0 +1,166 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Attributes for GCP Usage Cost config post request. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct GCPUsageCostConfigPostRequestAttributes { + /// The GCP account ID. + #[serde(rename = "billing_account_id")] + pub billing_account_id: String, + /// The GCP bucket name used to store the Usage Cost export. + #[serde(rename = "bucket_name")] + pub bucket_name: String, + /// The export dataset name used for the GCP Usage Cost report. + #[serde(rename = "export_dataset_name")] + pub export_dataset_name: String, + /// The export prefix used for the GCP Usage Cost report. + #[serde(rename = "export_prefix")] + pub export_prefix: Option, + /// The name of the GCP Usage Cost report. + #[serde(rename = "export_project_name")] + pub export_project_name: String, + /// The unique GCP service account email. + #[serde(rename = "service_account")] + pub service_account: String, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl GCPUsageCostConfigPostRequestAttributes { + pub fn new( + billing_account_id: String, + bucket_name: String, + export_dataset_name: String, + export_project_name: String, + service_account: String, + ) -> GCPUsageCostConfigPostRequestAttributes { + GCPUsageCostConfigPostRequestAttributes { + billing_account_id, + bucket_name, + export_dataset_name, + export_prefix: None, + export_project_name, + service_account, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn export_prefix(mut self, value: String) -> Self { + self.export_prefix = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for GCPUsageCostConfigPostRequestAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct GCPUsageCostConfigPostRequestAttributesVisitor; + impl<'a> Visitor<'a> for GCPUsageCostConfigPostRequestAttributesVisitor { + type Value = GCPUsageCostConfigPostRequestAttributes; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut billing_account_id: Option = None; + let mut bucket_name: Option = None; + let mut export_dataset_name: Option = None; + let mut export_prefix: Option = None; + let mut export_project_name: Option = None; + let mut service_account: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "billing_account_id" => { + billing_account_id = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "bucket_name" => { + bucket_name = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "export_dataset_name" => { + export_dataset_name = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "export_prefix" => { + if v.is_null() { + continue; + } + export_prefix = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "export_project_name" => { + export_project_name = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "service_account" => { + service_account = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let billing_account_id = billing_account_id + .ok_or_else(|| M::Error::missing_field("billing_account_id"))?; + let bucket_name = + bucket_name.ok_or_else(|| M::Error::missing_field("bucket_name"))?; + let export_dataset_name = export_dataset_name + .ok_or_else(|| M::Error::missing_field("export_dataset_name"))?; + let export_project_name = export_project_name + .ok_or_else(|| M::Error::missing_field("export_project_name"))?; + let service_account = + service_account.ok_or_else(|| M::Error::missing_field("service_account"))?; + + let content = GCPUsageCostConfigPostRequestAttributes { + billing_account_id, + bucket_name, + export_dataset_name, + export_prefix, + export_project_name, + service_account, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(GCPUsageCostConfigPostRequestAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_gcp_usage_cost_config_post_request_type.rs b/src/datadogV2/model/model_gcp_usage_cost_config_post_request_type.rs new file mode 100644 index 000000000..ac76202a3 --- /dev/null +++ b/src/datadogV2/model/model_gcp_usage_cost_config_post_request_type.rs @@ -0,0 +1,48 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. + +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +#[non_exhaustive] +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum GCPUsageCostConfigPostRequestType { + GCP_USAGE_COST_CONFIG_POST_REQUEST, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for GCPUsageCostConfigPostRequestType { + fn to_string(&self) -> String { + match self { + Self::GCP_USAGE_COST_CONFIG_POST_REQUEST => String::from("gcp_uc_config_post_request"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for GCPUsageCostConfigPostRequestType { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Self::UnparsedObject(v) => v.serialize(serializer), + _ => serializer.serialize_str(self.to_string().as_str()), + } + } +} + +impl<'de> Deserialize<'de> for GCPUsageCostConfigPostRequestType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "gcp_uc_config_post_request" => Self::GCP_USAGE_COST_CONFIG_POST_REQUEST, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/src/datadogV2/model/model_gcp_usage_cost_config_response.rs b/src/datadogV2/model/model_gcp_usage_cost_config_response.rs new file mode 100644 index 000000000..caa18953a --- /dev/null +++ b/src/datadogV2/model/model_gcp_usage_cost_config_response.rs @@ -0,0 +1,105 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Response of GCP Usage Cost config. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct GCPUsageCostConfigResponse { + /// GCP Usage Cost config. + #[serde(rename = "data")] + pub data: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl GCPUsageCostConfigResponse { + pub fn new() -> GCPUsageCostConfigResponse { + GCPUsageCostConfigResponse { + data: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn data(mut self, value: crate::datadogV2::model::GCPUsageCostConfig) -> Self { + self.data = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for GCPUsageCostConfigResponse { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for GCPUsageCostConfigResponse { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct GCPUsageCostConfigResponseVisitor; + impl<'a> Visitor<'a> for GCPUsageCostConfigResponseVisitor { + type Value = GCPUsageCostConfigResponse; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + if v.is_null() { + continue; + } + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = GCPUsageCostConfigResponse { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(GCPUsageCostConfigResponseVisitor) + } +} diff --git a/src/datadogV2/model/model_gcp_usage_cost_config_type.rs b/src/datadogV2/model/model_gcp_usage_cost_config_type.rs new file mode 100644 index 000000000..57cf13ad2 --- /dev/null +++ b/src/datadogV2/model/model_gcp_usage_cost_config_type.rs @@ -0,0 +1,48 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. + +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +#[non_exhaustive] +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum GCPUsageCostConfigType { + GCP_UC_CONFIG, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for GCPUsageCostConfigType { + fn to_string(&self) -> String { + match self { + Self::GCP_UC_CONFIG => String::from("gcp_uc_config"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for GCPUsageCostConfigType { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Self::UnparsedObject(v) => v.serialize(serializer), + _ => serializer.serialize_str(self.to_string().as_str()), + } + } +} + +impl<'de> Deserialize<'de> for GCPUsageCostConfigType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "gcp_uc_config" => Self::GCP_UC_CONFIG, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/src/datadogV2/model/model_gcp_usage_cost_configs_response.rs b/src/datadogV2/model/model_gcp_usage_cost_configs_response.rs new file mode 100644 index 000000000..448d8823a --- /dev/null +++ b/src/datadogV2/model/model_gcp_usage_cost_configs_response.rs @@ -0,0 +1,105 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// List of GCP Usage Cost configs. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct GCPUsageCostConfigsResponse { + /// A GCP Usage Cost config. + #[serde(rename = "data")] + pub data: Option>, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl GCPUsageCostConfigsResponse { + pub fn new() -> GCPUsageCostConfigsResponse { + GCPUsageCostConfigsResponse { + data: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn data(mut self, value: Vec) -> Self { + self.data = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for GCPUsageCostConfigsResponse { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for GCPUsageCostConfigsResponse { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct GCPUsageCostConfigsResponseVisitor; + impl<'a> Visitor<'a> for GCPUsageCostConfigsResponseVisitor { + type Value = GCPUsageCostConfigsResponse; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option> = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + if v.is_null() { + continue; + } + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = GCPUsageCostConfigsResponse { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(GCPUsageCostConfigsResponseVisitor) + } +} diff --git a/tests/scenarios/cassettes/v2/cloud_cost_management/Create-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.frozen b/tests/scenarios/cassettes/v2/cloud_cost_management/Create-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.frozen new file mode 100644 index 000000000..908fad476 --- /dev/null +++ b/tests/scenarios/cassettes/v2/cloud_cost_management/Create-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.frozen @@ -0,0 +1 @@ +2025-06-23T13:03:22.482Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/cloud_cost_management/Create-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.json b/tests/scenarios/cassettes/v2/cloud_cost_management/Create-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.json new file mode 100644 index 000000000..5c8ace27b --- /dev/null +++ b/tests/scenarios/cassettes/v2/cloud_cost_management/Create-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":{\"attributes\":{\"billing_account_id\":\"123456_A123BC_12AB34\",\"bucket_name\":\"dd-cost-bucket\",\"export_dataset_name\":\"billing\",\"export_prefix\":\"datadog_cloud_cost_usage_export\",\"export_project_name\":\"dd-cloud-cost-report\",\"service_account\":\"InvalidServiceAccount\"},\"type\":\"gcp_uc_config_post_request\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "post", + "uri": "https://api.datadoghq.com/api/v2/cost/gcp_uc_config" + }, + "response": { + "body": { + "string": "{\"errors\":[{\"title\":\"Generic Error\",\"detail\":\"not a valid service_account\"}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 400, + "message": "Bad Request" + } + }, + "recorded_at": "Mon, 23 Jun 2025 13:03:22 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/cloud_cost_management/Create-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-OK-response.frozen b/tests/scenarios/cassettes/v2/cloud_cost_management/Create-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-OK-response.frozen new file mode 100644 index 000000000..8357906fb --- /dev/null +++ b/tests/scenarios/cassettes/v2/cloud_cost_management/Create-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-OK-response.frozen @@ -0,0 +1 @@ +2025-06-16T17:46:53.205Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/cloud_cost_management/Create-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-OK-response.json b/tests/scenarios/cassettes/v2/cloud_cost_management/Create-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-OK-response.json new file mode 100644 index 000000000..ca0ee6340 --- /dev/null +++ b/tests/scenarios/cassettes/v2/cloud_cost_management/Create-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-OK-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":{\"attributes\":{\"billing_account_id\":\"123456_A123BC_12AB34\",\"bucket_name\":\"dd-cost-bucket\",\"export_dataset_name\":\"billing\",\"export_prefix\":\"datadog_cloud_cost_usage_export\",\"export_project_name\":\"dd-cloud-cost-report\",\"service_account\":\"dd-ccm-gcp-integration@my-environment.iam.gserviceaccount.com\"},\"type\":\"gcp_uc_config_post_request\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "post", + "uri": "https://api.datadoghq.com/api/v2/cost/gcp_uc_config" + }, + "response": { + "body": { + "string": "{\"data\":{\"id\":\"0\",\"type\":\"gcp_uc_config\",\"attributes\":{\"account_id\":\"123456_A123BC_12AB34\",\"bucket_name\":\"dd-cost-bucket\",\"created_at\":\"2025-03-24T21:00:03.851717\",\"dataset\":\"billing\",\"error_messages\":null,\"export_prefix\":\"datadog_cloud_cost_usage_export\",\"export_project_name\":\"dd-cloud-cost-report\",\"months\":15,\"project_id\":\"\",\"service_account\":\"dd-ccm-gcp-integration@my-environment.iam.gserviceaccount.com\",\"status\":\"active\",\"status_updated_at\":\"2025-05-09T21:01:48.748281\",\"updated_at\":\"2025-03-24T21:00:03.851717\"}}}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 200, + "message": "OK" + } + }, + "recorded_at": "Mon, 16 Jun 2025 17:46:53 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.frozen b/tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.frozen new file mode 100644 index 000000000..b32e1196f --- /dev/null +++ b/tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.frozen @@ -0,0 +1 @@ +2025-06-23T12:26:40.200Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.json b/tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.json new file mode 100644 index 000000000..0a7fe29d5 --- /dev/null +++ b/tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.json @@ -0,0 +1,33 @@ +{ + "http_interactions": [ + { + "request": { + "body": "", + "headers": { + "Accept": [ + "*/*" + ] + }, + "method": "delete", + "uri": "https://api.datadoghq.com/api/v2/cost/gcp_uc_config/Invalid" + }, + "response": { + "body": { + "string": "{\"errors\":[{\"status\":\"400\",\"title\":\"Invalid Parameter\",\"detail\":\"invalid parameter \\\"cloudAccountId\\\" in \\\"path\\\"; expected type \\\"int64\\\"\"}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 400, + "message": "Bad Request" + } + }, + "recorded_at": "Mon, 23 Jun 2025 12:26:40 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-No-Content-response.frozen b/tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-No-Content-response.frozen new file mode 100644 index 000000000..ba2579ca7 --- /dev/null +++ b/tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-No-Content-response.frozen @@ -0,0 +1 @@ +2025-06-13T20:58:16.900Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-No-Content-response.json b/tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-No-Content-response.json new file mode 100644 index 000000000..ab86b3331 --- /dev/null +++ b/tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-No-Content-response.json @@ -0,0 +1,33 @@ +{ + "http_interactions": [ + { + "request": { + "body": "", + "headers": { + "Accept": [ + "*/*" + ] + }, + "method": "delete", + "uri": "https://api.datadoghq.com/api/v2/cost/gcp_uc_config/100" + }, + "response": { + "body": { + "string": "{\"errors\":[{\"status\":\"204\",\"title\":\"No Content\"}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 204, + "message": "No Content" + } + }, + "recorded_at": "Fri, 13 Jun 2025 20:58:16 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Not-Found-response.frozen b/tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Not-Found-response.frozen new file mode 100644 index 000000000..41c71ad9f --- /dev/null +++ b/tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Not-Found-response.frozen @@ -0,0 +1 @@ +2025-06-23T13:06:22.086Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Not-Found-response.json b/tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Not-Found-response.json new file mode 100644 index 000000000..b49cb9a07 --- /dev/null +++ b/tests/scenarios/cassettes/v2/cloud_cost_management/Delete-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Not-Found-response.json @@ -0,0 +1,33 @@ +{ + "http_interactions": [ + { + "request": { + "body": "", + "headers": { + "Accept": [ + "*/*" + ] + }, + "method": "delete", + "uri": "https://api.datadoghq.com/api/v2/cost/gcp_uc_config/123456" + }, + "response": { + "body": { + "string": "{\"errors\":[{\"status\":\"404\",\"title\":\"Not Found\"}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 404, + "message": "Not Found" + } + }, + "recorded_at": "Mon, 23 Jun 2025 13:06:22 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/cloud_cost_management/List-Cloud-Cost-Management-GCP-Usage-Cost-configs-returns-OK-response.frozen b/tests/scenarios/cassettes/v2/cloud_cost_management/List-Cloud-Cost-Management-GCP-Usage-Cost-configs-returns-OK-response.frozen new file mode 100644 index 000000000..c5381ec8d --- /dev/null +++ b/tests/scenarios/cassettes/v2/cloud_cost_management/List-Cloud-Cost-Management-GCP-Usage-Cost-configs-returns-OK-response.frozen @@ -0,0 +1 @@ +2025-06-23T13:07:11.537Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/cloud_cost_management/List-Cloud-Cost-Management-GCP-Usage-Cost-configs-returns-OK-response.json b/tests/scenarios/cassettes/v2/cloud_cost_management/List-Cloud-Cost-Management-GCP-Usage-Cost-configs-returns-OK-response.json new file mode 100644 index 000000000..a24d081e6 --- /dev/null +++ b/tests/scenarios/cassettes/v2/cloud_cost_management/List-Cloud-Cost-Management-GCP-Usage-Cost-configs-returns-OK-response.json @@ -0,0 +1,33 @@ +{ + "http_interactions": [ + { + "request": { + "body": "", + "headers": { + "Accept": [ + "application/json" + ] + }, + "method": "get", + "uri": "https://api.datadoghq.com/api/v2/cost/gcp_uc_config" + }, + "response": { + "body": { + "string": "{\"data\":[]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 200, + "message": "OK" + } + }, + "recorded_at": "Mon, 23 Jun 2025 13:07:11 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.frozen b/tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.frozen new file mode 100644 index 000000000..48069d8a5 --- /dev/null +++ b/tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.frozen @@ -0,0 +1 @@ +2025-06-23T12:09:03.300Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.json b/tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.json new file mode 100644 index 000000000..46eda76be --- /dev/null +++ b/tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Bad-Request-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":{\"attributes\":{\"is_enabled\":true},\"type\":\"gcp_uc_config_patch_request\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "patch", + "uri": "https://api.datadoghq.com/api/v2/cost/gcp_uc_config/InvalidValue" + }, + "response": { + "body": { + "string": "{\"errors\":[{\"status\":\"400\",\"title\":\"Invalid Parameter\",\"detail\":\"invalid parameter \\\"cloudAccountId\\\" in \\\"path\\\"; expected type \\\"int64\\\"\"}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 400, + "message": "Bad Request" + } + }, + "recorded_at": "Mon, 23 Jun 2025 12:09:03 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Not-Found-response.frozen b/tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Not-Found-response.frozen new file mode 100644 index 000000000..71ddab128 --- /dev/null +++ b/tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Not-Found-response.frozen @@ -0,0 +1 @@ +2025-06-23T12:09:42.232Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Not-Found-response.json b/tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Not-Found-response.json new file mode 100644 index 000000000..404e9014a --- /dev/null +++ b/tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-Not-Found-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":{\"attributes\":{\"is_enabled\":true},\"type\":\"gcp_uc_config_patch_request\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "patch", + "uri": "https://api.datadoghq.com/api/v2/cost/gcp_uc_config/12345678" + }, + "response": { + "body": { + "string": "{\"errors\":[{\"title\":\"Generic Error\",\"detail\":\"rpc error: code = NotFound desc = cloud account '\ufffd' not found\"}]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 404, + "message": "Not Found" + } + }, + "recorded_at": "Mon, 23 Jun 2025 12:09:42 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-OK-response.frozen b/tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-OK-response.frozen new file mode 100644 index 000000000..d3bcf48de --- /dev/null +++ b/tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-OK-response.frozen @@ -0,0 +1 @@ +2025-06-16T19:07:00.082Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-OK-response.json b/tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-OK-response.json new file mode 100644 index 000000000..d4582a163 --- /dev/null +++ b/tests/scenarios/cassettes/v2/cloud_cost_management/Update-Cloud-Cost-Management-GCP-Usage-Cost-config-returns-OK-response.json @@ -0,0 +1,39 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":{\"attributes\":{\"is_enabled\":true},\"type\":\"gcp_uc_config_patch_request\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "patch", + "uri": "https://api.datadoghq.com/api/v2/cost/gcp_uc_config/100" + }, + "response": { + "body": { + "string": "{\"data\":{\"id\":\"100\",\"type\":\"gcp_uc_config\",\"attributes\":{\"account_id\":\"123456_A123BC_12AB34\",\"bucket_name\":\"dd-cloud-cost-management\",\"created_at\":\"2024-04-29T13:10:37.514046\",\"dataset\":\"billing\",\"error_messages\":null,\"export_prefix\":\"datadog_cloud_cost\",\"export_project_name\":\"datadog-cloud-cost\",\"months\":15,\"project_id\":\"\",\"service_account\":\"test@datadoghq.com\",\"status\":\"active\",\"status_updated_at\":\"2025-06-14T00:50:28.556876\",\"updated_at\":\"2025-06-14T00:50:28.556873\"}}}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 200, + "message": "OK" + } + }, + "recorded_at": "Mon, 16 Jun 2025 19:07:00 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/features/v2/cloud_cost_management.feature b/tests/scenarios/features/v2/cloud_cost_management.feature index 4c3188510..dcd04d3b8 100644 --- a/tests/scenarios/features/v2/cloud_cost_management.feature +++ b/tests/scenarios/features/v2/cloud_cost_management.feature @@ -1,8 +1,8 @@ @endpoint(cloud-cost-management) @endpoint(cloud-cost-management-v2) Feature: Cloud Cost Management The Cloud Cost Management API allows you to set up, edit, and delete Cloud - Cost Management accounts for AWS and Azure. You can query your cost data - by using the [Metrics + Cost Management accounts for AWS, Azure, and GCP. You can query your cost + data by using the [Metrics endpoint](https://docs.datadoghq.com/api/latest/metrics/#query-timeseries- data-across-multiple-products) and the `cloud_cost` data source. For more information, see the [Cloud Cost Management @@ -43,6 +43,21 @@ Feature: Cloud Cost Management Then the response status is 200 OK And the response "data.attributes.configs[0].account_id" is equal to "1234abcd-1234-abcd-1234-1234abcd1234" + @team:Datadog/cloud-cost-management + Scenario: Create Cloud Cost Management GCP Usage Cost config returns "Bad Request" response + Given new "CreateCostGCPUsageCostConfig" request + And body with value {"data": {"attributes": {"billing_account_id": "123456_A123BC_12AB34", "bucket_name": "dd-cost-bucket", "export_dataset_name": "billing", "export_prefix": "datadog_cloud_cost_usage_export", "export_project_name": "dd-cloud-cost-report", "service_account": "InvalidServiceAccount"}, "type": "gcp_uc_config_post_request"}} + When the request is sent + Then the response status is 400 Bad Request + + @replay-only @team:Datadog/cloud-cost-management + Scenario: Create Cloud Cost Management GCP Usage Cost config returns "OK" response + Given new "CreateCostGCPUsageCostConfig" request + And body with value {"data": {"attributes": {"billing_account_id": "123456_A123BC_12AB34", "bucket_name": "dd-cost-bucket", "export_dataset_name": "billing", "export_prefix": "datadog_cloud_cost_usage_export", "export_project_name": "dd-cloud-cost-report", "service_account": "dd-ccm-gcp-integration@my-environment.iam.gserviceaccount.com"}, "type": "gcp_uc_config_post_request"}} + When the request is sent + Then the response status is 200 OK + And the response "data.attributes.account_id" is equal to "123456_A123BC_12AB34" + @generated @skip @team:Datadog/cloud-cost-management Scenario: Create or update a budget returns "Bad Request" response Given new "UpsertBudget" request @@ -106,6 +121,27 @@ Feature: Cloud Cost Management When the request is sent Then the response status is 404 Not Found + @team:Datadog/cloud-cost-management + Scenario: Delete Cloud Cost Management GCP Usage Cost config returns "Bad Request" response + Given new "DeleteCostGCPUsageCostConfig" request + And request contains "cloud_account_id" parameter with value "Invalid" + When the request is sent + Then the response status is 400 Bad Request + + @replay-only @team:Datadog/cloud-cost-management + Scenario: Delete Cloud Cost Management GCP Usage Cost config returns "No Content" response + Given new "DeleteCostGCPUsageCostConfig" request + And request contains "cloud_account_id" parameter with value "100" + When the request is sent + Then the response status is 204 No Content + + @team:Datadog/cloud-cost-management + Scenario: Delete Cloud Cost Management GCP Usage Cost config returns "Not Found" response + Given new "DeleteCostGCPUsageCostConfig" request + And request contains "cloud_account_id" parameter with value "123456" + When the request is sent + Then the response status is 404 Not Found + @replay-only @team:Datadog/cloud-cost-management Scenario: Delete Custom Costs File returns "No Content" response Given new "DeleteCustomCostsFile" request @@ -185,6 +221,12 @@ Feature: Cloud Cost Management Then the response status is 200 OK And the response "data[0].attributes.configs[0].export_name" is equal to "test_export_name" + @team:Datadog/cloud-cost-management + Scenario: List Cloud Cost Management GCP Usage Cost configs returns "OK" response + Given new "ListCostGCPUsageCostConfigs" request + When the request is sent + Then the response status is 200 OK + @replay-only @team:Datadog/cloud-cost-management Scenario: List Custom Costs Files returns "OK" response Given new "ListCustomCostsFiles" request @@ -230,6 +272,31 @@ Feature: Cloud Cost Management Then the response status is 200 OK And the response "data.type" is equal to "azure_uc_configs" + @team:Datadog/cloud-cost-management + Scenario: Update Cloud Cost Management GCP Usage Cost config returns "Bad Request" response + Given new "UpdateCostGCPUsageCostConfig" request + And request contains "cloud_account_id" parameter with value "InvalidValue" + And body with value {"data": {"attributes": {"is_enabled": true}, "type": "gcp_uc_config_patch_request"}} + When the request is sent + Then the response status is 400 Bad Request + + @team:Datadog/cloud-cost-management + Scenario: Update Cloud Cost Management GCP Usage Cost config returns "Not Found" response + Given new "UpdateCostGCPUsageCostConfig" request + And request contains "cloud_account_id" parameter with value "12345678" + And body with value {"data": {"attributes": {"is_enabled": true}, "type": "gcp_uc_config_patch_request"}} + When the request is sent + Then the response status is 404 Not Found + + @replay-only @team:Datadog/cloud-cost-management + Scenario: Update Cloud Cost Management GCP Usage Cost config returns "OK" response + Given new "UpdateCostGCPUsageCostConfig" request + And request contains "cloud_account_id" parameter with value "100" + And body with value {"data": {"attributes": {"is_enabled": true}, "type": "gcp_uc_config_patch_request"}} + When the request is sent + Then the response status is 200 OK + And the response "data.attributes.account_id" is equal to "123456_A123BC_12AB34" + @replay-only @team:Datadog/cloud-cost-management Scenario: Upload Custom Costs File returns "Accepted" response Given new "UploadCustomCostsFile" request diff --git a/tests/scenarios/features/v2/undo.json b/tests/scenarios/features/v2/undo.json index 94da85dc2..a67059cda 100644 --- a/tests/scenarios/features/v2/undo.json +++ b/tests/scenarios/features/v2/undo.json @@ -730,6 +730,30 @@ "type": "safe" } }, + "ListCostGCPUsageCostConfigs": { + "tag": "Cloud Cost Management", + "undo": { + "type": "safe" + } + }, + "CreateCostGCPUsageCostConfig": { + "tag": "Cloud Cost Management", + "undo": { + "type": "idempotent" + } + }, + "DeleteCostGCPUsageCostConfig": { + "tag": "Cloud Cost Management", + "undo": { + "type": "idempotent" + } + }, + "UpdateCostGCPUsageCostConfig": { + "tag": "Cloud Cost Management", + "undo": { + "type": "idempotent" + } + }, "GetActiveBillingDimensions": { "tag": "Usage Metering", "undo": { diff --git a/tests/scenarios/function_mappings.rs b/tests/scenarios/function_mappings.rs index 0294f34cf..79e44f3c8 100644 --- a/tests/scenarios/function_mappings.rs +++ b/tests/scenarios/function_mappings.rs @@ -2343,6 +2343,22 @@ pub fn collect_function_calls(world: &mut DatadogWorld) { "v2.GetCustomCostsFile".into(), test_v2_get_custom_costs_file, ); + world.function_mappings.insert( + "v2.ListCostGCPUsageCostConfigs".into(), + test_v2_list_cost_gcp_usage_cost_configs, + ); + world.function_mappings.insert( + "v2.CreateCostGCPUsageCostConfig".into(), + test_v2_create_cost_gcp_usage_cost_config, + ); + world.function_mappings.insert( + "v2.DeleteCostGCPUsageCostConfig".into(), + test_v2_delete_cost_gcp_usage_cost_config, + ); + world.function_mappings.insert( + "v2.UpdateCostGCPUsageCostConfig".into(), + test_v2_update_cost_gcp_usage_cost_config, + ); world.function_mappings.insert( "v2.GetActiveBillingDimensions".into(), test_v2_get_active_billing_dimensions, @@ -16913,6 +16929,123 @@ fn test_v2_get_custom_costs_file(world: &mut DatadogWorld, _parameters: &HashMap world.response.code = response.status.as_u16(); } +fn test_v2_list_cost_gcp_usage_cost_configs( + world: &mut DatadogWorld, + _parameters: &HashMap, +) { + let api = world + .api_instances + .v2_api_cloud_cost_management + .as_ref() + .expect("api instance not found"); + let response = match block_on(api.list_cost_gcp_usage_cost_configs_with_http_info()) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + +fn test_v2_create_cost_gcp_usage_cost_config( + world: &mut DatadogWorld, + _parameters: &HashMap, +) { + let api = world + .api_instances + .v2_api_cloud_cost_management + .as_ref() + .expect("api instance not found"); + let body = serde_json::from_value(_parameters.get("body").unwrap().clone()).unwrap(); + let response = match block_on(api.create_cost_gcp_usage_cost_config_with_http_info(body)) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + +fn test_v2_delete_cost_gcp_usage_cost_config( + world: &mut DatadogWorld, + _parameters: &HashMap, +) { + let api = world + .api_instances + .v2_api_cloud_cost_management + .as_ref() + .expect("api instance not found"); + let cloud_account_id = + serde_json::from_value(_parameters.get("cloud_account_id").unwrap().clone()).unwrap(); + let response = + match block_on(api.delete_cost_gcp_usage_cost_config_with_http_info(cloud_account_id)) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + +fn test_v2_update_cost_gcp_usage_cost_config( + world: &mut DatadogWorld, + _parameters: &HashMap, +) { + let api = world + .api_instances + .v2_api_cloud_cost_management + .as_ref() + .expect("api instance not found"); + let cloud_account_id = + serde_json::from_value(_parameters.get("cloud_account_id").unwrap().clone()).unwrap(); + let body = serde_json::from_value(_parameters.get("body").unwrap().clone()).unwrap(); + let response = match block_on( + api.update_cost_gcp_usage_cost_config_with_http_info(cloud_account_id, body), + ) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + fn test_v2_get_active_billing_dimensions( world: &mut DatadogWorld, _parameters: &HashMap,