Skip to content

Commit f3843ab

Browse files
committed
fix clippy
1 parent b1306bd commit f3843ab

File tree

9 files changed

+321
-51
lines changed

9 files changed

+321
-51
lines changed

dsc_lib/src/configure/mod.rs

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ use crate::configure::context::{Context, ProcessMode};
66
use crate::configure::{config_doc::RestartRequired, parameters::Input};
77
use crate::discovery::discovery_trait::DiscoveryFilter;
88
use crate::dscerror::DscError;
9-
use crate::dscresources::invoke_result::ExportResult;
109
use crate::dscresources::{
11-
{dscresource::{Capability, Invoke, get_diff, validate_properties},
12-
invoke_result::{GetResult, SetResult, TestResult, ResourceSetResponse}},
13-
resource_manifest::Kind,
10+
{dscresource::{Capability, Invoke, get_diff, validate_properties, get_adapter_input_kind},
11+
invoke_result::{GetResult, SetResult, TestResult, ExportResult, ResourceSetResponse}},
12+
resource_manifest::{AdapterInputKind, Kind},
1413
};
1514
use crate::DscResource;
1615
use crate::discovery::Discovery;
@@ -177,7 +176,7 @@ fn escape_property_values(properties: &Map<String, Value>) -> Result<Option<Map<
177176
}
178177

