From ab78fb6803dd5cc5a741f8c1c2968c8d694ceaee Mon Sep 17 00:00:00 2001 From: James Sudbury Date: Tue, 23 Mar 2021 15:49:44 +0000 Subject: [PATCH] DnsRecordPtr: Re-implemented as a class-based resource with IPv6 support. (#213) - DnsRecordPtr - Added new resource to manage PTR records --- CHANGELOG.md | 2 + source/Classes/002.DnsRecordPtr.ps1 | 223 ++++++++++ .../1-DnsRecordPtr_Mandatory_config.ps1 | 56 +++ .../2-DnsRecordPtr_Full_config.ps1 | 58 +++ .../3-DnsRecordPtr_Remove_config.ps1 | 56 +++ .../4-DnsRecordPtr_Mandatory_v6_config.ps1 | 56 +++ .../5-DnsRecordPtr_Full_v6_config.ps1 | 58 +++ .../6-DnsRecordPtr_Remove_v6_config.ps1 | 56 +++ source/en-US/DnsRecordPtr.strings.psd1 | 13 + .../Classes/DnsRecordPtr.config.ps1 | 105 +++++ .../DnsRecordPtr.integration.tests.ps1 | 216 +++++++++ .../Classes/DnsRecordPtr.v6.config.ps1 | 105 +++++ .../DnsRecordPtr.v6.integration.tests.ps1 | 216 +++++++++ tests/Unit/Classes/DnsRecordPtr.tests.ps1 | 421 ++++++++++++++++++ tests/Unit/Classes/DnsRecordPtr.v6.tests.ps1 | 333 ++++++++++++++ tests/Unit/MockObjects/PtrRecordInstance.xml | 91 ++++ .../Unit/MockObjects/PtrV6RecordInstance.xml | 91 ++++ 17 files changed, 2156 insertions(+) create mode 100644 source/Classes/002.DnsRecordPtr.ps1 create mode 100644 source/Examples/Resources/DnsRecordPtr/1-DnsRecordPtr_Mandatory_config.ps1 create mode 100644 source/Examples/Resources/DnsRecordPtr/2-DnsRecordPtr_Full_config.ps1 create mode 100644 source/Examples/Resources/DnsRecordPtr/3-DnsRecordPtr_Remove_config.ps1 create mode 100644 source/Examples/Resources/DnsRecordPtr/4-DnsRecordPtr_Mandatory_v6_config.ps1 create mode 100644 source/Examples/Resources/DnsRecordPtr/5-DnsRecordPtr_Full_v6_config.ps1 create mode 100644 source/Examples/Resources/DnsRecordPtr/6-DnsRecordPtr_Remove_v6_config.ps1 create mode 100644 source/en-US/DnsRecordPtr.strings.psd1 create mode 100644 tests/Integration/Classes/DnsRecordPtr.config.ps1 create mode 100644 tests/Integration/Classes/DnsRecordPtr.integration.tests.ps1 create mode 100644 tests/Integration/Classes/DnsRecordPtr.v6.config.ps1 create mode 100644 tests/Integration/Classes/DnsRecordPtr.v6.integration.tests.ps1 create mode 100644 tests/Unit/Classes/DnsRecordPtr.tests.ps1 create mode 100644 tests/Unit/Classes/DnsRecordPtr.v6.tests.ps1 create mode 100644 tests/Unit/MockObjects/PtrRecordInstance.xml create mode 100644 tests/Unit/MockObjects/PtrV6RecordInstance.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index 49f5fe6f..72e3b8c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added new resource to manage CNAME records - DnsRecordCnameScoped - Added new resource to manage scoped CNAME records +- DnsRecordPtr + - Added new resource to manage PTR records ### Changed diff --git a/source/Classes/002.DnsRecordPtr.ps1 b/source/Classes/002.DnsRecordPtr.ps1 new file mode 100644 index 00000000..133914e5 --- /dev/null +++ b/source/Classes/002.DnsRecordPtr.ps1 @@ -0,0 +1,223 @@ +<# + .SYNOPSIS + The DnsRecordPtr DSC resource manages PTR DNS records against a specific zone on a Domain Name System (DNS) server. + + .DESCRIPTION + The DnsRecordPtr DSC resource manages PTR DNS records against a specific zone on a Domain Name System (DNS) server. + + .PARAMETER IpAddress + Specifies the IP address to which the record is associated (Can be either IPv4 or IPv6. (Key Parameter) + + .PARAMETER Name + Specifies the FQDN of the host when you add a PTR resource record. (Key Parameter) + + .NOTES + Reverse lookup zones do not support scopes, so there should be no DnsRecordPtrScoped subclass created. +#> + +[DscResource()] +class DnsRecordPtr : DnsRecordBase +{ + [DscProperty(Key)] + [System.String] + $IpAddress + + [DscProperty(Key)] + [System.String] + $Name + + hidden [System.String] $recordHostName + + [DnsRecordPtr] Get() + { + # Ensure $recordHostName is set + $this.recordHostName = $this.getRecordHostName($this.IpAddress) + + return ([DnsRecordBase] $this).Get() + } + + [void] Set() + { + # Ensure $recordHostName is set + $this.recordHostName = $this.getRecordHostName($this.IpAddress) + + ([DnsRecordBase] $this).Set() + } + + [System.Boolean] Test() + { + # Ensure $recordHostName is set + $this.recordHostName = $this.getRecordHostName($this.IpAddress) + + return ([DnsRecordBase] $this).Test() + } + + hidden [Microsoft.Management.Infrastructure.CimInstance] GetResourceRecord() + { + Write-Verbose -Message ($this.localizedData.GettingDnsRecordMessage -f 'Ptr', $this.ZoneName, $this.ZoneScope, $this.DnsServer) + + $dnsParameters = @{ + ZoneName = $this.ZoneName + ComputerName = $this.DnsServer + RRType = 'PTR' + Name = $this.recordHostName + } + + $record = Get-DnsServerResourceRecord @dnsParameters -ErrorAction SilentlyContinue | Where-Object -FilterScript { + $_.RecordData.PtrDomainName -eq "$($this.Name)." + } + + return $record + } + + hidden [DnsRecordPtr] NewDscResourceObjectFromRecord([Microsoft.Management.Infrastructure.CimInstance] $record) + { + $dscResourceObject = [DnsRecordPtr] @{ + ZoneName = $this.ZoneName + IpAddress = $this.IpAddress + Name = $this.Name + TimeToLive = $record.TimeToLive.ToString() + DnsServer = $this.DnsServer + Ensure = 'Present' + } + + return $dscResourceObject + } + + hidden [void] AddResourceRecord() + { + $dnsParameters = @{ + ZoneName = $this.ZoneName + ComputerName = $this.DnsServer + PTR = $true + Name = $this.recordHostName + PtrDomainName = $this.Name + } + + if ($null -ne $this.TimeToLive) + { + $dnsParameters.Add('TimeToLive', $this.TimeToLive) + } + + Write-Verbose -Message ($this.localizedData.CreatingDnsRecordMessage -f 'PTR', $this.ZoneName, $this.ZoneScope, $this.DnsServer) + + Add-DnsServerResourceRecord @dnsParameters + } + + hidden [void] ModifyResourceRecord([Microsoft.Management.Infrastructure.CimInstance] $existingRecord, [System.Collections.Hashtable[]] $propertiesNotInDesiredState) + { + $dnsParameters = @{ + ZoneName = $this.ZoneName + ComputerName = $this.DnsServer + } + + # Copy the existing record and modify values as appropriate + $newRecord = [Microsoft.Management.Infrastructure.CimInstance]::new($existingRecord) + + foreach ($propertyToChange in $propertiesNotInDesiredState) + { + switch ($propertyToChange.Property) + { + # Key parameters will never be affected, so only include Mandatory and Optional values in the switch statement + 'TimeToLive' + { + $newRecord.TimeToLive = [System.TimeSpan] $propertyToChange.ExpectedValue + } + + } + } + + Set-DnsServerResourceRecord @dnsParameters -OldInputObject $existingRecord -NewInputObject $newRecord -Verbose + } + + # Take a compressed IPv6 string (i.e.: fd00::1) and expand it out to the full notation (i.e.: fd00:0000:0000:0000:0000:0000:0000:0001) + hidden [System.String] expandIPv6String($string) + { + # Split the string on the colons + $segments = [System.Collections.ArrayList]::new(($string -split ':')) + + # Determine how many segments need to be added to reach the 8 required + $blankSegmentCount = 8 - $segments.count + + # Insert missing segments + for ($i = 0; $i -lt $blankSegmentCount; $i++) + { + $segments.Insert(1, '0000') + } + + # Pad out all segments with leading zeros + $paddedSegments = $segments | ForEach-Object { + $_.PadLeft(4, '0') + } + return ($paddedSegments -join ':') + } + + # Translate the IP address to the reverse notation used by the DNS server + hidden [System.String] getReverseNotation([System.Net.IpAddress] $ipAddressObj) + { + $significantData = [System.Collections.ArrayList]::New() + + switch ($ipAddressObj.AddressFamily) + { + 'InterNetwork' + { + $significantData.AddRange(($ipAddressObj.IPAddressToString -split '\.')) + break + } + + 'InterNetworkV6' + { + # Get the hex values into an ArrayList + $significantData.AddRange(($this.expandIPv6String($ipAddressObj.IPAddressToString) -replace ':', '' -split '')) + break + } + } + + $significantData.Reverse() + + # The reverse lookup notation puts a '.' between each hex value + return ($significantData -join '.').Trim('.') + } + + # Determine the record host name + hidden [System.String] getRecordHostName([System.Net.IpAddress] $ipAddressObj) + { + $reverseLookupAddressComponent = "" + + switch ($ipAddressObj.AddressFamily) + { + 'InterNetwork' + { + if (-not $this.ZoneName.ToLower().EndsWith('.in-addr.arpa')) + { + throw ($this.localizedData.NotAnIPv4Zone -f $this.ZoneName) + } + $reverseLookupAddressComponent = $this.ZoneName.Replace('.in-addr.arpa', '') + break + } + + 'InterNetworkV6' + { + if (-not $this.ZoneName.ToLower().EndsWith('.ip6.arpa')) + { + throw ($this.localizedData.NotAnIPv6Zone -f $this.ZoneName) + } + $reverseLookupAddressComponent = $this.ZoneName.Replace('.ip6.arpa', '') + break + } + } + + $reverseNotation = $this.getReverseNotation($ipAddressObj) + + # Check to make sure that the ip address actually belongs in this zone + if ($reverseNotation -notmatch "$($reverseLookupAddressComponent)`$") + { + throw $this.localizedData.WrongZone -f $ipAddressObj.IPAddressToString, $this.ZoneName + } + + # Strip the zone name from the reversed IP using a regular expression + $ptrRecordHostName = $reverseNotation -replace "\.$([System.Text.RegularExpressions.Regex]::Escape($reverseLookupAddressComponent))`$", "" + + return $ptrRecordHostName + } +} diff --git a/source/Examples/Resources/DnsRecordPtr/1-DnsRecordPtr_Mandatory_config.ps1 b/source/Examples/Resources/DnsRecordPtr/1-DnsRecordPtr_Mandatory_config.ps1 new file mode 100644 index 00000000..70ec116b --- /dev/null +++ b/source/Examples/Resources/DnsRecordPtr/1-DnsRecordPtr_Mandatory_config.ps1 @@ -0,0 +1,56 @@ +<#PSScriptInfo + +.VERSION 1.0.1 + +.GUID 1133365f-c781-4f18-9cb5-96ca1c282c87 + +.AUTHOR DSC Community + +.COMPANYNAME DSC Community + +.COPYRIGHT DSC Community contributors. All rights reserved. + +.TAGS DSCConfiguration + +.LICENSEURI https://github.com/dsccommunity/xDnsServer/blob/main/LICENSE + +.PROJECTURI https://github.com/dsccommunity/xDnsServer + +.ICONURI https://dsccommunity.org/images/DSC_Logo_300p.png + +.EXTERNALMODULEDEPENDENCIES + +.REQUIREDSCRIPTS + +.EXTERNALSCRIPTDEPENDENCIES + +.RELEASENOTES +Updated author, copyright notice, and URLs. + +.PRIVATEDATA 2016-Datacenter,2016-Datacenter-Server-Core + +#> + +#Requires -Module xDnsServer + + +<# + .DESCRIPTION + This configuration will ensure a DNS PTR record exists when only the mandatory properties are specified. +#> + +Configuration DnsRecordPtr_Mandatory_config +{ + Import-DscResource -ModuleName 'xDnsServer' + + Node localhost + { + DnsRecordPtr 'TestRecord' + { + ZoneName = '0.168.192.in-addr.arpa' + IpAddress = '192.168.0.9' + Name = 'quarks.contoso.com' + Ensure = 'Present' + } + } +} diff --git a/source/Examples/Resources/DnsRecordPtr/2-DnsRecordPtr_Full_config.ps1 b/source/Examples/Resources/DnsRecordPtr/2-DnsRecordPtr_Full_config.ps1 new file mode 100644 index 00000000..6f5006f2 --- /dev/null +++ b/source/Examples/Resources/DnsRecordPtr/2-DnsRecordPtr_Full_config.ps1 @@ -0,0 +1,58 @@ +<#PSScriptInfo + +.VERSION 1.0.1 + +.GUID 5aa5cffa-4e3a-4861-b601-73f234015bc9 + +.AUTHOR DSC Community + +.COMPANYNAME DSC Community + +.COPYRIGHT DSC Community contributors. All rights reserved. + +.TAGS DSCConfiguration + +.LICENSEURI https://github.com/dsccommunity/xDnsServer/blob/main/LICENSE + +.PROJECTURI https://github.com/dsccommunity/xDnsServer + +.ICONURI https://dsccommunity.org/images/DSC_Logo_300p.png + +.EXTERNALMODULEDEPENDENCIES + +.REQUIREDSCRIPTS + +.EXTERNALSCRIPTDEPENDENCIES + +.RELEASENOTES +Updated author, copyright notice, and URLs. + +.PRIVATEDATA 2016-Datacenter,2016-Datacenter-Server-Core + +#> + +#Requires -Module xDnsServer + + +<# + .DESCRIPTION + This configuration will ensure a DNS PTR record exists when all properties are specified. +#> + +Configuration DnsRecordPtr_Full_config +{ + Import-DscResource -ModuleName 'xDnsServer' + + Node localhost + { + DnsRecordPtr 'TestRecord' + { + ZoneName = '0.168.192.in-addr.arpa' + IpAddress = '192.168.0.9' + Name = 'quarks.contoso.com' + TimeToLive = '01:00:00' + DnsServer = 'localhost' + Ensure = 'Present' + } + } +} diff --git a/source/Examples/Resources/DnsRecordPtr/3-DnsRecordPtr_Remove_config.ps1 b/source/Examples/Resources/DnsRecordPtr/3-DnsRecordPtr_Remove_config.ps1 new file mode 100644 index 00000000..a49be643 --- /dev/null +++ b/source/Examples/Resources/DnsRecordPtr/3-DnsRecordPtr_Remove_config.ps1 @@ -0,0 +1,56 @@ +<#PSScriptInfo + +.VERSION 1.0.1 + +.GUID 35a2f156-e302-4d56-a41b-a2e9a05a4de6 + +.AUTHOR DSC Community + +.COMPANYNAME DSC Community + +.COPYRIGHT DSC Community contributors. All rights reserved. + +.TAGS DSCConfiguration + +.LICENSEURI https://github.com/dsccommunity/xDnsServer/blob/main/LICENSE + +.PROJECTURI https://github.com/dsccommunity/xDnsServer + +.ICONURI https://dsccommunity.org/images/DSC_Logo_300p.png + +.EXTERNALMODULEDEPENDENCIES + +.REQUIREDSCRIPTS + +.EXTERNALSCRIPTDEPENDENCIES + +.RELEASENOTES +Updated author, copyright notice, and URLs. + +.PRIVATEDATA 2016-Datacenter,2016-Datacenter-Server-Core + +#> + +#Requires -Module xDnsServer + + +<# + .DESCRIPTION + This configuration will ensure a DNS PTR record does not exist when mandatory properties are specified. +#> + +Configuration DnsRecordPtr_Remove_config +{ + Import-DscResource -ModuleName 'xDnsServer' + + Node localhost + { + DnsRecordPtr 'TestRecord' + { + ZoneName = '0.168.192.in-addr.arpa' + IpAddress = '192.168.0.9' + Name = 'quarks.contoso.com' + Ensure = 'Absent' + } + } +} diff --git a/source/Examples/Resources/DnsRecordPtr/4-DnsRecordPtr_Mandatory_v6_config.ps1 b/source/Examples/Resources/DnsRecordPtr/4-DnsRecordPtr_Mandatory_v6_config.ps1 new file mode 100644 index 00000000..31adef9a --- /dev/null +++ b/source/Examples/Resources/DnsRecordPtr/4-DnsRecordPtr_Mandatory_v6_config.ps1 @@ -0,0 +1,56 @@ +<#PSScriptInfo + +.VERSION 1.0.1 + +.GUID 954ac80d-0b21-43fa-911c-2bd875bfba36 + +.AUTHOR DSC Community + +.COMPANYNAME DSC Community + +.COPYRIGHT DSC Community contributors. All rights reserved. + +.TAGS DSCConfiguration + +.LICENSEURI https://github.com/dsccommunity/xDnsServer/blob/main/LICENSE + +.PROJECTURI https://github.com/dsccommunity/xDnsServer + +.ICONURI https://dsccommunity.org/images/DSC_Logo_300p.png + +.EXTERNALMODULEDEPENDENCIES + +.REQUIREDSCRIPTS + +.EXTERNALSCRIPTDEPENDENCIES + +.RELEASENOTES +Updated author, copyright notice, and URLs. + +.PRIVATEDATA 2016-Datacenter,2016-Datacenter-Server-Core + +#> + +#Requires -Module xDnsServer + + +<# + .DESCRIPTION + This configuration will ensure a DNS PTR record exists for an IPv6 address when only the mandatory properties are specified. +#> + +Configuration DnsRecordPtr_Mandatory_v6_config +{ + Import-DscResource -ModuleName 'xDnsServer' + + Node localhost + { + DnsRecordPtr 'TestRecord' + { + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + Ensure = 'Present' + } + } +} diff --git a/source/Examples/Resources/DnsRecordPtr/5-DnsRecordPtr_Full_v6_config.ps1 b/source/Examples/Resources/DnsRecordPtr/5-DnsRecordPtr_Full_v6_config.ps1 new file mode 100644 index 00000000..8c000b9c --- /dev/null +++ b/source/Examples/Resources/DnsRecordPtr/5-DnsRecordPtr_Full_v6_config.ps1 @@ -0,0 +1,58 @@ +<#PSScriptInfo + +.VERSION 1.0.1 + +.GUID f8172f8a-c8bd-4be3-a0ca-c636472ca31c + +.AUTHOR DSC Community + +.COMPANYNAME DSC Community + +.COPYRIGHT DSC Community contributors. All rights reserved. + +.TAGS DSCConfiguration + +.LICENSEURI https://github.com/dsccommunity/xDnsServer/blob/main/LICENSE + +.PROJECTURI https://github.com/dsccommunity/xDnsServer + +.ICONURI https://dsccommunity.org/images/DSC_Logo_300p.png + +.EXTERNALMODULEDEPENDENCIES + +.REQUIREDSCRIPTS + +.EXTERNALSCRIPTDEPENDENCIES + +.RELEASENOTES +Updated author, copyright notice, and URLs. + +.PRIVATEDATA 2016-Datacenter,2016-Datacenter-Server-Core + +#> + +#Requires -Module xDnsServer + + +<# + .DESCRIPTION + This configuration will ensure a DNS PTR record exists for an IPv6 address when all properties are specified. +#> + +Configuration DnsRecordPtr_Full_v6_config +{ + Import-DscResource -ModuleName 'xDnsServer' + + Node localhost + { + DnsRecordPtr 'TestRecord' + { + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + TimeToLive = '01:00:00' + DnsServer = 'localhost' + Ensure = 'Present' + } + } +} diff --git a/source/Examples/Resources/DnsRecordPtr/6-DnsRecordPtr_Remove_v6_config.ps1 b/source/Examples/Resources/DnsRecordPtr/6-DnsRecordPtr_Remove_v6_config.ps1 new file mode 100644 index 00000000..4c8b02df --- /dev/null +++ b/source/Examples/Resources/DnsRecordPtr/6-DnsRecordPtr_Remove_v6_config.ps1 @@ -0,0 +1,56 @@ +<#PSScriptInfo + +.VERSION 1.0.1 + +.GUID 6f460efd-2757-442e-82ad-b28c78c0746a + +.AUTHOR DSC Community + +.COMPANYNAME DSC Community + +.COPYRIGHT DSC Community contributors. All rights reserved. + +.TAGS DSCConfiguration + +.LICENSEURI https://github.com/dsccommunity/xDnsServer/blob/main/LICENSE + +.PROJECTURI https://github.com/dsccommunity/xDnsServer + +.ICONURI https://dsccommunity.org/images/DSC_Logo_300p.png + +.EXTERNALMODULEDEPENDENCIES + +.REQUIREDSCRIPTS + +.EXTERNALSCRIPTDEPENDENCIES + +.RELEASENOTES +Updated author, copyright notice, and URLs. + +.PRIVATEDATA 2016-Datacenter,2016-Datacenter-Server-Core + +#> + +#Requires -Module xDnsServer + + +<# + .DESCRIPTION + This configuration will ensure a DNS PTR record does not exist for an IPv6 address when mandatory properties are specified. +#> + +Configuration DnsRecordPtr_Remove_v6_config +{ + Import-DscResource -ModuleName 'xDnsServer' + + Node localhost + { + DnsRecordPtr 'TestRecord' + { + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + Ensure = 'Absent' + } + } +} diff --git a/source/en-US/DnsRecordPtr.strings.psd1 b/source/en-US/DnsRecordPtr.strings.psd1 new file mode 100644 index 00000000..332d6bed --- /dev/null +++ b/source/en-US/DnsRecordPtr.strings.psd1 @@ -0,0 +1,13 @@ +<# + .SYNOPSIS + The localized resource strings in English (en-US) for the + resource DnsRecordPtr. +#> + +ConvertFrom-StringData @' + GettingDnsRecordMessage = Getting specified DNS {0} record in zone '{1}' from '{3}'. + CreatingDnsRecordMessage = Creating {0} record specified in zone '{1}' on '{3}'. + NotAnIPv4Zone = The zone "{0}" is not an IPv4 reverse lookup zone. + NotAnIPv6Zone = The zone "{0}" is not an IPv6 reverse lookup zone. + WrongZone = "{0}" does not belong to the "{1}" zone. +'@ diff --git a/tests/Integration/Classes/DnsRecordPtr.config.ps1 b/tests/Integration/Classes/DnsRecordPtr.config.ps1 new file mode 100644 index 00000000..3e59f37a --- /dev/null +++ b/tests/Integration/Classes/DnsRecordPtr.config.ps1 @@ -0,0 +1,105 @@ +$zoneName = "0.168.192.in-addr.arpa" + +$ConfigurationData = @{ + AllNodes = , @{ + NodeName = 'localhost' + CertificateFile = $Null + } + NonNodeData = @{ + DnsRecordPtr_CreateRecord_Config = @{ + ZoneName = $zoneName + IpAddress = '192.168.0.9' + Name = 'quarks.contoso.com' + } + DnsRecordPtr_ModifyRecord_Config = @{ + ZoneName = $zoneName + IpAddress = '192.168.0.9' + Name = 'quarks.contoso.com' + DnsServer = 'localhost' + TimeToLive = '05:00:00' + Ensure = 'Present' + } + DnsRecordPtr_DeleteRecord_Config = @{ + ZoneName = $zoneName + IpAddress = '192.168.0.9' + Name = 'quarks.contoso.com' + Ensure = 'Absent' + } + } +} + +<# + .SYNOPSIS + Create an PTR record +#> +configuration DnsRecordPtr_CreateRecord_Config +{ + Import-DscResource -ModuleName 'xDnsServer' + + node $AllNodes.NodeName + { + xDnsServerPrimaryZone "Zone $zoneName" + { + Name = $zoneName + } + + DnsRecordPtr 'Integration_Test' + { + ZoneName = $ConfigurationData.NonNodeData.DnsRecordPtr_CreateRecord_Config.ZoneName + IpAddress = $ConfigurationData.NonNodeData.DnsRecordPtr_CreateRecord_Config.IpAddress + Name = $ConfigurationData.NonNodeData.DnsRecordPtr_CreateRecord_Config.Name + } + } +} + +<# + .SYNOPSIS + Modifies an existing PTR record +#> +configuration DnsRecordPtr_ModifyRecord_Config +{ + Import-DscResource -ModuleName 'xDnsServer' + + node $AllNodes.NodeName + { + xDnsServerPrimaryZone "Zone $zoneName" + { + Name = $zoneName + } + + DnsRecordPtr 'Integration_Test' + { + ZoneName = $ConfigurationData.NonNodeData.DnsRecordPtr_ModifyRecord_Config.ZoneName + IpAddress = $ConfigurationData.NonNodeData.DnsRecordPtr_ModifyRecord_Config.IpAddress + Name = $ConfigurationData.NonNodeData.DnsRecordPtr_ModifyRecord_Config.Name + DnsServer = $ConfigurationData.NonNodeData.DnsRecordPtr_ModifyRecord_Config.DnsServer + TimeToLive = $ConfigurationData.NonNodeData.DnsRecordPtr_ModifyRecord_Config.TimeToLive + Ensure = $ConfigurationData.NonNodeData.DnsRecordPtr_ModifyRecord_Config.Ensure + } + } +} + +<# + .SYNOPSIS + Deletes an existing PTR record +#> +configuration DnsRecordPtr_DeleteRecord_Config +{ + Import-DscResource -ModuleName 'xDnsServer' + + node $AllNodes.NodeName + { + xDnsServerPrimaryZone "Zone $zoneName" + { + Name = $zoneName + } + + DnsRecordPtr 'Integration_Test' + { + ZoneName = $ConfigurationData.NonNodeData.DnsRecordPtr_DeleteRecord_Config.ZoneName + IpAddress = $ConfigurationData.NonNodeData.DnsRecordPtr_DeleteRecord_Config.IpAddress + Name = $ConfigurationData.NonNodeData.DnsRecordPtr_DeleteRecord_Config.Name + Ensure = $ConfigurationData.NonNodeData.DnsRecordPtr_DeleteRecord_Config.Ensure + } + } +} diff --git a/tests/Integration/Classes/DnsRecordPtr.integration.tests.ps1 b/tests/Integration/Classes/DnsRecordPtr.integration.tests.ps1 new file mode 100644 index 00000000..84073488 --- /dev/null +++ b/tests/Integration/Classes/DnsRecordPtr.integration.tests.ps1 @@ -0,0 +1,216 @@ +$script:dscModuleName = 'xDnsServer' +$script:dscResourceFriendlyName = 'DnsRecordPtr' +$script:dscResourceName = "$($script:dscResourceFriendlyName)" + +try +{ + Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' +} +catch [System.IO.FileNotFoundException] +{ + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' +} + +$initializationParams = @{ + DSCModuleName = $script:dscModuleName + DSCResourceName = $script:dscResourceName + ResourceType = 'Class' + TestType = 'Integration' +} +$script:testEnvironment = Initialize-TestEnvironment @initializationParams + +# Using try/finally to always cleanup. +try +{ + #region Integration Tests + $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configurationFile + + Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + } + + $configurationName = "$($script:dscResourceName)_CreateRecord_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + 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 + } + + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.IpAddress | Should -Be $shouldBeData.IpAddress + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + + # Optional properties were not specified, so we just need to ensure the value exists + $resourceCurrentState.TimeToLive | Should -Not -Be $null + + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be 'localhost' + $resourceCurrentState.Ensure | Should -Be 'Present' + } + + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } + + $configurationName = "$($script:dscResourceName)_ModifyRecord_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + 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 + } + + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.IpAddress | Should -Be $shouldBeData.IpAddress + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + + # Optional properties + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer + $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + } + + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } + + $configurationName = "$($script:dscResourceName)_DeleteRecord_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + 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 + } + + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.IpAddress | Should -Be $shouldBeData.IpAddress + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + + # Optional properties + if ($shouldBeData.TimeToLive) + { + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + } + + # DnsServer is not specified in this test, so it defaults to 'localhost' + $resourceCurrentState.DnsServer | Should -Be 'localhost' + + # Ensure will be Absent + $resourceCurrentState.Ensure | Should -Be 'Absent' + } + + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } + + } + #endregion +} +finally +{ + Restore-TestEnvironment -TestEnvironment $script:testEnvironment +} diff --git a/tests/Integration/Classes/DnsRecordPtr.v6.config.ps1 b/tests/Integration/Classes/DnsRecordPtr.v6.config.ps1 new file mode 100644 index 00000000..294a461d --- /dev/null +++ b/tests/Integration/Classes/DnsRecordPtr.v6.config.ps1 @@ -0,0 +1,105 @@ +$zoneName = '0.0.d.f.ip6.arpa' + +$ConfigurationData = @{ + AllNodes = , @{ + NodeName = 'localhost' + CertificateFile = $Null + } + NonNodeData = @{ + DnsRecordPtr_CreateRecord_Config_v6 = @{ + ZoneName = $zoneName + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + } + DnsRecordPtr_ModifyRecord_Config_v6 = @{ + ZoneName = $zoneName + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + DnsServer = 'localhost' + TimeToLive = '05:00:00' + Ensure = 'Present' + } + DnsRecordPtr_DeleteRecord_Config_v6 = @{ + ZoneName = $zoneName + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + Ensure = 'Absent' + } + } +} + +<# + .SYNOPSIS + Create an IPv6 PTR record +#> +configuration DnsRecordPtr_CreateRecord_Config_v6 +{ + Import-DscResource -ModuleName 'xDnsServer' + + node $AllNodes.NodeName + { + xDnsServerPrimaryZone "Zone $zoneName" + { + Name = $zoneName + } + + DnsRecordPtr 'Integration_Test' + { + ZoneName = $ConfigurationData.NonNodeData.DnsRecordPtr_CreateRecord_Config_v6.ZoneName + IpAddress = $ConfigurationData.NonNodeData.DnsRecordPtr_CreateRecord_Config_v6.IpAddress + Name = $ConfigurationData.NonNodeData.DnsRecordPtr_CreateRecord_Config_v6.Name + } + } +} + +<# + .SYNOPSIS + Modifies an existing IPv6 PTR record +#> +configuration DnsRecordPtr_ModifyRecord_Config_v6 +{ + Import-DscResource -ModuleName 'xDnsServer' + + node $AllNodes.NodeName + { + xDnsServerPrimaryZone "Zone $zoneName" + { + Name = $zoneName + } + + DnsRecordPtr 'Integration_Test' + { + ZoneName = $ConfigurationData.NonNodeData.DnsRecordPtr_ModifyRecord_Config_v6.ZoneName + IpAddress = $ConfigurationData.NonNodeData.DnsRecordPtr_ModifyRecord_Config_v6.IpAddress + Name = $ConfigurationData.NonNodeData.DnsRecordPtr_ModifyRecord_Config_v6.Name + DnsServer = $ConfigurationData.NonNodeData.DnsRecordPtr_ModifyRecord_Config_v6.DnsServer + TimeToLive = $ConfigurationData.NonNodeData.DnsRecordPtr_ModifyRecord_Config_v6.TimeToLive + Ensure = $ConfigurationData.NonNodeData.DnsRecordPtr_ModifyRecord_Config_v6.Ensure + } + } +} + +<# + .SYNOPSIS + Deletes an existing IPv6 PTR record +#> +configuration DnsRecordPtr_DeleteRecord_Config_v6 +{ + Import-DscResource -ModuleName 'xDnsServer' + + node $AllNodes.NodeName + { + xDnsServerPrimaryZone "Zone $zoneName" + { + Name = $zoneName + } + + DnsRecordPtr 'Integration_Test' + { + ZoneName = $ConfigurationData.NonNodeData.DnsRecordPtr_DeleteRecord_Config_v6.ZoneName + IpAddress = $ConfigurationData.NonNodeData.DnsRecordPtr_DeleteRecord_Config_v6.IpAddress + Name = $ConfigurationData.NonNodeData.DnsRecordPtr_DeleteRecord_Config_v6.Name + Ensure = $ConfigurationData.NonNodeData.DnsRecordPtr_DeleteRecord_Config_v6.Ensure + } + } +} diff --git a/tests/Integration/Classes/DnsRecordPtr.v6.integration.tests.ps1 b/tests/Integration/Classes/DnsRecordPtr.v6.integration.tests.ps1 new file mode 100644 index 00000000..499603a2 --- /dev/null +++ b/tests/Integration/Classes/DnsRecordPtr.v6.integration.tests.ps1 @@ -0,0 +1,216 @@ +$script:dscModuleName = 'xDnsServer' +$script:dscResourceFriendlyName = 'DnsRecordPtr' +$script:dscResourceName = "$($script:dscResourceFriendlyName)" + +try +{ + Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' +} +catch [System.IO.FileNotFoundException] +{ + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' +} + +$initializationParams = @{ + DSCModuleName = $script:dscModuleName + DSCResourceName = $script:dscResourceName + ResourceType = 'Class' + TestType = 'Integration' +} +$script:testEnvironment = Initialize-TestEnvironment @initializationParams + +# Using try/finally to always cleanup. +try +{ + #region Integration Tests + $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).v6.config.ps1" + . $configurationFile + + Describe "$($script:dscResourceName)_Integration (IPv6)" { + BeforeAll { + $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + } + + $configurationName = "$($script:dscResourceName)_CreateRecord_Config_v6" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + 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 + } + + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.IpAddress | Should -Be $shouldBeData.IpAddress + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + + # Optional properties were not specified, so we just need to ensure the value exists + $resourceCurrentState.TimeToLive | Should -Not -Be $null + + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be 'localhost' + $resourceCurrentState.Ensure | Should -Be 'Present' + } + + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } + + $configurationName = "$($script:dscResourceName)_ModifyRecord_Config_v6" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + 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 + } + + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.IpAddress | Should -Be $shouldBeData.IpAddress + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + + # Optional properties + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer + $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + } + + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } + + $configurationName = "$($script:dscResourceName)_DeleteRecord_Config_v6" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + 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 + } + + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.IpAddress | Should -Be $shouldBeData.IpAddress + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + + # Optional properties + if ($shouldBeData.TimeToLive) + { + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + } + + # DnsServer is not specified in this test, so it defaults to 'localhost' + $resourceCurrentState.DnsServer | Should -Be 'localhost' + + # Ensure will be Absent + $resourceCurrentState.Ensure | Should -Be 'Absent' + } + + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } + + } + #endregion +} +finally +{ + Restore-TestEnvironment -TestEnvironment $script:testEnvironment +} diff --git a/tests/Unit/Classes/DnsRecordPtr.tests.ps1 b/tests/Unit/Classes/DnsRecordPtr.tests.ps1 new file mode 100644 index 00000000..ad087247 --- /dev/null +++ b/tests/Unit/Classes/DnsRecordPtr.tests.ps1 @@ -0,0 +1,421 @@ +<# + This pester file is an example of how organize a pester test. + There tests are based to dummy scenario. + Replace all properties, and mock commands by yours. +#> + +$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path +$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { + ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and + $(try + { + Test-ModuleManifest $_.FullName -ErrorAction Stop + } + catch + { + $false + }) } +).BaseName + +Import-Module $ProjectName + +Get-Module -Name 'DnsServer' -All | Remove-Module -Force +Import-Module -Name "$($PSScriptRoot)\..\Stubs\DnsServer.psm1" + +InModuleScope $ProjectName { + Describe DnsRecordPtr -Tag 'DnsRecord', 'DnsRecordPtr' { + Context 'Constructors' { + It 'Should not throw an exception when instantiated' { + { [DnsRecordPtr]::new() } | Should -Not -Throw + } + + It 'Has a default or empty constructor' { + $instance = [DnsRecordPtr]::new() + $instance | Should -Not -BeNullOrEmpty + } + } + + Context 'Type creation' { + It 'Should be type named DnsRecordPtr' { + $instance = [DnsRecordPtr]::new() + $instance.GetType().Name | Should -Be 'DnsRecordPtr' + } + } + } + + Describe "Testing DnsRecordPtr Get Method" -Tag 'Get', 'DnsRecord', 'DnsRecordPtr' { + BeforeEach { + $script:instanceDesiredState = [DnsRecordPtr] @{ + ZoneName = '0.168.192.in-addr.arpa' + IpAddress = '192.168.0.9' + Name = 'quarks.contoso.com' + } + } + + Context "When the configuration is absent" { + BeforeAll { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + } + } + + It 'Should return the state as absent' { + $currentState = $script:instanceDesiredState.Get() + + Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + $currentState.Ensure | Should -Be 'Absent' + } + + It 'Should return the same values as present in Key properties' { + $getMethodResourceResult = $script:instanceDesiredState.Get() + + $getMethodResourceResult.ZoneName | Should -Be $script:instanceDesiredState.ZoneName + $getMethodResourceResult.IpAddress | Should -Be $script:instanceDesiredState.IpAddress + $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name + } + + It 'Should return $false or $null respectively for the rest of the non-key properties' { + $getMethodResourceResult = $script:instanceDesiredState.Get() + + + $getMethodResourceResult.TimeToLive | Should -BeNullOrEmpty + $getMethodResourceResult.DnsServer | Should -Be 'localhost' + } + } + + Context "When the configuration is present" { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + + return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\PtrRecordInstance.xml" + } + } + + It 'Should return the state as present' { + $currentState = $script:instanceDesiredState.Get() + + Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + $currentState.Ensure | Should -Be 'Present' + } + + It 'Should return the same values as present in Key properties' { + $getMethodResourceResult = $script:instanceDesiredState.Get() + + $getMethodResourceResult.IpAddress | Should -Be $script:instanceDesiredState.IpAddress + $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name + } + } + + } + + Describe "Testing DnsRecordPtr Test Method" -Tag 'Test', 'DnsRecord', 'DnsRecordPtr' { + BeforeAll { + } + + Context 'When the system is in the desired state' { + Context 'When the configuration are absent' { + BeforeEach { + $script:instanceDesiredState = [DnsRecordPtr] @{ + ZoneName = '0.168.192.in-addr.arpa' + IpAddress = '192.168.0.9' + Name = 'quarks.contoso.com' + Ensure = [Ensure]::Absent + } + + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordPtr] @{ + ZoneName = '0.168.192.in-addr.arpa' + IpAddress = '192.168.0.9' + Name = 'quarks.contoso.com' + Ensure = [Ensure]::Absent + } + + return $mockInstanceCurrentState + } + } + + It 'Should return $true' { + $script:instanceDesiredState.Test() | Should -BeTrue + } + } + + Context 'When the configuration are present' { + BeforeEach { + $script:instanceDesiredState = [DnsRecordPtr] @{ + ZoneName = '0.168.192.in-addr.arpa' + IpAddress = '192.168.0.9' + Name = 'quarks.contoso.com' + } + + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordPtr] @{ + ZoneName = '0.168.192.in-addr.arpa' + IpAddress = '192.168.0.9' + Name = 'quarks.contoso.com' + Ensure = [Ensure]::Present + } + + return $mockInstanceCurrentState + } + } + + It 'Should return $true' { + $script:instanceDesiredState.Test() | Should -BeTrue + } + } + } + + Context 'When the system is not in the desired state' { + Context 'When the configuration should be absent' { + BeforeEach { + $script:instanceDesiredState = [DnsRecordPtr] @{ + ZoneName = '0.168.192.in-addr.arpa' + IpAddress = '192.168.0.9' + Name = 'quarks.contoso.com' + Ensure = [Ensure]::Absent + } + + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordPtr] @{ + ZoneName = '0.168.192.in-addr.arpa' + IpAddress = '192.168.0.9' + Name = 'quarks.contoso.com' + Ensure = [Ensure]::Present + } + + return $mockInstanceCurrentState + } + } + It 'Should return $false' { + $script:instanceDesiredState.Test() | Should -BeFalse + } + } + + Context 'When the configuration should be present' { + BeforeEach { + $script:instanceDesiredState = [DnsRecordPtr] @{ + ZoneName = '0.168.192.in-addr.arpa' + IpAddress = '192.168.0.9' + Name = 'quarks.contoso.com' + TimeToLive = '1:00:00' + Ensure = [Ensure]::Present + } + } + + It 'Should return $false when the object is not found' { + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordPtr] @{ + ZoneName = '0.168.192.in-addr.arpa' + IpAddress = '192.168.0.9' + Name = 'quarks.contoso.com' + Ensure = [Ensure]::Absent + } + + return $mockInstanceCurrentState + } + $script:instanceDesiredState.Test() | Should -BeFalse + } + + $testCasesToFail = @( + @{ + ZoneName = '0.168.192.in-addr.arpa' + IpAddress = '192.168.0.9' + Name = 'quarks.contoso.com' + DnsServer = 'localhost' + TimeToLive = '02:00:00' # Undesired + Ensure = 'Present' + } + ) + + It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { + param + ( + [System.String] $ZoneName, + [System.String] $IpAddress, + [System.String] $Name, + [System.String] $TimeToLive + ) + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordPtr] @{ + ZoneName = $ZoneName + IpAddress = $IpAddress + Name = $Name + Ensure = [Ensure]::Present + } + + return $mockInstanceCurrentState + } + + $script:instanceDesiredState.Test() | Should -BeFalse + } + } + } + } + + Describe "Testing DnsRecordPtr Set Method" -Tag 'Set', 'DnsRecord', 'DnsRecordPtr' { + BeforeAll { + # Mock the Add-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Add-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Add-DnsServerResourceRecord Called" -Verbose + } -Verifiable + + # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Remove-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Remove-DnsServerResourceRecord Called" -Verbose + } -Verifiable + + Mock -CommandName Set-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Set-DnsServerResourceRecord Called" -Verbose + } -Verifiable + } + + Context 'When the system is not in the desired state' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + + $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\PtrRecordInstance.xml" + + # Set a wrong value + $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' + + return $mockRecord + } + } + + Context 'When the configuration should be absent' { + BeforeAll { + $script:instanceDesiredState = [DnsRecordPtr] @{ + ZoneName = '0.168.192.in-addr.arpa' + IpAddress = '192.168.0.9' + Name = 'quarks.contoso.com' + Ensure = [Ensure]::Absent + } + } + + BeforeEach { + $script:instanceDesiredState.Ensure = [Ensure]::Absent + } + + It 'Should call the correct mocks' { + { $script:instanceDesiredState.Set() } | Should -Not -Throw + Assert-MockCalled -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + Assert-MockCalled -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + } + } + + Context 'When the configuration should be present' { + BeforeAll { + $script:instanceDesiredState = [DnsRecordPtr] @{ + ZoneName = '0.168.192.in-addr.arpa' + IpAddress = '192.168.0.9' + Name = 'quarks.contoso.com' + TimeToLive = '1:00:00' + Ensure = [Ensure]::Present + } + } + + BeforeEach { + $script:instanceDesiredState.Ensure = 'Present' + } + + It 'Should call the correct mocks when record exists' { + { $script:instanceDesiredState.Set() } | Should -Not -Throw + + Assert-MockCalled -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + } + + It 'Should call the correct mocks when record does not exist' { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + + return + } + + { $script:instanceDesiredState.Set() } | Should -Not -Throw + + Assert-MockCalled -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + } + } + + Assert-VerifiableMock + } + } + + Describe "Test bad inputs (both IPv4 and IPv6)" -Tag 'Test', 'DnsRecord', 'DnsRecordPtr' { + It "Throws when the IPv4 address is malformatted" { + $malformattedIPv4State = [DnsRecordPtr] @{ + ZoneName = '0.168.192.in-addr.arpa' + IpAddress = '192.168.0.DS9' + Name = 'quarks.contoso.com' + Ensure = 'Present' + } + + { $malformattedIPv4State.Get() } | Should -Throw -ExpectedMessage ('Cannot convert value "{0}" to type "System.Net.IPAddress". Error: "An invalid IP address was specified."' -f $malformattedIPv4State.IpAddress) + } + + It "Throws when the IPv6 address is malformatted" { + $malformattedIPv6State = [DnsRecordPtr] @{ + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::1::9' + Name = 'quarks.contoso.com' + Ensure = 'Present' + } + + { $malformattedIPv6State.Get() } | Should -Throw -ExpectedMessage ('Cannot convert value "{0}" to type "System.Net.IPAddress". Error: "An invalid IP address was specified."' -f $malformattedIPv6State.IpAddress) + } + + It "Throws when placed in an incorrect IPv4 reverse lookup zone" { + $wrongIPv4ZoneState = [DnsRecordPtr] @{ + ZoneName = '0.168.192.in-addr.arpa' + IpAddress = '192.168.2.9' + Name = 'quarks.contoso.com' + Ensure = 'Present' + } + + { $wrongIPv4ZoneState.Get() } | Should -Throw -ExpectedMessage ('"{0}" does not belong to the "{1}" zone' -f $wrongIPv4ZoneState.IpAddress, $wrongIPv4ZoneState.ZoneName) + } + + It "Throws when placed in an incorrect IPv6 reverse lookup zone" { + $wrongIPv6ZoneState = [DnsRecordPtr] @{ + ZoneName = '1.0.0.d.f.ip6.arpa' + IpAddress = 'fd00::9' + Name = 'quarks.contoso.com' + Ensure = 'Present' + } + + { $wrongIPv6ZoneState.Get() } | Should -Throw -ExpectedMessage ('"{0}" does not belong to the "{1}" zone' -f $wrongIPv6ZoneState.IpAddress, $wrongIPv6ZoneState.ZoneName) + } + + It "Throws trying to put an IPv6 address into an IPv4 reverse lookup zone" { + $zoneVersionMismatchV6InV4State = [DnsRecordPtr] @{ + ZoneName = '0.168.192.in-addr.arpa' + IpAddress = 'fd00::d59' + Name = 'quarks.contoso.com' + Ensure = 'Present' + } + + { $zoneVersionMismatchV6InV4State.Get() } | Should -Throw -ExpectedMessage ('The zone "{0}" is not an IPv6 reverse lookup zone.' -f $zoneVersionMismatchV6InV4State.ZoneName) + } + + It "Throws trying to put an IPv4 address into an IPv6 reverse lookup zone" { + $zoneVersionMismatchV4InV6State = [DnsRecordPtr] @{ + ZoneName = '1.0.0.d.f.ip6.arpa' + IpAddress = '192.168.2.9' + Name = 'quarks.contoso.com' + Ensure = 'Present' + } + + { $zoneVersionMismatchV4InV6State.Get() } | Should -Throw -ExpectedMessage ('The zone "{0}" is not an IPv4 reverse lookup zone.' -f $zoneVersionMismatchV4InV6State.ZoneName) + } + } +} diff --git a/tests/Unit/Classes/DnsRecordPtr.v6.tests.ps1 b/tests/Unit/Classes/DnsRecordPtr.v6.tests.ps1 new file mode 100644 index 00000000..4a16534f --- /dev/null +++ b/tests/Unit/Classes/DnsRecordPtr.v6.tests.ps1 @@ -0,0 +1,333 @@ +<# + This pester file is an example of how organize a pester test. + There tests are based to dummy scenario. + Replace all properties, and mock commands by yours. +#> + +$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path +$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { + ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and + $(try + { + Test-ModuleManifest $_.FullName -ErrorAction Stop + } + catch + { + $false + }) } +).BaseName + +Import-Module $ProjectName + +Get-Module -Name 'DnsServer' -All | Remove-Module -Force +Import-Module -Name "$($PSScriptRoot)\..\Stubs\DnsServer.psm1" + +InModuleScope $ProjectName { + Describe "Testing DnsRecordPtr Get Method (IPv6 inputs)" -Tag 'Get', 'DnsRecord', 'DnsRecordPtr' { + BeforeEach { + $script:instanceDesiredState = [DnsRecordPtr] @{ + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + } + } + + Context "When the configuration is absent" { + BeforeAll { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + } + } + + It 'Should return the state as absent' { + $currentState = $script:instanceDesiredState.Get() + + Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + $currentState.Ensure | Should -Be 'Absent' + } + + It 'Should return the same values as present in Key properties' { + $getMethodResourceResult = $script:instanceDesiredState.Get() + + $getMethodResourceResult.ZoneName | Should -Be $script:instanceDesiredState.ZoneName + $getMethodResourceResult.IpAddress | Should -Be $script:instanceDesiredState.IpAddress + $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name + } + + It 'Should return $false or $null respectively for the rest of the non-key properties' { + $getMethodResourceResult = $script:instanceDesiredState.Get() + + + $getMethodResourceResult.TimeToLive | Should -BeNullOrEmpty + $getMethodResourceResult.DnsServer | Should -Be 'localhost' + } + } + + Context "When the configuration is present" { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + + return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\PtrV6RecordInstance.xml" + } + } + + It 'Should return the state as present' { + $currentState = $script:instanceDesiredState.Get() + + Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + $currentState.Ensure | Should -Be 'Present' + } + + It 'Should return the same values as present in Key properties' { + $getMethodResourceResult = $script:instanceDesiredState.Get() + + $getMethodResourceResult.IpAddress | Should -Be $script:instanceDesiredState.IpAddress + $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name + } + } + + } + + Describe "Testing DnsRecordPtr Test Method (IPv6 inputs)" -Tag 'Test', 'DnsRecord', 'DnsRecordPtr' { + BeforeAll { + } + + Context 'When the system is in the desired state' { + Context 'When the configuration are absent' { + BeforeEach { + $script:instanceDesiredState = [DnsRecordPtr] @{ + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + Ensure = [Ensure]::Absent + } + + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordPtr] @{ + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + Ensure = [Ensure]::Absent + } + + return $mockInstanceCurrentState + } + } + + It 'Should return $true' { + $script:instanceDesiredState.Test() | Should -BeTrue + } + } + + Context 'When the configuration are present' { + BeforeEach { + $script:instanceDesiredState = [DnsRecordPtr] @{ + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + } + + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordPtr] @{ + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + Ensure = [Ensure]::Present + } + + return $mockInstanceCurrentState + } + } + + It 'Should return $true' { + $script:instanceDesiredState.Test() | Should -BeTrue + } + } + } + + Context 'When the system is not in the desired state' { + Context 'When the configuration should be absent' { + BeforeEach { + $script:instanceDesiredState = [DnsRecordPtr] @{ + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + Ensure = [Ensure]::Absent + } + + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordPtr] @{ + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + Ensure = [Ensure]::Present + } + + return $mockInstanceCurrentState + } + } + It 'Should return $false' { + $script:instanceDesiredState.Test() | Should -BeFalse + } + } + + Context 'When the configuration should be present' { + BeforeEach { + $script:instanceDesiredState = [DnsRecordPtr] @{ + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + TimeToLive = '1:00:00' + Ensure = [Ensure]::Present + } + } + + It 'Should return $false when the object is not found' { + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordPtr] @{ + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + Ensure = [Ensure]::Absent + } + + return $mockInstanceCurrentState + } + $script:instanceDesiredState.Test() | Should -BeFalse + } + + $testCasesToFail = @( + @{ + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + DnsServer = 'localhost' + TimeToLive = '02:00:00' # Undesired + Ensure = 'Present' + } + ) + + It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { + param + ( + [System.String] $ZoneName, + [System.String] $IpAddress, + [System.String] $Name, + [System.String] $TimeToLive + ) + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordPtr] @{ + ZoneName = $ZoneName + IpAddress = $IpAddress + Name = $Name + Ensure = [Ensure]::Present + } + + return $mockInstanceCurrentState + } + + $script:instanceDesiredState.Test() | Should -BeFalse + } + } + } + } + + Describe "Testing DnsRecordPtr Set Method (IPv6 inputs)" -Tag 'Set', 'DnsRecord', 'DnsRecordPtr' { + BeforeAll { + # Mock the Add-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Add-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Add-DnsServerResourceRecord Called" -Verbose + } -Verifiable + + # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Remove-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Remove-DnsServerResourceRecord Called" -Verbose + } -Verifiable + + Mock -CommandName Set-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Set-DnsServerResourceRecord Called" -Verbose + } -Verifiable + } + + Context 'When the system is not in the desired state' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + + $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\PtrV6RecordInstance.xml" + + # Set a wrong value + $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' + + return $mockRecord + } + } + + Context 'When the configuration should be absent' { + BeforeAll { + $script:instanceDesiredState = [DnsRecordPtr] @{ + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + Ensure = [Ensure]::Absent + } + } + + BeforeEach { + $script:instanceDesiredState.Ensure = [Ensure]::Absent + } + + It 'Should call the correct mocks' { + { $script:instanceDesiredState.Set() } | Should -Not -Throw + Assert-MockCalled -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + Assert-MockCalled -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + } + } + + Context 'When the configuration should be present' { + BeforeAll { + $script:instanceDesiredState = [DnsRecordPtr] @{ + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + TimeToLive = '1:00:00' + Ensure = [Ensure]::Present + } + } + + BeforeEach { + $script:instanceDesiredState.Ensure = 'Present' + } + + It 'Should call the correct mocks when record exists' { + { $script:instanceDesiredState.Set() } | Should -Not -Throw + + Assert-MockCalled -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + } + + It 'Should call the correct mocks when record does not exist' { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + + return + } + + { $script:instanceDesiredState.Set() } | Should -Not -Throw + + Assert-MockCalled -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + } + } + + Assert-VerifiableMock + } + } +} diff --git a/tests/Unit/MockObjects/PtrRecordInstance.xml b/tests/Unit/MockObjects/PtrRecordInstance.xml new file mode 100644 index 00000000..1919cea0 --- /dev/null +++ b/tests/Unit/MockObjects/PtrRecordInstance.xml @@ -0,0 +1,91 @@ + + + + Microsoft.Management.Infrastructure.CimInstance#root/Microsoft/Windows/DNS/DnsServerResourceRecord + Microsoft.Management.Infrastructure.CimInstance#ROOT/Microsoft/Windows/DNS/DnsDomain + Microsoft.Management.Infrastructure.CimInstance#DnsServerResourceRecord + Microsoft.Management.Infrastructure.CimInstance#DnsDomain + Microsoft.Management.Infrastructure.CimInstance + System.Object + + DnsServerResourceRecord + + 9 + 9 + IN + + + Microsoft.Management.Infrastructure.CimInstance#root/Microsoft/Windows/DNS/DnsServerResourceRecordPtr + Microsoft.Management.Infrastructure.CimInstance#ROOT/Microsoft/Windows/DNS/DnsServerResourceRecordData + Microsoft.Management.Infrastructure.CimInstance#DnsServerResourceRecordPtr + Microsoft.Management.Infrastructure.CimInstance#DnsServerResourceRecordData + Microsoft.Management.Infrastructure.CimInstance + System.Object + + DnsServerResourceRecordPtr + + quarks.contoso.com. + + + + + + System.Collections.ArrayList + System.Object + + + + + DnsServerResourceRecordData + ROOT/Microsoft/Windows/DNS + dnstest + -1031338600 + <CLASS NAME="DnsServerResourceRecordData"><QUALIFIER NAME="ClassVersion" TYPE="string"><VALUE>1.0.0</VALUE></QUALIFIER><QUALIFIER NAME="dynamic" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="locale" TYPE="sint32" TOSUBCLASS="false"><VALUE>1033</VALUE></QUALIFIER><QUALIFIER NAME="provider" TYPE="string"><VALUE>DnsServerPSProvider</VALUE></QUALIFIER></CLASS> + + + + + DnsServerResourceRecordPtr + root/Microsoft/Windows/DNS + dnstest + -1031350040 + <CLASS NAME="DnsServerResourceRecordPtr" SUPERCLASS="DnsServerResourceRecordData"><QUALIFIER NAME="dynamic" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="provider" TYPE="string"><VALUE>DnsServerPSProvider</VALUE></QUALIFIER><QUALIFIER NAME="ClassVersion" TYPE="string"><VALUE>1.0.0</VALUE></QUALIFIER><QUALIFIER NAME="locale" TYPE="sint32" TOSUBCLASS="false"><VALUE>1033</VALUE></QUALIFIER><PROPERTY NAME="PtrDomainName" TYPE="string"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="write" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER></PROPERTY></CLASS> + + + + + + + PTR + + PT1H + 12 + + + + + + + + + DnsDomain + ROOT/Microsoft/Windows/DNS + dnstest + -1031139384 + <CLASS NAME="DnsDomain"><QUALIFIER NAME="ClassVersion" TYPE="string"><VALUE>1.0.0</VALUE></QUALIFIER><QUALIFIER NAME="dynamic" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="locale" TYPE="sint32" TOSUBCLASS="false"><VALUE>1033</VALUE></QUALIFIER><QUALIFIER NAME="provider" TYPE="string"><VALUE>DnsServerPSProvider</VALUE></QUALIFIER><PROPERTY NAME="DistinguishedName" TYPE="string"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER></PROPERTY></CLASS> + + + + + DnsServerResourceRecord + root/Microsoft/Windows/DNS + dnstest + -1031137304 + <CLASS NAME="DnsServerResourceRecord" SUPERCLASS="DnsDomain"><QUALIFIER NAME="dynamic" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="provider" TYPE="string"><VALUE>DnsServerPSProvider</VALUE></QUALIFIER><QUALIFIER NAME="ClassVersion" TYPE="string"><VALUE>1.0.0</VALUE></QUALIFIER><QUALIFIER NAME="locale" TYPE="sint32" TOSUBCLASS="false"><VALUE>1033</VALUE></QUALIFIER><PROPERTY NAME="HostName" TYPE="string"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER></PROPERTY><PROPERTY NAME="RecordClass" TYPE="string"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="ValueMap" TYPE="string"><VALUE.ARRAY><VALUE>IN</VALUE><VALUE>CSNET</VALUE><VALUE>CHAOS</VALUE><VALUE>Hesiod</VALUE></VALUE.ARRAY></QUALIFIER></PROPERTY><PROPERTY NAME="RecordData" TYPE="string"><QUALIFIER NAME="EmbeddedInstance" TYPE="string"><VALUE>DnsServerResourceRecordData</VALUE></QUALIFIER><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="write" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER></PROPERTY><PROPERTY NAME="RecordType" TYPE="string"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="ValueMap" TYPE="string"><VALUE.ARRAY><VALUE>A</VALUE><VALUE>Ns</VALUE><VALUE>Md</VALUE><VALUE>Mf</VALUE><VALUE>CName</VALUE><VALUE>Soa</VALUE><VALUE>Mb</VALUE><VALUE>Mg</VALUE><VALUE>Mr</VALUE><VALUE>Null</VALUE><VALUE>Wks</VALUE><VALUE>Ptr</VALUE><VALUE>HInfo</VALUE><VALUE>MInfo</VALUE><VALUE>Mx</VALUE><VALUE>Text</VALUE><VALUE>Rp</VALUE><VALUE>Afsdb</VALUE><VALUE>X25</VALUE><VALUE>Isdn</VALUE><VALUE>Rt</VALUE><VALUE>Nsap</VALUE><VALUE>NsapPtr</VALUE><VALUE>Sig</VALUE><VALUE>Key</VALUE><VALUE>Px</VALUE><VALUE>Gpos</VALUE><VALUE>AAAA</VALUE><VALUE>Loc</VALUE><VALUE>Nxt</VALUE><VALUE>Eid</VALUE><VALUE>NimLoc</VALUE><VALUE>Srv</VALUE><VALUE>Atma</VALUE><VALUE>Naptr</VALUE><VALUE>Kx</VALUE><VALUE>Cert</VALUE><VALUE>A6</VALUE><VALUE>DName</VALUE><VALUE>Sink</VALUE><VALUE>Opt</VALUE><VALUE>Ds</VALUE><VALUE>Rrsig</VALUE><VALUE>NSEC</VALUE><VALUE>DnsKey</VALUE><VALUE>DhcId</VALUE><VALUE>Wins</VALUE><VALUE>WinsR</VALUE><VALUE>TLSA</VALUE><VALUE>UNKNOWN</VALUE></VALUE.ARRAY></QUALIFIER></PROPERTY><PROPERTY NAME="Timestamp" TYPE="datetime"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER></PROPERTY><PROPERTY NAME="TimeToLive" TYPE="datetime"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="write" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER></PROPERTY><PROPERTY NAME="Type" TYPE="uint16"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER></PROPERTY></CLASS> + + + + + + + diff --git a/tests/Unit/MockObjects/PtrV6RecordInstance.xml b/tests/Unit/MockObjects/PtrV6RecordInstance.xml new file mode 100644 index 00000000..abd21663 --- /dev/null +++ b/tests/Unit/MockObjects/PtrV6RecordInstance.xml @@ -0,0 +1,91 @@ + + + + Microsoft.Management.Infrastructure.CimInstance#root/Microsoft/Windows/DNS/DnsServerResourceRecord + Microsoft.Management.Infrastructure.CimInstance#ROOT/Microsoft/Windows/DNS/DnsDomain + Microsoft.Management.Infrastructure.CimInstance#DnsServerResourceRecord + Microsoft.Management.Infrastructure.CimInstance#DnsDomain + Microsoft.Management.Infrastructure.CimInstance + System.Object + + DnsServerResourceRecord + + 9.5.d.0.0.0.0.0.0.0.0.0.c.5.1.5.0.0.0.0.0.0.0.0.0.0.0.0 + 9.5.d.0.0.0.0.0.0.0.0.0.c.5.1.5.0.0.0.0.0.0.0.0.0.0.0.0 + IN + + + Microsoft.Management.Infrastructure.CimInstance#root/Microsoft/Windows/DNS/DnsServerResourceRecordPtr + Microsoft.Management.Infrastructure.CimInstance#ROOT/Microsoft/Windows/DNS/DnsServerResourceRecordData + Microsoft.Management.Infrastructure.CimInstance#DnsServerResourceRecordPtr + Microsoft.Management.Infrastructure.CimInstance#DnsServerResourceRecordData + Microsoft.Management.Infrastructure.CimInstance + System.Object + + DnsServerResourceRecordPtr + + quarks.contoso.com. + + + + + + System.Collections.ArrayList + System.Object + + + + + DnsServerResourceRecordData + ROOT/Microsoft/Windows/DNS + dnstest + -1035279224 + <CLASS NAME="DnsServerResourceRecordData"><QUALIFIER NAME="ClassVersion" TYPE="string"><VALUE>1.0.0</VALUE></QUALIFIER><QUALIFIER NAME="dynamic" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="locale" TYPE="sint32" TOSUBCLASS="false"><VALUE>1033</VALUE></QUALIFIER><QUALIFIER NAME="provider" TYPE="string"><VALUE>DnsServerPSProvider</VALUE></QUALIFIER></CLASS> + + + + + DnsServerResourceRecordPtr + root/Microsoft/Windows/DNS + dnstest + -1034914264 + <CLASS NAME="DnsServerResourceRecordPtr" SUPERCLASS="DnsServerResourceRecordData"><QUALIFIER NAME="dynamic" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="provider" TYPE="string"><VALUE>DnsServerPSProvider</VALUE></QUALIFIER><QUALIFIER NAME="ClassVersion" TYPE="string"><VALUE>1.0.0</VALUE></QUALIFIER><QUALIFIER NAME="locale" TYPE="sint32" TOSUBCLASS="false"><VALUE>1033</VALUE></QUALIFIER><PROPERTY NAME="PtrDomainName" TYPE="string"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="write" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER></PROPERTY></CLASS> + + + + + + + PTR + + PT1H + 12 + + + + + + + + + DnsDomain + ROOT/Microsoft/Windows/DNS + dnstest + -1031118584 + <CLASS NAME="DnsDomain"><QUALIFIER NAME="ClassVersion" TYPE="string"><VALUE>1.0.0</VALUE></QUALIFIER><QUALIFIER NAME="dynamic" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="locale" TYPE="sint32" TOSUBCLASS="false"><VALUE>1033</VALUE></QUALIFIER><QUALIFIER NAME="provider" TYPE="string"><VALUE>DnsServerPSProvider</VALUE></QUALIFIER><PROPERTY NAME="DistinguishedName" TYPE="string"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER></PROPERTY></CLASS> + + + + + DnsServerResourceRecord + root/Microsoft/Windows/DNS + dnstest + -1031137304 + <CLASS NAME="DnsServerResourceRecord" SUPERCLASS="DnsDomain"><QUALIFIER NAME="dynamic" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="provider" TYPE="string"><VALUE>DnsServerPSProvider</VALUE></QUALIFIER><QUALIFIER NAME="ClassVersion" TYPE="string"><VALUE>1.0.0</VALUE></QUALIFIER><QUALIFIER NAME="locale" TYPE="sint32" TOSUBCLASS="false"><VALUE>1033</VALUE></QUALIFIER><PROPERTY NAME="HostName" TYPE="string"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER></PROPERTY><PROPERTY NAME="RecordClass" TYPE="string"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="ValueMap" TYPE="string"><VALUE.ARRAY><VALUE>IN</VALUE><VALUE>CSNET</VALUE><VALUE>CHAOS</VALUE><VALUE>Hesiod</VALUE></VALUE.ARRAY></QUALIFIER></PROPERTY><PROPERTY NAME="RecordData" TYPE="string"><QUALIFIER NAME="EmbeddedInstance" TYPE="string"><VALUE>DnsServerResourceRecordData</VALUE></QUALIFIER><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="write" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER></PROPERTY><PROPERTY NAME="RecordType" TYPE="string"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="ValueMap" TYPE="string"><VALUE.ARRAY><VALUE>A</VALUE><VALUE>Ns</VALUE><VALUE>Md</VALUE><VALUE>Mf</VALUE><VALUE>CName</VALUE><VALUE>Soa</VALUE><VALUE>Mb</VALUE><VALUE>Mg</VALUE><VALUE>Mr</VALUE><VALUE>Null</VALUE><VALUE>Wks</VALUE><VALUE>Ptr</VALUE><VALUE>HInfo</VALUE><VALUE>MInfo</VALUE><VALUE>Mx</VALUE><VALUE>Text</VALUE><VALUE>Rp</VALUE><VALUE>Afsdb</VALUE><VALUE>X25</VALUE><VALUE>Isdn</VALUE><VALUE>Rt</VALUE><VALUE>Nsap</VALUE><VALUE>NsapPtr</VALUE><VALUE>Sig</VALUE><VALUE>Key</VALUE><VALUE>Px</VALUE><VALUE>Gpos</VALUE><VALUE>AAAA</VALUE><VALUE>Loc</VALUE><VALUE>Nxt</VALUE><VALUE>Eid</VALUE><VALUE>NimLoc</VALUE><VALUE>Srv</VALUE><VALUE>Atma</VALUE><VALUE>Naptr</VALUE><VALUE>Kx</VALUE><VALUE>Cert</VALUE><VALUE>A6</VALUE><VALUE>DName</VALUE><VALUE>Sink</VALUE><VALUE>Opt</VALUE><VALUE>Ds</VALUE><VALUE>Rrsig</VALUE><VALUE>NSEC</VALUE><VALUE>DnsKey</VALUE><VALUE>DhcId</VALUE><VALUE>Wins</VALUE><VALUE>WinsR</VALUE><VALUE>TLSA</VALUE><VALUE>UNKNOWN</VALUE></VALUE.ARRAY></QUALIFIER></PROPERTY><PROPERTY NAME="Timestamp" TYPE="datetime"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER></PROPERTY><PROPERTY NAME="TimeToLive" TYPE="datetime"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="write" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER></PROPERTY><PROPERTY NAME="Type" TYPE="uint16"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER></PROPERTY></CLASS> + + + + + + +