Skip to content

Commit d741244

Browse files
authored
SqlAudit: New resources (#1499)
- 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.
1 parent 1fe1dce commit d741244

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+7215
-110
lines changed

.vscode/settings.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@
6767
"xSQLAOGroupEnsure",
6868
"Test-SPDSCObjectHasProperty",
6969
"DynamicAlloc",
70-
"GetxPDTVariable"
70+
"GetxPDTVariable",
71+
"Dbcc",
72+
"creplace"
7173
],
7274
"cSpell.ignorePaths": [
7375
".git"

CHANGELOG.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4949
in desired state.
5050
- `ResourceBase` - class that can be inherited by class-based resource and
5151
provides functionality meant simplify the creating of class-based resource.
52+
- `SqlResourceBase` - class that can be inherited by class-based resource and
53+
provides default DSC properties and method for get a `[Server]`-object.
5254
- `ServerPermission` - complex type for the DSC resource SqlPermission.
5355
- The following private functions were added to the module (see comment-based
5456
help for more information):
@@ -72,8 +74,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7274
- `ConvertTo-SqlDscServerPermission`
7375
- `Get-SqlDscServerPermission`
7476
- `Set-SqlDscServerPermission`
77+
- `Invoke-SqlDscQuery`
78+
- `Get-SqlDscAudit`
79+
- `New-SqlDscAudit`
80+
- `Set-SqlDscAudit`
81+
- `Remove-SqlDscAudit`
82+
- `Enable-SqlDscAudit`
83+
- `Disable-SqlDscAudit`
7584
- Support for debugging of integration tests in AppVeyor.
7685
- Only run for pull requests
86+
- Add new resource SqlAudit.
7787
- CommonTestHelper
7888
- `Import-SqlModuleStub`
7989
- Added the optional parameter **PasThru** that, if used, will return the
@@ -86,6 +96,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8696
the PowerShell SqlServer stub module when a test has run.
8797
- SqlWindowsFirewall
8898
- Added integration tests for SqlWindowsFirewall ([issue #747](https://github.com/dsccommunity/SqlServerDsc/issues/747)).
99+
- `Get-DscProperty`
100+
- Added parameter `ExcludeName` to exclude property names from being returned.
89101

90102
### Changed
91103

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

302328
## [15.2.0] - 2021-09-01
303329

CONTRIBUTING.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -329,11 +329,11 @@ if (-not $databaseExist)
329329
A terminating error is an error that the user are not able to ignore by
330330
passing a parameter to the command (like for non-terminating errors).
331331

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

338338
>**NOTE:** Below output assumes `$ErrorView` is set to `'NormalView'` in the
339339
>PowerShell session.

appveyor.yml

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,47 +23,39 @@ environment:
2323
#- TEST_CONFIGURATION: Integration_SQL2019
2424

2525
# DEBUG: See section on_finish last in this file on how to block build to keep RDP open.
26+
# DEBUG: If running on own AppVeyor project, comment the line below that skips if it is not a pull request
2627
init:
2728
- ps: |
2829
# Only run for pull requests
29-
if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER)
30-
{
31-
return
32-
}
30+
if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER) { Write-Host -ForegroundColor 'Yellow' -Object 'Not a pull request, skipping.'; return }
3331
3432
iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
3533
34+
# DEBUG: If running on own AppVeyor project, comment the line below that skips if it is not a pull request
3635
install:
3736
- ps: |
3837
# Only run for pull requests
39-
if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER)
40-
{
41-
return
42-
}
38+
if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER) { Write-Host -ForegroundColor 'Yellow' -Object 'Not a pull request, skipping.'; return }
4339
4440
winrm quickconfig -quiet
4541
42+
# DEBUG: If running on own AppVeyor project, comment the line below that skips if it is not a pull request
4643
build_script:
4744
- pwsh: |
4845
# Only run for pull requests
49-
if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER)
50-
{
51-
return
52-
}
46+
if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER) { Write-Host -ForegroundColor 'Yellow' -Object 'Not a pull request, skipping.'; return }
5347
5448
# Build the module
5549
./build.ps1 -ResolveDependency -tasks build
5650
5751
# DEBUG: Comment and un-comment integration tests as needed for the purpose of debugging.
5852
# Note that some integration tests depend on each other to work. See the README for more
5953
# information: https://github.com/dsccommunity/SqlServerDsc/blob/main/tests/Integration/README.md
54+
# DEBUG: If running on own AppVeyor project, comment the line below that skips if it is not a pull request
6055
test_script:
6156
- ps: |
6257
# Only run for pull requests
63-
if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER)
64-
{
65-
return
66-
}
58+
if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER) { Write-Host -ForegroundColor 'Yellow' -Object 'Not a pull request, skipping.'; return }
6759
6860
./build.ps1 -Tasks test -CodeCoverageThreshold 0 -PesterTag $env:TEST_CONFIGURATION -PesterPath @(
6961
### Run the integration tests in a specific group order.
@@ -86,6 +78,7 @@ test_script:
8678
'tests/Integration/DSC_SqlRS.Integration.Tests.ps1'
8779
#'tests/Integration/DSC_SqlDatabaseUser.Integration.Tests.ps1'
8880
#'tests/Integration/DSC_SqlReplication.Integration.Tests.ps1'
81+
#'tests/Integration/DSC_SqlAudit.Integration.Tests.ps1'
8982
## Group 4
9083
#'tests/Integration/DSC_SqlScript.Integration.Tests.ps1'
9184
#'tests/Integration/DSC_SqlDatabasePermission.Integration.Tests.ps1'
@@ -102,8 +95,11 @@ test_script:
10295
10396
deploy: off
10497

105-
# DEBUG: Un-comment the following line so that build worker is kept up all of the 60 minutes.
98+
# DEBUG: Un-comment the line "$blockRdp = $true" so that build worker is kept up all of the 60 minutes.
99+
# DEBUG: If running on own AppVeyor project, comment the line below that skips if it is not a pull request
106100
on_finish:
107101
- ps: |
102+
if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER) { Write-Host -ForegroundColor 'Yellow' -Object 'Not a pull request, skipping.'; return }
103+
108104
#$blockRdp = $true
109-
iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
105+
iex ((New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))

