mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
@ -294,7 +294,9 @@
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
|
@ -60,6 +60,18 @@ type DNSProviderConfig struct {
|
||||
// NameFQDN:
|
||||
// This is the FQDN version of Name.
|
||||
// It should never have a trailiing ".".
|
||||
// Valid types:
|
||||
// A
|
||||
// AAAA
|
||||
// ANAME
|
||||
// CAA
|
||||
// CNAME
|
||||
// MX
|
||||
// NS
|
||||
// SRV
|
||||
// TXT
|
||||
// PAGE_RULE // pseudo rtype
|
||||
// TODO(tal): Add all the pseudo types
|
||||
type RecordConfig struct {
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"` // The short name. See below.
|
||||
@ -418,6 +430,32 @@ func SplitCombinedSrvValue(s string) (priority, weight, port uint16, target stri
|
||||
return uint16(priorityconv), uint16(weightconv), uint16(portconv), parts[3], nil
|
||||
}
|
||||
|
||||
func SplitCombinedCaaValue(s string) (tag string, flag uint8, value string, err error) {
|
||||
|
||||
splitData := strings.SplitN(s, " ", 3)
|
||||
if len(splitData) != 3 {
|
||||
err = fmt.Errorf("Unexpected data for CAA record returned by Vultr")
|
||||
return
|
||||
}
|
||||
|
||||
lflag, err := strconv.ParseUint(splitData[0], 10, 8)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
flag = uint8(lflag)
|
||||
|
||||
tag = splitData[1]
|
||||
|
||||
value = splitData[2]
|
||||
if strings.HasPrefix(value, `"`) && strings.HasSuffix(value, `"`) {
|
||||
value = value[1 : len(value)-1]
|
||||
}
|
||||
if strings.HasPrefix(value, `'`) && strings.HasSuffix(value, `'`) {
|
||||
value = value[1 : len(value)-1]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func copyObj(input interface{}, output interface{}) error {
|
||||
buf := &bytes.Buffer{}
|
||||
enc := gob.NewEncoder(buf)
|
||||
|
@ -41,7 +41,7 @@ var docNotes = providers.DocumentationNotes{
|
||||
}
|
||||
|
||||
func init() {
|
||||
providers.RegisterDomainServiceProviderType("CLOUDFLAREAPI", newCloudflare, providers.CanUseSRV, providers.CanUseAlias, docNotes)
|
||||
providers.RegisterDomainServiceProviderType("CLOUDFLAREAPI", newCloudflare, providers.CanUseSRV, providers.CanUseAlias, providers.CanUseCAA, docNotes)
|
||||
providers.RegisterCustomRecordType("CF_REDIRECT", "CLOUDFLAREAPI", "")
|
||||
providers.RegisterCustomRecordType("CF_TEMP_REDIRECT", "CLOUDFLAREAPI", "")
|
||||
}
|
||||
@ -333,13 +333,16 @@ func newCloudflare(m map[string]string, metadata json.RawMessage) (providers.DNS
|
||||
|
||||
// Used on the "existing" records.
|
||||
type cfRecData struct {
|
||||
Service string `json:"service"`
|
||||
Proto string `json:"proto"`
|
||||
Name string `json:"name"`
|
||||
Priority uint16 `json:"priority"`
|
||||
Weight uint16 `json:"weight"`
|
||||
Port uint16 `json:"port"`
|
||||
Target string `json:"target"`
|
||||
Service string `json:"service"` // SRV
|
||||
Proto string `json:"proto"` // SRV
|
||||
Priority uint16 `json:"priority"` // SRV
|
||||
Weight uint16 `json:"weight"` // SRV
|
||||
Port uint16 `json:"port"` // SRV
|
||||
Tag string `json:"tag"` // CAA
|
||||
Flags uint8 `json:"flags"` // CAA
|
||||
Value string `json:"value"` // CAA
|
||||
}
|
||||
|
||||
type cfRecord struct {
|
||||
@ -365,20 +368,35 @@ func (c *cfRecord) toRecord(domain string) *models.RecordConfig {
|
||||
c.Content = dnsutil.AddOrigin(c.Content+".", domain)
|
||||
}
|
||||
rc := &models.RecordConfig{
|
||||
NameFQDN: c.Name,
|
||||
Type: c.Type,
|
||||
Target: c.Content,
|
||||
MxPreference: c.Priority,
|
||||
TTL: c.TTL,
|
||||
Original: c,
|
||||
NameFQDN: c.Name,
|
||||
Type: c.Type,
|
||||
Target: c.Content,
|
||||
TTL: c.TTL,
|
||||
Original: c,
|
||||
}
|
||||
if c.Type == "SRV" {
|
||||
switch c.Type { // #rtype_variations
|
||||
case "A", "AAAA", "ANAME", "CNAME", "NS", "TXT":
|
||||
// nothing additional needed.
|
||||
case "CAA":
|
||||
var err error
|
||||
rc.CaaTag, rc.CaaFlag, rc.Target, err = models.SplitCombinedCaaValue(c.Content)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
case "MX":
|
||||
rc.MxPreference = c.Priority
|
||||
case "SRV":
|
||||
data := *c.Data
|
||||
rc.SrvPriority = data.Priority
|
||||
rc.SrvWeight = data.Weight
|
||||
rc.SrvPort = data.Port
|
||||
rc.Target = dnsutil.AddOrigin(data.Target+".", domain)
|
||||
default:
|
||||
panic(fmt.Sprintf("toRecord unimplemented rtype %v", c.Type))
|
||||
// We panic so that we quickly find any switch statements
|
||||
// that have not been updated for a new RR type.
|
||||
}
|
||||
|
||||
return rc
|
||||
}
|
||||
|
||||
|
@ -67,6 +67,7 @@ func (c *CloudflareApi) getRecordsForDomain(id string, domain string) ([]*models
|
||||
return nil, fmt.Errorf("Error fetching record list cloudflare: %s", stringifyErrors(data.Errors))
|
||||
}
|
||||
for _, rec := range data.Result {
|
||||
//fmt.Printf("REC: %+v\n", rec)
|
||||
records = append(records, rec.toRecord(domain))
|
||||
}
|
||||
ri := data.ResultInfo
|
||||
@ -75,6 +76,7 @@ func (c *CloudflareApi) getRecordsForDomain(id string, domain string) ([]*models
|
||||
}
|
||||
page++
|
||||
}
|
||||
//fmt.Printf("DEBUG REORDS=%v\n", records)
|
||||
return records, nil
|
||||
}
|
||||
|
||||
@ -129,6 +131,14 @@ func cfSrvData(rec *models.RecordConfig) *cfRecData {
|
||||
}
|
||||
}
|
||||
|
||||
func cfCaaData(rec *models.RecordConfig) *cfRecData {
|
||||
return &cfRecData{
|
||||
Tag: rec.CaaTag,
|
||||
Flags: rec.CaaFlag,
|
||||
Value: rec.Target,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CloudflareApi) createRec(rec *models.RecordConfig, domainID string) []*models.Correction {
|
||||
type createRecord struct {
|
||||
Name string `json:"name"`
|
||||
@ -161,6 +171,10 @@ func (c *CloudflareApi) createRec(rec *models.RecordConfig, domainID string) []*
|
||||
if rec.Type == "SRV" {
|
||||
cf.Data = cfSrvData(rec)
|
||||
cf.Name = rec.NameFQDN
|
||||
} else if rec.Type == "CAA" {
|
||||
cf.Data = cfCaaData(rec)
|
||||
cf.Name = rec.NameFQDN
|
||||
cf.Content = ""
|
||||
}
|
||||
endpoint := fmt.Sprintf(recordsURL, domainID)
|
||||
buf := &bytes.Buffer{}
|
||||
@ -204,6 +218,10 @@ func (c *CloudflareApi) modifyRecord(domainID, recID string, proxied bool, rec *
|
||||
if rec.Type == "SRV" {
|
||||
r.Data = cfSrvData(rec)
|
||||
r.Name = rec.NameFQDN
|
||||
} else if rec.Type == "CAA" {
|
||||
r.Data = cfCaaData(rec)
|
||||
r.Name = rec.NameFQDN
|
||||
r.Content = ""
|
||||
}
|
||||
endpoint := fmt.Sprintf(singleRecordURL, domainID, recID)
|
||||
buf := &bytes.Buffer{}
|
||||
|
@ -255,6 +255,11 @@ func toRecordConfig(dc *models.DomainConfig, r *vultr.DNSRecord) (*models.Record
|
||||
|
||||
if r.Type == "CAA" {
|
||||
// Vultr returns in the format "[flag] [tag] [value]"
|
||||
// TODO(tal): I copied this code into models/dns.go. At this point
|
||||
// we can probably replace the code below with:
|
||||
// rc.CaaFlag, rc.CaaTag, rc.Target, err := models.SplitCombinedCaaValue(rc.Target)
|
||||
// return rc, err
|
||||
|
||||
splitData := strings.SplitN(rc.Target, " ", 3)
|
||||
if len(splitData) != 3 {
|
||||
return nil, fmt.Errorf("Unexpected data for CAA record returned by Vultr")
|
||||
|
Reference in New Issue
Block a user