Skip to content

Proposal: Extended Resources #611

@michaeltlombardi

Description

@michaeltlombardi

Summary of the new feature / enhancement

As a resource author, I want to be able to create and maintain a resource that extends the capabilities of another resource without duplicating that resource's implementation. For example, given a File resource that can create empty files, delete files, and set permissions and modes for files, I want to create a TemplateFile resource that handles processing a template to define the contents of a file without having to reimplement permissions, existence, etc myself, or requiring my users to define two instances in their configuration document when one instance always implies the other.

Consider the following snippet of a fictional extended resource manifest:

type: Mikey.Go/TemplateFile
extends:
  type: Microsoft.Dsc.Fs/File
  version: "(1.0,2.0)"
schema:
  # skipping $schema, type, etc for brevity
  $ref: "<json-schema-uri-for-file-resource>"
  required: [template]
  properties:
    template:
      type: string
      writeOnly: true
    variables:
      type: object
      writeOnly: true
    content:
      type: string
      readOnly: true

In this case, the Mikey.Go/TemplateFile resource has all of the configurable properties of the Microsoft.Dsc.Fs/File and the new template, variables, and content properties that it defines.

From a functional perspective, given the following command:

@'
path: /code/message.txt
_exist: true
permissions: 0755
owner: mikey
template: |-
  Hello, {{ .name }}!
variables:
  name: world
'@ | dsc resource get -r Mikey.Go/TemplateFile --file -

I would expect DSC to do the following:

  1. Perform resource discovery to find Mikey.Go/TemplateFile
  2. Because that resource defines itself as extending Microsoft.Dsc.Fs/File, look in the cache for that resource to see if it exists in the valid version range.
  3. If it does, call the get operation for the File resource, holding the result temporarily. If it doesn't, error because the extended resource can't be used without it.
  4. If the get operation was successful, call the get operation for the Mikey.Go/TemplateFile resource, holding the result temporarily.
  5. Merge the result objects from both resources to return the canonical representation of the TemplateFile resource (which in this case includes the content property, but not the write-only template or variables properties, and the properties returned by the File resource.

Procedurally, DSC always invokes the extended resource after the resource it extends, and only if the referenced resource doesn't error during discovery or invocation.

From a practical perspective, this would support defining minimal generic resources that still provide functionality on their own, like File or OSInfo, which resource authors could then layer various behaviors on top of to suit different needs.

I think this behavior would be most useful for the File resource, where I can think of a dozen different iterations on managing file contents while still needing to set the existence and properties of the file itself - TemplateFile, CopyFile, DownloadFile.

Initially, I would expect extended resources only to add new configurable properties, not replace processing for existing ones - but that could be a future enhancement too (though obviously adds complexity).

I haven't specced this proposal out fully but wanted to write up initial thoughts and submit them here.

Proposed technical implementation details (optional)

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions