Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SqlDatabase: Support Changing Snapshot Isolation #1622

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- SqlReplication
- The resource are now using the helper function `Get-SqlInstanceMajorVersion`
([issue #1408](https://github.com/dsccommunity/SqlServerDsc/issues/1408)).
- SqlDatabase
- Support enabling or disabling snapshot isolation
([issue #845](https://github.com/dsccommunity/SqlServerDsc/issues/845)).

### Fixed
- SqlDatabaseRole
Expand Down
44 changes: 42 additions & 2 deletions source/DSCResources/DSC_SqlDatabase/DSC_SqlDatabase.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ function Get-TargetResource
CompatibilityLevel = $null
RecoveryModel = $null
OwnerName = $null
SnapshotIsolation = $null
}

$sqlServerObject = Connect-SQL -ServerName $ServerName -InstanceName $InstanceName
Expand All @@ -90,6 +91,7 @@ function Get-TargetResource
$returnValue['CompatibilityLevel'] = $sqlDatabaseObject.CompatibilityLevel
$returnValue['RecoveryModel'] = $sqlDatabaseObject.RecoveryModel
$returnValue['OwnerName'] = $sqlDatabaseObject.Owner
$returnValue['SnapshotIsolation'] = $sqlDatabaseObject.SnapshotIsolationState -eq 'Enabled'

Write-Verbose -Message (
$script:localizedData.DatabasePresent -f $Name
Expand Down Expand Up @@ -137,6 +139,9 @@ function Get-TargetResource

.PARAMETER OwnerName
Specifies the name of the login that should be the owner of the database.

.PARAMETER SnapshotIsolation
Specifics whether snapshot isolation should be enabled for the new database.
#>
function Set-TargetResource
{
Expand Down Expand Up @@ -181,7 +186,11 @@ function Set-TargetResource

[Parameter()]
[System.String]
$OwnerName
$OwnerName,

[Parameter()]
[System.Boolean]
$SnapshotIsolation
)

$sqlServerObject = Connect-SQL -ServerName $ServerName -InstanceName $InstanceName
Expand Down Expand Up @@ -275,6 +284,24 @@ function Set-TargetResource
$wasUpdate = $true
}

if ($PSBoundParameters.ContainsKey('SnapshotIsolation'))
{
Write-Verbose -Message (
$script:localizedData.UpdatingSnapshotIsolation -f $SnapshotIsolation
)

try
{
$sqlDatabaseObject.SetSnapshotIsolation($SnapshotIsolation)
}
catch
{
$errorMessage = $script:localizedData.FailedToUpdateSnapshotIsolation -f $SnapshotIsolation, $Name

New-InvalidOperationException -Message $errorMessage -ErrorRecord $_
}
}

try
{
if ($wasUpdate)
Expand Down Expand Up @@ -438,7 +465,11 @@ function Test-TargetResource

[Parameter()]
[System.String]
$OwnerName
$OwnerName,

[Parameter()]
[System.Boolean]
$SnapshotIsolation
)

Write-Verbose -Message (
Expand Down Expand Up @@ -516,6 +547,15 @@ function Test-TargetResource

$isDatabaseInDesiredState = $false
}

if ($PSBoundParameters.ContainsKey('SnapshotIsolation') -and $getTargetResourceResult.SnapshotIsolation -ne $SnapshotIsolation)
{
Write-Verbose -Message (
$script:localizedData.SnapshotIsolationWrong -f $Name, $getTargetResourceResult.SnapshotIsolation, $SnapshotIsolation
)

$isDatabaseInDesiredState = $false
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ class DSC_SqlDatabase : OMI_BaseResource
[Write, Description("Specifies the version of the _SQL Database Compatibility Level_ to use for the specified database."), ValueMap{"Version80","Version90","Version100","Version110","Version120","Version130","Version140","Version150"}, Values{"Version80","Version90","Version100","Version110","Version120","Version130","Version140","Version150"}] String CompatibilityLevel;
[Write, Description("The recovery model for the specified database."), ValueMap{"Simple","Full","BulkLogged"}, Values{"Simple","Full","BulkLogged"}] String RecoveryModel;
[Write, Description("Specifies the name of the login that should be the owner of the database.")] String OwnerName;
[Write, Description("Enables snapshot isolation for the specified database.")] Boolean SnapshotIsolation;
};
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,7 @@ ConvertFrom-StringData @'
OwnerNameWrong = The database '{0}' exist and has the owner '{1}', but expected it to have the owner '{2}'.
UpdatingOwner = Changing the database owner to '{0}'.
FailedToUpdateOwner = Failed changing to owner to '{0}' for the database '{1}'.
UpdatingSnapshotIsolation = Updating snapshot isolation to '{0}'.
FailedToUpdateSnapshotIsolation = Failed changing snapshot isolation to '{0}' for the database '{1}'.
SnapshotIsolationWrong = The database '{0}' exists and has snapshot isolation set to '{1}', but expected it to have snapshot isolation set to '{2}'.
'@
51 changes: 51 additions & 0 deletions tests/Integration/DSC_SqlDatabase.Integration.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,56 @@ try
}
}

$configurationName = "$($script:dscResourceName)_AddDatabase6_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.Name | Should -Be $ConfigurationData.AllNodes.DatabaseName6
$resourceCurrentState.ServerName | Should -Be $ConfigurationData.AllNodes.ServerName
$resourceCurrentState.InstanceName | Should -Be $ConfigurationData.AllNodes.InstanceName
$resourceCurrentState.SnapshotIsolation | Should -Be $ConfigurationData.AllNodes.SnapshotIsolation
}

