BrownField/Networking/VPN-SDWAN/NSX-T/Scripts/New-IfNotExist-DNS.ps1 (223 lines of code) (raw):
function New-IfNotExist-DNS {
param(
[string]$avsnsxTmanager,
[string]$nsxtUserName,
[Securestring]$nsxtPassword,
[string]$tier1GatewayName,
[string]$dnsServiceName,
[string]$dhcpServerAddress,
[string]$defaultforwarderzonepath = ""
)
$dnsInfo = Get-DNSInfo -avsnsxTmanager $avsnsxTmanager `
-nsxtUserName $nsxtUserName `
-nsxtPassword $nsxtPassword `
-tier1GatewayName $tier1GatewayName `
-dnsServiceName $dnsServiceName
if ($null -eq $dnsInfo.DNSAddress) {
$dnsInfo = New-DNS -avsnsxTmanager $avsnsxTmanager `
-nsxtUserName $nsxtUserName `
-nsxtPassword $nsxtPassword `
-tier1GatewayName $tier1GatewayName `
-dnsServiceName $dnsServiceName `
-dhcpServerAddress $dhcpServerAddress `
-defaultForwarderZonePath $dnsInfo.DefaultForwarderZonePath
}
return $dnsInfo
}
function Get-DNSInfo {
param(
[string]$dnsServiceName,
[string]$tier1GatewayName
)
$dnsResults = Get-DNSs -avsnsxTmanager $avsnsxTmanager `
-nsxtUserName $nsxtUserName `
-nsxtPassword $nsxtPassword `
-tier1GatewayName $tier1GatewayName
$dnsAddress = $dnsResults |
Where-Object {
$_.primary -and
$_.primary.display_name -and
$_.primary.display_name -eq $dnsServiceName -or
$_.primary.parent_path.Split("/")[-1] -eq $tier1GatewayName
} |
Select-Object -ExpandProperty primary |
Select-Object -ExpandProperty listener_ip
$defaultForwarderZonePath = $dnsResults |
Where-Object {
$_.primary -and
$_.primary.default_forwarder_zone_path
} |
Select-Object -ExpandProperty primary |
Select-Object -ExpandProperty default_forwarder_zone_path |
Select-Object -First 1
if ($null -ne $dns) {
Write-Host "DNS Service with name '$dnsServiceName' or for T1 '$tier1GatewayName' already exists."
}
return @{
DNSAddress = $dnsAddress
DefaultForwarderZonePath = $defaultForwarderZonePath
}
}
function Get-DNSs {
param(
[string]$avsnsxTmanager,
[string]$nsxtUserName,
[SecureString]$nsxtPassword,
[string]$tier1GatewayName
)
$getDNSuri = "$avsnsxTmanager/policy/api/v1/search/" +
"aggregate?page_size=50&cursor=0&sort_by=display_name&sort_ascending=true"
try {
$body = @{
primary = @{
resource_type = "PolicyDnsForwarder"
}
related = @(
@{
resource_type = "Tier0,Tier1"
join_condition = "path:parent_path"
alias = "gateway"
},
@{
resource_type = "SPAN"
join_condition = "path:$0.path"
alias = "gatewaySpan"
},
@{
resource_type = "PolicyDnsForwarderZone"
join_condition = "path:default_forwarder_zone_path"
alias = "defaultZone"
},
@{
resource_type = "PolicyDnsForwarderZone"
join_condition = "path:conditional_forwarder_zone_paths"
alias = "conditionalZones"
}
)
}
$jsonBody = $body | ConvertTo-Json -Depth 10
$response = Invoke-APIRequest -method "POST" `
-url $getDNSuri `
-body $jsonBody `
-avsnsxtUrl $avsnsxTmanager `
-avsnsxtUserName $nsxtUserName `
-avsnsxtPassword $nsxtPassword
if ($null -eq $response) {
return $null
}else {
return $response.results
}
}
catch {
Write-Error "Failed to get DNSs: $_"
}
}
function New-DNS {
param(
[string]$avsnsxTmanager,
[string]$nsxtUserName,
[SecureString]$nsxtPassword,
[string]$tier1GatewayName,
[string]$dnsServiceName,
[string]$dhcpServerAddress,
[string]$defaultForwarderZonePath
)
$dnsServerAddress = New-DNS-Address -dhcpServerAddress $dhcpServerAddress
if ($null -eq $dnsServerAddress) {
Write-Error "Failed to create DNS Service."
return
}
$newDNSServiceUrl = "$avsnsxTmanager/policy/api/v1/infra?enforce_revision_check=true"
$body = @{
resource_type = "Infra"
children = @(
@{
resource_type = "ChildResourceReference"
id = $tier1GatewayName
target_type = "Tier1"
children = @(
@{
PolicyDnsForwarder = @{
resource_type = "PolicyDnsForwarder"
log_level = "INFO"
enabled = $true
display_name = $dnsServiceName
listener_ip = $dnsServerAddress
cache_size = 1024
default_forwarder_zone_path = $defaultForwarderZonePath
id = $dnsServiceName
}
resource_type = "ChildPolicyDnsForwarder"
}
)
}
)
}
$body = $body | ConvertTo-Json -Depth 10
try {
$response = Invoke-APIRequest -method "Patch" `
-url $newDNSServiceUrl `
-body $body `
-avsnsxtUrl $avsnsxTmanager `
-avsnsxtUserName $nsxtUserName `
-avsnsxtPassword $nsxtPassword
if ($null -eq $response) {
Write-Error "Failed to create DNS Service."
return $null
}else {
Write-Host "DNS Service '$dnsServiceName' created successfully."
return @{
DNSAddress = $dnsServerAddress
DefaultForwarderZonePath = $defaultForwarderZonePath
}
}
}
catch {
Write-Error "Failed to create DNS Service: $_"
return $null
}
}
function New-DNS-Address {
param (
[string]$dhcpServerAddress
)
# Helper function to ensure the new network is within RFC1918 address space
function Test-RFC1918Address {
param (
[uint32]$addressUInt32
)
$rfc1918Ranges = @(
@{ Start = [BitConverter]::ToUInt32([System.Net.IPAddress]::Parse("10.0.0.0").GetAddressBytes(), 0); End = [BitConverter]::ToUInt32([System.Net.IPAddress]::Parse("10.255.255.255").GetAddressBytes(), 0) },
@{ Start = [BitConverter]::ToUInt32([System.Net.IPAddress]::Parse("172.16.0.0").GetAddressBytes(), 0); End = [BitConverter]::ToUInt32([System.Net.IPAddress]::Parse("172.31.255.255").GetAddressBytes(), 0) },
@{ Start = [BitConverter]::ToUInt32([System.Net.IPAddress]::Parse("192.168.0.0").GetAddressBytes(), 0); End = [BitConverter]::ToUInt32([System.Net.IPAddress]::Parse("192.168.255.255").GetAddressBytes(), 0) }
)
foreach ($range in $rfc1918Ranges) {
if ($addressUInt32 -ge $range.Start -and $addressUInt32 -le $range.End) {
return $true
}
}
return $false
}
# Extract the base network address and subnet mask
$originalNetwork, $prefixLength = $dhcpServerAddress -split '/'
$prefixLength = [int]$prefixLength
# Convert the base network address to an array of bytes
$baseAddressBytes = [System.Net.IPAddress]::Parse($originalNetwork).GetAddressBytes()
# Increment the third octet
$baseAddressBytes[2] = ($baseAddressBytes[2] + 1) % 256
# Set the fourth octet to 1
$baseAddressBytes[3] = 1
# Convert the byte array to an integer
$newSubnetStartUInt32 = [BitConverter]::ToUInt32($baseAddressBytes, 0)
# Ensure the new network is within RFC1918 address space
while (-not (Test-RFC1918Address -addressUInt32 $newSubnetStartUInt32)) {
$baseAddressBytes[2] = ($baseAddressBytes[2] + 1) % 256
$newSubnetStartUInt32 = [BitConverter]::ToUInt32($baseAddressBytes, 0)
}
# Convert the integer back to a byte array
$newSubnetStartBytes = [BitConverter]::GetBytes($newSubnetStartUInt32)
# Convert the byte array back to an IP address string
$newAddress = [System.Net.IPAddress]::new($newSubnetStartBytes).ToString()
# Return the new subnet address with the new prefix length
return "$newAddress"
}