From 8ae34f16ecb23ba35b70647d725458a14286f336 Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Wed, 10 Jul 2019 16:57:13 +0200 Subject: [PATCH] Changes to xADDomainTrust - Added integration tests (issue #348). --- CHANGELOG.md | 1 + .../MSFT_xADDomainTrust.Integration.Tests.ps1 | 349 ++++++++++++++++++ .../MSFT_xADDomainTrust.config.ps1 | 193 ++++++++++ 3 files changed, 543 insertions(+) create mode 100644 Tests/Integration/MSFT_xADDomainTrust.Integration.Tests.ps1 create mode 100644 Tests/Integration/MSFT_xADDomainTrust.config.ps1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 92828659c..fd53da113 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ it to use the same code pattern as the resource xADObjectEnabledState. - Added unit tests ([issue #324](https://github.com/PowerShell/xActiveDirectory/issues/324)). - Added comment-based help ([issue #337](https://github.com/PowerShell/xActiveDirectory/issues/337)). + - Added integration tests ([issue #348](https://github.com/PowerShell/xActiveDirectory/issues/348)). ## 3.0.0.0 diff --git a/Tests/Integration/MSFT_xADDomainTrust.Integration.Tests.ps1 b/Tests/Integration/MSFT_xADDomainTrust.Integration.Tests.ps1 new file mode 100644 index 000000000..f6e52a493 --- /dev/null +++ b/Tests/Integration/MSFT_xADDomainTrust.Integration.Tests.ps1 @@ -0,0 +1,349 @@ +if ($env:APPVEYOR -eq $true) +{ + Write-Warning -Message 'Integration test is not supported in AppVeyor.' + return +} + +$script:dscModuleName = 'xActiveDirectory' +$script:dscResourceFriendlyName = 'xADDomainTrust' +$script:dscResourceName = "MSFT_$($script:dscResourceFriendlyName)" + +#region HEADER +# Integration Test Template Version: 1.3.3 +[System.String] $script:moduleRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) +if ( (-not (Test-Path -Path (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests'))) -or ` + (-not (Test-Path -Path (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) ) +{ + & git @('clone', 'https://github.com/PowerShell/DscResource.Tests.git', (Join-Path -Path $script:moduleRoot -ChildPath 'DscResource.Tests')) +} + +Import-Module -Name (Join-Path -Path $script:moduleRoot -ChildPath (Join-Path -Path 'DSCResource.Tests' -ChildPath 'TestHelper.psm1')) -Force +$TestEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -TestType Integration +#endregion + +try +{ + $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configFile + + Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + } + + $configurationName = "$($script:dscResourceName)_CreateDomainTrust_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + # The variable $ConfigurationData was dot-sourced above. + ConfigurationData = $ConfigurationData + } + + & $configurationName @configurationParameters + + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } + + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId + } + + $resourceCurrentState.Ensure | Should -Be 'Present' + $resourceCurrentState.SourceDomainName | Should -Be $configurationData.AllNodes.SourceDomain + $resourceCurrentState.TargetDomainName | Should -Be $configurationData.AllNodes.TargetDomain + $resourceCurrentState.TargetDomainAdministratorCredential.UserName | Should -Be $configurationData.AllNodes.TargetUserName + $resourceCurrentState.TrustType | Should -Be 'External' + $resourceCurrentState.TrustDirection | Should -Be 'Outbound' + } + + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } + + $configurationName = "$($script:dscResourceName)_ChangeDomainTrustDirection_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + # The variable $ConfigurationData was dot-sourced above. + ConfigurationData = $ConfigurationData + } + + & $configurationName @configurationParameters + + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } + + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId + } + + $resourceCurrentState.Ensure | Should -Be 'Present' + $resourceCurrentState.SourceDomainName | Should -Be $configurationData.AllNodes.SourceDomain + $resourceCurrentState.TargetDomainName | Should -Be $configurationData.AllNodes.TargetDomain + $resourceCurrentState.TargetDomainAdministratorCredential.UserName | Should -Be $configurationData.AllNodes.TargetUserName + $resourceCurrentState.TrustType | Should -Be 'External' + $resourceCurrentState.TrustDirection | Should -Be 'Inbound' + } + + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } + + $configurationName = "$($script:dscResourceName)_RemoveDomainTrust_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + # The variable $ConfigurationData was dot-sourced above. + ConfigurationData = $ConfigurationData + } + + & $configurationName @configurationParameters + + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } + + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId + } + + $resourceCurrentState.Ensure | Should -Be 'Absent' + $resourceCurrentState.SourceDomainName | Should -Be $configurationData.AllNodes.SourceDomain + $resourceCurrentState.TargetDomainName | Should -Be $configurationData.AllNodes.TargetDomain + $resourceCurrentState.TargetDomainAdministratorCredential.UserName | Should -Be $configurationData.AllNodes.TargetUserName + $resourceCurrentState.TrustType | Should -BeNullOrEmpty + $resourceCurrentState.TrustDirection | Should -BeNullOrEmpty + } + + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } + + $configurationName = "$($script:dscResourceName)_CreateForestTrust_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + # The variable $ConfigurationData was dot-sourced above. + ConfigurationData = $ConfigurationData + } + + & $configurationName @configurationParameters + + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } + + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId + } + + $resourceCurrentState.Ensure | Should -Be 'Present' + $resourceCurrentState.SourceDomainName | Should -Be $configurationData.AllNodes.SourceForest + $resourceCurrentState.TargetDomainName | Should -Be $configurationData.AllNodes.TargetForest + $resourceCurrentState.TargetDomainAdministratorCredential.UserName | Should -Be $configurationData.AllNodes.TargetUserName + $resourceCurrentState.TrustType | Should -Be 'Forest' + $resourceCurrentState.TrustDirection | Should -Be 'Outbound' + } + + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } + + $configurationName = "$($script:dscResourceName)_ChangeForestTrustDirection_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + # The variable $ConfigurationData was dot-sourced above. + ConfigurationData = $ConfigurationData + } + + & $configurationName @configurationParameters + + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } + + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId + } + + $resourceCurrentState.Ensure | Should -Be 'Present' + $resourceCurrentState.SourceDomainName | Should -Be $configurationData.AllNodes.SourceForest + $resourceCurrentState.TargetDomainName | Should -Be $configurationData.AllNodes.TargetForest + $resourceCurrentState.TargetDomainAdministratorCredential.UserName | Should -Be $configurationData.AllNodes.TargetUserName + $resourceCurrentState.TrustType | Should -Be 'Forest' + $resourceCurrentState.TrustDirection | Should -Be 'Inbound' + } + + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } + + $configurationName = "$($script:dscResourceName)_RemoveForestTrust_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + # The variable $ConfigurationData was dot-sourced above. + ConfigurationData = $ConfigurationData + } + + & $configurationName @configurationParameters + + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } + + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId + } + + $resourceCurrentState.Ensure | Should -Be 'Absent' + $resourceCurrentState.SourceDomainName | Should -Be $configurationData.AllNodes.SourceForest + $resourceCurrentState.TargetDomainName | Should -Be $configurationData.AllNodes.TargetForest + $resourceCurrentState.TargetDomainAdministratorCredential.UserName | Should -Be $configurationData.AllNodes.TargetUserName + $resourceCurrentState.TrustType | Should -BeNullOrEmpty + $resourceCurrentState.TrustDirection | Should -BeNullOrEmpty + } + + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } + } +} +finally +{ + #region FOOTER + Restore-TestEnvironment -TestEnvironment $TestEnvironment + #endregion +} diff --git a/Tests/Integration/MSFT_xADDomainTrust.config.ps1 b/Tests/Integration/MSFT_xADDomainTrust.config.ps1 new file mode 100644 index 000000000..8bc536d22 --- /dev/null +++ b/Tests/Integration/MSFT_xADDomainTrust.config.ps1 @@ -0,0 +1,193 @@ +#region HEADER +# Integration Test Config Template Version: 1.2.0 +#endregion + +<# + .NOTES + To run this integration test there are prerequisites that need to + be setup. + + 1. One Domain Controller with forest contoso.com. + 2. One Domain Controller with forest lab.local. + 3. DNS working between the forests (conditional forwarder). + 4. Credentials with permission in the target domain (lab.local). + 5. If no certificate path is set to the environment variable + `$env:DscPublicCertificatePath` then `PSDscAllowPlainTextPassword = $true` + must be added to the ConfigurationData-block. +#> + +$configFile = [System.IO.Path]::ChangeExtension($MyInvocation.MyCommand.Path, 'json') +if (Test-Path -Path $configFile) +{ + <# + Allows reading the configuration data from a JSON file, for real testing + scenarios outside of the CI. + #> + $ConfigurationData = Get-Content -Path $configFile | ConvertFrom-Json +} +else +{ + $ConfigurationData = @{ + AllNodes = @( + @{ + NodeName = 'localhost' + CertificateFile = $env:DscPublicCertificatePath + + SourceDomain = 'contoso.com' + TargetDomain = 'lab.local' + + SourceForest = 'contoso.com' + TargetForest = 'lab.local' + + TargetUserName = "LAB\Administrator" + TargetPassword = 'P@ssw0rd1' + } + ) + } +} + +<# + .SYNOPSIS + Creates a domain trust. +#> +Configuration MSFT_xADDomainTrust_CreateDomainTrust_Config +{ + Import-DscResource -ModuleName 'xActiveDirectory' + + node $AllNodes.NodeName + { + xADDomainTrust 'Integration_Test' + { + SourceDomainName = $Node.SourceDomain + TargetDomainName = $Node.TargetDomain + TrustType = 'External' + TrustDirection = 'Outbound' + TargetDomainAdministratorCredential = New-Object ` + -TypeName System.Management.Automation.PSCredential ` + -ArgumentList @($Node.TargetUserName, (ConvertTo-SecureString -String $Node.TargetPassword -AsPlainText -Force)) + + } + } +} + +<# + .SYNOPSIS + Changes trust direction on an existing domain trust. +#> +Configuration MSFT_xADDomainTrust_ChangeDomainTrustDirection_Config +{ + Import-DscResource -ModuleName 'xActiveDirectory' + + node $AllNodes.NodeName + { + xADDomainTrust 'Integration_Test' + { + SourceDomainName = $Node.SourceDomain + TargetDomainName = $Node.TargetDomain + TrustType = 'External' + TrustDirection = 'Inbound' + TargetDomainAdministratorCredential = New-Object ` + -TypeName System.Management.Automation.PSCredential ` + -ArgumentList @($Node.TargetUserName, (ConvertTo-SecureString -String $Node.TargetPassword -AsPlainText -Force)) + + } + } +} + +<# + .SYNOPSIS + Removes the domain trust. +#> +Configuration MSFT_xADDomainTrust_RemoveDomainTrust_Config +{ + Import-DscResource -ModuleName 'xActiveDirectory' + + node $AllNodes.NodeName + { + xADDomainTrust 'Integration_Test' + { + Ensure = 'Absent' + SourceDomainName = $Node.SourceDomain + TargetDomainName = $Node.TargetDomain + TrustType = 'External' + TrustDirection = 'Bidirectional' + TargetDomainAdministratorCredential = New-Object ` + -TypeName System.Management.Automation.PSCredential ` + -ArgumentList @($Node.TargetUserName, (ConvertTo-SecureString -String $Node.TargetPassword -AsPlainText -Force)) + + } + } +} + +<# + .SYNOPSIS + Creates a forest trust. +#> +Configuration MSFT_xADDomainTrust_CreateForestTrust_Config +{ + Import-DscResource -ModuleName 'xActiveDirectory' + + node $AllNodes.NodeName + { + xADDomainTrust 'Integration_Test' + { + SourceDomainName = $Node.SourceForest + TargetDomainName = $Node.TargetForest + TrustType = 'Forest' + TrustDirection = 'Outbound' + TargetDomainAdministratorCredential = New-Object ` + -TypeName System.Management.Automation.PSCredential ` + -ArgumentList @($Node.TargetUserName, (ConvertTo-SecureString -String $Node.TargetPassword -AsPlainText -Force)) + + } + } +} + +<# + .SYNOPSIS + Changes trust direction on an existing forest trust. +#> +Configuration MSFT_xADDomainTrust_ChangeForestTrustDirection_Config +{ + Import-DscResource -ModuleName 'xActiveDirectory' + + node $AllNodes.NodeName + { + xADDomainTrust 'Integration_Test' + { + SourceDomainName = $Node.SourceForest + TargetDomainName = $Node.TargetForest + TrustType = 'Forest' + TrustDirection = 'Inbound' + TargetDomainAdministratorCredential = New-Object ` + -TypeName System.Management.Automation.PSCredential ` + -ArgumentList @($Node.TargetUserName, (ConvertTo-SecureString -String $Node.TargetPassword -AsPlainText -Force)) + + } + } +} + +<# + .SYNOPSIS + Removes the domain trust. +#> +Configuration MSFT_xADDomainTrust_RemoveForestTrust_Config +{ + Import-DscResource -ModuleName 'xActiveDirectory' + + node $AllNodes.NodeName + { + xADDomainTrust 'Integration_Test' + { + Ensure = 'Absent' + SourceDomainName = $Node.SourceForest + TargetDomainName = $Node.TargetForest + TrustType = 'Forest' + TrustDirection = 'Bidirectional' + TargetDomainAdministratorCredential = New-Object ` + -TypeName System.Management.Automation.PSCredential ` + -ArgumentList @($Node.TargetUserName, (ConvertTo-SecureString -String $Node.TargetPassword -AsPlainText -Force)) + + } + } +}