diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a5efa85..30b52b26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -70,7 +70,161 @@ changes since the last release, see the [diff on GitHub][unreleased]. for the `v3.0.0.0-alpha.5` release. Leave the release links under the release section. --> +### Added + +- Added the [`--what-if` (`-w`)][ur-aa] option to the [dsc config set][cmd-cset] command. When you + call `dsc config set` with the `--what-if` option, DSC doesn't actually invoke the resources to + enforce the desired state. Instead, it returns the expected output for the command, showing the + before and after state for each resource instance. + + The output for the `dsc config set` operation with the `--what-if` operation is the same as an + [actual configuration set operation][ur-ab], except that the metadata field + [executionType][ur-ac] is set to `WhatIf` instead of `Actual`. + + In this release, the generated output is synthetic, based on the results of the resources' `test` + operation. In the future, resources will be able to participate in what-if operations, reporting + more specifically how they will change the system. For example, participating resources could + indicate whether an actual set operation will require a reboot or whether the current user has +the correct permissions to manage that resource instance. + + <details><summary>Related work items</summary> + + - Issues: [#70][#70] + - PRs: [#400][#400] + + </details> + +- Added support for [importer resources][ur-ad]. These resources resolve external sources to a + nested DSC Configuration document. The resolved instances are processed as nested resource + instances. + + This required some updates to the schemas, all backwards-compatible: + + - Added a new [resourceKind][ur-ae] named `Import`. + - Added the [resolve][ur-af] command to resource manifests. + - Added the new [`Resolve`][ur-ag] capability, returned in the output for the + [dsc resource list][cmd-rlist] command when DSC discovers an importer resource. + + <details><summary>Related work items</summary> + + - Issues: [#429][#429] + - PRs: [#412][#412] + + </details> + +- Added the `Microsoft.DSC/Include` importer resource to resolve instances from an external + configuration document. The resolved instances are processed as nested instances for the + `Microsoft.DSC/Include` resource instance. + + You can use this resource to write smaller configuration documents and compose them as needed. + For example, you could define a security baseline and a web server configuration separately, then + combine them for a given application: + + ```yaml + $schema: &schema https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/config/document.json + resources: + # Group of included baseline configurations + - name: Baselines + type: Microsoft.DSC/Group + properties: + $schema: *schema + resources: + - name: Security Baseline + type: Microsoft.DSC/Include + properties: + configurationFile: security_baseline.dsc.yaml + parametersFile: security_baseline.parameters.yaml + - name: Web Server Baseline + type: Microsoft.DSC/Include + properties: + configurationFile: web_baseline.dsc.yaml + parametersFile: web_baseline.parameters.yaml + dependsOn: + - "[resourceId('Microsoft.DSC/Include', 'Security Baseline')]" + + # application configuration instances, all depend on the baselines + - name: Application configuration + type: MyApp/Settings + properties: + someSetting: someValue + dependsOn: + - "[resourceId('Microsoft.DSC/Group', 'Baselines')]" + ``` + + <details><summary>Related work items</summary> + + - Issues: [#429][#429] + - PRs: [#412][#412] + + </details> + +- Added caching for PowerShell Desired State Configuration (PSDSC) resources when using the + `Microsoft.DSC/PowerShell` and `Microsoft.Windows/PowerShell` adapters. The adapters use the + cache to speed up resource discovery. The performance improvement reduced the resource list time + under tests from eight seconds to two seconds, and reduced invocation operation times by half. + + The adapters cache the resources in the following locations, depending on your platform: + + | Adapter | Platform | Path | + | :----------------------------: | :------: | :---------------------------------------------- | + | `Microsoft.DSC/PowerShell` | Linux | `$HOME/.dsc/PSAdapterCache.json` | + | `Microsoft.DSC/PowerShell` | macOS | `$HOME/.dsc/PSAdapterCache.json` | + | `Microsoft.DSC/PowerShell` | Windows | `%LOCALAPPDATA%\dsc\PSAdapterCache.json` | + | `Microsoft.Windows/PowerShell` | Windows | `%LOCALAPPDATA%\dsc\WindowsPSAdapterCache.json` | + + The adapters check whether the cache is stale on each run and refresh it if: + + - The `PSModulePath` environmental variable is updated. + - Any module is added or removed from the `PSModulePath`. + - Any related files in a cached PSDSC resource module has been updated since the cache was + written. The adapter watches the `LastWriteTime` of module files with the following extensions: + `.ps1`, `.psd1`, `.psm1`, and `.mof`. + + <details><summary>Related work items</summary> + + - Issues: [#371][#371] + - PRs: [#432][#432] + + </details> + +- Added the `DSC.PackageManagement/Apt` resource for managing software on systems that use the + advanced package tool (APT). In this release, you can use the resource to: + + - Install the latest version of a package. + - Uninstall a package. + - Get the current state of a package. + - Export every installed package as a DSC resource instance. + + <details><summary>Related work items</summary> + + - Issues: _None_. + - PRs: [#434][#434] + + </details> + + +### Fixed + +- Fixed the JSON Schema for [exit codes][ur-fa] in the resource manifest to support negative + integers. Prior to this release, the DSC engine supported negative exit codes but the JSON Schema + forbid them. + + <details><summary>Related work items</summary> + + - Issues: [#407][#407] + - PRs: [#410][#410] + + </details> + <!-- Unreleased change links --> +[ur-aa]: ./docs/reference/cli/config/set.md#-w---what-if +[ur-ab]: ./docs/reference/schemas/outputs/config/set.md +[ur-ac]: ./docs/reference/schemas/metadata/Microsoft.DSC/properties.md#executiontype +[ur-ad]: ./docs/reference/schemas/definitions/resourceKind.md#importer-resources +[ur-ae]: ./docs/reference/schemas/definitions/resourceKind.md +[ur-af]: ./docs/reference/schemas/resource/manifest/resolve.md +[ur-ag]: ./docs/reference/schemas/outputs/resource/list.md#capability-resolve +[ur-fa]: ./docs/reference/schemas/resource/manifest/root.md#exitcodes ## [v3.0.0-preview.7][release-v3.0.0-preview.7] - 2024-04-22 @@ -1318,6 +1472,7 @@ For the full list of changes in this release, see the [diff on GitHub][compare-v [#362]: https://github.com/PowerShell/DSC/issues/362 [#364]: https://github.com/PowerShell/DSC/issues/364 [#368]: https://github.com/PowerShell/DSC/issues/368 +[#371]: https://github.com/PowerShell/DSC/issues/371 [#373]: https://github.com/PowerShell/DSC/issues/373 [#375]: https://github.com/PowerShell/DSC/issues/375 [#376]: https://github.com/PowerShell/DSC/issues/376 @@ -1327,11 +1482,19 @@ For the full list of changes in this release, see the [diff on GitHub][compare-v [#385]: https://github.com/PowerShell/DSC/issues/385 [#388]: https://github.com/PowerShell/DSC/issues/388 [#397]: https://github.com/PowerShell/DSC/issues/397 +[#400]: https://github.com/PowerShell/DSC/issues/400 [#401]: https://github.com/PowerShell/DSC/issues/401 [#405]: https://github.com/PowerShell/DSC/issues/405 +[#407]: https://github.com/PowerShell/DSC/issues/407 +[#410]: https://github.com/PowerShell/DSC/issues/410 +[#412]: https://github.com/PowerShell/DSC/issues/412 +[#429]: https://github.com/PowerShell/DSC/issues/429 +[#432]: https://github.com/PowerShell/DSC/issues/432 +[#434]: https://github.com/PowerShell/DSC/issues/434 [#45]: https://github.com/PowerShell/DSC/issues/45 [#49]: https://github.com/PowerShell/DSC/issues/49 [#57]: https://github.com/PowerShell/DSC/issues/57 +[#70]: https://github.com/PowerShell/DSC/issues/70 [#73]: https://github.com/PowerShell/DSC/issues/73 [#75]: https://github.com/PowerShell/DSC/issues/75 [#89]: https://github.com/PowerShell/DSC/issues/89 diff --git a/docs/reference/cli/config/set.md b/docs/reference/cli/config/set.md index b0e6b7ec..8049354d 100644 --- a/docs/reference/cli/config/set.md +++ b/docs/reference/cli/config/set.md @@ -125,6 +125,20 @@ Type: String Mandatory: false ``` +### -w, --what-if + +When you specify this flag option, DSC doesn't actually change the system state with the `set` +operation. Instead, it returns output indicating _how_ the operation will change system state when +called without this option. Use this option to preview the changes DSC will make to a system. + +The output for the command when you use this option is the same as without, except that the +`ExecutionType` metadata field is set to `WhatIf` instead of `Actual`. + +```yaml +Type: Boolean +Mandatory: false +``` + ### -f, --format The `--format` option controls the console output format for the command. If the command output is diff --git a/docs/reference/cli/dsc.md b/docs/reference/cli/dsc.md index 8ceecb97..b7d311db 100644 --- a/docs/reference/cli/dsc.md +++ b/docs/reference/cli/dsc.md @@ -162,6 +162,11 @@ execution of the command. | `5` | The command failed because a resource definition or instance value was invalid against its JSON schema. | | `6` | The command was cancelled by a <kbd>Ctrl</kbd>+<kbd>C</kbd> interruption. | +## Notes + +DSC expects input strings to use UTF-8 encoding. When you pass input from stdin or the path to a +file, ensure that the input is encoded as UTF-8. + [01]: completer/command.md [02]: config/command.md [03]: resource/command.md diff --git a/docs/reference/cli/resource/list.md b/docs/reference/cli/resource/list.md index 655ab137..8223f22e 100644 --- a/docs/reference/cli/resource/list.md +++ b/docs/reference/cli/resource/list.md @@ -45,25 +45,26 @@ dsc resource list ``` ```Output -Type Kind Version Caps RequireAdapter Description ------------------------------------------------------------------------------------------------------------------------------------------------------------------- -DSC.PackageManagement/Brew Resource 0.1.0 gs---e DSC resource to manage Homebrew packages -Microsoft.DSC.Transitional/RunCommandOnSet Resource 0.1.0 gs---- Takes a single-command line to execute on DSC set operation -Microsoft.DSC/Assertion Group 0.1.0 gs-t-- `test` will be invoked for all resources in the supplied configuration. -Microsoft.DSC/Group Group 0.1.0 gs-t-- All resources in the supplied configuration is treated as a group. -Microsoft.DSC/Parallel Group 0.1.0 gs-t-- All resources in the supplied configuration run concurrently. -Microsoft.DSC/PowerShell Adapter 0.1.0 gs-t-e Resource adapter to classic DSC Powershell resources. -Microsoft.Windows/RebootPending Resource 0.1.0 g----- Returns info about pending reboot. -Microsoft.Windows/Registry Resource 0.1.0 gs--d- Manage Windows Registry keys and values -Microsoft.Windows/WindowsPowerShell Adapter 0.1.0 gs-t-- Resource adapter to classic DSC Powershell resources in Windows PowerShell. -Microsoft.Windows/WMI Adapter 0.1.0 g----- Resource adapter to WMI resources. -Microsoft/OSInfo Resource 0.1.0 g----e Returns information about the operating system. -Microsoft/Process Resource 0.1.0 gs-t-e Returns information about running processes. -Test/Delete Resource 0.1.0 g---d- -Test/Echo Resource 0.1.0 gs-t-- -Test/Exist Resource 0.1.0 gsx--- -Test/Sleep Resource 0.1.0 gs-t-- -Test/TestGroup Adapter 0.1.0 g----- +Type Kind Version Caps RequireAdapter Description +------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Microsoft.DSC.Transitional/RunCommandOnSet Resource 0.1.0 gs----- Takes a single-command line to execute on DSC set operation +Microsoft.DSC/Assertion Group 0.1.0 gs-t--- `test` will be invoked for all resources in the supplied configuration. +Microsoft.DSC/Group Group 0.1.0 gs-t--- All resources in the supplied configuration is treated as a group. +Microsoft.DSC/Include Import 0.1.0 ------r Allows including a configuration file contents into current configuration. +Microsoft.DSC/Parallel Group 0.1.0 gs-t--- All resources in the supplied configuration run concurrently. +Microsoft.DSC/PowerShell Adapter 0.1.0 gs-t-e- Resource adapter to classic DSC Powershell resources. +Microsoft.Windows/RebootPending Resource 0.1.0 g------ Returns info about pending reboot. +Microsoft.Windows/Registry Resource 0.1.0 gs--d-- Manage Windows Registry keys and values +Microsoft.Windows/WMI Adapter 0.1.0 g------ Resource adapter to WMI resources. +Microsoft.Windows/WindowsPowerShell Adapter 0.1.0 gs-t--- Resource adapter to classic DSC Powershell resources in Windows PowerShell. +Microsoft/OSInfo Resource 0.1.0 g----e- Returns information about the operating system. +Microsoft/Process Resource 0.1.0 gs-t-e- Returns information about running processes. +Test/Delete Resource 0.1.0 g---d-- +Test/Echo Resource 0.1.0 gs-t--- +Test/Exist Resource 0.1.0 gsx---- +Test/Sleep Resource 0.1.0 gs-t--- +Test/TestGroup Adapter 0.1.0 g------ +Test/Trace Resource 0.1.0 gs-t--- ``` ### Example 2 - List a specific resource @@ -76,9 +77,9 @@ dsc resource list Microsoft.DSC/Group ``` ```Output -Type Kind Version Caps RequireAdapter Description -------------------------------------------------------------------------------------------------------------------------------- -Microsoft.DSC/Group Group 0.1.0 gs-t-- All resources in the supplied configuration is treated as a group. +Type Kind Version Caps RequireAdapter Description +-------------------------------------------------------------------------------------------------------------------------------- +Microsoft.DSC/Group Group 0.1.0 gs-t--- All resources in the supplied configuration is treated as a group. ``` ### Example 3 - List resources with a matching type name @@ -91,12 +92,13 @@ dsc resource list Microsoft.DSC/* ``` ```Output -Type Kind Version Caps RequireAdapter Description -------------------------------------------------------------------------------------------------------------------------------------------- -Microsoft.DSC/Assertion Group 0.1.0 gs-t-- `test` will be invoked for all resources in the supplied configuration. -Microsoft.DSC/Group Group 0.1.0 gs-t-- All resources in the supplied configuration is treated as a group. -Microsoft.DSC/Parallel Group 0.1.0 gs-t-- All resources in the supplied configuration run concurrently. -Microsoft.DSC/PowerShell Adapter 0.1.0 gs-t-e Resource adapter to classic DSC Powershell resources. +Type Kind Version Caps RequireAdapter Description +----------------------------------------------------------------------------------------------------------------------------------------------- +Microsoft.DSC/Assertion Group 0.1.0 gs-t--- `test` will be invoked for all resources in the supplied configuration. +Microsoft.DSC/Group Group 0.1.0 gs-t--- All resources in the supplied configuration is treated as a group. +Microsoft.DSC/Include Import 0.1.0 ------r Allows including a configuration file contents into current configuration. +Microsoft.DSC/Parallel Group 0.1.0 gs-t--- All resources in the supplied configuration run concurrently. +Microsoft.DSC/PowerShell Adapter 0.1.0 gs-t-e- Resource adapter to classic DSC Powershell resources. ``` ### Example 4 - List resources with a matching description @@ -109,11 +111,11 @@ dsc resource list --description 'supplied configuration' ``` ```Output -Type Kind Version Caps RequireAdapter Description ----------------------------------------------------------------------------------------------------------------------------------------- -Microsoft.DSC/Assertion Group 0.1.0 gs-t-- `test` will be invoked for all resources in the supplied configuration. -Microsoft.DSC/Group Group 0.1.0 gs-t-- All resources in the supplied configuration is treated as a group. -Microsoft.DSC/Parallel Group 0.1.0 gs-t-- All resources in the supplied configuration run concurrently. +Type Kind Version Caps RequireAdapter Description +----------------------------------------------------------------------------------------------------------------------------------------- +Microsoft.DSC/Assertion Group 0.1.0 gs-t--- `test` will be invoked for all resources in the supplied configuration. +Microsoft.DSC/Group Group 0.1.0 gs-t--- All resources in the supplied configuration is treated as a group. +Microsoft.DSC/Parallel Group 0.1.0 gs-t--- All resources in the supplied configuration run concurrently. ``` ### Example 5 - List resources with matching tags @@ -126,10 +128,10 @@ dsc resource list --tags Windows --tags Linux ``` ```output -Type Kind Version Caps RequireAdapter Description ----------------------------------------------------------------------------------------------------------------------- -Microsoft.Windows/Registry Resource 0.1.0 gs--d- Manage Windows Registry keys and values -Microsoft/OSInfo Resource 0.1.0 g----e Returns information about the operating system. +Type Kind Version Caps RequireAdapter Description +----------------------------------------------------------------------------------------------------------------------- +Microsoft.Windows/Registry Resource 0.1.0 gs--d-- Manage Windows Registry keys and values +Microsoft/OSInfo Resource 0.1.0 g----e- Returns information about the operating system. ``` ### Example 6 - List resources for a specific adapter @@ -144,20 +146,20 @@ dsc resource list --adapter Microsoft.DSC/PowerShell ``` ```Output -Type Kind Version Caps RequireAdapter Description ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -PSDscResources/Archive Resource 2.12.0.0 gs-t-- Microsoft.DSC/PowerShell This module contains the standard DSC resources. -PSDscResources/Environment Resource 2.12.0.0 gs-t-- Microsoft.DSC/PowerShell This module contains the standard DSC resources. -PSDscResources/Group Resource 2.12.0.0 gs-t-- Microsoft.DSC/PowerShell This module contains the standard DSC resources. -PSDscResources/MsiPackage Resource 2.12.0.0 gs-t-- Microsoft.DSC/PowerShell This module contains the standard DSC resources. -PSDscResources/Registry Resource 2.12.0.0 gs-t-- Microsoft.DSC/PowerShell This module contains the standard DSC resources. -PSDscResources/Script Resource 2.12.0.0 gs-t-- Microsoft.DSC/PowerShell This module contains the standard DSC resources. -PSDscResources/Service Resource 2.12.0.0 gs-t-- Microsoft.DSC/PowerShell This module contains the standard DSC resources. -PSDscResources/User Resource 2.12.0.0 gs-t-- Microsoft.DSC/PowerShell This module contains the standard DSC resources. -PSDscResources/WindowsFeature Resource 2.12.0.0 gs-t-- Microsoft.DSC/PowerShell This module contains the standard DSC resources. -PSDscResources/WindowsOptionalFeature Resource 2.12.0.0 gs-t-- Microsoft.DSC/PowerShell This module contains the standard DSC resources. -PSDscResources/WindowsPackageCab Resource 2.12.0.0 gs-t-- Microsoft.DSC/PowerShell This module contains the standard DSC resources. -PSDscResources/WindowsProcess Resource 2.12.0.0 gs-t-- Microsoft.DSC/PowerShell This module contains the standard DSC resources. +Type Kind Version Caps RequireAdapter Description +---------------------------------------------------------------------------------------------------------------------------------------------- +PSDscResources/Archive Resource 2.12.0.0 gs-t--- Microsoft.DSC/PowerShell This module contains the standard DSC resources. +PSDscResources/Environment Resource 2.12.0.0 gs-t--- Microsoft.DSC/PowerShell This module contains the standard DSC resources. +PSDscResources/Group Resource 2.12.0.0 gs-t--- Microsoft.DSC/PowerShell This module contains the standard DSC resources. +PSDscResources/MsiPackage Resource 2.12.0.0 gs-t--- Microsoft.DSC/PowerShell This module contains the standard DSC resources. +PSDscResources/Registry Resource 2.12.0.0 gs-t--- Microsoft.DSC/PowerShell This module contains the standard DSC resources. +PSDscResources/Script Resource 2.12.0.0 gs-t--- Microsoft.DSC/PowerShell This module contains the standard DSC resources. +PSDscResources/Service Resource 2.12.0.0 gs-t--- Microsoft.DSC/PowerShell This module contains the standard DSC resources. +PSDscResources/User Resource 2.12.0.0 gs-t--- Microsoft.DSC/PowerShell This module contains the standard DSC resources. +PSDscResources/WindowsFeature Resource 2.12.0.0 gs-t--- Microsoft.DSC/PowerShell This module contains the standard DSC resources. +PSDscResources/WindowsOptionalFeature Resource 2.12.0.0 gs-t--- Microsoft.DSC/PowerShell This module contains the standard DSC resources. +PSDscResources/WindowsPackageCab Resource 2.12.0.0 gs-t--- Microsoft.DSC/PowerShell This module contains the standard DSC resources. +PSDscResources/WindowsProcess Resource 2.12.0.0 gs-t--- Microsoft.DSC/PowerShell This module contains the standard DSC resources. ``` This next command specifies the resource name filter `*Windows*`, limiting the list of returned @@ -168,12 +170,12 @@ dsc resource list --adapter Microsoft.DSC/PowerShell *Windows* ``` ```Output -Type Kind Version Caps RequireAdapter Description ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -PSDscResources/WindowsFeature Resource 2.12.0.0 gs-t-- Microsoft.DSC/PowerShell This module contains the standard DSC resources. -PSDscResources/WindowsOptionalFeature Resource 2.12.0.0 gs-t-- Microsoft.DSC/PowerShell This module contains the standard DSC resources. -PSDscResources/WindowsPackageCab Resource 2.12.0.0 gs-t-- Microsoft.DSC/PowerShell This module contains the standard DSC resources. -PSDscResources/WindowsProcess Resource 2.12.0.0 gs-t-- Microsoft.DSC/PowerShell This module contains the standard DSC resources. +Type Kind Version Caps RequireAdapter Description +---------------------------------------------------------------------------------------------------------------------------------------------- +PSDscResources/WindowsFeature Resource 2.12.0.0 gs-t--- Microsoft.DSC/PowerShell This module contains the standard DSC resources. +PSDscResources/WindowsOptionalFeature Resource 2.12.0.0 gs-t--- Microsoft.DSC/PowerShell This module contains the standard DSC resources. +PSDscResources/WindowsPackageCab Resource 2.12.0.0 gs-t--- Microsoft.DSC/PowerShell This module contains the standard DSC resources. +PSDscResources/WindowsProcess Resource 2.12.0.0 gs-t--- Microsoft.DSC/PowerShell This module contains the standard DSC resources. ``` ## Arguments @@ -286,8 +288,10 @@ displayed in the listed order: - `t` indicates that the resource has the [Test capability][08] - `d` indicates that the resource has the [Delete capability][09] - `e` indicates that the resource has the [Export capability][10] + - `r` indicates that the resource has the [Resolve capability][11] - For example, the `Microsoft.Windows/Registry` resource has the following capabilities: `gs--d-`, indicating it has the `Get`, `Set`, and `Delete` capabilities. + For example, the `Microsoft.Windows/Registry` resource has the following capabilities: `gs--d-`, + indicating it has the `Get`, `Set`, and `Delete` capabilities. - **RequireAdapter** - The fully qualified type name of the adapter resource that DSC uses to invoke the returned resource. - **Description** - The short description of the resource's purpose and usage. @@ -306,3 +310,4 @@ To display the output objects as either JSON or YAML objects in the console, use [08]: ../../schemas/outputs/resource/list.md#capability-test [09]: ../../schemas/outputs/resource/list.md#capability-delete [10]: ../../schemas/outputs/resource/list.md#capability-export +[11]: ../../schemas/outputs/resource/list.md#capability-resolve diff --git a/docs/reference/schemas/definitions/resourceKind.md b/docs/reference/schemas/definitions/resourceKind.md index 6c12fa58..979f6079 100644 --- a/docs/reference/schemas/definitions/resourceKind.md +++ b/docs/reference/schemas/definitions/resourceKind.md @@ -17,7 +17,7 @@ Identifies whether a resource is an adapter resource, a group resource, or a nor SchemaDialect: https://json-schema.org/draft/2020-12/schema SchemaID: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/definitions/resourceKind.json Type: string -ValidValues: [Resource, Adapter, Group] +ValidValues: [Resource, Adapter, Group, Import] ``` ## Description @@ -27,6 +27,7 @@ DSC supports three kinds of command-based DSC Resources: - `Resource` - Indicates that the manifest isn't for a group or adapter resource. - `Group` - Indicates that the manifest is for a [group resource](#group-resources). - `Adapter` - Indicates that the manifest is for an [adapter resource](#adapter-resources). +- `Import` - Indicates that the manifest is for an [importer resource](#importer-resources). When `kind` isn't defined in the resource manifest, DSC infers the value for the property. If the `adapter` property is defined in the resource manifest, DSC infers the value of `kind` as @@ -54,16 +55,39 @@ modules. They don't define resource manifests. Group resources always operate on nested DSC Resource instances. Group resources can change how the nested instances are processed, like the `Microsoft.DSC/Assertion` group resource. +A group resource must always define the [kind][aa] property in the resource manifest. + Group resources can also be used to bundle sets of resources together for processing, like the `Microsoft.DSC/Group` resource. You can use the [dependsOn][03] property for a resource instance in a configuration to point to a group resource instead of enumerating each resource in the list. +### Importer resources + +Importer resources resolve an external source to a set of nested DSC Resource instances. The +properties of an importer resource define how to find and resolve the external source. + +An importer resource must always define the [kind][aa] and [resolve][ab] properties in the resource +manifest. + +For example, the `Microsoft.DSC/Import` importer resource resolves instances from an external +configuration document, enabling you to compose configurations from multiple files. + ### Nested resource instances -The resource instances declared in both adapter and group resources are called _nested resource -instances_. For nested instances, a resource instance is _adjacent_ if it's declared in the same -group or adapter instance. A resource instance is _external_ to a nested instance if it's declared -outside of the group or adapter instance, or nested inside an adjacent group or adapter instance. +The resource instances declared in adapter and group resources or resolved by importer resources +are called _nested resource instances_. + +For nested instances, a resource instance is _adjacent_ if: + +- It's declared in the same group or adapter instance. +- It's resolved by the same importer instance. + +A resource instance is _external_ to a nested instance if: + +- It's declared outside of the group or adapter instance +- It's resolved by a different importer instance +- It's nested inside an adjacent group, adapter, or importer instance. + For top-level instances, other instances at the top-level are adjacent. All other instances are external. @@ -122,14 +146,14 @@ Nested resource instances have limitations for the [dependsOn][03] property and [reference()][04] configuration function. 1. You can only reference adjacent instances. You can't reference a nested instance from outside of - the group or adapter that declares it. You can't use a reference to a resource outside of the - group or adapter resource for a nested instance. + the instance that declares or resolves it. You can't use a reference to a resource outside of the + group, adapter, or importer resource for a nested instance. 1. You can only use the `dependsOn` property for adjacent instances. You must add a dependency on - the group or adapter instance, not a nested instance of the group or adapter. Nested instances - can't depend on external instances. + the group, adapter, or importer instance, not a nested instance. Nested instances can't depend + on external instances. The following examples show valid and invalid references and dependencies. The examples use the -`Microsoft.DSC/Group` resource, but the functionality is the same for adapter resources. +`Microsoft.DSC/Group` resource, but the functionality is the same for adapter and import resources. #### Example 1 - Valid references and dependencies @@ -357,5 +381,7 @@ resources: [01]: ../resource/manifest/adapter.md [02]: ../resource/manifest/validate.md +[aa]: ../resource/manifest/root.md#kind [03]: ../config/resource.md#dependson +[ab]: ../resource/manifest/resolve.md [04]: ../config/functions/reference.md diff --git a/docs/reference/schemas/outputs/config/get.md b/docs/reference/schemas/outputs/config/get.md index 2fe5859e..19fd2af7 100644 --- a/docs/reference/schemas/outputs/config/get.md +++ b/docs/reference/schemas/outputs/config/get.md @@ -55,7 +55,7 @@ The metadata under this property describes the context of the overall operation: `Set`, `Test`, or `Export`. - [executionType][03] defines whether DSC actually applied an operation to the configuration or was run in `WhatIf` mode. This property is always `Actual` for `Get`, `Test`, and `Export` - operations. For `Set` operations, this value is `WhatIf` when DSC is invoked with the `--whatIf` + operations. For `Set` operations, this value is `WhatIf` when DSC is invoked with the `--what-if` argument. - [startDatetime][04] defines the start date and time for the DSC operation as a timestamp following the format defined in [RFC3339, section 5.6 (see `date-time`)][05], like diff --git a/docs/reference/schemas/outputs/config/set.md b/docs/reference/schemas/outputs/config/set.md index 87d98e83..72453bfc 100644 --- a/docs/reference/schemas/outputs/config/set.md +++ b/docs/reference/schemas/outputs/config/set.md @@ -56,7 +56,7 @@ The metadata under this property describes the context of the overall operation: `Set`, `Test`, or `Export`. - [executionType][03] defines whether DSC actually applied an operation to the configuration or was run in `WhatIf` mode. This property is always `Actual` for `Get`, `Test`, and `Export` - operations. For `Set` operations, this value is `WhatIf` when DSC is invoked with the `--whatIf` + operations. For `Set` operations, this value is `WhatIf` when DSC is invoked with the `--what-if` argument. - [startDatetime][04] defines the start date and time for the DSC operation as a timestamp following the format defined in [RFC3339, section 5.6 (see `date-time`)][05], like diff --git a/docs/reference/schemas/outputs/config/test.md b/docs/reference/schemas/outputs/config/test.md index deb411f5..4df9b60d 100644 --- a/docs/reference/schemas/outputs/config/test.md +++ b/docs/reference/schemas/outputs/config/test.md @@ -56,7 +56,7 @@ The metadata under this property describes the context of the overall operation: `Set`, `Test`, or `Export`. - [executionType][03] defines whether DSC actually applied an operation to the configuration or was run in `WhatIf` mode. This property is always `Actual` for `Get`, `Test`, and `Export` - operations. For `Set` operations, this value is `WhatIf` when DSC is invoked with the `--whatIf` + operations. For `Set` operations, this value is `WhatIf` when DSC is invoked with the `--what-if` argument. - [startDatetime][04] defines the start date and time for the DSC operation as a timestamp following the format defined in [RFC3339, section 5.6 (see `date-time`)][05], like diff --git a/docs/reference/schemas/outputs/resource/list.md b/docs/reference/schemas/outputs/resource/list.md index 42069bfa..6970ffb6 100644 --- a/docs/reference/schemas/outputs/resource/list.md +++ b/docs/reference/schemas/outputs/resource/list.md @@ -124,6 +124,10 @@ The following list describes the available capabilities for a resource: resource. A resource has this capability when it defines the [export][17] property in its resource manifest. Only resources with this capability are usable with the [dsc resource export][18] and [dsc config export][19] commands. +- <a id="capability-resolve" /> `Resolve` - The resource supports resolving nested resource + instances from an external source. A resource has this capability when it defines the + [resolve][20] property in its resource manifest. This functionality is primarily used by + [importer resources][21]. ```yaml Type: array @@ -211,7 +215,7 @@ Required: true Represents the values defined in the resource's manifest. This value is `null` for resources that aren't command-based. For more information on the value for this property, see -[Command-based DSC Resource manifest schema reference][20]. +[Command-based DSC Resource manifest schema reference][22]. ```yaml Type: [object, 'null'] @@ -238,4 +242,6 @@ Required: true [17]: ../../resource/manifest/export.md [18]: ../../../cli/resource/export.md [19]: ../../../cli/config/export.md -[20]: ../../resource/manifest/root.md +[20]: ../../resource/manifest/resolve.md +[21]: ../../definitions/resourceKind.md#importer-resources +[22]: ../../resource/manifest/root.md diff --git a/docs/reference/schemas/resource/manifest/resolve.md b/docs/reference/schemas/resource/manifest/resolve.md new file mode 100644 index 00000000..99b2c617 --- /dev/null +++ b/docs/reference/schemas/resource/manifest/resolve.md @@ -0,0 +1,160 @@ +--- +description: JSON schema reference for the 'resolve' property in a DSC Resource manifest +ms.date: 01/17/2024 +ms.topic: reference +title: DSC Resource manifest resolve property schema reference +--- + +# DSC Resource manifest resolve property schema reference + +## Synopsis + +Indicates how to call the resource to resolve a nested configuration document from an external +source. + +## Metadata + +```yaml +SchemaDialect: https://json-schema.org/draft/2020-12/schema +SchemaID: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/resource/manifest.resolve.json +Type: object +``` + +## Description + +Defines how DSC must call the DSC Resource to resolve an external source to nested DSC +Configuration Document. Define this method for [importer resources][01] and set the [kind][02] +property in the manifest root to `Import`. + +DSC sends data to the command in three ways: + +1. When `input` is `stdin`, DSC sends the data as a string representing the data as a compressed + JSON object without spaces or newlines between the object properties. +1. When `input` is `env`, DSC sends the data as environment variables. It creates an environment + variable for each property in the input data object, using the name and value of the property. +1. When the `args` array includes a JSON input argument definition, DSC sends the data as a string + representing the data as a compressed JSON object to the specified argument. + +If you don't define the `input` property and don't define a JSON input argument, DSC can't pass the +input JSON to the resource. You can only define one JSON input argument for a command. + +You must define the `input` property, one JSON input argument in the `args` property array, or +both. + +## Required properties + +The `resolve` definition must include these properties: + +- [executable](#executable) + +## Properties + +### executable + +The `executable` property defines the name of the command to run. The value must be the name of a +command discoverable in the system's `PATH` environment variable or the full path to the command. A +file extension is only required when the command isn't recognizable by the operating system as an +executable. + +```yaml +Type: string +Required: true +``` + +### args + +The `args` property defines the list of arguments to pass to the command. The arguments can be any +number of strings. If you want to pass the JSON object representing the property bag for the +resource to an argument, you can define a single item in the array as a [JSON object], indicating the +name of the argument with the `jsonInputArg` string property and whether the argument is mandatory +for the command with the `mandatory` boolean property. + +```yaml +Type: array +Required: false +Default: [] +Type: [string, object(JSON Input Argument)] +``` + +#### String arguments + +Any item in the argument array can be a string representing a static argument to pass to the +command, like `config` or `--format`. + +```yaml +Type: string +``` + +#### JSON input argument + +Defines an argument for the command that accepts the JSON input object as a string. DSC passes the +JSON input to the named argument when available. A JSON input argument is defined as a JSON object +with the following properties: + +- `jsonInputArg` (required) - the argument to pass the JSON data to for the command, like `--input`. +- `mandatory` (optional) - Indicate whether DSC should always pass the argument to the command, + even when there's no JSON input for the command. In that case, DSC passes an empty string to the + JSON input argument. + +You can only define one JSON input argument per arguments array. + +If you define a JSON input argument and an `input` kind for a command, DSC sends the JSON data both +ways: + +- If you define `input` as `env` and a JSON input argument, DSC sets an environment variable for + each property in the JSON input and passes the JSON input object as a string to the defined + argument. +- If you define `input` as `stdin` and a JSON input argument, DSC passes the JSON input over stdin + and as a string to the defined argument. +- If you define a JSON input argument without defining the `input` property, DSC only passes the + JSON input as a string to the defined argument. + +If you don't define the `input` property and don't define a JSON input argument, DSC can't pass the +input JSON to the resource. This makes the manifest invalid. You must define the `input` property, +a JSON input argument in the `args` property array, or both. + +```yaml +Type: object +RequiredProperties: [jsonInputArg] +``` + +### input + +The `input` property defines how to pass input to the resource. If this property isn't defined and +the definition doesn't define a [JSON input argument](#json-input-argument), DSC doesn't send any +input to the resource when invoking the `resolve` operation. + +The value of this property must be one of the following strings: + +- `env` - Indicates that the resource expects the properties of an instance to be specified as + environment variables with the same names and casing. + + This option only supports the following data types for instance properties: + + - `boolean` + - `integer` + - `number` + - `string` + - `array` of `integer` values + - `array` of `number` values + - `array` of `string` values + + For non-array values, DSC sets the environment variable to the specified value as-is. When the + data type is an array of values, DSC sets the environment variable as a comma-delimited string. + For example, the property `foo` with a value of `[1, 2, 3]` is saved in the `foo` environment + variable as `"1,2,3"`. + + If the resource needs to support complex properties with an `object` value or multi-type arrays, + set this to `stdin` instead. +- `stdin` - Indicates that the resource expects a JSON blob representing an instance from `stdin`. + The JSON must adhere to the instance schema for the resource. + +```yaml +Type: string +Required: false +ValidValues: [env, stdin] +``` + +<!-- Link reference definitions --> +[01]: ../../definitions/resourceKind.md#importer-resources +[02]: ./root.md#kind diff --git a/docs/reference/schemas/resource/manifest/root.md b/docs/reference/schemas/resource/manifest/root.md index 7e218956..46a75c3c 100644 --- a/docs/reference/schemas/resource/manifest/root.md +++ b/docs/reference/schemas/resource/manifest/root.md @@ -277,7 +277,7 @@ DSC interprets exit code `0` as a successful operation and any other exit code a ```yaml Type: object Required: false -PropertyNamePattern: ^[0-9]+# +PropertyNamePattern: ^-?[0-9]+# PropertyValueType: string ``` diff --git a/schemas/2024/04/bundled/outputs/resource/list.json b/schemas/2024/04/bundled/outputs/resource/list.json index 7e9d40b2..c678e738 100644 --- a/schemas/2024/04/bundled/outputs/resource/list.json +++ b/schemas/2024/04/bundled/outputs/resource/list.json @@ -26,7 +26,8 @@ "SetHandlesExist", "Test", "Delete", - "Export" + "Export", + "Resolve" ] } }, @@ -125,7 +126,8 @@ "enum": [ "Resource", "Adapter", - "Group" + "Group", + "Import" ] }, "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/definitions/semver.json": { @@ -146,8 +148,7 @@ "required": [ "$schema", "type", - "version", - "get" + "version" ], "properties": { "$schema": { @@ -211,6 +212,9 @@ "validate": { "$ref": "/PowerShell/DSC/main/schemas/2024/04/resource/manifest.validate.json" }, + "resolve": { + "$ref": "/PowerShell/DSC/main/schemas/2024/04/resource/manifest.resolve.json" + }, "adapter": { "$ref": "/PowerShell/DSC/main/schemas/2024/04/resource/manifest.adapter.json" }, @@ -244,7 +248,48 @@ "schema": { "$ref": "/PowerShell/DSC/main/schemas/2024/04/resource/manifest.schema.json" } - } + }, + "allOf": [ + { + "if": { + "properties": { + "kind": { + "const": "Adapter" + } + }, + "required": [ + "kind" + ] + }, + "then": { + "required": [ + "adapter" + ] + } + }, + { + "if": { + "properties": { + "kind": { + "const": "Import" + } + }, + "required": [ + "kind" + ] + }, + "then": { + "required": [ + "resolve" + ] + }, + "else": { + "required": [ + "get" + ] + } + } + ] }, "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/resource/manifest.get.json": { "$schema": "https://json-schema.org/draft/2020-12/schema", @@ -669,6 +714,73 @@ } ] }, + "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/resource/manifest.resolve.json": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/resource/manifest.resolve.json", + "title": "Resolve method", + "description": "Defines how DSC must call the DSC Resource to resolve a nested configuration document from an external source. Define this method for importer resources where the resource kind is set to `Import`.", + "type": "object", + "required": [ + "executable" + ], + "properties": { + "executable": { + "$ref": "/PowerShell/DSC/main/schemas/2024/04/definitions/commandExecutable.json" + }, + "args": { + "$ref": "/PowerShell/DSC/main/schemas/2024/04/definitions/commandArgs.json" + }, + "input": { + "$ref": "/PowerShell/DSC/main/schemas/2024/04/definitions/inputKind.json" + } + }, + "oneOf": [ + { + "required": [ + "input" + ], + "not": { + "properties": { + "args": { + "contains": { + "type": "object" + } + } + } + } + }, + { + "not": { + "required": [ + "input" + ] + }, + "properties": { + "args": { + "contains": { + "type": "object" + }, + "minContains": 1, + "maxContains": 1 + } + } + }, + { + "required": [ + "input" + ], + "properties": { + "args": { + "contains": { + "type": "object" + }, + "minContains": 1, + "maxContains": 1 + } + } + } + ] + }, "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/resource/manifest.adapter.json": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/resource/manifest.adapter.json", diff --git a/schemas/2024/04/bundled/outputs/resource/list.vscode.json b/schemas/2024/04/bundled/outputs/resource/list.vscode.json index 13476038..b0fa46da 100644 --- a/schemas/2024/04/bundled/outputs/resource/list.vscode.json +++ b/schemas/2024/04/bundled/outputs/resource/list.vscode.json @@ -26,7 +26,8 @@ "SetHandlesExist", "Test", "Delete", - "Export" + "Export", + "Resolve" ] } }, @@ -134,13 +135,15 @@ "enum": [ "Resource", "Adapter", - "Group" + "Group", + "Import" ], "markdownDescription": "***\n[_Online Documentation_][01]\n***\n\nDefines whether the resource is a normal DSC Resource, a group resource, or an adapter\nresource. This property is only required for group resources.\n\nDSC infers the default value for this property based on whether the [adapter][02] property is\ndefined in the manifest:\n\n- If the `adapter` property is defined in the manifest, the default `kind` is `Adapter`.\n- If the `adapter` property is not defined in the manifest, the default `kind` is `Resource`.\n\n[01]: https://learn.microsoft.com/powershell/dsc/reference/schemas/resource/manifest/root?view=dsc-3.0&preserve-view=true#kind\n", "markdownEnumDescriptions": [ "<!-- force a line break -->\n\nIndicates that the manifest is for a standard command-based DSC Resource.\n", "<!-- force a line break -->\n\nIndicates that the manifest is for an adapter resource that enables the use of\nnon-command-based resources with DSC.\n", - "<!-- force a line break -->\n\nIndicates that the manifest is for a group resource that processes an array of nested\nresource instances.\n" + "<!-- force a line break -->\n\nIndicates that the manifest is for a group resource that processes an array of nested\nresource instances.\n", + "<!-- force a line break -->\n\nIndicates that the manifest is for an import resource that resolves an external source to DSC\nresource instances. The resolved instances are processed as nested instances for the import\nresource.\n" ] }, "semver.json": { @@ -257,7 +260,7 @@ "label": " Define a resource", "markdownDescription": "Defines a standard resource that:\n\n- Can get the current state of an instance\n- Can set an instance to the desired state\n- Relies on DSC's synthetic testing to determine whether an instance is in the desired state\n- Defines an embedded JSON schema.", "body": { - "$schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json", + "${escape_dollar:$}schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json", "type": "${1:owner.area.group}/${2:${TM_FILENAME_BASE/^(.*?)[\\.]dsc[\\.]resource/$1/}}", "version": "${3:0.1.0}", "description": "${4:Synopsis for the resource's purpose}", @@ -296,7 +299,7 @@ "label": " Define a resource (group)", "markdownDescription": "Defines a group resource that expects a list of resource instances and operates on them.", "body": { - "$schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json", + "${escape_dollar:$}schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json", "type": "${1:owner.area.group}/${2:${TM_FILENAME_BASE/^(.*?)[\\.]dsc[\\.]resource/$1/}}", "version": "${3:0.1.0}", "description": "${4:Synopsis for the resource's purpose}", @@ -351,7 +354,7 @@ "label": " Define a resource (adapter)", "markdownDescription": "Defines an adapter resource that enables users to define non-command-based DSC Resources in\nthe configuration.", "body": { - "$schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json", + "${escape_dollar:$}schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json", "type": "${1:owner.area.group}/${2:${TM_FILENAME_BASE/^(.*?)[\\.]dsc[\\.]resource/$1/}}", "version": "${3:0.1.0}", "description": "${4:Synopsis for the resource's purpose}", @@ -411,11 +414,42 @@ } } }, + { + "label": " Define a resource (importer)", + "markdownDescription": "Defines an importer resource that can resolve an external source to nested resource\ninstances.", + "body": { + "${escape_dollar:$}schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json", + "type": "${1:owner.area.group}/${2:${TM_FILENAME_BASE/^(.*?)[\\.]dsc[\\.]resource/$1/}}", + "kind": "Import", + "version": "${3:0.1.0}", + "description": "${4:Synopsis for the resource's purpose}", + "resolve": { + "executable": "${5:executable name}", + "args": [ + "${6:argument}" + ], + "input": "${7:stdin}" + }, + "schema": { + "embedded": { + "${escape_dollar:$}schema": "${13|https://json-schema.org/draft/2020-12/schema,https://json-schema.org/draft/2019-09/schema,http://json-schema.org/draft-07/schema#|}", + "type": "object", + "properties": { + "${14:name}": { + "title": "${15:property title}", + "description": "${16:explanation of property purpose and usage}", + "type": "${17|string,integer,number,array,object,null|}" + } + } + } + } + } + }, { "label": " Define a resource (assertion-only)", "markdownDescription": "Defines an assertion resource that can get the current state of an instance but not configure\nit. By default, the resource relies on DSC's synthetic testing feature. If the resource\nimplements the `test` operation itself, define the `test` property.", "body": { - "$schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json", + "${escape_dollar:$}schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json", "type": "${1:owner.area.group}/${2:${TM_FILENAME_BASE/^(.*?)[\\.]dsc[\\.]resource/$1/}}", "version": "${3:0.1.0}", "description": "${4:Synopsis for the resource's purpose}", @@ -446,8 +480,7 @@ "required": [ "$schema", "type", - "version", - "get" + "version" ], "properties": { "$schema": { @@ -527,6 +560,9 @@ "validate": { "$ref": "#/$defs/PowerShell/DSC/main/schemas/2024/04/resource/manifest.validate.json" }, + "resolve": { + "$ref": "#/$defs/PowerShell/DSC/main/schemas/2024/04/resource/manifest.resolve.json" + }, "adapter": { "$ref": "#/$defs/PowerShell/DSC/main/schemas/2024/04/resource/manifest.adapter.json" }, @@ -573,7 +609,48 @@ "schema": { "$ref": "#/$defs/PowerShell/DSC/main/schemas/2024/04/resource/manifest.schema.json" } - } + }, + "allOf": [ + { + "if": { + "properties": { + "kind": { + "const": "Adapter" + } + }, + "required": [ + "kind" + ] + }, + "then": { + "required": [ + "adapter" + ] + } + }, + { + "if": { + "properties": { + "kind": { + "const": "Import" + } + }, + "required": [ + "kind" + ] + }, + "then": { + "required": [ + "resolve" + ] + }, + "else": { + "required": [ + "get" + ] + } + } + ] }, "manifest.get.json": { "$schema": "https://json-schema.org/draft/2020-12/schema", @@ -1259,6 +1336,113 @@ } ] }, + "manifest.resolve.json": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/resource/manifest.resolve.json", + "title": "Resolve method", + "description": "Defines how DSC must call the DSC Resource to resolve a nested configuration document from an external source. Define this method for importer resources where the resource kind is set to `Import`.", + "markdownDescription": "***\n[_Online Documentation_][01]\n***\n\nDefines how DSC must call the DSC Resource to resolve an external source to nested DSC\nConfiguration Document. Define this method for [importer resources][02] and set the [kind][03]\nproperty in the manifest root to `Import`.\n\nDSC sends data to the command in three ways:\n\n1. When `input` is `stdin`, DSC sends the data as a string representing the data as a compressed\n JSON object without spaces or newlines between the object properties.\n1. When `input` is `env`, DSC sends the data as environment variables. It creates an environment\n variable for each property in the input data object, using the name and value of the property.\n1. When the `args` array includes a JSON input argument definition, DSC sends the data as a string\n representing the data as a compressed JSON object to the specified argument.\n\nIf you don't define the `input` property and don't define a JSON input argument, DSC can't pass\nthe input JSON to the resource. You can only define one JSON input argument for a command.\n\nYou must define the `input` property, one JSON input argument in the `args` property array, or\nboth.\n\n[01]: https://learn.microsoft.com/powershell/dsc/reference/schemas/resource/manifest/resolve?view=dsc-3.0&preserve-view=true\n[02]: https://learn.microsoft.com/powershell/dsc/reference/schemas/definitions/resourceKind?view=dsc-3.0&preserve-view=true#importer-resources\n[03]: https://learn.microsoft.com/powershell/dsc/reference/schemas/resource/manifest/root?view=dsc-3.0&preserve-view=true#kind\n", + "type": "object", + "required": [ + "executable" + ], + "properties": { + "executable": { + "$ref": "#/$defs/PowerShell/DSC/main/schemas/2024/04/definitions/commandExecutable.json", + "markdownDescription": "***\n[_Online Documentation_][01]\n***\n\nDefines the name of the command to run. The value must be the name of a command discoverable\nin the system's `PATH` environment variable or the full path to the command. A file extension\nis only required when the command isn't recognizable by the operating system as an\nexecutable.\n\n[01]: https://learn.microsoft.com/powershell/dsc/reference/schemas/resource/manifest/resolve?view=dsc-3.0&preserve-view=true#executable\n" + }, + "args": { + "$ref": "#/$defs/PowerShell/DSC/main/schemas/2024/04/definitions/commandArgs.json", + "markdownDescription": "***\n[_Online Documentation_][01]\n***\n\nDefines an array of strings to pass as arguments to the command. DSC passes the arguments to\nthe command in the order they're specified.\n\nFor example, the given the following definition:\n\n```json\n{\n \"executable\": \"myresource\",\n \"args\": [\"config\", \"resolve\"]\n}\n```\n\nDSC invokes the command for the resource as:\n\n```bash\nmyresource config resolve\n```\n\nIf you want to pass the JSON object representing the property bag for a resource instance to\nan argument, you can define a single item in the array as a JSON object. Indicate the name of\nthe argument with the `jsonInputArg` string property and whether the argument is mandatory\nfor the command with the `mandatory` boolean property.` When the `mandatory` property is\ndefined as `true`, DSC passes an empty string to the argument when no JSON input is\navailable. When the `mandatory` property is undefined or defined as `false`, DSC doesn't pass\nthe argument at all when no JSON input is available. The default value for the `mandatory`\nproperty is `false`.\n\nFor example, given the following definition:\n\n```json\n{\n \"executable\": \"myresource\"\n \"args\": [\n \"config\",\n \"resolve\",\n { \"jsonInputArg\": \"--properties\" }\n ]\n}\n```\n\nDSC invokes the command for the resource as:\n\n```bash\nmyresource config resolve --properties <JSON string of instance properties>\n```\n\n[01]: https://learn.microsoft.com/powershell/dsc/reference/schemas/resource/manifest/resolve?view=dsc-3.0&preserve-view=true#args\n" + }, + "input": { + "$ref": "#/$defs/PowerShell/DSC/main/schemas/2024/04/definitions/inputKind.json", + "markdownDescription": "***\n[_Online Documentation_][01]\n***\n\nDefines how DSC should pass input to the command, either as environment variables or JSON\nover `stdin`. This property is optional when you define an object in the `args` list. If\nyou define a JSON input argument and an `input`, DSC sends the JSON data both ways:\n\n- If you define `input` as `env` and a JSON input argument, DSC sets an environment variable\n for each property in the JSON input and passes the JSON input object as a string to the\n defined argument.\n- If you define `input` as `stdin` and a JSON input argument, DSC passes the JSON input over\n stdin and as a string to the defined argument.\n- If you define a JSON input argument without defining the `input` property, DSC only passes\n the JSON input as a string to the defined argument.\n\nIf you don't define the `input` property and don't define a JSON input argument, DSC can't\npass the input JSON to the resource. This makes the manifest invalid. You must define the\n`input` property, a JSON input argument in the `args` property array, or both.\n\n[01]: https://learn.microsoft.com/powershell/dsc/reference/schemas/resource/manifest/resolve?view=dsc-3.0&preserve-view=true#input\n" + } + }, + "oneOf": [ + { + "required": [ + "input" + ], + "not": { + "properties": { + "args": { + "contains": { + "type": "object" + } + } + } + } + }, + { + "not": { + "required": [ + "input" + ] + }, + "properties": { + "args": { + "errorMessage": "The `resolve` command doesn't define either the `input` property or a JSON input argument, or it defines more than one JSON input argument. If you don't define the `input` property and don't define a JSON input argument, DSC can't pass the input JSON to the resource. You can only define one JSON input argument for a command.\n\nYou must define the `input` property, one JSON input argument in the `args` property array, or both. For more information, see:\n\nhttps://learn.microsoft.com/powershell/dsc/reference/schemas/resource/manifest/resolve?view=dsc-3.0&preserve-view=true", + "contains": { + "type": "object" + }, + "minContains": 1, + "maxContains": 1 + } + } + }, + { + "required": [ + "input" + ], + "properties": { + "args": { + "errorMessage": "You can only specify one JSON input argument for the `resolve` command. Remove the extra JSON input argument. When you use the JSON input argument, DSC sends the full JSON object as a string to the named argument.\n\nFor more information, see:\n\nhttps://learn.microsoft.com/powershell/dsc/reference/schemas/resource/manifest/resolve?view=dsc-3.0&preserve-view=true", + "contains": { + "type": "object" + }, + "minContains": 1, + "maxContains": 1 + } + } + } + ], + "defaultSnippets": [ + { + "label": " Define without arguments", + "markdownDescription": "Define the `resolve` command for the resource when no arguments are required and the JSON\ninput is sent over stdin or as environment variables.\n", + "body": { + "input": "${1|stdin,env|}", + "executable": "${2:executable_name}" + } + }, + { + "label": " Define with string arguments", + "markdownDescription": "Define the `resolve` command for the resource when at least one argument is required and the\nJSON input is sent over stdin or as environment variables.", + "body": { + "input": "${1|stdin,env|}", + "executable": "${2:executable_name}", + "args": [ + "${3:--first-argument}" + ] + } + }, + { + "label": " Define with a JSON input argument", + "markdownDescription": "Define the `resolve` command for the resource where the JSON input is passed as a one-line\nJSON object string to the specified argument.", + "body": { + "executable": "${1:executable_name}", + "args": [ + { + "jsonInputArg": "${2:argument_name}", + "mandatory": "^$3" + } + ] + } + } + ] + }, "manifest.adapter.json": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/resource/manifest.adapter.json", diff --git a/schemas/2024/04/bundled/resource/manifest.json b/schemas/2024/04/bundled/resource/manifest.json index c7c6360f..3ee9da2c 100644 --- a/schemas/2024/04/bundled/resource/manifest.json +++ b/schemas/2024/04/bundled/resource/manifest.json @@ -7,8 +7,7 @@ "required": [ "$schema", "type", - "version", - "get" + "version" ], "properties": { "$schema": { @@ -72,6 +71,9 @@ "validate": { "$ref": "/PowerShell/DSC/main/schemas/2024/04/resource/manifest.validate.json" }, + "resolve": { + "$ref": "/PowerShell/DSC/main/schemas/2024/04/resource/manifest.resolve.json" + }, "adapter": { "$ref": "/PowerShell/DSC/main/schemas/2024/04/resource/manifest.adapter.json" }, @@ -106,6 +108,47 @@ "$ref": "/PowerShell/DSC/main/schemas/2024/04/resource/manifest.schema.json" } }, + "allOf": [ + { + "if": { + "properties": { + "kind": { + "const": "Adapter" + } + }, + "required": [ + "kind" + ] + }, + "then": { + "required": [ + "adapter" + ] + } + }, + { + "if": { + "properties": { + "kind": { + "const": "Import" + } + }, + "required": [ + "kind" + ] + }, + "then": { + "required": [ + "resolve" + ] + }, + "else": { + "required": [ + "get" + ] + } + } + ], "$defs": { "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/definitions/resourceType.json": { "$schema": "https://json-schema.org/draft/2020-12/schema", @@ -133,7 +176,8 @@ "enum": [ "Resource", "Adapter", - "Group" + "Group", + "Import" ] }, "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/resource/manifest.get.json": { @@ -559,6 +603,73 @@ } ] }, + "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/resource/manifest.resolve.json": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/resource/manifest.resolve.json", + "title": "Resolve method", + "description": "Defines how DSC must call the DSC Resource to resolve a nested configuration document from an external source. Define this method for importer resources where the resource kind is set to `Import`.", + "type": "object", + "required": [ + "executable" + ], + "properties": { + "executable": { + "$ref": "/PowerShell/DSC/main/schemas/2024/04/definitions/commandExecutable.json" + }, + "args": { + "$ref": "/PowerShell/DSC/main/schemas/2024/04/definitions/commandArgs.json" + }, + "input": { + "$ref": "/PowerShell/DSC/main/schemas/2024/04/definitions/inputKind.json" + } + }, + "oneOf": [ + { + "required": [ + "input" + ], + "not": { + "properties": { + "args": { + "contains": { + "type": "object" + } + } + } + } + }, + { + "not": { + "required": [ + "input" + ] + }, + "properties": { + "args": { + "contains": { + "type": "object" + }, + "minContains": 1, + "maxContains": 1 + } + } + }, + { + "required": [ + "input" + ], + "properties": { + "args": { + "contains": { + "type": "object" + }, + "minContains": 1, + "maxContains": 1 + } + } + } + ] + }, "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/resource/manifest.adapter.json": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/resource/manifest.adapter.json", diff --git a/schemas/2024/04/bundled/resource/manifest.vscode.json b/schemas/2024/04/bundled/resource/manifest.vscode.json index a7c9bc84..429d5445 100644 --- a/schemas/2024/04/bundled/resource/manifest.vscode.json +++ b/schemas/2024/04/bundled/resource/manifest.vscode.json @@ -9,7 +9,7 @@ "label": " Define a resource", "markdownDescription": "Defines a standard resource that:\n\n- Can get the current state of an instance\n- Can set an instance to the desired state\n- Relies on DSC's synthetic testing to determine whether an instance is in the desired state\n- Defines an embedded JSON schema.", "body": { - "$schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json", + "${escape_dollar:$}schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json", "type": "${1:owner.area.group}/${2:${TM_FILENAME_BASE/^(.*?)[\\.]dsc[\\.]resource/$1/}}", "version": "${3:0.1.0}", "description": "${4:Synopsis for the resource's purpose}", @@ -48,7 +48,7 @@ "label": " Define a resource (group)", "markdownDescription": "Defines a group resource that expects a list of resource instances and operates on them.", "body": { - "$schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json", + "${escape_dollar:$}schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json", "type": "${1:owner.area.group}/${2:${TM_FILENAME_BASE/^(.*?)[\\.]dsc[\\.]resource/$1/}}", "version": "${3:0.1.0}", "description": "${4:Synopsis for the resource's purpose}", @@ -103,7 +103,7 @@ "label": " Define a resource (adapter)", "markdownDescription": "Defines an adapter resource that enables users to define non-command-based DSC Resources in\nthe configuration.", "body": { - "$schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json", + "${escape_dollar:$}schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json", "type": "${1:owner.area.group}/${2:${TM_FILENAME_BASE/^(.*?)[\\.]dsc[\\.]resource/$1/}}", "version": "${3:0.1.0}", "description": "${4:Synopsis for the resource's purpose}", @@ -163,11 +163,42 @@ } } }, + { + "label": " Define a resource (importer)", + "markdownDescription": "Defines an importer resource that can resolve an external source to nested resource\ninstances.", + "body": { + "${escape_dollar:$}schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json", + "type": "${1:owner.area.group}/${2:${TM_FILENAME_BASE/^(.*?)[\\.]dsc[\\.]resource/$1/}}", + "kind": "Import", + "version": "${3:0.1.0}", + "description": "${4:Synopsis for the resource's purpose}", + "resolve": { + "executable": "${5:executable name}", + "args": [ + "${6:argument}" + ], + "input": "${7:stdin}" + }, + "schema": { + "embedded": { + "${escape_dollar:$}schema": "${13|https://json-schema.org/draft/2020-12/schema,https://json-schema.org/draft/2019-09/schema,http://json-schema.org/draft-07/schema#|}", + "type": "object", + "properties": { + "${14:name}": { + "title": "${15:property title}", + "description": "${16:explanation of property purpose and usage}", + "type": "${17|string,integer,number,array,object,null|}" + } + } + } + } + } + }, { "label": " Define a resource (assertion-only)", "markdownDescription": "Defines an assertion resource that can get the current state of an instance but not configure\nit. By default, the resource relies on DSC's synthetic testing feature. If the resource\nimplements the `test` operation itself, define the `test` property.", "body": { - "$schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json", + "${escape_dollar:$}schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json", "type": "${1:owner.area.group}/${2:${TM_FILENAME_BASE/^(.*?)[\\.]dsc[\\.]resource/$1/}}", "version": "${3:0.1.0}", "description": "${4:Synopsis for the resource's purpose}", @@ -198,8 +229,7 @@ "required": [ "$schema", "type", - "version", - "get" + "version" ], "properties": { "$schema": { @@ -279,6 +309,9 @@ "validate": { "$ref": "#/$defs/PowerShell/DSC/main/schemas/2024/04/resource/manifest.validate.json" }, + "resolve": { + "$ref": "#/$defs/PowerShell/DSC/main/schemas/2024/04/resource/manifest.resolve.json" + }, "adapter": { "$ref": "#/$defs/PowerShell/DSC/main/schemas/2024/04/resource/manifest.adapter.json" }, @@ -326,6 +359,47 @@ "$ref": "#/$defs/PowerShell/DSC/main/schemas/2024/04/resource/manifest.schema.json" } }, + "allOf": [ + { + "if": { + "properties": { + "kind": { + "const": "Adapter" + } + }, + "required": [ + "kind" + ] + }, + "then": { + "required": [ + "adapter" + ] + } + }, + { + "if": { + "properties": { + "kind": { + "const": "Import" + } + }, + "required": [ + "kind" + ] + }, + "then": { + "required": [ + "resolve" + ] + }, + "else": { + "required": [ + "get" + ] + } + } + ], "$defs": { "PowerShell": { "DSC": { @@ -363,13 +437,15 @@ "enum": [ "Resource", "Adapter", - "Group" + "Group", + "Import" ], "markdownDescription": "***\n[_Online Documentation_][01]\n***\n\nDefines whether the resource is a normal DSC Resource, a group resource, or an adapter\nresource. This property is only required for group resources.\n\nDSC infers the default value for this property based on whether the [adapter][02] property is\ndefined in the manifest:\n\n- If the `adapter` property is defined in the manifest, the default `kind` is `Adapter`.\n- If the `adapter` property is not defined in the manifest, the default `kind` is `Resource`.\n\n[01]: https://learn.microsoft.com/powershell/dsc/reference/schemas/resource/manifest/root?view=dsc-3.0&preserve-view=true#kind\n", "markdownEnumDescriptions": [ "<!-- force a line break -->\n\nIndicates that the manifest is for a standard command-based DSC Resource.\n", "<!-- force a line break -->\n\nIndicates that the manifest is for an adapter resource that enables the use of\nnon-command-based resources with DSC.\n", - "<!-- force a line break -->\n\nIndicates that the manifest is for a group resource that processes an array of nested\nresource instances.\n" + "<!-- force a line break -->\n\nIndicates that the manifest is for a group resource that processes an array of nested\nresource instances.\n", + "<!-- force a line break -->\n\nIndicates that the manifest is for an import resource that resolves an external source to DSC\nresource instances. The resolved instances are processed as nested instances for the import\nresource.\n" ] }, "commandExecutable.json": { @@ -1149,6 +1225,113 @@ } ] }, + "manifest.resolve.json": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/resource/manifest.resolve.json", + "title": "Resolve method", + "description": "Defines how DSC must call the DSC Resource to resolve a nested configuration document from an external source. Define this method for importer resources where the resource kind is set to `Import`.", + "markdownDescription": "***\n[_Online Documentation_][01]\n***\n\nDefines how DSC must call the DSC Resource to resolve an external source to nested DSC\nConfiguration Document. Define this method for [importer resources][02] and set the [kind][03]\nproperty in the manifest root to `Import`.\n\nDSC sends data to the command in three ways:\n\n1. When `input` is `stdin`, DSC sends the data as a string representing the data as a compressed\n JSON object without spaces or newlines between the object properties.\n1. When `input` is `env`, DSC sends the data as environment variables. It creates an environment\n variable for each property in the input data object, using the name and value of the property.\n1. When the `args` array includes a JSON input argument definition, DSC sends the data as a string\n representing the data as a compressed JSON object to the specified argument.\n\nIf you don't define the `input` property and don't define a JSON input argument, DSC can't pass\nthe input JSON to the resource. You can only define one JSON input argument for a command.\n\nYou must define the `input` property, one JSON input argument in the `args` property array, or\nboth.\n\n[01]: https://learn.microsoft.com/powershell/dsc/reference/schemas/resource/manifest/resolve?view=dsc-3.0&preserve-view=true\n[02]: https://learn.microsoft.com/powershell/dsc/reference/schemas/definitions/resourceKind?view=dsc-3.0&preserve-view=true#importer-resources\n[03]: https://learn.microsoft.com/powershell/dsc/reference/schemas/resource/manifest/root?view=dsc-3.0&preserve-view=true#kind\n", + "type": "object", + "required": [ + "executable" + ], + "properties": { + "executable": { + "$ref": "#/$defs/PowerShell/DSC/main/schemas/2024/04/definitions/commandExecutable.json", + "markdownDescription": "***\n[_Online Documentation_][01]\n***\n\nDefines the name of the command to run. The value must be the name of a command discoverable\nin the system's `PATH` environment variable or the full path to the command. A file extension\nis only required when the command isn't recognizable by the operating system as an\nexecutable.\n\n[01]: https://learn.microsoft.com/powershell/dsc/reference/schemas/resource/manifest/resolve?view=dsc-3.0&preserve-view=true#executable\n" + }, + "args": { + "$ref": "#/$defs/PowerShell/DSC/main/schemas/2024/04/definitions/commandArgs.json", + "markdownDescription": "***\n[_Online Documentation_][01]\n***\n\nDefines an array of strings to pass as arguments to the command. DSC passes the arguments to\nthe command in the order they're specified.\n\nFor example, the given the following definition:\n\n```json\n{\n \"executable\": \"myresource\",\n \"args\": [\"config\", \"resolve\"]\n}\n```\n\nDSC invokes the command for the resource as:\n\n```bash\nmyresource config resolve\n```\n\nIf you want to pass the JSON object representing the property bag for a resource instance to\nan argument, you can define a single item in the array as a JSON object. Indicate the name of\nthe argument with the `jsonInputArg` string property and whether the argument is mandatory\nfor the command with the `mandatory` boolean property.` When the `mandatory` property is\ndefined as `true`, DSC passes an empty string to the argument when no JSON input is\navailable. When the `mandatory` property is undefined or defined as `false`, DSC doesn't pass\nthe argument at all when no JSON input is available. The default value for the `mandatory`\nproperty is `false`.\n\nFor example, given the following definition:\n\n```json\n{\n \"executable\": \"myresource\"\n \"args\": [\n \"config\",\n \"resolve\",\n { \"jsonInputArg\": \"--properties\" }\n ]\n}\n```\n\nDSC invokes the command for the resource as:\n\n```bash\nmyresource config resolve --properties <JSON string of instance properties>\n```\n\n[01]: https://learn.microsoft.com/powershell/dsc/reference/schemas/resource/manifest/resolve?view=dsc-3.0&preserve-view=true#args\n" + }, + "input": { + "$ref": "#/$defs/PowerShell/DSC/main/schemas/2024/04/definitions/inputKind.json", + "markdownDescription": "***\n[_Online Documentation_][01]\n***\n\nDefines how DSC should pass input to the command, either as environment variables or JSON\nover `stdin`. This property is optional when you define an object in the `args` list. If\nyou define a JSON input argument and an `input`, DSC sends the JSON data both ways:\n\n- If you define `input` as `env` and a JSON input argument, DSC sets an environment variable\n for each property in the JSON input and passes the JSON input object as a string to the\n defined argument.\n- If you define `input` as `stdin` and a JSON input argument, DSC passes the JSON input over\n stdin and as a string to the defined argument.\n- If you define a JSON input argument without defining the `input` property, DSC only passes\n the JSON input as a string to the defined argument.\n\nIf you don't define the `input` property and don't define a JSON input argument, DSC can't\npass the input JSON to the resource. This makes the manifest invalid. You must define the\n`input` property, a JSON input argument in the `args` property array, or both.\n\n[01]: https://learn.microsoft.com/powershell/dsc/reference/schemas/resource/manifest/resolve?view=dsc-3.0&preserve-view=true#input\n" + } + }, + "oneOf": [ + { + "required": [ + "input" + ], + "not": { + "properties": { + "args": { + "contains": { + "type": "object" + } + } + } + } + }, + { + "not": { + "required": [ + "input" + ] + }, + "properties": { + "args": { + "errorMessage": "The `resolve` command doesn't define either the `input` property or a JSON input argument, or it defines more than one JSON input argument. If you don't define the `input` property and don't define a JSON input argument, DSC can't pass the input JSON to the resource. You can only define one JSON input argument for a command.\n\nYou must define the `input` property, one JSON input argument in the `args` property array, or both. For more information, see:\n\nhttps://learn.microsoft.com/powershell/dsc/reference/schemas/resource/manifest/resolve?view=dsc-3.0&preserve-view=true", + "contains": { + "type": "object" + }, + "minContains": 1, + "maxContains": 1 + } + } + }, + { + "required": [ + "input" + ], + "properties": { + "args": { + "errorMessage": "You can only specify one JSON input argument for the `resolve` command. Remove the extra JSON input argument. When you use the JSON input argument, DSC sends the full JSON object as a string to the named argument.\n\nFor more information, see:\n\nhttps://learn.microsoft.com/powershell/dsc/reference/schemas/resource/manifest/resolve?view=dsc-3.0&preserve-view=true", + "contains": { + "type": "object" + }, + "minContains": 1, + "maxContains": 1 + } + } + } + ], + "defaultSnippets": [ + { + "label": " Define without arguments", + "markdownDescription": "Define the `resolve` command for the resource when no arguments are required and the JSON\ninput is sent over stdin or as environment variables.\n", + "body": { + "input": "${1|stdin,env|}", + "executable": "${2:executable_name}" + } + }, + { + "label": " Define with string arguments", + "markdownDescription": "Define the `resolve` command for the resource when at least one argument is required and the\nJSON input is sent over stdin or as environment variables.", + "body": { + "input": "${1|stdin,env|}", + "executable": "${2:executable_name}", + "args": [ + "${3:--first-argument}" + ] + } + }, + { + "label": " Define with a JSON input argument", + "markdownDescription": "Define the `resolve` command for the resource where the JSON input is passed as a one-line\nJSON object string to the specified argument.", + "body": { + "executable": "${1:executable_name}", + "args": [ + { + "jsonInputArg": "${2:argument_name}", + "mandatory": "^$3" + } + ] + } + } + ] + }, "manifest.adapter.json": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/resource/manifest.adapter.json", diff --git a/schemas/2024/04/definitions/resourceKind.json b/schemas/2024/04/definitions/resourceKind.json index 0ec0e0ca..29aad8a9 100644 --- a/schemas/2024/04/definitions/resourceKind.json +++ b/schemas/2024/04/definitions/resourceKind.json @@ -7,6 +7,7 @@ "enum": [ "Resource", "Adapter", - "Group" + "Group", + "Import" ] } diff --git a/schemas/2024/04/outputs/resource/list.json b/schemas/2024/04/outputs/resource/list.json index 87df8d73..e9f63bbd 100644 --- a/schemas/2024/04/outputs/resource/list.json +++ b/schemas/2024/04/outputs/resource/list.json @@ -26,7 +26,8 @@ "SetHandlesExist", "Test", "Delete", - "Export" + "Export", + "Resolve" ] } }, diff --git a/schemas/2024/04/resource/manifest.json b/schemas/2024/04/resource/manifest.json index cd75fe21..ddfd2cee 100644 --- a/schemas/2024/04/resource/manifest.json +++ b/schemas/2024/04/resource/manifest.json @@ -7,8 +7,7 @@ "required": [ "$schema", "type", - "version", - "get" + "version" ], "properties": { "$schema": { @@ -72,6 +71,9 @@ "validate": { "$ref": "/PowerShell/DSC/main/schemas/2024/04/resource/manifest.validate.json" }, + "resolve": { + "$ref": "/PowerShell/DSC/main/schemas/2024/04/resource/manifest.resolve.json" + }, "adapter": { "$ref": "/PowerShell/DSC/main/schemas/2024/04/resource/manifest.adapter.json" }, @@ -105,5 +107,46 @@ "schema": { "$ref": "/PowerShell/DSC/main/schemas/2024/04/resource/manifest.schema.json" } - } + }, + "allOf": [ + { + "if": { + "properties": { + "kind": { + "const": "Adapter" + } + }, + "required": [ + "kind" + ] + }, + "then": { + "required": [ + "adapter" + ] + } + }, + { + "if": { + "properties": { + "kind": { + "const": "Import" + } + }, + "required": [ + "kind" + ] + }, + "then": { + "required": [ + "resolve" + ] + }, + "else": { + "required": [ + "get" + ] + } + } + ] } diff --git a/schemas/2024/04/resource/manifest.resolve.json b/schemas/2024/04/resource/manifest.resolve.json new file mode 100644 index 00000000..823b37cd --- /dev/null +++ b/schemas/2024/04/resource/manifest.resolve.json @@ -0,0 +1,67 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/resource/manifest.resolve.json", + "title": "Resolve method", + "description": "Defines how DSC must call the DSC Resource to resolve a nested configuration document from an external source. Define this method for importer resources where the resource kind is set to `Import`.", + "type": "object", + "required": [ + "executable" + ], + "properties": { + "executable": { + "$ref": "/PowerShell/DSC/main/schemas/2024/04/definitions/commandExecutable.json" + }, + "args": { + "$ref": "/PowerShell/DSC/main/schemas/2024/04/definitions/commandArgs.json" + }, + "input": { + "$ref": "/PowerShell/DSC/main/schemas/2024/04/definitions/inputKind.json" + } + }, + "oneOf": [ + { + "required": [ + "input" + ], + "not": { + "properties": { + "args": { + "contains": { + "type": "object" + } + } + } + } + }, + { + "not": { + "required": [ + "input" + ] + }, + "properties": { + "args": { + "contains": { + "type": "object" + }, + "minContains": 1, + "maxContains": 1 + } + } + }, + { + "required": [ + "input" + ], + "properties": { + "args": { + "contains": { + "type": "object" + }, + "minContains": 1, + "maxContains": 1 + } + } + } + ] +} diff --git a/schemas/src/definitions/resourceKind.yaml b/schemas/src/definitions/resourceKind.yaml index 0de1645b..953b0760 100644 --- a/schemas/src/definitions/resourceKind.yaml +++ b/schemas/src/definitions/resourceKind.yaml @@ -12,6 +12,7 @@ enum: - Resource - Adapter - Group + - Import # VS Code only @@ -46,3 +47,9 @@ markdownEnumDescriptions: Indicates that the manifest is for a group resource that processes an array of nested resource instances. + - | # Import + <!-- force a line break --> + + Indicates that the manifest is for an import resource that resolves an external source to DSC + resource instances. The resolved instances are processed as nested instances for the import + resource. diff --git a/schemas/src/outputs/resource/list.yaml b/schemas/src/outputs/resource/list.yaml index 588ad43a..ac7e558a 100644 --- a/schemas/src/outputs/resource/list.yaml +++ b/schemas/src/outputs/resource/list.yaml @@ -37,6 +37,7 @@ properties: - Test - Delete - Export + - Resolve description: title: Resource Description description: >- diff --git a/schemas/src/resource/manifest.resolve.yaml b/schemas/src/resource/manifest.resolve.yaml new file mode 100644 index 00000000..a856dd65 --- /dev/null +++ b/schemas/src/resource/manifest.resolve.yaml @@ -0,0 +1,203 @@ +# yaml-language-server: $schema=https://json-schema.org/draft/2020-12/schema +$schema: https://json-schema.org/draft/2020-12/schema +$id: <HOST>/<PREFIX>/<VERSION>/resource/manifest.resolve.yaml + +title: Resolve method +description: >- + Defines how DSC must call the DSC Resource to resolve a nested configuration document from an + external source. Define this method for importer resources where the resource kind is set to + `Import`. + +markdownDescription: | # VS Code only + *** + [_Online Documentation_][01] + *** + + Defines how DSC must call the DSC Resource to resolve an external source to nested DSC + Configuration Document. Define this method for [importer resources][02] and set the [kind][03] + property in the manifest root to `Import`. + + DSC sends data to the command in three ways: + + 1. When `input` is `stdin`, DSC sends the data as a string representing the data as a compressed + JSON object without spaces or newlines between the object properties. + 1. When `input` is `env`, DSC sends the data as environment variables. It creates an environment + variable for each property in the input data object, using the name and value of the property. + 1. When the `args` array includes a JSON input argument definition, DSC sends the data as a string + representing the data as a compressed JSON object to the specified argument. + + If you don't define the `input` property and don't define a JSON input argument, DSC can't pass + the input JSON to the resource. You can only define one JSON input argument for a command. + + You must define the `input` property, one JSON input argument in the `args` property array, or + both. + + [01]: <DOCS_BASE_URL>/reference/schemas/resource/manifest/resolve?<DOCS_VERSION_PIN> + [02]: <DOCS_BASE_URL>/reference/schemas/definitions/resourceKind?<DOCS_VERSION_PIN>#importer-resources + [03]: <DOCS_BASE_URL>/reference/schemas/resource/manifest/root?<DOCS_VERSION_PIN>#kind + +type: object +required: + - executable +properties: + executable: + $ref: /<PREFIX>/<VERSION>/definitions/commandExecutable.yaml + markdownDescription: | + *** + [_Online Documentation_][01] + *** + + Defines the name of the command to run. The value must be the name of a command discoverable + in the system's `PATH` environment variable or the full path to the command. A file extension + is only required when the command isn't recognizable by the operating system as an + executable. + + [01]: <DOCS_BASE_URL>/reference/schemas/resource/manifest/resolve?<DOCS_VERSION_PIN>#executable + args: + $ref: /<PREFIX>/<VERSION>/definitions/commandArgs.yaml + markdownDescription: | + *** + [_Online Documentation_][01] + *** + + Defines an array of strings to pass as arguments to the command. DSC passes the arguments to + the command in the order they're specified. + + For example, the given the following definition: + + ```json + { + "executable": "myresource", + "args": ["config", "resolve"] + } + ``` + + DSC invokes the command for the resource as: + + ```bash + myresource config resolve + ``` + + If you want to pass the JSON object representing the property bag for a resource instance to + an argument, you can define a single item in the array as a JSON object. Indicate the name of + the argument with the `jsonInputArg` string property and whether the argument is mandatory + for the command with the `mandatory` boolean property.` When the `mandatory` property is + defined as `true`, DSC passes an empty string to the argument when no JSON input is + available. When the `mandatory` property is undefined or defined as `false`, DSC doesn't pass + the argument at all when no JSON input is available. The default value for the `mandatory` + property is `false`. + + For example, given the following definition: + + ```json + { + "executable": "myresource" + "args": [ + "config", + "resolve", + { "jsonInputArg": "--properties" } + ] + } + ``` + + DSC invokes the command for the resource as: + + ```bash + myresource config resolve --properties <JSON string of instance properties> + ``` + + [01]: <DOCS_BASE_URL>/reference/schemas/resource/manifest/resolve?<DOCS_VERSION_PIN>#args + input: + $ref: /<PREFIX>/<VERSION>/definitions/inputKind.yaml + markdownDescription: | + *** + [_Online Documentation_][01] + *** + + Defines how DSC should pass input to the command, either as environment variables or JSON + over `stdin`. This property is optional when you define an object in the `args` list. If + you define a JSON input argument and an `input`, DSC sends the JSON data both ways: + + - If you define `input` as `env` and a JSON input argument, DSC sets an environment variable + for each property in the JSON input and passes the JSON input object as a string to the + defined argument. + - If you define `input` as `stdin` and a JSON input argument, DSC passes the JSON input over + stdin and as a string to the defined argument. + - If you define a JSON input argument without defining the `input` property, DSC only passes + the JSON input as a string to the defined argument. + + If you don't define the `input` property and don't define a JSON input argument, DSC can't + pass the input JSON to the resource. This makes the manifest invalid. You must define the + `input` property, a JSON input argument in the `args` property array, or both. + + [01]: <DOCS_BASE_URL>/reference/schemas/resource/manifest/resolve?<DOCS_VERSION_PIN>#input + +# Need to use a oneOf with three possibilities because YAML extension in VS Code doesn't understand +# minContains - so we can't use a single if/else/then. Note that JSON, but not YAML, will fail when +# the manifest defines more than one JSON input argument. If/when the YAML extension is updated to +# support 2019-09 and later, we can simplify this to two schemas. +# +# We use long lines for error messages, which can't use Markdown. +oneOf: + - # Resolve command with explicit input kind - when `input` is defined and `args` is only strings. + # This subschema never triggers an error in testing. + required: [input] + not: + properties: { args: { contains: { type: object } } } + - # Resolve command with JSON input argument - when `input` isn't defined and `args` doesn't include + # a JSON input argument. Only raises an error when `args` has zero JSON input arguments or more + # than one. + not: { required: [input] } + properties: + args: + errorMessage: |- + The `resolve` command doesn't define either the `input` property or a JSON input argument, or it defines more than one JSON input argument. If you don't define the `input` property and don't define a JSON input argument, DSC can't pass the input JSON to the resource. You can only define one JSON input argument for a command. + + You must define the `input` property, one JSON input argument in the `args` property array, or both. For more information, see: + + <DOCS_BASE_URL>/reference/schemas/resource/manifest/resolve?<DOCS_VERSION_PIN> + contains: { type: object } + minContains: 1 + maxContains: 1 + - # Resolve command with explicit input kind and JSON input argument - when `input` is defined and + # args includes a JSON input argument. Only raises an error when `input` is defined and `args` + # contains more than one JSON input argument. + required: [input] + properties: + args: + errorMessage: |- + You can only specify one JSON input argument for the `resolve` command. Remove the extra JSON input argument. When you use the JSON input argument, DSC sends the full JSON object as a string to the named argument. + + For more information, see: + + <DOCS_BASE_URL>/reference/schemas/resource/manifest/resolve?<DOCS_VERSION_PIN> + contains: { type: object } + minContains: 1 + maxContains: 1 + +defaultSnippets: # VS Code only + - label: ' Define without arguments' + markdownDescription: | + Define the `resolve` command for the resource when no arguments are required and the JSON + input is sent over stdin or as environment variables. + body: + input: ${1|stdin,env|} + executable: ${2:executable_name} + - label: ' Define with string arguments' + markdownDescription: |- + Define the `resolve` command for the resource when at least one argument is required and the + JSON input is sent over stdin or as environment variables. + body: + input: ${1|stdin,env|} + executable: ${2:executable_name} + args: + - ${3:--first-argument} + - label: ' Define with a JSON input argument' + markdownDescription: |- + Define the `resolve` command for the resource where the JSON input is passed as a one-line + JSON object string to the specified argument. + body: + executable: ${1:executable_name} + args: + - jsonInputArg: ${2:argument_name} + mandatory: ^$3 diff --git a/schemas/src/resource/manifest.yaml b/schemas/src/resource/manifest.yaml index 3b09122d..11899107 100644 --- a/schemas/src/resource/manifest.yaml +++ b/schemas/src/resource/manifest.yaml @@ -30,10 +30,10 @@ defaultSnippets: - Relies on DSC's synthetic testing to determine whether an instance is in the desired state - Defines an embedded JSON schema. body: - $schema: <HOST>/<PREFIX>/<VERSION>/bundled/resource/manifest.yaml - type: '${1:owner.area.group}/${2:${TM_FILENAME_BASE/^(.*?)[\.]dsc[\.]resource/$1/}}' - version: '${3:0.1.0}' - description: ${4:Synopsis for the resource's purpose} + ${escape_dollar:$}schema: <HOST>/<PREFIX>/<VERSION>/bundled/resource/manifest.yaml + type: '${1:owner.area.group}/${2:${TM_FILENAME_BASE/^(.*?)[\.]dsc[\.]resource/$1/}}' + version: '${3:0.1.0}' + description: ${4:Synopsis for the resource's purpose} get: executable: ${5:executable name} args: ['${6:argument}'] @@ -58,10 +58,10 @@ defaultSnippets: markdownDescription: |- Defines a group resource that expects a list of resource instances and operates on them. body: - $schema: <HOST>/<PREFIX>/<VERSION>/bundled/resource/manifest.yaml - type: '${1:owner.area.group}/${2:${TM_FILENAME_BASE/^(.*?)[\.]dsc[\.]resource/$1/}}' - version: '${3:0.1.0}' - description: ${4:Synopsis for the resource's purpose} + ${escape_dollar:$}schema: <HOST>/<PREFIX>/<VERSION>/bundled/resource/manifest.yaml + type: '${1:owner.area.group}/${2:${TM_FILENAME_BASE/^(.*?)[\.]dsc[\.]resource/$1/}}' + version: '${3:0.1.0}' + description: ${4:Synopsis for the resource's purpose} get: executable: ${5:executable name} args: ['${6:argument}'] @@ -98,10 +98,10 @@ defaultSnippets: Defines an adapter resource that enables users to define non-command-based DSC Resources in the configuration. body: - $schema: <HOST>/<PREFIX>/<VERSION>/bundled/resource/manifest.yaml - type: '${1:owner.area.group}/${2:${TM_FILENAME_BASE/^(.*?)[\.]dsc[\.]resource/$1/}}' - version: '${3:0.1.0}' - description: ${4:Synopsis for the resource's purpose} + ${escape_dollar:$}schema: <HOST>/<PREFIX>/<VERSION>/bundled/resource/manifest.yaml + type: '${1:owner.area.group}/${2:${TM_FILENAME_BASE/^(.*?)[\.]dsc[\.]resource/$1/}}' + version: '${3:0.1.0}' + description: ${4:Synopsis for the resource's purpose} get: executable: ${5:executable name} args: ['${6:argument}'] @@ -138,16 +138,40 @@ defaultSnippets: description: ${28:explanation of property purpose and usage} type: ${29|string,integer,number,array,object,null|} + - label: ' Define a resource (importer)' + markdownDescription: |- + Defines an importer resource that can resolve an external source to nested resource + instances. + body: + ${escape_dollar:$}schema: <HOST>/<PREFIX>/<VERSION>/bundled/resource/manifest.yaml + type: '${1:owner.area.group}/${2:${TM_FILENAME_BASE/^(.*?)[\.]dsc[\.]resource/$1/}}' + kind: Import + version: '${3:0.1.0}' + description: ${4:Synopsis for the resource's purpose} + resolve: + executable: ${5:executable name} + args: ['${6:argument}'] + input: ${7:stdin} + schema: + embedded: + ${escape_dollar:$}schema: ${13|https://json-schema.org/draft/2020-12/schema,https://json-schema.org/draft/2019-09/schema,http://json-schema.org/draft-07/schema#|} + type: object + properties: + ${14:name}: + title: ${15:property title} + description: ${16:explanation of property purpose and usage} + type: ${17|string,integer,number,array,object,null|} + - label: ' Define a resource (assertion-only)' markdownDescription: |- Defines an assertion resource that can get the current state of an instance but not configure it. By default, the resource relies on DSC's synthetic testing feature. If the resource implements the `test` operation itself, define the `test` property. body: - $schema: <HOST>/<PREFIX>/<VERSION>/bundled/resource/manifest.yaml - type: '${1:owner.area.group}/${2:${TM_FILENAME_BASE/^(.*?)[\.]dsc[\.]resource/$1/}}' - version: '${3:0.1.0}' - description: ${4:Synopsis for the resource's purpose} + ${escape_dollar:$}schema: <HOST>/<PREFIX>/<VERSION>/bundled/resource/manifest.yaml + type: '${1:owner.area.group}/${2:${TM_FILENAME_BASE/^(.*?)[\.]dsc[\.]resource/$1/}}' + version: '${3:0.1.0}' + description: ${4:Synopsis for the resource's purpose} get: executable: ${5:executable name} args: ['${6:argument}'] @@ -167,7 +191,6 @@ required: - $schema - type - version - - get properties: $schema: title: Manifest Schema @@ -430,6 +453,8 @@ properties: $ref: /<PREFIX>/<VERSION>/resource/manifest.export.yaml validate: $ref: /<PREFIX>/<VERSION>/resource/manifest.validate.yaml + resolve: + $ref: /<PREFIX>/<VERSION>/resource/manifest.resolve.yaml adapter: $ref: /<PREFIX>/<VERSION>/resource/manifest.adapter.yaml exitCodes: @@ -488,3 +513,19 @@ properties: ${3:second exit code number}: ${4:second exit code meaning} schema: $ref: /<PREFIX>/<VERSION>/resource/manifest.schema.yaml + +allOf: + # Adapter resources must define the adapter command + - if: + properties: { kind: { const: Adapter } } + required: [kind] + then: + required: [adapter] + # Importer resources must define resolve, all others must define get + - if: + properties: { kind: { const: Import } } + required: [kind] + then: + required: [resolve] + else: + required: [get] \ No newline at end of file