From c825db5a4dccbf51d69d81bbda1a6dfcff1776cc Mon Sep 17 00:00:00 2001 From: Mark Lewis Date: Wed, 24 Jul 2019 14:58:54 +0100 Subject: [PATCH 1/5] Adding DNS Server Zone Scopes #95 Tests and module for adding DNS Server Zone Scopes which are used within DNS Policies. --- .../MSFT_xDnsServerZoneScope.psm1 | 150 ++++++++++++++++++ .../MSFT_xDnsServerZoneScope.schema.mof | 7 + README.md | 11 +- Tests/Unit/MSFT_xDnsServerZoneScope.Tests.ps1 | 141 ++++++++++++++++ 4 files changed, 308 insertions(+), 1 deletion(-) create mode 100644 DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.psm1 create mode 100644 DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.schema.mof create mode 100644 Tests/Unit/MSFT_xDnsServerZoneScope.Tests.ps1 diff --git a/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.psm1 b/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.psm1 new file mode 100644 index 00000000..214a2474 --- /dev/null +++ b/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.psm1 @@ -0,0 +1,150 @@ +# Localized messages +data LocalizedData +{ + # culture="en-US" + ConvertFrom-StringData @' + GettingDnsServerZoneScopeMessage = Getting DNS Server Zone Scope '{0}' in '{1}'. + CreatingDnsServerZoneScopeMessage = Creating DNS Server Zone Scope '{0}' in '{1}'. + RemovingDnsServerZoneScopeMessage = Removing DNS Server Zone Scope '{0}' from '{1}'. + NotDesiredPropertyMessage = DNS Server Zone Scope property '{0}' is not correct. Expected '{1}', actual '{2}' + InDesiredStateMessage = DNS Server Zone Scope '{0}' is in the desired state. + NotInDesiredStateMessage = DNS Server Zone Scope '{0}' is NOT in the desired state. +'@ +} + +<# + .SYNOPSIS + This will return the current state of the resource. + + .PARAMETER Name + Specifies the name of the Zone Scope. + + .PARAMETER ZoneName + Specify the existing DNS Zone to add a scope to. +#> +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Name, + + [Parameter(Mandatory = $true)] + [System.String] + $ZoneName + + ) + + Write-Verbose -Message ($LocalizedData.GettingDnsServerZoneScopeMessage -f $Name, $ZoneName) + $record = Get-DnsServerZoneScope -Name $Name -ZoneName $ZoneName -ErrorAction SilentlyContinue + + if ($null -eq $record) + { + return @{ + Name = $Name + ZoneName = $ZoneName + Ensure = 'Absent' + } + } + + return @{ + Name = $record.Name + ZoneName = $record.ZoneName + Ensure = 'Present' + } +} #end function Get-TargetResource + +<# + .SYNOPSIS + This will configure the resource. + + .PARAMETER Name + Specifies the name of the Zone Scope. + + .PARAMETER ZoneName + Specify the existing DNS Zone to add a scope to. +#> +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Name, + + [Parameter(Mandatory = $true)] + [System.String] + $ZoneName, + + [Parameter()] + [ValidateSet('Present','Absent')] + [System.String] + $Ensure = 'Present' + ) + + + $clientSubnet = Get-DnsServerZoneScope -Name $Name -ZoneName $ZoneName -ErrorAction SilentlyContinue + if ($Ensure -eq 'Present') + { + + if (!$clientSubnet) + { + Write-Verbose -Message ($LocalizedData.CreatingDnsServerZoneScopeMessage -f $Name, $ZoneName) + Add-DnsServerZoneScope -ZoneName $ZoneName -Name $Name + } + } + elseif ($Ensure -eq 'Absent') + { + Write-Verbose -Message ($LocalizedData.RemovingDnsServerZoneScopeMessage -f $Name, $ZoneName) + Remove-DnsServerZoneScope -Name $Name -ZoneName $ZoneName + } +} #end function Set-TargetResource + +<# + .SYNOPSIS + This will return whether the resource is in desired state. + + .PARAMETER Name + Specifies the name of the Zone Scope. + + .PARAMETER ZoneName + Specify the existing DNS Zone to add a scope to. +#> +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Name, + + [Parameter(Mandatory = $true)] + [System.String] + $ZoneName, + + [Parameter()] + [ValidateSet('Present','Absent')] + [System.String] + $Ensure = 'Present' + ) + + $result = Get-TargetResource -Name $Name -ZoneName $ZoneName + + if ($Ensure -ne $result.Ensure) + { + Write-Verbose -Message ($LocalizedData.NotDesiredPropertyMessage -f 'Ensure', $Ensure, $result.Ensure) + Write-Verbose -Message ($LocalizedData.NotInDesiredStateMessage -f $Name) + return $false + } + + Write-Verbose -Message ($LocalizedData.InDesiredStateMessage -f $Name) + return $true +} #end function Test-TargetResource + +Export-ModuleMember -Function *-TargetResource diff --git a/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.schema.mof b/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.schema.mof new file mode 100644 index 00000000..81ad0cf3 --- /dev/null +++ b/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.schema.mof @@ -0,0 +1,7 @@ +[ClassVersion("1.0.0.0"), FriendlyName("xDnsServerZoneScope")] +class MSFT_xDnsServerZoneScope : OMI_BaseResource +{ + [Key, Description("Specifies the name of the Zone Scope.")] string Name; + [Write, Description("Specify the existing DNS Zone to add a scope to.")] string ZoneName; +}; + diff --git a/README.md b/README.md index 0de3be89..e2f54f4a 100644 --- a/README.md +++ b/README.md @@ -212,13 +212,21 @@ Requires Windows Server 2016 onwards * **Name**: Specifies the name of the client subnet. * **IPv4Subnet**: Specify an array (1 or more values) of IPv4 Subnet addresses in CIDR Notation. * **IPv6Subnet**: Specify an array (1 of more values) of IPv6 Subnet addresses in CIDR Notation. -* **Ensure**: Whether the client subnet should be present or removed +* **Ensure**: Whether the client subnet should be present or removed. ### xDnsServerRootHint * **IsSingleInstance**: Specifies the resource is a single instance, the value must be 'Yes' * **NameServer**: A hashtable that defines the name server. Key and value must be strings. +### xDnsServerZoneScope + +Requires Windows Server 2016 onwards + +* **Name**: Specifies the name of the Zone Scope. +* **ZoneName**: Specifies the name of the DNS Zone the scope applies to. +* **Ensure**: Whether the Zone Scope should be present or removed. + ## Versions ### Unreleased @@ -229,6 +237,7 @@ Requires Windows Server 2016 onwards * Put the helper module to its own folder * Added xDnsServerRootHint resource * Added xDnsServerClientSubnet resource +* Added xDnsServerZoneScope resource ### 1.13.0.0 diff --git a/Tests/Unit/MSFT_xDnsServerZoneScope.Tests.ps1 b/Tests/Unit/MSFT_xDnsServerZoneScope.Tests.ps1 new file mode 100644 index 00000000..d65930ec --- /dev/null +++ b/Tests/Unit/MSFT_xDnsServerZoneScope.Tests.ps1 @@ -0,0 +1,141 @@ +#region HEADER +$script:DSCModuleName = 'xDnsServer' +$script:DSCResourceName = 'MSFT_xDnsServerZoneScope' + +$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 Unit +#endregion HEADER + +# Begin Testing +try +{ + #region Pester Tests + + InModuleScope $script:DSCResourceName { + #region Pester Test Initialization + $mocks = @{ + ZoneScopePresent = { + [PSCustomObject]@{ + ZoneName = 'contoso.com' + Name = 'ZoneScope' + } + } + Absent = { } + } + #endregion + + #region Function Get-TargetResource + Describe "MSFT_xDnsServerZoneScope\Get-TargetResource" -Tag 'Get' { + Context 'When the system is in the desired state' { + It 'Should set Ensure to Present when the Zone Scope is Present' { + Mock -CommandName Get-DnsServerZoneScope $mocks.ZoneScopePresent + + $getTargetResourceResult = Get-TargetResource -ZoneName 'contoso.com' -Name 'ZoneScope' + $getTargetResourceResult.Ensure | Should -Be 'Present' + $getTargetResourceResult.Name | Should -Be 'ZoneScope' + $getTargetResourceResult.ZoneName | Should -Be 'contoso.com' + + Assert-MockCalled -CommandName Get-DnsServerZoneScope -Exactly -Times 1 -Scope It + } + } + + Context 'When the system is not in the desired state' { + It 'Should set Ensure to Absent when the Zone Scope is not present' { + Mock -CommandName Get-DnsServerZoneScope $mocks.Absent + + $getTargetResourceResult = Get-TargetResource -ZoneName 'contoso.com' -Name 'ZoneScope' + $getTargetResourceResult.Ensure | Should -Be 'Absent' + $getTargetResourceResult.Name | Should -Be 'ZoneScope' + $getTargetResourceResult.ZoneName | Should -Be 'contoso.com' + + Assert-MockCalled -CommandName Get-DnsServerZoneScope -Exactly -Times 1 -Scope It + } + } + } + #endregion Function Get-TargetResource + + #region Function Test-TargetResource + Describe "MSFT_xDnsServerZoneScope\Test-TargetResource" -Tag 'Test' { + Context 'When the system is in the desired state' { + It 'Should return True when the Zone Scope exists' { + Mock -CommandName Get-DnsServerZoneScope $mocks.ZoneScopePresent + $params = @{ + Ensure = 'Present' + ZoneName = 'contoso.com' + Name = 'ZoneScope' + } + Test-TargetResource @params | Should -BeTrue + + Assert-MockCalled -CommandName Get-DnsServerZoneScope -Exactly -Times 1 -Scope It + } + } + + Context 'When the system is not in the desired state' { + It 'Should return False when the Ensure doesnt match' { + Mock -CommandName Get-DnsServerZoneScope $mocks.Absent + $params = @{ + Ensure = 'Present' + ZoneName = 'contoso.com' + Name = 'ZoneScope' + } + Test-TargetResource @params | Should -BeFalse + + Assert-MockCalled -CommandName Get-DnsServerZoneScope -Exactly -Times 1 -Scope It + } + } + } + #endregion + + #region Function Set-TargetResource + Describe "MSFT_xDnsServerZoneScope\Set-TargetResource" -Tag 'Set' { + Context 'When configuring DNS Server Zone Scopes' { + It 'Calls Add-DnsServerZoneScope in the set method when the subnet does not exist' { + Mock -CommandName Get-DnsServerZoneScope + Mock -CommandName Add-DnsServerZoneScope + + $params = @{ + Ensure = 'Present' + ZoneName = 'contoso.com' + Name = 'ZoneScope' + } + Set-TargetResource @params + + Assert-MockCalled Add-DnsServerZoneScope -Scope It -ParameterFilter { + $Name -eq 'ZoneScope' -and $ZoneName -eq 'contoso.com' + } + } + + It 'Calls Remove-DnsServerZoneScope in the set method when Ensure is Absent' { + Mock -CommandName Remove-DnsServerZoneScope + Mock -CommandName Get-DnsServerZoneScope { return $mocks.ZoneScopePresent } + $params = @{ + Ensure = 'Absent' + ZoneName = 'contoso.com' + Name = 'ZoneScope' + } + Set-TargetResource @params + + Assert-MockCalled Remove-DnsServerZoneScope -Scope It + } + } + } + #endregion + } #end InModuleScope +} +finally +{ + #region FOOTER + Restore-TestEnvironment -TestEnvironment $TestEnvironment + #endregion +} From 83c056afcd0a98579c9fe95417ed9209b9bb6c57 Mon Sep 17 00:00:00 2001 From: Mark Lewis Date: Wed, 24 Jul 2019 15:03:45 +0100 Subject: [PATCH 2/5] Correcting the Schema.Mof file with Ensure --- .../MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.schema.mof | 1 + 1 file changed, 1 insertion(+) diff --git a/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.schema.mof b/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.schema.mof index 81ad0cf3..e10684af 100644 --- a/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.schema.mof +++ b/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.schema.mof @@ -3,5 +3,6 @@ class MSFT_xDnsServerZoneScope : OMI_BaseResource { [Key, Description("Specifies the name of the Zone Scope.")] string Name; [Write, Description("Specify the existing DNS Zone to add a scope to.")] string ZoneName; + [Write, Description("Should this DNS Server Zone Scope be present or absent"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; }; From f2739bdf8ebf9592f16272c514fc64be24b7591a Mon Sep 17 00:00:00 2001 From: Mark Lewis Date: Wed, 24 Jul 2019 15:05:32 +0100 Subject: [PATCH 3/5] Zone Scope is unique to a Zone, Key is name and zonename --- .../MSFT_xDnsServerZoneScope.schema.mof | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.schema.mof b/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.schema.mof index e10684af..858db5f2 100644 --- a/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.schema.mof +++ b/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.schema.mof @@ -2,7 +2,7 @@ class MSFT_xDnsServerZoneScope : OMI_BaseResource { [Key, Description("Specifies the name of the Zone Scope.")] string Name; - [Write, Description("Specify the existing DNS Zone to add a scope to.")] string ZoneName; + [Key, Description("Specify the existing DNS Zone to add a scope to.")] string ZoneName; [Write, Description("Should this DNS Server Zone Scope be present or absent"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; }; From bf5e4c633ae239260bbec02bea064ad211927324 Mon Sep 17 00:00:00 2001 From: Mark Lewis Date: Wed, 24 Jul 2019 15:07:03 +0100 Subject: [PATCH 4/5] Remove spare line --- .../MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.psm1 | 1 - 1 file changed, 1 deletion(-) diff --git a/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.psm1 b/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.psm1 index 214a2474..b26146aa 100644 --- a/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.psm1 +++ b/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.psm1 @@ -86,7 +86,6 @@ function Set-TargetResource $Ensure = 'Present' ) - $clientSubnet = Get-DnsServerZoneScope -Name $Name -ZoneName $ZoneName -ErrorAction SilentlyContinue if ($Ensure -eq 'Present') { From 287841a036a4c917ad036decb645f3fed5c771ed Mon Sep 17 00:00:00 2001 From: Mark Lewis Date: Wed, 24 Jul 2019 17:17:04 +0100 Subject: [PATCH 5/5] Help Text to Match readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e2f54f4a..56c63ea6 100644 --- a/README.md +++ b/README.md @@ -224,7 +224,7 @@ Requires Windows Server 2016 onwards Requires Windows Server 2016 onwards * **Name**: Specifies the name of the Zone Scope. -* **ZoneName**: Specifies the name of the DNS Zone the scope applies to. +* **ZoneName**: Specify the existing DNS Zone to add a scope to. * **Ensure**: Whether the Zone Scope should be present or removed. ## Versions