Skip to content

Commit db86089

Browse files
api-clients-generation-pipeline[bot]ci.datadog-api-spec
andauthored
Add GET endpoint for custom forecast (#1832)
Co-authored-by: ci.datadog-api-spec <packages@datadoghq.com>
1 parent a1af7f4 commit db86089

14 files changed

Lines changed: 458 additions & 73 deletions

.generator/schemas/v2/openapi.yaml

Lines changed: 86 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -70492,6 +70492,8 @@ components:
7049270492
$ref: "#/components/schemas/ObservabilityPipelineTagCardinalityLimitProcessorPerMetricLimit"
7049370493
maxItems: 100
7049470494
type: array
70495+
tracking_mode:
70496+
$ref: "#/components/schemas/ObservabilityPipelineTagCardinalityLimitProcessorTrackingMode"
7049570497
type:
7049670498
$ref: "#/components/schemas/ObservabilityPipelineTagCardinalityLimitProcessorType"
7049770499
value_limit:
@@ -70506,6 +70508,7 @@ components:
7050670508
- type
7050770509
- include
7050870510
- limit_exceeded_action
70511+
- tracking_mode
7050970512
- value_limit
7051070513
- enabled
7051170514
type: object
@@ -70520,6 +70523,16 @@ components:
7052070523
x-enum-varnames:
7052170524
- DROP_TAG
7052270525
- DROP_EVENT
70526+
ObservabilityPipelineTagCardinalityLimitProcessorOverrideType:
70527+
description: How the override is applied. `limit_override` enforces a custom limit; `excluded` omits the metric or tag from cardinality tracking.
70528+
enum:
70529+
- limit_override
70530+
- excluded
70531+
example: limit_override
70532+
type: string
70533+
x-enum-varnames:
70534+
- LIMIT_OVERRIDE
70535+
- EXCLUDED
7052370536
ObservabilityPipelineTagCardinalityLimitProcessorPerMetricLimit:
7052470537
description: A cardinality override applied to a specific metric.
7052570538
properties:
@@ -70529,65 +70542,63 @@ components:
7052970542
description: The name of the metric this override applies to.
7053070543
example: "system.cpu.user"
7053170544
type: string
70532-
mode:
70533-
$ref: "#/components/schemas/ObservabilityPipelineTagCardinalityLimitProcessorPerMetricMode"
70545+
override_type:
70546+
$ref: "#/components/schemas/ObservabilityPipelineTagCardinalityLimitProcessorOverrideType"
7053470547
per_tag_limits:
70535-
description: A list of per-tag cardinality overrides that apply within this metric. Must be omitted when `mode` is `excluded`.
70548+
description: A list of per-tag cardinality overrides that apply within this metric. Must be omitted when `override_type` is `excluded`.
7053670549
items:
7053770550
$ref: "#/components/schemas/ObservabilityPipelineTagCardinalityLimitProcessorPerTagLimit"
7053870551
maxItems: 50
7053970552
type: array
7054070553
value_limit:
70541-
description: The maximum number of distinct tag value combinations allowed for this metric. Required when `mode` is `tracked`. Must be omitted when `mode` is `excluded`.
70554+
description: The maximum number of distinct tag value combinations allowed for this metric. Required when `override_type` is `limit_override`. Must be omitted when `override_type` is `excluded`.
7054270555
example: 10000
7054370556
format: int64
7054470557
maximum: 1000000
7054570558
minimum: 0
7054670559
type: integer
7054770560
required:
7054870561
- metric_name
70549-
- mode
70562+
- override_type
7055070563
type: object
70551-
ObservabilityPipelineTagCardinalityLimitProcessorPerMetricMode:
70552-
description: How the per-metric override is applied. `tracked` enforces a custom limit; `excluded` skips the metric entirely.
70553-
enum:
70554-
- tracked
70555-
- excluded
70556-
example: tracked
70557-
type: string
70558-
x-enum-varnames:
70559-
- TRACKED
70560-
- EXCLUDED
7056170564
ObservabilityPipelineTagCardinalityLimitProcessorPerTagLimit:
7056270565
description: A cardinality override for a specific tag key within a per-metric limit.
7056370566
properties:
70564-
mode:
70565-
$ref: "#/components/schemas/ObservabilityPipelineTagCardinalityLimitProcessorPerTagMode"
70567+
override_type:
70568+
$ref: "#/components/schemas/ObservabilityPipelineTagCardinalityLimitProcessorOverrideType"
7056670569
tag_key:
7056770570
description: The tag key this override applies to.
7056870571
example: "host"
7056970572
type: string
7057070573
value_limit:
70571-
description: The maximum number of distinct values allowed for this tag. Required when `mode` is `limit_override`. Must be omitted when `mode` is `excluded`.
70574+
description: The maximum number of distinct values allowed for this tag. Required when `override_type` is `limit_override`. Must be omitted when `override_type` is `excluded`.
7057270575
example: 5000
7057370576
format: int64
7057470577
maximum: 1000000
7057570578
minimum: 0
7057670579
type: integer
7057770580
required:
7057870581
- tag_key
70582+
- override_type
70583+
type: object
70584+
ObservabilityPipelineTagCardinalityLimitProcessorTrackingMode:
70585+
description: Controls whether the processor uses exact or probabilistic tag tracking.
70586+
properties:
70587+
mode:
70588+
$ref: "#/components/schemas/ObservabilityPipelineTagCardinalityLimitProcessorTrackingModeMode"
70589+
required:
7057970590
- mode
7058070591
type: object
70581-
ObservabilityPipelineTagCardinalityLimitProcessorPerTagMode:
70582-
description: How the per-tag override is applied. `limit_override` enforces a custom limit on the tag; `excluded` skips the tag from cardinality tracking.
70592+
ObservabilityPipelineTagCardinalityLimitProcessorTrackingModeMode:
70593+
description: The cardinality tracking algorithm to use.
7058370594
enum:
70584-
- limit_override
70585-
- excluded
70586-
example: limit_override
70595+
- exact_fingerprint
70596+
- probabilistic
70597+
example: exact_fingerprint
7058770598
type: string
7058870599
x-enum-varnames:
70589-
- LIMIT_OVERRIDE
70590-
- EXCLUDED
70600+
- EXACT_FINGERPRINT
70601+
- PROBABILISTIC
7059170602
ObservabilityPipelineTagCardinalityLimitProcessorType:
7059270603
default: tag_cardinality_limit
7059370604
description: The processor type. The value must be `tag_cardinality_limit`.
@@ -127284,6 +127295,56 @@ paths:
127284127295
x-unstable: |-
127285127296
**Note**: This endpoint is in preview and is subject to change.
127286127297
If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/).
127298+
get:
127299+
description: Get the custom forecast for a budget.
127300+
operationId: GetCustomForecast
127301+
parameters:
127302+
- $ref: "#/components/parameters/BudgetID"
127303+
responses:
127304+
"200":
127305+
content:
127306+
application/json:
127307+
examples:
127308+
default:
127309+
value:
127310+
data:
127311+
attributes:
127312+
budget_uid: 00000000-0000-0000-0000-000000000001
127313+
created_at: 1738258683590
127314+
created_by: 00000000-0a0a-0a0a-aaa0-00000000000a
127315+
entries:
127316+
- amount: 400
127317+
month: 202501
127318+
tag_filters:
127319+
- tag_key: service
127320+
tag_value: ec2
127321+
- amount: 450
127322+
month: 202502
127323+
tag_filters:
127324+
- tag_key: service
127325+
tag_value: ec2
127326+
updated_at: 1738258683590
127327+
updated_by: 00000000-0a0a-0a0a-aaa0-00000000000a
127328+
id: 11111111-1111-1111-1111-111111111111
127329+
type: custom_forecast
127330+
schema:
127331+
$ref: "#/components/schemas/CustomForecastResponse"
127332+
description: OK
127333+
"400":
127334+
$ref: "#/components/responses/BadRequestResponse"
127335+
"404":
127336+
$ref: "#/components/responses/NotFoundResponse"
127337+
"429":
127338+
$ref: "#/components/responses/TooManyRequestsResponse"
127339+
security:
127340+
- apiKeyAuth: []
127341+
appKeyAuth: []
127342+
summary: Get a budget's custom forecast
127343+
tags:
127344+
- Cloud Cost Management
127345+
x-unstable: |-
127346+
**Note**: This endpoint is in preview and is subject to change.
127347+
If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/).
127287127348
/api/v2/cost/budgets:
127288127349
get:
127289127350
description: List budgets.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Get a budget's custom forecast returns "OK" response
2+
use datadog_api_client::datadog;
3+
use datadog_api_client::datadogV2::api_cloud_cost_management::CloudCostManagementAPI;
4+
5+
#[tokio::main]
6+
async fn main() {
7+
let mut configuration = datadog::Configuration::new();
8+
configuration.set_unstable_operation_enabled("v2.GetCustomForecast", true);
9+
let api = CloudCostManagementAPI::with_config(configuration);
10+
let resp = api.get_custom_forecast("budget_id".to_string()).await;
11+
if let Ok(value) = resp {
12+
println!("{:#?}", value);
13+
} else {
14+
println!("{:#?}", resp.unwrap_err());
15+
}
16+
}

