From c3615c8895ee4ad97ffd0f516b64038a8c666ad7 Mon Sep 17 00:00:00 2001 From: "ci.datadog-api-spec" Date: Thu, 23 Oct 2025 11:38:50 +0000 Subject: [PATCH] Regenerate client from commit e118b2e of spec repo --- .generator/schemas/v2/openapi.yaml | 422 +++++++++++ ..._fleet-automation_CancelFleetDeployment.rs | 18 + ...tomation_CreateFleetDeploymentConfigure.rs | 36 + .../v2_fleet-automation_GetFleetDeployment.rs | 18 + ...2_fleet-automation_ListFleetDeployments.rs | 19 + src/datadog/configuration.rs | 4 + src/datadogV2/api/api_fleet_automation.rs | 656 ++++++++++++++++++ src/datadogV2/api/mod.rs | 1 + src/datadogV2/mod.rs | 1 + src/datadogV2/model/mod.rs | 28 +- src/datadogV2/model/model_fleet_deployment.rs | 125 ++++ .../model_fleet_deployment_attributes.rs | 183 +++++ ...l_fleet_deployment_configure_attributes.rs | 116 ++++ ...model_fleet_deployment_configure_create.rs | 115 +++ ...eet_deployment_configure_create_request.rs | 95 +++ .../model/model_fleet_deployment_file_op.rs | 51 ++ .../model/model_fleet_deployment_operation.rs | 137 ++++ .../model_fleet_deployment_resource_type.rs | 48 ++ .../model/model_fleet_deployment_response.rs | 105 +++ .../model/model_fleet_deployments_page.rs | 106 +++ .../model/model_fleet_deployments_response.rs | 109 +++ .../model_fleet_deployments_response_meta.rs | 105 +++ .../features/v2/fleet_automation.feature | 89 +++ tests/scenarios/features/v2/given.json | 13 + tests/scenarios/features/v2/undo.json | 31 + tests/scenarios/function_mappings.rs | 137 ++++ 26 files changed, 2766 insertions(+), 2 deletions(-) create mode 100644 examples/v2_fleet-automation_CancelFleetDeployment.rs create mode 100644 examples/v2_fleet-automation_CreateFleetDeploymentConfigure.rs create mode 100644 examples/v2_fleet-automation_GetFleetDeployment.rs create mode 100644 examples/v2_fleet-automation_ListFleetDeployments.rs create mode 100644 src/datadogV2/api/api_fleet_automation.rs create mode 100644 src/datadogV2/model/model_fleet_deployment.rs create mode 100644 src/datadogV2/model/model_fleet_deployment_attributes.rs create mode 100644 src/datadogV2/model/model_fleet_deployment_configure_attributes.rs create mode 100644 src/datadogV2/model/model_fleet_deployment_configure_create.rs create mode 100644 src/datadogV2/model/model_fleet_deployment_configure_create_request.rs create mode 100644 src/datadogV2/model/model_fleet_deployment_file_op.rs create mode 100644 src/datadogV2/model/model_fleet_deployment_operation.rs create mode 100644 src/datadogV2/model/model_fleet_deployment_resource_type.rs create mode 100644 src/datadogV2/model/model_fleet_deployment_response.rs create mode 100644 src/datadogV2/model/model_fleet_deployments_page.rs create mode 100644 src/datadogV2/model/model_fleet_deployments_response.rs create mode 100644 src/datadogV2/model/model_fleet_deployments_response_meta.rs create mode 100644 tests/scenarios/features/v2/fleet_automation.feature diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 364018c47..f35df7747 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -20093,6 +20093,179 @@ components: - PIPELINES_FAILED_DESCENDING - PIPELINES_DURATION_LOST_ASCENDING - PIPELINES_DURATION_LOST_DESCENDING + FleetDeployment: + description: A deployment that defines automated configuration changes for a + fleet of hosts. + properties: + attributes: + $ref: '#/components/schemas/FleetDeploymentAttributes' + id: + description: Unique identifier for the deployment. + example: aeadc05e-98a8-11ec-ac2c-da7ad0900001 + type: string + type: + $ref: '#/components/schemas/FleetDeploymentResourceType' + required: + - id + - type + - attributes + type: object + FleetDeploymentAttributes: + description: Attributes of a deployment in the response. + properties: + config_operations: + description: Ordered list of configuration file operations to perform on + the target hosts. + items: + $ref: '#/components/schemas/FleetDeploymentOperation' + type: array + estimated_end_time_unix: + description: Estimated completion time of the deployment as a Unix timestamp + (seconds since epoch). + example: 1699999999 + format: int64 + type: integer + filter_query: + description: Query used to filter and select target hosts for the deployment. + Uses the Datadog query syntax. + example: env:prod AND service:web + type: string + high_level_status: + description: Current high-level status of the deployment (for example, "pending", + "running", "completed", "failed"). + example: pending + type: string + total_hosts: + description: Total number of hosts targeted by this deployment. + example: 42 + format: int64 + type: integer + type: object + FleetDeploymentConfigureAttributes: + description: Attributes for creating a new configuration deployment. + properties: + config_operations: + description: Ordered list of configuration file operations to perform on + the target hosts. + items: + $ref: '#/components/schemas/FleetDeploymentOperation' + type: array + filter_query: + description: Query used to filter and select target hosts for the deployment. + Uses the Datadog query syntax. + example: env:prod AND service:web + type: string + required: + - config_operations + type: object + FleetDeploymentConfigureCreate: + description: Data for creating a new deployment. + properties: + attributes: + $ref: '#/components/schemas/FleetDeploymentConfigureAttributes' + type: + $ref: '#/components/schemas/FleetDeploymentResourceType' + required: + - type + - attributes + type: object + FleetDeploymentConfigureCreateRequest: + description: Request payload for creating a new deployment. + properties: + data: + $ref: '#/components/schemas/FleetDeploymentConfigureCreate' + required: + - data + type: object + FleetDeploymentFileOp: + description: "Type of file operation to perform on the target configuration + file.\n- `merge-patch`: Merges the provided patch data with the existing configuration + file.\n Creates the file if it doesn't exist.\n- `delete`: Removes the specified + configuration file from the target hosts." + enum: + - merge-patch + - delete + example: merge-patch + type: string + x-enum-varnames: + - MERGE_PATCH + - DELETE + FleetDeploymentOperation: + description: A single configuration file operation to perform on the target + hosts. + properties: + file_op: + $ref: '#/components/schemas/FleetDeploymentFileOp' + file_path: + description: Absolute path to the target configuration file on the host. + example: /datadog.yaml + type: string + patch: + additionalProperties: {} + description: 'Patch data in JSON format to apply to the configuration file. + + When using `merge-patch`, this object is merged with the existing configuration, + + allowing you to add, update, or override specific fields without replacing + the entire file. + + The structure must match the target configuration file format (for example, + YAML structure for Datadog Agent config). + + Not applicable when using the `delete` operation.' + example: + apm_config: + enabled: true + log_level: debug + logs_enabled: true + type: object + required: + - file_op + - file_path + type: object + FleetDeploymentResourceType: + default: deployment + description: The type of deployment resource. + enum: + - deployment + example: deployment + type: string + x-enum-varnames: + - DEPLOYMENT + FleetDeploymentResponse: + description: Response containing a single deployment. + properties: + data: + $ref: '#/components/schemas/FleetDeployment' + type: object + FleetDeploymentsPage: + description: Pagination details for the list of deployments. + properties: + total_count: + description: Total number of deployments available across all pages. + example: 25 + format: int64 + type: integer + type: object + FleetDeploymentsResponse: + description: Response containing a paginated list of deployments. + properties: + data: + description: Array of deployments matching the query criteria. + items: + $ref: '#/components/schemas/FleetDeployment' + type: array + meta: + $ref: '#/components/schemas/FleetDeploymentsResponseMeta' + required: + - data + type: object + FleetDeploymentsResponseMeta: + description: Metadata for the list of deployments, including pagination information. + properties: + page: + $ref: '#/components/schemas/FleetDeploymentsPage' + type: object FormulaLimit: description: 'Message for specifying limits to the number of values returned by a query. @@ -53094,6 +53267,249 @@ info: version: '1.0' openapi: 3.0.0 paths: + /api/unstable/fleet/deployments: + get: + description: 'Retrieve a list of all deployments for fleet automation. + + Use the `page_size` and `page_offset` parameters to paginate results.' + operationId: ListFleetDeployments + parameters: + - description: Number of deployments to return per page. Maximum value is 100. + in: query + name: page_size + required: false + schema: + default: 10 + format: int64 + maximum: 100 + type: integer + - description: Index of the first deployment to return. Use this with `page_size` + to paginate through results. + in: query + name: page_offset + required: false + schema: + default: 0 + format: int64 + type: integer + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/FleetDeploymentsResponse' + description: OK + '400': + $ref: '#/components/responses/BadRequestResponse' + '401': + $ref: '#/components/responses/UnauthorizedResponse' + '403': + $ref: '#/components/responses/ForbiddenResponse' + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + summary: List all deployments + tags: + - Fleet Automation + x-permission: + operator: AND + permissions: + - hosts_read + x-unstable: 'This endpoint is in Preview and may introduce breaking changes. + + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/).' + /api/unstable/fleet/deployments/configure: + post: + description: 'Create a new deployment to apply configuration changes + + to a fleet of hosts matching the specified filter query.' + operationId: CreateFleetDeploymentConfigure + requestBody: + content: + application/json: + examples: + add_log_integration: + summary: Add log integrations for multiple services + value: + data: + attributes: + config_operations: + - file_op: merge-patch + file_path: /conf.d/postgres.d/logs.yaml + patch: + logs: + - path: /var/log/postgres.log + service: postgres1 + source: postgres + type: file + - file_op: merge-patch + file_path: /conf.d/kafka.d/logs.yaml + patch: + logs: + - path: /var/log/kafka.log + service: kafka1 + source: kafka + type: file + filter_query: env:prod + type: deployment + delete_config_file: + summary: Delete a configuration file + value: + data: + attributes: + config_operations: + - file_op: delete + file_path: /conf.d/old-integration.yaml + filter_query: env:dev + type: deployment + enable_apm_and_logs: + summary: Enable APM and Logs products + value: + data: + attributes: + config_operations: + - file_op: merge-patch + file_path: /datadog.yaml + patch: + apm_config: + enabled: true + log_level: debug + logs_enabled: true + filter_query: env:prod AND service:web + type: deployment + simple_log_level: + summary: Set log level to info + value: + data: + attributes: + config_operations: + - file_op: merge-patch + file_path: /datadog.yaml + patch: + log_level: info + filter_query: env:staging + type: deployment + schema: + $ref: '#/components/schemas/FleetDeploymentConfigureCreateRequest' + description: Request payload containing the deployment details. + required: true + responses: + '201': + content: + application/json: + schema: + $ref: '#/components/schemas/FleetDeploymentResponse' + description: CREATED + '400': + $ref: '#/components/responses/BadRequestResponse' + '401': + $ref: '#/components/responses/UnauthorizedResponse' + '403': + $ref: '#/components/responses/ForbiddenResponse' + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + summary: Create a deployment + tags: + - Fleet Automation + x-permission: + operator: AND + permissions: + - agent_upgrade_write + - fleet_policies_write + x-unstable: 'This endpoint is in Preview and may introduce breaking changes. + + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/).' + /api/unstable/fleet/deployments/{deployment_id}: + get: + description: Retrieve the details of a specific deployment using its unique + identifier. + operationId: GetFleetDeployment + parameters: + - description: The unique identifier of the deployment to retrieve. + example: abc-def-ghi + in: path + name: deployment_id + required: true + schema: + type: string + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/FleetDeploymentResponse' + description: OK + '400': + $ref: '#/components/responses/BadRequestResponse' + '401': + $ref: '#/components/responses/UnauthorizedResponse' + '403': + $ref: '#/components/responses/ForbiddenResponse' + '404': + $ref: '#/components/responses/NotFoundResponse' + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + summary: Get a deployment by ID + tags: + - Fleet Automation + x-permission: + operator: AND + permissions: + - hosts_read + x-unstable: 'This endpoint is in Preview and may introduce breaking changes. + + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/).' + /api/unstable/fleet/deployments/{deployment_id}/cancel: + post: + description: 'Cancel this deployment and stop all associated operations. + + If a workflow is currently running for this deployment, it is canceled immediately. + + Changes already applied to hosts are not rolled back.' + operationId: CancelFleetDeployment + parameters: + - description: The unique identifier of the deployment to cancel. + example: abc-def-ghi + in: path + name: deployment_id + required: true + schema: + type: string + responses: + '204': + description: Deployment successfully canceled. + '400': + $ref: '#/components/responses/BadRequestResponse' + '401': + $ref: '#/components/responses/UnauthorizedResponse' + '403': + $ref: '#/components/responses/ForbiddenResponse' + '404': + $ref: '#/components/responses/NotFoundResponse' + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + summary: Cancel a deployment + tags: + - Fleet Automation + x-permission: + operator: AND + permissions: + - agent_upgrade_write + - fleet_policies_write + x-unstable: 'This endpoint is in Preview and may introduce breaking changes. + + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/).' /api/v2/actions-datastores: get: description: Lists all datastores for the organization. @@ -79828,6 +80244,12 @@ tags: through the Datadog API. See the [Fastly integration page](https://docs.datadoghq.com/integrations/fastly/) for more information. name: Fastly Integration +- description: 'Manage automated deployments across your fleet of hosts. + + Use these endpoints to create, retrieve, and cancel deployments + + that apply configuration changes to multiple hosts at once.' + name: Fleet Automation - description: 'Configure your Datadog-Google Cloud Platform (GCP) integration directly through the Datadog API. Read more about the [Datadog-Google Cloud Platform integration](https://docs.datadoghq.com/integrations/google_cloud_platform).' diff --git a/examples/v2_fleet-automation_CancelFleetDeployment.rs b/examples/v2_fleet-automation_CancelFleetDeployment.rs new file mode 100644 index 000000000..dc758cc10 --- /dev/null +++ b/examples/v2_fleet-automation_CancelFleetDeployment.rs @@ -0,0 +1,18 @@ +// Cancel a deployment returns "Deployment successfully canceled." response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_fleet_automation::FleetAutomationAPI; + +#[tokio::main] +async fn main() { + let mut configuration = datadog::Configuration::new(); + configuration.set_unstable_operation_enabled("v2.CancelFleetDeployment", true); + let api = FleetAutomationAPI::with_config(configuration); + let resp = api + .cancel_fleet_deployment("deployment_id".to_string()) + .await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_fleet-automation_CreateFleetDeploymentConfigure.rs b/examples/v2_fleet-automation_CreateFleetDeploymentConfigure.rs new file mode 100644 index 000000000..e0e69109c --- /dev/null +++ b/examples/v2_fleet-automation_CreateFleetDeploymentConfigure.rs @@ -0,0 +1,36 @@ +// Create a deployment returns "CREATED" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_fleet_automation::FleetAutomationAPI; +use datadog_api_client::datadogV2::model::FleetDeploymentConfigureAttributes; +use datadog_api_client::datadogV2::model::FleetDeploymentConfigureCreate; +use datadog_api_client::datadogV2::model::FleetDeploymentConfigureCreateRequest; +use datadog_api_client::datadogV2::model::FleetDeploymentFileOp; +use datadog_api_client::datadogV2::model::FleetDeploymentOperation; +use datadog_api_client::datadogV2::model::FleetDeploymentResourceType; +use serde_json::Value; +use std::collections::BTreeMap; + +#[tokio::main] +async fn main() { + let body = FleetDeploymentConfigureCreateRequest::new(FleetDeploymentConfigureCreate::new( + FleetDeploymentConfigureAttributes::new(vec![FleetDeploymentOperation::new( + FleetDeploymentFileOp::MERGE_PATCH, + "/datadog.yaml".to_string(), + ) + .patch(BTreeMap::from([ + ("log_level".to_string(), Value::from("debug")), + ("logs_enabled".to_string(), Value::from("True")), + ]))]) + .filter_query("env:prod AND service:web".to_string()), + FleetDeploymentResourceType::DEPLOYMENT, + )); + let mut configuration = datadog::Configuration::new(); + configuration.set_unstable_operation_enabled("v2.CreateFleetDeploymentConfigure", true); + let api = FleetAutomationAPI::with_config(configuration); + let resp = api.create_fleet_deployment_configure(body).await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_fleet-automation_GetFleetDeployment.rs b/examples/v2_fleet-automation_GetFleetDeployment.rs new file mode 100644 index 000000000..2afde32e7 --- /dev/null +++ b/examples/v2_fleet-automation_GetFleetDeployment.rs @@ -0,0 +1,18 @@ +// Get a deployment by ID returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_fleet_automation::FleetAutomationAPI; + +#[tokio::main] +async fn main() { + // there is a valid "deployment" in the system + let deployment_id = std::env::var("DEPLOYMENT_ID").unwrap(); + let mut configuration = datadog::Configuration::new(); + configuration.set_unstable_operation_enabled("v2.GetFleetDeployment", true); + let api = FleetAutomationAPI::with_config(configuration); + let resp = api.get_fleet_deployment(deployment_id.clone()).await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_fleet-automation_ListFleetDeployments.rs b/examples/v2_fleet-automation_ListFleetDeployments.rs new file mode 100644 index 000000000..268dac637 --- /dev/null +++ b/examples/v2_fleet-automation_ListFleetDeployments.rs @@ -0,0 +1,19 @@ +// List all deployments returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_fleet_automation::FleetAutomationAPI; +use datadog_api_client::datadogV2::api_fleet_automation::ListFleetDeploymentsOptionalParams; + +#[tokio::main] +async fn main() { + let mut configuration = datadog::Configuration::new(); + configuration.set_unstable_operation_enabled("v2.ListFleetDeployments", true); + let api = FleetAutomationAPI::with_config(configuration); + let resp = api + .list_fleet_deployments(ListFleetDeploymentsOptionalParams::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 2fa07007f..612ac9304 100644 --- a/src/datadog/configuration.rs +++ b/src/datadog/configuration.rs @@ -122,6 +122,10 @@ impl Configuration { impl Default for Configuration { fn default() -> Self { let unstable_operations = HashMap::from([ + ("v2.cancel_fleet_deployment".to_owned(), false), + ("v2.create_fleet_deployment_configure".to_owned(), false), + ("v2.get_fleet_deployment".to_owned(), false), + ("v2.list_fleet_deployments".to_owned(), false), ("v2.create_open_api".to_owned(), false), ("v2.delete_open_api".to_owned(), false), ("v2.get_open_api".to_owned(), false), diff --git a/src/datadogV2/api/api_fleet_automation.rs b/src/datadogV2/api/api_fleet_automation.rs new file mode 100644 index 000000000..7144db212 --- /dev/null +++ b/src/datadogV2/api/api_fleet_automation.rs @@ -0,0 +1,656 @@ +// 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 flate2::{ + write::{GzEncoder, ZlibEncoder}, + Compression, +}; +use log::warn; +use reqwest::header::{HeaderMap, HeaderValue}; +use serde::{Deserialize, Serialize}; +use std::io::Write; + +/// ListFleetDeploymentsOptionalParams is a struct for passing parameters to the method [`FleetAutomationAPI::list_fleet_deployments`] +#[non_exhaustive] +#[derive(Clone, Default, Debug)] +pub struct ListFleetDeploymentsOptionalParams { + /// Number of deployments to return per page. Maximum value is 100. + pub page_size: Option, + /// Index of the first deployment to return. Use this with `page_size` to paginate through results. + pub page_offset: Option, +} + +impl ListFleetDeploymentsOptionalParams { + /// Number of deployments to return per page. Maximum value is 100. + pub fn page_size(mut self, value: i64) -> Self { + self.page_size = Some(value); + self + } + /// Index of the first deployment to return. Use this with `page_size` to paginate through results. + pub fn page_offset(mut self, value: i64) -> Self { + self.page_offset = Some(value); + self + } +} + +/// CancelFleetDeploymentError is a struct for typed errors of method [`FleetAutomationAPI::cancel_fleet_deployment`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum CancelFleetDeploymentError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + +/// CreateFleetDeploymentConfigureError is a struct for typed errors of method [`FleetAutomationAPI::create_fleet_deployment_configure`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum CreateFleetDeploymentConfigureError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + +/// GetFleetDeploymentError is a struct for typed errors of method [`FleetAutomationAPI::get_fleet_deployment`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum GetFleetDeploymentError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + +/// ListFleetDeploymentsError is a struct for typed errors of method [`FleetAutomationAPI::list_fleet_deployments`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ListFleetDeploymentsError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + +/// Manage automated deployments across your fleet of hosts. +/// Use these endpoints to create, retrieve, and cancel deployments +/// that apply configuration changes to multiple hosts at once. +#[derive(Debug, Clone)] +pub struct FleetAutomationAPI { + config: datadog::Configuration, + client: reqwest_middleware::ClientWithMiddleware, +} + +impl Default for FleetAutomationAPI { + fn default() -> Self { + Self::with_config(datadog::Configuration::default()) + } +} + +impl FleetAutomationAPI { + pub fn new() -> Self { + Self::default() + } + pub fn with_config(config: datadog::Configuration) -> Self { + let mut reqwest_client_builder = reqwest::Client::builder(); + + if let Some(proxy_url) = &config.proxy_url { + let proxy = reqwest::Proxy::all(proxy_url).expect("Failed to parse proxy URL"); + reqwest_client_builder = reqwest_client_builder.proxy(proxy); + } + + let mut middleware_client_builder = + reqwest_middleware::ClientBuilder::new(reqwest_client_builder.build().unwrap()); + + 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, + ); + + middleware_client_builder = middleware_client_builder.with(retry_middleware); + } + + 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 } + } + + /// Cancel this deployment and stop all associated operations. + /// If a workflow is currently running for this deployment, it is canceled immediately. + /// Changes already applied to hosts are not rolled back. + pub async fn cancel_fleet_deployment( + &self, + deployment_id: String, + ) -> Result<(), datadog::Error> { + match self + .cancel_fleet_deployment_with_http_info(deployment_id) + .await + { + Ok(_) => Ok(()), + Err(err) => Err(err), + } + } + + /// Cancel this deployment and stop all associated operations. + /// If a workflow is currently running for this deployment, it is canceled immediately. + /// Changes already applied to hosts are not rolled back. + pub async fn cancel_fleet_deployment_with_http_info( + &self, + deployment_id: String, + ) -> Result, datadog::Error> { + let local_configuration = &self.config; + let operation_id = "v2.cancel_fleet_deployment"; + if local_configuration.is_unstable_operation_enabled(operation_id) { + warn!("Using unstable operation {operation_id}"); + } else { + let local_error = datadog::UnstableOperationDisabledError { + msg: "Operation 'v2.cancel_fleet_deployment' is not enabled".to_string(), + }; + return Err(datadog::Error::UnstableOperationDisabledError(local_error)); + } + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/unstable/fleet/deployments/{deployment_id}/cancel", + local_configuration.get_operation_host(operation_id), + deployment_id = datadog::urlencode(deployment_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::POST, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Accept", HeaderValue::from_static("*/*")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: None, + }) + } else { + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + + /// Create a new deployment to apply configuration changes + /// to a fleet of hosts matching the specified filter query. + pub async fn create_fleet_deployment_configure( + &self, + body: crate::datadogV2::model::FleetDeploymentConfigureCreateRequest, + ) -> Result< + crate::datadogV2::model::FleetDeploymentResponse, + datadog::Error, + > { + match self + .create_fleet_deployment_configure_with_http_info(body) + .await + { + Ok(response_content) => { + if let Some(e) = response_content.entity { + Ok(e) + } else { + Err(datadog::Error::Serde(serde::de::Error::custom( + "response content was None", + ))) + } + } + Err(err) => Err(err), + } + } + + /// Create a new deployment to apply configuration changes + /// to a fleet of hosts matching the specified filter query. + pub async fn create_fleet_deployment_configure_with_http_info( + &self, + body: crate::datadogV2::model::FleetDeploymentConfigureCreateRequest, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.create_fleet_deployment_configure"; + if local_configuration.is_unstable_operation_enabled(operation_id) { + warn!("Using unstable operation {operation_id}"); + } else { + let local_error = datadog::UnstableOperationDisabledError { + msg: "Operation 'v2.create_fleet_deployment_configure' is not enabled".to_string(), + }; + return Err(datadog::Error::UnstableOperationDisabledError(local_error)); + } + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/unstable/fleet/deployments/configure", + local_configuration.get_operation_host(operation_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::POST, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Content-Type", HeaderValue::from_static("application/json")); + headers.insert("Accept", HeaderValue::from_static("application/json")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + // build body parameters + let output = Vec::new(); + let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter); + if body.serialize(&mut ser).is_ok() { + if let Some(content_encoding) = headers.get("Content-Encoding") { + match content_encoding.to_str().unwrap_or_default() { + "gzip" => { + let mut enc = GzEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "deflate" => { + let mut enc = ZlibEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "zstd1" => { + let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap(); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + _ => { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + } else { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + match serde_json::from_str::( + &local_content, + ) { + Ok(e) => { + return Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: Some(e), + }) + } + Err(e) => return Err(datadog::Error::Serde(e)), + }; + } else { + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + + /// Retrieve the details of a specific deployment using its unique identifier. + pub async fn get_fleet_deployment( + &self, + deployment_id: String, + ) -> Result< + crate::datadogV2::model::FleetDeploymentResponse, + datadog::Error, + > { + match self + .get_fleet_deployment_with_http_info(deployment_id) + .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), + } + } + + /// Retrieve the details of a specific deployment using its unique identifier. + pub async fn get_fleet_deployment_with_http_info( + &self, + deployment_id: String, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.get_fleet_deployment"; + if local_configuration.is_unstable_operation_enabled(operation_id) { + warn!("Using unstable operation {operation_id}"); + } else { + let local_error = datadog::UnstableOperationDisabledError { + msg: "Operation 'v2.get_fleet_deployment' is not enabled".to_string(), + }; + return Err(datadog::Error::UnstableOperationDisabledError(local_error)); + } + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/unstable/fleet/deployments/{deployment_id}", + local_configuration.get_operation_host(operation_id), + deployment_id = datadog::urlencode(deployment_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::GET, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Accept", HeaderValue::from_static("application/json")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + match serde_json::from_str::( + &local_content, + ) { + Ok(e) => { + return Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: Some(e), + }) + } + Err(e) => return Err(datadog::Error::Serde(e)), + }; + } else { + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + + /// Retrieve a list of all deployments for fleet automation. + /// Use the `page_size` and `page_offset` parameters to paginate results. + pub async fn list_fleet_deployments( + &self, + params: ListFleetDeploymentsOptionalParams, + ) -> Result< + crate::datadogV2::model::FleetDeploymentsResponse, + datadog::Error, + > { + match self.list_fleet_deployments_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), + } + } + + /// Retrieve a list of all deployments for fleet automation. + /// Use the `page_size` and `page_offset` parameters to paginate results. + pub async fn list_fleet_deployments_with_http_info( + &self, + params: ListFleetDeploymentsOptionalParams, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.list_fleet_deployments"; + 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_fleet_deployments' is not enabled".to_string(), + }; + return Err(datadog::Error::UnstableOperationDisabledError(local_error)); + } + + // unbox and build optional parameters + let page_size = params.page_size; + let page_offset = params.page_offset; + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/unstable/fleet/deployments", + 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) = page_size { + local_req_builder = + local_req_builder.query(&[("page_size", &local_query_param.to_string())]); + }; + if let Some(ref local_query_param) = page_offset { + local_req_builder = + local_req_builder.query(&[("page_offset", &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 91c9e9d27..60421ca74 100644 --- a/src/datadogV2/api/mod.rs +++ b/src/datadogV2/api/mod.rs @@ -36,6 +36,7 @@ pub mod api_downtimes; pub mod api_error_tracking; pub mod api_events; pub mod api_fastly_integration; +pub mod api_fleet_automation; pub mod api_gcp_integration; pub mod api_incident_services; pub mod api_incident_teams; diff --git a/src/datadogV2/mod.rs b/src/datadogV2/mod.rs index 2ef949612..e8c51e94b 100644 --- a/src/datadogV2/mod.rs +++ b/src/datadogV2/mod.rs @@ -37,6 +37,7 @@ pub use self::api::api_downtimes; pub use self::api::api_error_tracking; pub use self::api::api_events; pub use self::api::api_fastly_integration; +pub use self::api::api_fleet_automation; pub use self::api::api_gcp_integration; pub use self::api::api_incident_services; pub use self::api::api_incident_teams; diff --git a/src/datadogV2/model/mod.rs b/src/datadogV2/model/mod.rs index 8c5e0ccea..8a29dac6e 100644 --- a/src/datadogV2/model/mod.rs +++ b/src/datadogV2/model/mod.rs @@ -2,6 +2,32 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2019-Present Datadog, Inc. +pub mod model_fleet_deployments_response; +pub use self::model_fleet_deployments_response::FleetDeploymentsResponse; +pub mod model_fleet_deployment; +pub use self::model_fleet_deployment::FleetDeployment; +pub mod model_fleet_deployment_attributes; +pub use self::model_fleet_deployment_attributes::FleetDeploymentAttributes; +pub mod model_fleet_deployment_operation; +pub use self::model_fleet_deployment_operation::FleetDeploymentOperation; +pub mod model_fleet_deployment_file_op; +pub use self::model_fleet_deployment_file_op::FleetDeploymentFileOp; +pub mod model_fleet_deployment_resource_type; +pub use self::model_fleet_deployment_resource_type::FleetDeploymentResourceType; +pub mod model_fleet_deployments_response_meta; +pub use self::model_fleet_deployments_response_meta::FleetDeploymentsResponseMeta; +pub mod model_fleet_deployments_page; +pub use self::model_fleet_deployments_page::FleetDeploymentsPage; +pub mod model_api_error_response; +pub use self::model_api_error_response::APIErrorResponse; +pub mod model_fleet_deployment_configure_create_request; +pub use self::model_fleet_deployment_configure_create_request::FleetDeploymentConfigureCreateRequest; +pub mod model_fleet_deployment_configure_create; +pub use self::model_fleet_deployment_configure_create::FleetDeploymentConfigureCreate; +pub mod model_fleet_deployment_configure_attributes; +pub use self::model_fleet_deployment_configure_attributes::FleetDeploymentConfigureAttributes; +pub mod model_fleet_deployment_response; +pub use self::model_fleet_deployment_response::FleetDeploymentResponse; pub mod model_datastore_array; pub use self::model_datastore_array::DatastoreArray; pub mod model_datastore_data; @@ -12,8 +38,6 @@ pub mod model_datastore_primary_key_generation_strategy; pub use self::model_datastore_primary_key_generation_strategy::DatastorePrimaryKeyGenerationStrategy; pub mod model_datastore_data_type; pub use self::model_datastore_data_type::DatastoreDataType; -pub mod model_api_error_response; -pub use self::model_api_error_response::APIErrorResponse; pub mod model_create_apps_datastore_request; pub use self::model_create_apps_datastore_request::CreateAppsDatastoreRequest; pub mod model_create_apps_datastore_request_data; diff --git a/src/datadogV2/model/model_fleet_deployment.rs b/src/datadogV2/model/model_fleet_deployment.rs new file mode 100644 index 000000000..bc61b47d5 --- /dev/null +++ b/src/datadogV2/model/model_fleet_deployment.rs @@ -0,0 +1,125 @@ +// 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 deployment that defines automated configuration changes for a fleet of hosts. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FleetDeployment { + /// Attributes of a deployment in the response. + #[serde(rename = "attributes")] + pub attributes: crate::datadogV2::model::FleetDeploymentAttributes, + /// Unique identifier for the deployment. + #[serde(rename = "id")] + pub id: String, + /// The type of deployment resource. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::FleetDeploymentResourceType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FleetDeployment { + pub fn new( + attributes: crate::datadogV2::model::FleetDeploymentAttributes, + id: String, + type_: crate::datadogV2::model::FleetDeploymentResourceType, + ) -> FleetDeployment { + FleetDeployment { + 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 FleetDeployment { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FleetDeploymentVisitor; + impl<'a> Visitor<'a> for FleetDeploymentVisitor { + type Value = FleetDeployment; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut attributes: Option = + None; + let mut id: Option = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "attributes" => { + attributes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "id" => { + 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::FleetDeploymentResourceType::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 = FleetDeployment { + attributes, + id, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FleetDeploymentVisitor) + } +} diff --git a/src/datadogV2/model/model_fleet_deployment_attributes.rs b/src/datadogV2/model/model_fleet_deployment_attributes.rs new file mode 100644 index 000000000..79656a3be --- /dev/null +++ b/src/datadogV2/model/model_fleet_deployment_attributes.rs @@ -0,0 +1,183 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Attributes of a deployment in the response. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FleetDeploymentAttributes { + /// Ordered list of configuration file operations to perform on the target hosts. + #[serde(rename = "config_operations")] + pub config_operations: Option>, + /// Estimated completion time of the deployment as a Unix timestamp (seconds since epoch). + #[serde(rename = "estimated_end_time_unix")] + pub estimated_end_time_unix: Option, + /// Query used to filter and select target hosts for the deployment. Uses the Datadog query syntax. + #[serde(rename = "filter_query")] + pub filter_query: Option, + /// Current high-level status of the deployment (for example, "pending", "running", "completed", "failed"). + #[serde(rename = "high_level_status")] + pub high_level_status: Option, + /// Total number of hosts targeted by this deployment. + #[serde(rename = "total_hosts")] + pub total_hosts: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FleetDeploymentAttributes { + pub fn new() -> FleetDeploymentAttributes { + FleetDeploymentAttributes { + config_operations: None, + estimated_end_time_unix: None, + filter_query: None, + high_level_status: None, + total_hosts: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn config_operations( + mut self, + value: Vec, + ) -> Self { + self.config_operations = Some(value); + self + } + + pub fn estimated_end_time_unix(mut self, value: i64) -> Self { + self.estimated_end_time_unix = Some(value); + self + } + + pub fn filter_query(mut self, value: String) -> Self { + self.filter_query = Some(value); + self + } + + pub fn high_level_status(mut self, value: String) -> Self { + self.high_level_status = Some(value); + self + } + + pub fn total_hosts(mut self, value: i64) -> Self { + self.total_hosts = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for FleetDeploymentAttributes { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for FleetDeploymentAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FleetDeploymentAttributesVisitor; + impl<'a> Visitor<'a> for FleetDeploymentAttributesVisitor { + type Value = FleetDeploymentAttributes; + + 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 config_operations: Option< + Vec, + > = None; + let mut estimated_end_time_unix: Option = None; + let mut filter_query: Option = None; + let mut high_level_status: Option = None; + let mut total_hosts: 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() { + "config_operations" => { + if v.is_null() { + continue; + } + config_operations = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "estimated_end_time_unix" => { + if v.is_null() { + continue; + } + estimated_end_time_unix = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "filter_query" => { + if v.is_null() { + continue; + } + filter_query = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "high_level_status" => { + if v.is_null() { + continue; + } + high_level_status = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "total_hosts" => { + if v.is_null() { + continue; + } + total_hosts = + 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 = FleetDeploymentAttributes { + config_operations, + estimated_end_time_unix, + filter_query, + high_level_status, + total_hosts, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FleetDeploymentAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_fleet_deployment_configure_attributes.rs b/src/datadogV2/model/model_fleet_deployment_configure_attributes.rs new file mode 100644 index 000000000..454523d98 --- /dev/null +++ b/src/datadogV2/model/model_fleet_deployment_configure_attributes.rs @@ -0,0 +1,116 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Attributes for creating a new configuration deployment. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FleetDeploymentConfigureAttributes { + /// Ordered list of configuration file operations to perform on the target hosts. + #[serde(rename = "config_operations")] + pub config_operations: Vec, + /// Query used to filter and select target hosts for the deployment. Uses the Datadog query syntax. + #[serde(rename = "filter_query")] + pub filter_query: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FleetDeploymentConfigureAttributes { + pub fn new( + config_operations: Vec, + ) -> FleetDeploymentConfigureAttributes { + FleetDeploymentConfigureAttributes { + config_operations, + filter_query: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn filter_query(mut self, value: String) -> Self { + self.filter_query = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for FleetDeploymentConfigureAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FleetDeploymentConfigureAttributesVisitor; + impl<'a> Visitor<'a> for FleetDeploymentConfigureAttributesVisitor { + type Value = FleetDeploymentConfigureAttributes; + + 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 config_operations: Option< + Vec, + > = None; + let mut filter_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() { + "config_operations" => { + config_operations = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "filter_query" => { + if v.is_null() { + continue; + } + filter_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 config_operations = config_operations + .ok_or_else(|| M::Error::missing_field("config_operations"))?; + + let content = FleetDeploymentConfigureAttributes { + config_operations, + filter_query, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FleetDeploymentConfigureAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_fleet_deployment_configure_create.rs b/src/datadogV2/model/model_fleet_deployment_configure_create.rs new file mode 100644 index 000000000..66c380ab2 --- /dev/null +++ b/src/datadogV2/model/model_fleet_deployment_configure_create.rs @@ -0,0 +1,115 @@ +// 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}; + +/// Data for creating a new deployment. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FleetDeploymentConfigureCreate { + /// Attributes for creating a new configuration deployment. + #[serde(rename = "attributes")] + pub attributes: crate::datadogV2::model::FleetDeploymentConfigureAttributes, + /// The type of deployment resource. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::FleetDeploymentResourceType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FleetDeploymentConfigureCreate { + pub fn new( + attributes: crate::datadogV2::model::FleetDeploymentConfigureAttributes, + type_: crate::datadogV2::model::FleetDeploymentResourceType, + ) -> FleetDeploymentConfigureCreate { + FleetDeploymentConfigureCreate { + attributes, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for FleetDeploymentConfigureCreate { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FleetDeploymentConfigureCreateVisitor; + impl<'a> Visitor<'a> for FleetDeploymentConfigureCreateVisitor { + type Value = FleetDeploymentConfigureCreate; + + 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::FleetDeploymentConfigureAttributes, + > = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "attributes" => { + attributes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::FleetDeploymentResourceType::UnparsedObject(_type_) => { + _unparsed = true; + }, + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let attributes = attributes.ok_or_else(|| M::Error::missing_field("attributes"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = FleetDeploymentConfigureCreate { + attributes, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FleetDeploymentConfigureCreateVisitor) + } +} diff --git a/src/datadogV2/model/model_fleet_deployment_configure_create_request.rs b/src/datadogV2/model/model_fleet_deployment_configure_create_request.rs new file mode 100644 index 000000000..e2c41ec3a --- /dev/null +++ b/src/datadogV2/model/model_fleet_deployment_configure_create_request.rs @@ -0,0 +1,95 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Request payload for creating a new deployment. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FleetDeploymentConfigureCreateRequest { + /// Data for creating a new deployment. + #[serde(rename = "data")] + pub data: crate::datadogV2::model::FleetDeploymentConfigureCreate, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FleetDeploymentConfigureCreateRequest { + pub fn new( + data: crate::datadogV2::model::FleetDeploymentConfigureCreate, + ) -> FleetDeploymentConfigureCreateRequest { + FleetDeploymentConfigureCreateRequest { + 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 FleetDeploymentConfigureCreateRequest { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FleetDeploymentConfigureCreateRequestVisitor; + impl<'a> Visitor<'a> for FleetDeploymentConfigureCreateRequestVisitor { + type Value = FleetDeploymentConfigureCreateRequest; + + 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 = FleetDeploymentConfigureCreateRequest { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FleetDeploymentConfigureCreateRequestVisitor) + } +} diff --git a/src/datadogV2/model/model_fleet_deployment_file_op.rs b/src/datadogV2/model/model_fleet_deployment_file_op.rs new file mode 100644 index 000000000..f96693ca9 --- /dev/null +++ b/src/datadogV2/model/model_fleet_deployment_file_op.rs @@ -0,0 +1,51 @@ +// 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 FleetDeploymentFileOp { + MERGE_PATCH, + DELETE, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for FleetDeploymentFileOp { + fn to_string(&self) -> String { + match self { + Self::MERGE_PATCH => String::from("merge-patch"), + Self::DELETE => String::from("delete"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for FleetDeploymentFileOp { + 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 FleetDeploymentFileOp { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "merge-patch" => Self::MERGE_PATCH, + "delete" => Self::DELETE, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/src/datadogV2/model/model_fleet_deployment_operation.rs b/src/datadogV2/model/model_fleet_deployment_operation.rs new file mode 100644 index 000000000..2a814249a --- /dev/null +++ b/src/datadogV2/model/model_fleet_deployment_operation.rs @@ -0,0 +1,137 @@ +// 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 configuration file operation to perform on the target hosts. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FleetDeploymentOperation { + /// Type of file operation to perform on the target configuration file. + /// - `merge-patch`: Merges the provided patch data with the existing configuration file. + /// Creates the file if it doesn't exist. + /// - `delete`: Removes the specified configuration file from the target hosts. + #[serde(rename = "file_op")] + pub file_op: crate::datadogV2::model::FleetDeploymentFileOp, + /// Absolute path to the target configuration file on the host. + #[serde(rename = "file_path")] + pub file_path: String, + /// Patch data in JSON format to apply to the configuration file. + /// When using `merge-patch`, this object is merged with the existing configuration, + /// allowing you to add, update, or override specific fields without replacing the entire file. + /// The structure must match the target configuration file format (for example, YAML structure for Datadog Agent config). + /// Not applicable when using the `delete` operation. + #[serde(rename = "patch")] + pub patch: Option>, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FleetDeploymentOperation { + pub fn new( + file_op: crate::datadogV2::model::FleetDeploymentFileOp, + file_path: String, + ) -> FleetDeploymentOperation { + FleetDeploymentOperation { + file_op, + file_path, + patch: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn patch(mut self, value: std::collections::BTreeMap) -> Self { + self.patch = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for FleetDeploymentOperation { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FleetDeploymentOperationVisitor; + impl<'a> Visitor<'a> for FleetDeploymentOperationVisitor { + type Value = FleetDeploymentOperation; + + 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 file_op: Option = None; + let mut file_path: Option = None; + let mut patch: 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() { + "file_op" => { + file_op = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _file_op) = file_op { + match _file_op { + crate::datadogV2::model::FleetDeploymentFileOp::UnparsedObject(_file_op) => { + _unparsed = true; + }, + _ => {} + } + } + } + "file_path" => { + file_path = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "patch" => { + if v.is_null() { + continue; + } + patch = 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 file_op = file_op.ok_or_else(|| M::Error::missing_field("file_op"))?; + let file_path = file_path.ok_or_else(|| M::Error::missing_field("file_path"))?; + + let content = FleetDeploymentOperation { + file_op, + file_path, + patch, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FleetDeploymentOperationVisitor) + } +} diff --git a/src/datadogV2/model/model_fleet_deployment_resource_type.rs b/src/datadogV2/model/model_fleet_deployment_resource_type.rs new file mode 100644 index 000000000..0568189e4 --- /dev/null +++ b/src/datadogV2/model/model_fleet_deployment_resource_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 FleetDeploymentResourceType { + DEPLOYMENT, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for FleetDeploymentResourceType { + fn to_string(&self) -> String { + match self { + Self::DEPLOYMENT => String::from("deployment"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for FleetDeploymentResourceType { + 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 FleetDeploymentResourceType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "deployment" => Self::DEPLOYMENT, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/src/datadogV2/model/model_fleet_deployment_response.rs b/src/datadogV2/model/model_fleet_deployment_response.rs new file mode 100644 index 000000000..f4762d767 --- /dev/null +++ b/src/datadogV2/model/model_fleet_deployment_response.rs @@ -0,0 +1,105 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Response containing a single deployment. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FleetDeploymentResponse { + /// A deployment that defines automated configuration changes for a fleet of hosts. + #[serde(rename = "data")] + pub data: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FleetDeploymentResponse { + pub fn new() -> FleetDeploymentResponse { + FleetDeploymentResponse { + data: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn data(mut self, value: crate::datadogV2::model::FleetDeployment) -> Self { + self.data = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for FleetDeploymentResponse { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for FleetDeploymentResponse { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FleetDeploymentResponseVisitor; + impl<'a> Visitor<'a> for FleetDeploymentResponseVisitor { + type Value = FleetDeploymentResponse; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + if v.is_null() { + continue; + } + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = FleetDeploymentResponse { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FleetDeploymentResponseVisitor) + } +} diff --git a/src/datadogV2/model/model_fleet_deployments_page.rs b/src/datadogV2/model/model_fleet_deployments_page.rs new file mode 100644 index 000000000..36b94628d --- /dev/null +++ b/src/datadogV2/model/model_fleet_deployments_page.rs @@ -0,0 +1,106 @@ +// 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}; + +/// Pagination details for the list of deployments. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FleetDeploymentsPage { + /// Total number of deployments available across all pages. + #[serde(rename = "total_count")] + pub total_count: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FleetDeploymentsPage { + pub fn new() -> FleetDeploymentsPage { + FleetDeploymentsPage { + total_count: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn total_count(mut self, value: i64) -> Self { + self.total_count = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for FleetDeploymentsPage { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for FleetDeploymentsPage { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FleetDeploymentsPageVisitor; + impl<'a> Visitor<'a> for FleetDeploymentsPageVisitor { + type Value = FleetDeploymentsPage; + + 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 total_count: 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() { + "total_count" => { + if v.is_null() { + continue; + } + total_count = + 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 = FleetDeploymentsPage { + total_count, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FleetDeploymentsPageVisitor) + } +} diff --git a/src/datadogV2/model/model_fleet_deployments_response.rs b/src/datadogV2/model/model_fleet_deployments_response.rs new file mode 100644 index 000000000..0c20e3cd9 --- /dev/null +++ b/src/datadogV2/model/model_fleet_deployments_response.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}; + +/// Response containing a paginated list of deployments. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FleetDeploymentsResponse { + /// Array of deployments matching the query criteria. + #[serde(rename = "data")] + pub data: Vec, + /// Metadata for the list of deployments, including pagination information. + #[serde(rename = "meta")] + pub meta: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FleetDeploymentsResponse { + pub fn new(data: Vec) -> FleetDeploymentsResponse { + FleetDeploymentsResponse { + data, + meta: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn meta(mut self, value: crate::datadogV2::model::FleetDeploymentsResponseMeta) -> Self { + self.meta = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for FleetDeploymentsResponse { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FleetDeploymentsResponseVisitor; + impl<'a> Visitor<'a> for FleetDeploymentsResponseVisitor { + type Value = FleetDeploymentsResponse; + + 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 meta: 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)?); + } + "meta" => { + if v.is_null() { + continue; + } + meta = 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 = FleetDeploymentsResponse { + data, + meta, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FleetDeploymentsResponseVisitor) + } +} diff --git a/src/datadogV2/model/model_fleet_deployments_response_meta.rs b/src/datadogV2/model/model_fleet_deployments_response_meta.rs new file mode 100644 index 000000000..98969b435 --- /dev/null +++ b/src/datadogV2/model/model_fleet_deployments_response_meta.rs @@ -0,0 +1,105 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Metadata for the list of deployments, including pagination information. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FleetDeploymentsResponseMeta { + /// Pagination details for the list of deployments. + #[serde(rename = "page")] + pub page: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FleetDeploymentsResponseMeta { + pub fn new() -> FleetDeploymentsResponseMeta { + FleetDeploymentsResponseMeta { + page: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn page(mut self, value: crate::datadogV2::model::FleetDeploymentsPage) -> Self { + self.page = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for FleetDeploymentsResponseMeta { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for FleetDeploymentsResponseMeta { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FleetDeploymentsResponseMetaVisitor; + impl<'a> Visitor<'a> for FleetDeploymentsResponseMetaVisitor { + type Value = FleetDeploymentsResponseMeta; + + 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 page: 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() { + "page" => { + if v.is_null() { + continue; + } + page = 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 = FleetDeploymentsResponseMeta { + page, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FleetDeploymentsResponseMetaVisitor) + } +} diff --git a/tests/scenarios/features/v2/fleet_automation.feature b/tests/scenarios/features/v2/fleet_automation.feature new file mode 100644 index 000000000..2e91b6e0a --- /dev/null +++ b/tests/scenarios/features/v2/fleet_automation.feature @@ -0,0 +1,89 @@ +@endpoint(fleet-automation) @endpoint(fleet-automation-v2) +Feature: Fleet Automation + Manage automated deployments across your fleet of hosts. Use these + endpoints to create, retrieve, and cancel deployments that apply + configuration changes to multiple hosts at once. + + Background: + Given a valid "apiKeyAuth" key in the system + And a valid "appKeyAuth" key in the system + And an instance of "FleetAutomation" API + + @generated @skip @team:DataDog/fleet-automation + Scenario: Cancel a deployment returns "Bad Request" response + Given operation "CancelFleetDeployment" enabled + And new "CancelFleetDeployment" request + And request contains "deployment_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:DataDog/fleet-automation + Scenario: Cancel a deployment returns "Deployment successfully canceled." response + Given operation "CancelFleetDeployment" enabled + And new "CancelFleetDeployment" request + And request contains "deployment_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 204 Deployment successfully canceled. + + @generated @skip @team:DataDog/fleet-automation + Scenario: Cancel a deployment returns "Not Found" response + Given operation "CancelFleetDeployment" enabled + And new "CancelFleetDeployment" request + And request contains "deployment_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 404 Not Found + + @generated @skip @team:DataDog/fleet-automation + Scenario: Create a deployment returns "Bad Request" response + Given operation "CreateFleetDeploymentConfigure" enabled + And new "CreateFleetDeploymentConfigure" request + And body with value {"data": {"attributes": {"config_operations": [{"file_op": "merge-patch", "file_path": "/datadog.yaml", "patch": {"apm_config": {"enabled": true}, "log_level": "debug", "logs_enabled": true}}], "filter_query": "env:prod AND service:web"}, "type": "deployment"}} + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:DataDog/fleet-automation + Scenario: Create a deployment returns "CREATED" response + Given operation "CreateFleetDeploymentConfigure" enabled + And new "CreateFleetDeploymentConfigure" request + And body with value {"data": {"attributes": {"config_operations": [{"file_op": "merge-patch", "file_path": "/datadog.yaml", "patch": {"apm_config": {"enabled": true}, "log_level": "debug", "logs_enabled": true}}], "filter_query": "env:prod AND service:web"}, "type": "deployment"}} + When the request is sent + Then the response status is 201 CREATED + + @generated @skip @team:DataDog/fleet-automation + Scenario: Get a deployment by ID returns "Bad Request" response + Given operation "GetFleetDeployment" enabled + And new "GetFleetDeployment" request + And request contains "deployment_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:DataDog/fleet-automation + Scenario: Get a deployment by ID returns "Not Found" response + Given operation "GetFleetDeployment" enabled + And new "GetFleetDeployment" request + And request contains "deployment_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 404 Not Found + + @skip @team:DataDog/fleet-automation + Scenario: Get a deployment by ID returns "OK" response + Given operation "GetFleetDeployment" enabled + And there is a valid "deployment" in the system + And new "GetFleetDeployment" request + And request contains "deployment_id" parameter from "deployment.id" + When the request is sent + Then the response status is 200 OK + + @generated @skip @team:DataDog/fleet-automation + Scenario: List all deployments returns "Bad Request" response + Given operation "ListFleetDeployments" enabled + And new "ListFleetDeployments" request + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:DataDog/fleet-automation + Scenario: List all deployments returns "OK" response + Given operation "ListFleetDeployments" enabled + And new "ListFleetDeployments" request + When the request is sent + Then the response status is 200 OK diff --git a/tests/scenarios/features/v2/given.json b/tests/scenarios/features/v2/given.json index 23b1000e2..a4ab9c24b 100644 --- a/tests/scenarios/features/v2/given.json +++ b/tests/scenarios/features/v2/given.json @@ -1,4 +1,17 @@ [ + { + "parameters": [ + { + "name": "body", + "value": "{\n \"data\": {\n \"type\": \"deployment\",\n \"attributes\": {\n \"filter_query\": \"env:prod AND service:{{ unique_lower }}\",\n \"config_operations\": [\n {\n \"file_op\": \"merge-patch\",\n \"file_path\": \"/datadog.yaml\",\n \"patch\": {\n \"log_level\": \"info\"\n }\n }\n ]\n }\n }\n}" + } + ], + "source": "data", + "step": "there is a valid \"deployment\" in the system", + "key": "deployment", + "tag": "Fleet Automation", + "operationId": "CreateFleetDeploymentConfigure" + }, { "parameters": [ { diff --git a/tests/scenarios/features/v2/undo.json b/tests/scenarios/features/v2/undo.json index 6c74e264b..bb35cea36 100644 --- a/tests/scenarios/features/v2/undo.json +++ b/tests/scenarios/features/v2/undo.json @@ -1,4 +1,35 @@ { + "ListFleetDeployments": { + "tag": "Fleet Automation", + "undo": { + "type": "safe" + } + }, + "CreateFleetDeploymentConfigure": { + "tag": "Fleet Automation", + "undo": { + "operationId": "CancelFleetDeployment", + "parameters": [ + { + "name": "deployment_id", + "source": "data.id" + } + ], + "type": "unsafe" + } + }, + "GetFleetDeployment": { + "tag": "Fleet Automation", + "undo": { + "type": "safe" + } + }, + "CancelFleetDeployment": { + "tag": "Fleet Automation", + "undo": { + "type": "idempotent" + } + }, "ListDatastores": { "tag": "Actions Datastores", "undo": { diff --git a/tests/scenarios/function_mappings.rs b/tests/scenarios/function_mappings.rs index dedc2950b..821ce5838 100644 --- a/tests/scenarios/function_mappings.rs +++ b/tests/scenarios/function_mappings.rs @@ -49,6 +49,7 @@ pub struct ApiInstances { pub v1_api_tags: Option, pub v1_api_users: Option, pub v1_api_authentication: Option, + pub v2_api_fleet_automation: Option, pub v2_api_actions_datastores: Option, pub v2_api_action_connection: Option, pub v2_api_agentless_scanning: Option, @@ -480,6 +481,14 @@ pub fn initialize_api_instance(world: &mut DatadogWorld, api: String) { ), ); } + "FleetAutomation" => { + world.api_instances.v2_api_fleet_automation = Some( + datadogV2::api_fleet_automation::FleetAutomationAPI::with_client_and_config( + world.config.clone(), + world.http_client.as_ref().unwrap().clone(), + ), + ); + } "ActionsDatastores" => { world.api_instances.v2_api_actions_datastores = Some( datadogV2::api_actions_datastores::ActionsDatastoresAPI::with_client_and_config( @@ -1790,6 +1799,21 @@ pub fn collect_function_calls(world: &mut DatadogWorld) { world .function_mappings .insert("v1.Validate".into(), test_v1_validate); + world.function_mappings.insert( + "v2.ListFleetDeployments".into(), + test_v2_list_fleet_deployments, + ); + world.function_mappings.insert( + "v2.CreateFleetDeploymentConfigure".into(), + test_v2_create_fleet_deployment_configure, + ); + world + .function_mappings + .insert("v2.GetFleetDeployment".into(), test_v2_get_fleet_deployment); + world.function_mappings.insert( + "v2.CancelFleetDeployment".into(), + test_v2_cancel_fleet_deployment, + ); world .function_mappings .insert("v2.ListDatastores".into(), test_v2_list_datastores); @@ -11482,6 +11506,119 @@ fn test_v1_validate(world: &mut DatadogWorld, _parameters: &HashMap) { + let api = world + .api_instances + .v2_api_fleet_automation + .as_ref() + .expect("api instance not found"); + let page_size = _parameters + .get("page_size") + .and_then(|param| Some(serde_json::from_value(param.clone()).unwrap())); + let page_offset = _parameters + .get("page_offset") + .and_then(|param| Some(serde_json::from_value(param.clone()).unwrap())); + let mut params = datadogV2::api_fleet_automation::ListFleetDeploymentsOptionalParams::default(); + params.page_size = page_size; + params.page_offset = page_offset; + let response = match block_on(api.list_fleet_deployments_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_create_fleet_deployment_configure( + world: &mut DatadogWorld, + _parameters: &HashMap, +) { + let api = world + .api_instances + .v2_api_fleet_automation + .as_ref() + .expect("api instance not found"); + let body = serde_json::from_value(_parameters.get("body").unwrap().clone()).unwrap(); + let response = match block_on(api.create_fleet_deployment_configure_with_http_info(body)) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + +fn test_v2_get_fleet_deployment(world: &mut DatadogWorld, _parameters: &HashMap) { + let api = world + .api_instances + .v2_api_fleet_automation + .as_ref() + .expect("api instance not found"); + let deployment_id = + serde_json::from_value(_parameters.get("deployment_id").unwrap().clone()).unwrap(); + let response = match block_on(api.get_fleet_deployment_with_http_info(deployment_id)) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + +fn test_v2_cancel_fleet_deployment(world: &mut DatadogWorld, _parameters: &HashMap) { + let api = world + .api_instances + .v2_api_fleet_automation + .as_ref() + .expect("api instance not found"); + let deployment_id = + serde_json::from_value(_parameters.get("deployment_id").unwrap().clone()).unwrap(); + let response = match block_on(api.cancel_fleet_deployment_with_http_info(deployment_id)) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + fn test_v2_list_datastores(world: &mut DatadogWorld, _parameters: &HashMap) { let api = world .api_instances