From 219ed849284b7a6643c79c883d4f346ce18fe020 Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Sat, 6 Jan 2018 09:56:07 +0100 Subject: [PATCH] Changes to SqlServerLogin - Added integration tests (issue #748). --- CHANGELOG.md | 2 + .../MSFT_SqlServerLogin.Integration.Tests.ps1 | 379 ++++++++++++++++++ .../MSFT_SqlServerLogin.config.ps1 | 255 ++++++++++++ Tests/Integration/README.md | 33 ++ 4 files changed, 669 insertions(+) create mode 100644 Tests/Integration/MSFT_SqlServerLogin.Integration.Tests.ps1 create mode 100644 Tests/Integration/MSFT_SqlServerLogin.config.ps1 diff --git a/CHANGELOG.md b/CHANGELOG.md index a720bc8a0..f943fd584 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,8 @@ Reporting Services to use SSL when connecting ([issue #990](https://github.com/PowerShell/SqlServerDsc/issues/990)). - Added complete example for SqlRS (based on the integration tests) ([issue #634](https://github.com/PowerShell/SqlServerDsc/issues/634)). +- Changes to SqlServerLogin + - Added integration tests ([issue #748](https://github.com/PowerShell/SqlServerDsc/issues/748)). - Changes to SqlServerNetwork - Added sysadmin account parameter usage to the examples. - Changes to SqlServerReplication diff --git a/Tests/Integration/MSFT_SqlServerLogin.Integration.Tests.ps1 b/Tests/Integration/MSFT_SqlServerLogin.Integration.Tests.ps1 new file mode 100644 index 000000000..9fee18805 --- /dev/null +++ b/Tests/Integration/MSFT_SqlServerLogin.Integration.Tests.ps1 @@ -0,0 +1,379 @@ +$script:DSCModuleName = 'SqlServerDsc' +$script:DSCResourceFriendlyName = 'SqlServerLogin' +$script:DSCResourceName = "MSFT_$($script:DSCResourceFriendlyName)" + +if (-not $env:APPVEYOR -eq $true) +{ + Write-Warning -Message ('Integration test for {0} will be skipped unless $env:APPVEYOR equals $true' -f $script:DSCResourceName) + return +} + +#region HEADER +# Integration Test Template Version: 1.1.2 +[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 + +$mockSqlAdminAccountPassword = ConvertTo-SecureString -String 'P@ssw0rd1' -AsPlainText -Force +$mockSqlAdminAccountUserName = "$env:COMPUTERNAME\SqlAdmin" +$mockSqlAdminCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $mockSqlAdminAccountUserName, $mockSqlAdminAccountPassword + +$mockUserAccountPassword = ConvertTo-SecureString -String 'P@ssw0rd1' -AsPlainText -Force +$mockUserCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList 'OnlyPasswordIsUsed', $mockUserAccountPassword + +try +{ + $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:DSCResourceName).config.ps1" + . $configFile + + $mockDscUser1Name = $ConfigurationData.AllNodes.DscUser1Name + $mockDscUser1Type = $ConfigurationData.AllNodes.DscUser1Type + $mockDscUser2Name = $ConfigurationData.AllNodes.DscUser2Name + $mockDscUser2Type = $ConfigurationData.AllNodes.DscUser2Type + $mockDscUser3Name = $ConfigurationData.AllNodes.DscUser3Name + $mockDscUser3Type = $ConfigurationData.AllNodes.DscUser3Type + $mockDscUser4Name = $ConfigurationData.AllNodes.DscUser4Name + $mockDscUser4Type = $ConfigurationData.AllNodes.DscUser4Type + $mockDscSqlUsers1Name = $ConfigurationData.AllNodes.DscSqlUsers1Name + $mockDscSqlUsers1Type = $ConfigurationData.AllNodes.DscSqlUsers1Type + + Describe "$($script:DSCResourceName)_Integration" { + BeforeAll { + $resourceId = "[$($script:DSCResourceFriendlyName)]Integration_Test" + } + + $configurationName = "$($script:DSCResourceName)_CreateDependencies_Config" + + <# + This will install dependencies using other resource modules, and is + done without running extra tests on the result. + This is done to speed up testing. + #> + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + UserCredential = $mockUserCredential + 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 + } + } + + $configurationName = "$($script:DSCResourceName)_AddLoginDscUser1_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + SqlAdministratorCredential = $mockSqlAdminCredential + 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' { + { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $currentConfiguration = Get-DscConfiguration + + $resourceCurrentState = $currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName + } | Where-Object -FilterScript { + $_.ResourceId -eq $resourceId + } + + $resourceCurrentState.Ensure | Should -Be 'Present' + $resourceCurrentState.Name | Should -Be $mockDscUser1Name + $resourceCurrentState.LoginType | Should -Be $mockDscUser1Type + $resourceCurrentState.Disabled | Should -Be $false + } + } + + $configurationName = "$($script:DSCResourceName)_AddLoginDscUser2_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + SqlAdministratorCredential = $mockSqlAdminCredential + 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' { + { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $currentConfiguration = Get-DscConfiguration + + $resourceCurrentState = $currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName + } | Where-Object -FilterScript { + $_.ResourceId -eq $resourceId + } + + $resourceCurrentState.Ensure | Should -Be 'Present' + $resourceCurrentState.Name | Should -Be $mockDscUser2Name + $resourceCurrentState.LoginType | Should -Be $mockDscUser2Type + $resourceCurrentState.Disabled | Should -Be $false + } + } + + $configurationName = "$($script:DSCResourceName)_AddLoginDscUser3_Disabled_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + SqlAdministratorCredential = $mockSqlAdminCredential + 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' { + { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $currentConfiguration = Get-DscConfiguration + + $resourceCurrentState = $currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName + } | Where-Object -FilterScript { + $_.ResourceId -eq $resourceId + } + + $resourceCurrentState.Ensure | Should -Be 'Present' + $resourceCurrentState.Name | Should -Be $mockDscUser3Name + $resourceCurrentState.LoginType | Should -Be $mockDscUser3Type + $resourceCurrentState.Disabled | Should -Be $true + } + } + + $configurationName = "$($script:DSCResourceName)_AddLoginDscUser4_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + SqlAdministratorCredential = $mockSqlAdminCredential + UserCredential = $mockUserCredential + 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' { + { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $currentConfiguration = Get-DscConfiguration + + $resourceCurrentState = $currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName + } | Where-Object -FilterScript { + $_.ResourceId -eq $resourceId + } + + $resourceCurrentState.Ensure | Should -Be 'Present' + $resourceCurrentState.Name | Should -Be $mockDscUser4Name + $resourceCurrentState.LoginType | Should -Be $mockDscUser4Type + $resourceCurrentState.Disabled | Should -Be $false + } + } + + $configurationName = "$($script:DSCResourceName)_AddLoginDscSqlUsers1_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + SqlAdministratorCredential = $mockSqlAdminCredential + 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' { + { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $currentConfiguration = Get-DscConfiguration + + $resourceCurrentState = $currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName + } | Where-Object -FilterScript { + $_.ResourceId -eq $resourceId + } + + $resourceCurrentState.Ensure | Should -Be 'Present' + $resourceCurrentState.Name | Should -Be $mockDscSqlUsers1Name + $resourceCurrentState.LoginType | Should -Be $mockDscSqlUsers1Type + $resourceCurrentState.Disabled | Should -Be $false + } + } + + $configurationName = "$($script:DSCResourceName)_RemoveLoginDscUser3_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + SqlAdministratorCredential = $mockSqlAdminCredential + 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' { + { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $currentConfiguration = Get-DscConfiguration + + $resourceCurrentState = $currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName + } | Where-Object -FilterScript { + $_.ResourceId -eq $resourceId + } + + $resourceCurrentState.Ensure | Should -Be 'Absent' + $resourceCurrentState.Name | Should -Be $mockDscUser3Name + $resourceCurrentState.LoginType | Should -BeNullOrEmpty + } + } + } +} +finally +{ + #region FOOTER + + Restore-TestEnvironment -TestEnvironment $TestEnvironment + + #endregion +} diff --git a/Tests/Integration/MSFT_SqlServerLogin.config.ps1 b/Tests/Integration/MSFT_SqlServerLogin.config.ps1 new file mode 100644 index 000000000..6ff76aedc --- /dev/null +++ b/Tests/Integration/MSFT_SqlServerLogin.config.ps1 @@ -0,0 +1,255 @@ +# This is used to make sure the integration test run in the correct order. +[Microsoft.DscResourceKit.IntegrationTest(OrderNumber = 3)] +param() + +$ConfigurationData = @{ + AllNodes = @( + @{ + NodeName = 'localhost' + ServerName = $env:COMPUTERNAME + InstanceName = 'DSCSQL2016' + + PSDscAllowPlainTextPassword = $true + + DscUser1Name = ('{0}\{1}' -f $env:COMPUTERNAME, 'DscUser1') + DscUser1Type = 'WindowsUser' + + DscUser2Name = ('{0}\{1}' -f $env:COMPUTERNAME, 'DscUser2') + DscUser2Type = 'WindowsUser' + + DscUser3Name = ('{0}\{1}' -f $env:COMPUTERNAME, 'DscUser3') + DscUser3Type = 'WindowsUser' + + DscUser4Name = 'DscUser4' + DscUser4Type = 'SqlLogin' + + DscSqlUsers1Name = ('{0}\{1}' -f $env:COMPUTERNAME, 'DscSqlUsers1') + DscSqlUsers1Type = 'WindowsGroup' + } + ) +} + +Configuration MSFT_SqlServerLogin_CreateDependencies_Config +{ + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.Management.Automation.PSCredential] + $UserCredential + ) + + Import-DscResource -ModuleName 'PSDscResources' + + node localhost { + User 'CreateDscUser1' + { + Ensure = 'Present' + UserName = Split-Path -Path $Node.DscUser1Name -Leaf + Password = $UserCredential + } + + User 'CreateDscUser2' + { + Ensure = 'Present' + UserName = Split-Path -Path $Node.DscUser2Name -Leaf + Password = $UserCredential + } + + User 'CreateDscUser3' + { + Ensure = 'Present' + UserName = Split-Path -Path $Node.DscUser3Name -Leaf + Password = $UserCredential + } + + Group 'CreateDscSqlUsers1' + { + Ensure = 'Present' + GroupName = 'DscSqlUsers1' + Members = @( + Split-Path -Path $Node.DscUser1Name -Leaf + Split-Path -Path $Node.DscUser2Name -Leaf + ) + + DependsOn = @( + '[User]CreateDscUser1' + '[User]CreateDscUser2' + ) + } + } +} + +Configuration MSFT_SqlServerLogin_AddLoginDscUser1_Config +{ + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.Management.Automation.PSCredential] + $SqlAdministratorCredential + ) + + Import-DscResource -ModuleName 'SqlServerDsc' + + node localhost { + SqlServerLogin 'Integration_Test' + { + Ensure = 'Present' + Name = $Node.DscUser1Name + LoginType = $Node.DscUser1Type + + ServerName = $Node.ServerName + InstanceName = $Node.InstanceName + + PsDscRunAsCredential = $SqlAdministratorCredential + } + } +} + +Configuration MSFT_SqlServerLogin_AddLoginDscUser2_Config +{ + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.Management.Automation.PSCredential] + $SqlAdministratorCredential + ) + + Import-DscResource -ModuleName 'SqlServerDsc' + + node localhost { + SqlServerLogin 'Integration_Test' + { + Ensure = 'Present' + Name = $Node.DscUser2Name + LoginType = $Node.DscUser2Type + + ServerName = $Node.ServerName + InstanceName = $Node.InstanceName + + PsDscRunAsCredential = $SqlAdministratorCredential + } + } +} + +Configuration MSFT_SqlServerLogin_AddLoginDscUser3_Disabled_Config +{ + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.Management.Automation.PSCredential] + $SqlAdministratorCredential + ) + + Import-DscResource -ModuleName 'SqlServerDsc' + + node localhost { + SqlServerLogin 'Integration_Test' + { + Ensure = 'Present' + Name = $Node.DscUser3Name + LoginType = $Node.DscUser3Type + Disabled = $true + + ServerName = $Node.ServerName + InstanceName = $Node.InstanceName + + PsDscRunAsCredential = $SqlAdministratorCredential + } + } +} + +Configuration MSFT_SqlServerLogin_AddLoginDscUser4_Config +{ + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.Management.Automation.PSCredential] + $SqlAdministratorCredential, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.Management.Automation.PSCredential] + $UserCredential + ) + + Import-DscResource -ModuleName 'SqlServerDsc' + + node localhost { + SqlServerLogin 'Integration_Test' + { + Ensure = 'Present' + Name = $Node.DscUser4Name + LoginType = $Node.DscUser4Type + LoginCredential = $UserCredential + LoginMustChangePassword = $false + LoginPasswordExpirationEnabled = $true + LoginPasswordPolicyEnforced = $true + + ServerName = $Node.ServerName + InstanceName = $Node.InstanceName + + PsDscRunAsCredential = $SqlAdministratorCredential + } + } +} + +Configuration MSFT_SqlServerLogin_AddLoginDscSqlUsers1_Config +{ + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.Management.Automation.PSCredential] + $SqlAdministratorCredential + ) + + Import-DscResource -ModuleName 'SqlServerDsc' + + node localhost { + SqlServerLogin 'Integration_Test' + { + Ensure = 'Present' + Name = $Node.DscSqlUsers1Name + LoginType = $Node.DscSqlUsers1Type + + ServerName = $Node.ServerName + InstanceName = $Node.InstanceName + + PsDscRunAsCredential = $SqlAdministratorCredential + } + } +} + +Configuration MSFT_SqlServerLogin_RemoveLoginDscUser3_Config +{ + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.Management.Automation.PSCredential] + $SqlAdministratorCredential + ) + + Import-DscResource -ModuleName 'SqlServerDsc' + + node localhost { + SqlServerLogin 'Integration_Test' + { + Ensure = 'Absent' + Name = $Node.DscUser3Name + LoginType = $Node.DscUser3Type + + ServerName = $Node.ServerName + InstanceName = $Node.InstanceName + + PsDscRunAsCredential = $SqlAdministratorCredential + } + } +} + + diff --git a/Tests/Integration/README.md b/Tests/Integration/README.md index fb3db8921..42adc3932 100644 --- a/Tests/Integration/README.md +++ b/Tests/Integration/README.md @@ -81,3 +81,36 @@ The integration test will change the data, log and backup path of instance Data | Log | Backup --- | --- | --- C:\SQLData | C:\SQLLog | C:\Backups + +## SqlServerLogin + +**Run order:** 2 +**Depends on:** SqlSetup + +The integration tests will leave the following local Windows users on the build +worker. + +Username | Password | Permission +--- | --- | --- +DscUser1 | P@ssw0rd1 | Local user +DscUser2 | P@ssw0rd1 | Local user +DscUser3 | P@ssw0rd1 | Local user + +The integration tests will leave the following local Windows groups on the build +worker. + +Username | Members | Member of | Permission +--- | --- | --- | --- +DscSqlUsers1 | DscUser1, DscUser2 | *None* | *None* + +The integration tests will leave the following logins on the SQL Server instance +**DSCSQL2016**. + +Login | Type | Password | Permission +--- | --- | --- | --- +DscUser1 | Windows | P@ssw0rd1 | *None* +DscUser2 | Windows | P@ssw0rd1 | *None* +DscUser4 | SQL | P@ssw0rd1 | *None* + +> **Note:** Login DscUser3 was create disabled and was used to test removal of +> a login.