src/datadog/configuration.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,7 @@ impl Default for Configuration {
506506
),
507507
("v2.get_cost_anomaly".to_owned(), false),
508508
("v2.get_cost_tag_metadata_currency".to_owned(), false),
509+
("v2.get_custom_forecast".to_owned(), false),
509510
("v2.list_cost_anomalies".to_owned(), false),
510511
("v2.list_cost_tag_key_sources".to_owned(), false),
511512
("v2.list_cost_tag_metadata".to_owned(), false),

src/datadogV2/api/api_cloud_cost_management.rs

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,14 @@ pub enum GetCustomCostsFileError {
887887
UnknownValue(serde_json::Value),
888888
}
889889

890+
/// GetCustomForecastError is a struct for typed errors of method [`CloudCostManagementAPI::get_custom_forecast`]
891+
#[derive(Debug, Clone, Serialize, Deserialize)]
892+
#[serde(untagged)]
893+
pub enum GetCustomForecastError {
894+
APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
895+
UnknownValue(serde_json::Value),
896+
}
897+
890898
/// GetTagPipelinesRulesetError is a struct for typed errors of method [`CloudCostManagementAPI::get_tag_pipelines_ruleset`]
891899
#[derive(Debug, Clone, Serialize, Deserialize)]
892900
#[serde(untagged)]
@@ -5301,6 +5309,123 @@ impl CloudCostManagementAPI {
53015309
}
53025310
}
53035311

