Add functions for configuration data handling and extend template merging capabilities

This commit is contained in:
Torsten Brendgen
2026-07-03 10:34:27 +02:00
parent 735bfc9f61
commit fcbe61902f
8 changed files with 408 additions and 76 deletions

View 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
}

View 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)
}

View 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)
}

View 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
}

View 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
}

View 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)
}