Skip to content

Commit

Permalink
SqlAudit: New resources (#1499)
Browse files Browse the repository at this point in the history
- SqlServerDsc
  - Add new resource SqlServerAudit.
  - The following classes were added to the module:
    - `SqlResourceBase` - class that can be inherited by class-based resource and
      provides default DSC properties and method for get a `[Server]`-object.
  - The following public functions were added to the module (see comment-based
    help for more information):
    - `Invoke-SqlDscQuery`
    - `Get-SqlDscAudit`
    - `New-SqlDscAudit`
    - `Set-SqlDscAudit`
    - `Remove-SqlDscAudit`
    - `Enable-SqlDscAudit`
    - `Disable-SqlDscAudit`
- `Get-DscProperty`
  - Added parameter `ExcludeName` to exclude property names from being returned.
- SqlPermission
  - Fix comment-based help.
- `ConvertTo-Reason`
  - Fix to handle `$null` values on Windows PowerShell.
  - If the property name contain the word 'Path' the value will be parsed to
    replace backslash or slashes at the end of the string, e.g. `'/mypath/'`
    will become `'/mypath'`.
- `ResourceBase`
  - Now handles `Ensure` correctly from derived `GetCurrentState()`. But
    requires that the `GetCurrentState()` only return key property if object
    is present, and does not return key property if object is absent.
    Optionally the resource's derived `GetCurrentState()` can handle `Ensure`
    itself.
  • Loading branch information
johlju authored Aug 13, 2022
1 parent 1fe1dce commit d741244
Show file tree
Hide file tree
Showing 45 changed files with 7,215 additions and 110 deletions.
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@
"xSQLAOGroupEnsure",
"Test-SPDSCObjectHasProperty",
"DynamicAlloc",
"GetxPDTVariable"
"GetxPDTVariable",
"Dbcc",
"creplace"
],
"cSpell.ignorePaths": [
".git"
Expand Down
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
in desired state.
- `ResourceBase` - class that can be inherited by class-based resource and
provides functionality meant simplify the creating of class-based resource.
- `SqlResourceBase` - class that can be inherited by class-based resource and
provides default DSC properties and method for get a `[Server]`-object.
- `ServerPermission` - complex type for the DSC resource SqlPermission.
- The following private functions were added to the module (see comment-based
help for more information):
Expand All @@ -72,8 +74,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `ConvertTo-SqlDscServerPermission`
- `Get-SqlDscServerPermission`
- `Set-SqlDscServerPermission`
- `Invoke-SqlDscQuery`
- `Get-SqlDscAudit`
- `New-SqlDscAudit`
- `Set-SqlDscAudit`
- `Remove-SqlDscAudit`
- `Enable-SqlDscAudit`
- `Disable-SqlDscAudit`
- Support for debugging of integration tests in AppVeyor.
- Only run for pull requests
- Add new resource SqlAudit.
- CommonTestHelper
- `Import-SqlModuleStub`
- Added the optional parameter **PasThru** that, if used, will return the
Expand All @@ -86,6 +96,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
the PowerShell SqlServer stub module when a test has run.
- SqlWindowsFirewall
- Added integration tests for SqlWindowsFirewall ([issue #747](https://github.com/dsccommunity/SqlServerDsc/issues/747)).
- `Get-DscProperty`
- Added parameter `ExcludeName` to exclude property names from being returned.

### Changed

Expand Down Expand Up @@ -296,8 +308,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed comment-based help and cleaned up comments.
- Fix localized string that referenced 'user' instead of 'principal',
and correct localized string ID for each string.
- Fix comment-based help.
- SqlPermission
- Fix comment-based help.
- `Set-SqlDscDatabasePermission`
- Minor code cleanup.
- `ConvertTo-Reason`
- Fix to handle `$null` values on Windows PowerShell.
- If the property name contain the word 'Path' the value will be parsed to
replace backslash or slashes at the end of the string, e.g. `'/mypath/'`
will become `'/mypath'`.
- `ResourceBase`
- Now handles `Ensure` correctly from derived `GetCurrentState()`. But
requires that the `GetCurrentState()` only return key property if object
is present, and does not return key property if object is absent.
Optionally the resource's derived `GetCurrentState()` can handle `Ensure`
itself.

## [15.2.0] - 2021-09-01

Expand Down
10 changes: 5 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -329,11 +329,11 @@ if (-not $databaseExist)
A terminating error is an error that the user are not able to ignore by
passing a parameter to the command (like for non-terminating errors).

If a command shall throw an terminating error the statement `throw` shall
not be used, neither shall the command `Write-Error` be used with the parameter
`-ErrorAction `Stop``. Instead the method `$PSCmdlet.ThrowTerminatingError()`
shall be used to throw a terminating error.

If a command shall throw an terminating error then the statement `throw` shall
not be used, neither shall the command `Write-Error` with the parameter
`-ErrorAction Stop`. Always use the method `$PSCmdlet.ThrowTerminatingError()`
to throw a terminating error. The exception is when a `[ValidateScript()]`
has to throw an error, then `throw` must be used.

>**NOTE:** Below output assumes `$ErrorView` is set to `'NormalView'` in the
>PowerShell session.
Expand Down
32 changes: 14 additions & 18 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,47 +23,39 @@ environment:
#- TEST_CONFIGURATION: Integration_SQL2019

# DEBUG: See section on_finish last in this file on how to block build to keep RDP open.
# DEBUG: If running on own AppVeyor project, comment the line below that skips if it is not a pull request
init:
- ps: |
# Only run for pull requests
if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER)
{
return
}
if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER) { Write-Host -ForegroundColor 'Yellow' -Object 'Not a pull request, skipping.'; return }
iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
# DEBUG: If running on own AppVeyor project, comment the line below that skips if it is not a pull request
install:
- ps: |
# Only run for pull requests
if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER)
{
return
}
if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER) { Write-Host -ForegroundColor 'Yellow' -Object 'Not a pull request, skipping.'; return }
winrm quickconfig -quiet
# DEBUG: If running on own AppVeyor project, comment the line below that skips if it is not a pull request
build_script:
- pwsh: |
# Only run for pull requests
if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER)
{
return
}
if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER) { Write-Host -ForegroundColor 'Yellow' -Object 'Not a pull request, skipping.'; return }
# Build the module
./build.ps1 -ResolveDependency -tasks build
# DEBUG: Comment and un-comment integration tests as needed for the purpose of debugging.
# Note that some integration tests depend on each other to work. See the README for more
# information: https://github.com/dsccommunity/SqlServerDsc/blob/main/tests/Integration/README.md
# DEBUG: If running on own AppVeyor project, comment the line below that skips if it is not a pull request
test_script:
- ps: |
# Only run for pull requests
if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER)
{
return
}
if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER) { Write-Host -ForegroundColor 'Yellow' -Object 'Not a pull request, skipping.'; return }
./build.ps1 -Tasks test -CodeCoverageThreshold 0 -PesterTag $env:TEST_CONFIGURATION -PesterPath @(
### Run the integration tests in a specific group order.
Expand All @@ -86,6 +78,7 @@ test_script:
'tests/Integration/DSC_SqlRS.Integration.Tests.ps1'
#'tests/Integration/DSC_SqlDatabaseUser.Integration.Tests.ps1'
#'tests/Integration/DSC_SqlReplication.Integration.Tests.ps1'
#'tests/Integration/DSC_SqlAudit.Integration.Tests.ps1'
## Group 4
#'tests/Integration/DSC_SqlScript.Integration.Tests.ps1'
#'tests/Integration/DSC_SqlDatabasePermission.Integration.Tests.ps1'
Expand All @@ -102,8 +95,11 @@ test_script:
deploy: off

# DEBUG: Un-comment the following line so that build worker is kept up all of the 60 minutes.
# DEBUG: Un-comment the line "$blockRdp = $true" so that build worker is kept up all of the 60 minutes.
# DEBUG: If running on own AppVeyor project, comment the line below that skips if it is not a pull request
on_finish:
- ps: |
if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER) { Write-Host -ForegroundColor 'Yellow' -Object 'Not a pull request, skipping.'; return }
#$blockRdp = $true
iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
iex ((New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
2 changes: 2 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ stages:
- task: PowerShell@2
name: test
displayName: 'Run HQRM Test'
condition: succeededOrFailed()
inputs:
filePath: './build.ps1'
arguments: '-Tasks hqrmtest'
Expand Down Expand Up @@ -197,6 +198,7 @@ stages:
'tests/Integration/DSC_SqlRS.Integration.Tests.ps1'
'tests/Integration/DSC_SqlDatabaseUser.Integration.Tests.ps1'
'tests/Integration/DSC_SqlReplication.Integration.Tests.ps1'
'tests/Integration/DSC_SqlAudit.Integration.Tests.ps1'
# Group 4
'tests/Integration/DSC_SqlScript.Integration.Tests.ps1'
'tests/Integration/DSC_SqlDatabasePermission.Integration.Tests.ps1'
Expand Down
1 change: 1 addition & 0 deletions build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ BuildWorkflow:

test:
- Pester_Tests_Stop_On_Fail
- Convert_Pester_Coverage
- Pester_If_Code_Coverage_Under_Threshold

publish:
Expand Down
77 changes: 18 additions & 59 deletions source/Classes/010.ResourceBase.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -52,86 +52,45 @@ class ResourceBase
}
}