azure-pipelines.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ stages:
8787
- task: PowerShell@2
8888
name: test
8989
displayName: 'Run HQRM Test'
90+
condition: succeededOrFailed()
9091
inputs:
9192
filePath: './build.ps1'
9293
arguments: '-Tasks hqrmtest'
@@ -197,6 +198,7 @@ stages:
197198
'tests/Integration/DSC_SqlRS.Integration.Tests.ps1'
198199
'tests/Integration/DSC_SqlDatabaseUser.Integration.Tests.ps1'
199200
'tests/Integration/DSC_SqlReplication.Integration.Tests.ps1'
201+
'tests/Integration/DSC_SqlAudit.Integration.Tests.ps1'
200202
# Group 4
201203
'tests/Integration/DSC_SqlScript.Integration.Tests.ps1'
202204
'tests/Integration/DSC_SqlDatabasePermission.Integration.Tests.ps1'

build.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ BuildWorkflow:
2424

2525
test:
2626
- Pester_Tests_Stop_On_Fail
27+
- Convert_Pester_Coverage
2728
- Pester_If_Code_Coverage_Under_Threshold
2829

2930
publish:

source/Classes/010.ResourceBase.ps1

Lines changed: 18 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -52,86 +52,45 @@ class ResourceBase
5252
}
5353
}
5454

55+
$keyPropertyAddedToCurrentState = $false
56+
5557
# Set key property values unless it was returned from the derived class' GetCurrentState().
5658
foreach ($propertyName in $keyProperty.Keys)
5759
{
5860
if ($propertyName -notin @($getCurrentStateResult.Keys))
5961
{
6062
# Add the key value to the instance to be returned.
6163
$dscResourceObject.$propertyName = $this.$propertyName
62-
}
63-
}
64-
65-
$ignoreProperty = @()
6664

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

84-
<#
85-
Returns all enforced properties not in desires state, or $null if
86-
all enforced properties are in desired state.
87-
#>
88-
$propertiesNotInDesiredState = $this.Compare($getCurrentStateResult, $ignoreProperty)
89-
90-
<#
91-
Return the correct values for Ensure property if the derived DSC resource
92-
has such property and it hasn't been already set by GetCurrentState().
93-
#>
9469
if (($this | Test-ResourceHasDscProperty -Name 'Ensure') -and -not $getCurrentStateResult.ContainsKey('Ensure'))
9570
{
96-
if ($propertiesNotInDesiredState)
71+
# Evaluate if we should set Ensure property.
72+
if ($keyPropertyAddedToCurrentState)
9773
{
9874
<#
99-
Get all the key properties that might not be in desired state.
100-
This will return $null if all key properties are in desired state.
75+
A key property was added to the current state, assume its because
76+
the object did not exist in the current state. Set Ensure to Absent.
10177
#>
102-
$keyPropertiesNotInDesiredState = $this | Get-DscProperty -Name $propertiesNotInDesiredState.Property -Type 'Key'
103-
104-
if ($keyPropertiesNotInDesiredState)
105-
{
106-
<#
107-
The compare come back with at least one key property that was
108-
not in desired state. That only happens if the object does not
109-
exist on the node, so the Ensure value is set to Absent since
110-
the object does not exist.
111-
#>
112-
$dscResourceObject.Ensure = [Ensure]::Absent
113-
}
114-
else
115-
{
116-
<#
117-
The compare come back with all key properties in desired state.
118-
That only happens if the object exist on the node, so the Ensure
119-
value is set to Present since the object exist.
120-
#>
121-
$dscResourceObject.Ensure = [Ensure]::Present
122-
}
78+
$dscResourceObject.Ensure = [Ensure]::Absent
79+
$getCurrentStateResult.Ensure = [Ensure]::Absent
12380
}
12481
else
12582
{
126-
<#
127-
The compare come back with $null, meaning that all key properties
128-
match. That only happens if the object exist on the node, so the
129-
Ensure value is set to Present since the object exist.
130-
#>
13183
$dscResourceObject.Ensure = [Ensure]::Present
84+
$getCurrentStateResult.Ensure = [Ensure]::Present
13285
}
13386
}
13487

