513 lines
18 KiB
PowerShell
513 lines
18 KiB
PowerShell
$script:ModuleRoot = Split-Path -Path $PSScriptRoot -Parent
|
|
Import-Module (Join-Path -Path $script:ModuleRoot -ChildPath "Resolve-DSCConfigurationData.psd1") -Force
|
|
|
|
Describe "Resolve-DSCConfigurationData" {
|
|
It "resolves parameters using Value before DefaultValue" {
|
|
$ConfigurationData = @{
|
|
Parameters = @{
|
|
Name = @{
|
|
DefaultValue = "Default"
|
|
Value = "Deployment"
|
|
}
|
|
}
|
|
Resources = @{
|
|
Value = "[parameters('Name')]"
|
|
}
|
|
}
|
|
|
|
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
|
|
|
|
$Result.Resources.Value | Should Be "Deployment"
|
|
}
|
|
|
|
It "allows parameter values listed in AllowedValues" {
|
|
$ConfigurationData = @{
|
|
Parameters = @{
|
|
Stage = @{
|
|
Value = "Test"
|
|
AllowedValues = @(
|
|
"Install",
|
|
"Test",
|
|
"Release"
|
|
)
|
|
}
|
|
}
|
|
Resources = @{
|
|
Stage = "[parameters('Stage')]"
|
|
}
|
|
}
|
|
|
|
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
|
|
|
|
$Result.Resources.Stage | Should Be "Test"
|
|
}
|
|
|
|
It "validates DefaultValue against AllowedValues when Value is not set" {
|
|
$ConfigurationData = @{
|
|
Parameters = @{
|
|
Stage = @{
|
|
DefaultValue = "Release"
|
|
AllowedValues = @(
|
|
"Install",
|
|
"Test",
|
|
"Release"
|
|
)
|
|
}
|
|
}
|
|
Resources = @{
|
|
Stage = "[parameters('Stage')]"
|
|
}
|
|
}
|
|
|
|
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
|
|
|
|
$Result.Resources.Stage | Should Be "Release"
|
|
}
|
|
|
|
It "throws when a parameter value is not listed in AllowedValues" {
|
|
$ConfigurationData = @{
|
|
Parameters = @{
|
|
Stage = @{
|
|
Value = "Production"
|
|
AllowedValues = @(
|
|
"Install",
|
|
"Test",
|
|
"Release"
|
|
)
|
|
}
|
|
}
|
|
Resources = @{
|
|
Stage = "[parameters('Stage')]"
|
|
}
|
|
}
|
|
|
|
{ Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData } | Should Throw
|
|
}
|
|
|
|
It "validates array parameter items against AllowedValues" {
|
|
$ConfigurationData = @{
|
|
Parameters = @{
|
|
ServerRoles = @{
|
|
Type = "array"
|
|
Value = @(
|
|
"WebFrontEnd",
|
|
"Application"
|
|
)
|
|
AllowedValues = @(
|
|
"WebFrontEnd",
|
|
"Application",
|
|
"Search"
|
|
)
|
|
}
|
|
}
|
|
Resources = @{
|
|
Roles = "[parameters('ServerRoles')]"
|
|
}
|
|
}
|
|
|
|
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
|
|
|
|
$Result.Resources.Roles[0] | Should Be "WebFrontEnd"
|
|
$Result.Resources.Roles[1] | Should Be "Application"
|
|
}
|
|
|
|
It "throws when an array parameter item is not listed in AllowedValues" {
|
|
$ConfigurationData = @{
|
|
Parameters = @{
|
|
ServerRoles = @{
|
|
Type = "array"
|
|
Value = @(
|
|
"WebFrontEnd",
|
|
"InvalidRole"
|
|
)
|
|
AllowedValues = @(
|
|
"WebFrontEnd",
|
|
"Application",
|
|
"Search"
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
{ Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData } | Should Throw
|
|
}
|
|
|
|
It "validates required parameters" {
|
|
$ConfigurationData = @{
|
|
Parameters = @{
|
|
DatabasePrefix = @{
|
|
Type = "string"
|
|
Required = $true
|
|
}
|
|
}
|
|
}
|
|
|
|
{ Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData } | Should Throw
|
|
}
|
|
|
|
It "validates parameter length constraints" {
|
|
$ConfigurationData = @{
|
|
Parameters = @{
|
|
DatabasePrefix = @{
|
|
Value = "S"
|
|
MinLength = 2
|
|
MaxLength = 10
|
|
}
|
|
}
|
|
}
|
|
|
|
{ Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData } | Should Throw
|
|
}
|
|
|
|
It "validates parameter patterns" {
|
|
$ConfigurationData = @{
|
|
Parameters = @{
|
|
DatabasePrefix = @{
|
|
Value = "Share Point"
|
|
Pattern = "^[A-Za-z][A-Za-z0-9_-]*$"
|
|
}
|
|
}
|
|
}
|
|
|
|
{ Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData } | Should Throw
|
|
}
|
|
|
|
It "validates supported parameter types" {
|
|
$ConfigurationData = @{
|
|
Parameters = @{
|
|
Name = @{
|
|
Type = "string"
|
|
Value = "SharePoint"
|
|
}
|
|
Port = @{
|
|
Type = "int"
|
|
Value = 1433
|
|
}
|
|
Enabled = @{
|
|
Type = "bool"
|
|
Value = $true
|
|
}
|
|
Roles = @{
|
|
Type = "array"
|
|
Value = @(
|
|
"WebFrontEnd",
|
|
"Application"
|
|
)
|
|
}
|
|
SecretReference = @{
|
|
Type = "secureString"
|
|
Value = @{
|
|
SecretName = "SharePointFarmPassphrase"
|
|
}
|
|
Sensitive = $true
|
|
}
|
|
CredentialReference = @{
|
|
Type = "credential"
|
|
Value = @{
|
|
CredentialName = "SharePointSetup"
|
|
}
|
|
Sensitive = $true
|
|
}
|
|
}
|
|
Resources = @{
|
|
Name = "[parameters('Name')]"
|
|
Port = "[parameters('Port')]"
|
|
Enabled = "[parameters('Enabled')]"
|
|
RoleCount = "[length(parameters('Roles'))]"
|
|
}
|
|
}
|
|
|
|
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
|
|
|
|
$Result.Resources.Name | Should Be "SharePoint"
|
|
$Result.Resources.Port | Should Be 1433
|
|
$Result.Resources.Enabled | Should Be $true
|
|
$Result.Resources.RoleCount | Should Be 2
|
|
}
|
|
|
|
It "throws when parameter type validation fails" {
|
|
$ConfigurationData = @{
|
|
Parameters = @{
|
|
Port = @{
|
|
Type = "int"
|
|
Value = "1433"
|
|
}
|
|
}
|
|
}
|
|
|
|
{ Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData } | Should Throw
|
|
}
|
|
|
|
It "validates numeric ranges" {
|
|
$ConfigurationData = @{
|
|
Parameters = @{
|
|
Port = @{
|
|
Type = "int"
|
|
Value = 1433
|
|
MinValue = 1
|
|
MaxValue = 65535
|
|
}
|
|
}
|
|
Resources = @{
|
|
Port = "[parameters('Port')]"
|
|
}
|
|
}
|
|
|
|
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
|
|
|
|
$Result.Resources.Port | Should Be 1433
|
|
}
|
|
|
|
It "throws when numeric range validation fails" {
|
|
$ConfigurationData = @{
|
|
Parameters = @{
|
|
Port = @{
|
|
Type = "int"
|
|
Value = 70000
|
|
MinValue = 1
|
|
MaxValue = 65535
|
|
}
|
|
}
|
|
}
|
|
|
|
{ Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData } | Should Throw
|
|
}
|
|
|
|
It "supports localized deprecated parameter messages" {
|
|
$ConfigurationData = @{
|
|
Parameters = @{
|
|
OldDatabasePrefix = @{
|
|
Value = "SharePoint"
|
|
Deprecated = @{
|
|
Message = @{
|
|
"de-DE" = "Der Parameter [OldDatabasePrefix] ist veraltet. Verwende [DatabasePrefix]."
|
|
"en-US" = "Parameter [OldDatabasePrefix] is deprecated. Use [DatabasePrefix]."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Resources = @{
|
|
Value = "[parameters('OldDatabasePrefix')]"
|
|
}
|
|
}
|
|
|
|
$Warnings = @()
|
|
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData -WarningVariable Warnings 3>$null
|
|
|
|
$Result.Resources.Value | Should Be "SharePoint"
|
|
$Warnings.Count | Should Be 1
|
|
([string]$Warnings[0]) | Should Match "OldDatabasePrefix"
|
|
}
|
|
|
|
It "resolves variables that reference parameters" {
|
|
$ConfigurationData = @{
|
|
Parameters = @{
|
|
Prefix = @{
|
|
Value = "SharePoint"
|
|
}
|
|
}
|
|
Variables = @{
|
|
ConfigDbName = "[concat(parameters('Prefix'), '_Farm_Config')]"
|
|
}
|
|
Resources = @{
|
|
DatabaseName = "[variables('ConfigDbName')]"
|
|
}
|
|
}
|
|
|
|
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
|
|
|
|
$Result.Variables.ConfigDbName | Should Be "SharePoint_Farm_Config"
|
|
$Result.Resources.DatabaseName | Should Be "SharePoint_Farm_Config"
|
|
}
|
|
|
|
It "resolves nested functions" {
|
|
$ConfigurationData = @{
|
|
Parameters = @{
|
|
Prefix = @{
|
|
Value = "sharepoint"
|
|
}
|
|
}
|
|
Resources = @{
|
|
Name = "[concat(toUpper(parameters('Prefix')), '_Services')]"
|
|
}
|
|
}
|
|
|
|
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
|
|
|
|
$Result.Resources.Name | Should Be "SHAREPOINT_Services"
|
|
}
|
|
|
|
It "resolves string helper functions" {
|
|
$ConfigurationData = @{
|
|
Resources = @{
|
|
Lower = "[toLower('BGW-LAN')]"
|
|
Upper = "[toUpper('bgw-lan')]"
|
|
First = "[firstIndexOf('a', 'b', 'c')]"
|
|
Last = "[lastIndexOf('a', 'b', 'c')]"
|
|
Index = "[indexOf('BGW', 1)]"
|
|
Substring = "[substring('SharePoint', 5, 5)]"
|
|
Replace = "[replace('BGW-LAN', '-', '_')]"
|
|
}
|
|
}
|
|
|
|
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
|
|
|
|
$Result.Resources.Lower | Should Be "bgw-lan"
|
|
$Result.Resources.Upper | Should Be "BGW-LAN"
|
|
$Result.Resources.First | Should Be "a"
|
|
$Result.Resources.Last | Should Be "c"
|
|
$Result.Resources.Index | Should Be "G"
|
|
$Result.Resources.Substring | Should Be "Point"
|
|
$Result.Resources.Replace | Should Be "BGW_LAN"
|
|
}
|
|
|
|
It "resolves formatting, fallback, and conditional functions" {
|
|
$ConfigurationData = @{
|
|
Parameters = @{
|
|
DatabasePrefix = @{
|
|
Value = "SharePoint"
|
|
}
|
|
DomainLabel = @{
|
|
Value = "LAN"
|
|
}
|
|
Stage = @{
|
|
Value = "Test"
|
|
}
|
|
OptionalValue = @{
|
|
Value = ""
|
|
}
|
|
}
|
|
Resources = @{
|
|
Formatted = "[format('{0}_{1}_{2}', parameters('DatabasePrefix'), parameters('DomainLabel'), parameters('Stage'))]"
|
|
Fallback = "[coalesce(parameters('OptionalValue'), 'DefaultValue')]"
|
|
Conditional = "[if(equals(parameters('Stage'), 'Test'), 'TST', 'PRD')]"
|
|
NotEquals = "[notEquals(parameters('Stage'), 'Prod')]"
|
|
AndValue = "[and(equals(parameters('Stage'), 'Test'), not(empty(parameters('DatabasePrefix'))))]"
|
|
OrValue = "[or(equals(parameters('Stage'), 'Prod'), equals(parameters('Stage'), 'Test'))]"
|
|
}
|
|
}
|
|
|
|
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
|
|
|
|
$Result.Resources.Formatted | Should Be "SharePoint_LAN_Test"
|
|
$Result.Resources.Fallback | Should Be "DefaultValue"
|
|
$Result.Resources.Conditional | Should Be "TST"
|
|
$Result.Resources.NotEquals | Should Be $true
|
|
$Result.Resources.AndValue | Should Be $true
|
|
$Result.Resources.OrValue | Should Be $true
|
|
}
|
|
|
|
It "resolves collection and string inspection functions" {
|
|
$ConfigurationData = @{
|
|
Parameters = @{
|
|
DomainFQDN = @{
|
|
Value = "bgw-online.de"
|
|
}
|
|
}
|
|
Resources = @{
|
|
Split = "[split(parameters('DomainFQDN'), '.')]"
|
|
Joined = "[join(split(parameters('DomainFQDN'), '.'), '_')]"
|
|
JoinedNotEmpty = "[joinNotEmpty('_', 'SharePoint', '', 'LAN', 'Test', '', 'Services')]"
|
|
Take = "[join(take(split(parameters('DomainFQDN'), '.'), 1), '_')]"
|
|
Skip = "[join(skip(split(parameters('DomainFQDN'), '.'), 1), '_')]"
|
|
First = "[first(split(parameters('DomainFQDN'), '.'))]"
|
|
Last = "[last(split(parameters('DomainFQDN'), '.'))]"
|
|
Unique = "[join(unique(split('SP.SP.SQL', '.')), '_')]"
|
|
Sort = "[join(sort(split('SQL.SP.APP', '.')), '_')]"
|
|
ContainsString = "[contains(parameters('DomainFQDN'), 'online')]"
|
|
ContainsArray = "[contains(split(parameters('DomainFQDN'), '.'), 'de')]"
|
|
StartsWith = "[startsWith(parameters('DomainFQDN'), 'bgw')]"
|
|
EndsWith = "[endsWith(parameters('DomainFQDN'), 'DE')]"
|
|
Length = "[length(split(parameters('DomainFQDN'), '.'))]"
|
|
Empty = "[empty('')]"
|
|
}
|
|
}
|
|
|
|
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
|
|
|
|
$Result.Resources.Split[0] | Should Be "bgw-online"
|
|
$Result.Resources.Split[1] | Should Be "de"
|
|
$Result.Resources.Joined | Should Be "bgw-online_de"
|
|
$Result.Resources.JoinedNotEmpty | Should Be "SharePoint_LAN_Test_Services"
|
|
$Result.Resources.Take | Should Be "bgw-online"
|
|
$Result.Resources.Skip | Should Be "de"
|
|
$Result.Resources.First | Should Be "bgw-online"
|
|
$Result.Resources.Last | Should Be "de"
|
|
$Result.Resources.Unique | Should Be "SP_SQL"
|
|
$Result.Resources.Sort | Should Be "APP_SP_SQL"
|
|
$Result.Resources.ContainsString | Should Be $true
|
|
$Result.Resources.ContainsArray | Should Be $true
|
|
$Result.Resources.StartsWith | Should Be $true
|
|
$Result.Resources.EndsWith | Should Be $true
|
|
$Result.Resources.Length | Should Be 2
|
|
$Result.Resources.Empty | Should Be $true
|
|
}
|
|
|
|
It "resolves trim and padding functions" {
|
|
$ConfigurationData = @{
|
|
Resources = @{
|
|
Trim = "[trim(' SharePoint ')]"
|
|
TrimStart = "[trimStart(' SharePoint')]"
|
|
TrimEnd = "[trimEnd('SharePoint ')]"
|
|
PadLeft = "[padLeft('1', 2, '0')]"
|
|
PadRight = "[padRight('SP', 4, '0')]"
|
|
DefaultIfEmpty = "[defaultIfEmpty('', 'SharePoint')]"
|
|
Sanitized = "[sanitizeName(' SharePoint LAN/Test DB ')]"
|
|
Normalized = "[normalizeSeparator('__SharePoint___LAN_Test__', '_')]"
|
|
Prefix = "[prefixIfNotEmpty('LAN', 'BGW-')]"
|
|
EmptyPrefix = "[prefixIfNotEmpty('', 'BGW-')]"
|
|
Suffix = "[suffixIfNotEmpty('SharePoint', '_DB')]"
|
|
EmptySuffix = "[suffixIfNotEmpty('', '_DB')]"
|
|
}
|
|
}
|
|
|
|
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
|
|
|
|
$Result.Resources.Trim | Should Be "SharePoint"
|
|
$Result.Resources.TrimStart | Should Be "SharePoint"
|
|
$Result.Resources.TrimEnd | Should Be "SharePoint"
|
|
$Result.Resources.PadLeft | Should Be "01"
|
|
$Result.Resources.PadRight | Should Be "SP00"
|
|
$Result.Resources.DefaultIfEmpty | Should Be "SharePoint"
|
|
$Result.Resources.Sanitized | Should Be "SharePoint_LAN_Test_DB"
|
|
$Result.Resources.Normalized | Should Be "SharePoint_LAN_Test"
|
|
$Result.Resources.Prefix | Should Be "BGW-LAN"
|
|
$Result.Resources.EmptyPrefix | Should Be ""
|
|
$Result.Resources.Suffix | Should Be "SharePoint_DB"
|
|
$Result.Resources.EmptySuffix | Should Be ""
|
|
}
|
|
|
|
It "resolves values inside arrays recursively" {
|
|
$ConfigurationData = @{
|
|
Parameters = @{
|
|
NodeName = @{
|
|
Value = "SP01"
|
|
}
|
|
}
|
|
AllNodes = @(
|
|
@{
|
|
NodeName = "[parameters('NodeName')]"
|
|
}
|
|
)
|
|
}
|
|
|
|
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
|
|
|
|
$Result.AllNodes[0].NodeName | Should Be "SP01"
|
|
}
|
|
|
|
It "throws for circular variables" {
|
|
$ConfigurationData = @{
|
|
Variables = @{
|
|
A = "[variables('B')]"
|
|
B = "[variables('A')]"
|
|
}
|
|
Resources = @{
|
|
Value = "[variables('A')]"
|
|
}
|
|
}
|
|
|
|
{ Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData } | Should Throw
|
|
}
|
|
}
|