-
Notifications
You must be signed in to change notification settings - Fork 57
DSC_DNSServerStubZone: Added a new resource to manage file-backed DNS Stub Zones #276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
f623062
00a9e9e
c3b0641
94e9a81
ca9a3bc
f592598
1c37718
14180f4
404618e
53f03e8
83d1c59
e267bf6
303eefb
59f19fa
198f6d1
02feec1
080b38e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,243 @@ | ||
| $script:dscResourceCommonPath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\DscResource.Common' | ||
| $script:dnsServerDscCommonPath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\DnsServerDsc.Common' | ||
|
|
||
| Import-Module -Name $script:dscResourceCommonPath | ||
| Import-Module -Name $script:dnsServerDscCommonPath | ||
|
|
||
| $script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' | ||
|
|
||
| function Get-TargetResource | ||
| { | ||
| [CmdletBinding()] | ||
| [OutputType([System.Collections.Hashtable])] | ||
| param | ||
| ( | ||
| [Parameter(Mandatory = $true)] | ||
| [System.String] | ||
| $Name, | ||
|
|
||
| [Parameter(Mandatory = $true)] | ||
| [ValidateNotNullOrEmpty()] | ||
| [System.String[]] | ||
| $MasterServers, | ||
|
|
||
| [Parameter()] | ||
| [ValidateNotNullOrEmpty()] | ||
| [System.String] | ||
| $ZoneFile = "$Name.dns", | ||
|
|
||
| [Parameter()] | ||
| [ValidateSet('Present','Absent')] | ||
| [System.String] | ||
| $Ensure = 'Present' | ||
| ) | ||
|
|
||
| Assert-Module -ModuleName 'DNSServer' | ||
|
|
||
| Write-Verbose ($script:localizedData.CheckingZoneMessage -f $Name, $Ensure) | ||
|
|
||
| $dnsServerZone = Get-DnsServerZone -Name $Name -ErrorAction SilentlyContinue | ||
|
|
||
| $targetResource = @{ | ||
| Name = $Name | ||
| MasterServers = $dnsServerZone.MasterServers | ForEach-Object { $_.IPAddressToString } | ||
| ZoneFile = $dnsServerZone.ZoneFile | ||
| Ensure = if (-not $dnsServerZone) { 'Absent' } else { 'Present' } | ||
| } | ||
|
|
||
| return $targetResource | ||
|
|
||
| } #end function Get-TargetResource | ||
|
|
||
| function Test-TargetResource | ||
| { | ||
| [CmdletBinding()] | ||
| [OutputType([System.Boolean])] | ||
| param | ||
| ( | ||
| [Parameter(Mandatory = $true)] | ||
| [System.String] | ||
| $Name, | ||
|
|
||
| [Parameter(Mandatory = $true)] | ||
| [ValidateNotNullOrEmpty()] | ||
| [System.String[]] | ||
| $MasterServers, | ||
|
|
||
| [Parameter()] | ||
| [ValidateNotNullOrEmpty()] | ||
| [System.String] | ||
| $ZoneFile = "$Name.dns", | ||
|
|
||
| [Parameter()] | ||
| [ValidateSet('Present','Absent')] | ||
| [System.String] | ||
| $Ensure = 'Present' | ||
| ) | ||
|
|
||
| $targetResource = Get-TargetResource @PSBoundParameters | ||
| $targetResourceInCompliance = $true | ||
| $dnsServerZone = Get-DnsServerZone -Name $Name -ErrorAction SilentlyContinue | ||
|
|
||
| #If we specify that we want to ensure the zone should be ABSENT, check compliance. | ||
| if ($Ensure -eq 'Absent') | ||
| { | ||
| #If the results of our Get-TargetResource shows that the zone is PRESENT, set compliance, because we want it to be absent. | ||
| if ($targetResource.Ensure -eq 'Present') | ||
| { | ||
| # Dns zone is present and should be absent. '{0}' '{1}' '{2}' <--- Definitions in the DSC_DnsServerStubZone.strings.psd1 | ||
| Write-Verbose ($script:localizedData.NotDesiredPropertyMessage -f 'Ensure', 'Absent', 'Present') | ||
|
|
||
| $targetResourceInCompliance = $false | ||
| return $targetResourceInCompliance | ||
|
|
||
| } | ||
| } | ||
| #If we specify that we want to ensure the zone should be PRESENT, check compliance. | ||
indented-automation marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if ($Ensure -eq 'Present') | ||
| { | ||
| #If the results of our Get-TargetResource shows that the zone is PRESENT, set compliance, because we want it to be absent. | ||
| if ($targetResource.Ensure -eq 'Absent') | ||
| { | ||
| # Dns zone is absent and should be present. | ||
| Write-Verbose ($script:localizedData.NotDesiredPropertyMessage -f 'Ensure', 'Present', 'Absent') | ||
|
|
||
| $targetResourceInCompliance = $false | ||
| return $targetResourceInCompliance | ||
| } | ||
|
|
||
| #If the results of our Get-TargetResource shows that the zone is PRESENT, move on to the next validation check. | ||
| if ($targetResource.Ensure -eq 'Present') | ||
| { | ||
| #If the Zone is AD integrated, set non-compliance. | ||
| if ($dnsServerZone.IsDSIntegrated -eq $true) | ||
| { | ||
| #Zone Storage differs from the desired configuration | ||
| Write-Verbose ($script:localizedData.NotDesiredPropertyMessage -f 'ZoneStorageLocation', 'Active Directory', 'File') | ||
|
|
||
| $targetResourceInCompliance = $false | ||
| return $targetResourceInCompliance | ||
| } | ||
| #If the ZoneType isn't of type Stub, set non-compliance. | ||
| if ($dnsServerZone.ZoneType -ne 'Stub') | ||
| { | ||
| #Zone Type differs from the desired configuration | ||
| Write-Verbose ($script:localizedData.NotDesiredPropertyMessage -f 'ZoneType', 'Stub', $dnsServerZone.ZoneType) | ||
|
|
||
| $targetResourceInCompliance = $false | ||
| return $targetResourceInCompliance | ||
| } | ||
| #If the Zone File name differ from the desired configuration, set non-compliance. | ||
| if ($targetResource.ZoneFile -ne $ZoneFile) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens to this value if the stub zone is DS integrated? This effectively an extension of checking the zone type. You blindly assume that the zone either does not exist or is already a (file based) stub zone.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be fixed, but always welcome a second set of eyes. |
||
| { | ||
| #ZoneFile name differs from the desired configuration | ||
| Write-Verbose ($script:localizedData.NotDesiredPropertyMessage -f 'ZoneFile', $targetResource.ZoneFile, $ZoneFile) | ||
|
|
||
| $targetResourceInCompliance = $false | ||
| return $targetResourceInCompliance | ||
| } | ||
| #If the Master Servers differ from the desired configuration, set non-compliance. | ||
| $Comparison = Compare-Object -ReferenceObject $MasterServers -DifferenceObject $targetResource.MasterServers | ||
| if ($Comparison) | ||
| { | ||
| #Zone Master Servers differ from the desired configuration | ||
| Write-Verbose ($script:localizedData.NotDesiredPropertyMessage -f 'MasterServers', ($MasterServers -join ','), ($targetResource.MasterServers -join ',')) | ||
| $targetResourceInCompliance = $false | ||
| } | ||
|
|
||
| return $targetResourceInCompliance | ||
|
|
||
| } | ||
|
|
||
| } | ||
|
|
||
| } #end function Test-TargetResource | ||
|
|
||
| function Set-TargetResource | ||
| { | ||
| [CmdletBinding()] | ||
| param | ||
| ( | ||
| [Parameter(Mandatory = $true)] | ||
| [System.String] | ||
| $Name, | ||
|
|
||
| [Parameter(Mandatory = $true)] | ||
| [ValidateNotNullOrEmpty()] | ||
| [System.String[]] | ||
| $MasterServers, | ||
|
|
||
| [Parameter()] | ||
indented-automation marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| [ValidateNotNullOrEmpty()] | ||
| [System.String] | ||
| $ZoneFile = "$Name.dns", | ||
|
|
||
| [Parameter()] | ||
| [ValidateSet('Present','Absent')] | ||
| [System.String] | ||
| $Ensure = 'Present' | ||
| ) | ||
|
|
||
| Assert-Module -ModuleName 'DNSServer' | ||
| $targetResource = Get-TargetResource @PSBoundParameters | ||
| $dnsServerZone = Get-DnsServerZone -Name $Name -ErrorAction SilentlyContinue | ||
|
|
||
| if ($Ensure -eq 'Absent') | ||
| { | ||
| Write-Verbose ($script:localizedData.CheckingZoneMessage -f $Name, $Ensure) | ||
|
|
||
| if ($dnsServerZone.type -eq 'Stub' -and $dnsServerZone.IsDSIntegrated -eq $false) | ||
| { | ||
|
|
||
| # Remove the DNS Server zone. | ||
| Write-Verbose ($script:localizedData.RemovingZoneMessage -f $Name) | ||
| Get-DnsServerZone -Name $Name | Remove-DnsServerZone -Force | ||
|
|
||
| } | ||
| else | ||
| { | ||
| if ($dnsServerZone.type -ne 'Stub') | ||
| { | ||
|
|
||
| # Zone is not a stub zone. | ||
| Write-Verbose ($script:localizedData.NotDesiredPropertyMessage -f 'ZoneType', 'Stub', $dnsServerZone.ZoneType) | ||
| } | ||
| if ($dnsServerZone.IsDSIntegrated -ne $false) | ||
| { | ||
|
|
||
| # Zone is AD integrated. | ||
| Write-Verbose ($script:localizedData.NotDesiredPropertyMessage -f 'ZoneStorageLocation', 'Active Directory', 'File') | ||
| } | ||
|
|
||
| } | ||
| } | ||
|
|
||
| if ($Ensure -eq 'Present') | ||
| { | ||
| Write-Verbose ($script:localizedData.CheckingZoneMessage -f $Name, $Ensure) | ||
|
|
||
| if ($dnsServerZone.ZoneType -eq 'Stub' -and $dnsServerZone.IsDSIntegrated -eq $false) | ||
| { | ||
| # Compare the Desired master servers to the Existing master servers - if Existing doesn't match Desired, update the master servers for the zone. | ||
| $Comparison = Compare-Object -ReferenceObject $MasterServers -DifferenceObject $targetResource.MasterServers | ||
|
|
||
| #If the Master Servers differ from the desired configuration, set them to the desired configuration. | ||
| if ($Comparison) | ||
| { | ||
| # Update the Master Servers list | ||
| Set-DnsServerStubZone -Name $Name -MasterServers $MasterServers | ||
|
|
||
| Write-Verbose ($script:localizedData.SetPropertyMessage -f 'MasterServers') | ||
indented-automation marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| } | ||
| elseif (-not $dnsServerZone) | ||
| { | ||
| # Create the DNS Server zone. | ||
| Add-DnsServerStubZone -Name $Name -ZoneFile $ZoneFile -MasterServers $MasterServers | ||
|
|
||
| Write-Verbose ($script:localizedData.AddingZoneMessage -f $Name) | ||
| } | ||
| } | ||
|
|
||
| } #end function Set-TargetResource | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| [ClassVersion("1.0.0.0"), FriendlyName("DnsServerStubZone")] | ||
| class DSC_DnsServerStubZone : OMI_BaseResource | ||
| { | ||
| [Key, Description("Name of the DNS Server stub zone")] String Name; | ||
| [Write, Description("Name of the DNS Server stub zone file. If not specified, defaults to 'ZoneName.dns'.")] String ZoneFile; | ||
| [Required, Description("List of master server IP addresses used by the stub zone.")] String MasterServers[]; | ||
| [Write, Description("Whether the DNS zone should be present or absent"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # Description | ||
|
|
||
| The DnsServerStubZone DSC resource manages a standalone file-backed Stub zone on a given Domain Name System (DNS) server. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| # culture="en-US" | ||
| ConvertFrom-StringData @' | ||
| CheckingZoneMessage = Checking DNS server zone with name '{0}' is '{1}'... | ||
| AddingZoneMessage = Adding DNS server zone '{0}' ... | ||
| RemovingZoneMessage = Removing DNS server zone '{0}' ... | ||
| NotDesiredPropertyMessage = DNS server zone property '{0}' is not correct. Expected '{1}', Actual '{2}' | ||
| SetPropertyMessage = DNS server zone property '{0}' is set | ||
| '@ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At no point do you test the current zone type which is going to make for some exciting results if the zone exists as primary or secondary.
I would consider it legitimate for this resource to bail out with an error if the zone exists but is of the wrong type. However, you may also consider it correct to fix the problem. I'd defer to other folks on common handling though @johlju and @dan-hughes.
Whatever happens, you should check zone type and handle it appropriately. Blinding assuming that it can only possibly be a stub zone is a recipe for disaster.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be fixed, but always welcome a second set of eyes.