Skip to content

Commit 66047e0

Browse files
authored
Merge pull request #774 from SteveL-MSFT/implicit-ps-set
Fix adapter configuration set which returns `result`, but needs to be `resources`
2 parents 7f90fbb + 33e2a2f commit 66047e0

File tree

4 files changed

+29
-10
lines changed

4 files changed

+29
-10
lines changed

dsc_lib/src/configure/mod.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -405,12 +405,18 @@ impl Configurator {
405405
let GetResult::Resource(after_result) = after_result else {
406406
return Err(DscError::NotSupported(t!("configure.mod.groupNotSupportedForDelete").to_string()))
407407
};
408-
let before_value = serde_json::to_value(&before_response.actual_state)?;
409-
let after_value = serde_json::to_value(&after_result.actual_state)?;
408+
let diff = get_diff(&before_response.actual_state, &after_result.actual_state);
409+
let mut before: Map<String, Value> = serde_json::from_value(before_response.actual_state)?;
410+
// a `get` will return a `result` property, but an actual `set` will have that as `resources`
411+
if before.contains_key("result") && !before.contains_key("resources") {
412+
before.insert("resources".to_string() ,before["result"].clone());
413+
before.remove("result");
414+
}
415+
let before_value = serde_json::to_value(&before)?;
410416
SetResult::Resource(ResourceSetResponse {
411-
before_state: before_response.actual_state,
417+
before_state: before_value.clone(),
412418
after_state: after_result.actual_state,
413-
changed_properties: Some(get_diff(&before_value, &after_value)),
419+
changed_properties: Some(diff),
414420
})
415421
},
416422
GetResult::Group(_) => {

dsc_lib/src/dscresources/command_resource.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use clap::ValueEnum;
55
use jsonschema::Validator;
66
use rust_i18n::t;
77
use serde::Deserialize;
8-
use serde_json::Value;
8+
use serde_json::{Map, Value};
99
use std::{collections::HashMap, env, process::Stdio};
1010
use crate::configure::{config_doc::ExecutionKind, config_result::{ResourceGetResult, ResourceTestResult}};
1111
use crate::dscerror::DscError;
@@ -146,12 +146,24 @@ pub fn invoke_set(resource: &ResourceManifest, cwd: &str, desired: &str, skip_te
146146
verify_json(resource, cwd, &stdout)?;
147147
}
148148

149-
let pre_state: Value = if exit_code == 0 {
149+
let pre_state_value: Value = if exit_code == 0 {
150150
serde_json::from_str(&stdout)?
151151
}
152152
else {
153153
return Err(DscError::Command(resource.resource_type.clone(), exit_code, stderr));
154154
};
155+
let pre_state = if pre_state_value.is_object() {
156+
let mut pre_state_map: Map<String, Value> = serde_json::from_value(pre_state_value)?;
157+
158+
// if the resource is an adapter, then the `get` will return a `result`, but a full `set` expects the before state to be `resources`
159+
if resource.kind == Some(Kind::Adapter) && pre_state_map.contains_key("result") && !pre_state_map.contains_key("resources") {
160+
pre_state_map.insert("resources".to_string(), pre_state_map["result"].clone());
161+
pre_state_map.remove("result");
162+
}
163+
serde_json::to_value(pre_state_map)?
164+
} else {
165+
pre_state_value
166+
};
155167

156168
let mut env: Option<HashMap<String, String>> = None;
157169
let mut input_desired: Option<&str> = None;

dsc_lib/src/dscresources/dscresource.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ impl Invoke for DscResource {
259259
};
260260
let before_state = resource_result.before_state
261261
.as_object().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "beforeState", property_type = "object").to_string()))?
262-
.get("result").ok_or(DscError::Operation(t!("dscresources.dscresource.propertyNotFound", property = "result").to_string()))?
262+
.get("resources").ok_or(DscError::Operation(t!("dscresources.dscresource.propertyNotFound", property = "resources").to_string()))?
263263
.as_array().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "result", property_type = "array").to_string()))?[0]
264264
.as_object().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "result", property_type = "object").to_string()))?
265265
.get("properties").ok_or(DscError::Operation(t!("dscresources.dscresource.propertyNotFound", property = "properties").to_string()))?.clone();

powershell-adapter/Tests/powershellgroup.config.tests.ps1

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,10 @@ Describe 'PowerShell adapter resource tests' {
221221
Name: 'DSCv3'
222222
"@
223223

224-
$out = dsc config $operation -i $yaml | ConvertFrom-Json
225-
$text = dsc config $operation -i $yaml | Out-String
226-
$LASTEXITCODE | Should -Be 0
224+
$out = dsc -l trace config $operation -i $yaml 2> $TestDrive/tracing.txt
225+
$text = $out | Out-String
226+
$out = $out | ConvertFrom-Json
227+
$LASTEXITCODE | Should -Be 0 -Because (Get-Content -Raw -Path $TestDrive/tracing.txt)
227228
switch ($Operation) {
228229
'get' {
229230
$out.results[0].result.actualState.Name | Should -BeExactly 'TestClassResource1' -Because $text

0 commit comments

Comments
 (0)