$keyPropertyAddedToCurrentState = $false

# Set key property values unless it was returned from the derived class' GetCurrentState().
foreach ($propertyName in $keyProperty.Keys)
{
if ($propertyName -notin @($getCurrentStateResult.Keys))
{
# Add the key value to the instance to be returned.
$dscResourceObject.$propertyName = $this.$propertyName
}
}

$ignoreProperty = @()

<#
TODO: This need to be re-evaluated for a resource that is using Ensure
property. How Ensure is handled might need to be refactored, or
removed altogether from this base class.
If the derived DSC resource has a Ensure property and it was not returned
by GetCurrentState(), then the property Ensure is removed from the
comparison (when calling Compare()). The property Ensure is ignored
since the method GetCurrentState() did not return it, and the current
state for property Ensure cannot be determined until the method Compare()
has run to determined if other properties are not in desired state.
#>
if (($this | Test-ResourceHasDscProperty -Name 'Ensure') -and -not $getCurrentStateResult.ContainsKey('Ensure'))
{
$ignoreProperty += 'Ensure'
$keyPropertyAddedToCurrentState = $true
}
}

<#
Returns all enforced properties not in desires state, or $null if
all enforced properties are in desired state.
#>
$propertiesNotInDesiredState = $this.Compare($getCurrentStateResult, $ignoreProperty)

