Skip to content

Commit 1539757

Browse files
committed
add what-if argkind
1 parent 0cd3fd7 commit 1539757

File tree

10 files changed

+51
-39
lines changed

10 files changed

+51
-39
lines changed

dsc/src/subcommand.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ pub fn config(subcommand: &ConfigSubCommand, parameters: &Option<String>, stdin:
250250

251251
if let ConfigSubCommand::Set { what_if , .. } = subcommand {
252252
if *what_if {
253-
configurator.context.execution_type = ExecutionKind::WhatIf;
253+
configurator.context.execution_type = ExecutionKind::WhatIfDSC;
254254
}
255255
};
256256

@@ -511,11 +511,12 @@ fn list_resources(dsc: &mut DscManager, resource_name: &Option<String>, adapter_
511511
write_table = true;
512512
}
513513
for resource in dsc.list_available_resources(&resource_name.clone().unwrap_or("*".to_string()), &adapter_name.clone().unwrap_or_default()) {
514-
let mut capabilities = "-------".to_string();
514+
let mut capabilities = "--------".to_string();
515515
let capability_types = [
516516
(Capability::Get, "g"),
517517
(Capability::Set, "s"),
518518
(Capability::SetHandlesExist, "x"),
519+
(Capability::SetHandlesWhatIf, "w"),
519520
(Capability::Test, "t"),
520521
(Capability::Delete, "d"),
521522
(Capability::Export, "e"),

dsc_lib/src/configure/config_doc.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ pub enum Operation {
3030
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
3131
pub enum ExecutionKind {
3232
Actual,
33-
WhatIf,
33+
#[serde(rename = "WhatIf")]
34+
WhatIfDSC,
35+
#[serde(rename = "WhatIf")]
36+
WhatIfResource,
3437
}
3538

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

dsc_lib/src/configure/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ impl Configurator {
318318
set_result = dsc_resource.set(&desired, skip_test, &self.context.execution_type)?;
319319
end_datetime = chrono::Local::now();
320320
} else if dsc_resource.capabilities.contains(&Capability::Delete) {
321-
if self.context.execution_type == ExecutionKind::WhatIf {
321+
if self.context.execution_type == ExecutionKind::WhatIfDSC {
322322
// TODO: add delete what-if support
323323
return Err(DscError::NotSupported("What-if execution not supported for delete".to_string()));
324324
}

dsc_lib/src/discovery/command_discovery.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use crate::discovery::discovery_trait::ResourceDiscovery;
55
use crate::discovery::convert_wildcard_to_regex;
66
use crate::dscresources::dscresource::{Capability, DscResource, ImplementedAs};
7-
use crate::dscresources::resource_manifest::{import_manifest, validate_semver, Kind, ResourceManifest};
7+
use crate::dscresources::resource_manifest::{import_manifest, validate_semver, ArgKind, Kind, ResourceManifest};
88
use crate::dscresources::command_resource::invoke_command;
99
use crate::dscerror::DscError;
1010
use indicatif::ProgressStyle;
@@ -449,6 +449,14 @@ fn load_manifest(path: &Path) -> Result<DscResource, DscError> {
449449
if set.handles_exist == Some(true) {
450450
capabilities.push(Capability::SetHandlesExist);
451451
}
452+
if let Some(arg_values) = &set.args {
453+
for arg in arg_values {
454+
if let &ArgKind::WhatIf { .. } = arg {
455+
capabilities.push(Capability::SetHandlesWhatIf);
456+
break;
457+
}
458+
}
459+
}
452460
}
453461
if manifest.test.is_some() {
454462
capabilities.push(Capability::Test);

dsc_lib/src/dscresources/command_resource.rs

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ pub fn invoke_get(resource: &ResourceManifest, cwd: &str, filter: &str) -> Resul
5050
let Some(get) = &resource.get else {
5151
return Err(DscError::NotImplemented("get".to_string()));
5252
};
53-
let args = process_args(&get.args, filter);
53+
let args = process_args(&get.args, filter, &ExecutionKind::Actual);
5454
if !filter.is_empty() {
5555
verify_json(resource, cwd, filter)?;
5656
command_input = get_command_input(&get.input, filter)?;
@@ -105,7 +105,7 @@ pub fn invoke_set(resource: &ResourceManifest, cwd: &str, desired: &str, skip_te
105105
if !skip_test && set.pre_test != Some(true) {
106106
info!("No pretest, invoking test {}", &resource.resource_type);
107107
let test_result = invoke_test(resource, cwd, desired)?;
108-
if execution_type == &ExecutionKind::WhatIf && set.handles_what_if != Some(true) {
108+
if execution_type == &ExecutionKind::WhatIfDSC {
109109
return Ok(test_result.into());
110110
}
111111
let (in_desired_state, actual_state) = match test_result {
@@ -130,14 +130,14 @@ pub fn invoke_set(resource: &ResourceManifest, cwd: &str, desired: &str, skip_te
130130
}
131131
}
132132

133-
if ExecutionKind::WhatIf == *execution_type && set.handles_what_if != Some(true) {
133+
if ExecutionKind::WhatIfDSC == *execution_type {
134134
return Err(DscError::NotImplemented("cannot process what-if execution type, resource does not implement what-if or pre-test".to_string()));
135135
}
136136

137137
let Some(get) = &resource.get else {
138138
return Err(DscError::NotImplemented("get".to_string()));
139139
};
140-
let args = process_args(&get.args, desired);
140+
let args = process_args(&get.args, desired, &ExecutionKind::Actual);
141141
let command_input = get_command_input(&get.input, desired)?;
142142

143143
info!("Getting current state for set by invoking get {} using {}", &resource.resource_type, &get.executable);
@@ -157,16 +157,7 @@ pub fn invoke_set(resource: &ResourceManifest, cwd: &str, desired: &str, skip_te
157157

158158
let mut env: Option<HashMap<String, String>> = None;
159159
let mut input_desired: Option<&str> = None;
160-
let mut args = process_args(&set.args, desired);
161-
if ExecutionKind::WhatIf == *execution_type {
162-
if let Some(mut arguments) = args {
163-
arguments.push("--what-if".to_string());
164-
args = Some(arguments);
165-
}
166-
else {
167-
args = Some(vec!["--what-if".to_string()]);
168-
}
169-
}
160+
let args = process_args(&set.args, desired, execution_type);
170161
match &set.input {
171162
Some(InputKind::Env) => {
172163
env = Some(json_to_hashmap(desired)?);
@@ -269,7 +260,7 @@ pub fn invoke_test(resource: &ResourceManifest, cwd: &str, expected: &str) -> Re
269260

270261
verify_json(resource, cwd, expected)?;
271262

272-
let args = process_args(&test.args, expected);
263+
let args = process_args(&test.args, expected, &ExecutionKind::Actual);
273264
let command_input = get_command_input(&test.input, expected)?;
274265

275266
info!("Invoking test '{}' using '{}'", &resource.resource_type, &test.executable);
@@ -383,7 +374,7 @@ pub fn invoke_delete(resource: &ResourceManifest, cwd: &str, filter: &str) -> Re
383374

384375
verify_json(resource, cwd, filter)?;
385376

386-
let args = process_args(&delete.args, filter);
377+
let args = process_args(&delete.args, filter, &ExecutionKind::Actual);
387378
let command_input = get_command_input(&delete.input, filter)?;
388379

389380
info!("Invoking delete '{}' using '{}'", &resource.resource_type, &delete.executable);
@@ -414,7 +405,7 @@ pub fn invoke_validate(resource: &ResourceManifest, cwd: &str, config: &str) ->
414405
return Err(DscError::NotImplemented("validate".to_string()));
415406
};
416407

417-
let args = process_args(&validate.args, config);
408+
let args = process_args(&validate.args, config, &ExecutionKind::Actual);
418409
let command_input = get_command_input(&validate.input, config)?;
419410

420411
info!("Invoking validate '{}' using '{}'", &resource.resource_type, &validate.executable);
@@ -489,9 +480,9 @@ pub fn invoke_export(resource: &ResourceManifest, cwd: &str, input: Option<&str>
489480
command_input = get_command_input(&export.input, input)?;
490481
}
491482

492-
args = process_args(&export.args, input);
483+
args = process_args(&export.args, input, &ExecutionKind::Actual);
493484
} else {
494-
args = process_args(&export.args, "");
485+
args = process_args(&export.args, "", &ExecutionKind::Actual);
495486
}
496487

497488
let (_exit_code, stdout, stderr) = invoke_command(&export.executable, args, command_input.stdin.as_deref(), Some(cwd), command_input.env)?;
@@ -536,7 +527,7 @@ pub fn invoke_resolve(resource: &ResourceManifest, cwd: &str, input: &str) -> Re
536527
return Err(DscError::Operation(format!("Resolve is not supported by resource {}", &resource.resource_type)));
537528
};
538529

539-
let args = process_args(&resolve.args, input);
530+
let args = process_args(&resolve.args, input, &ExecutionKind::Actual);
540531
let command_input = get_command_input(&resolve.input, input)?;
541532

542533
info!("Invoking resolve '{}' using '{}'", &resource.resource_type, &resolve.executable);
@@ -628,7 +619,7 @@ pub fn invoke_command(executable: &str, args: Option<Vec<String>>, input: Option
628619
Ok((exit_code, stdout, cleaned_stderr))
629620
}
630621

631-
fn process_args(args: &Option<Vec<ArgKind>>, value: &str) -> Option<Vec<String>> {
622+
fn process_args(args: &Option<Vec<ArgKind>>, value: &str, execution_type: &ExecutionKind) -> Option<Vec<String>> {
632623
let Some(arg_values) = args else {
633624
debug!("No args to process");
634625
return None;
@@ -648,6 +639,11 @@ fn process_args(args: &Option<Vec<ArgKind>>, value: &str) -> Option<Vec<String>>
648639
processed_args.push(json_input_arg.clone());
649640
processed_args.push(value.to_string());
650641
},
642+
ArgKind::WhatIf { what_if_input_arg} => {
643+
if execution_type == &ExecutionKind::WhatIfResource {
644+
processed_args.push(what_if_input_arg.clone());
645+
}
646+
}
651647
}
652648
}
653649

dsc_lib/src/dscresources/dscresource.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,13 @@ impl Invoke for DscResource {
211211
return Err(DscError::MissingManifest(self.type_name.clone()));
212212
};
213213
let resource_manifest = import_manifest(manifest.clone())?;
214-
command_resource::invoke_set(&resource_manifest, &self.directory, desired, skip_test, execution_type)
214+
let execution = if self.capabilities.contains(&Capability::SetHandlesWhatIf) && execution_type == &ExecutionKind::WhatIfDSC {
215+
ExecutionKind::WhatIfResource
216+
}
217+
else {
218+
execution_type.clone()
219+
};
220+
command_resource::invoke_set(&resource_manifest, &self.directory, desired, skip_test, &execution)
215221
},
216222
}
217223
}

dsc_lib/src/dscresources/resource_manifest.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ pub enum ArgKind {
103103
/// Indicates if argument is mandatory which will pass an empty string if no JSON input is provided. Default is false.
104104
mandatory: Option<bool>,
105105
},
106+
WhatIf {
107+
/// The argument that serves as the what-if switch.
108+
#[serde(rename = "whatIfInputArg")]
109+
what_if_input_arg: String,
110+
}
106111
}
107112

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

tools/dsctest/dscwhatif.dsc.resource.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
"set": {
1212
"executable": "dsctest",
1313
"args": [
14-
"what-if"
14+
"what-if",
15+
{
16+
"whatIfInputArg": "--what-if"
17+
}
1518
],
16-
"handlesWhatIf": true,
1719
"implementsPretest": true,
1820
"return": "state"
1921
},

tools/dsctest/src/args.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ pub enum SubCommand {
5858

5959
#[clap(name = "what-if", about = "Check if it is a what-if operation")]
6060
WhatIf {
61-
#[clap(name = "what-if", short, long, help = "The input to the what-if command as JSON")]
61+
#[clap(name = "what-if", short, long, help = "Run as a what-if executionType instead of actual executionType")]
6262
what_if: bool,
6363
}
6464
}

tools/dsctest/src/whatif.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,6 @@
44
use schemars::JsonSchema;
55
use serde::{Deserialize, Serialize};
66

7-
// #[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
8-
// #[serde(untagged)]
9-
// pub enum ExecutionKind {
10-
// #[serde(rename = "actual")]
11-
// Actual,
12-
// #[serde(rename = "whatIf")]
13-
// WhatIf,
14-
// }
15-
167
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
178
#[serde(deny_unknown_fields)]
189
pub struct WhatIf {

0 commit comments

Comments
 (0)