Skip to content
Merged
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
1 change: 1 addition & 0 deletions dsc/locales/en-us.toml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ invalidOperationOnAdapter = "Can not perform this operation on the adapter itsel
setInputEmpty = "Desired input is empty"
testInputEmpty = "Expected input is required"
jsonError = "JSON: %{err}"
routingToDelete = "Routing to delete operation because _exist is false"

[subcommand]
actualStateNotObject = "actual_state is not an object"
Expand Down
60 changes: 59 additions & 1 deletion dsc/src/resource_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ use crate::args::{GetOutputFormat, OutputFormat};
use crate::util::{EXIT_DSC_ERROR, EXIT_INVALID_ARGS, EXIT_JSON_ERROR, EXIT_DSC_RESOURCE_NOT_FOUND, write_object};
use dsc_lib::configure::config_doc::{Configuration, ExecutionKind};
use dsc_lib::configure::add_resource_export_results_to_configuration;
use dsc_lib::dscresources::{resource_manifest::Kind, invoke_result::{GetResult, ResourceGetResponse}};
use dsc_lib::dscresources::{resource_manifest::Kind, invoke_result::{GetResult, ResourceGetResponse, ResourceSetResponse, SetResult}};
use dsc_lib::dscresources::dscresource::{Capability, get_diff};
use dsc_lib::dscerror::DscError;
use rust_i18n::t;
use serde_json::Value;
use tracing::{error, debug};

use dsc_lib::{
Expand Down Expand Up @@ -142,6 +144,62 @@ pub fn set(dsc: &mut DscManager, resource_type: &str, version: Option<&str>, inp
exit(EXIT_DSC_ERROR);
}

let exist = match serde_json::from_str::<Value>(input) {
Ok(v) => {
if let Some(exist_value) = v.get("_exist") {
!matches!(exist_value, Value::Bool(false))
} else {
true
}
},
Err(_) => true,
};

if !exist && resource.capabilities.contains(&Capability::Delete) && !resource.capabilities.contains(&Capability::SetHandlesExist) {
debug!("{}", t!("resource_command.routingToDelete"));

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

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) => {
error!("{err}");
exit(EXIT_DSC_ERROR);
}
};

let diff = get_diff(&after_state, &before_state);

let result = SetResult::Resource(ResourceSetResponse {
before_state,
after_state,
changed_properties: Some(diff),
});

let json = match serde_json::to_string(&result) {
Ok(json) => json,
Err(err) => {
error!("{}", t!("resource_command.jsonError", err = err));
exit(EXIT_JSON_ERROR);
}
};
write_object(&json, format, false);
return;
}

match resource.set(input, true, &ExecutionKind::Actual) {
Ok(result) => {
// convert to json
Expand Down
6 changes: 6 additions & 0 deletions dsc/tests/dsc_resource_set.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,10 @@ Describe 'Invoke a resource set directly' {
$out.afterState.version | Should -BeExactly '1.1.2'
$out.changedProperties | Should -BeNullOrEmpty
}

It '_exist false routes to delete operation' {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a test case to handle what-if for this scenario?

Copy link
Contributor Author

@Gijsreyn Gijsreyn Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is --what-if not only for dsc config? I can't seem to find them on dsc resource options.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe you are correct, so nevermind.

$out = dsc -l trace resource set --resource Test/Delete --input '{"_exist": false}' 2>&1
$LASTEXITCODE | Should -Be 0
$out | Out-String | Should -Match 'Routing to delete operation because _exist is false'
}
}