Improve readability for nested resource instances in `dsc config` command output
Summary of the new feature / enhancement
As a user, I want to be able to review the output of the
dsc configcommands for configurations with nested instances and quickly understand the results without needing to compare multiple arrays for the same nested instance.
Current Context
This is a re-raising of #266, which was partially addressed.
Currently, when you use DSC to manage a configuration document containing nested resource instances, you get output that can be very difficult to parse, especially if you're not familiar with the data structure already.
The following details show the differences in output for:
- A flat configuration document containing adjacent, non-nested resource instances.
- A configuration document containing the same instances nested within a group resource instance.
Flat resources instances
In this example, the resources are defined adjacently, without being nested inside a group resource instance.
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- type: Microsoft.DSC.Debug/Echo
name: Foo
properties:
output: Example Foo
- type: Microsoft.DSC.Debug/Echo
name: Bar
properties:
output: Example Bar
When you use dsc config get to retrieve the current state, you can clearly
see the result for every defined instance.
dsc config get result
metadata: # elided for brevity
results:
- metadata: # elided for brevity
name: Foo
type: Microsoft.DSC.Debug/Echo
result:
actualState:
output: Example Foo
- metadata: # elided for brevity
name: Bar
type: Microsoft.DSC.Debug/Echo
result:
actualState:
output: Example Bar
messages: []
hadErrors: false
When you use dsc config test to verify the desired state, you can compare the desired state, actual state, boolean result, and list of differing properties for every defined instance.
dsc config test result
metadata: # elided for brevity
results:
- metadata: # elided for brevity
name: Foo
type: Microsoft.DSC.Debug/Echo
result:
desiredState:
output: Example Foo
actualState:
output: Example Foo
inDesiredState: true
differingProperties: []
- metadata: # elided for brevity
name: Bar
type: Microsoft.DSC.Debug/Echo
result:
desiredState:
output: Example Bar
actualState:
output: Example Bar
inDesiredState: true
differingProperties: []
messages: []
hadErrors: false
When you use dsc config set to enforce the desired state, you can compare the state before the operation, the state after the operation, and the list of changed properties for every defined instance.
dsc config set result
metadata: # elided for brevity
results:
- metadata: # elided for brevity
name: Foo
type: Microsoft.DSC.Debug/Echo
result:
beforeState:
output: Example Foo
afterState:
output: Example Foo
changedProperties: null
- metadata: # elided for brevity
name: Bar
type: Microsoft.DSC.Debug/Echo
result:
beforeState:
output: Example Bar
afterState:
output: Example Bar
changedProperties: null
messages: []
hadErrors: false`
Nested resource instances
In this example, the resources are defined adjacently as nested instances of a top-level group resource.
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- type: Microsoft.DSC/Group
name: Grouped Echo
properties:
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- type: Microsoft.DSC.Debug/Echo
name: Foo
properties:
output: Example Foo
- type: Microsoft.DSC.Debug/Echo
name: Bar
properties:
output: Example Bar
When you use dsc config get to retrieve the current state, you can clearly
see the result for every defined instance. Here, the result array for the
group resource is an array of single-instance get results - it looks mostly
like the output for the top-level instances, just nested within the group.
dsc config get result
metadata: # elided for brevity
results:
- metadata:
Microsoft.DSC:
duration: PT3.3259367S
name: Grouped Echo
type: Microsoft.DSC/Group
result:
- metadata: # elided for brevity
name: Foo
type: Microsoft.DSC.Debug/Echo
result:
actualState:
output: Example Foo
- metadata: # elided for brevity
name: Bar
type: Microsoft.DSC.Debug/Echo
result:
actualState:
output: Example Bar
messages: []
hadErrors: false
When you use dsc config test to verify the desired state, it's difficult to understand the results. The group resource result has the desiredState, actualState, inDesiredState, and differingProperties fields, but:
- The
desiredStateis the desired state for the entire group - The
actualStatecontains the expected results for the nested instances. - The
inDesiredStatevalue isfalse, which is inaccurate - the results show that the nested instances are both in the desired state. This appears to be caused by comparing the group resource's desired state to the test results for the nested instances. - The
differingPropertiesvalue isn't coherent - we don't expect differing properties for a group or adapter, which definitionally doesn't have it's own desired state, separate from the nested instances.
dsc config test result
metadata: # elided for brevity
results:
- metadata: # elided for brevity
name: Grouped Echo
type: Microsoft.DSC/Group
result:
desiredState:
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- type: Microsoft.DSC.Debug/Echo
name: Foo
properties:
output: Example Foo
- type: Microsoft.DSC.Debug/Echo
name: Bar
properties:
output: Example Bar
actualState:
- metadata: # elided for brevity
name: Foo
type: Microsoft.DSC.Debug/Echo
result:
desiredState:
output: Example Foo
actualState:
output: Example Foo
inDesiredState: true
differingProperties: []
- metadata: # elided for brevity
name: Bar
type: Microsoft.DSC.Debug/Echo
result:
desiredState:
output: Example Bar
actualState:
output: Example Bar
inDesiredState: true
differingProperties: []
inDesiredState: false
differingProperties:
- resources
- _exist
messages: []
hadErrors: false
When you use dsc config set to enforce the desired state, it's difficult to understand the results. The group resource result has the beforeState, afterState, and changedProperties fields, but:
- The
beforeStateseems to be an array containing get results for every nested instance/ - The
afterStatecontains the expected set results for every nested instance. - The
changedPropertiesfield is incoherent, again because group and adapter resources don't have a desired state separate from the nested instances. In this case, the field is at least an empty array, but probably shouldn't be included at all.
dsc config set result
metadata: # elided for brevity
results:
- metadata: # elided for brevity
name: Grouped Echo
type: Microsoft.DSC/Group
result:
beforeState:
- metadata: # elided for brevity
name: Foo
type: Microsoft.DSC.Debug/Echo
result:
actualState:
output: Example Foo
- metadata: # elided for brevity
name: Bar
type: Microsoft.DSC.Debug/Echo
result:
actualState:
output: Example Bar
afterState:
- metadata: # elided for brevity
name: Foo
type: Microsoft.DSC.Debug/Echo
result:
beforeState:
output: Example Foo
afterState:
output: Example Foo
changedProperties: null
- metadata: # elided for brevity
name: Bar
type: Microsoft.DSC.Debug/Echo
result:
beforeState:
output: Example Bar
afterState:
output: Example Bar
changedProperties: null
changedProperties: []
messages: []
hadErrors: false
Proposed technical implementation details (optional)
I propose changing the results to the following for test and set for any resource instance containing nested instances:
Test Results
For resources with nested instances, I propose that the test result:
- Not include the
differingPropertiesfield. - That we define an
instanceResultsorresultsfield as an array containing the resource test result for every nested instance. I thinkinstanceResultscould help to semantically disambiguate the array, but I'm not attached to any particular name for this field. - That the
inDesiredStatefield betrueif theinDesiredStatefield for every nested instance istrueand otherwisefalse.
Group instance test result
metadata: # elided for brevity
name: Grouped Echo
type: Microsoft.DSC/Group
result:
inDesiredState: true
# Using a different property name to clearly signal the semantics of the
# array, but it could be `results` if needed.
instanceResults:
- metadata: # elided for brevity
name: Foo
type: Microsoft.DSC.Debug/Echo
result:
desiredState:
output: Example Foo
actualState:
output: Example Foo
inDesiredState: true
differingProperties: []
- metadata: # elided for brevity
name: Bar
type: Microsoft.DSC.Debug/Echo
result:
desiredState:
output: Example Bar
actualState:
output: Example Bar
inDesiredState: true
differingProperties: []
Full configuration result
metadata: # elided for brevity
results:
- metadata: # elided for brevity
name: Grouped Echo
type: Microsoft.DSC/Group
result:
inDesiredState: true
# Using a different property name to clearly signal the semantics of the
# array, but it could be `results` if needed.
instanceResults:
- metadata: # elided for brevity
name: Foo
type: Microsoft.DSC.Debug/Echo
result:
desiredState:
output: Example Foo
actualState:
output: Example Foo
inDesiredState: true
differingProperties: []
- metadata: # elided for brevity
name: Bar
type: Microsoft.DSC.Debug/Echo
result:
desiredState:
output: Example Bar
actualState:
output: Example Bar
inDesiredState: true
differingProperties: []
messages: []
hadErrors: false
Set Results
For resources with nested instances, I propose that the set result:
- Not include the
changedPropertiesfield. - That we define an
instanceResultsorresultsfield as an array containing the resource set result for every nested instance. I thinkinstanceResultscould help to semantically disambiguate the array, but I'm not attached to any particular name for this field.
I can also see an argument for having the result for the group be replaced by results, but that would cause it to deviate from typical resource instances. I think having it nested one layer as an array is okay in this instance.
We could also consider whether it would be useful to define a changedResources field, which returns the resource IDs for any nested resource instance that had a result with the changedProperties field containing one or more property name.
Group instance set result
metadata: # elided for brevity
name: Grouped Echo
type: Microsoft.DSC/Group
result:
# Using a different property name to clearly signal the semantics of the
# array, but it could be `results` if needed.
instanceResults:
- metadata: # elided for brevity
name: Foo
type: Microsoft.DSC.Debug/Echo
result:
beforeState:
output: Example Foo
afterState:
output: Example Foo
changedProperties: null
- metadata: # elided for brevity
name: Bar
type: Microsoft.DSC.Debug/Echo
result:
beforeState:
output: Example Bar
afterState:
output: Example Bar
changedProperties: null
Full configuration result
metadata: # elided for brevity
results:
- metadata: # elided for brevity
name: Grouped Echo
type: Microsoft.DSC/Group
result:
# Using a different property name to clearly signal the semantics of the
# array, but it could be `results` if needed.
instanceResults:
- metadata: # elided for brevity
name: Foo
type: Microsoft.DSC.Debug/Echo
result:
beforeState:
output: Example Foo
afterState:
output: Example Foo
changedProperties: null
- metadata: # elided for brevity
name: Bar
type: Microsoft.DSC.Debug/Echo
result:
beforeState:
output: Example Bar
afterState:
output: Example Bar
changedProperties: null
messages: []
hadErrors: false