diff --git a/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.psm1 b/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.psm1 new file mode 100644 index 00000000..b26146aa --- /dev/null +++ b/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.psm1 @@ -0,0 +1,149 @@ +# 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..858db5f2 --- /dev/null +++ b/DSCResources/MSFT_xDnsServerZoneScope/MSFT_xDnsServerZoneScope.schema.mof @@ -0,0 +1,8 @@ +[ClassVersion("1.0.0.0"), FriendlyName("xDnsServerZoneScope")] +class MSFT_xDnsServerZoneScope : OMI_BaseResource +{ + [Key, Description("Specifies the name of the Zone Scope.")] string Name; + [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; +}; + diff --git a/README.md b/README.md index 0de3be89..56c63ea6 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**: Specify the existing DNS Zone to add a scope 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 +}