diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 3bd4dc490..01713f0b6 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -18173,6 +18173,25 @@ components: - tag_key - updated_at type: object + CostTagDescriptionResponse: + description: Single Cloud Cost Management tag key description returned by the get-by-key endpoint. + example: + data: + attributes: + cloud: aws + created_at: "2026-01-01T12:00:00Z" + description: AWS account that owns this cost. + source: human + tag_key: account_id + updated_at: "2026-01-01T12:00:00Z" + id: account_id + type: cost_tag_description + properties: + data: + $ref: "#/components/schemas/CostTagDescription" + required: + - data + type: object CostTagDescriptionSource: description: Origin of the description. `human` indicates the description was written by a user, `ai_generated` was produced by AI, and `datadog` is a default supplied by Datadog. enum: @@ -18194,6 +18213,50 @@ components: type: string x-enum-varnames: - COST_TAG_DESCRIPTION + CostTagDescriptionUpsertRequest: + description: Request body for creating or updating a Cloud Cost Management tag key description. + example: + data: + attributes: + cloud: aws + description: AWS account that owns this cost. + id: account_id + type: cost_tag_description + properties: + data: + $ref: "#/components/schemas/CostTagDescriptionUpsertRequestData" + required: + - data + type: object + CostTagDescriptionUpsertRequestData: + description: Resource envelope carrying the tag key description being upserted. The `id` is informational; the authoritative tag key is taken from the URL path. + properties: + attributes: + $ref: "#/components/schemas/CostTagDescriptionUpsertRequestDataAttributes" + id: + description: Identifier of the tag key the description applies to. Matches the `tag_key` path parameter. + example: account_id + type: string + type: + $ref: "#/components/schemas/CostTagDescriptionType" + required: + - attributes + - type + type: object + CostTagDescriptionUpsertRequestDataAttributes: + description: Mutable attributes set when creating or updating a Cloud Cost Management tag key description. + properties: + cloud: + description: Cloud provider this description applies to (for example, `aws`). Omit to set the cross-cloud default for the tag key. + example: aws + type: string + description: + description: The human-readable description for the tag key. + example: AWS account that owns this cost. + type: string + required: + - description + type: object CostTagDescriptionsResponse: description: List of Cloud Cost Management tag key descriptions for the organization, optionally filtered to a single cloud provider. example: @@ -34119,6 +34182,55 @@ components: required: - type type: object + GenerateCostTagDescriptionResponse: + description: Response wrapping an AI-generated Cloud Cost Management tag key description. + example: + data: + attributes: + description: AWS account that owns this cost. + id: account_id + type: cost_generated_tag_description + properties: + data: + $ref: "#/components/schemas/GeneratedCostTagDescription" + required: + - data + type: object + GeneratedCostTagDescription: + description: AI-generated Cloud Cost Management tag key description returned by the generate endpoint. The result is returned to the client but is not persisted by this endpoint. + properties: + attributes: + $ref: "#/components/schemas/GeneratedCostTagDescriptionAttributes" + id: + description: The tag key the AI description was generated for. + example: account_id + type: string + type: + $ref: "#/components/schemas/GeneratedCostTagDescriptionType" + required: + - attributes + - id + - type + type: object + GeneratedCostTagDescriptionAttributes: + description: Attributes of an AI-generated Cloud Cost Management tag key description. + properties: + description: + description: The AI-generated description for the tag key. + example: AWS account that owns this cost. + type: string + required: + - description + type: object + GeneratedCostTagDescriptionType: + default: cost_generated_tag_description + description: Type of the AI-generated Cloud Cost Management tag description resource. + enum: + - cost_generated_tag_description + example: cost_generated_tag_description + type: string + x-enum-varnames: + - COST_GENERATED_TAG_DESCRIPTION GetActionConnectionResponse: description: The response for found connection properties: @@ -108672,6 +108784,226 @@ paths: operator: OR permissions: - cloud_cost_management_read + /api/v2/cost/tag_descriptions/{tag_key}: + delete: + description: Delete a Cloud Cost Management tag key description. When `cloud` is omitted, deletes every description for the tag key, falling back to Datadog's global default when available. When `cloud` is provided, deletes only the description scoped to that cloud provider. + operationId: DeleteCostTagDescriptionByKey + parameters: + - description: The tag key whose description is being deleted. + in: path + name: tag_key + required: true + schema: + type: string + - description: Cloud provider to scope the deletion to (for example, `aws`). Omit to delete every description for the tag key. + in: query + name: cloud + required: false + schema: + type: string + responses: + "204": + description: No Content + "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: Delete a Cloud Cost Management tag description + tags: + - Cloud Cost Management + "x-permission": + operator: OR + permissions: + - cloud_cost_management_write + get: + description: Get the Cloud Cost Management description for a single tag key. Use `filter[cloud]` to scope the lookup to a specific cloud provider; when omitted, the response resolves the description in fallback order (cloud-specific organization override, then cloudless organization default, then Datadog's global default). + operationId: GetCostTagDescriptionByKey + parameters: + - description: The tag key whose description is being fetched. + in: path + name: tag_key + required: true + schema: + type: string + - description: Cloud provider to scope the lookup to (for example, `aws`). Omit to use the resolved fallback. + in: query + name: filter[cloud] + required: false + schema: + type: string + responses: + "200": + content: + application/json: + examples: + default: + value: + data: + attributes: + cloud: aws + created_at: "2026-01-01T12:00:00Z" + description: AWS account that owns this cost. + source: human + tag_key: account_id + updated_at: "2026-01-01T12:00:00Z" + id: account_id + type: cost_tag_description + schema: + $ref: "#/components/schemas/CostTagDescriptionResponse" + description: OK + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/APIErrorResponse" + description: Bad Request + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/APIErrorResponse" + description: Forbidden + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/APIErrorResponse" + description: Not Found + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - cloud_cost_management_read + summary: Get a Cloud Cost Management tag description + tags: + - Cloud Cost Management + "x-permission": + operator: OR + permissions: + - cloud_cost_management_read + put: + description: Create or update a Cloud Cost Management tag key description. The new description and optional cloud scoping are supplied in the request body. Omit `cloud` to set a cross-cloud default for the tag key. + operationId: UpsertCostTagDescriptionByKey + parameters: + - description: The tag key whose description is being upserted. + in: path + name: tag_key + required: true + schema: + type: string + requestBody: + content: + application/json: + examples: + default: + value: + data: + attributes: + cloud: aws + description: AWS account that owns this cost. + id: account_id + type: cost_tag_description + schema: + $ref: "#/components/schemas/CostTagDescriptionUpsertRequest" + required: true + responses: + "204": + description: No Content + "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: Upsert a Cloud Cost Management tag description + tags: + - Cloud Cost Management + "x-permission": + operator: OR + permissions: + - cloud_cost_management_write + /api/v2/cost/tag_descriptions/{tag_key}/generate: + get: + description: Use AI to draft a Cloud Cost Management tag key description based on associated cost data. The generated description is returned in the response and is not persisted by this endpoint; follow up with `UpsertCostTagDescriptionByKey` to save it. + operationId: GenerateCostTagDescriptionByKey + parameters: + - description: The tag key to generate an AI description for. + in: path + name: tag_key + required: true + schema: + type: string + responses: + "200": + content: + application/json: + examples: + default: + value: + data: + attributes: + description: AWS account that owns this cost. + id: account_id + type: cost_generated_tag_description + schema: + $ref: "#/components/schemas/GenerateCostTagDescriptionResponse" + 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_read + summary: Generate a Cloud Cost Management tag description + tags: + - Cloud Cost Management + "x-permission": + operator: OR + permissions: + - cloud_cost_management_read /api/v2/cost/tag_keys: get: description: List Cloud Cost Management tag keys. diff --git a/examples/v2_cloud-cost-management_DeleteCostTagDescriptionByKey.rs b/examples/v2_cloud-cost-management_DeleteCostTagDescriptionByKey.rs new file mode 100644 index 000000000..fea271b00 --- /dev/null +++ b/examples/v2_cloud-cost-management_DeleteCostTagDescriptionByKey.rs @@ -0,0 +1,21 @@ +// Delete a Cloud Cost Management tag description returns "No Content" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_cloud_cost_management::CloudCostManagementAPI; +use datadog_api_client::datadogV2::api_cloud_cost_management::DeleteCostTagDescriptionByKeyOptionalParams; + +#[tokio::main] +async fn main() { + let configuration = datadog::Configuration::new(); + let api = CloudCostManagementAPI::with_config(configuration); + let resp = api + .delete_cost_tag_description_by_key( + "tag_key".to_string(), + DeleteCostTagDescriptionByKeyOptionalParams::default(), + ) + .await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_cloud-cost-management_GenerateCostTagDescriptionByKey.rs b/examples/v2_cloud-cost-management_GenerateCostTagDescriptionByKey.rs new file mode 100644 index 000000000..52728ece0 --- /dev/null +++ b/examples/v2_cloud-cost-management_GenerateCostTagDescriptionByKey.rs @@ -0,0 +1,17 @@ +// Generate a Cloud Cost Management tag description 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 + .generate_cost_tag_description_by_key("tag_key".to_string()) + .await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_cloud-cost-management_GetCostTagDescriptionByKey.rs b/examples/v2_cloud-cost-management_GetCostTagDescriptionByKey.rs new file mode 100644 index 000000000..03a1a232a --- /dev/null +++ b/examples/v2_cloud-cost-management_GetCostTagDescriptionByKey.rs @@ -0,0 +1,21 @@ +// Get a Cloud Cost Management tag description returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_cloud_cost_management::CloudCostManagementAPI; +use datadog_api_client::datadogV2::api_cloud_cost_management::GetCostTagDescriptionByKeyOptionalParams; + +#[tokio::main] +async fn main() { + let configuration = datadog::Configuration::new(); + let api = CloudCostManagementAPI::with_config(configuration); + let resp = api + .get_cost_tag_description_by_key( + "tag_key".to_string(), + GetCostTagDescriptionByKeyOptionalParams::default(), + ) + .await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_cloud-cost-management_UpsertCostTagDescriptionByKey.rs b/examples/v2_cloud-cost-management_UpsertCostTagDescriptionByKey.rs new file mode 100644 index 000000000..49781b80d --- /dev/null +++ b/examples/v2_cloud-cost-management_UpsertCostTagDescriptionByKey.rs @@ -0,0 +1,31 @@ +// Upsert a Cloud Cost Management tag description returns "No Content" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_cloud_cost_management::CloudCostManagementAPI; +use datadog_api_client::datadogV2::model::CostTagDescriptionType; +use datadog_api_client::datadogV2::model::CostTagDescriptionUpsertRequest; +use datadog_api_client::datadogV2::model::CostTagDescriptionUpsertRequestData; +use datadog_api_client::datadogV2::model::CostTagDescriptionUpsertRequestDataAttributes; + +#[tokio::main] +async fn main() { + let body = CostTagDescriptionUpsertRequest::new( + CostTagDescriptionUpsertRequestData::new( + CostTagDescriptionUpsertRequestDataAttributes::new( + "AWS account that owns this cost.".to_string(), + ) + .cloud("aws".to_string()), + CostTagDescriptionType::COST_TAG_DESCRIPTION, + ) + .id("account_id".to_string()), + ); + let configuration = datadog::Configuration::new(); + let api = CloudCostManagementAPI::with_config(configuration); + let resp = api + .upsert_cost_tag_description_by_key("tag_key".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 02449cd05..c5619aac5 100644 --- a/src/datadogV2/api/api_cloud_cost_management.rs +++ b/src/datadogV2/api/api_cloud_cost_management.rs @@ -11,6 +11,22 @@ use reqwest::header::{HeaderMap, HeaderValue}; use serde::{Deserialize, Serialize}; use std::io::Write; +/// DeleteCostTagDescriptionByKeyOptionalParams is a struct for passing parameters to the method [`CloudCostManagementAPI::delete_cost_tag_description_by_key`] +#[non_exhaustive] +#[derive(Clone, Default, Debug)] +pub struct DeleteCostTagDescriptionByKeyOptionalParams { + /// Cloud provider to scope the deletion to (for example, `aws`). Omit to delete every description for the tag key. + pub cloud: Option, +} + +impl DeleteCostTagDescriptionByKeyOptionalParams { + /// Cloud provider to scope the deletion to (for example, `aws`). Omit to delete every description for the tag key. + pub fn cloud(mut self, value: String) -> Self { + self.cloud = Some(value); + self + } +} + /// GetCommitmentsCommitmentListOptionalParams is a struct for passing parameters to the method [`CloudCostManagementAPI::get_commitments_commitment_list`] #[non_exhaustive] #[derive(Clone, Default, Debug)] @@ -169,6 +185,22 @@ impl GetCommitmentsUtilizationTimeseriesOptionalParams { } } +/// GetCostTagDescriptionByKeyOptionalParams is a struct for passing parameters to the method [`CloudCostManagementAPI::get_cost_tag_description_by_key`] +#[non_exhaustive] +#[derive(Clone, Default, Debug)] +pub struct GetCostTagDescriptionByKeyOptionalParams { + /// Cloud provider to scope the lookup to (for example, `aws`). Omit to use the resolved fallback. + pub filter_cloud: Option, +} + +impl GetCostTagDescriptionByKeyOptionalParams { + /// Cloud provider to scope the lookup to (for example, `aws`). Omit to use the resolved fallback. + pub fn filter_cloud(mut self, value: String) -> Self { + self.filter_cloud = Some(value); + self + } +} + /// GetCostTagKeyOptionalParams is a struct for passing parameters to the method [`CloudCostManagementAPI::get_cost_tag_key`] #[non_exhaustive] #[derive(Clone, Default, Debug)] @@ -611,6 +643,14 @@ pub enum DeleteCostGCPUsageCostConfigError { UnknownValue(serde_json::Value), } +/// DeleteCostTagDescriptionByKeyError is a struct for typed errors of method [`CloudCostManagementAPI::delete_cost_tag_description_by_key`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum DeleteCostTagDescriptionByKeyError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// DeleteCustomAllocationRuleError is a struct for typed errors of method [`CloudCostManagementAPI::delete_custom_allocation_rule`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -635,6 +675,14 @@ pub enum DeleteTagPipelinesRulesetError { UnknownValue(serde_json::Value), } +/// GenerateCostTagDescriptionByKeyError is a struct for typed errors of method [`CloudCostManagementAPI::generate_cost_tag_description_by_key`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum GenerateCostTagDescriptionByKeyError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// GetBudgetError is a struct for typed errors of method [`CloudCostManagementAPI::get_budget`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -747,6 +795,14 @@ pub enum GetCostGCPUsageCostConfigError { UnknownValue(serde_json::Value), } +/// GetCostTagDescriptionByKeyError is a struct for typed errors of method [`CloudCostManagementAPI::get_cost_tag_description_by_key`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum GetCostTagDescriptionByKeyError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// GetCostTagKeyError is a struct for typed errors of method [`CloudCostManagementAPI::get_cost_tag_key`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -1011,6 +1067,14 @@ pub enum UpsertBudgetError { UnknownValue(serde_json::Value), } +/// UpsertCostTagDescriptionByKeyError is a struct for typed errors of method [`CloudCostManagementAPI::upsert_cost_tag_description_by_key`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum UpsertCostTagDescriptionByKeyError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// ValidateBudgetError is a struct for typed errors of method [`CloudCostManagementAPI::validate_budget`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -2271,6 +2335,108 @@ impl CloudCostManagementAPI { } } + /// Delete a Cloud Cost Management tag key description. When `cloud` is omitted, deletes every description for the tag key, falling back to Datadog's global default when available. When `cloud` is provided, deletes only the description scoped to that cloud provider. + pub async fn delete_cost_tag_description_by_key( + &self, + tag_key: String, + params: DeleteCostTagDescriptionByKeyOptionalParams, + ) -> Result<(), datadog::Error> { + match self + .delete_cost_tag_description_by_key_with_http_info(tag_key, params) + .await + { + Ok(_) => Ok(()), + Err(err) => Err(err), + } + } + + /// Delete a Cloud Cost Management tag key description. When `cloud` is omitted, deletes every description for the tag key, falling back to Datadog's global default when available. When `cloud` is provided, deletes only the description scoped to that cloud provider. + pub async fn delete_cost_tag_description_by_key_with_http_info( + &self, + tag_key: String, + params: DeleteCostTagDescriptionByKeyOptionalParams, + ) -> Result, datadog::Error> + { + let local_configuration = &self.config; + let operation_id = "v2.delete_cost_tag_description_by_key"; + + // unbox and build optional parameters + let cloud = params.cloud; + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/cost/tag_descriptions/{tag_key}", + local_configuration.get_operation_host(operation_id), + tag_key = datadog::urlencode(tag_key) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::DELETE, local_uri_str.as_str()); + + if let Some(ref local_query_param) = cloud { + local_req_builder = + local_req_builder.query(&[("cloud", &local_query_param.to_string())]); + }; + + // 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 a custom allocation rule - Delete an existing custom allocation rule by its ID pub async fn delete_custom_allocation_rule( &self, @@ -2541,6 +2707,118 @@ impl CloudCostManagementAPI { } } + /// Use AI to draft a Cloud Cost Management tag key description based on associated cost data. The generated description is returned in the response and is not persisted by this endpoint; follow up with `UpsertCostTagDescriptionByKey` to save it. + pub async fn generate_cost_tag_description_by_key( + &self, + tag_key: String, + ) -> Result< + crate::datadogV2::model::GenerateCostTagDescriptionResponse, + datadog::Error, + > { + match self + .generate_cost_tag_description_by_key_with_http_info(tag_key) + .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), + } + } + + /// Use AI to draft a Cloud Cost Management tag key description based on associated cost data. The generated description is returned in the response and is not persisted by this endpoint; follow up with `UpsertCostTagDescriptionByKey` to save it. + pub async fn generate_cost_tag_description_by_key_with_http_info( + &self, + tag_key: String, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.generate_cost_tag_description_by_key"; + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/cost/tag_descriptions/{tag_key}/generate", + local_configuration.get_operation_host(operation_id), + tag_key = datadog::urlencode(tag_key) + ); + 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)) + } + } + /// Get a budget pub async fn get_budget( &self, @@ -4239,6 +4517,128 @@ impl CloudCostManagementAPI { } } + /// Get the Cloud Cost Management description for a single tag key. Use `filter[cloud]` to scope the lookup to a specific cloud provider; when omitted, the response resolves the description in fallback order (cloud-specific organization override, then cloudless organization default, then Datadog's global default). + pub async fn get_cost_tag_description_by_key( + &self, + tag_key: String, + params: GetCostTagDescriptionByKeyOptionalParams, + ) -> Result< + crate::datadogV2::model::CostTagDescriptionResponse, + datadog::Error, + > { + match self + .get_cost_tag_description_by_key_with_http_info(tag_key, params) + .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), + } + } + + /// Get the Cloud Cost Management description for a single tag key. Use `filter[cloud]` to scope the lookup to a specific cloud provider; when omitted, the response resolves the description in fallback order (cloud-specific organization override, then cloudless organization default, then Datadog's global default). + pub async fn get_cost_tag_description_by_key_with_http_info( + &self, + tag_key: String, + params: GetCostTagDescriptionByKeyOptionalParams, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.get_cost_tag_description_by_key"; + + // unbox and build optional parameters + let filter_cloud = params.filter_cloud; + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/cost/tag_descriptions/{tag_key}", + local_configuration.get_operation_host(operation_id), + tag_key = datadog::urlencode(tag_key) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::GET, local_uri_str.as_str()); + + if let Some(ref local_query_param) = filter_cloud { + local_req_builder = + local_req_builder.query(&[("filter[cloud]", &local_query_param.to_string())]); + }; + + // 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)) + } + } + /// Get details for a specific Cloud Cost Management tag key, including example tag values and description. pub async fn get_cost_tag_key( &self, @@ -8603,6 +9003,147 @@ impl CloudCostManagementAPI { } } + /// Create or update a Cloud Cost Management tag key description. The new description and optional cloud scoping are supplied in the request body. Omit `cloud` to set a cross-cloud default for the tag key. + pub async fn upsert_cost_tag_description_by_key( + &self, + tag_key: String, + body: crate::datadogV2::model::CostTagDescriptionUpsertRequest, + ) -> Result<(), datadog::Error> { + match self + .upsert_cost_tag_description_by_key_with_http_info(tag_key, body) + .await + { + Ok(_) => Ok(()), + Err(err) => Err(err), + } + } + + /// Create or update a Cloud Cost Management tag key description. The new description and optional cloud scoping are supplied in the request body. Omit `cloud` to set a cross-cloud default for the tag key. + pub async fn upsert_cost_tag_description_by_key_with_http_info( + &self, + tag_key: String, + body: crate::datadogV2::model::CostTagDescriptionUpsertRequest, + ) -> Result, datadog::Error> + { + let local_configuration = &self.config; + let operation_id = "v2.upsert_cost_tag_description_by_key"; + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/cost/tag_descriptions/{tag_key}", + local_configuration.get_operation_host(operation_id), + tag_key = datadog::urlencode(tag_key) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::PUT, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Content-Type", HeaderValue::from_static("application/json")); + headers.insert("Accept", HeaderValue::from_static("*/*")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + // build body parameters + let output = Vec::new(); + let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter); + if body.serialize(&mut ser).is_ok() { + if let Some(content_encoding) = headers.get("Content-Encoding") { + match content_encoding.to_str().unwrap_or_default() { + "gzip" => { + let mut enc = GzEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "deflate" => { + let mut enc = ZlibEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + #[cfg(feature = "zstd")] + "zstd1" => { + let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap(); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + _ => { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + } else { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: None, + }) + } else { + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + /// Validate a budget configuration without creating or modifying it pub async fn validate_budget( &self, diff --git a/src/datadogV2/model/mod.rs b/src/datadogV2/model/mod.rs index 4f61da0e3..fcb18f6fc 100644 --- a/src/datadogV2/model/mod.rs +++ b/src/datadogV2/model/mod.rs @@ -2958,6 +2958,22 @@ pub mod model_cost_tag_description_source; pub use self::model_cost_tag_description_source::CostTagDescriptionSource; pub mod model_cost_tag_description_type; pub use self::model_cost_tag_description_type::CostTagDescriptionType; +pub mod model_cost_tag_description_response; +pub use self::model_cost_tag_description_response::CostTagDescriptionResponse; +pub mod model_cost_tag_description_upsert_request; +pub use self::model_cost_tag_description_upsert_request::CostTagDescriptionUpsertRequest; +pub mod model_cost_tag_description_upsert_request_data; +pub use self::model_cost_tag_description_upsert_request_data::CostTagDescriptionUpsertRequestData; +pub mod model_cost_tag_description_upsert_request_data_attributes; +pub use self::model_cost_tag_description_upsert_request_data_attributes::CostTagDescriptionUpsertRequestDataAttributes; +pub mod model_generate_cost_tag_description_response; +pub use self::model_generate_cost_tag_description_response::GenerateCostTagDescriptionResponse; +pub mod model_generated_cost_tag_description; +pub use self::model_generated_cost_tag_description::GeneratedCostTagDescription; +pub mod model_generated_cost_tag_description_attributes; +pub use self::model_generated_cost_tag_description_attributes::GeneratedCostTagDescriptionAttributes; +pub mod model_generated_cost_tag_description_type; +pub use self::model_generated_cost_tag_description_type::GeneratedCostTagDescriptionType; pub mod model_cost_tag_keys_response; pub use self::model_cost_tag_keys_response::CostTagKeysResponse; pub mod model_cost_tag_key; diff --git a/src/datadogV2/model/model_cost_tag_description_response.rs b/src/datadogV2/model/model_cost_tag_description_response.rs new file mode 100644 index 000000000..001349870 --- /dev/null +++ b/src/datadogV2/model/model_cost_tag_description_response.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}; + +/// Single Cloud Cost Management tag key description returned by the get-by-key endpoint. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct CostTagDescriptionResponse { + /// A Cloud Cost Management tag key description, either cross-cloud or scoped to a single cloud provider. + #[serde(rename = "data")] + pub data: crate::datadogV2::model::CostTagDescription, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl CostTagDescriptionResponse { + pub fn new(data: crate::datadogV2::model::CostTagDescription) -> CostTagDescriptionResponse { + CostTagDescriptionResponse { + 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 CostTagDescriptionResponse { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct CostTagDescriptionResponseVisitor; + impl<'a> Visitor<'a> for CostTagDescriptionResponseVisitor { + type Value = CostTagDescriptionResponse; + + 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 = CostTagDescriptionResponse { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(CostTagDescriptionResponseVisitor) + } +} diff --git a/src/datadogV2/model/model_cost_tag_description_upsert_request.rs b/src/datadogV2/model/model_cost_tag_description_upsert_request.rs new file mode 100644 index 000000000..804056c4f --- /dev/null +++ b/src/datadogV2/model/model_cost_tag_description_upsert_request.rs @@ -0,0 +1,95 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Request body for creating or updating a Cloud Cost Management tag key description. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct CostTagDescriptionUpsertRequest { + /// Resource envelope carrying the tag key description being upserted. The `id` is informational; the authoritative tag key is taken from the URL path. + #[serde(rename = "data")] + pub data: crate::datadogV2::model::CostTagDescriptionUpsertRequestData, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl CostTagDescriptionUpsertRequest { + pub fn new( + data: crate::datadogV2::model::CostTagDescriptionUpsertRequestData, + ) -> CostTagDescriptionUpsertRequest { + CostTagDescriptionUpsertRequest { + 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 CostTagDescriptionUpsertRequest { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct CostTagDescriptionUpsertRequestVisitor; + impl<'a> Visitor<'a> for CostTagDescriptionUpsertRequestVisitor { + type Value = CostTagDescriptionUpsertRequest; + + 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 = CostTagDescriptionUpsertRequest { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(CostTagDescriptionUpsertRequestVisitor) + } +} diff --git a/src/datadogV2/model/model_cost_tag_description_upsert_request_data.rs b/src/datadogV2/model/model_cost_tag_description_upsert_request_data.rs new file mode 100644 index 000000000..ba3d1ea36 --- /dev/null +++ b/src/datadogV2/model/model_cost_tag_description_upsert_request_data.rs @@ -0,0 +1,132 @@ +// 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}; + +/// Resource envelope carrying the tag key description being upserted. The `id` is informational; the authoritative tag key is taken from the URL path. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct CostTagDescriptionUpsertRequestData { + /// Mutable attributes set when creating or updating a Cloud Cost Management tag key description. + #[serde(rename = "attributes")] + pub attributes: crate::datadogV2::model::CostTagDescriptionUpsertRequestDataAttributes, + /// Identifier of the tag key the description applies to. Matches the `tag_key` path parameter. + #[serde(rename = "id")] + pub id: Option, + /// Type of the Cloud Cost Management tag description resource. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::CostTagDescriptionType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl CostTagDescriptionUpsertRequestData { + pub fn new( + attributes: crate::datadogV2::model::CostTagDescriptionUpsertRequestDataAttributes, + type_: crate::datadogV2::model::CostTagDescriptionType, + ) -> CostTagDescriptionUpsertRequestData { + CostTagDescriptionUpsertRequestData { + attributes, + id: None, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn id(mut self, value: String) -> Self { + self.id = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for CostTagDescriptionUpsertRequestData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct CostTagDescriptionUpsertRequestDataVisitor; + impl<'a> Visitor<'a> for CostTagDescriptionUpsertRequestDataVisitor { + type Value = CostTagDescriptionUpsertRequestData; + + 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::CostTagDescriptionUpsertRequestDataAttributes, + > = 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::CostTagDescriptionType::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 = CostTagDescriptionUpsertRequestData { + attributes, + id, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(CostTagDescriptionUpsertRequestDataVisitor) + } +} diff --git a/src/datadogV2/model/model_cost_tag_description_upsert_request_data_attributes.rs b/src/datadogV2/model/model_cost_tag_description_upsert_request_data_attributes.rs new file mode 100644 index 000000000..b1b185efc --- /dev/null +++ b/src/datadogV2/model/model_cost_tag_description_upsert_request_data_attributes.rs @@ -0,0 +1,111 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Mutable attributes set when creating or updating a Cloud Cost Management tag key description. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct CostTagDescriptionUpsertRequestDataAttributes { + /// Cloud provider this description applies to (for example, `aws`). Omit to set the cross-cloud default for the tag key. + #[serde(rename = "cloud")] + pub cloud: Option, + /// The human-readable description for the tag key. + #[serde(rename = "description")] + pub description: String, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl CostTagDescriptionUpsertRequestDataAttributes { + pub fn new(description: String) -> CostTagDescriptionUpsertRequestDataAttributes { + CostTagDescriptionUpsertRequestDataAttributes { + cloud: None, + description, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn cloud(mut self, value: String) -> Self { + self.cloud = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for CostTagDescriptionUpsertRequestDataAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct CostTagDescriptionUpsertRequestDataAttributesVisitor; + impl<'a> Visitor<'a> for CostTagDescriptionUpsertRequestDataAttributesVisitor { + type Value = CostTagDescriptionUpsertRequestDataAttributes; + + 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 cloud: Option = None; + let mut description: 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() { + "cloud" => { + if v.is_null() { + continue; + } + cloud = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "description" => { + description = + 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 description = + description.ok_or_else(|| M::Error::missing_field("description"))?; + + let content = CostTagDescriptionUpsertRequestDataAttributes { + cloud, + description, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(CostTagDescriptionUpsertRequestDataAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_generate_cost_tag_description_response.rs b/src/datadogV2/model/model_generate_cost_tag_description_response.rs new file mode 100644 index 000000000..0dda4514b --- /dev/null +++ b/src/datadogV2/model/model_generate_cost_tag_description_response.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}; + +/// Response wrapping an AI-generated Cloud Cost Management tag key description. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct GenerateCostTagDescriptionResponse { + /// AI-generated Cloud Cost Management tag key description returned by the generate endpoint. The result is returned to the client but is not persisted by this endpoint. + #[serde(rename = "data")] + pub data: crate::datadogV2::model::GeneratedCostTagDescription, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl GenerateCostTagDescriptionResponse { + pub fn new( + data: crate::datadogV2::model::GeneratedCostTagDescription, + ) -> GenerateCostTagDescriptionResponse { + GenerateCostTagDescriptionResponse { + 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 GenerateCostTagDescriptionResponse { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct GenerateCostTagDescriptionResponseVisitor; + impl<'a> Visitor<'a> for GenerateCostTagDescriptionResponseVisitor { + type Value = GenerateCostTagDescriptionResponse; + + 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 = GenerateCostTagDescriptionResponse { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(GenerateCostTagDescriptionResponseVisitor) + } +} diff --git a/src/datadogV2/model/model_generated_cost_tag_description.rs b/src/datadogV2/model/model_generated_cost_tag_description.rs new file mode 100644 index 000000000..59bfd56f1 --- /dev/null +++ b/src/datadogV2/model/model_generated_cost_tag_description.rs @@ -0,0 +1,127 @@ +// 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}; + +/// AI-generated Cloud Cost Management tag key description returned by the generate endpoint. The result is returned to the client but is not persisted by this endpoint. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct GeneratedCostTagDescription { + /// Attributes of an AI-generated Cloud Cost Management tag key description. + #[serde(rename = "attributes")] + pub attributes: crate::datadogV2::model::GeneratedCostTagDescriptionAttributes, + /// The tag key the AI description was generated for. + #[serde(rename = "id")] + pub id: String, + /// Type of the AI-generated Cloud Cost Management tag description resource. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::GeneratedCostTagDescriptionType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl GeneratedCostTagDescription { + pub fn new( + attributes: crate::datadogV2::model::GeneratedCostTagDescriptionAttributes, + id: String, + type_: crate::datadogV2::model::GeneratedCostTagDescriptionType, + ) -> GeneratedCostTagDescription { + GeneratedCostTagDescription { + attributes, + id, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for GeneratedCostTagDescription { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct GeneratedCostTagDescriptionVisitor; + impl<'a> Visitor<'a> for GeneratedCostTagDescriptionVisitor { + type Value = GeneratedCostTagDescription; + + 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::GeneratedCostTagDescriptionAttributes, + > = 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" => { + 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::GeneratedCostTagDescriptionType::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 id = id.ok_or_else(|| M::Error::missing_field("id"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = GeneratedCostTagDescription { + attributes, + id, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(GeneratedCostTagDescriptionVisitor) + } +} diff --git a/src/datadogV2/model/model_generated_cost_tag_description_attributes.rs b/src/datadogV2/model/model_generated_cost_tag_description_attributes.rs new file mode 100644 index 000000000..45bbf7362 --- /dev/null +++ b/src/datadogV2/model/model_generated_cost_tag_description_attributes.rs @@ -0,0 +1,94 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Attributes of an AI-generated Cloud Cost Management tag key description. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct GeneratedCostTagDescriptionAttributes { + /// The AI-generated description for the tag key. + #[serde(rename = "description")] + pub description: String, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl GeneratedCostTagDescriptionAttributes { + pub fn new(description: String) -> GeneratedCostTagDescriptionAttributes { + GeneratedCostTagDescriptionAttributes { + description, + 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 GeneratedCostTagDescriptionAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct GeneratedCostTagDescriptionAttributesVisitor; + impl<'a> Visitor<'a> for GeneratedCostTagDescriptionAttributesVisitor { + type Value = GeneratedCostTagDescriptionAttributes; + + 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 description: 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() { + "description" => { + description = + 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 description = + description.ok_or_else(|| M::Error::missing_field("description"))?; + + let content = GeneratedCostTagDescriptionAttributes { + description, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(GeneratedCostTagDescriptionAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_generated_cost_tag_description_type.rs b/src/datadogV2/model/model_generated_cost_tag_description_type.rs new file mode 100644 index 000000000..844d89541 --- /dev/null +++ b/src/datadogV2/model/model_generated_cost_tag_description_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 GeneratedCostTagDescriptionType { + COST_GENERATED_TAG_DESCRIPTION, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for GeneratedCostTagDescriptionType { + fn to_string(&self) -> String { + match self { + Self::COST_GENERATED_TAG_DESCRIPTION => String::from("cost_generated_tag_description"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for GeneratedCostTagDescriptionType { + 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 GeneratedCostTagDescriptionType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "cost_generated_tag_description" => Self::COST_GENERATED_TAG_DESCRIPTION, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/tests/scenarios/features/v2/cloud_cost_management.feature b/tests/scenarios/features/v2/cloud_cost_management.feature index 17779e459..8a8beef7c 100644 --- a/tests/scenarios/features/v2/cloud_cost_management.feature +++ b/tests/scenarios/features/v2/cloud_cost_management.feature @@ -190,6 +190,20 @@ Feature: Cloud Cost Management When the request is sent Then the response status is 404 Not Found + @generated @skip @team:DataDog/cloud-cost-management + Scenario: Delete a Cloud Cost Management tag description returns "Bad Request" response + Given new "DeleteCostTagDescriptionByKey" request + And request contains "tag_key" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:DataDog/cloud-cost-management + Scenario: Delete a Cloud Cost Management tag description returns "No Content" response + Given new "DeleteCostTagDescriptionByKey" request + And request contains "tag_key" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 204 No Content + @team:DataDog/cloud-cost-management Scenario: Delete a budget returns "Bad Request" response Given new "DeleteBudget" request @@ -218,6 +232,20 @@ Feature: Cloud Cost Management When the request is sent Then the response status is 204 No Content + @generated @skip @team:DataDog/cloud-cost-management + Scenario: Generate a Cloud Cost Management tag description returns "Bad Request" response + Given new "GenerateCostTagDescriptionByKey" request + And request contains "tag_key" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:DataDog/cloud-cost-management + Scenario: Generate a Cloud Cost Management tag description returns "OK" response + Given new "GenerateCostTagDescriptionByKey" request + And request contains "tag_key" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 200 OK + @replay-only @team:DataDog/cloud-cost-management Scenario: Get Custom Costs File returns "OK" response Given new "GetCustomCostsFile" request @@ -250,6 +278,27 @@ Feature: Cloud Cost Management And the response "data.type" is equal to "gcp_uc_config" And the response "data.attributes.account_id" is equal to "123456_ABCDEF_123ABC" + @generated @skip @team:DataDog/cloud-cost-management + Scenario: Get a Cloud Cost Management tag description returns "Bad Request" response + Given new "GetCostTagDescriptionByKey" request + And request contains "tag_key" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:DataDog/cloud-cost-management + Scenario: Get a Cloud Cost Management tag description returns "Not Found" response + Given new "GetCostTagDescriptionByKey" request + And request contains "tag_key" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 404 Not Found + + @generated @skip @team:DataDog/cloud-cost-management + Scenario: Get a Cloud Cost Management tag description returns "OK" response + Given new "GetCostTagDescriptionByKey" request + And request contains "tag_key" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 200 OK + @generated @skip @team:DataDog/cloud-cost-management Scenario: Get a Cloud Cost Management tag key returns "Bad Request" response Given new "GetCostTagKey" request @@ -857,6 +906,22 @@ Feature: Cloud Cost Management When the request is sent Then the response status is 400 Bad Request + @generated @skip @team:DataDog/cloud-cost-management + Scenario: Upsert a Cloud Cost Management tag description returns "Bad Request" response + Given new "UpsertCostTagDescriptionByKey" request + And request contains "tag_key" parameter from "REPLACE.ME" + And body with value {"data": {"attributes": {"cloud": "aws", "description": "AWS account that owns this cost."}, "id": "account_id", "type": "cost_tag_description"}} + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:DataDog/cloud-cost-management + Scenario: Upsert a Cloud Cost Management tag description returns "No Content" response + Given new "UpsertCostTagDescriptionByKey" request + And request contains "tag_key" parameter from "REPLACE.ME" + And body with value {"data": {"attributes": {"cloud": "aws", "description": "AWS account that owns this cost."}, "id": "account_id", "type": "cost_tag_description"}} + When the request is sent + Then the response status is 204 No Content + @generated @skip @team:DataDog/cloud-cost-management Scenario: Validate CSV budget returns "OK" response Given new "ValidateCsvBudget" request diff --git a/tests/scenarios/features/v2/undo.json b/tests/scenarios/features/v2/undo.json index c22b14729..5ef29b4d9 100644 --- a/tests/scenarios/features/v2/undo.json +++ b/tests/scenarios/features/v2/undo.json @@ -1868,6 +1868,30 @@ "type": "safe" } }, + "DeleteCostTagDescriptionByKey": { + "tag": "Cloud Cost Management", + "undo": { + "type": "idempotent" + } + }, + "GetCostTagDescriptionByKey": { + "tag": "Cloud Cost Management", + "undo": { + "type": "safe" + } + }, + "UpsertCostTagDescriptionByKey": { + "tag": "Cloud Cost Management", + "undo": { + "type": "idempotent" + } + }, + "GenerateCostTagDescriptionByKey": { + "tag": "Cloud Cost Management", + "undo": { + "type": "safe" + } + }, "ListCostTagKeys": { "tag": "Cloud Cost Management", "undo": { diff --git a/tests/scenarios/function_mappings.rs b/tests/scenarios/function_mappings.rs index 39ddb24b1..91ead71f5 100644 --- a/tests/scenarios/function_mappings.rs +++ b/tests/scenarios/function_mappings.rs @@ -3808,6 +3808,22 @@ pub fn collect_function_calls(world: &mut DatadogWorld) { "v2.ListCostTagDescriptions".into(), test_v2_list_cost_tag_descriptions, ); + world.function_mappings.insert( + "v2.DeleteCostTagDescriptionByKey".into(), + test_v2_delete_cost_tag_description_by_key, + ); + world.function_mappings.insert( + "v2.GetCostTagDescriptionByKey".into(), + test_v2_get_cost_tag_description_by_key, + ); + world.function_mappings.insert( + "v2.UpsertCostTagDescriptionByKey".into(), + test_v2_upsert_cost_tag_description_by_key, + ); + world.function_mappings.insert( + "v2.GenerateCostTagDescriptionByKey".into(), + test_v2_generate_cost_tag_description_by_key, + ); world .function_mappings .insert("v2.ListCostTagKeys".into(), test_v2_list_cost_tag_keys); @@ -28875,6 +28891,136 @@ fn test_v2_list_cost_tag_descriptions( world.response.code = response.status.as_u16(); } +fn test_v2_delete_cost_tag_description_by_key( + world: &mut DatadogWorld, + _parameters: &HashMap, +) { + let api = world + .api_instances + .v2_api_cloud_cost_management + .as_ref() + .expect("api instance not found"); + let tag_key = serde_json::from_value(_parameters.get("tag_key").unwrap().clone()).unwrap(); + let cloud = _parameters + .get("cloud") + .and_then(|param| Some(serde_json::from_value(param.clone()).unwrap())); + let mut params = + datadogV2::api_cloud_cost_management::DeleteCostTagDescriptionByKeyOptionalParams::default( + ); + params.cloud = cloud; + let response = + match block_on(api.delete_cost_tag_description_by_key_with_http_info(tag_key, params)) { + 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_cost_tag_description_by_key( + world: &mut DatadogWorld, + _parameters: &HashMap, +) { + let api = world + .api_instances + .v2_api_cloud_cost_management + .as_ref() + .expect("api instance not found"); + let tag_key = serde_json::from_value(_parameters.get("tag_key").unwrap().clone()).unwrap(); + let filter_cloud = _parameters + .get("filter[cloud]") + .and_then(|param| Some(serde_json::from_value(param.clone()).unwrap())); + let mut params = + datadogV2::api_cloud_cost_management::GetCostTagDescriptionByKeyOptionalParams::default(); + params.filter_cloud = filter_cloud; + let response = + match block_on(api.get_cost_tag_description_by_key_with_http_info(tag_key, params)) { + 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_upsert_cost_tag_description_by_key( + world: &mut DatadogWorld, + _parameters: &HashMap, +) { + let api = world + .api_instances + .v2_api_cloud_cost_management + .as_ref() + .expect("api instance not found"); + let tag_key = serde_json::from_value(_parameters.get("tag_key").unwrap().clone()).unwrap(); + let body = serde_json::from_value(_parameters.get("body").unwrap().clone()).unwrap(); + let response = + match block_on(api.upsert_cost_tag_description_by_key_with_http_info(tag_key, 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_generate_cost_tag_description_by_key( + world: &mut DatadogWorld, + _parameters: &HashMap, +) { + let api = world + .api_instances + .v2_api_cloud_cost_management + .as_ref() + .expect("api instance not found"); + let tag_key = serde_json::from_value(_parameters.get("tag_key").unwrap().clone()).unwrap(); + let response = match block_on(api.generate_cost_tag_description_by_key_with_http_info(tag_key)) + { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + fn test_v2_list_cost_tag_keys(world: &mut DatadogWorld, _parameters: &HashMap) { let api = world .api_instances