-
Notifications
You must be signed in to change notification settings - Fork 55
Description
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
Fileresource that can create empty files, delete files, and set permissions and modes for files, I want to create aTemplateFileresource 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: trueIn 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:
- Perform resource discovery to find
Mikey.Go/TemplateFile - 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. - If it does, call the
getoperation for theFileresource, holding the result temporarily. If it doesn't, error because the extended resource can't be used without it. - If the
getoperation was successful, call thegetoperation for theMikey.Go/TemplateFileresource, holding the result temporarily. - Merge the result objects from both resources to return the canonical representation of the
TemplateFileresource (which in this case includes thecontentproperty, but not the write-onlytemplateorvariablesproperties, and the properties returned by theFileresource.
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