<#
Return the correct values for Ensure property if the derived DSC resource
has such property and it hasn't been already set by GetCurrentState().
#>
if (($this | Test-ResourceHasDscProperty -Name 'Ensure') -and -not $getCurrentStateResult.ContainsKey('Ensure'))
{
if ($propertiesNotInDesiredState)
# Evaluate if we should set Ensure property.
if ($keyPropertyAddedToCurrentState)
{
<#
Get all the key properties that might not be in desired state.
This will return $null if all key properties are in desired state.
A key property was added to the current state, assume its because
the object did not exist in the current state. Set Ensure to Absent.
#>
$keyPropertiesNotInDesiredState = $this | Get-DscProperty -Name $propertiesNotInDesiredState.Property -Type 'Key'

if ($keyPropertiesNotInDesiredState)
{
<#
The compare come back with at least one key property that was
not in desired state. That only happens if the object does not
exist on the node, so the Ensure value is set to Absent since
the object does not exist.
#>
$dscResourceObject.Ensure = [Ensure]::Absent
}
else
{
<#
The compare come back with all key properties in desired state.
That only happens if the object exist on the node, so the Ensure
value is set to Present since the object exist.
#>
$dscResourceObject.Ensure = [Ensure]::Present
}
$dscResourceObject.Ensure = [Ensure]::Absent
$getCurrentStateResult.Ensure = [Ensure]::Absent
}
else
{
<#
The compare come back with $null, meaning that all key properties
match. That only happens if the object exist on the node, so the
Ensure value is set to Present since the object exist.
#>
$dscResourceObject.Ensure = [Ensure]::Present
$getCurrentStateResult.Ensure = [Ensure]::Present
}
}

<#
Returns all enforced properties not in desires state, or $null if
all enforced properties are in desired state.
#>
$propertiesNotInDesiredState = $this.Compare($getCurrentStateResult, @())

<#
Return the correct values for Reasons property if the derived DSC resource
has such property and it hasn't been already set by GetCurrentState().
Expand All @@ -140,7 +99,7 @@ class ResourceBase
{
# Always return an empty array if all properties are in desired state.
$dscResourceObject.Reasons = $propertiesNotInDesiredState |
ConvertTo-Reason -ResourceName $this.GetType()
ConvertTo-Reason -ResourceName $this.GetType().Name
}

# Return properties.
Expand Down
81 changes: 81 additions & 0 deletions source/Classes/011.SqlResourceBase.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<#
.SYNOPSIS
The SqlResource base have generic properties and methods for the class-based
resources.
.PARAMETER InstanceName
The name of the _SQL Server_ instance to be configured. Default value is
`'MSSQLSERVER'`.
.PARAMETER ServerName
The host name of the _SQL Server_ to be configured. Default value is the
current computer name.
.PARAMETER Credential
Specifies the credential to use to connect to the _SQL Server_ instance.
If parameter **Credential'* is not provided then the resource instance is
run using the credential that runs the configuration.
.PARAMETER Reasons
Returns the reason a property is not in desired state.
#>
class SqlResourceBase : ResourceBase
{
<#
Property for holding the server connection object.
This should be an object of type [Microsoft.SqlServer.Management.Smo.Server]
but using that type fails the build process currently.
See issue https://github.com/dsccommunity/DscResource.DocGenerator/issues/121.
#>
hidden [System.Object] $SqlServerObject

[DscProperty(Key)]
[System.String]
$InstanceName

[DscProperty()]
[System.String]
$ServerName = (Get-ComputerName)

[DscProperty()]
[PSCredential]
$Credential

[DscProperty(NotConfigurable)]
[Reason[]]
$Reasons

SqlResourceBase () : base ()
{
$this.SqlServerObject = $null
}

<#
Returns and reuses the server connection object. If the server connection
object does not exist a connection to the SQL Server instance will occur.
This should return an object of type [Microsoft.SqlServer.Management.Smo.Server]
but using that type fails the build process currently.
See issue https://github.com/dsccommunity/DscResource.DocGenerator/issues/121.
#>
hidden [System.Object] GetServerObject()
{
if (-not $this.SqlServerObject)
{
$connectSqlDscDatabaseEngineParameters = @{
ServerName = $this.ServerName
InstanceName = $this.InstanceName
}

if ($this.Credential)
{
$connectSqlDscDatabaseEngineParameters.Credential = $this.Credential
}

$this.SqlServerObject = Connect-SqlDscDatabaseEngine @connectSqlDscDatabaseEngineParameters
}

return $this.SqlServerObject
}
}
Loading

0 comments on commit d741244

Please sign in to comment.