PowerShell / DSC

This repo is for the DSC v3 project
MIT License
195 stars 24 forks source link

Stdin for config vs resource #253

Closed mgreenegit closed 6 months ago

mgreenegit commented 10 months ago

Summary of the new feature / enhancement

With the implementation we have at this time, the only way a resource group author can determine if the input is from a configuration or resource is to look for a resources property at the top level. This is problematic for two reasons.

1 - When the input is from a configuration, the Name and Type properties are not dsc properties, they are describing the resource. The input moves to being under properties. This shift in behavior will require the author to have read docs and understand, otherwise they will waste time figuring it out. 2 - There could be a dsc resource with the name resources already in existence.

Proposed technical implementation details (optional)

First, I would propose that any time we offer stdin to a resource group, if should include some information about the command that has been run. In the first example below the parameter is include as _context, in the second example the entire command is included.

Proposal1 - simple:

{
  "_context": "config"
  }
  "resources": [
    {
      "name": "bits",
      "type": "PsDscResources/Service",
      "properties": {
        "Name": "bits"
        "State": "Running"
      }
    }
  ]
}

Proposal2 - full:

{
  "_context": "dsc config test"
  }
  "resources": [
    {
      "name": "bits",
      "type": "PsDscResources/Service",
      "properties": {
        "Name": "bits"
        "State": "Running"
      }
    }
  ]
}

Second, I would propose that when stdin is from a configuration, we should use the _ to indicate the properties are referencing details about the resource and are not actually properties of the resource.

Example:

{
  "_context": "config"
  }
  "resources": [
    {
      "_name": "bits",
      "_type": "PsDscResources/Service",
      "_properties": {
        "Name": "bits"
        "State": "Running"
      }
    }
  ]
}
mgreenegit commented 10 months ago

Follow up, after much validation.

Proposal is we should ALWAYS format input as below and include $schema when appropriate.

{
  "$schema": "",
  "resources": [
    {
      "name": "name",
      "type": "type",
      "properties": {
        "property1": "property1",
        "property2": "property2"
      }
    }
  ]
}
michaeltlombardi commented 10 months ago

I'm not sure the $schema key is fully necessary and it feels strange to use that keyword to mean something other than "the canonical URI of the JSON schema that validates this object."

I think there are four cases where a provider/group might have to decide how to process the input differently:

  1. When resources contains more than one item and was called from dsc config *.
  2. When resources contains more than one item and was called from dsc resource * (invoking the provider or group directly, rather than a resource that depends on the provider).
  3. When resources contains exactly one item and was called from dsc config *.
  4. When resources contains exactly one item and was called from dsc resource *.

I can't actually think of cases where I would do different processing for 1&2 or 3&4. I can definitely see different processing for one-item and many-items, but not depending on the higher-order calling.

Also worth noting, this becomes a contract for DSC, for group/provider authors, and for integrating tools. Requiring conditionally inserting/handling different values for $schema adds a layer of complexity over checking the item count for resources (which I think is still required anyway).

SteveL-MSFT commented 6 months ago

If this is needed, I would suggest we use the metadata optional property:

metadata:
  Microsoft.DSC:
    Context: configuration

Basically, the DSC property is our namespace and reserved. All other metadata is ignored and intended to be used by the config author for keeping their own information that isn't processed.