Plugins/TotalUptime.ps1
function Get-CurrentPluginType { 'dns-01' } function Add-DnsTxt { [CmdletBinding()] param( [Parameter(Mandatory, Position = 0)] [string]$RecordName, [Parameter(Mandatory, Position = 1)] [string]$TxtValue, [Parameter(Mandatory)] [pscredential]$TotalUptimeCredential, [string]$TotalUptimeApiRoot = 'https://api.totaluptime.com', [Parameter(ValueFromRemainingArguments)] $ExtraParams ) #Find apex domain for record $DomainMetadata = Find-TotalUptimeDomain -RecordName $RecordName -TotalUptimeCredential $TotalUptimeCredential -TotalUptimeApiRoot $TotalUptimeApiRoot if (-not $DomainMetadata) { throw "Unable to find TotalUptime DNS Zone for $RecordName" } Write-Debug "Found Domain ID $($DomainMetadata.id) for record $RecordName" #strip domain component from record $recShort = ($RecordName -ireplace [regex]::Escape($DomainMetadata.domainName), [string]::Empty).TrimEnd('.') if ($recShort -eq [string]::Empty) { $recShort = '@' } Write-Debug "Stripped record name to $recShort" $txtRecord = Find-TotalUptimeTXTRecord -DomainID $DomainMetadata.id -RecordName $recShort -TxtContent $TxtValue -TotalUptimeCredential $TotalUptimeCredential -TotalUptimeApiRoot $TotalUptimeApiRoot if ($txtRecord) { Write-Debug 'Record already exists, nothing to do' return } #Build Request $reqParams = @{ Uri = "$TotalUptimeApiRoot/CloudDNS/Domain/$($DomainMetadata.id)/TXTRecord" Method = 'Post' Headers = @{ Authorization = ("Basic {0}" -f (ConvertTo-TotalUptimeBasicHTTPAuthString -Credential $TotalUptimeCredential)); Accept = "application/json" 'Content-Type' = "application/x-www-form-urlencoded" } Body = @{ txtHostName = $recShort; txtText = $TxtValue; txtTTL = 60; } | ConvertTo-Json -Compress Verbose = $false ErrorAction = 'Stop' } Write-Debug "POST $($reqParams.Uri)`n$($reqParams.Body)" $Response = Invoke-RestMethod @reqParams @script:UseBasic #failure throw error if ($Response.status -ne 'Success') { throw $Response.message } else { Write-Debug $Response.message } <# .SYNOPSIS Add a DNS TXT record to TotalUptime .DESCRIPTION Add a DNS TXT record to TotalUptime .PARAMETER RecordName The fully qualified name of the TXT record. .PARAMETER TxtValue The value of the TXT record. .PARAMETER TotalUptimeCredential The API username and password required to authenticate. .PARAMETER TotalUptimeApiRoute The API root URL. defaults to https://api.totaluptime.com .PARAMETER ExtraParams This parameter can be ignored and is only used to prevent errors when splatting with more parameters than this function supports. .EXAMPLE Add-DnsTxt '_acme-challenge.example.com' 'txt-value' -TotalUptimeCredential (Get-Credential) Adds a TXT record for the specified site with the specified value. #> } function Remove-DnsTxt { [CmdletBinding()] param( [Parameter(Mandatory, Position = 0)] [string]$RecordName, [Parameter(Mandatory, Position = 1)] [string]$TxtValue, [Parameter(Mandatory)] [pscredential]$TotalUptimeCredential, [string]$TotalUptimeApiRoot = 'https://api.totaluptime.com', [Parameter(ValueFromRemainingArguments)] $ExtraParams ) #Find apex domain for record $DomainMetadata = Find-TotalUptimeDomain -RecordName $RecordName -TotalUptimeCredential $TotalUptimeCredential -TotalUptimeApiRoot $TotalUptimeApiRoot if (-not $DomainMetadata) { throw "Unable to find TotalUptime DNS Zone for $RecordName" } #Format recordname as short form $recShort = ($RecordName -ireplace [regex]::Escape($DomainMetadata.domainName), [string]::Empty).TrimEnd('.') if ($recShort -eq [string]::Empty) { $recShort = '@' } $txtRecord = Find-TotalUptimeTXTRecord -DomainID $DomainMetadata.id -RecordName $recShort -TxtContent $TxtValue -TotalUptimeCredential $TotalUptimeCredential -TotalUptimeApiRoot $TotalUptimeApiRoot if (-not $txtRecord) { Write-Debug 'No record found, nothing to do' return } #Build Request $reqParams = @{ Uri = "$TotalUptimeApiRoot/CloudDNS/Domain/$($DomainMetadata.id)/TXTRecord/$($txtRecord.id)" Method = 'Delete' Headers = @{ Authorization = 'Basic {0}' -f (ConvertTo-TotalUptimeBasicHTTPAuthString -Credential $TotalUptimeCredential) Accept = 'application/json' } Verbose = $false ErrorAction = 'Stop' } Write-Debug "DELETE $($reqParams.Uri)" $Response = Invoke-RestMethod @reqParams @script:UseBasic # throw error on failure if ($Response.status -ne 'Success') { throw $Response.message } else { Write-Debug $Response.message } <# .SYNOPSIS Remove a DNS TXT record from TotalUptime .DESCRIPTION Remove a DNS TXT record from TotalUptime .PARAMETER RecordName The fully qualified name of the TXT record. .PARAMETER TxtValue The value of the TXT record. .PARAMETER TotalUptimeCredential The API username and password required to authenticate. .PARAMETER TotalUptimeApiRoute The API root URL. defaults to https://api.totaluptime.com .PARAMETER ExtraParams This parameter can be ignored and is only used to prevent errors when splatting with more parameters than this function supports. .EXAMPLE Remove-DnsTxt '_acme-challenge.example.com' 'txt-value' -TotalUptimeCredential (Get-Credential) Removes a TXT record for the specified site with the specified value. #> } function Save-DnsTxt { [CmdletBinding()] param( [Parameter(ValueFromRemainingArguments)] $ExtraParams ) <# .SYNOPSIS Not required. .DESCRIPTION This provider does not require calling this function to commit changes to DNS records. .PARAMETER ExtraParams This parameter can be ignored and is only used to prevent errors when splatting with more parameters than this function supports. #> } ############################ # Helper Functions ############################ # API Documentation # https://totaluptime.com/api/v2/ # Auth function function ConvertTo-TotalUptimeBasicHTTPAuthString { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [PSCredential]$Credential ) #Converts a PSCredential Object to a HTTP Basic Auth String $base64AuthString = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $Credential.GetNetworkCredential().UserName, $Credential.GetNetworkCredential().Password))) return $base64AuthString } # Search Functions function Find-TotalUptimeDomain { [CmdletBinding()] param ( [Parameter(Mandatory, Position = 0)] [string]$RecordName, [Parameter(Mandatory)] [pscredential]$TotalUptimeCredential, [string]$TotalUptimeApiRoot = 'https://api.totaluptime.com' ) #retrieve domains in account $Domains = Get-TotalUptimeDomains -TotalUptimeCredential $TotalUptimeCredential -TotalUptimeApiRoot $TotalUptimeApiRoot -EA Stop $DomainNames = $Domains.rows.domainName #check if domain is in domain list $pieces = $RecordName.Split('.') for ($i = 0; $i -lt ($pieces.Count - 1); $i++) { $domainTest = $pieces[$i..($pieces.Count - 1)] -join '.' Write-Debug "Checking $domainTest" if ($domainTest -in $DomainNames) { Write-Debug "Found $domainTest" return $domains.rows | Where-Object domainName -eq $domainTest } } Write-Debug "Unable to find matching domain" return $null } function Find-TotalUptimeTXTRecord { [CmdletBinding()] param ( [Parameter(Mandatory, Position = 0)] [string]$RecordName, [Parameter(Mandatory, Position = 1)] [string]$TxtContent, [Parameter(Mandatory, Position = 2)] [string]$DomainID, [Parameter(Mandatory)] [pscredential]$TotalUptimeCredential, [string]$TotalUptimeApiRoot = 'https://api.totaluptime.com' ) #retrieve TXT records for Domain $TXTRecords = Get-TotalUptimeTXTRecords -DomainID $DomainID -TotalUptimeCredential $TotalUptimeCredential -TotalUptimeApiRoot $TotalUptimeApiRoot #filter by name an content $TXTRecords.rows | Where-Object { ($_.txtHostName -eq $RecordName) -and ($_.txtText -eq $TxtContent) } } # API Calls function Get-TotalUptimeDomains { [CmdletBinding()] param( [Parameter(Mandatory)] [pscredential]$TotalUptimeCredential, [string]$TotalUptimeApiRoot = 'https://api.totaluptime.com' ) #Build Request $reqParams = @{ Uri = "$TotalUptimeApiRoot/CloudDNS/Domain/All" Headers = @{ Authorization = 'Basic {0}' -f (ConvertTo-TotalUptimeBasicHTTPAuthString -Credential $TotalUptimeCredential) Accept = 'application/json' } Verbose = $false ErrorAction = 'Stop' } #Execute Request Write-Debug "GET $($reqParams.Uri)" Invoke-RestMethod @reqParams @script:UseBasic } function Get-TotalUptimeTXTRecords { [CmdletBinding()] param( [Parameter(Mandatory)]$DomainID, [pscredential]$TotalUptimeCredential, [string]$TotalUptimeApiRoot = 'https://api.totaluptime.com' ) #Build Request $reqParams = @{ Uri = "$TotalUptimeApiRoot/CloudDNS/Domain/$DomainID/TXTRecord/All" Headers = @{ Authorization = ("Basic {0}" -f (ConvertTo-TotalUptimeBasicHTTPAuthString -Credential $TotalUptimeCredential)); Accept = "application/json" } Verbose = $false ErrorAction = 'Stop' } #Execute Request Write-Debug "GET $($reqParams.Uri)" Invoke-RestMethod @reqParams @script:UseBasic } |