diff --git a/.apigentools-info b/.apigentools-info index 29553c60f..99f6d1df5 100644 --- a/.apigentools-info +++ b/.apigentools-info @@ -4,13 +4,13 @@ "spec_versions": { "v1": { "apigentools_version": "1.6.6", - "regenerated": "2025-06-06 17:43:35.331372", - "spec_repo_commit": "01341d5b" + "regenerated": "2025-06-09 17:01:31.482218", + "spec_repo_commit": "53d58e94" }, "v2": { "apigentools_version": "1.6.6", - "regenerated": "2025-06-06 17:43:35.348469", - "spec_repo_commit": "01341d5b" + "regenerated": "2025-06-09 17:01:31.498759", + "spec_repo_commit": "53d58e94" } } } \ No newline at end of file diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index d093ae5ab..44d36947a 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -15857,6 +15857,221 @@ 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. + format: int64 + type: integer + 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 + 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_usage_cost_config_patch_request + description: Type of GCP Usage Cost config patch request. + enum: + - gcp_usage_cost_config_patch_request + example: gcp_usage_cost_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: + 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 + dataset: + 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 + is_enabled: + description: Whether or not the Cloud Cost Management account is enabled. + type: boolean + months: + description: The month of the report. + format: int32 + maximum: 36 + type: integer + service_account: + description: The unique GCP service account email. + example: dd-ccm-gcp-integration@my-environment.iam.gserviceaccount.com + type: string + required: + - account_id + - bucket_name + - dataset + - export_prefix + - export_project_name + - service_account + type: object + GCPUsageCostConfigPostRequestType: + default: gcp_usage_cost_config_post_request + description: Type of GCP Usage Cost config post request. + enum: + - gcp_usage_cost_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_usage_cost_config + description: Type of GCP Usage Cost config. + enum: + - gcp_usage_cost_config + example: gcp_usage_cost_config + type: string + x-enum-varnames: + - GCP_USAGE_COST_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: @@ -45328,6 +45543,152 @@ 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/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_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 @@ -62946,8 +63307,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..4a636d5c7 --- /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(), + "datadog_cloud_cost_usage_export".to_string(), + "dd-cloud-cost-report".to_string(), + "dd-ccm-gcp-integration@my-environment.iam.gserviceaccount.com".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..c0df1529b 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::GCPUsageCostConfigsResponse, + 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 9286041bb..2f53a5343 100644 --- a/src/datadogV2/model/mod.rs +++ b/src/datadogV2/model/mod.rs @@ -1228,6 +1228,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..c42020d76 --- /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: i64) -> 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..c8ab0f874 --- /dev/null +++ b/src/datadogV2/model/model_gcp_usage_cost_config_attributes.rs @@ -0,0 +1,281 @@ +// 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")] + 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: Vec) -> 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" => { + if v.is_null() { + continue; + } + 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..cfb80245f --- /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_usage_cost_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_usage_cost_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..827b792c4 --- /dev/null +++ b/src/datadogV2/model/model_gcp_usage_cost_config_post_request_attributes.rs @@ -0,0 +1,191 @@ +// 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 = "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 export dataset name used for the GCP Usage Cost report. + #[serde(rename = "dataset")] + pub dataset: String, + /// 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, + /// Whether or not the Cloud Cost Management account is enabled. + #[serde(rename = "is_enabled")] + pub is_enabled: Option, + /// The month of the report. + #[serde(rename = "months")] + pub months: Option, + /// 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( + account_id: String, + bucket_name: String, + dataset: String, + export_prefix: String, + export_project_name: String, + service_account: String, + ) -> GCPUsageCostConfigPostRequestAttributes { + GCPUsageCostConfigPostRequestAttributes { + account_id, + bucket_name, + dataset, + export_prefix, + export_project_name, + is_enabled: None, + months: None, + service_account, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn is_enabled(mut self, value: bool) -> Self { + self.is_enabled = Some(value); + self + } + + pub fn months(mut self, value: i32) -> Self { + self.months = 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 account_id: Option = None; + let mut bucket_name: Option = None; + let mut dataset: Option = None; + let mut export_prefix: Option = None; + let mut export_project_name: Option = None; + let mut is_enabled: Option = None; + let mut months: 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() { + "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)?); + } + "dataset" => { + dataset = 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)?); + } + "is_enabled" => { + if v.is_null() { + continue; + } + is_enabled = 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)?); + } + "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 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 content = GCPUsageCostConfigPostRequestAttributes { + account_id, + bucket_name, + dataset, + export_prefix, + export_project_name, + is_enabled, + months, + 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..67d88bf21 --- /dev/null +++ b/src/datadogV2/model/model_gcp_usage_cost_config_post_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 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_usage_cost_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_usage_cost_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..2cbd4e803 --- /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_USAGE_COST_CONFIG, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for GCPUsageCostConfigType { + fn to_string(&self) -> String { + match self { + Self::GCP_USAGE_COST_CONFIG => String::from("gcp_usage_cost_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_usage_cost_config" => Self::GCP_USAGE_COST_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/features/v2/cloud_cost_management.feature b/tests/scenarios/features/v2/cloud_cost_management.feature index 4c3188510..4d94a3f2a 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 @@ -20,7 +20,7 @@ Feature: Cloud Cost Management When the request is sent Then the response status is 400 Bad Request - @replay-only @team:Datadog/cloud-cost-management + @team:Datadog/cloud-cost-management Scenario: Create Cloud Cost Management AWS CUR config returns "OK" response Given new "CreateCostAWSCURConfig" request And body with value {"data": {"attributes": {"account_id": "123456789123", "bucket_name": "dd-cost-bucket", "bucket_region": "us-east-1", "report_name": "dd-report-name", "report_prefix": "dd-report-prefix"}, "type": "aws_cur_config_post_request"}} @@ -35,7 +35,7 @@ Feature: Cloud Cost Management When the request is sent Then the response status is 400 Bad Request - @replay-only @team:Datadog/cloud-cost-management + @team:Datadog/cloud-cost-management Scenario: Create Cloud Cost Management Azure configs returns "OK" response Given new "CreateCostAzureUCConfigs" request And body with value {"data": {"attributes": {"account_id": "1234abcd-1234-abcd-1234-1234abcd1234", "actual_bill_config": {"export_name": "dd-actual-export", "export_path": "dd-export-path", "storage_account": "dd-storage-account", "storage_container": "dd-storage-container"}, "amortized_bill_config": {"export_name": "dd-actual-export", "export_path": "dd-export-path", "storage_account": "dd-storage-account", "storage_container": "dd-storage-container"}, "client_id": "1234abcd-1234-abcd-1234-1234abcd1234", "is_enabled": true, "scope": "subscriptions/1234abcd-1234-abcd-1234-1234abcd1234"}, "type": "azure_uc_config_post_request"}} @@ -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" + @generated @skip @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": {"account_id": "123456_A123BC_12AB34", "bucket_name": "dd-cost-bucket", "dataset": "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_usage_cost_config_post_request"}} + When the request is sent + Then the response status is 400 Bad Request + + @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": {"account_id": "123456_A123BC_12AB34", "bucket_name": "dd-cost-bucket", "dataset": "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_usage_cost_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 @@ -71,7 +86,7 @@ Feature: Cloud Cost Management When the request is sent Then the response status is 400 Bad Request - @replay-only @team:Datadog/cloud-cost-management + @team:Datadog/cloud-cost-management Scenario: Delete Cloud Cost Management AWS CUR config returns "No Content" response Given new "DeleteCostAWSCURConfig" request And request contains "cloud_account_id" parameter with value "100" @@ -92,7 +107,7 @@ Feature: Cloud Cost Management When the request is sent Then the response status is 400 Bad Request - @replay-only @team:Datadog/cloud-cost-management + @team:Datadog/cloud-cost-management Scenario: Delete Cloud Cost Management Azure config returns "No Content" response Given new "DeleteCostAzureUCConfig" request And request contains "cloud_account_id" parameter with value "100" @@ -106,7 +121,28 @@ Feature: Cloud Cost Management When the request is sent Then the response status is 404 Not Found - @replay-only @team:Datadog/cloud-cost-management + @generated @skip @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 from "REPLACE.ME" + When the request is sent + Then the response status is 400 Bad Request + + @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 + + @generated @skip @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 from "REPLACE.ME" + When the request is sent + Then the response status is 404 Not Found + + @team:Datadog/cloud-cost-management Scenario: Delete Custom Costs File returns "No Content" response Given new "DeleteCustomCostsFile" request And request contains "file_id" parameter with value "9d055d22-a838-4e9f-bc34-a4f9ab66280c" @@ -134,7 +170,7 @@ Feature: Cloud Cost Management When the request is sent Then the response status is 204 No Content - @replay-only @team:Datadog/cloud-cost-management + @team:Datadog/cloud-cost-management Scenario: Get Custom Costs File returns "OK" response Given new "GetCustomCostsFile" request And request contains "file_id" parameter with value "9d055d22-a838-4e9f-bc34-a4f9ab66280c" @@ -171,21 +207,28 @@ Feature: Cloud Cost Management When the request is sent Then the response status is 200 OK - @replay-only @team:Datadog/cloud-cost-management + @team:Datadog/cloud-cost-management Scenario: List Cloud Cost Management AWS CUR configs returns "OK" response Given new "ListCostAWSCURConfigs" request When the request is sent Then the response status is 200 OK And the response "data[0].attributes.bucket_name" is equal to "test_bucket_name" - @replay-only @team:Datadog/cloud-cost-management + @team:Datadog/cloud-cost-management Scenario: List Cloud Cost Management Azure configs returns "OK" response Given new "ListCostAzureUCConfigs" request When the request is sent Then the response status is 200 OK And the response "data[0].attributes.configs[0].export_name" is equal to "test_export_name" - @replay-only @team:Datadog/cloud-cost-management + @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 + And the response "data[0].attributes.bucket_name" is equal to "test_bucket_name" + + @team:Datadog/cloud-cost-management Scenario: List Custom Costs Files returns "OK" response Given new "ListCustomCostsFiles" request When the request is sent @@ -204,7 +247,7 @@ Feature: Cloud Cost Management When the request is sent Then the response status is 200 OK - @replay-only @team:Datadog/cloud-cost-management + @team:Datadog/cloud-cost-management Scenario: Update Cloud Cost Management AWS CUR config returns "OK" response Given new "UpdateCostAWSCURConfig" request And request contains "cloud_account_id" parameter with value "100" @@ -221,7 +264,7 @@ Feature: Cloud Cost Management When the request is sent Then the response status is 400 Bad Request - @replay-only @team:Datadog/cloud-cost-management + @team:Datadog/cloud-cost-management Scenario: Update Cloud Cost Management Azure config returns "OK" response Given new "UpdateCostAzureUCConfigs" request And request contains "cloud_account_id" parameter with value "100" @@ -230,7 +273,16 @@ Feature: Cloud Cost Management Then the response status is 200 OK And the response "data.type" is equal to "azure_uc_configs" - @replay-only @team:Datadog/cloud-cost-management + @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_usage_cost_config_patch_request"}} + When the request is sent + Then the response status is 200 OK + And the response "data[0].attributes.account_id" is equal to "123456_A123BC_12AB34" + + @team:Datadog/cloud-cost-management Scenario: Upload Custom Costs File returns "Accepted" response Given new "UploadCustomCostsFile" request And body with value [{ "ProviderName": "my_provider", "ChargePeriodStart": "2023-05-06", "ChargePeriodEnd": "2023-06-06","ChargeDescription": "my_description","BilledCost": 250,"BillingCurrency": "USD","Tags": {"key": "value"}}] diff --git a/tests/scenarios/features/v2/undo.json b/tests/scenarios/features/v2/undo.json index 2d33b5cd7..13b52893c 100644 --- a/tests/scenarios/features/v2/undo.json +++ b/tests/scenarios/features/v2/undo.json @@ -706,6 +706,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 8d09a4da2..d43a2fe39 100644 --- a/tests/scenarios/function_mappings.rs +++ b/tests/scenarios/function_mappings.rs @@ -2329,6 +2329,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, @@ -16740,6 +16756,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,