5312+
/// Get the custom forecast for a budget.
5313+
pub async fn get_custom_forecast(
5314+
&self,
5315+
budget_id: String,
5316+
) -> Result<
5317+
crate::datadogV2::model::CustomForecastResponse,
5318+
datadog::Error<GetCustomForecastError>,
5319+
> {
5320+
match self.get_custom_forecast_with_http_info(budget_id).await {
5321+
Ok(response_content) => {
5322+
if let Some(e) = response_content.entity {
5323+
Ok(e)
5324+
} else {
5325+
Err(datadog::Error::Serde(serde::de::Error::custom(
5326+
"response content was None",
5327+
)))
5328+
}
5329+
}
5330+
Err(err) => Err(err),
5331+
}
5332+
}
5333+
5334+
/// Get the custom forecast for a budget.
5335+
pub async fn get_custom_forecast_with_http_info(
5336+
&self,
5337+
budget_id: String,
5338+
) -> Result<
5339+
datadog::ResponseContent<crate::datadogV2::model::CustomForecastResponse>,
5340+
datadog::Error<GetCustomForecastError>,
5341+
> {
5342+
let local_configuration = &self.config;
5343+
let operation_id = "v2.get_custom_forecast";
5344+
if local_configuration.is_unstable_operation_enabled(operation_id) {
5345+
warn!("Using unstable operation {operation_id}");
5346+
} else {
5347+
let local_error = datadog::UnstableOperationDisabledError {
5348+
msg: "Operation 'v2.get_custom_forecast' is not enabled".to_string(),
5349+
};
5350+
return Err(datadog::Error::UnstableOperationDisabledError(local_error));
5351+
}
5352+
5353+
let local_client = &self.client;
5354+
5355+
let local_uri_str = format!(
5356+
"{}/api/v2/cost/budget/{budget_id}/custom-forecast",
5357+
local_configuration.get_operation_host(operation_id),
5358+
budget_id = datadog::urlencode(budget_id)
5359+
);
5360+
let mut local_req_builder =
5361+
local_client.request(reqwest::Method::GET, local_uri_str.as_str());
5362+
5363+
// build headers
5364+
let mut headers = HeaderMap::new();
5365+
headers.insert("Accept", HeaderValue::from_static("application/json"));
5366+
5367+
// build user agent
5368+
match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
5369+
Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
5370+
Err(e) => {
5371+
log::warn!("Failed to parse user agent header: {e}, falling back to default");
5372+
headers.insert(
5373+
reqwest::header::USER_AGENT,
5374+
HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
5375+
)
5376+
}
5377+
};
5378+
5379+
// build auth
5380+
if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
5381+
headers.insert(
5382+
"DD-API-KEY",
5383+
HeaderValue::from_str(local_key.key.as_str())
5384+
.expect("failed to parse DD-API-KEY header"),
5385+
);
5386+
};
5387+
if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
5388+
headers.insert(
5389+
"DD-APPLICATION-KEY",
5390+
HeaderValue::from_str(local_key.key.as_str())
5391+
.expect("failed to parse DD-APPLICATION-KEY header"),
5392+
);
5393+
};
5394+
5395+
local_req_builder = local_req_builder.headers(headers);
5396+
let local_req = local_req_builder.build()?;
5397+
log::debug!("request content: {:?}", local_req.body());
5398+
let local_resp = local_client.execute(local_req).await?;
5399+
5400+
let local_status = local_resp.status();
5401+
let local_content = local_resp.text().await?;
5402+
log::debug!("response content: {}", local_content);
5403+
5404+
if !local_status.is_client_error() && !local_status.is_server_error() {
5405+
match serde_json::from_str::<crate::datadogV2::model::CustomForecastResponse>(
5406+
&local_content,
5407+
) {
5408+
Ok(e) => {
5409+
return Ok(datadog::ResponseContent {
5410+
status: local_status,
5411+
content: local_content,
5412+
entity: Some(e),
5413+
})
5414+
}
5415+
Err(e) => return Err(datadog::Error::Serde(e)),
5416+
};
5417+
} else {
5418+
let local_entity: Option<GetCustomForecastError> =
5419+
serde_json::from_str(&local_content).ok();
5420+
let local_error = datadog::ResponseContent {
5421+
status: local_status,
5422+
content: local_content,
5423+
entity: local_entity,
5424+
};
5425+
Err(datadog::Error::ResponseError(local_error))
5426+
}
5427+
}
5428+
53045429
/// Get a specific tag pipeline ruleset - Retrieve a specific tag pipeline ruleset by its ID
53055430
pub async fn get_tag_pipelines_ruleset(
53065431
&self,

src/datadogV2/model/mod.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7658,12 +7658,14 @@ pub mod model_observability_pipeline_tag_cardinality_limit_processor_action;
76587658
pub use self::model_observability_pipeline_tag_cardinality_limit_processor_action::ObservabilityPipelineTagCardinalityLimitProcessorAction;
76597659
pub mod model_observability_pipeline_tag_cardinality_limit_processor_per_metric_limit;
76607660
pub use self::model_observability_pipeline_tag_cardinality_limit_processor_per_metric_limit::ObservabilityPipelineTagCardinalityLimitProcessorPerMetricLimit;
7661-
pub mod model_observability_pipeline_tag_cardinality_limit_processor_per_metric_mode;
7662-
pub use self::model_observability_pipeline_tag_cardinality_limit_processor_per_metric_mode::ObservabilityPipelineTagCardinalityLimitProcessorPerMetricMode;
7661+
pub mod model_observability_pipeline_tag_cardinality_limit_processor_override_type;
7662+
pub use self::model_observability_pipeline_tag_cardinality_limit_processor_override_type::ObservabilityPipelineTagCardinalityLimitProcessorOverrideType;
76637663
pub mod model_observability_pipeline_tag_cardinality_limit_processor_per_tag_limit;
76647664
pub use self::model_observability_pipeline_tag_cardinality_limit_processor_per_tag_limit::ObservabilityPipelineTagCardinalityLimitProcessorPerTagLimit;
7665-
pub mod model_observability_pipeline_tag_cardinality_limit_processor_per_tag_mode;
7666-
pub use self::model_observability_pipeline_tag_cardinality_limit_processor_per_tag_mode::ObservabilityPipelineTagCardinalityLimitProcessorPerTagMode;
7665+
pub mod model_observability_pipeline_tag_cardinality_limit_processor_tracking_mode;
7666+
pub use self::model_observability_pipeline_tag_cardinality_limit_processor_tracking_mode::ObservabilityPipelineTagCardinalityLimitProcessorTrackingMode;
7667+
pub mod model_observability_pipeline_tag_cardinality_limit_processor_tracking_mode_mode;
7668+
pub use self::model_observability_pipeline_tag_cardinality_limit_processor_tracking_mode_mode::ObservabilityPipelineTagCardinalityLimitProcessorTrackingModeMode;
76677669
pub mod model_observability_pipeline_tag_cardinality_limit_processor_type;
76687670
pub use self::model_observability_pipeline_tag_cardinality_limit_processor_type::ObservabilityPipelineTagCardinalityLimitProcessorType;
76697671
pub mod model_observability_pipeline_config_processor_item;

0 commit comments

Comments
 (0)