Skip to content

Commit

Permalink
DnsRecordNs: Implemented as a class-based resource (#254)
Browse files Browse the repository at this point in the history
- DnsRecordNs
  - Added new resource to manage NS records
- DnsRecordNsScoped
  - Added new resource to manage scoped NS records
  • Loading branch information
Sudman1 authored Apr 23, 2021
1 parent 97f6ef7 commit b17d68f
Show file tree
Hide file tree
Showing 20 changed files with 2,095 additions and 8 deletions.
12 changes: 8 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed code coverage in the pipeline ([issue #246](https://github.com/dsccommunity/DnsServerDsc/issues/246)).
- ResourceBase
- Added new method `Assert()` tha calls `Assert-Module` and `AssertProperties()`.
- DnsRecordNs
- Added new resource to manage NS records
- DnsRecordNsScoped
- Added new resource to manage scoped NS records

### Changed

Expand Down Expand Up @@ -153,7 +157,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
(EDNS) settings ([issue #194](https://github.com/dsccommunity/DnsServerDsc/issues/194)).
- xDNSServerClientSubnet
- Added integration tests.
- xDnsServerPrimaryZone
- DnsServerPrimaryZone
- Added integration tests ([issue #173](https://github.com/dsccommunity/DnsServerDsc/issues/173)).
- Added more examples.
- xDnsRecordMx
Expand Down Expand Up @@ -227,7 +231,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
parameter `DnsServer`. This prevents the resource from being used twice
in the same configuration using the same value for the parameter `DnsServer`
([issue #157](https://github.com/dsccommunity/DnsServerDsc/issues/157)).
- xDnsServerPrimaryZone
- DnsServerPrimaryZone
- Now the property `Name` is always returned from `Get-TargetResource`
since it is a `Key` property.
- xDnsServerForwarder
Expand Down Expand Up @@ -343,7 +347,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
master and dev branch ([issue #73](https://github.com/PowerShell/xActiveDirectory/issues/73)).
- Updated description of resource module in README.md.
- Added resource xDnsServerZoneAging. [Claudio Spizzi (@claudiospizzi)](https://github.com/claudiospizzi)
- Changes to xDnsServerPrimaryZone
- Changes to DnsServerPrimaryZone
- Fix bug in Get-TargetResource that caused the Zone Name to be null
([issue #63](https://github.com/dsccommunity/DnsServerDsc/issues/63)).
[Brandon Padgett (@gerane)](https://github.com/gerane)
Expand Down Expand Up @@ -399,7 +403,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Added Resource xDnsRecord with support for CNames.
- This will replace xDnsARecord in a future release.
- Added **xDnsServerPrimaryZone** resource
- Added **DnsServerPrimaryZone** resource

## [1.4.0.0] - 2015-12-02

Expand Down
6 changes: 3 additions & 3 deletions source/Classes/003.DnsRecordMx.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
The DnsRecordMx DSC resource manages MX DNS records against a specific zone on a Domain Name System (DNS) server.
.PARAMETER EmailDomain
Everything after the '@' in the email addresses supported by this mail exchanger. It must be a subdomain the zone or the zone itself. To specify all subdomains, use the '*' character (i.e.: *.contoso.com). (Key Parameter)
Everything after the '@' in the email addresses supported by this mail exchanger. It must be a subdomain the zone or the zone itself. To specify all subdomains, use the '*' character (i.e.: *.contoso.com). (Key Parameter)
.PARAMETER MailExchange
FQDN of the server handling email for the specified email domain. When setting the value, this FQDN must resolve to an IP address and cannot reference a CNAME record. (Key Parameter)
FQDN of the server handling email for the specified email domain. When setting the value, this FQDN must resolve to an IP address and cannot reference a CNAME record. (Key Parameter)
.PARAMETER Priority
Specifies the priority for this MX record among other MX records that belong to the same email domain, where a lower value has a higher priority. (Mandatory Parameter)
Specifies the priority for this MX record among other MX records that belong to the same email domain, where a lower value has a higher priority. (Mandatory Parameter)
#>

[DscResource()]
Expand Down
162 changes: 162 additions & 0 deletions source/Classes/003.DnsRecordNs.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
<#
.SYNOPSIS
The DnsRecordNs DSC resource manages NS DNS records against a specific zone on a Domain Name System (DNS) server.
.DESCRIPTION
The DnsRecordNs DSC resource manages NS DNS records against a specific zone on a Domain Name System (DNS) server.
.PARAMETER DomainName
Specifies the fully qualified DNS domain name for which the NameServer is authoritative. It must be a subdomain the zone or the zone itself. To specify all subdomains, use the '*' character (i.e.: *.contoso.com). (Key Parameter)
.PARAMETER NameServer
Specifies the name server of a domain. This should be a fully qualified domain name, not an IP address (Key Parameter)
#>

[DscResource()]
class DnsRecordNs : DnsRecordBase
{
[DscProperty(Key)]
[System.String]
$DomainName

[DscProperty(Key)]
[System.String]
$NameServer

[DnsRecordNs] Get()
{
return ([DnsRecordBase] $this).Get()
}

[void] Set()
{
([DnsRecordBase] $this).Set()
}

[System.Boolean] Test()
{
return ([DnsRecordBase] $this).Test()
}

[System.String] getRecordName()
{
$aRecordName = $null

# Use regex matching to determine if the domain name provided is a subdomain of the ZoneName (ends in ZoneName).
$regexMatch = $this.DomainName | Select-String -Pattern "^((.*?)\.){0,1}$($this.ZoneName)`$"

if ($null -eq $regexMatch)
{
throw ($this.localizedData.DomainZoneMismatch -f $this.DomainName, $this.ZoneName)
}
else
{
# Match group 2 contains the value in which we are interested.
$aRecordName = $regexMatch.Matches.Groups[2].Value
if ($aRecordName -eq '')
{
$aRecordName = '.'
}
}
return $aRecordName
}

hidden [Microsoft.Management.Infrastructure.CimInstance] GetResourceRecord()
{
Write-Verbose -Message ($this.localizedData.GettingDnsRecordMessage -f 'Ns', $this.ZoneName, $this.ZoneScope, $this.DnsServer)

$dnsParameters = @{
ZoneName = $this.ZoneName
ComputerName = $this.DnsServer
RRType = 'NS'
}

if ($this.isScoped)
{
$dnsParameters['ZoneScope'] = $this.ZoneScope
}

$record = Get-DnsServerResourceRecord @dnsParameters -ErrorAction SilentlyContinue | Where-Object -FilterScript {
$translatedRecordName = $this.getRecordName()
if ($translatedRecordName -eq '.')
{
$translatedRecordName = '@'
}
$_.HostName -eq $translatedRecordName -and
$_.RecordData.NameServer -eq "$($this.NameServer)."
}

return $record
}

hidden [DnsRecordNs] NewDscResourceObjectFromRecord([Microsoft.Management.Infrastructure.CimInstance] $record)
{
$dscResourceObject = [DnsRecordNs] @{
ZoneName = $this.ZoneName
DomainName = $this.DomainName
NameServer = $this.NameServer
TimeToLive = $record.TimeToLive.ToString()
DnsServer = $this.DnsServer
Ensure = 'Present'
}

return $dscResourceObject
}

hidden [void] AddResourceRecord()
{
$dnsParameters = @{
ZoneName = $this.ZoneName
ComputerName = $this.DnsServer
NS = $true
Name = $this.getRecordName()
NameServer = $this.NameServer
}

if ($this.isScoped)
{
$dnsParameters['ZoneScope'] = $this.ZoneScope
}

if ($null -ne $this.TimeToLive)
{
$dnsParameters.Add('TimeToLive', $this.TimeToLive)
}

Write-Verbose -Message ($this.localizedData.CreatingDnsRecordMessage -f 'NS', $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
}

if ($this.isScoped)
{
$dnsParameters['ZoneScope'] = $this.ZoneScope
}

# 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
}
}
63 changes: 63 additions & 0 deletions source/Classes/004.DnsRecordNsScoped.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<#
.SYNOPSIS
The DnsRecordNsScoped DSC resource manages NS DNS records against a specific zone and zone scope on a Domain Name System (DNS) server.
.DESCRIPTION
The DnsRecordNsScoped DSC resource manages NS DNS records against a specific zone and zone scope on a Domain Name System (DNS) server.
.PARAMETER ZoneScope
Specifies the name of a zone scope. (Key Parameter)
#>

[DscResource()]
class DnsRecordNsScoped : DnsRecordNs
{
[DscProperty(Key)]
[System.String]
$ZoneScope

[DnsRecordNsScoped] Get()
{
return ([DnsRecordBase] $this).Get()
}

[void] Set()
{
([DnsRecordBase] $this).Set()
}

[System.Boolean] Test()
{
return ([DnsRecordBase] $this).Test()
}

hidden [Microsoft.Management.Infrastructure.CimInstance] GetResourceRecord()
{
return ([DnsRecordNs] $this).GetResourceRecord()
}

hidden [DnsRecordNsScoped] NewDscResourceObjectFromRecord([Microsoft.Management.Infrastructure.CimInstance] $record)
{
$dscResourceObject = [DnsRecordNsScoped] @{
ZoneName = $this.ZoneName
ZoneScope = $this.ZoneScope
DomainName = $this.DomainName
NameServer = $this.NameServer
TimeToLive = $record.TimeToLive.ToString()
DnsServer = $this.DnsServer
Ensure = 'Present'
}

return $dscResourceObject
}

hidden [void] AddResourceRecord()
{
([DnsRecordNs] $this).AddResourceRecord()
}

hidden [void] ModifyResourceRecord([Microsoft.Management.Infrastructure.CimInstance] $existingRecord, [System.Collections.Hashtable[]] $propertiesNotInDesiredState)
{
([DnsRecordNs] $this).ModifyResourceRecord($existingRecord, $propertiesNotInDesiredState)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<#PSScriptInfo
.VERSION 1.0.1
.GUID 308f2896-a19f-42bf-a371-140418850175
.AUTHOR DSC Community
.COMPANYNAME DSC Community
.COPYRIGHT DSC Community contributors. All rights reserved.
.TAGS DSCConfiguration
.LICENSEURI https://github.com/dsccommunity/DnsServerDsc/blob/main/LICENSE
.PROJECTURI https://github.com/dsccommunity/DnsServerDsc
.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 DnsServerDsc


<#
.DESCRIPTION
This configuration will ensure a DNS NS record exists when only the mandatory properties are specified.
#>

Configuration DnsRecordNs_Mandatory_config
{
Import-DscResource -ModuleName 'DnsServerDsc'

Node localhost
{
DnsRecordNs 'TestRecord'
{
ZoneName = 'contoso.com'
DomainName = 'contoso.com'
NameServer = 'ns.contoso.com'
Ensure = 'Present'
}
}
}
Loading

0 comments on commit b17d68f

Please sign in to comment.