Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 30 additions & 4 deletions docs/reference/cli/resource/set.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,25 @@ Enforces the desired state for a resource instance.
### Instance properties from input option

```sh
dsc resource set --input <INPUT> --resource <RESOURCE>
dsc resource set --input <INPUT> --resource <RESOURCE> [--what-if]
```

### Instance properties from file

```sh
dsc resource set --file <FILE> --resource <RESOURCE>
dsc resource set --file <FILE> --resource <RESOURCE> [--what-if]
```

### Instance properties from stdin

```sh
cat <FILE> | dsc resource set [Options] --resource <RESOURCE> --file -
cat <FILE> | dsc resource set [Options] --resource <RESOURCE> --file - [--what-if]
```

### What-if mode

```sh
dsc resource set --input <INPUT> --resource <RESOURCE> --what-if
```

## Description
Expand Down Expand Up @@ -215,6 +221,27 @@ LongSyntax : --output-format <OUTPUT_FORMAT>
ShortSyntax : -o <OUTPUT_FORMAT>
```

### -w, --what-if

<a id="-w"></a>
<a id="--what-if"></a>

When you specify this flag option, DSC doesn't actually change the system state with the `set`
operation. Instead, it returns output indicating _how_ the operation will change system state when
called without this option. Use this option to preview the changes DSC will make to a system.

This option is useful for interactive and exploratory operations, allowing you to see what changes
would be made before actually applying them.

This option also supports the `--dry-run` and `--noop` aliases for compatibility with other tools.

```yaml
Type : boolean
Mandatory : false
LongSyntax : --what-if
ShortSyntax : -w
```

### -h, --help

<a id="-h"></a>
Expand All @@ -240,7 +267,6 @@ For more information about the formatting of the output data, see the
[--output-format option](#--output-format).

<!-- Link reference definitions -->
[zz]: https://jsonlines.org/
[01]: ../config/set.md
[02]: ../config/set.md
[03]: ../../schemas/resource/manifest/set.md#implementspretest
Expand Down
2 changes: 2 additions & 0 deletions dsc/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ pub enum ResourceSubCommand {
file: Option<String>,
#[clap(short = 'o', long, help = t!("args.outputFormat").to_string())]
output_format: Option<OutputFormat>,
#[clap(short = 'w', long, visible_aliases = ["dry-run", "noop"], help = t!("args.whatIf").to_string())]
what_if: bool,
},
#[clap(name = "test", about = "Invoke the test operation to a resource", arg_required_else_help = true)]
Test {
Expand Down
32 changes: 21 additions & 11 deletions dsc/src/resource_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ pub fn get_all(dsc: &mut DscManager, resource_type: &str, version: Option<&str>,
}
}

pub fn set(dsc: &mut DscManager, resource_type: &str, version: Option<&str>, input: &str, format: Option<&OutputFormat>) {
pub fn set(dsc: &mut DscManager, resource_type: &str, version: Option<&str>, input: &str, format: Option<&OutputFormat>, what_if: bool) {
if input.is_empty() {
error!("{}", t!("resource_command.setInputEmpty"));
exit(EXIT_INVALID_ARGS);
Expand All @@ -144,6 +144,8 @@ pub fn set(dsc: &mut DscManager, resource_type: &str, version: Option<&str>, inp
exit(EXIT_DSC_ERROR);
}

let execution_kind = if what_if { ExecutionKind::WhatIf } else { ExecutionKind::Actual };

let exist = match serde_json::from_str::<Value>(input) {
Ok(v) => {
if let Some(exist_value) = v.get("_exist") {
Expand All @@ -167,18 +169,26 @@ pub fn set(dsc: &mut DscManager, resource_type: &str, version: Option<&str>, inp
}
};

if let Err(err) = resource.delete(input) {
error!("{err}");
exit(EXIT_DSC_ERROR);
}

let after_state = match resource.get(input) {
Ok(GetResult::Resource(response)) => response.actual_state,
Ok(_) => unreachable!(),
Err(err) => {
let after_state = if what_if {
let mut simulated_state = before_state.clone();
if let Value::Object(ref mut map) = simulated_state {
map.insert("_exist".to_string(), Value::Bool(false));
}
simulated_state
} else {
if let Err(err) = resource.delete(input) {
error!("{err}");
exit(EXIT_DSC_ERROR);
}

match resource.get(input) {
Ok(GetResult::Resource(response)) => response.actual_state,
Ok(_) => unreachable!(),
Err(err) => {
error!("{err}");
exit(EXIT_DSC_ERROR);
}
}
};

let diff = get_diff(&before_state, &after_state);
Expand All @@ -200,7 +210,7 @@ pub fn set(dsc: &mut DscManager, resource_type: &str, version: Option<&str>, inp
return;
}

match resource.set(input, true, &ExecutionKind::Actual) {
match resource.set(input, true, &execution_kind) {
Ok(result) => {
// convert to json
let json = match serde_json::to_string(&result) {
Expand Down
4 changes: 2 additions & 2 deletions dsc/src/subcommand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,10 +571,10 @@ pub fn resource(subcommand: &ResourceSubCommand, progress_format: ProgressFormat
resource_command::get(&mut dsc, resource, version.as_deref(), &parsed_input, output_format.as_ref());
}
},
ResourceSubCommand::Set { resource, version, input, file: path, output_format } => {
ResourceSubCommand::Set { resource, version, input, file: path, output_format, what_if } => {
dsc.find_resources(&[DiscoveryFilter::new(resource, version.clone())], progress_format);
let parsed_input = get_input(input.as_ref(), path.as_ref());
resource_command::set(&mut dsc, resource, version.as_deref(), &parsed_input, output_format.as_ref());
resource_command::set(&mut dsc, resource, version.as_deref(), &parsed_input, output_format.as_ref(), *what_if);
},
ResourceSubCommand::Test { resource, version, input, file: path, output_format } => {
dsc.find_resources(&[DiscoveryFilter::new(resource, version.clone())], progress_format);
Expand Down
20 changes: 20 additions & 0 deletions dsc/tests/dsc_resource_set.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,24 @@ Describe 'Invoke a resource set directly' {
$LASTEXITCODE | Should -Be 0
$out | Out-String | Should -Match 'Routing to delete operation because _exist is false'
}

It 'what-if execution of WhatIf resource via <alias>' -TestCases @(
@{ alias = '-w' }
@{ alias = '--what-if' }
@{ alias = '--dry-run' }
@{ alias = '--noop' }
) {
param($alias)
$result = dsc resource set $alias -r Test/WhatIf --input '{"executionType":"Actual"}' | ConvertFrom-Json
$LASTEXITCODE | Should -Be 0
$result.afterState.executionType | Should -BeExactly 'WhatIf'
$result.changedProperties | Should -BeExactly 'executionType'
}

It 'actual execution of WhatIf resource' {
$result = dsc resource set -r Test/WhatIf --input '{"executionType":"Actual"}' | ConvertFrom-Json
$LASTEXITCODE | Should -Be 0
$result.afterState.executionType | Should -BeExactly 'Actual'
$result.changedProperties | Should -Be $null
}
}