Skip to content

Commit 112bb64

Browse files
author
Steve Lee (POWERSHELL HE/HIM) (from Dev Box)
committed
add set and test
1 parent 85ea8a3 commit 112bb64

File tree

2 files changed

+84
-6
lines changed

2 files changed

+84
-6
lines changed

dsc_lib/src/dscresources/dscresource.rs

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Licensed under the MIT License.
33

44
use crate::{configure::{config_doc::{Configuration, ExecutionKind, Resource}, Configurator}, dscresources::resource_manifest::Kind};
5-
use crate::dscresources::invoke_result::ResourceGetResponse;
5+
use crate::dscresources::invoke_result::{ResourceGetResponse, ResourceSetResponse};
66
use dscerror::DscError;
77
use rust_i18n::t;
88
use schemars::JsonSchema;
@@ -219,10 +219,10 @@ impl Invoke for DscResource {
219219
let mut configurator = self.clone().create_config_for_adapter(adapter, filter)?;
220220
let result = configurator.invoke_get()?;
221221
let GetResult::Resource(ref resource_result) = result.results[0].result else {
222-
return Err(DscError::Operation(t!("dscresources.dscresource.invokeGetReturnedNoResult", resource = self.type_name).to_string()));
222+
return Err(DscError::Operation(t!("dscresources.dscresource.invokeReturnedWrongResult", operation = "get", resource = self.type_name).to_string()));
223223
};
224224
let properties = resource_result.actual_state
225-
.as_object().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "actual_state", r#type = "object").to_string()))?
225+
.as_object().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "actualState", r#type = "object").to_string()))?
226226
.get("result").ok_or(DscError::Operation(t!("dscresources.dscresource.propertyNotFound", property = "result").to_string()))?
227227
.as_array().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "result", r#type = "array").to_string()))?[0]
228228
.as_object().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "result", r#type = "object").to_string()))?
@@ -252,7 +252,28 @@ impl Invoke for DscResource {
252252
if let Some(adapter) = &self.require_adapter {
253253
let mut configurator = self.clone().create_config_for_adapter(adapter, desired)?;
254254
let result = configurator.invoke_set(false)?;
255-
return Ok(result.results[0].result.clone());
255+
let SetResult::Resource(ref resource_result) = result.results[0].result else {
256+
return Err(DscError::Operation(t!("dscresources.dscresource.invokeReturnedWrongResult", operation = "set", resource = self.type_name).to_string()));
257+
};
258+
let before_state = resource_result.before_state
259+
.as_object().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "beforeState", r#type = "object").to_string()))?
260+
.get("result").ok_or(DscError::Operation(t!("dscresources.dscresource.propertyNotFound", property = "result").to_string()))?
261+
.as_array().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "result", r#type = "array").to_string()))?[0]
262+
.as_object().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "result", r#type = "object").to_string()))?
263+
.get("properties").ok_or(DscError::Operation(t!("dscresources.dscresource.propertyNotFound", property = "properties").to_string()))?.clone();
264+
let after_state = resource_result.after_state
265+
.as_object().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "afterState", r#type = "object").to_string()))?
266+
.get("result").ok_or(DscError::Operation(t!("dscresources.dscresource.propertyNotFound", property = "result").to_string()))?
267+
.as_array().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "result", r#type = "array").to_string()))?[0]
268+
.as_object().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "result", r#type = "object").to_string()))?
269+
.get("properties").ok_or(DscError::Operation(t!("dscresources.dscresource.propertyNotFound", property = "properties").to_string()))?.clone();
270+
let diff = get_diff(&before_state, &after_state);
271+
let set_result = SetResult::Resource(ResourceSetResponse {
272+
before_state: before_state.clone(),
273+
after_state: after_state.clone(),
274+
changed_properties: if diff.is_empty() { None } else { Some(diff) },
275+
});
276+
return Ok(set_result);
256277
}
257278

258279
match &self.implemented_as {
@@ -274,7 +295,29 @@ impl Invoke for DscResource {
274295
if let Some(adapter) = &self.require_adapter {
275296
let mut configurator = self.clone().create_config_for_adapter(adapter, expected)?;
276297
let result = configurator.invoke_test()?;
277-
return Ok(result.results[0].result.clone());
298+
let TestResult::Resource(ref resource_result) = result.results[0].result else {
299+
return Err(DscError::Operation(t!("dscresources.dscresource.invokeReturnedWrongResult", operation = "test", resource = self.type_name).to_string()));
300+
};
301+
let desired_state = resource_result.desired_state
302+
.as_object().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "desiredState", r#type = "object").to_string()))?
303+
.get("resources").ok_or(DscError::Operation(t!("dscresources.dscresource.propertyNotFound", property = "resources").to_string()))?
304+
.as_array().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "resources", r#type = "array").to_string()))?[0]
305+
.as_object().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "resources", r#type = "object").to_string()))?
306+
.get("properties").ok_or(DscError::Operation(t!("dscresources.dscresource.propertyNotFound", property = "properties").to_string()))?.clone();
307+
let actual_state = resource_result.actual_state
308+
.as_object().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "actualState", r#type = "object").to_string()))?
309+
.get("result").ok_or(DscError::Operation(t!("dscresources.dscresource.propertyNotFound", property = "result").to_string()))?
310+
.as_array().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "result", r#type = "array").to_string()))?[0]
311+
.as_object().ok_or(DscError::Operation(t!("dscresources.dscresource.propertyIncorrectType", property = "result", r#type = "object").to_string()))?
312+
.get("properties").ok_or(DscError::Operation(t!("dscresources.dscresource.propertyNotFound", property = "properties").to_string()))?.clone();
313+
let diff_properties = get_diff(&desired_state, &actual_state);
314+
let test_result = TestResult::Resource(ResourceTestResponse {
315+
desired_state,
316+
actual_state,
317+
in_desired_state: resource_result.in_desired_state,
318+
diff_properties,
319+
});
320+
return Ok(test_result);
278321
}
279322

280323
match &self.implemented_as {

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

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Describe 'PowerShell adapter resource tests' {
4646
'@
4747
$yaml | dsc -l trace config get -f - 2> "$TestDrive/tracing.txt"
4848
$LASTEXITCODE | Should -Be 2
49-
"$TestDrive/tracing.txt" | Should -FileContentMatch 'DSC resource TestClassResourceNotExist/TestClassResourceNotExist module not found.'
49+
"$TestDrive/tracing.txt" | Should -FileContentMatch "DSC resource 'TestClassResourceNotExist/TestClassResourceNotExist' module not found."
5050
}
5151

5252
It 'Test works on config with class-based resources' {
@@ -202,4 +202,39 @@ Describe 'PowerShell adapter resource tests' {
202202
$LASTEXITCODE | Should -Be 0
203203
$out.results.result.actualState.result.properties.HashTableProp.Name | Should -BeExactly 'DSCv3'
204204
}
205+
206+
It 'Config calling PS Resource directly works for <operation>' -TestCases @(
207+
@{ Operation = 'get' }
208+
@{ Operation = 'set' }
209+
@{ Operation = 'test' }
210+
) {
211+
param($Operation)
212+
213+
$yaml = @"
214+
`$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
215+
resources:
216+
- name: Class-resource Info
217+
type: TestClassResource/TestClassResource
218+
properties:
219+
Name: 'TestClassResource1'
220+
HashTableProp:
221+
Name: 'DSCv3'
222+
"@
223+
224+
$out = dsc config $operation -i $yaml | ConvertFrom-Json
225+
$text = dsc config $operation -i $yaml | Out-String
226+
$LASTEXITCODE | Should -Be 0
227+
switch ($Operation) {
228+
'get' {
229+
$out.results[0].result.actualState.Name | Should -BeExactly 'TestClassResource1' -Because $text
230+
}
231+
'set' {
232+
$out.results[0].result.beforeState.Name | Should -BeExactly 'TestClassResource1' -Because $text
233+
$out.results[0].result.afterState | Should -BeNullOrEmpty
234+
}
235+
'test' {
236+
$out.results[0].result.actualState.InDesiredState | Should -BeFalse -Because $text
237+
}
238+
}
239+
}
205240
}

0 commit comments

Comments
 (0)