Add functions for configuration data handling and extend template merging capabilities
This commit is contained in:
22
Private/Get-ConfigurationDataDictionaryValue.ps1
Normal file
22
Private/Get-ConfigurationDataDictionaryValue.ps1
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
function Get-ConfigurationDataDictionaryValue {
|
||||||
|
[CmdletBinding()]
|
||||||
|
Param(
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[System.Collections.IDictionary]
|
||||||
|
$Dictionary,
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]
|
||||||
|
$Key,
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[AllowNull()]
|
||||||
|
$DefaultValue = $null
|
||||||
|
)
|
||||||
|
|
||||||
|
if(Test-ConfigurationDataDictionaryKey -Dictionary $Dictionary -Key $Key){
|
||||||
|
return $Dictionary[$Key]
|
||||||
|
}
|
||||||
|
|
||||||
|
return $DefaultValue
|
||||||
|
}
|
||||||
31
Private/Get-ConfigurationDataTemplateExtends.ps1
Normal file
31
Private/Get-ConfigurationDataTemplateExtends.ps1
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
function Get-ConfigurationDataTemplateExtends {
|
||||||
|
[CmdletBinding()]
|
||||||
|
Param(
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[System.Collections.IDictionary]
|
||||||
|
$ConfigurationData
|
||||||
|
)
|
||||||
|
|
||||||
|
$Extends = $null
|
||||||
|
|
||||||
|
if(Test-ConfigurationDataDictionaryKey -Dictionary $ConfigurationData -Key "Metadata"){
|
||||||
|
$Metadata = Get-ConfigurationDataDictionaryValue -Dictionary $ConfigurationData -Key "Metadata"
|
||||||
|
if($Metadata -is [System.Collections.IDictionary] -and (Test-ConfigurationDataDictionaryKey -Dictionary $Metadata -Key "Extends")){
|
||||||
|
$Extends = Get-ConfigurationDataDictionaryValue -Dictionary $Metadata -Key "Extends"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($null -eq $Extends -and (Test-ConfigurationDataDictionaryKey -Dictionary $ConfigurationData -Key "Extends")){
|
||||||
|
$Extends = Get-ConfigurationDataDictionaryValue -Dictionary $ConfigurationData -Key "Extends"
|
||||||
|
}
|
||||||
|
|
||||||
|
if($null -eq $Extends){
|
||||||
|
return @()
|
||||||
|
}
|
||||||
|
|
||||||
|
if($Extends -is [System.Array] -and $Extends -isnot [string]){
|
||||||
|
return @($Extends)
|
||||||
|
}
|
||||||
|
|
||||||
|
return @($Extends)
|
||||||
|
}
|
||||||
42
Private/Get-ConfigurationDataTemplateMergeFile.ps1
Normal file
42
Private/Get-ConfigurationDataTemplateMergeFile.ps1
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
function Get-ConfigurationDataTemplateMergeFile {
|
||||||
|
[CmdletBinding()]
|
||||||
|
Param(
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]
|
||||||
|
$Path,
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[hashtable]
|
||||||
|
$Visited = @{}
|
||||||
|
)
|
||||||
|
|
||||||
|
$ResolvedPath = Resolve-ConfigurationDataTemplatePath -Path $Path
|
||||||
|
|
||||||
|
if($Visited.ContainsKey($ResolvedPath)){
|
||||||
|
$Chain = @($Visited.Keys + $ResolvedPath) -join " -> "
|
||||||
|
throw "Circular configuration data template inheritance detected: $Chain"
|
||||||
|
}
|
||||||
|
|
||||||
|
$Visited[$ResolvedPath] = $true
|
||||||
|
|
||||||
|
$ConfigurationData = Import-PowerShellDataFile -Path $ResolvedPath
|
||||||
|
if($ConfigurationData -isnot [System.Collections.IDictionary]){
|
||||||
|
throw "Configuration data template [$ResolvedPath] must contain a hashtable."
|
||||||
|
}
|
||||||
|
|
||||||
|
$Files = @()
|
||||||
|
$BasePath = Split-Path -Path $ResolvedPath -Parent
|
||||||
|
foreach($ParentPath in @(Get-ConfigurationDataTemplateExtends -ConfigurationData $ConfigurationData)){
|
||||||
|
if([string]::IsNullOrWhiteSpace([string]$ParentPath)){
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
$ResolvedParentPath = Resolve-ConfigurationDataTemplatePath -Path ([string]$ParentPath) -BasePath $BasePath
|
||||||
|
$Files += @(Get-ConfigurationDataTemplateMergeFile -Path $ResolvedParentPath -Visited $Visited)
|
||||||
|
}
|
||||||
|
|
||||||
|
$Files += $ResolvedPath
|
||||||
|
$Visited.Remove($ResolvedPath)
|
||||||
|
|
||||||
|
return @($Files)
|
||||||
|
}
|
||||||
49
Private/Merge-ConfigurationDataTemplateFile.ps1
Normal file
49
Private/Merge-ConfigurationDataTemplateFile.ps1
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
function Merge-ConfigurationDataTemplateFile {
|
||||||
|
[CmdletBinding()]
|
||||||
|
Param(
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string[]]
|
||||||
|
$Path,
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[switch]
|
||||||
|
$PassThru
|
||||||
|
)
|
||||||
|
|
||||||
|
$MergeFiles = @()
|
||||||
|
$AddedFiles = @{}
|
||||||
|
|
||||||
|
foreach($Item in $Path){
|
||||||
|
foreach($File in @(Get-ConfigurationDataTemplateMergeFile -Path $Item)){
|
||||||
|
if(-not $AddedFiles.ContainsKey($File)){
|
||||||
|
$MergeFiles += $File
|
||||||
|
$AddedFiles[$File] = $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$MergedConfigurationData = $null
|
||||||
|
foreach($File in $MergeFiles){
|
||||||
|
$TemplateData = Import-PowerShellDataFile -Path $File
|
||||||
|
if($null -eq $MergedConfigurationData){
|
||||||
|
$MergedConfigurationData = Copy-ConfigurationDataValue -Value $TemplateData
|
||||||
|
if($MergedConfigurationData -is [System.Collections.IDictionary] -and (Test-ConfigurationDataDictionaryKey -Dictionary $MergedConfigurationData -Key "Metadata")){
|
||||||
|
$MergedConfigurationData.Remove("Metadata")
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$MergedConfigurationData = Merge-DSCConfigurationData -Template $MergedConfigurationData -Deployment $TemplateData
|
||||||
|
if($MergedConfigurationData -is [System.Collections.IDictionary] -and (Test-ConfigurationDataDictionaryKey -Dictionary $MergedConfigurationData -Key "Metadata")){
|
||||||
|
$MergedConfigurationData.Remove("Metadata")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($PassThru){
|
||||||
|
return [PSCustomObject]@{
|
||||||
|
Files = $MergeFiles
|
||||||
|
ConfigurationData = $MergedConfigurationData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $MergedConfigurationData
|
||||||
|
}
|
||||||
24
Private/Resolve-ConfigurationDataTemplatePath.ps1
Normal file
24
Private/Resolve-ConfigurationDataTemplatePath.ps1
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
function Resolve-ConfigurationDataTemplatePath {
|
||||||
|
[CmdletBinding()]
|
||||||
|
Param(
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]
|
||||||
|
$Path,
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[string]
|
||||||
|
$BasePath = (Get-Location).Path
|
||||||
|
)
|
||||||
|
|
||||||
|
$CandidatePath = $Path
|
||||||
|
if(-not [System.IO.Path]::IsPathRooted($CandidatePath)){
|
||||||
|
$CandidatePath = Join-Path -Path $BasePath -ChildPath $CandidatePath
|
||||||
|
}
|
||||||
|
|
||||||
|
$ResolvedPath = Resolve-Path -Path $CandidatePath -ErrorAction SilentlyContinue
|
||||||
|
if($null -eq $ResolvedPath){
|
||||||
|
throw "Configuration data template [$Path] was not found. Base path [$BasePath]."
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ResolvedPath.ProviderPath
|
||||||
|
}
|
||||||
18
Private/Test-ConfigurationDataDictionaryKey.ps1
Normal file
18
Private/Test-ConfigurationDataDictionaryKey.ps1
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
function Test-ConfigurationDataDictionaryKey {
|
||||||
|
[CmdletBinding()]
|
||||||
|
Param(
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[System.Collections.IDictionary]
|
||||||
|
$Dictionary,
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]
|
||||||
|
$Key
|
||||||
|
)
|
||||||
|
|
||||||
|
if($Dictionary -is [System.Collections.Specialized.OrderedDictionary]){
|
||||||
|
return $Dictionary.Contains($Key)
|
||||||
|
}
|
||||||
|
|
||||||
|
return $Dictionary.ContainsKey($Key)
|
||||||
|
}
|
||||||
@@ -1,47 +1,65 @@
|
|||||||
function Merge-DSCConfigurationData {
|
function Merge-DSCConfigurationData {
|
||||||
[CmdletBinding()]
|
[CmdletBinding(DefaultParameterSetName="Data")]
|
||||||
Param(
|
Param(
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true, ParameterSetName="Data")]
|
||||||
[System.Collections.Hashtable]
|
[System.Collections.IDictionary]
|
||||||
$Template,
|
$Template,
|
||||||
[Parameter(Mandatory=$false)]
|
|
||||||
[System.Collections.Hashtable]
|
[Parameter(Mandatory=$false, ParameterSetName="Data")]
|
||||||
|
[System.Collections.IDictionary]
|
||||||
$Deployment = @{},
|
$Deployment = @{},
|
||||||
[Parameter(Mandatory=$false)]
|
|
||||||
[System.Collections.Hashtable]
|
[Parameter(Mandatory=$false, ParameterSetName="Data")]
|
||||||
$Output
|
[System.Collections.IDictionary]
|
||||||
|
$Output,
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$true, ParameterSetName="Path", ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
|
||||||
|
[Alias("FullName")]
|
||||||
|
[string[]]
|
||||||
|
$Path,
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$false, ParameterSetName="Path")]
|
||||||
|
[switch]
|
||||||
|
$PassThru
|
||||||
)
|
)
|
||||||
|
|
||||||
|
begin {
|
||||||
|
$TemplatePath = @()
|
||||||
|
}
|
||||||
|
|
||||||
|
process {
|
||||||
|
if($PSCmdlet.ParameterSetName -eq "Path"){
|
||||||
|
$TemplatePath += @($Path)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if($Output -eq $null){
|
if($Output -eq $null){
|
||||||
$Output = $Deployment
|
$Output = $Deployment
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($Property in $Template.GetEnumerator()){
|
foreach($Property in $Template.GetEnumerator()){
|
||||||
if($Property.Value -is [System.Collections.Hashtable]){
|
if($Property.Name -eq "Metadata"){
|
||||||
Write-Verbose "Key [$($Property.Name)] is a Hashtable"
|
Write-Verbose "Skipping metadata block during configuration data merge"
|
||||||
if($null -ne $Deployment.$($Property.Name)){
|
continue
|
||||||
Write-Verbose "Key [$($Property.Name)] is present in Deployment Data"
|
|
||||||
$Output.($Property.Name) = Merge-DSCConfigurationData -Template $Template.$($Property.Name) -Deployment $Deployment.$($Property.Name) -Output $Output.$($Property.Name)
|
|
||||||
}else{
|
|
||||||
Write-Verbose "Key [$($Property.Name)] is not present in Deployment Data"
|
|
||||||
$Output.Add($($Property.Name),(Copy-ConfigurationDataValue -Value $Template.$($Property.Name)))
|
|
||||||
}
|
}
|
||||||
}elseif($Property.Value -is [System.Collections.Specialized.OrderedDictionary]){
|
|
||||||
Write-Verbose "Key [$($Property.Name)] is a Ordered Dictionary"
|
if($Property.Value -is [System.Collections.IDictionary]){
|
||||||
if($null -ne $Deployment.$($Property.Name)){
|
Write-Verbose "Key [$($Property.Name)] is a Dictionary"
|
||||||
|
if(Test-ConfigurationDataDictionaryKey -Dictionary $Deployment -Key $Property.Name){
|
||||||
Write-Verbose "Key [$($Property.Name)] is present in Deployment Data"
|
Write-Verbose "Key [$($Property.Name)] is present in Deployment Data"
|
||||||
$Output.($Property.Name) = Merge-DSCConfigurationData -Template $Template.$($Property.Name) -Deployment $Deployment.$($Property.Name) -Output $Output.$($Property.Name)
|
$Output[$Property.Name] = Merge-DSCConfigurationData -Template $Template[$Property.Name] -Deployment $Deployment[$Property.Name] -Output $Output[$Property.Name]
|
||||||
}else{
|
}else{
|
||||||
Write-Verbose "Key [$($Property.Name)] is not present in Deployment Data"
|
Write-Verbose "Key [$($Property.Name)] is not present in Deployment Data"
|
||||||
$Output.Add($($Property.Name),(Copy-ConfigurationDataValue -Value $Template.$($Property.Name)))
|
$Output.Add($Property.Name,(Copy-ConfigurationDataValue -Value $Template[$Property.Name]))
|
||||||
}
|
}
|
||||||
}elseif($Property.Value -is [System.Array]){
|
}elseif($Property.Value -is [System.Array]){
|
||||||
Write-Verbose "$($Property.Name) is ein Array"
|
Write-Verbose "$($Property.Name) is ein Array"
|
||||||
Write-Verbose "Total Items in Template Array [$($Property.Value.Count)]"
|
Write-Verbose "Total Items in Template Array [$($Property.Value.Count)]"
|
||||||
Write-Verbose "Total Items in Deployment Array [$($Deployment.$($Property.Name).Count)]"
|
Write-Verbose "Total Items in Deployment Array [$(@(Get-ConfigurationDataDictionaryValue -Dictionary $Deployment -Key $Property.Name -DefaultValue @()).Count)]"
|
||||||
if($null -ne $Deployment.$($Property.Name)){
|
if(Test-ConfigurationDataDictionaryKey -Dictionary $Deployment -Key $Property.Name){
|
||||||
Write-Verbose "Array is defined in Deployment"
|
Write-Verbose "Array is defined in Deployment"
|
||||||
|
|
||||||
|
$DeploymentArray = Get-ConfigurationDataDictionaryValue -Dictionary $Deployment -Key $Property.Name
|
||||||
$TemplateItems = for($i=0;$i -lt $Property.Value.Count; $i++){
|
$TemplateItems = for($i=0;$i -lt $Property.Value.Count; $i++){
|
||||||
$SearchKeyNames = @(Get-ConfigurationDataArrayMergeKeyNames -ArrayName $Property.Name -Item $Property.Value[$i])
|
$SearchKeyNames = @(Get-ConfigurationDataArrayMergeKeyNames -ArrayName $Property.Name -Item $Property.Value[$i])
|
||||||
[PSCustomObject]@{
|
[PSCustomObject]@{
|
||||||
@@ -58,19 +76,19 @@ function Merge-DSCConfigurationData {
|
|||||||
|
|
||||||
if($SearchKeyNames.Count -eq 0){
|
if($SearchKeyNames.Count -eq 0){
|
||||||
Write-Verbose "No matching name key found for item in [$($Property.Name)]"
|
Write-Verbose "No matching name key found for item in [$($Property.Name)]"
|
||||||
$Output.$($Property.Name) += ,(Copy-ConfigurationDataValue -Value $TemplateItem.Value)
|
$Output[$Property.Name] += ,(Copy-ConfigurationDataValue -Value $TemplateItem.Value)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if($TemplateItem.IsWildcard){
|
if($TemplateItem.IsWildcard){
|
||||||
$MatchingDeploymentItems = @($Deployment.$($Property.Name) | Where-Object { Test-ConfigurationDataItemHasKeys -Item $_ -KeyNames $SearchKeyNames })
|
$MatchingDeploymentItems = @($DeploymentArray | Where-Object { Test-ConfigurationDataItemHasKeys -Item $_ -KeyNames $SearchKeyNames })
|
||||||
}else{
|
}else{
|
||||||
$MatchingDeploymentItems = @($Deployment.$($Property.Name) | Where-Object { Test-ConfigurationDataItemKeyMatch -Left $_ -Right $TemplateItem.Value -KeyNames $SearchKeyNames })
|
$MatchingDeploymentItems = @($DeploymentArray | Where-Object { Test-ConfigurationDataItemKeyMatch -Left $_ -Right $TemplateItem.Value -KeyNames $SearchKeyNames })
|
||||||
}
|
}
|
||||||
|
|
||||||
if($MatchingDeploymentItems.Count -gt 0){
|
if($MatchingDeploymentItems.Count -gt 0){
|
||||||
foreach($DeploymentItem in $MatchingDeploymentItems){
|
foreach($DeploymentItem in $MatchingDeploymentItems){
|
||||||
$OutputItem = @($Output.$($Property.Name) | Where-Object { Test-ConfigurationDataItemKeyMatch -Left $_ -Right $DeploymentItem -KeyNames $SearchKeyNames })[0]
|
$OutputItem = @($Output[$Property.Name] | Where-Object { Test-ConfigurationDataItemKeyMatch -Left $_ -Right $DeploymentItem -KeyNames $SearchKeyNames })[0]
|
||||||
Merge-DSCConfigurationData -Template $TemplateItem.Value -Deployment $DeploymentItem -Output $OutputItem | Out-Null
|
Merge-DSCConfigurationData -Template $TemplateItem.Value -Deployment $DeploymentItem -Output $OutputItem | Out-Null
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
@@ -78,21 +96,29 @@ function Merge-DSCConfigurationData {
|
|||||||
Write-Verbose "Wildcard item [$(Format-ConfigurationDataMergeKey -Item $TemplateItem.Value -KeyNames $SearchKeyNames)] in [$($Property.Name)] matched no deployment items"
|
Write-Verbose "Wildcard item [$(Format-ConfigurationDataMergeKey -Item $TemplateItem.Value -KeyNames $SearchKeyNames)] in [$($Property.Name)] matched no deployment items"
|
||||||
}else{
|
}else{
|
||||||
Write-Verbose "Pair [$(Format-ConfigurationDataMergeKey -Item $TemplateItem.Value -KeyNames $SearchKeyNames)] not present"
|
Write-Verbose "Pair [$(Format-ConfigurationDataMergeKey -Item $TemplateItem.Value -KeyNames $SearchKeyNames)] not present"
|
||||||
$Output.$($Property.Name) += ,(Copy-ConfigurationDataValue -Value $TemplateItem.Value)
|
$Output[$Property.Name] += ,(Copy-ConfigurationDataValue -Value $TemplateItem.Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
Write-Verbose "Array is not defined in Deployment"
|
Write-Verbose "Array is not defined in Deployment"
|
||||||
$Output.$($Property.Name) = Copy-ConfigurationDataValue -Value $Template.$($Property.Name)
|
$Output[$Property.Name] = Copy-ConfigurationDataValue -Value $Template[$Property.Name]
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
Write-Verbose "$($Property.Name) is a String or Integer Value"
|
Write-Verbose "$($Property.Name) is a String or Integer Value"
|
||||||
if($null -eq $Deployment.$($Property.Name)){
|
if(-not (Test-ConfigurationDataDictionaryKey -Dictionary $Deployment -Key $Property.Name)){
|
||||||
$Output.Add($Property.Name,(Copy-ConfigurationDataValue -Value $Template.($Property.Name)))
|
$Output.Add($Property.Name,(Copy-ConfigurationDataValue -Value $Template[$Property.Name]))
|
||||||
}elseif($Deployment.$($Property.Name) -ne $Property.Value){
|
}elseif($Deployment[$Property.Name] -ne $Property.Value){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $Output
|
return $Output
|
||||||
|
}
|
||||||
|
|
||||||
|
end {
|
||||||
|
if($PSCmdlet.ParameterSetName -eq "Path"){
|
||||||
|
return Merge-ConfigurationDataTemplateFile -Path $TemplatePath -PassThru:$PassThru
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
120
Tests/Extends.Tests.ps1
Normal file
120
Tests/Extends.Tests.ps1
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
$script:ModuleRoot = Split-Path -Parent $PSScriptRoot
|
||||||
|
$script:ModuleManifest = Join-Path -Path $script:ModuleRoot -ChildPath 'Merge-DSCConfigurationData.psd1'
|
||||||
|
|
||||||
|
Import-Module $script:ModuleManifest -Force
|
||||||
|
|
||||||
|
Describe 'Merge-DSCConfigurationData Extends' {
|
||||||
|
It 'keeps the existing hashtable merge behavior' {
|
||||||
|
$Template = @{
|
||||||
|
Parameters = @{
|
||||||
|
DomainFQDN = @{
|
||||||
|
Type = 'string'
|
||||||
|
Required = $true
|
||||||
|
DefaultValue = 'example.local'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$Deployment = @{
|
||||||
|
Parameters = @{
|
||||||
|
DomainFQDN = @{
|
||||||
|
Value = 'contoso.local'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$Result = Merge-DSCConfigurationData -Template $Template -Deployment $Deployment
|
||||||
|
|
||||||
|
$Result.Parameters.DomainFQDN.Type | Should Be 'string'
|
||||||
|
$Result.Parameters.DomainFQDN.Required | Should Be $true
|
||||||
|
$Result.Parameters.DomainFQDN.Value | Should Be 'contoso.local'
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'merges a child template with Metadata.Extends' {
|
||||||
|
$DefaultPath = Join-Path -Path $TestDrive -ChildPath 'Default.psd1'
|
||||||
|
$ChildPath = Join-Path -Path $TestDrive -ChildPath 'Contoso.psd1'
|
||||||
|
|
||||||
|
@'
|
||||||
|
@{
|
||||||
|
Metadata = @{
|
||||||
|
TemplateType = 'Environment'
|
||||||
|
Name = 'Default'
|
||||||
|
}
|
||||||
|
Parameters = @{
|
||||||
|
DomainFQDN = @{
|
||||||
|
Type = 'string'
|
||||||
|
Required = $true
|
||||||
|
DefaultValue = 'example.local'
|
||||||
|
}
|
||||||
|
DomainNetBIOS = @{
|
||||||
|
Type = 'string'
|
||||||
|
Required = $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Resources = @{
|
||||||
|
NonNodeData = @{
|
||||||
|
RequiredModules = @(
|
||||||
|
@{
|
||||||
|
Name = 'ActiveDirectoryDsc'
|
||||||
|
Version = '6.7.1'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'@ | Set-Content -Path $DefaultPath -Encoding UTF8
|
||||||
|
|
||||||
|
@'
|
||||||
|
@{
|
||||||
|
Metadata = @{
|
||||||
|
TemplateType = 'Environment'
|
||||||
|
Name = 'Contoso'
|
||||||
|
Extends = './Default.psd1'
|
||||||
|
}
|
||||||
|
Parameters = @{
|
||||||
|
DomainFQDN = @{
|
||||||
|
Value = 'contoso.local'
|
||||||
|
}
|
||||||
|
DomainNetBIOS = @{
|
||||||
|
Value = 'CONTOSO'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'@ | Set-Content -Path $ChildPath -Encoding UTF8
|
||||||
|
|
||||||
|
$Result = Merge-DSCConfigurationData -Path $ChildPath -PassThru
|
||||||
|
|
||||||
|
$Result.Files.Count | Should Be 2
|
||||||
|
[System.IO.Path]::GetFileName($Result.Files[0]) | Should Be 'Default.psd1'
|
||||||
|
[System.IO.Path]::GetFileName($Result.Files[1]) | Should Be 'Contoso.psd1'
|
||||||
|
$Result.ConfigurationData.Parameters.DomainFQDN.Type | Should Be 'string'
|
||||||
|
$Result.ConfigurationData.Parameters.DomainFQDN.Value | Should Be 'contoso.local'
|
||||||
|
$Result.ConfigurationData.Parameters.DomainNetBIOS.Required | Should Be $true
|
||||||
|
$Result.ConfigurationData.Parameters.DomainNetBIOS.Value | Should Be 'CONTOSO'
|
||||||
|
$Result.ConfigurationData.Resources.NonNodeData.RequiredModules[0].Name | Should Be 'ActiveDirectoryDsc'
|
||||||
|
$Result.ConfigurationData.ContainsKey('Metadata') | Should Be $false
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'detects circular Metadata.Extends references' {
|
||||||
|
$APath = Join-Path -Path $TestDrive -ChildPath 'A.psd1'
|
||||||
|
$BPath = Join-Path -Path $TestDrive -ChildPath 'B.psd1'
|
||||||
|
|
||||||
|
@'
|
||||||
|
@{
|
||||||
|
Metadata = @{
|
||||||
|
Extends = './B.psd1'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'@ | Set-Content -Path $APath -Encoding UTF8
|
||||||
|
|
||||||
|
@'
|
||||||
|
@{
|
||||||
|
Metadata = @{
|
||||||
|
Extends = './A.psd1'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'@ | Set-Content -Path $BPath -Encoding UTF8
|
||||||
|
|
||||||
|
{ Merge-DSCConfigurationData -Path $APath } | Should Throw
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user