diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index d4dfe8ead..d3505929e 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -5879,6 +5879,115 @@ components: required: - type type: object + AzureScanOptions: + description: The definition of `AzureScanOptions` object. + example: + data: + attributes: + vuln_containers_os: true + vuln_host_os: true + id: 12345678-90ab-cdef-1234-567890abcdef + type: azure_scan_options + properties: + data: + $ref: '#/components/schemas/AzureScanOptionsData' + type: object + AzureScanOptionsArray: + description: The definition of `AzureScanOptionsArray` object. + example: + data: + - attributes: + vuln_containers_os: true + vuln_host_os: true + id: 12345678-90ab-cdef-1234-567890abcdef + type: azure_scan_options + properties: + data: + description: The `AzureScanOptionsArray` `data`. + items: + $ref: '#/components/schemas/AzureScanOptionsData' + type: array + required: + - data + type: object + AzureScanOptionsData: + description: The definition of `AzureScanOptionsData` object. + properties: + attributes: + $ref: '#/components/schemas/AzureScanOptionsDataAttributes' + id: + description: The `AzureScanOptionsData` `id`. + example: '' + type: string + type: + $ref: '#/components/schemas/AzureScanOptionsDataType' + required: + - type + - id + type: object + AzureScanOptionsDataAttributes: + description: The definition of `AzureScanOptionsDataAttributes` object. + properties: + vuln_containers_os: + description: The `attributes` `vuln_containers_os`. + type: boolean + vuln_host_os: + description: The `attributes` `vuln_host_os`. + type: boolean + type: object + AzureScanOptionsDataType: + default: azure_scan_options + description: The type of the resource. The value should always be `azure_scan_options`. + enum: + - azure_scan_options + example: azure_scan_options + type: string + x-enum-varnames: + - AZURE_SCAN_OPTIONS + AzureScanOptionsInputUpdate: + description: The definition of `AzureScanOptionsInputUpdate` object. + example: + data: + id: 12345678-90ab-cdef-1234-567890abcdef + type: azure_scan_options + properties: + data: + $ref: '#/components/schemas/AzureScanOptionsInputUpdateData' + type: object + AzureScanOptionsInputUpdateData: + description: The definition of `AzureScanOptionsInputUpdateData` object. + properties: + attributes: + $ref: '#/components/schemas/AzureScanOptionsInputUpdateDataAttributes' + id: + description: The `AzureScanOptionsInputUpdateData` `id`. + example: '' + type: string + type: + $ref: '#/components/schemas/AzureScanOptionsInputUpdateDataType' + required: + - type + - id + type: object + AzureScanOptionsInputUpdateDataAttributes: + description: The definition of `AzureScanOptionsInputUpdateDataAttributes` object. + properties: + vuln_containers_os: + description: The `attributes` `vuln_containers_os`. + type: boolean + vuln_host_os: + description: The `attributes` `vuln_host_os`. + type: boolean + type: object + AzureScanOptionsInputUpdateDataType: + default: azure_scan_options + description: Azure scan options resource type. + enum: + - azure_scan_options + example: azure_scan_options + type: string + x-enum-varnames: + - AZURE_SCAN_OPTIONS AzureStorageDestination: description: The `azure_storage` destination forwards logs to an Azure Blob Storage container. @@ -51570,6 +51679,11 @@ paths: $ref: '#/components/responses/NotAuthorizedResponse' '429': $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - security_monitoring_findings_read summary: List AWS Scan Options tags: - Agentless Scanning @@ -51598,6 +51712,11 @@ paths: $ref: '#/components/responses/ConflictResponse' '429': $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - org_management summary: Post AWS Scan Options tags: - Agentless Scanning @@ -51619,6 +51738,11 @@ paths: $ref: '#/components/responses/NotFoundResponse' '429': $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - org_management summary: Delete AWS Scan Options tags: - Agentless Scanning @@ -51642,6 +51766,11 @@ paths: $ref: '#/components/responses/NotFoundResponse' '429': $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - security_monitoring_findings_read summary: Get AWS scan options tags: - Agentless Scanning @@ -51668,10 +51797,121 @@ paths: $ref: '#/components/responses/NotFoundResponse' '429': $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - org_management summary: Patch AWS Scan Options tags: - Agentless Scanning x-codegen-request-body-name: body + /api/v2/agentless_scanning/accounts/azure: + get: + description: Fetches the scan options configured for Azure accounts. + operationId: ListAzureScanOptions + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/AzureScanOptionsArray' + description: OK + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - security_monitoring_findings_read + summary: List azure scan options + tags: + - Agentless Scanning + post: + description: Activate Agentless scan options for an Azure subscription. + operationId: CreateAzureScanOptions + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/AzureScanOptions' + required: true + responses: + '201': + content: + application/json: + schema: + $ref: '#/components/schemas/AzureScanOptions' + description: Created + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - org_management + summary: Create azure scan options + tags: + - Agentless Scanning + /api/v2/agentless_scanning/accounts/azure/{subscription_id}: + delete: + description: Delete Agentless scan options for an Azure subscription. + operationId: DeleteAzureScanOptions + parameters: + - description: The Azure subscription ID. + in: path + name: subscription_id + required: true + schema: + example: 12345678-90ab-cdef-1234-567890abcdef + type: string + responses: + '204': + description: No Content + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - org_management + summary: Delete azure scan options + tags: + - Agentless Scanning + patch: + description: Update the Agentless scan options for an activated subscription. + operationId: UpdateAzureScanOptions + parameters: + - description: The Azure subscription ID. + in: path + name: subscription_id + required: true + schema: + example: 12345678-90ab-cdef-1234-567890abcdef + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/AzureScanOptionsInputUpdate' + required: true + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/AzureScanOptions' + description: OK + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - org_management + summary: Update azure scan options + tags: + - Agentless Scanning /api/v2/agentless_scanning/ondemand/aws: get: description: Fetches the most recent 1000 AWS on demand tasks. @@ -51687,6 +51927,11 @@ paths: $ref: '#/components/responses/NotAuthorizedResponse' '429': $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - security_monitoring_findings_read summary: Get AWS On Demand tasks tags: - Agentless Scanning @@ -51719,6 +51964,11 @@ paths: $ref: '#/components/responses/NotAuthorizedResponse' '429': $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - org_management summary: Post an AWS on demand task tags: - Agentless Scanning @@ -51748,6 +51998,11 @@ paths: $ref: '#/components/responses/NotFoundResponse' '429': $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - security_monitoring_findings_read summary: Get AWS On Demand task by id tags: - Agentless Scanning diff --git a/examples/v2_agentless-scanning_CreateAzureScanOptions.rs b/examples/v2_agentless-scanning_CreateAzureScanOptions.rs new file mode 100644 index 000000000..19bcb83b6 --- /dev/null +++ b/examples/v2_agentless-scanning_CreateAzureScanOptions.rs @@ -0,0 +1,30 @@ +// Create azure scan options returns "Created" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_agentless_scanning::AgentlessScanningAPI; +use datadog_api_client::datadogV2::model::AzureScanOptions; +use datadog_api_client::datadogV2::model::AzureScanOptionsData; +use datadog_api_client::datadogV2::model::AzureScanOptionsDataAttributes; +use datadog_api_client::datadogV2::model::AzureScanOptionsDataType; + +#[tokio::main] +async fn main() { + let body = AzureScanOptions::new().data( + AzureScanOptionsData::new( + "12345678-90ab-cdef-1234-567890abcdef".to_string(), + AzureScanOptionsDataType::AZURE_SCAN_OPTIONS, + ) + .attributes( + AzureScanOptionsDataAttributes::new() + .vuln_containers_os(true) + .vuln_host_os(true), + ), + ); + let configuration = datadog::Configuration::new(); + let api = AgentlessScanningAPI::with_config(configuration); + let resp = api.create_azure_scan_options(body).await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_agentless-scanning_DeleteAzureScanOptions.rs b/examples/v2_agentless-scanning_DeleteAzureScanOptions.rs new file mode 100644 index 000000000..21485584d --- /dev/null +++ b/examples/v2_agentless-scanning_DeleteAzureScanOptions.rs @@ -0,0 +1,17 @@ +// Delete azure scan options returns "No Content" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_agentless_scanning::AgentlessScanningAPI; + +#[tokio::main] +async fn main() { + let configuration = datadog::Configuration::new(); + let api = AgentlessScanningAPI::with_config(configuration); + let resp = api + .delete_azure_scan_options("12345678-90ab-cdef-1234-567890abcdef".to_string()) + .await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_agentless-scanning_ListAzureScanOptions.rs b/examples/v2_agentless-scanning_ListAzureScanOptions.rs new file mode 100644 index 000000000..f93ca39cf --- /dev/null +++ b/examples/v2_agentless-scanning_ListAzureScanOptions.rs @@ -0,0 +1,15 @@ +// List azure scan options returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_agentless_scanning::AgentlessScanningAPI; + +#[tokio::main] +async fn main() { + let configuration = datadog::Configuration::new(); + let api = AgentlessScanningAPI::with_config(configuration); + let resp = api.list_azure_scan_options().await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_agentless-scanning_UpdateAzureScanOptions.rs b/examples/v2_agentless-scanning_UpdateAzureScanOptions.rs new file mode 100644 index 000000000..bcd6f8432 --- /dev/null +++ b/examples/v2_agentless-scanning_UpdateAzureScanOptions.rs @@ -0,0 +1,24 @@ +// Update azure scan options returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_agentless_scanning::AgentlessScanningAPI; +use datadog_api_client::datadogV2::model::AzureScanOptionsInputUpdate; +use datadog_api_client::datadogV2::model::AzureScanOptionsInputUpdateData; +use datadog_api_client::datadogV2::model::AzureScanOptionsInputUpdateDataType; + +#[tokio::main] +async fn main() { + let body = AzureScanOptionsInputUpdate::new().data(AzureScanOptionsInputUpdateData::new( + "12345678-90ab-cdef-1234-567890abcdef".to_string(), + AzureScanOptionsInputUpdateDataType::AZURE_SCAN_OPTIONS, + )); + let configuration = datadog::Configuration::new(); + let api = AgentlessScanningAPI::with_config(configuration); + let resp = api + .update_azure_scan_options("12345678-90ab-cdef-1234-567890abcdef".to_string(), body) + .await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/src/datadogV2/api/api_agentless_scanning.rs b/src/datadogV2/api/api_agentless_scanning.rs index cd3e8256d..0d5cdfc90 100644 --- a/src/datadogV2/api/api_agentless_scanning.rs +++ b/src/datadogV2/api/api_agentless_scanning.rs @@ -26,6 +26,14 @@ pub enum CreateAwsScanOptionsError { UnknownValue(serde_json::Value), } +/// CreateAzureScanOptionsError is a struct for typed errors of method [`AgentlessScanningAPI::create_azure_scan_options`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum CreateAzureScanOptionsError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// DeleteAwsScanOptionsError is a struct for typed errors of method [`AgentlessScanningAPI::delete_aws_scan_options`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -34,6 +42,14 @@ pub enum DeleteAwsScanOptionsError { UnknownValue(serde_json::Value), } +/// DeleteAzureScanOptionsError is a struct for typed errors of method [`AgentlessScanningAPI::delete_azure_scan_options`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum DeleteAzureScanOptionsError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// GetAwsOnDemandTaskError is a struct for typed errors of method [`AgentlessScanningAPI::get_aws_on_demand_task`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -66,6 +82,14 @@ pub enum ListAwsScanOptionsError { UnknownValue(serde_json::Value), } +/// ListAzureScanOptionsError is a struct for typed errors of method [`AgentlessScanningAPI::list_azure_scan_options`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ListAzureScanOptionsError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// UpdateAwsScanOptionsError is a struct for typed errors of method [`AgentlessScanningAPI::update_aws_scan_options`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -74,6 +98,14 @@ pub enum UpdateAwsScanOptionsError { UnknownValue(serde_json::Value), } +/// UpdateAzureScanOptionsError is a struct for typed errors of method [`AgentlessScanningAPI::update_azure_scan_options`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum UpdateAzureScanOptionsError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// Datadog Agentless Scanning provides visibility into risks and vulnerabilities /// within your hosts, running containers, and serverless functions—all without /// requiring teams to install Agents on every host or where Agents cannot be installed. @@ -451,6 +483,159 @@ impl AgentlessScanningAPI { } } + /// Activate Agentless scan options for an Azure subscription. + pub async fn create_azure_scan_options( + &self, + body: crate::datadogV2::model::AzureScanOptions, + ) -> Result< + crate::datadogV2::model::AzureScanOptions, + datadog::Error, + > { + match self.create_azure_scan_options_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), + } + } + + /// Activate Agentless scan options for an Azure subscription. + pub async fn create_azure_scan_options_with_http_info( + &self, + body: crate::datadogV2::model::AzureScanOptions, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.create_azure_scan_options"; + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/agentless_scanning/accounts/azure", + 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)) + } + } + /// Delete Agentless scan options for an AWS account. pub async fn delete_aws_scan_options( &self, @@ -542,6 +727,97 @@ impl AgentlessScanningAPI { } } + /// Delete Agentless scan options for an Azure subscription. + pub async fn delete_azure_scan_options( + &self, + subscription_id: String, + ) -> Result<(), datadog::Error> { + match self + .delete_azure_scan_options_with_http_info(subscription_id) + .await + { + Ok(_) => Ok(()), + Err(err) => Err(err), + } + } + + /// Delete Agentless scan options for an Azure subscription. + pub async fn delete_azure_scan_options_with_http_info( + &self, + subscription_id: String, + ) -> Result, datadog::Error> { + let local_configuration = &self.config; + let operation_id = "v2.delete_azure_scan_options"; + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/agentless_scanning/accounts/azure/{subscription_id}", + local_configuration.get_operation_host(operation_id), + subscription_id = datadog::urlencode(subscription_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::DELETE, 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)) + } + } + /// Fetch the data of a specific on demand task. pub async fn get_aws_on_demand_task( &self, @@ -970,6 +1246,112 @@ impl AgentlessScanningAPI { } } + /// Fetches the scan options configured for Azure accounts. + pub async fn list_azure_scan_options( + &self, + ) -> Result< + crate::datadogV2::model::AzureScanOptionsArray, + datadog::Error, + > { + match self.list_azure_scan_options_with_http_info().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), + } + } + + /// Fetches the scan options configured for Azure accounts. + pub async fn list_azure_scan_options_with_http_info( + &self, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.list_azure_scan_options"; + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/agentless_scanning/accounts/azure", + local_configuration.get_operation_host(operation_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)) + } + } + /// Update the Agentless scan options for an activated account. pub async fn update_aws_scan_options( &self, @@ -1108,4 +1490,163 @@ impl AgentlessScanningAPI { Err(datadog::Error::ResponseError(local_error)) } } + + /// Update the Agentless scan options for an activated subscription. + pub async fn update_azure_scan_options( + &self, + subscription_id: String, + body: crate::datadogV2::model::AzureScanOptionsInputUpdate, + ) -> Result< + crate::datadogV2::model::AzureScanOptions, + datadog::Error, + > { + match self + .update_azure_scan_options_with_http_info(subscription_id, 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), + } + } + + /// Update the Agentless scan options for an activated subscription. + pub async fn update_azure_scan_options_with_http_info( + &self, + subscription_id: String, + body: crate::datadogV2::model::AzureScanOptionsInputUpdate, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.update_azure_scan_options"; + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/agentless_scanning/accounts/azure/{subscription_id}", + local_configuration.get_operation_host(operation_id), + subscription_id = datadog::urlencode(subscription_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::PATCH, 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)) + } + } } diff --git a/src/datadogV2/model/mod.rs b/src/datadogV2/model/mod.rs index 5bb6bc30a..ae608a304 100644 --- a/src/datadogV2/model/mod.rs +++ b/src/datadogV2/model/mod.rs @@ -554,6 +554,24 @@ pub mod model_aws_scan_options_update_data; pub use self::model_aws_scan_options_update_data::AwsScanOptionsUpdateData; pub mod model_aws_scan_options_update_attributes; pub use self::model_aws_scan_options_update_attributes::AwsScanOptionsUpdateAttributes; +pub mod model_azure_scan_options_array; +pub use self::model_azure_scan_options_array::AzureScanOptionsArray; +pub mod model_azure_scan_options_data; +pub use self::model_azure_scan_options_data::AzureScanOptionsData; +pub mod model_azure_scan_options_data_attributes; +pub use self::model_azure_scan_options_data_attributes::AzureScanOptionsDataAttributes; +pub mod model_azure_scan_options_data_type; +pub use self::model_azure_scan_options_data_type::AzureScanOptionsDataType; +pub mod model_azure_scan_options; +pub use self::model_azure_scan_options::AzureScanOptions; +pub mod model_azure_scan_options_input_update; +pub use self::model_azure_scan_options_input_update::AzureScanOptionsInputUpdate; +pub mod model_azure_scan_options_input_update_data; +pub use self::model_azure_scan_options_input_update_data::AzureScanOptionsInputUpdateData; +pub mod model_azure_scan_options_input_update_data_attributes; +pub use self::model_azure_scan_options_input_update_data_attributes::AzureScanOptionsInputUpdateDataAttributes; +pub mod model_azure_scan_options_input_update_data_type; +pub use self::model_azure_scan_options_input_update_data_type::AzureScanOptionsInputUpdateDataType; pub mod model_aws_on_demand_list_response; pub use self::model_aws_on_demand_list_response::AwsOnDemandListResponse; pub mod model_aws_on_demand_data; diff --git a/src/datadogV2/model/model_azure_scan_options.rs b/src/datadogV2/model/model_azure_scan_options.rs new file mode 100644 index 000000000..742d7ea4f --- /dev/null +++ b/src/datadogV2/model/model_azure_scan_options.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}; + +/// The definition of `AzureScanOptions` object. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct AzureScanOptions { + /// The definition of `AzureScanOptionsData` object. + #[serde(rename = "data")] + pub data: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl AzureScanOptions { + pub fn new() -> AzureScanOptions { + AzureScanOptions { + data: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn data(mut self, value: crate::datadogV2::model::AzureScanOptionsData) -> 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 AzureScanOptions { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for AzureScanOptions { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct AzureScanOptionsVisitor; + impl<'a> Visitor<'a> for AzureScanOptionsVisitor { + type Value = AzureScanOptions; + + 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 = AzureScanOptions { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(AzureScanOptionsVisitor) + } +} diff --git a/src/datadogV2/model/model_azure_scan_options_array.rs b/src/datadogV2/model/model_azure_scan_options_array.rs new file mode 100644 index 000000000..cd15d44ec --- /dev/null +++ b/src/datadogV2/model/model_azure_scan_options_array.rs @@ -0,0 +1,92 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// The definition of `AzureScanOptionsArray` object. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct AzureScanOptionsArray { + /// The `AzureScanOptionsArray` `data`. + #[serde(rename = "data")] + pub data: Vec, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl AzureScanOptionsArray { + pub fn new(data: Vec) -> AzureScanOptionsArray { + AzureScanOptionsArray { + 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 AzureScanOptionsArray { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct AzureScanOptionsArrayVisitor; + impl<'a> Visitor<'a> for AzureScanOptionsArrayVisitor { + type Value = AzureScanOptionsArray; + + 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 = AzureScanOptionsArray { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(AzureScanOptionsArrayVisitor) + } +} diff --git a/src/datadogV2/model/model_azure_scan_options_data.rs b/src/datadogV2/model/model_azure_scan_options_data.rs new file mode 100644 index 000000000..418763de9 --- /dev/null +++ b/src/datadogV2/model/model_azure_scan_options_data.rs @@ -0,0 +1,135 @@ +// 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}; + +/// The definition of `AzureScanOptionsData` object. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct AzureScanOptionsData { + /// The definition of `AzureScanOptionsDataAttributes` object. + #[serde(rename = "attributes")] + pub attributes: Option, + /// The `AzureScanOptionsData` `id`. + #[serde(rename = "id")] + pub id: String, + /// The type of the resource. The value should always be `azure_scan_options`. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::AzureScanOptionsDataType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl AzureScanOptionsData { + pub fn new( + id: String, + type_: crate::datadogV2::model::AzureScanOptionsDataType, + ) -> AzureScanOptionsData { + AzureScanOptionsData { + attributes: None, + id, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn attributes( + mut self, + value: crate::datadogV2::model::AzureScanOptionsDataAttributes, + ) -> Self { + self.attributes = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for AzureScanOptionsData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct AzureScanOptionsDataVisitor; + impl<'a> Visitor<'a> for AzureScanOptionsDataVisitor { + type Value = AzureScanOptionsData; + + 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::AzureScanOptionsDataAttributes, + > = 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" => { + if v.is_null() { + continue; + } + 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::AzureScanOptionsDataType::UnparsedObject(_type_) => { + _unparsed = true; + }, + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let id = id.ok_or_else(|| M::Error::missing_field("id"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = AzureScanOptionsData { + attributes, + id, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(AzureScanOptionsDataVisitor) + } +} diff --git a/src/datadogV2/model/model_azure_scan_options_data_attributes.rs b/src/datadogV2/model/model_azure_scan_options_data_attributes.rs new file mode 100644 index 000000000..59aa80e62 --- /dev/null +++ b/src/datadogV2/model/model_azure_scan_options_data_attributes.rs @@ -0,0 +1,124 @@ +// 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}; + +/// The definition of `AzureScanOptionsDataAttributes` object. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct AzureScanOptionsDataAttributes { + /// The `attributes` `vuln_containers_os`. + #[serde(rename = "vuln_containers_os")] + pub vuln_containers_os: Option, + /// The `attributes` `vuln_host_os`. + #[serde(rename = "vuln_host_os")] + pub vuln_host_os: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl AzureScanOptionsDataAttributes { + pub fn new() -> AzureScanOptionsDataAttributes { + AzureScanOptionsDataAttributes { + vuln_containers_os: None, + vuln_host_os: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn vuln_containers_os(mut self, value: bool) -> Self { + self.vuln_containers_os = Some(value); + self + } + + pub fn vuln_host_os(mut self, value: bool) -> Self { + self.vuln_host_os = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for AzureScanOptionsDataAttributes { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for AzureScanOptionsDataAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct AzureScanOptionsDataAttributesVisitor; + impl<'a> Visitor<'a> for AzureScanOptionsDataAttributesVisitor { + type Value = AzureScanOptionsDataAttributes; + + 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 vuln_containers_os: Option = None; + let mut vuln_host_os: 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() { + "vuln_containers_os" => { + if v.is_null() { + continue; + } + vuln_containers_os = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "vuln_host_os" => { + if v.is_null() { + continue; + } + vuln_host_os = + 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 = AzureScanOptionsDataAttributes { + vuln_containers_os, + vuln_host_os, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(AzureScanOptionsDataAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_azure_scan_options_data_type.rs b/src/datadogV2/model/model_azure_scan_options_data_type.rs new file mode 100644 index 000000000..bf903ebb7 --- /dev/null +++ b/src/datadogV2/model/model_azure_scan_options_data_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 AzureScanOptionsDataType { + AZURE_SCAN_OPTIONS, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for AzureScanOptionsDataType { + fn to_string(&self) -> String { + match self { + Self::AZURE_SCAN_OPTIONS => String::from("azure_scan_options"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for AzureScanOptionsDataType { + 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 AzureScanOptionsDataType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "azure_scan_options" => Self::AZURE_SCAN_OPTIONS, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/src/datadogV2/model/model_azure_scan_options_input_update.rs b/src/datadogV2/model/model_azure_scan_options_input_update.rs new file mode 100644 index 000000000..287765659 --- /dev/null +++ b/src/datadogV2/model/model_azure_scan_options_input_update.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}; + +/// The definition of `AzureScanOptionsInputUpdate` object. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct AzureScanOptionsInputUpdate { + /// The definition of `AzureScanOptionsInputUpdateData` object. + #[serde(rename = "data")] + pub data: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl AzureScanOptionsInputUpdate { + pub fn new() -> AzureScanOptionsInputUpdate { + AzureScanOptionsInputUpdate { + data: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn data(mut self, value: crate::datadogV2::model::AzureScanOptionsInputUpdateData) -> 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 AzureScanOptionsInputUpdate { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for AzureScanOptionsInputUpdate { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct AzureScanOptionsInputUpdateVisitor; + impl<'a> Visitor<'a> for AzureScanOptionsInputUpdateVisitor { + type Value = AzureScanOptionsInputUpdate; + + 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 = AzureScanOptionsInputUpdate { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(AzureScanOptionsInputUpdateVisitor) + } +} diff --git a/src/datadogV2/model/model_azure_scan_options_input_update_data.rs b/src/datadogV2/model/model_azure_scan_options_input_update_data.rs new file mode 100644 index 000000000..663487929 --- /dev/null +++ b/src/datadogV2/model/model_azure_scan_options_input_update_data.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}; + +/// The definition of `AzureScanOptionsInputUpdateData` object. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct AzureScanOptionsInputUpdateData { + /// The definition of `AzureScanOptionsInputUpdateDataAttributes` object. + #[serde(rename = "attributes")] + pub attributes: Option, + /// The `AzureScanOptionsInputUpdateData` `id`. + #[serde(rename = "id")] + pub id: String, + /// Azure scan options resource type. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::AzureScanOptionsInputUpdateDataType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl AzureScanOptionsInputUpdateData { + pub fn new( + id: String, + type_: crate::datadogV2::model::AzureScanOptionsInputUpdateDataType, + ) -> AzureScanOptionsInputUpdateData { + AzureScanOptionsInputUpdateData { + attributes: None, + id, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn attributes( + mut self, + value: crate::datadogV2::model::AzureScanOptionsInputUpdateDataAttributes, + ) -> Self { + self.attributes = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for AzureScanOptionsInputUpdateData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct AzureScanOptionsInputUpdateDataVisitor; + impl<'a> Visitor<'a> for AzureScanOptionsInputUpdateDataVisitor { + type Value = AzureScanOptionsInputUpdateData; + + 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::AzureScanOptionsInputUpdateDataAttributes, + > = None; + let mut id: Option = None; + let mut type_: Option< + crate::datadogV2::model::AzureScanOptionsInputUpdateDataType, + > = 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" => { + if v.is_null() { + continue; + } + 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::AzureScanOptionsInputUpdateDataType::UnparsedObject(_type_) => { + _unparsed = true; + }, + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let id = id.ok_or_else(|| M::Error::missing_field("id"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = AzureScanOptionsInputUpdateData { + attributes, + id, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(AzureScanOptionsInputUpdateDataVisitor) + } +} diff --git a/src/datadogV2/model/model_azure_scan_options_input_update_data_attributes.rs b/src/datadogV2/model/model_azure_scan_options_input_update_data_attributes.rs new file mode 100644 index 000000000..e64d49727 --- /dev/null +++ b/src/datadogV2/model/model_azure_scan_options_input_update_data_attributes.rs @@ -0,0 +1,124 @@ +// 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}; + +/// The definition of `AzureScanOptionsInputUpdateDataAttributes` object. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct AzureScanOptionsInputUpdateDataAttributes { + /// The `attributes` `vuln_containers_os`. + #[serde(rename = "vuln_containers_os")] + pub vuln_containers_os: Option, + /// The `attributes` `vuln_host_os`. + #[serde(rename = "vuln_host_os")] + pub vuln_host_os: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl AzureScanOptionsInputUpdateDataAttributes { + pub fn new() -> AzureScanOptionsInputUpdateDataAttributes { + AzureScanOptionsInputUpdateDataAttributes { + vuln_containers_os: None, + vuln_host_os: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn vuln_containers_os(mut self, value: bool) -> Self { + self.vuln_containers_os = Some(value); + self + } + + pub fn vuln_host_os(mut self, value: bool) -> Self { + self.vuln_host_os = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for AzureScanOptionsInputUpdateDataAttributes { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for AzureScanOptionsInputUpdateDataAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct AzureScanOptionsInputUpdateDataAttributesVisitor; + impl<'a> Visitor<'a> for AzureScanOptionsInputUpdateDataAttributesVisitor { + type Value = AzureScanOptionsInputUpdateDataAttributes; + + 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 vuln_containers_os: Option = None; + let mut vuln_host_os: 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() { + "vuln_containers_os" => { + if v.is_null() { + continue; + } + vuln_containers_os = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "vuln_host_os" => { + if v.is_null() { + continue; + } + vuln_host_os = + 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 = AzureScanOptionsInputUpdateDataAttributes { + vuln_containers_os, + vuln_host_os, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(AzureScanOptionsInputUpdateDataAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_azure_scan_options_input_update_data_type.rs b/src/datadogV2/model/model_azure_scan_options_input_update_data_type.rs new file mode 100644 index 000000000..e5b7db689 --- /dev/null +++ b/src/datadogV2/model/model_azure_scan_options_input_update_data_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 AzureScanOptionsInputUpdateDataType { + AZURE_SCAN_OPTIONS, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for AzureScanOptionsInputUpdateDataType { + fn to_string(&self) -> String { + match self { + Self::AZURE_SCAN_OPTIONS => String::from("azure_scan_options"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for AzureScanOptionsInputUpdateDataType { + 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 AzureScanOptionsInputUpdateDataType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "azure_scan_options" => Self::AZURE_SCAN_OPTIONS, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/tests/scenarios/cassettes/v2/agentless_scanning/Create-azure-scan-options-returns-Created-response.frozen b/tests/scenarios/cassettes/v2/agentless_scanning/Create-azure-scan-options-returns-Created-response.frozen new file mode 100644 index 000000000..1f060e7c1 --- /dev/null +++ b/tests/scenarios/cassettes/v2/agentless_scanning/Create-azure-scan-options-returns-Created-response.frozen @@ -0,0 +1 @@ +2025-09-30T18:30:00.006Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/agentless_scanning/Create-azure-scan-options-returns-Created-response.json b/tests/scenarios/cassettes/v2/agentless_scanning/Create-azure-scan-options-returns-Created-response.json new file mode 100644 index 000000000..1f0d68ca5 --- /dev/null +++ b/tests/scenarios/cassettes/v2/agentless_scanning/Create-azure-scan-options-returns-Created-response.json @@ -0,0 +1,67 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"data\":{\"attributes\":{\"vuln_containers_os\":true,\"vuln_host_os\":true},\"id\":\"12345678-90ab-cdef-1234-567890abcdef\",\"type\":\"azure_scan_options\"}}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "post", + "uri": "https://api.datadoghq.com/api/v2/agentless_scanning/accounts/azure" + }, + "response": { + "body": { + "string": "{\"data\":{\"id\":\"12345678-90ab-cdef-1234-567890abcdef\",\"type\":\"azure_scan_options\",\"attributes\":{\"vuln_containers_os\":true,\"vuln_host_os\":true}}}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 201, + "message": "Created" + } + }, + "recorded_at": "Tue, 30 Sep 2025 18:30:00 GMT" + }, + { + "request": { + "body": "", + "headers": { + "Accept": [ + "*/*" + ] + }, + "method": "delete", + "uri": "https://api.datadoghq.com/api/v2/agentless_scanning/accounts/azure/12345678-90ab-cdef-1234-567890abcdef" + }, + "response": { + "body": { + "string": "", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 200, + "message": "OK" + } + }, + "recorded_at": "Tue, 30 Sep 2025 18:30:00 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/agentless_scanning/List-azure-scan-options-returns-OK-response.frozen b/tests/scenarios/cassettes/v2/agentless_scanning/List-azure-scan-options-returns-OK-response.frozen new file mode 100644 index 000000000..9a9117548 --- /dev/null +++ b/tests/scenarios/cassettes/v2/agentless_scanning/List-azure-scan-options-returns-OK-response.frozen @@ -0,0 +1 @@ +2025-09-30T18:30:00.763Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v2/agentless_scanning/List-azure-scan-options-returns-OK-response.json b/tests/scenarios/cassettes/v2/agentless_scanning/List-azure-scan-options-returns-OK-response.json new file mode 100644 index 000000000..65a7e3fc3 --- /dev/null +++ b/tests/scenarios/cassettes/v2/agentless_scanning/List-azure-scan-options-returns-OK-response.json @@ -0,0 +1,33 @@ +{ + "http_interactions": [ + { + "request": { + "body": "", + "headers": { + "Accept": [ + "application/json" + ] + }, + "method": "get", + "uri": "https://api.datadoghq.com/api/v2/agentless_scanning/accounts/azure" + }, + "response": { + "body": { + "string": "{\"data\":[]}", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/vnd.api+json" + ] + }, + "status": { + "code": 200, + "message": "OK" + } + }, + "recorded_at": "Tue, 30 Sep 2025 18:30:00 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/features/v2/agentless_scanning.feature b/tests/scenarios/features/v2/agentless_scanning.feature index f5f66c57c..280cc3413 100644 --- a/tests/scenarios/features/v2/agentless_scanning.feature +++ b/tests/scenarios/features/v2/agentless_scanning.feature @@ -12,6 +12,13 @@ Feature: Agentless Scanning And a valid "appKeyAuth" key in the system And an instance of "AgentlessScanning" API + @skip-validation @team:DataDog/k9-agentless + Scenario: Create azure scan options returns "Created" response + Given new "CreateAzureScanOptions" request + And body with value {"data": {"attributes": {"vuln_containers_os": true, "vuln_host_os": true}, "id": "12345678-90ab-cdef-1234-567890abcdef", "type": "azure_scan_options"}} + When the request is sent + Then the response status is 201 Created + @team:DataDog/k9-agentless Scenario: Delete AWS Scan Options returns "Bad Request" response Given new "DeleteAwsScanOptions" request @@ -33,6 +40,13 @@ Feature: Agentless Scanning When the request is sent Then the response status is 404 Not Found + @generated @skip @team:DataDog/k9-agentless + Scenario: Delete azure scan options returns "No Content" response + Given new "DeleteAzureScanOptions" request + And request contains "subscription_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 204 No Content + @team:DataDog/k9-agentless Scenario: Get AWS On Demand task by id returns "Bad Request" response Given new "GetAwsOnDemandTask" request @@ -92,6 +106,12 @@ Feature: Agentless Scanning When the request is sent Then the response status is 200 OK + @team:DataDog/k9-agentless + Scenario: List azure scan options returns "OK" response + Given new "ListAzureScanOptions" request + When the request is sent + Then the response status is 200 OK + @skip @team:DataDog/k9-agentless Scenario: Patch AWS Scan Options returns "Bad Request" response Given new "UpdateAwsScanOptions" request @@ -159,3 +179,11 @@ Feature: Agentless Scanning And body with value {"data": {"attributes": {"arn": "invalid-arn"}, "type": "aws_resource"}} When the request is sent Then the response status is 400 Bad Request + + @generated @skip @team:DataDog/k9-agentless + Scenario: Update azure scan options returns "OK" response + Given new "UpdateAzureScanOptions" request + And request contains "subscription_id" parameter from "REPLACE.ME" + And body with value {"data": {"id": "12345678-90ab-cdef-1234-567890abcdef", "type": "azure_scan_options"}} + When the request is sent + Then the response status is 200 OK diff --git a/tests/scenarios/features/v2/undo.json b/tests/scenarios/features/v2/undo.json index 92c07fe00..6fcf52fce 100644 --- a/tests/scenarios/features/v2/undo.json +++ b/tests/scenarios/features/v2/undo.json @@ -152,6 +152,37 @@ "type": "idempotent" } }, + "ListAzureScanOptions": { + "tag": "Agentless Scanning", + "undo": { + "type": "safe" + } + }, + "CreateAzureScanOptions": { + "tag": "Agentless Scanning", + "undo": { + "operationId": "DeleteAzureScanOptions", + "parameters": [ + { + "name": "subscription_id", + "source": "data.id" + } + ], + "type": "unsafe" + } + }, + "DeleteAzureScanOptions": { + "tag": "Agentless Scanning", + "undo": { + "type": "idempotent" + } + }, + "UpdateAzureScanOptions": { + "tag": "Agentless Scanning", + "undo": { + "type": "idempotent" + } + }, "ListAwsOnDemandTasks": { "tag": "Agentless Scanning", "undo": { diff --git a/tests/scenarios/function_mappings.rs b/tests/scenarios/function_mappings.rs index 256846a1f..cae9c45b7 100644 --- a/tests/scenarios/function_mappings.rs +++ b/tests/scenarios/function_mappings.rs @@ -1842,6 +1842,22 @@ pub fn collect_function_calls(world: &mut DatadogWorld) { "v2.UpdateAwsScanOptions".into(), test_v2_update_aws_scan_options, ); + world.function_mappings.insert( + "v2.ListAzureScanOptions".into(), + test_v2_list_azure_scan_options, + ); + world.function_mappings.insert( + "v2.CreateAzureScanOptions".into(), + test_v2_create_azure_scan_options, + ); + world.function_mappings.insert( + "v2.DeleteAzureScanOptions".into(), + test_v2_delete_azure_scan_options, + ); + world.function_mappings.insert( + "v2.UpdateAzureScanOptions".into(), + test_v2_update_azure_scan_options, + ); world.function_mappings.insert( "v2.ListAwsOnDemandTasks".into(), test_v2_list_aws_on_demand_tasks, @@ -11945,6 +11961,118 @@ fn test_v2_update_aws_scan_options(world: &mut DatadogWorld, _parameters: &HashM world.response.code = response.status.as_u16(); } +fn test_v2_list_azure_scan_options(world: &mut DatadogWorld, _parameters: &HashMap) { + let api = world + .api_instances + .v2_api_agentless_scanning + .as_ref() + .expect("api instance not found"); + let response = match block_on(api.list_azure_scan_options_with_http_info()) { + 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_azure_scan_options( + world: &mut DatadogWorld, + _parameters: &HashMap, +) { + let api = world + .api_instances + .v2_api_agentless_scanning + .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_azure_scan_options_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_delete_azure_scan_options( + world: &mut DatadogWorld, + _parameters: &HashMap, +) { + let api = world + .api_instances + .v2_api_agentless_scanning + .as_ref() + .expect("api instance not found"); + let subscription_id = + serde_json::from_value(_parameters.get("subscription_id").unwrap().clone()).unwrap(); + let response = match block_on(api.delete_azure_scan_options_with_http_info(subscription_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_update_azure_scan_options( + world: &mut DatadogWorld, + _parameters: &HashMap, +) { + let api = world + .api_instances + .v2_api_agentless_scanning + .as_ref() + .expect("api instance not found"); + let subscription_id = + serde_json::from_value(_parameters.get("subscription_id").unwrap().clone()).unwrap(); + let body = serde_json::from_value(_parameters.get("body").unwrap().clone()).unwrap(); + let response = + match block_on(api.update_azure_scan_options_with_http_info(subscription_id, 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_list_aws_on_demand_tasks( world: &mut DatadogWorld, _parameters: &HashMap,