1
0
mirror of https://github.com/StackExchange/dnscontrol.git synced 2024-05-11 05:55:12 +00:00

CLOUDFLARE: Support CAA rtype (#285)

* Add CAA support to cloudflare
This commit is contained in:
Tom Limoncelli
2017-12-20 10:25:23 -05:00
committed by GitHub
parent ed2b34d473
commit 611a597ae0
5 changed files with 95 additions and 14 deletions

View File

@ -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>

View File

@ -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)

View File

@ -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 {
@ -368,17 +371,32 @@ func (c *cfRecord) toRecord(domain string) *models.RecordConfig {
NameFQDN: c.Name,
Type: c.Type,
Target: c.Content,
MxPreference: c.Priority,
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
}

View File

@ -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{}

View File

@ -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")