2021-03-18 11:36:42 +08:00
|
|
|
package dnsmadeeasy
|
|
|
|
|
|
|
|
import (
|
|
|
|
"strconv"
|
|
|
|
|
2023-05-21 01:21:45 +08:00
|
|
|
"github.com/StackExchange/dnscontrol/v4/models"
|
2021-03-18 11:36:42 +08:00
|
|
|
)
|
|
|
|
|
2021-12-14 20:49:00 +08:00
|
|
|
// DNS Made Easy does not allow the system name servers to be edited, and said records appear to always have a fixed TTL of 86400.
|
|
|
|
const fixedNameServerRecordTTL = 86400
|
|
|
|
|
2021-03-18 11:36:42 +08:00
|
|
|
type singleDomainResponse struct {
|
|
|
|
ID int `json:"id"`
|
|
|
|
Name string `json:"name"`
|
|
|
|
DelegateNameServers []string `json:"delegateNameServers"`
|
|
|
|
NameServers []singleDomainResponseNameServer `json:"nameServers"`
|
|
|
|
ProcessMulti bool `json:"processMulti"`
|
|
|
|
ActiveThirdParties []interface{} `json:"activeThirdParties"`
|
|
|
|
PendingActionID int `json:"pendingActionId"`
|
|
|
|
GtdEnabled bool `json:"gtdEnabled"`
|
|
|
|
Created int64 `json:"created"`
|
|
|
|
Updated int64 `json:"updated"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type singleDomainResponseNameServer struct {
|
|
|
|
Fqdn string `json:"fqdn"`
|
|
|
|
Ipv4 string `json:"ipv4"`
|
|
|
|
Ipv6 string `json:"ipv6"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type singleDomainRequestData struct {
|
|
|
|
Name string `json:"name"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type multiDomainResponse struct {
|
|
|
|
TotalRecords int `json:"totalRecords"`
|
|
|
|
TotalPages int `json:"totalPages"`
|
|
|
|
Data []multiDomainResponseDataEntry `json:"data"`
|
|
|
|
Page int `json:"page"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type multiDomainResponseDataEntry struct {
|
|
|
|
ID int `json:"id"`
|
|
|
|
Name string `json:"name"`
|
|
|
|
FolderID int `json:"folderId"`
|
|
|
|
GtdEnabled bool `json:"gtdEnabled"`
|
|
|
|
ProcessMulti bool `json:"processMulti"`
|
|
|
|
ActiveThirdParties []interface{} `json:"activeThirdParties"`
|
|
|
|
PendingActionID int `json:"pendingActionId"`
|
|
|
|
VanityID int `json:"vanityId,omitempty"`
|
|
|
|
Created int64 `json:"created"`
|
|
|
|
Updated int64 `json:"updated"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type recordResponse struct {
|
|
|
|
TotalRecords int `json:"totalRecords"`
|
|
|
|
TotalPages int `json:"totalPages"`
|
|
|
|
Data []recordResponseDataEntry `json:"data"`
|
|
|
|
Page int `json:"page"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type recordResponseDataEntry struct {
|
|
|
|
ID int `json:"id"`
|
|
|
|
Name string `json:"name"`
|
|
|
|
Type string `json:"type"`
|
|
|
|
Value string `json:"value"`
|
|
|
|
TTL int `json:"ttl"`
|
|
|
|
|
|
|
|
Source int `json:"source"`
|
|
|
|
SourceID int `json:"sourceId"`
|
|
|
|
|
|
|
|
DynamicDNS bool `json:"dynamicDns"`
|
|
|
|
Password string `json:"password"`
|
|
|
|
|
|
|
|
// A records
|
|
|
|
Monitor bool `json:"monitor"`
|
|
|
|
Failover bool `json:"failover"`
|
|
|
|
Failed bool `json:"failed"`
|
|
|
|
|
|
|
|
// Global Traffic Director
|
|
|
|
GtdLocation string `json:"gtdLocation"`
|
|
|
|
|
|
|
|
// HTTPRED records
|
|
|
|
Description string `json:"description"`
|
|
|
|
Keywords string `json:"keywords"`
|
|
|
|
Title string `json:"title"`
|
|
|
|
RedirectType string `json:"redirectType"`
|
|
|
|
HardLink bool `json:"hardLink"`
|
|
|
|
|
|
|
|
// MX records
|
|
|
|
MxLevel int `json:"mxLevel"`
|
|
|
|
|
|
|
|
// SRV records
|
|
|
|
Weight int `json:"weight"`
|
|
|
|
Priority int `json:"Priority"`
|
|
|
|
Port int `json:"port"`
|
|
|
|
|
|
|
|
// CAA records
|
|
|
|
CaaType string `json:"caaType"`
|
|
|
|
IssuerCritical int `json:"issuerCritical"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type recordRequestData struct {
|
|
|
|
ID int `json:"id"`
|
|
|
|
Name string `json:"name"`
|
|
|
|
Type string `json:"type"`
|
|
|
|
Value string `json:"value"`
|
|
|
|
TTL int `json:"ttl"`
|
|
|
|
|
|
|
|
// Global Traffic Director
|
|
|
|
GtdLocation string `json:"gtdLocation"`
|
|
|
|
|
|
|
|
// MX records
|
|
|
|
MxLevel int `json:"mxLevel"`
|
|
|
|
|
|
|
|
// SRV records
|
|
|
|
Weight int `json:"weight,omitempty"`
|
|
|
|
Priority int `json:"priority,omitempty"`
|
|
|
|
Port int `json:"port,omitempty"`
|
|
|
|
|
|
|
|
// CAA records
|
|
|
|
CaaType string `json:"caaType"`
|
|
|
|
IssuerCritical int `json:"issuerCritical"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func toRecordConfig(domain string, record *recordResponseDataEntry) *models.RecordConfig {
|
|
|
|
rc := &models.RecordConfig{
|
|
|
|
Type: record.Type,
|
|
|
|
TTL: uint32(record.TTL),
|
|
|
|
Original: record,
|
|
|
|
}
|
|
|
|
|
|
|
|
rc.SetLabel(record.Name, domain)
|
|
|
|
|
|
|
|
var err error
|
|
|
|
if record.Type == "MX" {
|
|
|
|
err = rc.SetTargetMX(uint16(record.MxLevel), record.Value)
|
|
|
|
} else if record.Type == "SRV" {
|
|
|
|
err = rc.SetTargetSRV(uint16(record.Priority), uint16(record.Weight), uint16(record.Port), record.Value)
|
|
|
|
} else if record.Type == "CAA" {
|
2021-12-07 01:45:34 +08:00
|
|
|
value, unquoteErr := strconv.Unquote(record.Value)
|
|
|
|
if unquoteErr != nil {
|
2021-03-18 11:36:42 +08:00
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
err = rc.SetTargetCAA(uint8(record.IssuerCritical), record.CaaType, value)
|
|
|
|
} else {
|
|
|
|
err = rc.PopulateFromString(record.Type, record.Value, domain)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc
|
|
|
|
}
|
|
|
|
|
|
|
|
func fromRecordConfig(rc *models.RecordConfig) *recordRequestData {
|
|
|
|
label := rc.GetLabel()
|
|
|
|
if label == "@" {
|
|
|
|
label = ""
|
|
|
|
}
|
|
|
|
|
|
|
|
record := &recordRequestData{
|
|
|
|
Type: rc.Type,
|
|
|
|
TTL: int(rc.TTL),
|
|
|
|
GtdLocation: "DEFAULT",
|
|
|
|
Name: label,
|
|
|
|
Value: rc.GetTargetCombined(),
|
|
|
|
}
|
|
|
|
|
|
|
|
if record.Type == "MX" {
|
|
|
|
record.MxLevel = int(rc.MxPreference)
|
|
|
|
record.Value = rc.GetTargetField()
|
|
|
|
} else if record.Type == "SRV" {
|
|
|
|
target := rc.GetTargetField()
|
|
|
|
if target == "." {
|
|
|
|
target += "."
|
|
|
|
}
|
|
|
|
|
|
|
|
record.Priority = int(rc.SrvPriority)
|
|
|
|
record.Weight = int(rc.SrvWeight)
|
|
|
|
record.Port = int(rc.SrvPort)
|
|
|
|
record.Value = target
|
|
|
|
} else if record.Type == "CAA" {
|
|
|
|
record.IssuerCritical = int(rc.CaaFlag)
|
|
|
|
record.CaaType = rc.CaaTag
|
|
|
|
record.Value = rc.GetTargetField()
|
|
|
|
}
|
|
|
|
|
|
|
|
return record
|
|
|
|
}
|
|
|
|
|
|
|
|
func systemNameServerToRecordConfig(domain string, nameServer string) *models.RecordConfig {
|
|
|
|
target := nameServer + "."
|
2021-06-03 01:48:19 +08:00
|
|
|
return toRecordConfig(domain, &recordResponseDataEntry{Type: "NS", Value: target, TTL: fixedNameServerRecordTTL})
|
2021-03-18 11:36:42 +08:00
|
|
|
}
|