179178
fn add_metadata(dsc_resource: &DscResource, mut properties: Option<Map<String, Value>>, resource_metadata: Option<Metadata> ) -> Result<String, DscError> {
180-
if dsc_resource.kind == Kind::Adapter {
179+
if dsc_resource.kind == Kind::Adapter && get_adapter_input_kind(dsc_resource)? == AdapterInputKind::Full {
181180
// add metadata to the properties so the adapter knows this is a config
182181
let mut metadata: Map<String, Value> = Map::new();
183182
if let Some(resource_metadata) = resource_metadata {
@@ -319,6 +318,15 @@ impl Configurator {
319318
&self.config
320319
}
321320

321+
/// Get the discovery.
322+
///
323+
/// # Returns
324+
///
325+
/// * `&Discovery` - The discovery.
326+
pub fn discovery(&mut self) -> &mut Discovery {
327+
&mut self.discovery
328+
}
329+
322330
fn get_properties(&mut self, resource: &Resource, resource_kind: &Kind) -> Result<Option<Map<String, Value>>, DscError> {
323331
match resource_kind {
324332
Kind::Group => {
@@ -342,14 +350,14 @@ impl Configurator {
342350
/// This function will return an error if the underlying resource fails.
343351
pub fn invoke_get(&mut self) -> Result<ConfigurationGetResult, DscError> {
344352
self.unroll_copy_loops()?;
345-
353+
346354
let mut result = ConfigurationGetResult::new();
347355
let resources = get_resource_invocation_order(&self.config, &mut self.statement_parser, &self.context)?;
348356
let mut progress = ProgressBar::new(resources.len() as u64, self.progress_format)?;
349357
let discovery = &mut self.discovery.clone();
350358
for resource in resources {
351359
let evaluated_name = self.evaluate_resource_name(&resource.name)?;
352-
360+
353361
progress.set_resource(&evaluated_name, &resource.resource_type);
354362
progress.write_activity(format!("Get '{evaluated_name}'").as_str());
355363
if self.skip_resource(&resource)? {
@@ -424,14 +432,14 @@ impl Configurator {
424432
#[allow(clippy::too_many_lines)]
425433
pub fn invoke_set(&mut self, skip_test: bool) -> Result<ConfigurationSetResult, DscError> {
426434
self.unroll_copy_loops()?;
427-
435+
428436
let mut result = ConfigurationSetResult::new();
429437
let resources = get_resource_invocation_order(&self.config, &mut self.statement_parser, &self.context)?;
430438
let mut progress = ProgressBar::new(resources.len() as u64, self.progress_format)?;
431439
let discovery = &mut self.discovery.clone();
432440
for resource in resources {
433441
let evaluated_name = self.evaluate_resource_name(&resource.name)?;
434-
442+
435443
progress.set_resource(&evaluated_name, &resource.resource_type);
436444
progress.write_activity(format!("Set '{evaluated_name}'").as_str());
437445
if self.skip_resource(&resource)? {
@@ -580,14 +588,14 @@ impl Configurator {
580588
/// This function will return an error if the underlying resource fails.
581589
pub fn invoke_test(&mut self) -> Result<ConfigurationTestResult, DscError> {
582590
self.unroll_copy_loops()?;
583-
591+
584592
let mut result = ConfigurationTestResult::new();
585593
let resources = get_resource_invocation_order(&self.config, &mut self.statement_parser, &self.context)?;
586594
let mut progress = ProgressBar::new(resources.len() as u64, self.progress_format)?;
587595
let discovery = &mut self.discovery.clone();
588596
for resource in resources {
589597
let evaluated_name = self.evaluate_resource_name(&resource.name)?;
590-
598+
591599
progress.set_resource(&evaluated_name, &resource.resource_type);
592600
progress.write_activity(format!("Test '{evaluated_name}'").as_str());
593601
if self.skip_resource(&resource)? {
@@ -658,7 +666,7 @@ impl Configurator {
658666
/// This function will return an error if the underlying resource fails.
659667
pub fn invoke_export(&mut self) -> Result<ConfigurationExportResult, DscError> {
660668
self.unroll_copy_loops()?;
661-
669+
662670
let mut result = ConfigurationExportResult::new();
663671
let mut conf = config_doc::Configuration::new();
664672
conf.metadata.clone_from(&self.config.metadata);
@@ -668,7 +676,7 @@ impl Configurator {
668676
let discovery = &mut self.discovery.clone();
669677
for resource in &resources {
670678
let evaluated_name = self.evaluate_resource_name(&resource.name)?;
671-
679+
672680
progress.set_resource(&evaluated_name, &resource.resource_type);
673681
progress.write_activity(format!("Export '{evaluated_name}'").as_str());
674682
if self.skip_resource(resource)? {
@@ -916,7 +924,7 @@ impl Configurator {
916924
fn unroll_copy_loops(&mut self) -> Result<(), DscError> {
917925
let mut config = self.config.clone();
918926
let config_copy = config.clone();
919-
927+
920928
for resource in config_copy.resources {
921929
// if the resource contains `Copy`, unroll it
922930
if let Some(copy) = &resource.copy {
@@ -931,7 +939,7 @@ impl Configurator {
931939
return Err(DscError::Parser(t!("configure.mod.copyNameResultNotString").to_string()))
932940
};
933941
new_resource.name = new_name.to_string();
934-
942+
935943
new_resource.copy = None;
936944
copy_resources.push(new_resource);
937945
}
@@ -941,7 +949,7 @@ impl Configurator {
941949
config.resources.extend(copy_resources);
942950
}
943951
}
944-
952+
945953
self.config = config;
946954
Ok(())
947955
}
@@ -967,12 +975,12 @@ impl Configurator {
967975
if self.context.process_mode == ProcessMode::Copy {
968976
return Ok(name.to_string());
969977
}
970-
978+
971979
// evaluate the resource name (handles both expressions and literals)
972980
let Value::String(evaluated_name) = self.statement_parser.parse_and_execute(name, &self.context)? else {
973981
return Err(DscError::Parser(t!("configure.mod.nameResultNotString").to_string()))
974982
};
975-
983+
976984
Ok(evaluated_name)
977985
}
978986

dsc_lib/src/dscresources/command_resource.rs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pub fn invoke_get(resource: &ResourceManifest, cwd: &str, filter: &str) -> Resul
3131
let Some(get) = &resource.get else {
3232
return Err(DscError::NotImplemented("get".to_string()));
3333
};
34-
let args = process_args(get.args.as_ref(), filter);
34+
let args = process_args(get.args.as_ref(), filter, &resource.resource_type);
3535
if !filter.is_empty() {
3636
verify_json(resource, cwd, filter)?;
3737
command_input = get_command_input(get.input.as_ref(), filter)?;
@@ -136,7 +136,7 @@ pub fn invoke_set(resource: &ResourceManifest, cwd: &str, desired: &str, skip_te
136136
let Some(get) = &resource.get else {
137137
return Err(DscError::NotImplemented("get".to_string()));
138138
};
139-
let args = process_args(get.args.as_ref(), desired);
139+
let args = process_args(get.args.as_ref(), desired, &resource.resource_type);
140140
let command_input = get_command_input(get.input.as_ref(), desired)?;
141141

142142
info!("{}", t!("dscresources.commandResource.setGetCurrent", resource = &resource.resource_type, executable = &get.executable));
@@ -168,7 +168,7 @@ pub fn invoke_set(resource: &ResourceManifest, cwd: &str, desired: &str, skip_te
168168

169169
let mut env: Option<HashMap<String, String>> = None;
170170
let mut input_desired: Option<&str> = None;
171-
let args = process_args(set.args.as_ref(), desired);
171+
let args = process_args(set.args.as_ref(), desired, &resource.resource_type);
172172
match &set.input {
173173
Some(InputKind::Env) => {
174174
env = Some(json_to_hashmap(desired)?);
@@ -272,7 +272,7 @@ pub fn invoke_test(resource: &ResourceManifest, cwd: &str, expected: &str) -> Re
272272

273273
verify_json(resource, cwd, expected)?;
274274

275-
let args = process_args(test.args.as_ref(), expected);
275+
let args = process_args(test.args.as_ref(), expected, &resource.resource_type);
276276
let command_input = get_command_input(test.input.as_ref(), expected)?;
277277

278278
info!("{}", t!("dscresources.commandResource.invokeTestUsing", resource = &resource.resource_type, executable = &test.executable));
@@ -410,7 +410,7 @@ pub fn invoke_delete(resource: &ResourceManifest, cwd: &str, filter: &str) -> Re
410410

411411
verify_json(resource, cwd, filter)?;
412412

413-
let args = process_args(delete.args.as_ref(), filter);
413+
let args = process_args(delete.args.as_ref(), filter, &resource.resource_type);
414414
let command_input = get_command_input(delete.input.as_ref(), filter)?;
415415

416416
info!("{}", t!("dscresources.commandResource.invokeDeleteUsing", resource = &resource.resource_type, executable = &delete.executable));
@@ -441,7 +441,7 @@ pub fn invoke_validate(resource: &ResourceManifest, cwd: &str, config: &str) ->
441441
return Err(DscError::NotImplemented("validate".to_string()));
442442
};
443443

444-
let args = process_args(validate.args.as_ref(), config);
444+
let args = process_args(validate.args.as_ref(), config, &resource.resource_type);
445445
let command_input = get_command_input(validate.input.as_ref(), config)?;
446446

447447
info!("{}", t!("dscresources.commandResource.invokeValidateUsing", resource = &resource.resource_type, executable = &validate.executable));
@@ -525,9 +525,9 @@ pub fn invoke_export(resource: &ResourceManifest, cwd: &str, input: Option<&str>
525525
command_input = get_command_input(export.input.as_ref(), input)?;
526526
}
527527

528-
args = process_args(export.args.as_ref(), input);
528+
args = process_args(export.args.as_ref(), input, &resource.resource_type);
529529
} else {
530-
args = process_args(export.args.as_ref(), "");
530+
args = process_args(export.args.as_ref(), "", &resource.resource_type);
531531
}
532532

533533
let (_exit_code, stdout, stderr) = invoke_command(&export.executable, args, command_input.stdin.as_deref(), Some(cwd), command_input.env, resource.exit_codes.as_ref())?;
@@ -572,7 +572,7 @@ pub fn invoke_resolve(resource: &ResourceManifest, cwd: &str, input: &str) -> Re
572572
return Err(DscError::Operation(t!("dscresources.commandResource.resolveNotSupported", resource = &resource.resource_type).to_string()));
573573
};
574574

575-
let args = process_args(resolve.args.as_ref(), input);
575+
let args = process_args(resolve.args.as_ref(), input, &resource.resource_type);
576576
let command_input = get_command_input(resolve.input.as_ref(), input)?;
577577

578578
info!("{}", t!("dscresources.commandResource.invokeResolveUsing", resource = &resource.resource_type, executable = &resolve.executable));
@@ -749,7 +749,7 @@ pub async fn invoke_command(executable: &str, args: Option<Vec<String>>, input:
749749
/// # Returns
750750
///
751751
/// A vector of strings representing the processed arguments
752-
pub fn process_args(args: Option<&Vec<ArgKind>>, value: &str) -> Option<Vec<String>> {
752+
pub fn process_args(args: Option<&Vec<ArgKind>>, input: &str, resource_type: &str) -> Option<Vec<String>> {
753753
let Some(arg_values) = args else {
754754
debug!("{}", t!("dscresources.commandResource.noArgs"));
755755
return None;
@@ -762,13 +762,17 @@ pub fn process_args(args: Option<&Vec<ArgKind>>, value: &str) -> Option<Vec<Stri
762762
processed_args.push(s.clone());
763763
},
764764
ArgKind::Json { json_input_arg, mandatory } => {
765-
if value.is_empty() && *mandatory != Some(true) {
765+
if input.is_empty() && *mandatory != Some(true) {
766766
continue;
767767
}
768768

769769
processed_args.push(json_input_arg.clone());
770-
processed_args.push(value.to_string());
770+
processed_args.push(input.to_string());
771771
},
772+
ArgKind::ResourceType { resource_type_arg } => {
773+
processed_args.push(resource_type_arg.clone());
774+
processed_args.push(resource_type.to_string());
775+
}
772776
}
773777
}
774778

dsc_lib/src/dscresources/dscresource.rs

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4-
use crate::{configure::{Configurator, config_doc::{Configuration, ExecutionKind, Resource}, context::ProcessMode, parameters::{SECURE_VALUE_REDACTED, is_secure_value}}, dscresources::resource_manifest::Kind};
4+
use crate::{configure::{Configurator, config_doc::{Configuration, ExecutionKind, Resource}, context::ProcessMode, parameters::{SECURE_VALUE_REDACTED, is_secure_value}}, dscresources::resource_manifest::{AdapterInputKind, Kind}};
55
use crate::dscresources::invoke_result::{ResourceGetResponse, ResourceSetResponse};
66
use dscerror::DscError;
77
use jsonschema::Validator;
@@ -129,6 +129,36 @@ impl DscResource {
129129
configurator.context.process_mode = ProcessMode::NoExpressionEvaluation;
130130
Ok(configurator)
131131
}
132+
133+
fn invoke_get_with_adapter(&self, adapter: &str, filter: &str) -> Result<GetResult, DscError> {
134+
let mut configurator = self.clone().create_config_for_adapter(adapter, filter)?;
135+
let adapter = Self::get_adapter_resource(&mut configurator, adapter)?;
136+
if get_adapter_input_kind(&adapter)? == AdapterInputKind::Single {
137+
return adapter.get(filter);
138+
}
139+
140+
let result = configurator.invoke_get()?;
141+
let GetResult::Resource(ref resource_result) = result.results[0].result else {
142+
return Err(DscError::Operation(t!("dscresources.dscresource.invokeReturnedWrongResult", operation = "get", resource = self.type_name).to_string()));
143+
};
144+
let properties = resource_result.actual_state
145+
.as_object().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "actualState", property_type = "object").to_string()))?
146+
.get("result").ok_or(DscError::Operation(t!("dscresources.dscresource.propertyNotFound", property = "result").to_string()))?
147+
.as_array().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "result", property_type = "array").to_string()))?[0]
148+
.as_object().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "result", property_type = "object").to_string()))?
149+
.get("properties").ok_or(DscError::Operation(t!("dscresources.dscresource.propertyNotFound", property = "properties").to_string()))?.clone();
150+
let get_result = GetResult::Resource(ResourceGetResponse {
151+
actual_state: properties.clone(),
152+
});
153+
Ok(get_result)
154+
}
155+
156+
fn get_adapter_resource(configurator: &mut Configurator, adapter: &str) -> Result<DscResource, DscError> {
157+
if let Some(adapter_resource) = configurator.discovery().find_resource(adapter, None) {
158+
return Ok(adapter_resource.clone());
159+
}
160+
Err(DscError::Operation(t!("dscresources.dscresource.adapterResourceNotFound", adapter = adapter).to_string()))
161+
}
132162
}
133163

134164
impl Default for DscResource {
@@ -229,21 +259,7 @@ impl Invoke for DscResource {
229259
fn get(&self, filter: &str) -> Result<GetResult, DscError> {
230260
debug!("{}", t!("dscresources.dscresource.invokeGet", resource = self.type_name));
231261
if let Some(adapter) = &self.require_adapter {
232-
let mut configurator = self.clone().create_config_for_adapter(adapter, filter)?;
233-
let result = configurator.invoke_get()?;
234-
let GetResult::Resource(ref resource_result) = result.results[0].result else {
235-
return Err(DscError::Operation(t!("dscresources.dscresource.invokeReturnedWrongResult", operation = "get", resource = self.type_name).to_string()));
236-
};
237-
let properties = resource_result.actual_state
238-
.as_object().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "actualState", property_type = "object").to_string()))?
239-
.get("result").ok_or(DscError::Operation(t!("dscresources.dscresource.propertyNotFound", property = "result").to_string()))?
240-
.as_array().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "result", property_type = "array").to_string()))?[0]
241-
.as_object().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "result", property_type = "object").to_string()))?
242-
.get("properties").ok_or(DscError::Operation(t!("dscresources.dscresource.propertyNotFound", property = "properties").to_string()))?.clone();
243-
let get_result = GetResult::Resource(ResourceGetResponse {
244-
actual_state: properties.clone(),
245-
});
246-
return Ok(get_result);
262+
return self.invoke_get_with_adapter(adapter, filter);
247263
}
248264

249265
match &self.implemented_as {
@@ -523,6 +539,28 @@ pub fn redact(value: &Value) -> Value {
523539
value.clone()
524540
}
525541

542+
/// Gets the input kind for an adapter resource
543+
///
544+
/// # Arguments
545+
/// * `adapter` - The adapter resource to get the input kind for
546+
///
547+
/// # Returns
548+
/// * `Result<AdapterInputKind, DscError>` - The input kind of the adapter or an error if not found
549+
///
550+
/// # Errors
551+
/// * `DscError` - The adapter manifest is not found or invalid
552+
pub fn get_adapter_input_kind(adapter: &DscResource) -> Result<AdapterInputKind, DscError> {
553+
if let Some(manifest) = &adapter.manifest {
554+
if let Ok(manifest) = serde_json::from_value::<ResourceManifest>(manifest.clone()) {
555+
if let Some(adapter_operation) = manifest.adapter {
556+
return Ok(adapter_operation.input_kind);
557+
}
558+
}
559+
}
560+
Err(DscError::Operation(t!("dscresources.dscresource.adapterManifestNotFound", adapter = adapter.type_name).to_string()))
561+
}
562+
563+
526564
#[must_use]
527565
/// Performs a comparison of two JSON Values if the expected is a strict subset of the actual
528566
///

dsc_lib/src/dscresources/resource_manifest.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ pub enum ArgKind {
8686
/// Indicates if argument is mandatory which will pass an empty string if no JSON input is provided. Default is false.
8787
mandatory: Option<bool>,
8888
},
89+
ResourceType {
90+
/// The argument that accepts the resource type name.
91+
#[serde(rename = "resourceTypArg")]
92+
resource_type_arg: String,
93+
}
8994
}
9095

9196
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
@@ -213,18 +218,22 @@ pub struct ResolveMethod {
213218
pub struct Adapter {
214219
/// The way to list adapter supported resources.
215220
pub list: ListMethod,
216-
/// Defines how the adapter supports accepting configuraiton.
217-
pub config: ConfigKind,
221+
/// Defines how the adapter supports accepting configuration.
222+
#[serde(alias = "config", rename = "inputKind")]
223+
pub input_kind: AdapterInputKind,
218224
}
219225

220226
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
221-
pub enum ConfigKind {
227+
pub enum AdapterInputKind {
222228
/// The adapter accepts full unprocessed configuration.
223229
#[serde(rename = "full")]
224230
Full,
225231
/// The adapter accepts configuration as a sequence.
226232
#[serde(rename = "sequence")]
227233
Sequence,
234+
/// The adapter accepts a single resource input.
235+
#[serde(rename = "single")]
236+
Single,
228237
}
229238

230239
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]

0 commit comments

Comments
 (0)