It 'Should return $true when Test-DscConfiguration is run' {
Test-DscConfiguration -Verbose | Should -Be 'True'
}
}

$configurationName = "$($script:dscResourceName)_RemoveDatabase2_Config"

Context ('When using configuration {0}' -f $configurationName) {
Expand Down Expand Up @@ -333,6 +383,7 @@ try
$resourceCurrentState.OwnerName | Should -BeNullOrEmpty
$resourceCurrentState.RecoveryModel | Should -BeNullOrEmpty
$resourceCurrentState.CompatibilityLevel | Should -BeNullOrEmpty
$resourceCurrentState.SnapshotIsolation | Should -BeNullOrEmpty
}

It 'Should return $true when Test-DscConfiguration is run' {
Expand Down
27 changes: 27 additions & 0 deletions tests/Integration/DSC_SqlDatabase.config.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ else
DatabaseName3 = 'Database3'
DatabaseName4 = 'Database4'
DatabaseName5 = 'Database5'
DatabaseName6 = 'Database6'

Collation = 'SQL_Latin1_General_Pref_CP850_CI_AS'
CompatibilityLevel = 'Version120'
RecoveryModel = 'Simple'
OwnerName = 'sa'
SnapshotIsolation = $true
}
)
}
Expand Down Expand Up @@ -164,6 +166,31 @@ Configuration DSC_SqlDatabase_AddDatabase5_Config
}
}

<#
.SYNOPSIS
Creates a database with a specific snapshot isolation.
#>
Configuration DSC_SqlDatabase_AddDatabase6_Config
{
Import-DscResource -ModuleName 'SqlServerDsc'

node $AllNodes.NodeName
{
SqlDatabase 'Integration_Test'
{
Ensure = 'Present'
ServerName = $Node.ServerName
InstanceName = $Node.InstanceName
Name = $Node.DatabaseName6
SnapshotIsolation = $Node.SnapshotIsolation

PsDscRunAsCredential = New-Object `
-TypeName System.Management.Automation.PSCredential `
-ArgumentList @($Node.Username, (ConvertTo-SecureString -String $Node.Password -AsPlainText -Force))
}
}
}

<#
.SYNOPSIS
Removes the second databases that was created.
Expand Down