diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index fd5ed0088..24a058666 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -29986,6 +29986,25 @@ components: data: $ref: "#/components/schemas/ListDeploymentRuleResponseData" type: object + DeploymentGatesEvaluationConfiguration: + description: |- + Inline rule definitions for a deployment gate evaluation. When provided, rules are evaluated + directly from this configuration instead of using the preconfigured gate rules. + At least one rule is required. + properties: + dry_run: + description: Gate-level dry run. When enabled, the rules are evaluated normally but the gate always returns `pass`. The real result is visible in the Datadog UI. + example: false + type: boolean + rules: + description: The list of rules to evaluate. At least one rule is required. + items: + $ref: "#/components/schemas/DeploymentGatesEvaluationRule" + minItems: 1 + type: array + required: + - rules + type: object DeploymentGatesEvaluationRequest: description: Request body for triggering a deployment gate evaluation. properties: @@ -29995,8 +30014,13 @@ components: - data type: object DeploymentGatesEvaluationRequestAttributes: - description: Attributes for a deployment gate evaluation request. + description: |- + Attributes for a deployment gate evaluation request. + When `configuration` is provided, rules are evaluated inline from that configuration. + When omitted, rules are resolved from the preconfigured gate for the given service and environment. properties: + configuration: + $ref: "#/components/schemas/DeploymentGatesEvaluationConfiguration" env: description: The environment of the deployment. example: "staging" @@ -30166,6 +30190,60 @@ components: type: string x-enum-varnames: - DEPLOYMENT_GATES_EVALUATION_RESULT_RESPONSE + DeploymentGatesEvaluationRule: + description: A rule to evaluate as part of a deployment gate evaluation. + discriminator: + mapping: + faulty_deployment_detection: "#/components/schemas/DeploymentGatesFDDRule" + monitor: "#/components/schemas/DeploymentGatesMonitorRule" + propertyName: type + oneOf: + - $ref: "#/components/schemas/DeploymentGatesMonitorRule" + - $ref: "#/components/schemas/DeploymentGatesFDDRule" + DeploymentGatesFDDRule: + description: A faulty deployment detection rule to evaluate as part of a deployment gate evaluation. + properties: + dry_run: + description: Rule-level dry run. When enabled, the rule is evaluated normally but it always returns `pass`. The real result is visible in the Datadog UI. + example: false + type: boolean + name: + description: Human-readable name for this rule. + example: "apm faulty deployment" + type: string + options: + $ref: "#/components/schemas/DeploymentGatesFDDRuleOptions" + type: + $ref: "#/components/schemas/DeploymentGatesFDDRuleType" + required: + - type + - name + type: object + DeploymentGatesFDDRuleOptions: + description: Options for a `faulty_deployment_detection` rule. + properties: + duration: + description: Evaluation window in seconds. Maximum 7200 (2 hours). + example: 900 + format: int64 + maximum: 7200 + type: integer + excluded_resources: + description: APM resource names to exclude from analysis. + example: + - "GET /healthcheck" + items: + type: string + type: array + type: object + DeploymentGatesFDDRuleType: + description: The type identifier for a faulty deployment detection rule. + enum: + - faulty_deployment_detection + example: faulty_deployment_detection + type: string + x-enum-varnames: + - FAULTY_DEPLOYMENT_DETECTION DeploymentGatesListResponse: description: Response containing a paginated list of deployment gates. properties: @@ -30200,6 +30278,49 @@ components: minimum: 1 type: integer type: object + DeploymentGatesMonitorRule: + description: A monitor rule to evaluate as part of a deployment gate evaluation. + properties: + dry_run: + description: Rule-level dry run. When enabled, the rule is evaluated normally but always returns `pass`. The real result is visible in the Datadog UI. + example: false + type: boolean + name: + description: Human-readable name for this rule. + example: "error rate monitors" + type: string + options: + $ref: "#/components/schemas/DeploymentGatesMonitorRuleOptions" + type: + $ref: "#/components/schemas/DeploymentGatesMonitorRuleType" + required: + - type + - name + type: object + DeploymentGatesMonitorRuleOptions: + description: Options for a `monitor` rule. + properties: + duration: + description: Evaluation window in seconds. Maximum 7200 (2 hours). + example: 300 + format: int64 + maximum: 7200 + type: integer + query: + description: Monitor search query. + example: "service:transaction-backend env:production" + type: string + required: + - query + type: object + DeploymentGatesMonitorRuleType: + description: The type identifier for a monitor rule. + enum: + - monitor + example: monitor + type: string + x-enum-varnames: + - MONITOR DeploymentGatesRuleResponse: description: The result of a single rule evaluation. properties: @@ -124667,12 +124788,17 @@ paths: Triggers an asynchronous deployment gate evaluation for the given service and environment. Returns an evaluation ID that can be used to poll for the result via the `GET /api/v2/deployments/gates/evaluation/{id}` endpoint. + + When the `configuration` attribute is provided, rules are evaluated inline from that configuration + and no pre-configured gate is required. When `configuration` is omitted, rules are resolved from the + gate pre-configured for the given service and environment through the Datadog UI, API, or Terraform. operationId: TriggerDeploymentGatesEvaluation requestBody: content: application/json: examples: default: + summary: Evaluate a preconfigured gate value: data: attributes: @@ -124682,6 +124808,31 @@ paths: service: transaction-backend version: v1.2.3 type: deployment_gates_evaluation_request + with-configuration: + summary: Evaluate with inline rule configuration + value: + data: + attributes: + configuration: + dry_run: false + rules: + - dry_run: false + name: error rate monitors + options: + duration: 300 + query: "service:transaction-backend env:production" + type: monitor + - dry_run: false + name: apm faulty deployment + options: + duration: 900 + excluded_resources: + - "GET /healthcheck" + type: faulty_deployment_detection + env: production + service: transaction-backend + version: 1.2.3 + type: deployment_gates_evaluation_request schema: $ref: "#/components/schemas/DeploymentGatesEvaluationRequest" required: true diff --git a/examples/v2_deployment-gates_TriggerDeploymentGatesEvaluation.rs b/examples/v2_deployment-gates_TriggerDeploymentGatesEvaluation.rs index 44d9a841f..f6f3f1da8 100644 --- a/examples/v2_deployment-gates_TriggerDeploymentGatesEvaluation.rs +++ b/examples/v2_deployment-gates_TriggerDeploymentGatesEvaluation.rs @@ -1,10 +1,15 @@ // Trigger a deployment gate evaluation returns "Accepted" response use datadog_api_client::datadog; use datadog_api_client::datadogV2::api_deployment_gates::DeploymentGatesAPI; +use datadog_api_client::datadogV2::model::DeploymentGatesEvaluationConfiguration; use datadog_api_client::datadogV2::model::DeploymentGatesEvaluationRequest; use datadog_api_client::datadogV2::model::DeploymentGatesEvaluationRequestAttributes; use datadog_api_client::datadogV2::model::DeploymentGatesEvaluationRequestData; use datadog_api_client::datadogV2::model::DeploymentGatesEvaluationRequestDataType; +use datadog_api_client::datadogV2::model::DeploymentGatesEvaluationRule; +use datadog_api_client::datadogV2::model::DeploymentGatesMonitorRule; +use datadog_api_client::datadogV2::model::DeploymentGatesMonitorRuleOptions; +use datadog_api_client::datadogV2::model::DeploymentGatesMonitorRuleType; #[tokio::main] async fn main() { @@ -13,6 +18,24 @@ async fn main() { "staging".to_string(), "transaction-backend".to_string(), ) + .configuration( + DeploymentGatesEvaluationConfiguration::new(vec![ + DeploymentGatesEvaluationRule::DeploymentGatesMonitorRule(Box::new( + DeploymentGatesMonitorRule::new( + "error rate monitors".to_string(), + DeploymentGatesMonitorRuleType::MONITOR, + ) + .dry_run(false) + .options( + DeploymentGatesMonitorRuleOptions::new( + "service:transaction-backend env:production".to_string(), + ) + .duration(300), + ), + )), + ]) + .dry_run(false), + ) .identifier("pre-deploy".to_string()) .primary_tag("region:us-east-1".to_string()) .version("v1.2.3".to_string()), diff --git a/src/datadogV2/api/api_deployment_gates.rs b/src/datadogV2/api/api_deployment_gates.rs index 74b21ec92..6a83d10ed 100644 --- a/src/datadogV2/api/api_deployment_gates.rs +++ b/src/datadogV2/api/api_deployment_gates.rs @@ -1384,6 +1384,10 @@ impl DeploymentGatesAPI { /// Triggers an asynchronous deployment gate evaluation for the given service and environment. /// Returns an evaluation ID that can be used to poll for the result via the /// `GET /api/v2/deployments/gates/evaluation/{id}` endpoint. + /// + /// When the `configuration` attribute is provided, rules are evaluated inline from that configuration + /// and no pre-configured gate is required. When `configuration` is omitted, rules are resolved from the + /// gate pre-configured for the given service and environment through the Datadog UI, API, or Terraform. pub async fn trigger_deployment_gates_evaluation( &self, body: crate::datadogV2::model::DeploymentGatesEvaluationRequest, @@ -1411,6 +1415,10 @@ impl DeploymentGatesAPI { /// Triggers an asynchronous deployment gate evaluation for the given service and environment. /// Returns an evaluation ID that can be used to poll for the result via the /// `GET /api/v2/deployments/gates/evaluation/{id}` endpoint. + /// + /// When the `configuration` attribute is provided, rules are evaluated inline from that configuration + /// and no pre-configured gate is required. When `configuration` is omitted, rules are resolved from the + /// gate pre-configured for the given service and environment through the Datadog UI, API, or Terraform. pub async fn trigger_deployment_gates_evaluation_with_http_info( &self, body: crate::datadogV2::model::DeploymentGatesEvaluationRequest, diff --git a/src/datadogV2/model/mod.rs b/src/datadogV2/model/mod.rs index bf1fd2384..ff505aeb7 100644 --- a/src/datadogV2/model/mod.rs +++ b/src/datadogV2/model/mod.rs @@ -3462,6 +3462,22 @@ pub mod model_deployment_gates_evaluation_request_data; pub use self::model_deployment_gates_evaluation_request_data::DeploymentGatesEvaluationRequestData; pub mod model_deployment_gates_evaluation_request_attributes; pub use self::model_deployment_gates_evaluation_request_attributes::DeploymentGatesEvaluationRequestAttributes; +pub mod model_deployment_gates_evaluation_configuration; +pub use self::model_deployment_gates_evaluation_configuration::DeploymentGatesEvaluationConfiguration; +pub mod model_deployment_gates_monitor_rule; +pub use self::model_deployment_gates_monitor_rule::DeploymentGatesMonitorRule; +pub mod model_deployment_gates_monitor_rule_options; +pub use self::model_deployment_gates_monitor_rule_options::DeploymentGatesMonitorRuleOptions; +pub mod model_deployment_gates_monitor_rule_type; +pub use self::model_deployment_gates_monitor_rule_type::DeploymentGatesMonitorRuleType; +pub mod model_deployment_gates_fdd_rule; +pub use self::model_deployment_gates_fdd_rule::DeploymentGatesFDDRule; +pub mod model_deployment_gates_fdd_rule_options; +pub use self::model_deployment_gates_fdd_rule_options::DeploymentGatesFDDRuleOptions; +pub mod model_deployment_gates_fdd_rule_type; +pub use self::model_deployment_gates_fdd_rule_type::DeploymentGatesFDDRuleType; +pub mod model_deployment_gates_evaluation_rule; +pub use self::model_deployment_gates_evaluation_rule::DeploymentGatesEvaluationRule; pub mod model_deployment_gates_evaluation_request_data_type; pub use self::model_deployment_gates_evaluation_request_data_type::DeploymentGatesEvaluationRequestDataType; pub mod model_deployment_gates_evaluation_response; diff --git a/src/datadogV2/model/model_deployment_gates_evaluation_configuration.rs b/src/datadogV2/model/model_deployment_gates_evaluation_configuration.rs new file mode 100644 index 000000000..6fce77701 --- /dev/null +++ b/src/datadogV2/model/model_deployment_gates_evaluation_configuration.rs @@ -0,0 +1,114 @@ +// 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}; + +/// Inline rule definitions for a deployment gate evaluation. When provided, rules are evaluated +/// directly from this configuration instead of using the preconfigured gate rules. +/// At least one rule is required. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct DeploymentGatesEvaluationConfiguration { + /// Gate-level dry run. When enabled, the rules are evaluated normally but the gate always returns `pass`. The real result is visible in the Datadog UI. + #[serde(rename = "dry_run")] + pub dry_run: Option, + /// The list of rules to evaluate. At least one rule is required. + #[serde(rename = "rules")] + pub rules: Vec, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl DeploymentGatesEvaluationConfiguration { + pub fn new( + rules: Vec, + ) -> DeploymentGatesEvaluationConfiguration { + DeploymentGatesEvaluationConfiguration { + dry_run: None, + rules, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn dry_run(mut self, value: bool) -> Self { + self.dry_run = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for DeploymentGatesEvaluationConfiguration { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct DeploymentGatesEvaluationConfigurationVisitor; + impl<'a> Visitor<'a> for DeploymentGatesEvaluationConfigurationVisitor { + type Value = DeploymentGatesEvaluationConfiguration; + + 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 dry_run: Option = None; + let mut rules: 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() { + "dry_run" => { + if v.is_null() { + continue; + } + dry_run = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "rules" => { + rules = 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 rules = rules.ok_or_else(|| M::Error::missing_field("rules"))?; + + let content = DeploymentGatesEvaluationConfiguration { + dry_run, + rules, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(DeploymentGatesEvaluationConfigurationVisitor) + } +} diff --git a/src/datadogV2/model/model_deployment_gates_evaluation_request_attributes.rs b/src/datadogV2/model/model_deployment_gates_evaluation_request_attributes.rs index 53bfab0dc..627b62569 100644 --- a/src/datadogV2/model/model_deployment_gates_evaluation_request_attributes.rs +++ b/src/datadogV2/model/model_deployment_gates_evaluation_request_attributes.rs @@ -7,10 +7,17 @@ use serde_with::skip_serializing_none; use std::fmt::{self, Formatter}; /// Attributes for a deployment gate evaluation request. +/// When `configuration` is provided, rules are evaluated inline from that configuration. +/// When omitted, rules are resolved from the preconfigured gate for the given service and environment. #[non_exhaustive] #[skip_serializing_none] #[derive(Clone, Debug, PartialEq, Serialize)] pub struct DeploymentGatesEvaluationRequestAttributes { + /// Inline rule definitions for a deployment gate evaluation. When provided, rules are evaluated + /// directly from this configuration instead of using the preconfigured gate rules. + /// At least one rule is required. + #[serde(rename = "configuration")] + pub configuration: Option, /// The environment of the deployment. #[serde(rename = "env")] pub env: String, @@ -36,6 +43,7 @@ pub struct DeploymentGatesEvaluationRequestAttributes { impl DeploymentGatesEvaluationRequestAttributes { pub fn new(env: String, service: String) -> DeploymentGatesEvaluationRequestAttributes { DeploymentGatesEvaluationRequestAttributes { + configuration: None, env, identifier: None, primary_tag: None, @@ -46,6 +54,14 @@ impl DeploymentGatesEvaluationRequestAttributes { } } + pub fn configuration( + mut self, + value: crate::datadogV2::model::DeploymentGatesEvaluationConfiguration, + ) -> Self { + self.configuration = Some(value); + self + } + pub fn identifier(mut self, value: String) -> Self { self.identifier = Some(value); self @@ -87,6 +103,9 @@ impl<'de> Deserialize<'de> for DeploymentGatesEvaluationRequestAttributes { where M: MapAccess<'a>, { + let mut configuration: Option< + crate::datadogV2::model::DeploymentGatesEvaluationConfiguration, + > = None; let mut env: Option = None; let mut identifier: Option = None; let mut primary_tag: Option = None; @@ -100,6 +119,13 @@ impl<'de> Deserialize<'de> for DeploymentGatesEvaluationRequestAttributes { while let Some((k, v)) = map.next_entry::()? { match k.as_str() { + "configuration" => { + if v.is_null() { + continue; + } + configuration = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } "env" => { env = Some(serde_json::from_value(v).map_err(M::Error::custom)?); } @@ -136,6 +162,7 @@ impl<'de> Deserialize<'de> for DeploymentGatesEvaluationRequestAttributes { let service = service.ok_or_else(|| M::Error::missing_field("service"))?; let content = DeploymentGatesEvaluationRequestAttributes { + configuration, env, identifier, primary_tag, diff --git a/src/datadogV2/model/model_deployment_gates_evaluation_request_data.rs b/src/datadogV2/model/model_deployment_gates_evaluation_request_data.rs index 7567a2028..5c86f8b35 100644 --- a/src/datadogV2/model/model_deployment_gates_evaluation_request_data.rs +++ b/src/datadogV2/model/model_deployment_gates_evaluation_request_data.rs @@ -12,6 +12,8 @@ use std::fmt::{self, Formatter}; #[derive(Clone, Debug, PartialEq, Serialize)] pub struct DeploymentGatesEvaluationRequestData { /// Attributes for a deployment gate evaluation request. + /// When `configuration` is provided, rules are evaluated inline from that configuration. + /// When omitted, rules are resolved from the preconfigured gate for the given service and environment. #[serde(rename = "attributes")] pub attributes: crate::datadogV2::model::DeploymentGatesEvaluationRequestAttributes, /// JSON:API type for a deployment gate evaluation request. diff --git a/src/datadogV2/model/model_deployment_gates_evaluation_rule.rs b/src/datadogV2/model/model_deployment_gates_evaluation_rule.rs new file mode 100644 index 000000000..469f767ad --- /dev/null +++ b/src/datadogV2/model/model_deployment_gates_evaluation_rule.rs @@ -0,0 +1,44 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::{Deserialize, Deserializer, Serialize}; + +/// A rule to evaluate as part of a deployment gate evaluation. +#[non_exhaustive] +#[derive(Clone, Debug, PartialEq, Serialize)] +#[serde(untagged)] +pub enum DeploymentGatesEvaluationRule { + DeploymentGatesMonitorRule(Box), + DeploymentGatesFDDRule(Box), + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl<'de> Deserialize<'de> for DeploymentGatesEvaluationRule { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let value: serde_json::Value = Deserialize::deserialize(deserializer)?; + if let Ok(_v) = serde_json::from_value::< + Box, + >(value.clone()) + { + if !_v._unparsed { + return Ok(DeploymentGatesEvaluationRule::DeploymentGatesMonitorRule( + _v, + )); + } + } + if let Ok(_v) = serde_json::from_value::>( + value.clone(), + ) { + if !_v._unparsed { + return Ok(DeploymentGatesEvaluationRule::DeploymentGatesFDDRule(_v)); + } + } + + return Ok(DeploymentGatesEvaluationRule::UnparsedObject( + crate::datadog::UnparsedObject { value }, + )); + } +} diff --git a/src/datadogV2/model/model_deployment_gates_fdd_rule.rs b/src/datadogV2/model/model_deployment_gates_fdd_rule.rs new file mode 100644 index 000000000..024b829c7 --- /dev/null +++ b/src/datadogV2/model/model_deployment_gates_fdd_rule.rs @@ -0,0 +1,151 @@ +// 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}; + +/// A faulty deployment detection rule to evaluate as part of a deployment gate evaluation. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct DeploymentGatesFDDRule { + /// Rule-level dry run. When enabled, the rule is evaluated normally but it always returns `pass`. The real result is visible in the Datadog UI. + #[serde(rename = "dry_run")] + pub dry_run: Option, + /// Human-readable name for this rule. + #[serde(rename = "name")] + pub name: String, + /// Options for a `faulty_deployment_detection` rule. + #[serde(rename = "options")] + pub options: Option, + /// The type identifier for a faulty deployment detection rule. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::DeploymentGatesFDDRuleType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl DeploymentGatesFDDRule { + pub fn new( + name: String, + type_: crate::datadogV2::model::DeploymentGatesFDDRuleType, + ) -> DeploymentGatesFDDRule { + DeploymentGatesFDDRule { + dry_run: None, + name, + options: None, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn dry_run(mut self, value: bool) -> Self { + self.dry_run = Some(value); + self + } + + pub fn options( + mut self, + value: crate::datadogV2::model::DeploymentGatesFDDRuleOptions, + ) -> Self { + self.options = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for DeploymentGatesFDDRule { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct DeploymentGatesFDDRuleVisitor; + impl<'a> Visitor<'a> for DeploymentGatesFDDRuleVisitor { + type Value = DeploymentGatesFDDRule; + + 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 dry_run: Option = None; + let mut name: Option = None; + let mut options: 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() { + "dry_run" => { + if v.is_null() { + continue; + } + dry_run = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "name" => { + name = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "options" => { + if v.is_null() { + continue; + } + options = 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::DeploymentGatesFDDRuleType::UnparsedObject(_type_) => { + _unparsed = true; + }, + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let name = name.ok_or_else(|| M::Error::missing_field("name"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = DeploymentGatesFDDRule { + dry_run, + name, + options, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(DeploymentGatesFDDRuleVisitor) + } +} diff --git a/src/datadogV2/model/model_deployment_gates_fdd_rule_options.rs b/src/datadogV2/model/model_deployment_gates_fdd_rule_options.rs new file mode 100644 index 000000000..a704692ca --- /dev/null +++ b/src/datadogV2/model/model_deployment_gates_fdd_rule_options.rs @@ -0,0 +1,123 @@ +// 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}; + +/// Options for a `faulty_deployment_detection` rule. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct DeploymentGatesFDDRuleOptions { + /// Evaluation window in seconds. Maximum 7200 (2 hours). + #[serde(rename = "duration")] + pub duration: Option, + /// APM resource names to exclude from analysis. + #[serde(rename = "excluded_resources")] + pub excluded_resources: Option>, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl DeploymentGatesFDDRuleOptions { + pub fn new() -> DeploymentGatesFDDRuleOptions { + DeploymentGatesFDDRuleOptions { + duration: None, + excluded_resources: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn duration(mut self, value: i64) -> Self { + self.duration = Some(value); + self + } + + pub fn excluded_resources(mut self, value: Vec) -> Self { + self.excluded_resources = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for DeploymentGatesFDDRuleOptions { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for DeploymentGatesFDDRuleOptions { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct DeploymentGatesFDDRuleOptionsVisitor; + impl<'a> Visitor<'a> for DeploymentGatesFDDRuleOptionsVisitor { + type Value = DeploymentGatesFDDRuleOptions; + + 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 duration: Option = None; + let mut excluded_resources: 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() { + "duration" => { + if v.is_null() { + continue; + } + duration = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "excluded_resources" => { + if v.is_null() { + continue; + } + excluded_resources = + 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 = DeploymentGatesFDDRuleOptions { + duration, + excluded_resources, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(DeploymentGatesFDDRuleOptionsVisitor) + } +} diff --git a/src/datadogV2/model/model_deployment_gates_fdd_rule_type.rs b/src/datadogV2/model/model_deployment_gates_fdd_rule_type.rs new file mode 100644 index 000000000..6fa2cf58a --- /dev/null +++ b/src/datadogV2/model/model_deployment_gates_fdd_rule_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 DeploymentGatesFDDRuleType { + FAULTY_DEPLOYMENT_DETECTION, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for DeploymentGatesFDDRuleType { + fn to_string(&self) -> String { + match self { + Self::FAULTY_DEPLOYMENT_DETECTION => String::from("faulty_deployment_detection"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for DeploymentGatesFDDRuleType { + 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 DeploymentGatesFDDRuleType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "faulty_deployment_detection" => Self::FAULTY_DEPLOYMENT_DETECTION, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/src/datadogV2/model/model_deployment_gates_monitor_rule.rs b/src/datadogV2/model/model_deployment_gates_monitor_rule.rs new file mode 100644 index 000000000..255c33136 --- /dev/null +++ b/src/datadogV2/model/model_deployment_gates_monitor_rule.rs @@ -0,0 +1,153 @@ +// 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}; + +/// A monitor rule to evaluate as part of a deployment gate evaluation. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct DeploymentGatesMonitorRule { + /// Rule-level dry run. When enabled, the rule is evaluated normally but always returns `pass`. The real result is visible in the Datadog UI. + #[serde(rename = "dry_run")] + pub dry_run: Option, + /// Human-readable name for this rule. + #[serde(rename = "name")] + pub name: String, + /// Options for a `monitor` rule. + #[serde(rename = "options")] + pub options: Option, + /// The type identifier for a monitor rule. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::DeploymentGatesMonitorRuleType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl DeploymentGatesMonitorRule { + pub fn new( + name: String, + type_: crate::datadogV2::model::DeploymentGatesMonitorRuleType, + ) -> DeploymentGatesMonitorRule { + DeploymentGatesMonitorRule { + dry_run: None, + name, + options: None, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn dry_run(mut self, value: bool) -> Self { + self.dry_run = Some(value); + self + } + + pub fn options( + mut self, + value: crate::datadogV2::model::DeploymentGatesMonitorRuleOptions, + ) -> Self { + self.options = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for DeploymentGatesMonitorRule { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct DeploymentGatesMonitorRuleVisitor; + impl<'a> Visitor<'a> for DeploymentGatesMonitorRuleVisitor { + type Value = DeploymentGatesMonitorRule; + + 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 dry_run: Option = None; + let mut name: Option = None; + let mut options: Option< + crate::datadogV2::model::DeploymentGatesMonitorRuleOptions, + > = 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() { + "dry_run" => { + if v.is_null() { + continue; + } + dry_run = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "name" => { + name = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "options" => { + if v.is_null() { + continue; + } + options = 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::DeploymentGatesMonitorRuleType::UnparsedObject(_type_) => { + _unparsed = true; + }, + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let name = name.ok_or_else(|| M::Error::missing_field("name"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = DeploymentGatesMonitorRule { + dry_run, + name, + options, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(DeploymentGatesMonitorRuleVisitor) + } +} diff --git a/src/datadogV2/model/model_deployment_gates_monitor_rule_options.rs b/src/datadogV2/model/model_deployment_gates_monitor_rule_options.rs new file mode 100644 index 000000000..d2d9f0522 --- /dev/null +++ b/src/datadogV2/model/model_deployment_gates_monitor_rule_options.rs @@ -0,0 +1,109 @@ +// 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}; + +/// Options for a `monitor` rule. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct DeploymentGatesMonitorRuleOptions { + /// Evaluation window in seconds. Maximum 7200 (2 hours). + #[serde(rename = "duration")] + pub duration: Option, + /// Monitor search query. + #[serde(rename = "query")] + pub query: String, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl DeploymentGatesMonitorRuleOptions { + pub fn new(query: String) -> DeploymentGatesMonitorRuleOptions { + DeploymentGatesMonitorRuleOptions { + duration: None, + query, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn duration(mut self, value: i64) -> Self { + self.duration = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for DeploymentGatesMonitorRuleOptions { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct DeploymentGatesMonitorRuleOptionsVisitor; + impl<'a> Visitor<'a> for DeploymentGatesMonitorRuleOptionsVisitor { + type Value = DeploymentGatesMonitorRuleOptions; + + 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 duration: Option = None; + let mut query: 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() { + "duration" => { + if v.is_null() { + continue; + } + duration = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "query" => { + query = 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 query = query.ok_or_else(|| M::Error::missing_field("query"))?; + + let content = DeploymentGatesMonitorRuleOptions { + duration, + query, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(DeploymentGatesMonitorRuleOptionsVisitor) + } +} diff --git a/src/datadogV2/model/model_deployment_gates_monitor_rule_type.rs b/src/datadogV2/model/model_deployment_gates_monitor_rule_type.rs new file mode 100644 index 000000000..54acff51b --- /dev/null +++ b/src/datadogV2/model/model_deployment_gates_monitor_rule_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 DeploymentGatesMonitorRuleType { + MONITOR, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for DeploymentGatesMonitorRuleType { + fn to_string(&self) -> String { + match self { + Self::MONITOR => String::from("monitor"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for DeploymentGatesMonitorRuleType { + 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 DeploymentGatesMonitorRuleType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "monitor" => Self::MONITOR, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/tests/scenarios/features/v2/deployment_gates.feature b/tests/scenarios/features/v2/deployment_gates.feature index df9494d2a..de5ceaeaa 100644 --- a/tests/scenarios/features/v2/deployment_gates.feature +++ b/tests/scenarios/features/v2/deployment_gates.feature @@ -286,7 +286,7 @@ Feature: Deployment Gates Scenario: Trigger a deployment gate evaluation returns "Accepted" response Given operation "TriggerDeploymentGatesEvaluation" enabled And new "TriggerDeploymentGatesEvaluation" request - And body with value {"data": {"attributes": {"env": "staging", "identifier": "pre-deploy", "primary_tag": "region:us-east-1", "service": "transaction-backend", "version": "v1.2.3"}, "type": "deployment_gates_evaluation_request"}} + And body with value {"data": {"attributes": {"configuration": {"dry_run": false, "rules": [{"dry_run": false, "name": "error rate monitors", "options": {"duration": 300, "query": "service:transaction-backend env:production"}, "type": "monitor"}]}, "env": "staging", "identifier": "pre-deploy", "primary_tag": "region:us-east-1", "service": "transaction-backend", "version": "v1.2.3"}, "type": "deployment_gates_evaluation_request"}} When the request is sent Then the response status is 202 Accepted @@ -294,7 +294,7 @@ Feature: Deployment Gates Scenario: Trigger a deployment gate evaluation returns "Bad request." response Given operation "TriggerDeploymentGatesEvaluation" enabled And new "TriggerDeploymentGatesEvaluation" request - And body with value {"data": {"attributes": {"env": "staging", "identifier": "pre-deploy", "primary_tag": "region:us-east-1", "service": "transaction-backend", "version": "v1.2.3"}, "type": "deployment_gates_evaluation_request"}} + And body with value {"data": {"attributes": {"configuration": {"dry_run": false, "rules": [{"dry_run": false, "name": "error rate monitors", "options": {"duration": 300, "query": "service:transaction-backend env:production"}, "type": "monitor"}]}, "env": "staging", "identifier": "pre-deploy", "primary_tag": "region:us-east-1", "service": "transaction-backend", "version": "v1.2.3"}, "type": "deployment_gates_evaluation_request"}} When the request is sent Then the response status is 400 Bad request. @@ -302,7 +302,7 @@ Feature: Deployment Gates Scenario: Trigger a deployment gate evaluation returns "Deployment gate not found." response Given operation "TriggerDeploymentGatesEvaluation" enabled And new "TriggerDeploymentGatesEvaluation" request - And body with value {"data": {"attributes": {"env": "staging", "identifier": "pre-deploy", "primary_tag": "region:us-east-1", "service": "transaction-backend", "version": "v1.2.3"}, "type": "deployment_gates_evaluation_request"}} + And body with value {"data": {"attributes": {"configuration": {"dry_run": false, "rules": [{"dry_run": false, "name": "error rate monitors", "options": {"duration": 300, "query": "service:transaction-backend env:production"}, "type": "monitor"}]}, "env": "staging", "identifier": "pre-deploy", "primary_tag": "region:us-east-1", "service": "transaction-backend", "version": "v1.2.3"}, "type": "deployment_gates_evaluation_request"}} When the request is sent Then the response status is 404 Deployment gate not found.