DSC icon indicating copy to clipboard operation
DSC copied to clipboard

Meta Issue: Documenting DSC Resources

Open michaeltlombardi opened this issue 2 years ago • 0 comments

Summary of the new feature / enhancement

As a DSC user, I want to be able to find and read reference documentation for DSC Resources so I can understand how to use them. Ideally, I would be able to read the documentation in the console and online.

As a DSC resource author, I want to be able to provide my users with reference documentation to help them be more effective and reduce the number of issues I have to address. Ideally, I would be able to author my reference documentation once and include it in my own documentation site as well as the dsc command.

As an integrating developer, I want to be able to reuse the reference documentation for a resource so that my users can understand them without having to leave the context of my tooling to do so.

Currently:

  • I can run dsc --format yaml resource list --resource Microsoft.Windows/Registry to get back the representation of the resource. This includes a lot of information about the implementation, but I need to understand what I'm looking at to parse it usefully. If the manifest embeds the schema, I can review it in this output. The default table view only gives me a short description, which isn't enough to fully use the resource.

    dsc resource list output
    type: Microsoft.Windows/Registry
    version: 0.1.0
    path: C:\code\pwsh\DSCv3\bin\debug\registry.dsc.resource.json
    description: Registry configuration provider for the Windows Registry
    directory: C:\code\pwsh\DSCv3\bin\debug
    implementedAs: null
    author: null
    properties: []
    requires: null
    manifest:
      $schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/bundled/resource/manifest.json
      type: Microsoft.Windows/Registry
      version: 0.1.0
      description: Registry configuration provider for the Windows Registry
      tags:
      - Windows
      - NT
      get:
        executable: registry
        args:
        - config
        - get
        input: stdin
      set:
        executable: registry
        args:
        - config
        - set
        input: stdin
        implementsPretest: true
        return: state
      test:
        executable: registry
        args:
        - config
        - test
        input: stdin
        return: state
      exitCodes:
        '2': Invalid input
        '0': Success
        '3': Registry error
        '4': JSON serialization failed
        '1': Invalid parameter
      schema:
        command:
          executable: registry
          args:
          - schema
    
  • I can run dsc resource schema --resource Microsoft.Windows/Registry to get back the resource schema, which describes the shape of the resource but requires me to understand how to interpret JSON schemas.

    dsc resource schema output
    $schema: http://json-schema.org/draft-07/schema#
    title: Registry
    type: object
    required:
    - keyPath
    properties:
      $id:
        description: The ID of the resource.  Value is ignored for input.
        type:
        - string
        - 'null'
      _clobber:
        description: Flag indicating whether the registry value should be overwritten if it already exists.
        type:
        - boolean
        - 'null'
      _exist:
        description: Flag indicating whether the registry value should be present or absent.
        type:
        - boolean
        - 'null'
      _inDesiredState:
        description: Flag indicating whether the resource is in the desired state.  Value is ignored for input.
        type:
        - boolean
        - 'null'
      keyPath:
        description: The path to the registry key.
        type: string
      valueData:
        description: The data of the registry value.
        anyOf:
        - $ref: '#/definitions/RegistryValueData'
        - type: 'null'
      valueName:
        description: The name of the registry value.
        type:
        - string
        - 'null'
    additionalProperties: false
    definitions:
      RegistryValueData:
        oneOf:
        - type: object
          required:
          - String
          properties:
            String:
              type: string
          additionalProperties: false
        - type: object
          required:
          - ExpandString
          properties:
            ExpandString:
              type: string
          additionalProperties: false
        - type: object
          required:
          - Binary
          properties:
            Binary:
              type: array
              items:
                type: integer
                format: uint8
                minimum: 0.0
          additionalProperties: false
        - type: object
          required:
          - DWord
          properties:
            DWord:
              type: integer
              format: uint32
              minimum: 0.0
          additionalProperties: false
        - type: object
          required:
          - MultiString
          properties:
            MultiString:
              type: array
              items:
                type: string
          additionalProperties: false
        - type: object
          required:
          - QWord
          properties:
            QWord:
              type: integer
              format: uint64
              minimum: 0.0
          additionalProperties: false
    

I've manually implemented a documentation structure for DSC Resources (Microsoft/OSInfo, Microsoft.Windows/Registry, but there's no good way for a user to know about those docs from the command line.

My experience as a PSDSC user, integrating developer, and resource author is that not having a well-defined way to surface reference documentation made it much harder to use and understand individual resources. I often had to hunt for the resource documentation, then compare it against the implementation to make sure it was up to date. This often meant I would go directly to the implementation instead of reading documentation.

Proposed technical implementation details (optional)

I think there's several options for addressing this need and worth investigating them sooner than later, as the usability of the resources is going to be critical to user success. The following list is a set of proposals. If we decide to accept any of the proposals, I'll replace the list item with a reference to the issue for it.

  • [ ] Add the projectURL and docsURL properties to the resource manifest. This would enable users to navigate from the manifest information to the appropriate repo or website.
  • For defining the reference documentation itself, one of:
    • [ ] Either add a docs property to the resource manifest or supporting a separate .dsc.docs.json file that contains the structured reference documentation for a resource. This would enable a single-source-of-truth for rendering the reference documentation locally, on a static site, or converting to Markdown. With a strongly structured data format, we can more reliably describe the resource and its properties, especially for documentation needs that are not best captured in JSON Schemas.
    • [ ] Surface the VS Code documentation keywords from a resource schema into a readable format. The schema could define the markdownDescription and markdownEnumDescriptions keywords for the properties. The difficulty here is that JSON Schema definitions may be very complex and auto-generating documentation from them is difficult. Especially to the level of usability we would want for DSC Resources.
    • [ ] Support finding .dsc.resource.md files with a metadata block that associates them to a specific resource. We could provide a template for this file and use it as the reference documentation.
  • [ ] Add a command to surface reference documentation for a resource. If the resource manifest indicates that it has online documentation, a --online flag could open the online documentation in the default browser.
  • [ ] Define a model for examples-as-acceptance tests. It would be useful for resource authors to be able to define a set of example configuration documents that can be used both for acceptance testing and incorporated into the documentation. I think resource unit tests will always depend on the implementation language, but we can provide a lightweight model for acceptance testing that serves a dual purpose.

Regarding the three proposals for defining reference documentation:

I think the most robust option is the docs-as-data, where the resource documentation is in a docs keyword in the manifest or in a separate file. We can schematize this structure and provide a default transformer to Markdown for it. With the documentation saved in a data file, users can inspect particular properties or notes more easily. We could explore a tighter coupling/updating/testing for the documentation against the resource schema in the future, but that wouldn't be necessary for the initial model.

The JSON schema-introspection is, theoretically, better because it requires that the author only write and maintain a single data structure and that information is then available directly in the editor as well without any extra work. However, retrieving reference documentation from a schema is very difficult, especially if the schema uses the definitions or $defs keywords, or uses conditional or compositional keywords. Even with the extended vocabulary VS Code provides, the documentation surface isn't particularly robust. It would also require a lot of up front implementation code to retrieve the documentation from the schema and transform it for a reader.

The companion Markdown file option is the simplest to implement and author, but imposes limitations on how the documentation should be rendered, rather than what should be documented. It also makes any coupling/updating/testing of the documentation and schema more difficult. It's the simplest to implement but also the most limited.

michaeltlombardi avatar Nov 08 '23 18:11 michaeltlombardi