PowerShell / PowerShell/DSC

Improve readability for nested resource instances in `dsc config` command output

Open
#728 2 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Breaking Change Issue-Enhancement
Dominant language
Rust
Stars
523
Forks
75
Avg merge
3d 16h
Merged PRs (30d)
24

Description

Summary of the new feature / enhancement

As a user, I want to be able to review the output of the dsc config commands 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:

  1. A flat configuration document containing adjacent, non-nested resource instances.
  2. 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:

  1. The desiredState is the desired state for the entire group
  2. The actualState contains the expected results for the nested instances.
  3. The inDesiredState value is false, 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.
  4. The differingProperties value 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:

  1. The beforeState seems to be an array containing get results for every nested instance/
  2. The afterState contains the expected set results for every nested instance.
  3. The changedProperties field 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:

  1. Not include the differingProperties field.
  2. That we define an instanceResults or results field as an array containing the resource test result for every nested instance. I think instanceResults could help to semantically disambiguate the array, but I'm not attached to any particular name for this field.
  3. That the inDesiredState field be true if the inDesiredState field for every nested instance is true and otherwise false.
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:

  1. Not include the changedProperties field.
  2. That we define an instanceResults or results field as an array containing the resource set result for every nested instance. I think instanceResults could 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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the dsc config get, dsc config test, and dsc config set command paths and compare their current nested-resource result shapes with the proposed instanceResults behavior. Done means nested test and set results are readable, aggregate inDesiredState correctly, and omit incoherent group-level difference fields.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.