From 4b8bab52052b24464e29ed3b6136b7c57881ea4a Mon Sep 17 00:00:00 2001 From: "ci.datadog-api-spec" Date: Thu, 11 Jun 2026 15:38:08 +0000 Subject: [PATCH] Regenerate client from commit f4bff5f of spec repo --- .generator/schemas/v2/openapi.yaml | 302 ++++++++++++ ...alth-insights_ListNetworkHealthInsights.rs | 19 + src/datadog/configuration.rs | 1 + .../api/api_network_health_insights.rs | 263 +++++++++++ src/datadogV2/api/mod.rs | 1 + src/datadogV2/mod.rs | 1 + src/datadogV2/model/mod.rs | 14 + .../model/model_network_health_insight.rs | 126 +++++ ...model_network_health_insight_attributes.rs | 443 ++++++++++++++++++ .../model_network_health_insight_category.rs | 57 +++ ...del_network_health_insight_failure_type.rs | 66 +++ ...l_network_health_insight_traffic_volume.rs | 141 ++++++ .../model_network_health_insights_response.rs | 94 ++++ .../model_network_health_insights_type.rs | 48 ++ .../v2/network_health_insights.feature | 23 + tests/scenarios/features/v2/undo.json | 6 + tests/scenarios/function_mappings.rs | 49 ++ 17 files changed, 1654 insertions(+) create mode 100644 examples/v2_network-health-insights_ListNetworkHealthInsights.rs create mode 100644 src/datadogV2/api/api_network_health_insights.rs create mode 100644 src/datadogV2/model/model_network_health_insight.rs create mode 100644 src/datadogV2/model/model_network_health_insight_attributes.rs create mode 100644 src/datadogV2/model/model_network_health_insight_category.rs create mode 100644 src/datadogV2/model/model_network_health_insight_failure_type.rs create mode 100644 src/datadogV2/model/model_network_health_insight_traffic_volume.rs create mode 100644 src/datadogV2/model/model_network_health_insights_response.rs create mode 100644 src/datadogV2/model/model_network_health_insights_type.rs create mode 100644 tests/scenarios/features/v2/network_health_insights.feature diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index fd5ed0088..2330cee6f 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -58756,6 +58756,191 @@ components: - type - attributes type: object + NetworkHealthInsight: + description: A single network health insight describing a service-to-service connectivity issue. + properties: + attributes: + $ref: "#/components/schemas/NetworkHealthInsightAttributes" + id: + description: Unique identifier for this network health insight. + example: example-insight-id + type: string + type: + $ref: "#/components/schemas/NetworkHealthInsightsType" + required: + - type + - id + - attributes + type: object + NetworkHealthInsightAttributes: + description: Detailed attributes of a network health insight. + properties: + account_id: + description: AWS account identifier where the certificate is located. Only set for `tls-cert` insights. + example: "123456789012" + type: string + certificate_id: + description: ARN or identifier of the certificate. Only set for `tls-cert` insights. + example: "arn:aws:acm:us-east-1:123456789012:certificate/abcd1234-a123-456b-a123-12345678901f" + type: string + certificate_lifetime_percent: + description: |- + Percentage of the certificate's validity period that has elapsed, ranging from 0 to 100. + Only set for `tls-cert` insights. + example: 96.7 + format: double + type: number + client_region: + description: AWS region where the client is located. Only set for `tls-cert` insights. + example: us-west-2 + type: string + client_service: + description: |- + Name of the service making the request (DNS query or TLS-secured connection). + Set to `N/A` when the client service cannot be determined. + example: network-logger + type: string + days_until_expiration: + description: |- + Number of days remaining until the certificate expires. Negative values indicate the + certificate has already expired. Only set for `tls-cert` insights. + example: 3 + format: int64 + type: integer + dns_query: + description: Domain name that was being resolved when the DNS failure occurred. Only set for `dns` insights. + example: kafka-broker.internal.domain.com + type: string + dns_server: + description: DNS server that received the failing query. Only set for `dns` insights. + example: cluster-dns + type: string + domain_name: + description: Domain name covered by the certificate. Only set for `tls-cert` insights. + example: api.example.com + type: string + failure_magnitude: + description: |- + Count of failed events observed during the query window. Only set for `dns`, `tcp`, + and `security-group` insights. + example: 150 + format: int64 + minimum: 0 + type: integer + failure_rate: + description: |- + Percentage of requests that failed during the query window, ranging from 0 to 100. + Only set for `dns`, `tcp`, and `security-group` insights. + example: 91 + format: double + maximum: 100 + minimum: 0 + type: number + failure_type: + $ref: "#/components/schemas/NetworkHealthInsightFailureType" + loadbalancer_id: + description: ARN of the load balancer using the certificate. Only set for `tls-cert` insights. + example: "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/my-lb/50dc6c495c0c9188" + type: string + server_region: + description: AWS region where the server or load balancer is located. Only set for `tls-cert` insights. + example: us-east-1 + type: string + server_service: + description: Name of the target service the client was trying to reach. + example: kafka + type: string + total_requests: + description: |- + Total number of requests observed during the query window. Provides context for + `failure_magnitude` and `failure_rate`. Only set for `dns`, `tcp`, and `security-group` insights. + example: 1200 + format: int64 + minimum: 0 + type: integer + traffic_volume: + $ref: "#/components/schemas/NetworkHealthInsightTrafficVolume" + type: + $ref: "#/components/schemas/NetworkHealthInsightCategory" + type: object + NetworkHealthInsightCategory: + description: |- + Category of network health insight. Indicates whether the insight relates to a DNS issue (`dns`), + a TCP issue (`tcp`), a TLS certificate issue (`tls-cert`), or a security group denial (`security-group`). + enum: + - dns + - tcp + - tls-cert + - security-group + example: dns + type: string + x-enum-varnames: + - DNS + - TCP + - TLS_CERT + - SECURITY_GROUP + NetworkHealthInsightFailureType: + description: |- + Specific failure type within the insight category. For DNS insights: `timeout`, `nxdomain`, + `servfail`, or `general_failure`. For TLS certificate insights: `expired` or `expiring_soon`. + For security group insights: `denied`. + enum: + - timeout + - nxdomain + - servfail + - general_failure + - expired + - expiring_soon + - denied + example: nxdomain + type: string + x-enum-varnames: + - TIMEOUT + - NXDOMAIN + - SERVFAIL + - GENERAL_FAILURE + - EXPIRED + - EXPIRING_SOON + - DENIED + NetworkHealthInsightTrafficVolume: + description: Network traffic volume metrics between the client and server services during the query window. + properties: + bytes_read: + description: Total bytes read from the server to the client during the query window. + example: 1800000 + format: int64 + type: integer + bytes_written: + description: Total bytes written from the client to the server during the query window. + example: 2500000 + format: int64 + type: integer + total_traffic: + description: Sum of bytes written and bytes read across the query window. + example: 4300000 + format: int64 + type: integer + type: object + NetworkHealthInsightsResponse: + description: Response containing a list of network health insights for the organization. + properties: + data: + description: Array of network health insights returned for the query window. + items: + $ref: "#/components/schemas/NetworkHealthInsight" + type: array + required: + - data + type: object + NetworkHealthInsightsType: + default: network-health-insights + description: The resource type for network health insights. Always `network-health-insights`. + enum: + - network-health-insights + example: network-health-insights + type: string + x-enum-varnames: + - NETWORK_HEALTH_INSIGHTS NodeType: additionalProperties: {} description: A tree-sitter node type definition for a given language, describing the node's structure, subtypes, and fields. @@ -147560,6 +147745,118 @@ paths: summary: Update the tags for an interface tags: - Network Device Monitoring + /api/v2/network-health-insights: + get: + description: |- + Return network health insights for the organization within the given time window. + Insights are produced by analyzing DNS failures pre-classified by `network-dns-logger`, + TLS certificate metrics, and denied security group connections. Each insight + identifies the client and server services involved, the type of issue, and the + magnitude of the failure observed during the query window. + operationId: ListNetworkHealthInsights + parameters: + - description: |- + Unix timestamp (number of seconds since epoch) of the start of the query window. + If not provided, the start of the query window will be 15 minutes before the `to` timestamp. + If neither `from` nor `to` are provided, the query window will be `[now - 15m, now]`. + example: "1716800000" + in: query + name: from + required: false + schema: + type: string + - description: |- + Unix timestamp (number of seconds since epoch) of the end of the query window. + If not provided, the end of the query window will be the current time. + If neither `from` nor `to` are provided, the query window will be `[now - 15m, now]`. + example: "1716800900" + in: query + name: to + required: false + schema: + type: string + responses: + "200": + content: + application/json: + examples: + default: + value: + data: + - attributes: + client_service: "network-logger" + dns_query: "kafka-broker.internal.domain.com" + dns_server: "cluster-dns" + failure_magnitude: 150 + failure_rate: 91 + failure_type: "nxdomain" + server_service: "kafka" + total_requests: 1200 + traffic_volume: + bytes_read: 1800000 + bytes_written: 2500000 + total_traffic: 4300000 + type: "dns" + id: "example-insight-id" + type: "network-health-insights" + - attributes: + account_id: "123456789012" + certificate_id: "arn:aws:acm:us-east-1:123456789012:certificate/abcd1234-a123-456b-a123-12345678901f" + certificate_lifetime_percent: 96.7 + client_region: "us-west-2" + client_service: "N/A" + days_until_expiration: 3 + domain_name: "api.example.com" + failure_type: "expiring_soon" + loadbalancer_id: "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/my-lb/50dc6c495c0c9188" + server_region: "us-east-1" + server_service: "web-frontend" + type: "tls-cert" + id: "example-cert-insight-id" + type: "network-health-insights" + - attributes: + client_service: "web-frontend" + failure_magnitude: 85 + failure_rate: 68.5 + failure_type: "denied" + server_service: "database" + total_requests: 124 + type: "security-group" + id: "example-security-group-insight-id" + type: "network-health-insights" + schema: + $ref: "#/components/schemas/NetworkHealthInsightsResponse" + description: OK + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Bad Request + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Forbidden + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Internal Server Error + summary: List network health insights + tags: + - Network Health Insights + x-permission: + operator: OR + permissions: + - network_health_insights_read + x-unstable: |- + **Note**: This endpoint is in preview and is subject to change. + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). /api/v2/network/connections/aggregate: get: description: Get all aggregated connections. @@ -184659,6 +184956,11 @@ tags: - description: |- The Network Device Monitoring API allows you to fetch devices and interfaces and their attributes. See the [Network Device Monitoring page](https://docs.datadoghq.com/network_monitoring/) for more information. name: Network Device Monitoring + - description: |- + Analyze network health by surfacing actionable insights for services experiencing connectivity issues. + Insights are derived from DNS failure data (timeouts, NXDOMAIN, SERVFAIL, general failures), + TLS certificate health (expired, expiring soon), and security group denials. + name: Network Health Insights - description: |- Configure OAuth2 clients for Datadog. Supports RFC 7591 Dynamic Client Registration and management of OAuth2 client scopes restrictions. diff --git a/examples/v2_network-health-insights_ListNetworkHealthInsights.rs b/examples/v2_network-health-insights_ListNetworkHealthInsights.rs new file mode 100644 index 000000000..029d46143 --- /dev/null +++ b/examples/v2_network-health-insights_ListNetworkHealthInsights.rs @@ -0,0 +1,19 @@ +// List network health insights returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_network_health_insights::ListNetworkHealthInsightsOptionalParams; +use datadog_api_client::datadogV2::api_network_health_insights::NetworkHealthInsightsAPI; + +#[tokio::main] +async fn main() { + let mut configuration = datadog::Configuration::new(); + configuration.set_unstable_operation_enabled("v2.ListNetworkHealthInsights", true); + let api = NetworkHealthInsightsAPI::with_config(configuration); + let resp = api + .list_network_health_insights(ListNetworkHealthInsightsOptionalParams::default()) + .await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/src/datadog/configuration.rs b/src/datadog/configuration.rs index 14bfb144a..84f30a6f0 100644 --- a/src/datadog/configuration.rs +++ b/src/datadog/configuration.rs @@ -574,6 +574,7 @@ impl Default for Configuration { false, ), ("v2.validate_monitor_user_template".to_owned(), false), + ("v2.list_network_health_insights".to_owned(), false), ("v2.delete_scopes_restriction".to_owned(), false), ("v2.get_o_auth2_well_known_sites".to_owned(), false), ("v2.get_scopes_restriction".to_owned(), false), diff --git a/src/datadogV2/api/api_network_health_insights.rs b/src/datadogV2/api/api_network_health_insights.rs new file mode 100644 index 000000000..1b7767a28 --- /dev/null +++ b/src/datadogV2/api/api_network_health_insights.rs @@ -0,0 +1,263 @@ +// 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 crate::datadog; +use log::warn; +use reqwest::header::{HeaderMap, HeaderValue}; +use serde::{Deserialize, Serialize}; + +/// ListNetworkHealthInsightsOptionalParams is a struct for passing parameters to the method [`NetworkHealthInsightsAPI::list_network_health_insights`] +#[non_exhaustive] +#[derive(Clone, Default, Debug)] +pub struct ListNetworkHealthInsightsOptionalParams { + /// Unix timestamp (number of seconds since epoch) of the start of the query window. + /// If not provided, the start of the query window will be 15 minutes before the `to` timestamp. + /// If neither `from` nor `to` are provided, the query window will be `[now - 15m, now]`. + pub from: Option, + /// Unix timestamp (number of seconds since epoch) of the end of the query window. + /// If not provided, the end of the query window will be the current time. + /// If neither `from` nor `to` are provided, the query window will be `[now - 15m, now]`. + pub to: Option, +} + +impl ListNetworkHealthInsightsOptionalParams { + /// Unix timestamp (number of seconds since epoch) of the start of the query window. + /// If not provided, the start of the query window will be 15 minutes before the `to` timestamp. + /// If neither `from` nor `to` are provided, the query window will be `[now - 15m, now]`. + pub fn from(mut self, value: String) -> Self { + self.from = Some(value); + self + } + /// Unix timestamp (number of seconds since epoch) of the end of the query window. + /// If not provided, the end of the query window will be the current time. + /// If neither `from` nor `to` are provided, the query window will be `[now - 15m, now]`. + pub fn to(mut self, value: String) -> Self { + self.to = Some(value); + self + } +} + +/// ListNetworkHealthInsightsError is a struct for typed errors of method [`NetworkHealthInsightsAPI::list_network_health_insights`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ListNetworkHealthInsightsError { + JSONAPIErrorResponse(crate::datadogV2::model::JSONAPIErrorResponse), + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + +/// Analyze network health by surfacing actionable insights for services experiencing connectivity issues. +/// Insights are derived from DNS failure data (timeouts, NXDOMAIN, SERVFAIL, general failures), +/// TLS certificate health (expired, expiring soon), and security group denials. +#[derive(Debug, Clone)] +pub struct NetworkHealthInsightsAPI { + config: datadog::Configuration, + client: reqwest_middleware::ClientWithMiddleware, +} + +impl Default for NetworkHealthInsightsAPI { + fn default() -> Self { + Self::with_config(datadog::Configuration::default()) + } +} + +impl NetworkHealthInsightsAPI { + pub fn new() -> Self { + Self::default() + } + pub fn with_config(config: datadog::Configuration) -> Self { + let reqwest_client_builder = { + let builder = reqwest::Client::builder(); + #[cfg(not(target_arch = "wasm32"))] + let builder = if let Some(proxy_url) = &config.proxy_url { + builder.proxy(reqwest::Proxy::all(proxy_url).expect("Failed to parse proxy URL")) + } else { + builder + }; + builder + }; + + let middleware_client_builder = { + let builder = + reqwest_middleware::ClientBuilder::new(reqwest_client_builder.build().unwrap()); + #[cfg(feature = "retry")] + let builder = if config.enable_retry { + struct RetryableStatus; + impl reqwest_retry::RetryableStrategy for RetryableStatus { + fn handle( + &self, + res: &Result, + ) -> Option { + match res { + Ok(success) => reqwest_retry::default_on_request_success(success), + Err(_) => None, + } + } + } + let backoff_policy = reqwest_retry::policies::ExponentialBackoff::builder() + .build_with_max_retries(config.max_retries); + + let retry_middleware = + reqwest_retry::RetryTransientMiddleware::new_with_policy_and_strategy( + backoff_policy, + RetryableStatus, + ); + + builder.with(retry_middleware) + } else { + builder + }; + builder + }; + + let client = middleware_client_builder.build(); + + Self { config, client } + } + + pub fn with_client_and_config( + config: datadog::Configuration, + client: reqwest_middleware::ClientWithMiddleware, + ) -> Self { + Self { config, client } + } + + /// Return network health insights for the organization within the given time window. + /// Insights are produced by analyzing DNS failures pre-classified by `network-dns-logger`, + /// TLS certificate metrics, and denied security group connections. Each insight + /// identifies the client and server services involved, the type of issue, and the + /// magnitude of the failure observed during the query window. + pub async fn list_network_health_insights( + &self, + params: ListNetworkHealthInsightsOptionalParams, + ) -> Result< + crate::datadogV2::model::NetworkHealthInsightsResponse, + datadog::Error, + > { + match self + .list_network_health_insights_with_http_info(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), + } + } + + /// Return network health insights for the organization within the given time window. + /// Insights are produced by analyzing DNS failures pre-classified by `network-dns-logger`, + /// TLS certificate metrics, and denied security group connections. Each insight + /// identifies the client and server services involved, the type of issue, and the + /// magnitude of the failure observed during the query window. + pub async fn list_network_health_insights_with_http_info( + &self, + params: ListNetworkHealthInsightsOptionalParams, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.list_network_health_insights"; + if local_configuration.is_unstable_operation_enabled(operation_id) { + warn!("Using unstable operation {operation_id}"); + } else { + let local_error = datadog::UnstableOperationDisabledError { + msg: "Operation 'v2.list_network_health_insights' is not enabled".to_string(), + }; + return Err(datadog::Error::UnstableOperationDisabledError(local_error)); + } + + // unbox and build optional parameters + let from = params.from; + let to = params.to; + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/network-health-insights", + local_configuration.get_operation_host(operation_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::GET, local_uri_str.as_str()); + + if let Some(ref local_query_param) = from { + local_req_builder = + local_req_builder.query(&[("from", &local_query_param.to_string())]); + }; + if let Some(ref local_query_param) = to { + local_req_builder = local_req_builder.query(&[("to", &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)) + } + } +} diff --git a/src/datadogV2/api/mod.rs b/src/datadogV2/api/mod.rs index a611a90ab..1c5c3bc22 100644 --- a/src/datadogV2/api/mod.rs +++ b/src/datadogV2/api/mod.rs @@ -75,6 +75,7 @@ pub mod api_microsoft_teams_integration; pub mod api_model_lab_api; pub mod api_monitors; pub mod api_network_device_monitoring; +pub mod api_network_health_insights; pub mod api_o_auth2_client_public; pub mod api_observability_pipelines; pub mod api_oci_integration; diff --git a/src/datadogV2/mod.rs b/src/datadogV2/mod.rs index 89ca6eaba..c5fc979a8 100644 --- a/src/datadogV2/mod.rs +++ b/src/datadogV2/mod.rs @@ -76,6 +76,7 @@ pub use self::api::api_microsoft_teams_integration; pub use self::api::api_model_lab_api; pub use self::api::api_monitors; pub use self::api::api_network_device_monitoring; +pub use self::api::api_network_health_insights; pub use self::api::api_o_auth2_client_public; pub use self::api::api_observability_pipelines; pub use self::api::api_oci_integration; diff --git a/src/datadogV2/model/mod.rs b/src/datadogV2/model/mod.rs index bf1fd2384..728809b47 100644 --- a/src/datadogV2/model/mod.rs +++ b/src/datadogV2/model/mod.rs @@ -6602,6 +6602,20 @@ pub mod model_list_interface_tags_response; pub use self::model_list_interface_tags_response::ListInterfaceTagsResponse; pub mod model_list_interface_tags_response_data; pub use self::model_list_interface_tags_response_data::ListInterfaceTagsResponseData; +pub mod model_network_health_insights_response; +pub use self::model_network_health_insights_response::NetworkHealthInsightsResponse; +pub mod model_network_health_insight; +pub use self::model_network_health_insight::NetworkHealthInsight; +pub mod model_network_health_insight_attributes; +pub use self::model_network_health_insight_attributes::NetworkHealthInsightAttributes; +pub mod model_network_health_insight_failure_type; +pub use self::model_network_health_insight_failure_type::NetworkHealthInsightFailureType; +pub mod model_network_health_insight_traffic_volume; +pub use self::model_network_health_insight_traffic_volume::NetworkHealthInsightTrafficVolume; +pub mod model_network_health_insight_category; +pub use self::model_network_health_insight_category::NetworkHealthInsightCategory; +pub mod model_network_health_insights_type; +pub use self::model_network_health_insights_type::NetworkHealthInsightsType; pub mod model_single_aggregated_connection_response_array; pub use self::model_single_aggregated_connection_response_array::SingleAggregatedConnectionResponseArray; pub mod model_single_aggregated_connection_response_data; diff --git a/src/datadogV2/model/model_network_health_insight.rs b/src/datadogV2/model/model_network_health_insight.rs new file mode 100644 index 000000000..9a57c339a --- /dev/null +++ b/src/datadogV2/model/model_network_health_insight.rs @@ -0,0 +1,126 @@ +// 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 single network health insight describing a service-to-service connectivity issue. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct NetworkHealthInsight { + /// Detailed attributes of a network health insight. + #[serde(rename = "attributes")] + pub attributes: crate::datadogV2::model::NetworkHealthInsightAttributes, + /// Unique identifier for this network health insight. + #[serde(rename = "id")] + pub id: String, + /// The resource type for network health insights. Always `network-health-insights`. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::NetworkHealthInsightsType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl NetworkHealthInsight { + pub fn new( + attributes: crate::datadogV2::model::NetworkHealthInsightAttributes, + id: String, + type_: crate::datadogV2::model::NetworkHealthInsightsType, + ) -> NetworkHealthInsight { + NetworkHealthInsight { + 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 NetworkHealthInsight { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct NetworkHealthInsightVisitor; + impl<'a> Visitor<'a> for NetworkHealthInsightVisitor { + type Value = NetworkHealthInsight; + + 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::NetworkHealthInsightAttributes, + > = 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::NetworkHealthInsightsType::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 = NetworkHealthInsight { + attributes, + id, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(NetworkHealthInsightVisitor) + } +} diff --git a/src/datadogV2/model/model_network_health_insight_attributes.rs b/src/datadogV2/model/model_network_health_insight_attributes.rs new file mode 100644 index 000000000..9251b1335 --- /dev/null +++ b/src/datadogV2/model/model_network_health_insight_attributes.rs @@ -0,0 +1,443 @@ +// 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}; + +/// Detailed attributes of a network health insight. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct NetworkHealthInsightAttributes { + /// AWS account identifier where the certificate is located. Only set for `tls-cert` insights. + #[serde(rename = "account_id")] + pub account_id: Option, + /// ARN or identifier of the certificate. Only set for `tls-cert` insights. + #[serde(rename = "certificate_id")] + pub certificate_id: Option, + /// Percentage of the certificate's validity period that has elapsed, ranging from 0 to 100. + /// Only set for `tls-cert` insights. + #[serde(rename = "certificate_lifetime_percent")] + pub certificate_lifetime_percent: Option, + /// AWS region where the client is located. Only set for `tls-cert` insights. + #[serde(rename = "client_region")] + pub client_region: Option, + /// Name of the service making the request (DNS query or TLS-secured connection). + /// Set to `N/A` when the client service cannot be determined. + #[serde(rename = "client_service")] + pub client_service: Option, + /// Number of days remaining until the certificate expires. Negative values indicate the + /// certificate has already expired. Only set for `tls-cert` insights. + #[serde(rename = "days_until_expiration")] + pub days_until_expiration: Option, + /// Domain name that was being resolved when the DNS failure occurred. Only set for `dns` insights. + #[serde(rename = "dns_query")] + pub dns_query: Option, + /// DNS server that received the failing query. Only set for `dns` insights. + #[serde(rename = "dns_server")] + pub dns_server: Option, + /// Domain name covered by the certificate. Only set for `tls-cert` insights. + #[serde(rename = "domain_name")] + pub domain_name: Option, + /// Count of failed events observed during the query window. Only set for `dns`, `tcp`, + /// and `security-group` insights. + #[serde(rename = "failure_magnitude")] + pub failure_magnitude: Option, + /// Percentage of requests that failed during the query window, ranging from 0 to 100. + /// Only set for `dns`, `tcp`, and `security-group` insights. + #[serde(rename = "failure_rate")] + pub failure_rate: Option, + /// Specific failure type within the insight category. For DNS insights: `timeout`, `nxdomain`, + /// `servfail`, or `general_failure`. For TLS certificate insights: `expired` or `expiring_soon`. + /// For security group insights: `denied`. + #[serde(rename = "failure_type")] + pub failure_type: Option, + /// ARN of the load balancer using the certificate. Only set for `tls-cert` insights. + #[serde(rename = "loadbalancer_id")] + pub loadbalancer_id: Option, + /// AWS region where the server or load balancer is located. Only set for `tls-cert` insights. + #[serde(rename = "server_region")] + pub server_region: Option, + /// Name of the target service the client was trying to reach. + #[serde(rename = "server_service")] + pub server_service: Option, + /// Total number of requests observed during the query window. Provides context for + /// `failure_magnitude` and `failure_rate`. Only set for `dns`, `tcp`, and `security-group` insights. + #[serde(rename = "total_requests")] + pub total_requests: Option, + /// Network traffic volume metrics between the client and server services during the query window. + #[serde(rename = "traffic_volume")] + pub traffic_volume: Option, + /// Category of network health insight. Indicates whether the insight relates to a DNS issue (`dns`), + /// a TCP issue (`tcp`), a TLS certificate issue (`tls-cert`), or a security group denial (`security-group`). + #[serde(rename = "type")] + pub type_: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl NetworkHealthInsightAttributes { + pub fn new() -> NetworkHealthInsightAttributes { + NetworkHealthInsightAttributes { + account_id: None, + certificate_id: None, + certificate_lifetime_percent: None, + client_region: None, + client_service: None, + days_until_expiration: None, + dns_query: None, + dns_server: None, + domain_name: None, + failure_magnitude: None, + failure_rate: None, + failure_type: None, + loadbalancer_id: None, + server_region: None, + server_service: None, + total_requests: None, + traffic_volume: None, + type_: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn account_id(mut self, value: String) -> Self { + self.account_id = Some(value); + self + } + + pub fn certificate_id(mut self, value: String) -> Self { + self.certificate_id = Some(value); + self + } + + pub fn certificate_lifetime_percent(mut self, value: f64) -> Self { + self.certificate_lifetime_percent = Some(value); + self + } + + pub fn client_region(mut self, value: String) -> Self { + self.client_region = Some(value); + self + } + + pub fn client_service(mut self, value: String) -> Self { + self.client_service = Some(value); + self + } + + pub fn days_until_expiration(mut self, value: i64) -> Self { + self.days_until_expiration = Some(value); + self + } + + pub fn dns_query(mut self, value: String) -> Self { + self.dns_query = Some(value); + self + } + + pub fn dns_server(mut self, value: String) -> Self { + self.dns_server = Some(value); + self + } + + pub fn domain_name(mut self, value: String) -> Self { + self.domain_name = Some(value); + self + } + + pub fn failure_magnitude(mut self, value: i64) -> Self { + self.failure_magnitude = Some(value); + self + } + + pub fn failure_rate(mut self, value: f64) -> Self { + self.failure_rate = Some(value); + self + } + + pub fn failure_type( + mut self, + value: crate::datadogV2::model::NetworkHealthInsightFailureType, + ) -> Self { + self.failure_type = Some(value); + self + } + + pub fn loadbalancer_id(mut self, value: String) -> Self { + self.loadbalancer_id = Some(value); + self + } + + pub fn server_region(mut self, value: String) -> Self { + self.server_region = Some(value); + self + } + + pub fn server_service(mut self, value: String) -> Self { + self.server_service = Some(value); + self + } + + pub fn total_requests(mut self, value: i64) -> Self { + self.total_requests = Some(value); + self + } + + pub fn traffic_volume( + mut self, + value: crate::datadogV2::model::NetworkHealthInsightTrafficVolume, + ) -> Self { + self.traffic_volume = Some(value); + self + } + + pub fn type_(mut self, value: crate::datadogV2::model::NetworkHealthInsightCategory) -> Self { + self.type_ = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for NetworkHealthInsightAttributes { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for NetworkHealthInsightAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct NetworkHealthInsightAttributesVisitor; + impl<'a> Visitor<'a> for NetworkHealthInsightAttributesVisitor { + type Value = NetworkHealthInsightAttributes; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut account_id: Option = None; + let mut certificate_id: Option = None; + let mut certificate_lifetime_percent: Option = None; + let mut client_region: Option = None; + let mut client_service: Option = None; + let mut days_until_expiration: Option = None; + let mut dns_query: Option = None; + let mut dns_server: Option = None; + let mut domain_name: Option = None; + let mut failure_magnitude: Option = None; + let mut failure_rate: Option = None; + let mut failure_type: Option< + crate::datadogV2::model::NetworkHealthInsightFailureType, + > = None; + let mut loadbalancer_id: Option = None; + let mut server_region: Option = None; + let mut server_service: Option = None; + let mut total_requests: Option = None; + let mut traffic_volume: Option< + crate::datadogV2::model::NetworkHealthInsightTrafficVolume, + > = 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() { + "account_id" => { + if v.is_null() { + continue; + } + account_id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "certificate_id" => { + if v.is_null() { + continue; + } + certificate_id = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "certificate_lifetime_percent" => { + if v.is_null() || v.as_str() == Some("") { + continue; + } + certificate_lifetime_percent = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "client_region" => { + if v.is_null() { + continue; + } + client_region = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "client_service" => { + if v.is_null() { + continue; + } + client_service = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "days_until_expiration" => { + if v.is_null() { + continue; + } + days_until_expiration = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "dns_query" => { + if v.is_null() { + continue; + } + dns_query = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "dns_server" => { + if v.is_null() { + continue; + } + dns_server = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "domain_name" => { + if v.is_null() { + continue; + } + domain_name = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "failure_magnitude" => { + if v.is_null() { + continue; + } + failure_magnitude = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "failure_rate" => { + if v.is_null() || v.as_str() == Some("") { + continue; + } + failure_rate = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "failure_type" => { + if v.is_null() { + continue; + } + failure_type = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _failure_type) = failure_type { + match _failure_type { + crate::datadogV2::model::NetworkHealthInsightFailureType::UnparsedObject(_failure_type) => { + _unparsed = true; + }, + _ => {} + } + } + } + "loadbalancer_id" => { + if v.is_null() { + continue; + } + loadbalancer_id = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "server_region" => { + if v.is_null() { + continue; + } + server_region = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "server_service" => { + if v.is_null() { + continue; + } + server_service = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "total_requests" => { + if v.is_null() { + continue; + } + total_requests = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "traffic_volume" => { + if v.is_null() { + continue; + } + traffic_volume = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + if v.is_null() { + continue; + } + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::NetworkHealthInsightCategory::UnparsedObject(_type_) => { + _unparsed = true; + }, + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = NetworkHealthInsightAttributes { + account_id, + certificate_id, + certificate_lifetime_percent, + client_region, + client_service, + days_until_expiration, + dns_query, + dns_server, + domain_name, + failure_magnitude, + failure_rate, + failure_type, + loadbalancer_id, + server_region, + server_service, + total_requests, + traffic_volume, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(NetworkHealthInsightAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_network_health_insight_category.rs b/src/datadogV2/model/model_network_health_insight_category.rs new file mode 100644 index 000000000..311b2b3e2 --- /dev/null +++ b/src/datadogV2/model/model_network_health_insight_category.rs @@ -0,0 +1,57 @@ +// 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 NetworkHealthInsightCategory { + DNS, + TCP, + TLS_CERT, + SECURITY_GROUP, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for NetworkHealthInsightCategory { + fn to_string(&self) -> String { + match self { + Self::DNS => String::from("dns"), + Self::TCP => String::from("tcp"), + Self::TLS_CERT => String::from("tls-cert"), + Self::SECURITY_GROUP => String::from("security-group"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for NetworkHealthInsightCategory { + 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 NetworkHealthInsightCategory { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "dns" => Self::DNS, + "tcp" => Self::TCP, + "tls-cert" => Self::TLS_CERT, + "security-group" => Self::SECURITY_GROUP, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/src/datadogV2/model/model_network_health_insight_failure_type.rs b/src/datadogV2/model/model_network_health_insight_failure_type.rs new file mode 100644 index 000000000..a04746e59 --- /dev/null +++ b/src/datadogV2/model/model_network_health_insight_failure_type.rs @@ -0,0 +1,66 @@ +// 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 NetworkHealthInsightFailureType { + TIMEOUT, + NXDOMAIN, + SERVFAIL, + GENERAL_FAILURE, + EXPIRED, + EXPIRING_SOON, + DENIED, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for NetworkHealthInsightFailureType { + fn to_string(&self) -> String { + match self { + Self::TIMEOUT => String::from("timeout"), + Self::NXDOMAIN => String::from("nxdomain"), + Self::SERVFAIL => String::from("servfail"), + Self::GENERAL_FAILURE => String::from("general_failure"), + Self::EXPIRED => String::from("expired"), + Self::EXPIRING_SOON => String::from("expiring_soon"), + Self::DENIED => String::from("denied"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for NetworkHealthInsightFailureType { + 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 NetworkHealthInsightFailureType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "timeout" => Self::TIMEOUT, + "nxdomain" => Self::NXDOMAIN, + "servfail" => Self::SERVFAIL, + "general_failure" => Self::GENERAL_FAILURE, + "expired" => Self::EXPIRED, + "expiring_soon" => Self::EXPIRING_SOON, + "denied" => Self::DENIED, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/src/datadogV2/model/model_network_health_insight_traffic_volume.rs b/src/datadogV2/model/model_network_health_insight_traffic_volume.rs new file mode 100644 index 000000000..854df197b --- /dev/null +++ b/src/datadogV2/model/model_network_health_insight_traffic_volume.rs @@ -0,0 +1,141 @@ +// 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}; + +/// Network traffic volume metrics between the client and server services during the query window. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct NetworkHealthInsightTrafficVolume { + /// Total bytes read from the server to the client during the query window. + #[serde(rename = "bytes_read")] + pub bytes_read: Option, + /// Total bytes written from the client to the server during the query window. + #[serde(rename = "bytes_written")] + pub bytes_written: Option, + /// Sum of bytes written and bytes read across the query window. + #[serde(rename = "total_traffic")] + pub total_traffic: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl NetworkHealthInsightTrafficVolume { + pub fn new() -> NetworkHealthInsightTrafficVolume { + NetworkHealthInsightTrafficVolume { + bytes_read: None, + bytes_written: None, + total_traffic: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn bytes_read(mut self, value: i64) -> Self { + self.bytes_read = Some(value); + self + } + + pub fn bytes_written(mut self, value: i64) -> Self { + self.bytes_written = Some(value); + self + } + + pub fn total_traffic(mut self, value: i64) -> Self { + self.total_traffic = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for NetworkHealthInsightTrafficVolume { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for NetworkHealthInsightTrafficVolume { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct NetworkHealthInsightTrafficVolumeVisitor; + impl<'a> Visitor<'a> for NetworkHealthInsightTrafficVolumeVisitor { + type Value = NetworkHealthInsightTrafficVolume; + + 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 bytes_read: Option = None; + let mut bytes_written: Option = None; + let mut total_traffic: 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() { + "bytes_read" => { + if v.is_null() { + continue; + } + bytes_read = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "bytes_written" => { + if v.is_null() { + continue; + } + bytes_written = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "total_traffic" => { + if v.is_null() { + continue; + } + total_traffic = + 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 = NetworkHealthInsightTrafficVolume { + bytes_read, + bytes_written, + total_traffic, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(NetworkHealthInsightTrafficVolumeVisitor) + } +} diff --git a/src/datadogV2/model/model_network_health_insights_response.rs b/src/datadogV2/model/model_network_health_insights_response.rs new file mode 100644 index 000000000..acead1b50 --- /dev/null +++ b/src/datadogV2/model/model_network_health_insights_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 containing a list of network health insights for the organization. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct NetworkHealthInsightsResponse { + /// Array of network health insights returned for the query window. + #[serde(rename = "data")] + pub data: Vec, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl NetworkHealthInsightsResponse { + pub fn new( + data: Vec, + ) -> NetworkHealthInsightsResponse { + NetworkHealthInsightsResponse { + 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 NetworkHealthInsightsResponse { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct NetworkHealthInsightsResponseVisitor; + impl<'a> Visitor<'a> for NetworkHealthInsightsResponseVisitor { + type Value = NetworkHealthInsightsResponse; + + 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 = NetworkHealthInsightsResponse { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(NetworkHealthInsightsResponseVisitor) + } +} diff --git a/src/datadogV2/model/model_network_health_insights_type.rs b/src/datadogV2/model/model_network_health_insights_type.rs new file mode 100644 index 000000000..4f61bdd2b --- /dev/null +++ b/src/datadogV2/model/model_network_health_insights_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 NetworkHealthInsightsType { + NETWORK_HEALTH_INSIGHTS, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for NetworkHealthInsightsType { + fn to_string(&self) -> String { + match self { + Self::NETWORK_HEALTH_INSIGHTS => String::from("network-health-insights"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for NetworkHealthInsightsType { + 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 NetworkHealthInsightsType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "network-health-insights" => Self::NETWORK_HEALTH_INSIGHTS, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/tests/scenarios/features/v2/network_health_insights.feature b/tests/scenarios/features/v2/network_health_insights.feature new file mode 100644 index 000000000..c5036b6af --- /dev/null +++ b/tests/scenarios/features/v2/network_health_insights.feature @@ -0,0 +1,23 @@ +@endpoint(network-health-insights) @endpoint(network-health-insights-v2) +Feature: Network Health Insights + Analyze network health by surfacing actionable insights for services + experiencing connectivity issues. Insights are derived from DNS failure + data (timeouts, NXDOMAIN, SERVFAIL, general failures), TLS certificate + health (expired, expiring soon), and security group denials. + + Background: + Given a valid "apiKeyAuth" key in the system + And a valid "appKeyAuth" key in the system + And an instance of "NetworkHealthInsights" API + And operation "ListNetworkHealthInsights" enabled + And new "ListNetworkHealthInsights" request + + @generated @skip @team:DataDog/cloud-network-monitoring + Scenario: List network health insights returns "Bad Request" response + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:DataDog/cloud-network-monitoring + Scenario: List network health insights returns "OK" response + When the request is sent + Then the response status is 200 OK diff --git a/tests/scenarios/features/v2/undo.json b/tests/scenarios/features/v2/undo.json index 2de79b4fe..0118bfb67 100644 --- a/tests/scenarios/features/v2/undo.json +++ b/tests/scenarios/features/v2/undo.json @@ -5145,6 +5145,12 @@ "type": "idempotent" } }, + "ListNetworkHealthInsights": { + "tag": "Network Health Insights", + "undo": { + "type": "safe" + } + }, "GetAggregatedConnections": { "tag": "Cloud Network Monitoring", "undo": { diff --git a/tests/scenarios/function_mappings.rs b/tests/scenarios/function_mappings.rs index 8e5e0b46a..61a6aa47b 100644 --- a/tests/scenarios/function_mappings.rs +++ b/tests/scenarios/function_mappings.rs @@ -153,6 +153,8 @@ pub struct ApiInstances { pub v2_api_monitors: Option, pub v2_api_network_device_monitoring: Option, + pub v2_api_network_health_insights: + Option, pub v2_api_cloud_network_monitoring: Option, pub v2_api_o_auth2_client_public: @@ -1040,6 +1042,12 @@ pub fn initialize_api_instance(world: &mut DatadogWorld, api: String) { world.http_client.as_ref().unwrap().clone() )); } + "NetworkHealthInsights" => { + world.api_instances.v2_api_network_health_insights = Some(datadogV2::api_network_health_insights::NetworkHealthInsightsAPI::with_client_and_config( + world.config.clone(), + world.http_client.as_ref().unwrap().clone() + )); + } "CloudNetworkMonitoring" => { world.api_instances.v2_api_cloud_network_monitoring = Some(datadogV2::api_cloud_network_monitoring::CloudNetworkMonitoringAPI::with_client_and_config( world.config.clone(), @@ -5676,6 +5684,10 @@ pub fn collect_function_calls(world: &mut DatadogWorld) { "v2.UpdateInterfaceUserTags".into(), test_v2_update_interface_user_tags, ); + world.function_mappings.insert( + "v2.ListNetworkHealthInsights".into(), + test_v2_list_network_health_insights, + ); world.function_mappings.insert( "v2.GetAggregatedConnections".into(), test_v2_get_aggregated_connections, @@ -43957,6 +43969,43 @@ fn test_v2_update_interface_user_tags( world.response.code = response.status.as_u16(); } +fn test_v2_list_network_health_insights( + world: &mut DatadogWorld, + _parameters: &HashMap, +) { + let api = world + .api_instances + .v2_api_network_health_insights + .as_ref() + .expect("api instance not found"); + let from = _parameters + .get("from") + .and_then(|param| Some(serde_json::from_value(param.clone()).unwrap())); + let to = _parameters + .get("to") + .and_then(|param| Some(serde_json::from_value(param.clone()).unwrap())); + let mut params = + datadogV2::api_network_health_insights::ListNetworkHealthInsightsOptionalParams::default(); + params.from = from; + params.to = to; + let response = match block_on(api.list_network_health_insights_with_http_info(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_aggregated_connections( world: &mut DatadogWorld, _parameters: &HashMap,