88+
<#
89+
Returns all enforced properties not in desires state, or $null if
90+
all enforced properties are in desired state.
91+
#>
92+
$propertiesNotInDesiredState = $this.Compare($getCurrentStateResult, @())
93+
13594
<#
13695
Return the correct values for Reasons property if the derived DSC resource
13796
has such property and it hasn't been already set by GetCurrentState().
@@ -140,7 +99,7 @@ class ResourceBase
14099
{
141100
# Always return an empty array if all properties are in desired state.
142101
$dscResourceObject.Reasons = $propertiesNotInDesiredState |
143-
ConvertTo-Reason -ResourceName $this.GetType()
102+
ConvertTo-Reason -ResourceName $this.GetType().Name
144103
}
145104

146105
# Return properties.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<#
2+
.SYNOPSIS
3+
The SqlResource base have generic properties and methods for the class-based
4+
resources.
5+
6+
.PARAMETER InstanceName
7+
The name of the _SQL Server_ instance to be configured. Default value is
8+
`'MSSQLSERVER'`.
9+
10+
.PARAMETER ServerName
11+
The host name of the _SQL Server_ to be configured. Default value is the
12+
current computer name.
13+
14+
.PARAMETER Credential
15+
Specifies the credential to use to connect to the _SQL Server_ instance.
16+
17+
If parameter **Credential'* is not provided then the resource instance is
18+
run using the credential that runs the configuration.
19+
20+
.PARAMETER Reasons
21+
Returns the reason a property is not in desired state.
22+
#>
23+
class SqlResourceBase : ResourceBase
24+
{
25+
<#
26+
Property for holding the server connection object.
27+
This should be an object of type [Microsoft.SqlServer.Management.Smo.Server]
28+
but using that type fails the build process currently.
29+
See issue https://github.com/dsccommunity/DscResource.DocGenerator/issues/121.
30+
#>
31+
hidden [System.Object] $SqlServerObject
32+
33+
[DscProperty(Key)]
34+
[System.String]
35+
$InstanceName
36+
37+
[DscProperty()]
38+
[System.String]
39+
$ServerName = (Get-ComputerName)
40+
41+
[DscProperty()]
42+
[PSCredential]
43+
$Credential
44+
45+
[DscProperty(NotConfigurable)]
46+
[Reason[]]
47+
$Reasons
48+
49+
SqlResourceBase () : base ()
50+
{
51+
$this.SqlServerObject = $null
52+
}
53+
54+
<#
55+
Returns and reuses the server connection object. If the server connection
56+
object does not exist a connection to the SQL Server instance will occur.
57+
58+
This should return an object of type [Microsoft.SqlServer.Management.Smo.Server]
59+
but using that type fails the build process currently.
60+
See issue https://github.com/dsccommunity/DscResource.DocGenerator/issues/121.
61+
#>
62+
hidden [System.Object] GetServerObject()
63+
{
64+
if (-not $this.SqlServerObject)
65+
{
66+
$connectSqlDscDatabaseEngineParameters = @{
67+
ServerName = $this.ServerName
68+
InstanceName = $this.InstanceName
69+
}
70+
71+
if ($this.Credential)
72+
{
73+
$connectSqlDscDatabaseEngineParameters.Credential = $this.Credential
74+
}
75+
76+
$this.SqlServerObject = Connect-SqlDscDatabaseEngine @connectSqlDscDatabaseEngineParameters
77+
}
78+
79+
return $this.SqlServerObject
80+
}
81+
}

0 commit comments

Comments
 (0)